Version 2.0.0-dev.49.0

Merge commit '17d7f23e71d588656612d1dfdee4c90d16ddc594' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 931d854..de609346 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,24 +1,13 @@
-## 2.0.0-dev.48.0
-
-### Language
-
-#### Strong Mode
-
-### Core library changes
-
-### Dart VM
+## 2.0.0-dev.49.0
 
 ### Tool Changes
 
 #### Pub
 
-#### Other Tools
+* Fix another bug where the version solver could crash when resolving a conflict
+  involving pre-release constraints ([`pub_semver` issue 20][]).
 
-## 2.0.0-dev.49.0
-
-## 2.0.0-dev.47.0
-
-### Tool Changes
+[`pub_semver` issue 20]: https://github.com/dart-lang/pub_semver/issues/20
 
 ## 2.0.0-dev.48.0
 
diff --git a/DEPS b/DEPS
index 82394f1..4ba2514 100644
--- a/DEPS
+++ b/DEPS
@@ -96,10 +96,9 @@
   "http_throttle_tag" : "@1.0.1",
   "idl_parser_rev": "@5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
   "intl_tag": "@0.15.2",
-  "isolate_tag": "@1.1.0",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@2.0.6",
-  "linter_tag": "@0.1.47",
+  "linter_tag": "@0.1.48",
   "logging_tag": "@0.11.3+1",
   "markdown_tag": "@1.1.1",
   "matcher_tag": "@0.12.1+4",
@@ -116,7 +115,7 @@
   "pool_tag": "@1.3.4",
   "protobuf_tag": "@0.7.1",
   "pub_rev": "@4947e0b3cb3ec77e4e8fe0d3141ce4dc60f43256",
-  "pub_semver_tag": "@1.3.6",
+  "pub_semver_tag": "@1.3.7",
   "quiver_tag": "@5aaa3f58c48608af5b027444d561270b53f15dbf",
   "resource_rev":"@af5a5bf65511943398146cf146e466e5f0b95cb9",
   "root_certificates_rev": "@16ef64be64c7dfdff2b9f4b910726e635ccc519e",
@@ -251,8 +250,6 @@
       Var("http_throttle_tag"),
   Var("dart_root") + "/third_party/pkg/intl":
       Var("dart_git") + "intl.git" + Var("intl_tag"),
-  Var("dart_root") + "/third_party/pkg/isolate":
-      Var("dart_git") + "isolate.git" + Var("isolate_tag"),
   Var("dart_root") + "/third_party/pkg/json_rpc_2":
       Var("dart_git") + "json_rpc_2.git" + Var("json_rpc_2_tag"),
   Var("dart_root") + "/third_party/pkg/linter":
diff --git a/docs/language/informal/subtyping.md b/docs/language/informal/subtyping.md
index 121a657..20aa5aa 100644
--- a/docs/language/informal/subtyping.md
+++ b/docs/language/informal/subtyping.md
@@ -1,4 +1,4 @@
-# Dart 2.0 static and runtime subtyping
+# Dart 2.0 Static and Runtime Subtyping
 
 leafp@google.com
 
@@ -7,6 +7,7 @@
 This is intended to define the core of the Dart 2.0 static and runtime subtyping
 relation.
 
+
 ## Types
 
 The syntactic set of types used in this draft are a slight simplification of
@@ -14,12 +15,15 @@
 
 The meta-variables `X`, `Y`, and `Z` range over type variables.
 
-The meta-variables `T`, `S`, and `U` range over types.
+The meta-variables `T`, `S`, `U`, and `V` range over types.
 
 The meta-variable `C` ranges over classes.
 
 The meta-variable `B` ranges over types used as bounds for type variables.
 
+As a general rule, indices up to `k` are used for type parameters and type
+arguments, `n` for required value parameters, and `m` for all value parameters.
+
 The set of types under consideration are as follows:
 
 - Type variables `X`
@@ -31,10 +35,10 @@
 - `Function`
 - `Future<T>`
 - `FutureOr<T>`
-- Interface types `C`, `C<T0, ..., Tn>`
+- Interface types `C`, `C<T0, ..., Tk>`
 - Function types
-  - `U Function<X0 extends B0, ...., Xl extends Bl>(T0 x0, ...., Tn xn, [Tn+1 xn+1, ..., Tm xm])`
-  - `U Function<X0 extends B0, ...., Xl extends Bl>(T0 x0, ...., Tn xn, {Tn+1 xn+1, ..., Tm xm})`
+  - `U Function<X0 extends B0, ...., Xk extends Bk>(T0 x0, ...., Tn xn, [Tn+1 xn+1, ..., Tm xm])`
+  - `U Function<X0 extends B0, ...., Xk extends Bk>(T0 x0, ...., Tn xn, {Tn+1 xn+1, ..., Tm xm})`
 
 We leave the set of interface types unspecified, but assume a class hierarchy
 which provides a mapping from interfaces types `T` to the set of direct
@@ -46,7 +50,7 @@
 The types `Object`, `dynamic` and `void` are all referred to as *top* types, and
 are considered equivalent as types (including when they appear as sub-components
 of other types).  They exist as distinct names only to support distinct errors
-and warnings (or absense thereof).
+and warnings (or absence thereof).
 
 The type `X & T` represents the result of a type promotion operation on a
 variable.  In certain circumstances (defined elsewhere) a variable `x` of type
@@ -56,16 +60,18 @@
 type variables only occur statically (never at runtime).
 
 Given the current promotion semantics the following properties are also true:
-   - If `X` has bound `B` then for any type `X & T`, `T <: B` will be true
+   - If `X` has bound `B` then for any type `X & T`, `T <: B` will be true.
    - Promoted type variable types will only appear as top level types: that is,
      they can never appear as sub-components of other types, in bounds, or as
      part of other promoted type variables.
 
+
 ## Notation
 
-We use `S[T0/Y0, ..., Tl/Yl]` for the result of performing a simultaneous
-capture-avoiding substitution of types `T0, ..., Tl` for the type variables `Y0,
-..., Yl` in the type `S`.
+We use `S[T0/Y0, ..., Tk/Yk]` for the result of performing a simultaneous
+capture-avoiding substitution of types `T0, ..., Tk` for the type variables
+`Y0, ..., Yk` in the type `S`.
+
 
 ## Type equality
 
@@ -75,7 +81,8 @@
 
 TODO: make these rules explicit.
 
-## Algorithmic (Syntax Directed) Subtyping
+
+## Algorithmic subtyping
 
 By convention the following rules are intended to be applied in top down order,
 with exactly one rule syntactically applying.  That is, rules are written in the
@@ -91,9 +98,15 @@
 a rule (but not the syntactic criteria for any rule preceeding it), then the
 subtyping query holds iff the listed additional conditions hold.
 
+This makes the rules algorithmic, because they correspond in an obvious manner
+to an algorithm with an acceptable time complexity, and it makes them syntax
+directed because the overall structure of the algorithm corresponds to specific
+syntactic shapes. We will use the word _algorithmic_ to refer to this property.
+
 The runtime subtyping rules can be derived by eliminating all clauses dealing
 with promoted type variables.
 
+
 ### Rules
 
 We say that a type `T0` is a subtype of a type `T1` (written `T0 <: T1`) when:
@@ -140,26 +153,30 @@
 
 - **Function Type/Function**: `T0` is a function type and `T1` is `Function`
 
-- **Interface Compositionality**: `T0` is an interface type `C0<S0, ..., Sn>`
-  and `T1` is `C0<U0, ..., Un>`
+- **Interface Compositionality**: `T0` is an interface type `C0<S0, ..., Sk>`
+  and `T1` is `C0<U0, ..., Uk>`
   - and each `Si <: Ui`
 
 - **Super-Interface**: `T0` is an interface type with super-interfaces `S0,...Sn`
   - and `Si <: T1` for some `i`
 
-- **Positional Function Types**: `T0` is `U0 Function<X0 extends B00, ..., Xk extends B0k>(T0 x0, ..., Tn xn, [Tn+1 xn+1, ..., Tm xm])`
-  - and `T1` is `U1 Function<Y0 extends B10, ..., Yk extends B1k>(S0 y0, ..., Sp yp, [Sp+1 yp+1, ..., Sq yq])`
+- **Positional Function Types**: `T0` is
+  `U0 Function<X0 extends B00, ..., Xk extends B0k>(V0 x0, ..., Vn xn, [Vn+1 xn+1, ..., Vm xm])`
+  - and `T1` is
+    `U1 Function<Y0 extends B10, ..., Yk extends B1k>(S0 y0, ..., Sp yp, [Sp+1 yp+1, ..., Sq yq])`
   - and `p >= n`
   - and `m >= q`
-  - and `Si[Z0/Y0, ..., Zk/Yk] <: Ti[Z0/X0, ..., Zk/Xk]` for `i` in `0...q`
+  - and `Si[Z0/Y0, ..., Zk/Yk] <: Vi[Z0/X0, ..., Zk/Xk]` for `i` in `0...q`
   - and `U0[Z0/X0, ..., Zk/Xk] <: U1[Z0/Y0, ..., Zk/Yk]`
   - and `B0i[Z0/X0, ..., Zk/Xk] === B1i[Z0/Y0, ..., Zk/Yk]` for `i` in `0...k`
   - where the `Zi` are fresh type variables with bounds `B0i[Z0/X0, ..., Zk/Xk]`
 
-- **Named Function Types**: `T0` is `U0 Function<X0 extends B00, ..., Xk extends B0k>(T0 x0, ..., Tn xn, {Tn+1 xn+1, ..., Tm xm})`
-  - and `T1` is `U1 Function<Y0 extends B10, ..., Yk extends B1k>(S0 y0, ..., Sn yn, {Sn+1 yn+1, ..., Sq yq})`
+- **Named Function Types**: `T0` is
+  `U0 Function<X0 extends B00, ..., Xk extends B0k>(V0 x0, ..., Vn xn, {Vn+1 xn+1, ..., Vm xm})`
+  - and `T1` is
+    `U1 Function<Y0 extends B10, ..., Yk extends B1k>(S0 y0, ..., Sn yn, {Sn+1 yn+1, ..., Sq yq})`
   - and `{yn+1, ... , yq}` subsetof `{xn+1, ... , xm}`
-  - and `Si[Z0/Y0, ..., Zk/Yk] <: Ti[Z0/X0, ..., Zk/Xk]` for `i` in `0...n`
+  - and `Si[Z0/Y0, ..., Zk/Yk] <: Vi[Z0/X0, ..., Zk/Xk]` for `i` in `0...n`
   - and `Si[Z0/Y0, ..., Zk/Yk] <: Tj[Z0/X0, ..., Zk/Xk]` for `i` in `n+1...q`, `yj = xi`
   - and `U0[Z0/X0, ..., Zk/Xk] <: U1[Z0/Y0, ..., Zk/Yk]`
   - and `B0i[Z0/X0, ..., Zk/Xk] === B1i[Z0/Y0, ..., Zk/Yk]` for `i` in `0...k`
@@ -169,14 +186,18 @@
 that the choice of common variable names avoid capture.  It is valid to choose
 the `Xi` or the `Yi` for `Zi` so long as capture is avoided*
 
-## Derivation of syntax directed rules
 
-This section sketches out the derivation of the syntax directed rules from the
-interpretation of `FutureOr` and promoted type bounds as intersection types.
+## Derivation of algorithmic rules
 
-### Non syntax directed rules
+This section sketches out the derivation of the algorithmic rules from the
+interpretation of `FutureOr` as a union type, and promoted type bounds as
+intersection types, based on standard rules for such types that do not satisfy
+the requirements for being algorithmic.
 
-The non syntax directed rules that we derive from first principles of union and
+
+### Non-algorithmic rules
+
+The non-algorithmic rules that we derive from first principles of union and
 intersection types are as follows:
 
 Left union introduction:
@@ -191,16 +212,17 @@
 Right intersection introduction:
  - `S <: X & T` if `S <: X` and `S <: T`
 
-The only remaining non-syntax directed rule is the variable bounds rule:
+The only remaining non-algorithmic rule is the variable bounds rule:
 
 Variable bounds:
   - `X <: T` if `X extends B` and `B <: T`
 
-All other rules are syntax directed.
+All other rules are algorithmic.
 
-Note: I believe that bounds can be treated simply as uses of intersections,
+Note: We believe that bounds can be treated simply as uses of intersections,
 which could simplify this presentation.
 
+
 ### Preliminaries
 
 **Lemma 1**: If there is any derivation of `FutureOr<S> <: T`, then there is a
@@ -250,7 +272,6 @@
      - so by left union introduction, we have a derivation of `FutureOr<S> <: X & T0`
      - QED
 
-
 Note: The reverse is not true.  Counter-example:
 
 Given arbitrary `B <: A`, suppose we wish to show that `(X extends FutureOr<B>)
@@ -279,7 +300,6 @@
 right union introduction rule.  But applying the variable bounds rule doesn't
 work.
 
-
 **Lemma 2**: If there is any derivation of `S <: X & T`, then there is
 derivation ending in a use of right intersection introduction.
 
@@ -326,29 +346,30 @@
      - so by right intersection introduction, we have a derivation of `FutureOr<S0> <: X & T`
      - QED
 
-
 **Conjecture 1**: `FutureOr<A> <: FutureOr<B>` is derivable iff `A <: B` is
 derivable.
 
-pf: Showing that `A <: B => FutureOr<A> <: FutureOr<B>` is easy, it's not
-immediately clear to me how to tackle the opposite direction.
-
+Showing that `A <: B => FutureOr<A> <: FutureOr<B>` is easy, but it is not
+immediately clear how to tackle the opposite direction.
 
 **Lemma 3**: Transitivity of subtyping is admissible.  Given derivations of `A <: B`
 and `B <: C`, there is a derivation of `A <: C`.
 
-proof sketch: The proof should go through by induction on sizes of derivations,
+Proof sketch: The proof should go through by induction on sizes of derivations,
 cases on pairs of rules used.  For any pair of rules used, we can construct a
 new derivation of the desired result using only smaller derivations.
 
 **Observation 1**: Given `X` with bound `S`, we have the property that for all
 instances of `X & T`, `T <: S` will be true, and hence `S <: M => T <: M`.
 
-### Syntax directed rules
+
+### Algorithmic rules
 
 Consider `T0 <: T1`.
 
+
 #### Union on the left
+
 By lemma 1, if `T0` is of the form `FutureOr<S0>` and there is any derivation of
 `T0 <: T1`, then there is a derivation ending with a use of left union
 introduction so we have the rule:
@@ -357,6 +378,7 @@
   - and `Future<S0> <: T1`
   - and `S0 <: T1`
 
+
 #### Identical type variables
 
 If `T0` and `T1` are both the same unpromoted type variable, then subtyping
@@ -375,10 +397,12 @@
 is `X0 & S1`
   - and `T0 <: S1`.
 
-*Note that neither of the previous rules are required to make the rules syntax
-directed: they are merely useful special cases of the next rule.*
+*Note that neither of the previous rules are required to make the rules
+algorithmic: they are merely useful special cases of the next rule.*
+
 
 #### Intersection on the right
+
 By lemma 2, if `T1` is of the `X1 & S1` and there is any derivation of `T0 <:
 T1`, then there is a derivation ending with a use of right intersection
 introduction, hence the rule:
@@ -387,7 +411,9 @@
   - and `T0 <: X1`
   - and `T0 <: S1`
 
+
 #### Union on the right
+
 Suppose `T1` is `FutureOr<S1>`. The rules above have eliminated the possibility
 that `T0` is of the form `FutureOr<S0`.  The only rules that could possibly
 apply then are right union introduction, left intersection introduction, or the
@@ -418,7 +444,9 @@
   - or `T0` is `X0` and `X0` has bound `S0` and `S0 <: T1`
   - or `T0` is `X0 & S0` and `S0 <: T1`
 
+
 #### Intersection on the left
+
 Suppose `T0` is `X0 & S0`. We've eliminated the possibility that `T1` is
 `FutureOr<S1>`, the possibility that `T1` is `X1 & S1`, and the possibility that
 `T1` is any variant of `X0`.  The only remaining rule that applies is left
@@ -430,7 +458,9 @@
 `T0` is a promoted type variable `X0 & S0`
   - and `S0 <: T1`
 
+
 #### Type variable on the left
+
 Suppose `T0` is `X0`.  We've eliminated the possibility that `T1` is
 `FutureOr<S1>`, the possibility that `T1` is `X1 & S1`, and the possibility that
 `T1` is any variant of `X0`.  The only rule that applies is the variable bounds
@@ -439,8 +469,5 @@
 `T0` is a type variable `X0` with bound `B0`
   - and `B0 <: T1`
 
-This eliminates all of the non-syntax directed rules: the remainder are strictly
-syntax directed.
-
-
-## Testing
+This eliminates all of the non-algorithmic rules: the remainder are strictly
+algorithmic.
diff --git a/pkg/analysis_server/benchmark/benchmarks.dart b/pkg/analysis_server/benchmark/benchmarks.dart
index 62e0b44..274571d 100644
--- a/pkg/analysis_server/benchmark/benchmarks.dart
+++ b/pkg/analysis_server/benchmark/benchmarks.dart
@@ -14,11 +14,13 @@
 import 'package:path/path.dart' as path;
 
 import 'perf/benchmarks_impl.dart';
+import 'perf/flutter_analyze_benchmark.dart';
 
 Future main(List<String> args) async {
   final List<Benchmark> benchmarks = [
     new ColdAnalysisBenchmark(),
-    new AnalysisBenchmark()
+    new AnalysisBenchmark(),
+    new FlutterAnalyzeBenchmark(),
   ];
 
   CommandRunner runner = new CommandRunner(
@@ -110,6 +112,11 @@
       actualIterations = math.min(benchmark.maxIterations, repeatCount);
     }
 
+    if (benchmark.needsSetup) {
+      print('Setting up $benchmarkId...');
+      await benchmark.oneTimeSetup();
+    }
+
     try {
       BenchMarkResult result;
       Stopwatch time = new Stopwatch()..start();
@@ -129,6 +136,8 @@
       print('Finished in ${time.elapsed.inSeconds} seconds.\n');
       Map m = {'benchmark': benchmarkId, 'result': result.toJson()};
       print(json.encode(m));
+
+      await benchmark.oneTimeCleanup();
     } catch (error, st) {
       print('$benchmarkId threw exception: $error');
       print(st);
@@ -147,6 +156,12 @@
 
   Benchmark(this.id, this.description, {this.enabled: true, this.kind: 'cpu'});
 
+  bool get needsSetup => false;
+
+  Future oneTimeSetup() => new Future.value();
+
+  Future oneTimeCleanup() => new Future.value();
+
   Future<BenchMarkResult> run({
     bool quick: false,
     bool useCFE: false,
diff --git a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
index 7f54193..0058fdf 100644
--- a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
@@ -109,7 +109,7 @@
   static bool isFormat(String line) {
     List<String> fields = _parseFields(line);
     if (fields.length < 2) return false;
-    int timeStamp = int.parse(fields[0], onError: (_) => -1);
+    int timeStamp = int.tryParse(fields[0]) ?? -1;
     String opCode = fields[1];
     return timeStamp > 0 && opCode == 'Ver';
   }
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index a84e913..a04fb4a 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -174,10 +174,12 @@
 
   String portText = args[DIAGNOSTIC_PORT_OPTION];
   if (portText != null) {
-    perfArgs.diagnosticPort = int.parse(portText, onError: (s) {
-      print('invalid $DIAGNOSTIC_PORT_OPTION: $s');
+    if (int.tryParse(portText) == null) {
+      print('invalid $DIAGNOSTIC_PORT_OPTION: $portText');
       showHelp = true;
-    });
+    } else {
+      perfArgs.diagnosticPort = int.tryParse(portText);
+    }
   }
 
   if (args[VERY_VERBOSE_CMDLINE_OPTION] || rawArgs.contains('-vv')) {
diff --git a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart b/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
deleted file mode 100644
index fb60e43..0000000
--- a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:args/args.dart';
-import 'package:test/test.dart';
-
-import 'performance_tests.dart';
-
-/**
- * Pass in the directory of the source to be analyzed as option `--source`,
- * optionally specify a priority file with `--priority` and the specific
- * test to run with `--metric`.  If no test is specified, the default is
- * `analysis`.
- */
-main(List<String> arguments) {
-  ArgParser parser = _createArgParser();
-  var args = parser.parse(arguments);
-  if (args[SOURCE_OPTION] == null) {
-    print('path to source directory must be specified');
-    exit(1);
-  }
-  source = args[SOURCE_OPTION];
-  priorityFile = args[PRIORITY_FILE_OPTION];
-  List names = args[METRIC_NAME_OPTION] as List;
-  for (var name in names) {
-    metricNames.add(name as String);
-  }
-
-  var test;
-
-  if (metricNames.isEmpty) {
-    test = new AnalysisTimingTest();
-  } else {
-    test = new SubscriptionTimingTest();
-  }
-
-  Future.wait(<Future>[test.test_timing()]);
-}
-
-const DEFAULT_METRIC = 'analysis';
-const METRIC_NAME_OPTION = 'metric';
-const PRIORITY_FILE_OPTION = 'priority';
-const SOURCE_OPTION = 'source';
-
-final metricNames = <String>[];
-String priorityFile;
-String source;
-
-ArgParser _createArgParser() => new ArgParser()
-  ..addMultiOption(METRIC_NAME_OPTION,
-      help: 'metric name (defaults to `analysis`)')
-  ..addOption(SOURCE_OPTION, help: 'full path to source directory for analysis')
-  ..addOption(PRIORITY_FILE_OPTION,
-      help: '(optional) full path to a priority file');
-
-/**
- * AnalysisTimingTest measures the time taken by the analysis server to fully analyze
- * the given directory. Measurement is started after setting the analysis root, and
- * analysis is considered complete on receiving the `"isAnalyzing": false` message
- * from the analysis server.
- */
-class AnalysisTimingTest extends AbstractTimingTest {
-  Future test_timing() async {
-    // Set root after subscribing to avoid empty notifications.
-    await init(source);
-
-    setAnalysisRoot();
-    stopwatch.start();
-    await analysisFinished;
-    print('analysis completed in ${stopwatch.elapsed}');
-
-    await shutdown();
-  }
-}
-
-class Metric {
-  List<Duration> timings = <Duration>[];
-  Stream eventStream;
-  AnalysisService service;
-  String name;
-  Metric(this.name, this.service, this.eventStream);
-  String toString() => '$name: $service, ${eventStream.runtimeType}, $timings';
-}
-
-/**
- * SubscriptionTimingTest measures the time taken by the analysis server to return
- * information for navigation, semantic highlighting, outline, get occurrences,
- * overrides, folding and implemented. These timings are wrt to the specified priority file
- * - the file that is currently opened and has focus in the editor. Measure the time from
- * when the client subscribes for the notifications till there is a response from the server.
- * Does not wait for analysis to be complete before subscribing for notifications.
- */
-class SubscriptionTimingTest extends AbstractTimingTest {
-  List<Metric> _metrics;
-
-  List<Metric> get metrics => _metrics ??= metricNames.map(getMetric).toList();
-
-  Metric getMetric(String name) {
-    switch (name) {
-      case 'folding':
-        return new Metric(name, AnalysisService.FOLDING, onAnalysisFolding);
-      case 'highlighting':
-        return new Metric(
-            name, AnalysisService.HIGHLIGHTS, onAnalysisHighlights);
-      case 'implemented':
-        return new Metric(
-            name, AnalysisService.IMPLEMENTED, onAnalysisImplemented);
-      case 'navigation':
-        return new Metric(
-            name, AnalysisService.NAVIGATION, onAnalysisNavigation);
-      case 'outline':
-        return new Metric(name, AnalysisService.OUTLINE, onAnalysisOutline);
-      case 'occurences':
-        return new Metric(
-            name, AnalysisService.OCCURRENCES, onAnalysisOccurrences);
-      case 'overrides':
-        return new Metric(name, AnalysisService.OVERRIDES, onAnalysisOverrides);
-    }
-    print('no metric found for $name');
-    exit(1);
-    return null; // Won't get here.
-  }
-
-  Future test_timing() async {
-//   debugStdio();
-
-    expect(metrics, isNotEmpty);
-    expect(priorityFile, isNotNull,
-        reason: 'A priority file must be specified for '
-            '${metrics.first.name} testing.');
-
-    await init(source);
-    stopwatch.start();
-
-    metrics.forEach((Metric m) => m.eventStream.listen((_) {
-          m.timings.add(
-              new Duration(milliseconds: stopwatch.elapsed.inMilliseconds));
-        }));
-
-    var subscriptions = <AnalysisService, List<String>>{};
-    metrics.forEach((Metric m) => subscriptions[m.service] = [priorityFile]);
-
-    sendAnalysisSetSubscriptions(subscriptions);
-
-    // Set root after subscribing to avoid empty notifications.
-    setAnalysisRoot();
-
-    sendAnalysisSetPriorityFiles([priorityFile]);
-
-    await analysisFinished;
-    print('analysis completed in ${stopwatch.elapsed}');
-    metrics.forEach((Metric m) => print('${m.name} timings: ${m.timings}'));
-
-    await shutdown();
-  }
-}
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_angular.dart b/pkg/analysis_server/benchmark/perf/benchmark_angular.dart
deleted file mode 100644
index c93138d..0000000
--- a/pkg/analysis_server/benchmark/perf/benchmark_angular.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2016, 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 'benchmark_scenario.dart';
-import 'memory_tests.dart';
-
-main(List<String> args) async {
-  int length = args.length;
-  if (length < 1) {
-    print(
-        'Usage: dart benchmark_local.dart path_to_np8080 (an example ngdart project)'
-        ' [benchmark_id]');
-    return;
-  }
-  paths = new PathHolder(projectPath: args[0]);
-  String id = args.length >= 2 ? args[1] : null;
-  if (id == null) {
-    for (String id in benchmarks.keys) {
-      BenchmarkFunction benchmark = benchmarks[id];
-      await benchmark(id);
-    }
-  } else {
-    BenchmarkFunction benchmark = benchmarks[id];
-    if (benchmark != null) {
-      benchmark(id);
-    }
-  }
-}
-
-const Map<String, BenchmarkFunction> benchmarks =
-    const <String, BenchmarkFunction>{
-  'ng-initialAnalysis': run_ng_initialAnalysis,
-  'ng-change-dart': run_ng_change_dart,
-  'ng-change-html': run_ng_change_html,
-  'ng-memory-initialAnalysis': run_ng_memory_initialAnalysis,
-};
-
-PathHolder paths;
-
-Future run_ng_change_dart(String id) async {
-  String description = r'''
-1. Open 'packages/np8080'.
-2. Add an @Output to the class
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
-      roots: [paths.packageNp8080],
-      file: paths.editorDart,
-      fileChange: new FileChange(
-          afterStr: 'showPreview = false;',
-          insertStr: '@Output() EventEmitter<int> myEventEmitter;'),
-      numOfRepeats: 10);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_ng_change_html(String id) async {
-  String description = r'''
-1. Open 'packages/np8080'.
-2. Change the contents of a mustache
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
-      roots: [paths.packageNp8080],
-      file: paths.editorHtml,
-      fileChange: new FileChange(
-          afterStr: 'note.lastModified', afterStrBack: 4, insertStr: 'NewName'),
-      numOfRepeats: 4);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_ng_initialAnalysis(String id) async {
-  String description = r'''
-1. Start server, set 'package/np8080' analysis roots.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
-      roots: [paths.packageNp8080], numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_ng_memory_initialAnalysis(String id) async {
-  String description = r'''
-1. Start server, set 'package/np8080' as the analysis root.
-2. Measure the memory usage after finishing initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> sizes = await AnalysisServerMemoryUsageTest
-      .start_waitInitialAnalysis_shutdown(
-          roots: <String>[paths.packageNp8080], numOfRepeats: 3);
-  printMemoryResults(id, description, sizes);
-}
-
-typedef BenchmarkFunction(String id);
-
-class PathHolder {
-  String editorHtml;
-  String editorDart;
-  String packageNp8080;
-
-  PathHolder({String projectPath}) {
-    editorHtml = '$projectPath/lib/editor/editor_component.html';
-    editorDart = '$projectPath/lib/editor/editor_component.dart';
-    packageNp8080 = projectPath;
-  }
-}
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart b/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart
deleted file mode 100644
index 2e47a2b..0000000
--- a/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright (c) 2016, 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:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-
-import 'benchmark_scenario.dart';
-import 'memory_tests.dart';
-
-main(List<String> args) async {
-  int length = args.length;
-  if (length < 1) {
-    print('Usage: dart benchmark_local.dart path_to_flutter_checkout'
-        ' [benchmark_id]');
-    return;
-  }
-  paths = new PathHolder(flutterPath: args[0]);
-  String id = args.length >= 2 ? args[1] : null;
-  if (id == null) {
-    for (String id in benchmarks.keys) {
-      BenchmarkFunction benchmark = benchmarks[id];
-      await benchmark(id);
-    }
-  } else {
-    BenchmarkFunction benchmark = benchmarks[id];
-    if (benchmark != null) {
-      benchmark(id);
-    }
-  }
-}
-
-const Map<String, BenchmarkFunction> benchmarks =
-    const <String, BenchmarkFunction>{
-  'flutter-initialAnalysis-1': run_flutter_initialAnalysis_1,
-  'flutter-initialAnalysis-2': run_flutter_initialAnalysis_2,
-  'flutter-change-1': run_flutter_change_1,
-  'flutter-change-2': run_flutter_change_2,
-  'flutter-completion-1': run_flutter_completion_1,
-  'flutter-completion-2': run_flutter_completion_2,
-  'flutter-refactoring-1': run_flutter_refactoring_1,
-  'flutter-memory-initialAnalysis-1': run_flutter_memory_initialAnalysis_1,
-  'flutter-memory-initialAnalysis-2': run_flutter_memory_initialAnalysis_2,
-};
-
-PathHolder paths;
-
-Future run_flutter_change_1(String id) async {
-  String description = r'''
-1. Open 'packages/flutter'.
-2. Change a method body in lib/src/painting/colors.dart
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
-      roots: [paths.packageFlutter],
-      file: '${paths.packageFlutter}/lib/src/painting/colors.dart',
-      fileChange: new FileChange(
-          afterStr: 'final double h = hue % 360;', insertStr: 'print(12345);'),
-      numOfRepeats: 10);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_change_2(String id) async {
-  String description = r'''
-1. Open 'packages/flutter'.
-2. Change the name of a public method in lib/src/painting/colors.dart
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
-      roots: [paths.packageFlutter],
-      file: '${paths.packageFlutter}/lib/src/painting/colors.dart',
-      fileChange: new FileChange(
-          afterStr: 'withValue(dou', afterStrBack: 4, insertStr: 'NewName'),
-      numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_completion_1(String id) async {
-  String description = r'''
-1. Open 'packages/flutter'.
-2. Change a method body in packages/flutter/lib/src/material/button.dart
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  String completionMarker = 'print(12345);';
-  List<int> times = await new BenchmarkScenario()
-      .waitAnalyze_change_getCompletion(
-          roots: [paths.packageFlutter],
-          file: '${paths.packageFlutter}/lib/src/material/button.dart',
-          fileChange: new FileChange(
-              afterStr: 'Widget build(BuildContext context) {',
-              insertStr: completionMarker),
-          completeAfterStr: completionMarker,
-          numOfRepeats: 10);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_completion_2(String id) async {
-  String description = r'''
-1. Open 'packages/flutter'.
-2. Change the name of a public method in lib/src/rendering/layer.dart
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario()
-      .waitAnalyze_change_getCompletion(
-          roots: [paths.packageFlutter],
-          file: '${paths.packageFlutter}/lib/src/rendering/layer.dart',
-          fileChange: new FileChange(
-              replaceWhat: 'void removeAllChildren() {',
-              replaceWith: 'void removeAllChildren2() {print(12345);parent.'),
-          completeAfterStr: 'print(12345);parent.',
-          numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_initialAnalysis_1(String id) async {
-  String description = r'''
-1. Start server, set 'hello_world' analysis root.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
-      roots: [paths.exampleHelloWorld], numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_initialAnalysis_2(String id) async {
-  String description = r'''
-1. Start server, set 'hello_world' and 'flutter_gallery' analysis roots.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
-      roots: [paths.exampleHelloWorld, paths.exampleGallery], numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_memory_initialAnalysis_1(String id) async {
-  String description = r'''
-1. Start server, set 'packages/flutter' as the analysis root.
-2. Measure the memory usage after finishing initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> sizes = await AnalysisServerMemoryUsageTest
-      .start_waitInitialAnalysis_shutdown(
-          roots: <String>[paths.packageFlutter], numOfRepeats: 3);
-  printMemoryResults(id, description, sizes);
-}
-
-Future run_flutter_memory_initialAnalysis_2(String id) async {
-  String description = r'''
-1. Start server, set 'packages/flutter' and 'packages/flutter_markdown' analysis roots.
-2. Measure the memory usage after finishing initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> sizes = await AnalysisServerMemoryUsageTest
-      .start_waitInitialAnalysis_shutdown(
-          roots: <String>[paths.packageFlutter, paths.packageMarkdown],
-          numOfRepeats: 3);
-  printMemoryResults(id, description, sizes);
-}
-
-Future run_flutter_refactoring_1(String id) async {
-  String description = r'''
-1. Open 'packages/flutter'.
-2. Change the name of a public method in lib/src/rendering/layer.dart
-3. Request rename refactoring for `getSourcesWithFullName` and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario()
-      .waitAnalyze_change_getRefactoring(
-          roots: [paths.packageFlutter],
-          file: '${paths.packageFlutter}/lib/src/rendering/layer.dart',
-          fileChange: new FileChange(
-              replaceWhat: 'void removeAllChildren() {',
-              replaceWith: 'void removeAllChildren2() {'),
-          refactoringAtStr: 'addToScene(ui.SceneBuilder builder',
-          refactoringKind: RefactoringKind.RENAME,
-          refactoringOptions: new RenameOptions('addToScene2'),
-          numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-typedef BenchmarkFunction(String id);
-
-class PathHolder {
-  String exampleHelloWorld;
-  String exampleGallery;
-  String exampleStocks;
-  String packageFlutter;
-  String packageMarkdown;
-  String packageSprites;
-
-  PathHolder({String flutterPath}) {
-    exampleHelloWorld = '$flutterPath/examples/hello_world';
-    exampleGallery = '$flutterPath/examples/flutter_gallery';
-    exampleStocks = '$flutterPath/examples/stocks';
-    packageFlutter = '$flutterPath/packages/flutter';
-    packageMarkdown = '$flutterPath/packages/flutter_markdown';
-    packageSprites = '$flutterPath/packages/flutter_sprites';
-  }
-}
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart b/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
deleted file mode 100644
index 930bc0e..0000000
--- a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 2016, 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:math';
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-
-import '../../test/integration/support/integration_tests.dart';
-import 'performance_tests.dart';
-
-void printBenchmarkResults(String id, String description, List<int> times) {
-  int minTime = times.fold(1 << 20, min);
-  String now = new DateTime.now().toUtc().toIso8601String();
-  print('$now ========== $id');
-  print('times: $times');
-  print('min_time: $minTime');
-  print(description.trim());
-  print('--------------------');
-  print('');
-  print('');
-}
-
-class BenchmarkScenario extends AbstractTimingTest {
-  /**
-   * Init.
-   *  - Start Analysis Server.
-   *  - Set the analysis [roots].
-   *  - Wait for analysis to complete.
-   *  - Make [file] the priority file.
-   *
-   * Measurement.
-   *  - Change the [file] according to the [fileChange].
-   *  - Record the time to finish analysis.
-   *
-   * Repeat.
-   *  - Undo changes to the [file].
-   *  - Repeat measurement [numOfRepeats] times.
-   */
-  Future<List<int>> waitAnalyze_change_analyze(
-      {List<String> roots,
-      String file,
-      FileChange fileChange,
-      int numOfRepeats}) async {
-    outOfTestExpect(roots, isNotNull, reason: 'roots');
-    outOfTestExpect(file, isNotNull, reason: 'file');
-    outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
-    outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
-    // Initialize Analysis Server.
-    await super.setUp();
-    await subscribeToStatusNotifications();
-    // Set roots and analyze.
-    await sendAnalysisSetAnalysisRoots(roots, []);
-    await analysisFinished;
-    // Make the file priority.
-    await sendAnalysisSetPriorityFiles([file]);
-    // Repeat.
-    List<int> times = <int>[];
-    for (int i = 0; i < numOfRepeats; i++) {
-      // Update and wait for analysis.
-      Stopwatch stopwatch = new Stopwatch()..start();
-      await _applyFileChange(file, fileChange);
-      await analysisFinished;
-      times.add(stopwatch.elapsed.inMilliseconds);
-      // Remove the overlay and analyze.
-      await sendAnalysisUpdateContent({file: new RemoveContentOverlay()});
-      await analysisFinished;
-    }
-    // Done.
-    await shutdown();
-    return times;
-  }
-
-  /**
-   * Init.
-   * 1. Start Analysis Server.
-   * 2. Set the analysis [roots].
-   * 3. Wait for analysis to complete.
-   * 4. Make [file] the priority file.
-   *
-   * Measurement.
-   * 5. Change the [file] according to the [fileChange].
-   * 6. Request [completeAfterStr] in the updated file content.
-   * 7. Record the time to get completion results.
-   * 8. Undo changes to the [file] and analyze.
-   * 9. Go to (5).
-   */
-  Future<List<int>> waitAnalyze_change_getCompletion(
-      {List<String> roots,
-      String file,
-      FileChange fileChange,
-      String completeAfterStr,
-      int numOfRepeats}) async {
-    outOfTestExpect(roots, isNotNull, reason: 'roots');
-    outOfTestExpect(file, isNotNull, reason: 'file');
-    outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
-    outOfTestExpect(completeAfterStr, isNotNull, reason: 'completeAfterStr');
-    outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
-    // Initialize Analysis Server.
-    await super.setUp();
-    await subscribeToStatusNotifications();
-    // Set roots and analyze.
-    await sendAnalysisSetAnalysisRoots(roots, []);
-    await analysisFinished;
-    // Make the file priority.
-    await sendAnalysisSetPriorityFiles([file]);
-    // Repeat.
-    List<int> times = <int>[];
-    for (int i = 0; i < numOfRepeats; i++) {
-      String updatedContent = await _applyFileChange(file, fileChange);
-      // Measure completion time.
-      int completionOffset =
-          _indexOfEnd(file, updatedContent, completeAfterStr);
-      Duration completionDuration =
-          await _measureCompletionTime(file, completionOffset);
-      times.add(completionDuration.inMilliseconds);
-      // Remove the overlay and analyze.
-      await sendAnalysisUpdateContent({file: new RemoveContentOverlay()});
-      await analysisFinished;
-    }
-    // Done.
-    await shutdown();
-    return times;
-  }
-
-  /**
-   * Init.
-   * 1. Start Analysis Server.
-   * 2. Set the analysis [roots].
-   * 3. Wait for analysis to complete.
-   * 4. Make [file] the priority file.
-   *
-   * Measurement.
-   * 5. Change the [file] according to the [fileChange].
-   * 6. Request [refactoringAtStr] in the updated file content.
-   * 7. Record the time to get refactoring.
-   * 8. Undo changes to the [file] and analyze.
-   * 9. Go to (5).
-   */
-  Future<List<int>> waitAnalyze_change_getRefactoring(
-      {List<String> roots,
-      String file,
-      FileChange fileChange,
-      String refactoringAtStr,
-      RefactoringKind refactoringKind,
-      RefactoringOptions refactoringOptions,
-      int numOfRepeats}) async {
-    outOfTestExpect(roots, isNotNull, reason: 'roots');
-    outOfTestExpect(file, isNotNull, reason: 'file');
-    outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
-    outOfTestExpect(refactoringAtStr, isNotNull, reason: 'refactoringAtStr');
-    outOfTestExpect(refactoringKind, isNotNull, reason: 'refactoringKind');
-    outOfTestExpect(refactoringOptions, isNotNull,
-        reason: 'refactoringOptions');
-    outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
-    // Initialize Analysis Server.
-    await super.setUp();
-    await subscribeToStatusNotifications();
-    // Set roots and analyze.
-    await sendAnalysisSetAnalysisRoots(roots, []);
-    await analysisFinished;
-    // Make the file priority.
-    await sendAnalysisSetPriorityFiles([file]);
-    // Repeat.
-    List<int> times = <int>[];
-    for (int i = 0; i < numOfRepeats; i++) {
-      String updatedContent = await _applyFileChange(file, fileChange);
-      // Measure time to get refactoring.
-      int refactoringOffset = _indexOf(file, updatedContent, refactoringAtStr);
-      Duration refactoringDuration = await _measureRefactoringTime(
-          file, refactoringOffset, refactoringKind, refactoringOptions);
-      times.add(refactoringDuration.inMilliseconds);
-      // Remove the overlay and analyze.
-      await sendAnalysisUpdateContent({file: new RemoveContentOverlay()});
-      await analysisFinished;
-    }
-    // Done.
-    await shutdown();
-    return times;
-  }
-
-  /**
-   * Compute updated content of the [file] as described by [desc], add overlay
-   * for the [file], and return the updated content.
-   */
-  Future<String> _applyFileChange(String file, FileChange desc) async {
-    String originalContent = _getFileContent(file);
-    String updatedContent;
-    if (desc.afterStr != null) {
-      int offset = _indexOfEnd(file, originalContent, desc.afterStr);
-      offset -= desc.afterStrBack;
-      updatedContent = originalContent.substring(0, offset) +
-          desc.insertStr +
-          originalContent.substring(offset);
-    } else if (desc.replaceWhat != null) {
-      int offset = _indexOf(file, originalContent, desc.replaceWhat);
-      updatedContent = originalContent.substring(0, offset) +
-          desc.replaceWith +
-          originalContent.substring(offset + desc.replaceWhat.length);
-    }
-    await sendAnalysisUpdateContent(
-        {file: new AddContentOverlay(updatedContent)});
-    return updatedContent;
-  }
-
-  Future<Duration> _measureCompletionTime(String file, int offset) async {
-    Stopwatch stopwatch = new Stopwatch();
-    stopwatch.start();
-    Completer<Duration> completer = new Completer<Duration>();
-    var completionSubscription = onCompletionResults.listen((_) {
-      completer.complete(stopwatch.elapsed);
-    });
-    try {
-      await sendCompletionGetSuggestions(file, offset);
-      return await completer.future;
-    } finally {
-      completionSubscription.cancel();
-    }
-  }
-
-  Future<Duration> _measureRefactoringTime(
-      String file,
-      int offset,
-      RefactoringKind refactoringKind,
-      RefactoringOptions refactoringOptions) async {
-    Stopwatch stopwatch = new Stopwatch();
-    stopwatch.start();
-    await sendEditGetRefactoring(refactoringKind, file, offset, 0, false,
-        options: refactoringOptions);
-    return stopwatch.elapsed;
-  }
-
-  /**
-   *  1. Start Analysis Server.
-   *  2. Set the analysis [roots].
-   *  3. Wait for analysis to complete.
-   *  4. Record the time to finish analysis.
-   *  5. Shutdown.
-   *  6. Go to (1).
-   */
-  static Future<List<int>> start_waitInitialAnalysis_shutdown(
-      {List<String> roots, int numOfRepeats}) async {
-    outOfTestExpect(roots, isNotNull, reason: 'roots');
-    outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
-    // Repeat.
-    List<int> times = <int>[];
-    for (int i = 0; i < numOfRepeats; i++) {
-      BenchmarkScenario instance = new BenchmarkScenario();
-      // Initialize Analysis Server.
-      await instance.setUp();
-      await instance.subscribeToStatusNotifications();
-      // Set roots and analyze.
-      Stopwatch stopwatch = new Stopwatch()..start();
-      await instance.sendAnalysisSetAnalysisRoots(roots, []);
-      await instance.analysisFinished;
-      times.add(stopwatch.elapsed.inMilliseconds);
-      // Stop the server.
-      await instance.shutdown();
-    }
-    return times;
-  }
-
-  static String _getFileContent(String path) {
-    File file = new File(path);
-    outOfTestExpect(file.existsSync(), isTrue,
-        reason: 'File $path does not exist.');
-    return file.readAsStringSync();
-  }
-
-  /**
-   * Return the index of [what] in [where] in the [file], fail if not found.
-   */
-  static int _indexOf(String file, String where, String what) {
-    int index = where.indexOf(what);
-    outOfTestExpect(index, isNot(-1), reason: 'Cannot find |$what| in $file.');
-    return index;
-  }
-
-  /**
-   * Return the end index if [what] in [where] in the [file], fail if not found.
-   */
-  static int _indexOfEnd(String file, String where, String what) {
-    return _indexOf(file, where, what) + what.length;
-  }
-}
-
-class FileChange {
-  final String afterStr;
-  final int afterStrBack;
-  final String insertStr;
-  final String replaceWhat;
-  final String replaceWith;
-
-  FileChange(
-      {this.afterStr,
-      this.afterStrBack: 0,
-      this.insertStr,
-      this.replaceWhat,
-      this.replaceWith}) {
-    if (afterStr != null) {
-      outOfTestExpect(insertStr, isNotNull, reason: 'insertStr');
-    } else if (replaceWhat != null) {
-      outOfTestExpect(replaceWith, isNotNull, reason: 'replaceWith');
-    }
-  }
-}
diff --git a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
deleted file mode 100644
index 0a12041..0000000
--- a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:test/test.dart';
-
-import 'performance_tests.dart';
-
-const COMPLETION_OFFSET = 'offset';
-const PRIORITY_FILE_OPTION = 'priority';
-const SOURCE_OPTION = 'source';
-
-/**
- * Pass in the directory of the source to be analyzed as option `--source`,
- * specify a priority file with `--priority` and an offset for completions
- * with a `--offset`.
- */
-main(List<String> arguments) async {
-  ArgParser parser = _createArgParser();
-  var args = parser.parse(arguments);
-  if (args[SOURCE_OPTION] == null) {
-    print('path to source directory must be specified');
-    exit(1);
-  }
-
-  int offset = int.parse(args[COMPLETION_OFFSET]);
-  String priorityFile = args[PRIORITY_FILE_OPTION];
-  String source = args[SOURCE_OPTION];
-
-  CompletionTimingTest test =
-      new CompletionTimingTest(offset, priorityFile, source);
-  await test.test_timing();
-}
-
-ArgParser _createArgParser() => new ArgParser()
-  ..addOption(SOURCE_OPTION, help: 'full path to source directory for analysis')
-  ..addOption(PRIORITY_FILE_OPTION, help: 'full path to a priority file')
-  ..addOption(COMPLETION_OFFSET, help: 'offset in file for code completions');
-
-/**
- * CompletionTimingTest measures the time taken for the analysis server to respond with
- * completion suggestions for a given file and offset. The time measured starts when
- * the analysis root is set and is done when the completion suggestions are received
- * from the server. The test does not wait for analysis to be complete before asking for
- * completions.
- */
-class CompletionTimingTest extends AbstractTimingTest {
-  final int offset;
-  final String priorityFile;
-  final String source;
-
-  List<Duration> timings = <Duration>[];
-
-  CompletionTimingTest(this.offset, this.priorityFile, this.source);
-
-  Future test_timing() async {
-//    debugStdio();
-
-    expect(priorityFile, isNotNull,
-        reason: 'A priority file must be specified for completion testing.');
-    expect(offset, isNotNull,
-        reason: 'An offset must be specified for completion testing.');
-
-    await init(source);
-    stopwatch.start();
-
-    onCompletionResults.listen((_) {
-      timings.add(new Duration(milliseconds: stopwatch.elapsed.inMilliseconds));
-    });
-
-    setAnalysisRoot();
-    sendAnalysisSetPriorityFiles([priorityFile]);
-    sendCompletionGetSuggestions(priorityFile, offset);
-
-    await analysisFinished;
-
-    print('analysis completed in ${stopwatch.elapsed}');
-    print('completion received at : $timings');
-    await shutdown();
-  }
-}
diff --git a/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
new file mode 100644
index 0000000..620c032
--- /dev/null
+++ b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
@@ -0,0 +1,119 @@
+// 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 'package:path/path.dart' as path;
+
+import '../benchmarks.dart';
+
+/// benchmarks:
+///   - analysis-flutter-analyze
+class FlutterAnalyzeBenchmark extends Benchmark {
+  FlutterAnalyzeBenchmark()
+      : super(
+          'analysis-flutter-analyze',
+          "Clone the flutter/flutter repo and run "
+              "'flutter analyze --flutter-repo' with the current Dart VM and "
+              "analysis server.",
+          kind: 'cpu',
+        );
+
+  bool get needsSetup => true;
+
+  Directory flutterDir;
+
+  Future oneTimeSetup() async {
+    flutterDir = Directory.systemTemp.createTempSync('flutter');
+
+    // git clone https://github.com/flutter/flutter $flutterDir
+    await _runProcess('git', [
+      'clone',
+      'https://github.com/flutter/flutter',
+      path.canonicalize(flutterDir.path)
+    ]);
+
+    String flutterTool = path.join(flutterDir.path, 'bin', 'flutter');
+
+    // flutter --version
+    await _runProcess(flutterTool, ['--version'], cwd: flutterDir.path);
+
+    // flutter precache
+    await _runProcess(flutterTool, ['precache'], cwd: flutterDir.path);
+
+    // flutter update-packages
+    await _runProcess(flutterTool, ['update-packages'], cwd: flutterDir.path);
+  }
+
+  Future oneTimeCleanup() {
+    try {
+      flutterDir.deleteSync(recursive: true);
+    } on FileSystemException catch (e) {
+      print(e);
+    }
+
+    return new Future.value();
+  }
+
+  int get maxIterations => 3;
+
+  @override
+  Future<BenchMarkResult> run({
+    bool quick: false,
+    bool useCFE: false,
+    bool verbose: false,
+  }) async {
+    if (!quick) {
+      deleteServerCache();
+    }
+
+    final Stopwatch stopwatch = new Stopwatch()..start();
+
+    await _runProcess(
+      Platform.resolvedExecutable,
+      [
+        'packages/flutter_tools/bin/flutter_tools.dart',
+        'analyze',
+        '--flutter-repo',
+      ],
+      cwd: flutterDir.path,
+      failOnError: false,
+    );
+
+    stopwatch.stop();
+
+    return new BenchMarkResult('micros', stopwatch.elapsedMicroseconds);
+  }
+}
+
+Future<int> _runProcess(
+  String command,
+  List<String> args, {
+  String cwd,
+  bool failOnError = true,
+}) async {
+  print('\n$command ${args.join(' ')}');
+
+  Process process = await Process.start(command, args, workingDirectory: cwd);
+
+  process.stdout
+      .transform(utf8.decoder)
+      .transform(new LineSplitter())
+      .listen((line) {
+    print('  $line');
+  });
+  process.stderr
+      .transform(utf8.decoder)
+      .transform(new LineSplitter())
+      .listen((line) => print('  $line'));
+
+  int exitCode = await process.exitCode;
+  if (exitCode != 0 && failOnError) {
+    throw '$command exited with $exitCode';
+  }
+
+  return exitCode;
+}
diff --git a/pkg/analysis_server/benchmark/perf/performance_tests.dart b/pkg/analysis_server/benchmark/perf/performance_tests.dart
deleted file mode 100644
index 540678c..0000000
--- a/pkg/analysis_server/benchmark/perf/performance_tests.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:test/test.dart';
-
-import '../../test/integration/support/integration_tests.dart';
-
-/**
- * Base class for analysis server performance tests.
- */
-abstract class AbstractAnalysisServerPerformanceTest
-    extends AbstractAnalysisServerIntegrationTest {
-  /**
-   * Stopwatch for timing results;
-   */
-  Stopwatch stopwatch = new Stopwatch();
-
-  /**
-   * Send the server an 'analysis.setAnalysisRoots' command directing it to
-   * analyze [sourceDirectory].
-   */
-  Future setAnalysisRoot() =>
-      sendAnalysisSetAnalysisRoots([sourceDirectory.path], []);
-
-  /**
-   * The server is automatically started before every test.
-   */
-  @override
-  Future setUp() {
-    onAnalysisErrors.listen((AnalysisErrorsParams params) {
-      currentAnalysisErrors[params.file] = params.errors;
-    });
-    onServerError.listen((ServerErrorParams params) {
-      // A server error should never happen during an integration test.
-      fail('${params.message}\n${params.stackTrace}');
-    });
-    Completer serverConnected = new Completer();
-    onServerConnected.listen((_) {
-      outOfTestExpect(serverConnected.isCompleted, isFalse);
-      serverConnected.complete();
-    });
-    return startServer(checked: false).then((_) {
-      server.listenToOutput(dispatchNotification);
-      server.exitCode.then((_) {
-        skipShutdown = true;
-      });
-      return serverConnected.future;
-    });
-  }
-
-  /**
-   * After every test, the server is stopped.
-   */
-  Future shutdown() async => await shutdownIfNeeded();
-
-  /**
-   * Enable [ServerService.STATUS] notifications so that [analysisFinished]
-   * can be used.
-   */
-  Future subscribeToStatusNotifications() async {
-    await sendServerSetSubscriptions([ServerService.STATUS]);
-  }
-}
-
-class AbstractTimingTest extends AbstractAnalysisServerPerformanceTest {
-  Future init(String source) async {
-    await super.setUp();
-    sourceDirectory = new Directory(source);
-    return subscribeToStatusNotifications();
-  }
-}
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index e050dc0..23bda67 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  1.20.0
+  1.20.1
 </h1>
 <p>
   This document contains a specification of the API provided by the
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 703297c..9b4578e 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -43,7 +43,6 @@
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
 import 'package:analysis_server/src/utilities/null_string_sink.dart';
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/exception/exception.dart';
@@ -51,8 +50,8 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
@@ -64,6 +63,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/util/glob.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
@@ -108,7 +108,7 @@
    * The version of the analysis server. The value should be replaced
    * automatically during the build.
    */
-  static final String VERSION = '1.20.0';
+  static final String VERSION = '1.20.1';
 
   /**
    * The options of this server instance.
diff --git a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
index 15fe295..d1fe2d4 100644
--- a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -53,6 +54,8 @@
 
   _DartUnitClosingLabelsComputerVisitor(this.computer);
 
+  ClosingLabel get _currentLabel => labelStack.isEmpty ? null : labelStack.last;
+
   @override
   Object visitInstanceCreationExpression(InstanceCreationExpression node) {
     ClosingLabel label;
@@ -117,9 +120,9 @@
 
     checkLinesUsing = checkLinesUsing ?? node;
 
-    final LineInfo_Location start =
+    final CharacterLocation start =
         computer._lineInfo.getLocation(checkLinesUsing.offset);
-    final LineInfo_Location end =
+    final CharacterLocation end =
         computer._lineInfo.getLocation(checkLinesUsing.end - 1);
 
     final ClosingLabel closingLabel =
@@ -141,13 +144,11 @@
     return closingLabel;
   }
 
-  void _pushLabel(ClosingLabel label) {
-    labelStack.add(label);
-  }
-
-  ClosingLabel get _currentLabel => labelStack.isEmpty ? null : labelStack.last;
-
   void _popLabel() {
     labelStack.removeLast();
   }
+
+  void _pushLabel(ClosingLabel label) {
+    labelStack.add(label);
+  }
 }
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 0508fa7..3516bbe 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart' as engine;
 import 'package:analyzer/dart/element/type.dart' as engine;
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
@@ -106,7 +107,7 @@
   }
 
   Location _getLocationOffsetLength(int offset, int length) {
-    LineInfo_Location lineLocation = lineInfo.getLocation(offset);
+    CharacterLocation lineLocation = lineInfo.getLocation(offset);
     int startLine = lineLocation.lineNumber;
     int startColumn = lineLocation.columnNumber;
     return new Location(file, offset, length, startLine, startColumn);
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 84d9d18..a1ad9b6 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -8,18 +8,14 @@
 import 'dart:core';
 
 import 'package:analysis_server/src/plugin/notification_manager.dart';
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
-import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/source/path_filter.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
-import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
@@ -30,6 +26,10 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/pubspec/pubspec_validator.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/path_filter.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
+import 'package:analyzer/src/source/sdk_ext.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:analyzer/src/util/glob.dart';
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 64878c1..22b7f36 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -561,6 +561,18 @@
     int length = params.length;
     // add refactoring kinds
     List<RefactoringKind> kinds = <RefactoringKind>[];
+    // Try EXTRACT_WIDGETS.
+    {
+      var unit = await server.getResolvedCompilationUnit(file);
+      var analysisSession = server.getAnalysisDriver(file)?.currentSession;
+      if (unit != null && analysisSession != null) {
+        var refactoring = new ExtractWidgetRefactoring(
+            searchEngine, analysisSession, unit, offset);
+        if (refactoring.isAvailable()) {
+          kinds.add(RefactoringKind.EXTRACT_WIDGET);
+        }
+      }
+    }
     // try EXTRACT_*
     if (length != 0) {
       kinds.add(RefactoringKind.EXTRACT_LOCAL_VARIABLE);
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index 36980eb..4686b23 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -8,10 +8,10 @@
 import 'dart:io' show Platform, Process, ProcessResult;
 
 import 'package:analysis_server/src/plugin/notification_manager.dart';
-import 'package:analyzer/context/context_root.dart' as analyzer;
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/context/context_root.dart' as analyzer;
 import 'package:analyzer/src/generated/bazel.dart';
 import 'package:analyzer/src/generated/gn.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -303,6 +303,11 @@
       <PluginInfo, Map<String, List<int>>>{};
 
   /**
+   * The console environment key used by the pub tool.
+   */
+  static const String _pubEnvironmentKey = 'PUB_ENVIRONMENT';
+
+  /**
    * The resource provider used to access the file system.
    */
   final ResourceProvider resourceProvider;
@@ -834,11 +839,6 @@
   }
 
   /**
-   * The console environment key used by the pub tool.
-   */
-  static const String _pubEnvironmentKey = 'PUB_ENVIRONMENT';
-
-  /**
    * Returns the environment value that should be used when running pub.
    *
    * Includes any existing environment value, if one exists.
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
index 8de5ea2..5d050de 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
@@ -4,8 +4,8 @@
 
 import 'package:analysis_server/src/plugin/plugin_locator.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:front_end/src/base/source.dart';
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index a84b950..ca18225 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/error/error.dart' as engine;
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart' as engine;
 import 'package:analyzer/src/error/codes.dart' as engine;
 import 'package:analyzer/src/generated/engine.dart' as engine;
@@ -107,7 +108,7 @@
     int startLine = -1;
     int startColumn = -1;
     if (lineInfo != null) {
-      engine.LineInfo_Location lineLocation = lineInfo.getLocation(offset);
+      CharacterLocation lineLocation = lineInfo.getLocation(offset);
       if (lineLocation != null) {
         startLine = lineLocation.lineNumber;
         startColumn = lineLocation.columnNumber;
@@ -272,8 +273,7 @@
   try {
     engine.LineInfo lineInfo = unitElement.lineInfo;
     if (lineInfo != null) {
-      engine.LineInfo_Location offsetLocation =
-          lineInfo.getLocation(range.offset);
+      CharacterLocation offsetLocation = lineInfo.getLocation(range.offset);
       startLine = offsetLocation.lineNumber;
       startColumn = offsetLocation.columnNumber;
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index f0d5a9e..351c240 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -36,7 +36,7 @@
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
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 f7d3540..3cdcf21 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -16,7 +16,6 @@
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/utilities/flutter.dart' as flutter;
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -26,6 +25,7 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index 6a0010c..76d0115 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -145,6 +145,11 @@
   }
 
   @override
+  bool isAvailable() {
+    return !_checkSelection().hasFatalError;
+  }
+
+  @override
   bool requiresPreview() => false;
 
   /// Checks if [offset] is a widget creation expression that can be extracted.
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index 3fe03a8..96243dd 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -250,6 +250,12 @@
    * level of checking.
    */
   RefactoringStatus checkName();
+
+  /**
+   * Return `true` if refactoring is available, possibly without checking all
+   * initial conditions.
+   */
+  bool isAvailable();
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 4676e02..d138f3e 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -10,8 +10,8 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
 
 /**
  * Instances of the class [SocketServer] implement the common parts of
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 51249a4..b3050c4 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -20,11 +20,10 @@
 import 'package:analysis_server/src/status/element_writer.dart';
 import 'package:analysis_server/src/status/pages.dart';
 import 'package:analysis_server/src/utilities/profiling.dart';
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
@@ -36,6 +35,7 @@
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/source/sdk_ext.dart';
 import 'package:path/path.dart' as pathPackage;
 
 final String kCustomCss = '''
@@ -1200,6 +1200,52 @@
   }
 }
 
+class ServiceProtocol {
+  final WebSocket socket;
+
+  int _id = 0;
+  Map<String, Completer> _completers = {};
+
+  ServiceProtocol._(this.socket) {
+    socket.listen(_handleMessage);
+  }
+
+  Future<Map> call(String method, [Map args]) {
+    String id = '${++_id}';
+    Completer completer = new Completer();
+    _completers[id] = completer;
+    Map m = {'id': id, 'method': method};
+    if (args != null) m['params'] = args;
+    String message = jsonEncode(m);
+    socket.add(message);
+    return completer.future;
+  }
+
+  Future dispose() => socket.close();
+
+  void _handleMessage(dynamic message) {
+    if (message is! String) {
+      return;
+    }
+
+    try {
+      dynamic json = jsonDecode(message);
+      if (json.containsKey('id')) {
+        dynamic id = json['id'];
+        _completers[id]?.complete(json['result']);
+        _completers.remove(id);
+      }
+    } catch (e) {
+      // ignore
+    }
+  }
+
+  static Future<ServiceProtocol> connect(Uri uri) async {
+    WebSocket socket = await WebSocket.connect(uri.toString());
+    return new ServiceProtocol._(socket);
+  }
+}
+
 class StatusPage extends DiagnosticPageWithNav {
   StatusPage(DiagnosticsSite site)
       : super(site, 'status', 'Status',
@@ -1280,49 +1326,3 @@
     });
   }
 }
-
-class ServiceProtocol {
-  final WebSocket socket;
-
-  int _id = 0;
-  Map<String, Completer> _completers = {};
-
-  static Future<ServiceProtocol> connect(Uri uri) async {
-    WebSocket socket = await WebSocket.connect(uri.toString());
-    return new ServiceProtocol._(socket);
-  }
-
-  ServiceProtocol._(this.socket) {
-    socket.listen(_handleMessage);
-  }
-
-  Future<Map> call(String method, [Map args]) {
-    String id = '${++_id}';
-    Completer completer = new Completer();
-    _completers[id] = completer;
-    Map m = {'id': id, 'method': method};
-    if (args != null) m['params'] = args;
-    String message = jsonEncode(m);
-    socket.add(message);
-    return completer.future;
-  }
-
-  void _handleMessage(dynamic message) {
-    if (message is! String) {
-      return;
-    }
-
-    try {
-      dynamic json = jsonDecode(message);
-      if (json.containsKey('id')) {
-        dynamic id = json['id'];
-        _completers[id]?.complete(json['result']);
-        _completers.remove(id);
-      }
-    } catch (e) {
-      // ignore
-    }
-  }
-
-  Future dispose() => socket.close();
-}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 0e1ae08..43c8630 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -10,7 +10,6 @@
   args: '>=0.13.0 <2.0.0'
   dart_style: '^1.0.6'
   intl: ^0.15.0
-  isolate: '>=0.2.2 <2.0.0'
   linter: ^0.1.16
   logging: any
   package_config: '>=0.1.5 <2.0.0'
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 19f1ac7..8e99e48 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -4,13 +4,13 @@
 
 import 'dart:async';
 
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 95bce6d..6b36df9 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -12,9 +12,9 @@
 import 'package:analysis_server/src/domain_analysis.dart';
 import 'package:analysis_server/src/plugin/notification_manager.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analyzer/context/context_root.dart' as analyzer;
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/context/context_root.dart' as analyzer;
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
diff --git a/pkg/analysis_server/test/benchmarks_test.dart b/pkg/analysis_server/test/benchmarks_test.dart
index 6fa9319..5dd51fb 100644
--- a/pkg/analysis_server/test/benchmarks_test.dart
+++ b/pkg/analysis_server/test/benchmarks_test.dart
@@ -27,6 +27,10 @@
     });
 
     for (String benchmarkId in benchmarks) {
+      if (benchmarkId == 'analysis-flutter-analyze') {
+        continue;
+      }
+
       test(benchmarkId, () {
         ProcessResult r = Process.runSync(
           Platform.resolvedExecutable,
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index db983e5..431bf6a 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -7,12 +7,12 @@
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analysis_server/src/plugin/notification_manager.dart';
 import 'package:analysis_server/src/utilities/null_string_sink.dart';
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/error/codes.dart';
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 29f95af..ed61e22 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -13,6 +13,7 @@
 
 import '../analysis_abstract.dart';
 import '../mocks.dart';
+import '../src/utilities/flutter_util.dart' as flutter;
 
 main() {
   defineReflectiveSuite(() {
@@ -789,6 +790,15 @@
 class GetAvailableRefactoringsTest extends AbstractAnalysisTest {
   List<RefactoringKind> kinds;
 
+  void addFlutterPackage() {
+    var libFolder = flutter.configureFlutterPackage(resourceProvider);
+    packageMapProvider.packageMap['flutter'] = [libFolder];
+    // Create .packages in the project.
+    newFile(join(projectPath, '.packages'), content: '''
+flutter:${libFolder.toUri()}
+''');
+  }
+
   /**
    * Tests that there is refactoring of the given [kind] is available at the
    * [search] offset.
@@ -866,6 +876,23 @@
     expect(kinds, contains(RefactoringKind.EXTRACT_METHOD));
   }
 
+  Future test_extractWidget() async {
+    addFlutterPackage();
+    addTestFile('''
+import 'package:flutter/material.dart';
+
+class MyWidget extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return new Text('AAA');
+  }
+}
+''');
+    await waitForTasksFinished();
+    await getRefactoringsForString('new Text');
+    expect(kinds, contains(RefactoringKind.EXTRACT_WIDGET));
+  }
+
   Future test_rename_hasElement_class() {
     return assertHasRenameRefactoring('''
 class Test {}
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 53ebe1f..6a26f97 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -11,9 +11,9 @@
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/source/package_map_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
 import 'package:front_end/src/base/timestamped_data.dart';
 import 'package:test/test.dart';
 
diff --git a/pkg/analysis_server/test/services/linter/linter_test.dart b/pkg/analysis_server/test/services/linter/linter_test.dart
index c88c48a..19272d8 100644
--- a/pkg/analysis_server/test/services/linter/linter_test.dart
+++ b/pkg/analysis_server/test/services/linter/linter_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/lint/options_rule_validator.dart';
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index 8c0088f..b03c081 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -7,10 +7,10 @@
 
 import 'package:analysis_server/src/plugin/notification_manager.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/channel/channel.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart';
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 2707c57..8b7669b 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -8,10 +8,10 @@
 import 'package:analysis_server/src/plugin/plugin_locator.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/plugin/plugin_watcher.dart';
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
@@ -135,7 +135,7 @@
     fsState = new FileSystemState(
         new PerformanceLog(null),
         new MemoryByteStore(),
-        null,
+        new FileContentOverlay(),
         resourceProvider,
         sourceFactory,
         new AnalysisOptionsImpl(),
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 50954cd..62c933f 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  <version>1.20.0</version>
+  <version>1.20.1</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
diff --git a/pkg/analyzer/lib/dart/ast/resolution_base_classes.dart b/pkg/analyzer/lib/dart/ast/resolution_base_classes.dart
deleted file mode 100644
index 54ca0d8..0000000
--- a/pkg/analyzer/lib/dart/ast/resolution_base_classes.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016, 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.
-
-/**
- * Abstract base class for a resolved element maintained in an AST data
- * structure.
- *
- * This abstract type decouples the AST representation from depending on the
- * element model.
- */
-abstract class ResolutionTarget {}
-
-/**
- * Abstract base class for a resolved type maintained in AST data structure.
- *
- * This abstract type decouples the AST representation from depending on the
- * type model.
- */
-abstract class ResolutionType {}
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 12a88e8..5b2237b 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -34,10 +34,7 @@
  * statements declares a local variable then the local variable will be
  * represented by an element.
  */
-library analyzer.dart.element.element;
-
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/resolution_base_classes.dart';
 import 'package:analyzer/dart/constant/value.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
@@ -45,8 +42,8 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/api/model.dart' show AnalysisTarget;
 import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/model.dart' show AnalysisTarget;
 
 /**
  * An element that represents a class.
@@ -564,7 +561,7 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class Element implements AnalysisTarget, ResolutionTarget {
+abstract class Element implements AnalysisTarget {
   /**
    * A comparator that can be used to sort elements by their name offset.
    * Elements with a smaller offset will be sorted to be before elements with a
@@ -848,8 +845,7 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class ElementAnnotation
-    implements ConstantEvaluationTarget, ResolutionTarget {
+abstract class ElementAnnotation implements ConstantEvaluationTarget {
   /**
    * An empty list of annotations.
    */
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 69d76ad..64c8606 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -20,9 +20,6 @@
  * parameters. But if we declare a variable as `Pair<String, int> pair;` the
  * references to `String` and `int` are type arguments.
  */
-library analyzer.dart.element.type;
-
-import 'package:analyzer/dart/ast/resolution_base_classes.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;
 import 'package:analyzer/src/generated/type_system.dart' show TypeSystem;
@@ -32,7 +29,7 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class DartType implements ResolutionType {
+abstract class DartType {
   /**
    * An empty list of types.
    */
@@ -127,6 +124,16 @@
    */
   bool isAssignableTo(DartType type);
 
+  /// Indicates whether `this` represents a type that is equivalent to `dest`.
+  ///
+  /// This is different from `operator==`.  Consider for example:
+  ///
+  ///     typedef void F<T>(); // T not used!
+  ///
+  /// `operator==` would consider F<int> and F<bool> to be different types;
+  /// `isEquivalentTo` considers them to be equivalent.
+  bool isEquivalentTo(DartType dest);
+
   /**
    * Return `true` if this type is more specific than the given [type].
    */
@@ -172,16 +179,6 @@
    */
   DartType substitute2(
       List<DartType> argumentTypes, List<DartType> parameterTypes);
-
-  /// Indicates whether `this` represents a type that is equivalent to `dest`.
-  ///
-  /// This is different from `operator==`.  Consider for example:
-  ///
-  ///     typedef void F<T>(); // T not used!
-  ///
-  /// `operator==` would consider F<int> and F<bool> to be different types;
-  /// `isEquivalentTo` considers them to be equivalent.
-  bool isEquivalentTo(DartType dest);
 }
 
 /**
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 1d0416c..beb7369 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -678,7 +678,6 @@
   StrongModeCode.TOP_LEVEL_INSTANCE_GETTER,
   StrongModeCode.TOP_LEVEL_INSTANCE_METHOD,
   StrongModeCode.TOP_LEVEL_UNSUPPORTED,
-  StrongModeCode.USES_DYNAMIC_AS_BOTTOM,
   TodoCode.TODO,
 ];
 
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 07493b9..4c05644 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -197,28 +197,6 @@
     }
   }
 
-  _MemoryFile renameFileSync(_MemoryFile file, String newPath) {
-    String path = file.path;
-    if (newPath == path) {
-      return file;
-    }
-    _MemoryResource existingNewResource = _pathToResource[newPath];
-    if (existingNewResource is _MemoryFolder) {
-      throw new FileSystemException(
-          path, 'Could not be renamed: $newPath is a folder.');
-    }
-    _MemoryFile newFile = _newFile(newPath);
-    _pathToResource.remove(path);
-    _pathToBytes[newPath] = _pathToBytes.remove(path);
-    _pathToTimestamp[newPath] = _pathToTimestamp.remove(path);
-    if (existingNewResource != null) {
-      _notifyWatchers(newPath, ChangeType.REMOVE);
-    }
-    _notifyWatchers(path, ChangeType.REMOVE);
-    _notifyWatchers(newPath, ChangeType.ADD);
-    return newFile;
-  }
-
   File updateFile(String path, String content, [int stamp]) {
     path = pathContext.normalize(path);
     newFolder(pathContext.dirname(path));
@@ -286,6 +264,28 @@
     });
   }
 
+  _MemoryFile _renameFileSync(_MemoryFile file, String newPath) {
+    String path = file.path;
+    if (newPath == path) {
+      return file;
+    }
+    _MemoryResource existingNewResource = _pathToResource[newPath];
+    if (existingNewResource is _MemoryFolder) {
+      throw new FileSystemException(
+          path, 'Could not be renamed: $newPath is a folder.');
+    }
+    _MemoryFile newFile = _newFile(newPath);
+    _pathToResource.remove(path);
+    _pathToBytes[newPath] = _pathToBytes.remove(path);
+    _pathToTimestamp[newPath] = _pathToTimestamp.remove(path);
+    if (existingNewResource != null) {
+      _notifyWatchers(newPath, ChangeType.REMOVE);
+    }
+    _notifyWatchers(path, ChangeType.REMOVE);
+    _notifyWatchers(newPath, ChangeType.ADD);
+    return newFile;
+  }
+
   void _setFileContent(_MemoryFile file, List<int> bytes) {
     String path = file.path;
     _pathToResource[path] = file;
@@ -444,7 +444,7 @@
 
   @override
   File renameSync(String newPath) {
-    return _provider.renameFileSync(this, newPath);
+    return _provider._renameFileSync(this, newPath);
   }
 
   @override
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 1812123..a5d2a99 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -12,7 +12,6 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
-import 'package:isolate/isolate_runner.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
@@ -40,9 +39,9 @@
 }
 
 /**
-* The name of the directory containing plugin specific subfolders used to
-* store data across sessions.
-*/
+ * The name of the directory containing plugin specific subfolders used to
+ * store data across sessions.
+ */
 const String _SERVER_DIR = ".dartServer";
 
 /**
@@ -72,8 +71,6 @@
    */
   final String _stateLocation;
 
-  static Future<IsolateRunner> pathsToTimesIsolate = IsolateRunner.spawn();
-
   @override
   final AbsolutePathContext absolutePathContext =
       new AbsolutePathContext(io.Platform.isWindows);
@@ -103,8 +100,7 @@
   @override
   Future<List<int>> getModificationTimes(List<Source> sources) async {
     List<String> paths = sources.map((source) => source.fullName).toList();
-    IsolateRunner runner = await pathsToTimesIsolate;
-    return runner.run(_pathsToTimes, paths);
+    return _pathsToTimes(paths);
   }
 
   @override
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index 27d0c1a..38bf416 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -2,12 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.instrumentation.instrumentation;
-
 import 'dart:async';
 import 'dart:convert';
 
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 
 /**
  * A container with analysis performance constants.
diff --git a/pkg/analyzer/lib/source/analysis_options_provider.dart b/pkg/analyzer/lib/source/analysis_options_provider.dart
index 550f3e3..939f634 100644
--- a/pkg/analyzer/lib/source/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/source/analysis_options_provider.dart
@@ -2,142 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:core';
+@deprecated
+library analyzer.src.analysis_options.analysis_options_provider;
 
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/source/source_resource.dart';
-import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/util/yaml.dart';
-import 'package:source_span/source_span.dart';
-import 'package:yaml/yaml.dart';
-
-/// Provide the options found in the analysis options file.
-class AnalysisOptionsProvider {
-  /// The source factory used to resolve include declarations
-  /// in analysis options files or `null` if include is not supported.
-  SourceFactory sourceFactory;
-
-  AnalysisOptionsProvider([this.sourceFactory]);
-
-  /// Provide the options found in either
-  /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_FILE] or
-  /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE].
-  /// Recursively merge options referenced by an include directive
-  /// and remove the include directive from the resulting options map.
-  /// Return an empty options map if the file does not exist.
-  YamlMap getOptions(Folder root, {bool crawlUp: false}) {
-    File optionsFile = getOptionsFile(root, crawlUp: crawlUp);
-    if (optionsFile == null) {
-      return new YamlMap();
-    }
-    return getOptionsFromFile(optionsFile);
-  }
-
-  /// Return the analysis options file from which options should be read, or
-  /// `null` if there is no analysis options file for code in the given [root].
-  ///
-  /// The given [root] directory will be searched first. If no file is found and
-  /// if [crawlUp] is `true`, then enclosing directories will be searched.
-  File getOptionsFile(Folder root, {bool crawlUp: false}) {
-    Resource resource = null;
-    for (Folder folder = root; folder != null; folder = folder.parent) {
-      resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
-      if (resource.exists) {
-        break;
-      }
-      resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
-      if (resource.exists || !crawlUp) {
-        break;
-      }
-    }
-    if (resource is File && resource.exists) {
-      return resource;
-    }
-    return null;
-  }
-
-  /// Provide the options found in [file].
-  /// Recursively merge options referenced by an include directive
-  /// and remove the include directive from the resulting options map.
-  /// Return an empty options map if the file does not exist.
-  YamlMap getOptionsFromFile(File file) {
-    return getOptionsFromSource(new FileSource(file));
-  }
-
-  /// Provide the options found in [source].
-  /// Recursively merge options referenced by an include directive
-  /// and remove the include directive from the resulting options map.
-  /// Return an empty options map if the file does not exist.
-  YamlMap getOptionsFromSource(Source source) {
-    YamlMap options = getOptionsFromString(_readAnalysisOptions(source));
-    YamlNode node = getValue(options, AnalyzerOptions.include);
-    if (sourceFactory != null && node is YamlScalar) {
-      var path = node.value;
-      if (path is String) {
-        Source parent = sourceFactory.resolveUri(source, path);
-        options = merge(getOptionsFromSource(parent), options);
-      }
-    }
-    return options;
-  }
-
-  /// Provide the options found in [optionsSource].
-  /// An include directive, if present, will be left as-is,
-  /// and the referenced options will NOT be merged into the result.
-  /// Return an empty options map if the source is null.
-  YamlMap getOptionsFromString(String optionsSource) {
-    if (optionsSource == null) {
-      return new YamlMap();
-    }
-    try {
-      YamlNode doc = loadYamlNode(optionsSource);
-      if (doc is YamlMap) {
-        return doc;
-      }
-      return new YamlMap();
-    } on YamlException catch (e) {
-      throw new OptionsFormatException(e.message, e.span);
-    } catch (e) {
-      throw new OptionsFormatException('Unable to parse YAML document.');
-    }
-  }
-
-  /// Merge the given options contents where the values in [defaults] may be
-  /// overridden by [overrides].
-  ///
-  /// Some notes about merge semantics:
-  ///
-  ///   * lists are merged (without duplicates).
-  ///   * lists of scalar values can be promoted to simple maps when merged with
-  ///     maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes
-  ///     {'opt1': true, 'opt2': true}.
-  ///   * maps are merged recursively.
-  ///   * if map values cannot be merged, the overriding value is taken.
-  ///
-  YamlMap merge(YamlMap defaults, YamlMap overrides) =>
-      new Merger().mergeMap(defaults, overrides);
-
-  /// Read the contents of [source] as a string.
-  /// Returns null if source is null or does not exist.
-  String _readAnalysisOptions(Source source) {
-    try {
-      return source.contents.data;
-    } catch (e) {
-      // Source can't be read.
-      return null;
-    }
-  }
-}
-
-/// Thrown on options format exceptions.
-class OptionsFormatException implements Exception {
-  final String message;
-  final SourceSpan span;
-  OptionsFormatException(this.message, [this.span]);
-
-  @override
-  String toString() =>
-      'OptionsFormatException: ${message?.toString()}, ${span?.toString()}';
-}
+export 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
diff --git a/pkg/analyzer/lib/source/custom_resolver.dart b/pkg/analyzer/lib/source/custom_resolver.dart
index f5bbf46..8dfe9f9 100644
--- a/pkg/analyzer/lib/source/custom_resolver.dart
+++ b/pkg/analyzer/lib/source/custom_resolver.dart
@@ -2,29 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+@deprecated
 library analyzer.source.custom_resolver;
 
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-class CustomUriResolver extends UriResolver {
-  final ResourceProvider resourceProvider;
-  final Map<String, String> _urlMappings;
-
-  CustomUriResolver(this.resourceProvider, this._urlMappings);
-
-  @override
-  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
-    String mapping = _urlMappings[uri.toString()];
-    if (mapping == null) {
-      return null;
-    }
-    Uri fileUri = new Uri.file(mapping);
-    if (!fileUri.isAbsolute) {
-      return null;
-    }
-    return resourceProvider
-        .getFile(resourceProvider.pathContext.fromUri(fileUri))
-        .createSource(actualUri ?? uri);
-  }
-}
+export 'package:analyzer/src/source/custom_resolver.dart';
diff --git a/pkg/analyzer/lib/source/line_info.dart b/pkg/analyzer/lib/source/line_info.dart
new file mode 100644
index 0000000..38ac611
--- /dev/null
+++ b/pkg/analyzer/lib/source/line_info.dart
@@ -0,0 +1,119 @@
+// 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:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+/**
+ * The location of a character represented as a line and column pair.
+ */
+// ignore: deprecated_member_use
+class CharacterLocation extends LineInfo_Location {
+  // TODO(brianwilkerson) Replace the body of this class with the body of
+  // LineInfo_Location and remove LineInfo_Location.
+  /**
+   * Initialize a newly created location to represent the location of the
+   * character at the given [lineNumber] and [columnNumber].
+   */
+  CharacterLocation(int lineNumber, int columnNumber)
+      : super(lineNumber, columnNumber);
+}
+
+/**
+ * Information about line and column information within a source file.
+ */
+class LineInfo {
+  /**
+   * A list containing the offsets of the first character of each line in the
+   * source code.
+   */
+  final List<int> lineStarts;
+
+  /**
+   * The zero-based [lineStarts] index resulting from the last call to
+   * [getLocation].
+   */
+  int _previousLine = 0;
+
+  /**
+   * Initialize a newly created set of line information to represent the data
+   * encoded in the given list of [lineStarts].
+   */
+  LineInfo(this.lineStarts) {
+    if (lineStarts == null) {
+      throw new ArgumentError("lineStarts must be non-null");
+    } else if (lineStarts.length < 1) {
+      throw new ArgumentError("lineStarts must be non-empty");
+    }
+  }
+
+  /**
+   * Initialize a newly created set of line information corresponding to the
+   * given file [content].
+   */
+  factory LineInfo.fromContent(String content) =>
+      new LineInfo(StringUtilities.computeLineStarts(content));
+
+  /**
+   * The number of lines.
+   */
+  int get lineCount => lineStarts.length;
+
+  /**
+   * Return the location information for the character at the given [offset].
+   */
+  CharacterLocation getLocation(int offset) {
+    var min = 0;
+    var max = lineStarts.length - 1;
+
+    // Subsequent calls to [getLocation] are often for offsets near each other.
+    // To take advantage of that, we cache the index of the line start we found
+    // when this was last called. If the current offset is on that line or
+    // later, we'll skip those early indices completely when searching.
+    if (offset >= lineStarts[_previousLine]) {
+      min = _previousLine;
+
+      // Before kicking off a full binary search, do a quick check here to see
+      // if the new offset is on that exact line.
+      if (min == lineStarts.length - 1 || offset < lineStarts[min + 1]) {
+        return new CharacterLocation(min + 1, offset - lineStarts[min] + 1);
+      }
+    }
+
+    // Binary search to fine the line containing this offset.
+    while (min < max) {
+      var midpoint = (max - min + 1) ~/ 2 + min;
+
+      if (lineStarts[midpoint] > offset) {
+        max = midpoint - 1;
+      } else {
+        min = midpoint;
+      }
+    }
+
+    _previousLine = min;
+
+    return new CharacterLocation(min + 1, offset - lineStarts[min] + 1);
+  }
+
+  /**
+   * Return the offset of the first character on the line with the given
+   * [lineNumber].
+   */
+  int getOffsetOfLine(int lineNumber) {
+    if (lineNumber < 0 || lineNumber >= lineCount) {
+      throw new ArgumentError(
+          'Invalid line number: $lineNumber; must be between 0 and ${lineCount - 1}');
+    }
+    return lineStarts[lineNumber];
+  }
+
+  /**
+   * Return the offset of the first character on the line following the line
+   * containing the given [offset].
+   */
+  int getOffsetOfLineAfter(int offset) {
+    return getOffsetOfLine(getLocation(offset).lineNumber + 1);
+  }
+}
diff --git a/pkg/analyzer/lib/source/package_map_provider.dart b/pkg/analyzer/lib/source/package_map_provider.dart
index b2eb8b6..f3c2119 100644
--- a/pkg/analyzer/lib/source/package_map_provider.dart
+++ b/pkg/analyzer/lib/source/package_map_provider.dart
@@ -2,43 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+@deprecated
 library analyzer.source.package_map_provider;
 
-import 'package:analyzer/file_system/file_system.dart';
-
-/**
- * Data structure output by PackageMapProvider.  This contains both the package
- * map and dependency information.
- */
-class PackageMapInfo {
-  /**
-   * The package map itself.  This is a map from package name to a list of
-   * the folders containing source code for the package.
-   *
-   * `null` if an error occurred.
-   */
-  Map<String, List<Folder>> packageMap;
-
-  /**
-   * Dependency information.  This is a set of the paths which were consulted
-   * in order to generate the package map.  If any of these files is
-   * modified, the package map will need to be regenerated.
-   */
-  Set<String> dependencies;
-
-  PackageMapInfo(this.packageMap, this.dependencies);
-}
-
-/**
- * A PackageMapProvider is an entity capable of determining the mapping from
- * package name to source directory for a given folder.
- */
-abstract class PackageMapProvider {
-  /**
-   * Compute a package map for the given folder, if possible.
-   *
-   * If a package map can't be computed (e.g. because an error occurred), a
-   * [PackageMapInfo] will still be returned, but its packageMap will be null.
-   */
-  PackageMapInfo computePackageMap(Folder folder);
-}
+export 'package:analyzer/src/source/package_map_provider.dart';
diff --git a/pkg/analyzer/lib/source/path_filter.dart b/pkg/analyzer/lib/source/path_filter.dart
index c207014..ba5454e 100644
--- a/pkg/analyzer/lib/source/path_filter.dart
+++ b/pkg/analyzer/lib/source/path_filter.dart
@@ -2,76 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+@deprecated
 library analyzer.source.path_filter;
 
-import 'package:analyzer/src/util/glob.dart';
-import 'package:path/path.dart' as path;
-
-/// Filter paths against a set of [_ignorePatterns] relative to a [root]
-/// directory. Paths outside of [root] are also ignored.
-class PathFilter {
-  /// The path context to use when manipulating paths.
-  final path.Context pathContext;
-
-  /// Path that all ignore patterns are relative to.
-  final String root;
-
-  /// List of ignore patterns that paths are tested against.
-  final List<Glob> _ignorePatterns = new List<Glob>();
-
-  /// Construct a new path filter rooted at [root] with [ignorePatterns].
-  /// If [pathContext] is not specified, then the system path context is used.
-  PathFilter(this.root, List<String> ignorePatterns, [path.Context pathContext])
-      : this.pathContext = pathContext ?? path.context {
-    setIgnorePatterns(ignorePatterns);
-  }
-
-  /// Returns true if [path] should be ignored. A path is ignored if it is not
-  /// contained in [root] or matches one of the ignore patterns.
-  /// [path] is absolute or relative to [root].
-  bool ignored(String path) {
-    path = _canonicalize(path);
-    return !_contained(path) || _match(path);
-  }
-
-  /// Set the ignore patterns.
-  void setIgnorePatterns(List<String> ignorePatterns) {
-    _ignorePatterns.clear();
-    if (ignorePatterns != null) {
-      for (var ignorePattern in ignorePatterns) {
-        _ignorePatterns.add(new Glob(pathContext.separator, ignorePattern));
-      }
-    }
-  }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    for (Glob pattern in _ignorePatterns) {
-      sb.write('$pattern ');
-    }
-    sb.writeln('');
-    return sb.toString();
-  }
-
-  /// Returns the absolute path of [path], relative to [root].
-  String _canonicalize(String path) =>
-      pathContext.normalize(pathContext.join(root, path));
-
-  /// Returns true when [path] is contained inside [root].
-  bool _contained(String path) => path.startsWith(root);
-
-  /// Returns true if [path] matches any ignore patterns.
-  bool _match(String path) {
-    path = _relative(path);
-    for (Glob glob in _ignorePatterns) {
-      if (glob.matches(path)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /// Returns the relative portion of [path] from [root].
-  String _relative(String path) => pathContext.relative(path, from: root);
-}
+export 'package:analyzer/src/source/path_filter.dart';
diff --git a/pkg/analyzer/lib/source/pub_package_map_provider.dart b/pkg/analyzer/lib/source/pub_package_map_provider.dart
index 26436d9..feb2221 100644
--- a/pkg/analyzer/lib/source/pub_package_map_provider.dart
+++ b/pkg/analyzer/lib/source/pub_package_map_provider.dart
@@ -2,183 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+@deprecated
 library analyzer.source.pub_package_map_provider;
 
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:core';
-import 'dart:io' as io;
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_provider.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/generated/engine.dart';
-
-/**
- * The function used to run pub list.
- */
-typedef io.ProcessResult RunPubList(Folder folder);
-
-/**
- * Implementation of PackageMapProvider that operates by executing pub.
- */
-class PubPackageMapProvider implements PackageMapProvider {
-  static const String PUB_LIST_COMMAND = 'list-package-dirs';
-
-  /**
-   * The name of the 'pubspec.lock' file, which we assume is the dependency
-   * in the event that [PUB_LIST_COMMAND] fails.
-   */
-  static const String PUBSPEC_LOCK_NAME = 'pubspec.lock';
-
-  /**
-   * [ResourceProvider] that is used to create the [Folder]s that populate the
-   * package map.
-   */
-  final ResourceProvider resourceProvider;
-
-  /**
-   * Sdk that we use to find the pub executable.
-   */
-  final FolderBasedDartSdk sdk;
-
-  /**
-   * The function used to run pub list.
-   */
-  RunPubList _runPubList;
-
-  /**
-   * Construct a new instance.
-   * A [RunPubList] implementation may be injected for testing
-   */
-  PubPackageMapProvider(this.resourceProvider, this.sdk, [this._runPubList]) {
-    if (_runPubList == null) {
-      _runPubList = _runPubListDefault;
-    }
-  }
-
-  @override
-  PackageMapInfo computePackageMap(Folder folder) {
-    // If the pubspec.lock file does not exist, no need to run anything.
-    {
-      String lockPath = getPubspecLockPath(folder);
-      if (!resourceProvider.getFile(lockPath).exists) {
-        return computePackageMapError(folder);
-      }
-    }
-    // TODO(paulberry) make this asynchronous so that we can (a) do other
-    // analysis while it's in progress, and (b) time out if it takes too long
-    // to respond.
-    io.ProcessResult result;
-    try {
-      result = _runPubList(folder);
-    } on io.ProcessException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Error running pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
-    }
-    if (result == null || result.exitCode != 0) {
-      String exitCode =
-          result != null ? 'exit code ${result.exitCode}' : 'null';
-      AnalysisEngine.instance.logger
-          .logInformation("pub $PUB_LIST_COMMAND failed: $exitCode");
-      return computePackageMapError(folder);
-    }
-    try {
-      PackageMapInfo packageMap =
-          parsePackageMap(json.decode(result.stdout), folder);
-      return packageMap;
-    } catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logError(
-          "Malformed output from pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
-    }
-
-    return computePackageMapError(folder);
-  }
-
-  /**
-   * Create a PackageMapInfo object representing an error condition.
-   */
-  PackageMapInfo computePackageMapError(Folder folder) {
-    // Even if an error occurs, we still need to know the dependencies, so that
-    // we'll know when to try running "pub list-package-dirs" again.
-    // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when
-    // an error occurs, so just assume there is one dependency, "pubspec.lock".
-    String lockPath = getPubspecLockPath(folder);
-    List<String> dependencies = <String>[lockPath];
-    return new PackageMapInfo(null, dependencies.toSet());
-  }
-
-  /**
-   * Return the path to the `pubspec.lock` file in the given [folder].
-   */
-  String getPubspecLockPath(Folder folder) =>
-      resourceProvider.pathContext.join(folder.path, PUBSPEC_LOCK_NAME);
-
-  /**
-   * Decode the JSON output from pub into a package map.  Paths in the
-   * output are considered relative to [folder].
-   */
-  PackageMapInfo parsePackageMap(Map obj, Folder folder) {
-    // The output of pub looks like this:
-    // {
-    //   "packages": {
-    //     "foo": "path/to/foo",
-    //     "bar": ["path/to/bar1", "path/to/bar2"],
-    //     "myapp": "path/to/myapp",  // self link is included
-    //   },
-    //   "input_files": [
-    //     "path/to/myapp/pubspec.lock"
-    //   ]
-    // }
-    Map<String, List<Folder>> packageMap = new HashMap<String, List<Folder>>();
-    Map packages = obj['packages'];
-    processPaths(String packageName, List paths) {
-      List<Folder> folders = <Folder>[];
-      for (var path in paths) {
-        if (path is String) {
-          Resource resource = folder.getChildAssumingFolder(path);
-          if (resource is Folder) {
-            folders.add(resource);
-          }
-        }
-      }
-      if (folders.isNotEmpty) {
-        packageMap[packageName] = folders;
-      }
-    }
-
-    packages.forEach((key, value) {
-      if (value is String) {
-        processPaths(key, [value]);
-      } else if (value is List) {
-        processPaths(key, value);
-      }
-    });
-    Set<String> dependencies = new Set<String>();
-    List inputFiles = obj['input_files'];
-    if (inputFiles != null) {
-      for (var path in inputFiles) {
-        if (path is String) {
-          dependencies.add(folder.canonicalizePath(path));
-        }
-      }
-    }
-    return new PackageMapInfo(packageMap, dependencies);
-  }
-
-  /**
-   * Run pub list to determine the packages and input files.
-   */
-  io.ProcessResult _runPubListDefault(Folder folder) {
-    String executablePath = sdk.pubExecutable.path;
-    List<String> arguments = [PUB_LIST_COMMAND];
-    String workingDirectory = folder.path;
-    int subprocessId = AnalysisEngine.instance.instrumentationService
-        .logSubprocessStart(executablePath, arguments, workingDirectory);
-    io.ProcessResult result = io.Process
-        .runSync(executablePath, arguments, workingDirectory: workingDirectory);
-    AnalysisEngine.instance.instrumentationService.logSubprocessResult(
-        subprocessId, result.exitCode, result.stdout, result.stderr);
-    return result;
-  }
-}
+export 'package:analyzer/src/source/pub_package_map_provider.dart';
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index a1ea2b3..7f5557b 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -2,206 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+@deprecated
 library analyzer.source.sdk_ext;
 
-import 'dart:convert';
-import 'dart:core';
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_provider.dart'
-    show PackageMapProvider;
-import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
-import 'package:path/path.dart' as pathos;
-
-/// Given a packageMap (see [PackageMapProvider]), check in each package's lib
-/// directory for the existence of a `_sdkext` file. This file must contain a
-/// JSON encoded map. Each key in the map is a `dart:` library name. Each value
-/// is a path (relative to the directory containing `_sdkext`) to a dart script
-/// for the given library. For example:
-/// {
-///   "dart:sky": "../sdk_ext/dart_sky.dart"
-/// }
-///
-/// If a key doesn't begin with `dart:` it is ignored.
-class SdkExtUriResolver extends UriResolver {
-  static const String SDK_EXT_NAME = '_sdkext';
-  static const String DART_COLON_PREFIX = 'dart:';
-
-  final Map<String, String> _urlMappings = <String, String>{};
-
-  /**
-   * The absolute paths of the extension files that contributed to the
-   * [_urlMappings].
-   */
-  final List<String> extensionFilePaths = <String>[];
-
-  /// Construct a [SdkExtUriResolver] from a package map
-  /// (see [PackageMapProvider]).
-  SdkExtUriResolver(Map<String, List<Folder>> packageMap) {
-    if (packageMap == null) {
-      return;
-    }
-    packageMap.forEach(_processPackage);
-  }
-
-  /// Number of sdk extensions.
-  int get length => _urlMappings.length;
-
-  /**
-   * Return a table mapping the names of extensions to the paths where those
-   * extensions can be found.
-   */
-  Map<String, String> get urlMappings =>
-      new Map<String, String>.from(_urlMappings);
-
-  /// Return the path mapping for [libName] or null if there is none.
-  String operator [](String libName) => _urlMappings[libName];
-
-  /// Programmatically add a new SDK extension given a JSON description
-  /// ([sdkExtJSON]) and a lib directory ([libDir]).
-  void addSdkExt(String sdkExtJSON, Folder libDir) {
-    _processSdkExt(sdkExtJSON, libDir);
-  }
-
-  @override
-  Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
-    String libraryName = _libraryName(importUri);
-    String partPath = _partPath(importUri);
-    // Lookup library name in mappings.
-    String mapping = _urlMappings[libraryName];
-    if (mapping == null) {
-      // Not found.
-      return null;
-    }
-    // This mapping points to the main entry file of the sdk extension.
-    Uri libraryEntry = new Uri.file(mapping);
-    if (!libraryEntry.isAbsolute) {
-      // We expect an absolute path.
-      return null;
-    }
-
-    if (partPath != null) {
-      return _resolvePart(libraryEntry, partPath, importUri);
-    } else {
-      return _resolveEntry(libraryEntry, importUri);
-    }
-  }
-
-  @override
-  Uri restoreAbsolute(Source source) {
-    String extensionName = _findExtensionNameFor(source.fullName);
-    if (extensionName != null) {
-      return Uri.parse(extensionName);
-    }
-    // TODO(johnmccutchan): Handle restoring parts.
-    return null;
-  }
-
-  /// Return the extension name for [fullName] or `null`.
-  String _findExtensionNameFor(String fullName) {
-    var result;
-    _urlMappings.forEach((extensionName, pathMapping) {
-      if (pathMapping == fullName) {
-        result = extensionName;
-      }
-    });
-    return result;
-  }
-
-  /// Return the library name of [importUri].
-  String _libraryName(Uri importUri) {
-    var uri = importUri.toString();
-    int index = uri.indexOf('/');
-    if (index >= 0) {
-      return uri.substring(0, index);
-    }
-    return uri;
-  }
-
-  /// Return the part path of [importUri].
-  String _partPath(Uri importUri) {
-    var uri = importUri.toString();
-    int index = uri.indexOf('/');
-    if (index >= 0) {
-      return uri.substring(index + 1);
-    }
-    return null;
-  }
-
-  /// Given a package [name] and a list of folders ([libDirs]),
-  /// add any found sdk extensions.
-  void _processPackage(String name, List<Folder> libDirs) {
-    for (var libDir in libDirs) {
-      var sdkExt = _readDotSdkExt(libDir);
-      if (sdkExt != null) {
-        _processSdkExt(sdkExt, libDir);
-      }
-    }
-  }
-
-  /// Given the JSON for an SDK extension ([sdkExtJSON]) and a folder
-  /// ([libDir]), setup the uri mapping.
-  void _processSdkExt(String sdkExtJSON, Folder libDir) {
-    var sdkExt;
-    try {
-      sdkExt = json.decode(sdkExtJSON);
-    } catch (e) {
-      return;
-    }
-    if ((sdkExt == null) || (sdkExt is! Map)) {
-      return;
-    }
-    bool contributed = false;
-    sdkExt.forEach((k, v) {
-      if (_processSdkExtension(k, v, libDir)) {
-        contributed = true;
-      }
-    });
-    if (contributed) {
-      extensionFilePaths.add(libDir.getChild(SDK_EXT_NAME).path);
-    }
-  }
-
-  /// Install the mapping from [name] to [libDir]/[file].
-  bool _processSdkExtension(String name, String file, Folder libDir) {
-    if (!name.startsWith(DART_COLON_PREFIX)) {
-      // SDK extensions must begin with 'dart:'.
-      return false;
-    }
-    var key = name;
-    var value = libDir.canonicalizePath(file);
-    _urlMappings[key] = value;
-    return true;
-  }
-
-  /// Read the contents of [libDir]/[SDK_EXT_NAME] as a string.
-  /// Returns null if the file doesn't exist.
-  String _readDotSdkExt(Folder libDir) {
-    File file = libDir.getChild(SDK_EXT_NAME);
-    try {
-      return file.readAsStringSync();
-    } on FileSystemException {
-      // File can't be read.
-      return null;
-    }
-  }
-
-  /// Resolve an import of an sdk extension.
-  Source _resolveEntry(Uri libraryEntry, Uri importUri) {
-    // Library entry.
-    JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
-    return new FileBasedSource(javaFile, importUri);
-  }
-
-  /// Resolve a 'part' statement inside an sdk extension.
-  Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
-    // Library part.
-    var directory = pathos.dirname(libraryEntry.path);
-    var partUri = new Uri.file(pathos.join(directory, partPath));
-    assert(partUri.isAbsolute);
-    JavaFile javaFile = new JavaFile.fromUri(partUri);
-    return new FileBasedSource(javaFile, importUri);
-  }
-}
+export 'package:analyzer/src/source/sdk_ext.dart';
diff --git a/pkg/analyzer/lib/source/source_range.dart b/pkg/analyzer/lib/source/source_range.dart
new file mode 100644
index 0000000..338ad7a
--- /dev/null
+++ b/pkg/analyzer/lib/source/source_range.dart
@@ -0,0 +1,130 @@
+// 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:math" as math;
+
+/**
+ * A source range defines a range of characters within source code.
+ */
+class SourceRange {
+  /**
+   * An empty source range (a range with offset `0` and length `0`).
+   */
+  static const SourceRange EMPTY = const SourceRange(0, 0);
+
+  /**
+   * The 0-based index of the first character of the source range.
+   */
+  final int offset;
+
+  /**
+   * The number of characters in the source range.
+   */
+  final int length;
+
+  /**
+   * Initialize a newly created source range using the given [offset] and
+   * [length].
+   */
+  const SourceRange(this.offset, this.length);
+
+  /**
+   * Return the 0-based index of the character immediately after this source
+   * range.
+   */
+  int get end => offset + length;
+
+  @override
+  int get hashCode => 31 * offset + length;
+
+  @override
+  bool operator ==(Object other) {
+    return other is SourceRange &&
+        other.offset == offset &&
+        other.length == length;
+  }
+
+  /**
+   * Return `true` if [x] is in the interval `[offset, offset + length)`.
+   */
+  bool contains(int x) => offset <= x && x < offset + length;
+
+  /**
+   * Return `true` if [x] is in the interval `(offset, offset + length)`.
+   */
+  bool containsExclusive(int x) => offset < x && x < offset + length;
+
+  /**
+   * Return `true` if the [otherRange] covers this source range.
+   */
+  bool coveredBy(SourceRange otherRange) => otherRange.covers(this);
+
+  /**
+   * Return `true` if this source range covers the [otherRange].
+   */
+  bool covers(SourceRange otherRange) =>
+      offset <= otherRange.offset && otherRange.end <= end;
+
+  /**
+   * Return `true` if this source range ends inside the [otherRange].
+   */
+  bool endsIn(SourceRange otherRange) {
+    int thisEnd = end;
+    return otherRange.contains(thisEnd);
+  }
+
+  /**
+   * Return a source range covering [delta] characters before the start of this
+   * source range and [delta] characters after the end of this source range.
+   */
+  SourceRange getExpanded(int delta) =>
+      new SourceRange(offset - delta, delta + length + delta);
+
+  /**
+   * Return a source range with the same offset as this source range but whose
+   * length is [delta] characters longer than this source range.
+   */
+  SourceRange getMoveEnd(int delta) => new SourceRange(offset, length + delta);
+
+  /**
+   * Return a source range with the same length as this source range but whose
+   * offset is [delta] characters after the offset of this source range.
+   */
+  SourceRange getTranslated(int delta) =>
+      new SourceRange(offset + delta, length);
+
+  /**
+   * Return the minimal source range that covers both this and the [otherRange].
+   */
+  SourceRange getUnion(SourceRange otherRange) {
+    int newOffset = math.min(offset, otherRange.offset);
+    int newEnd =
+        math.max(offset + length, otherRange.offset + otherRange.length);
+    return new SourceRange(newOffset, newEnd - newOffset);
+  }
+
+  /**
+   * Return `true` if this source range intersects the [otherRange].
+   */
+  bool intersects(SourceRange otherRange) {
+    if (otherRange == null) {
+      return false;
+    }
+    if (end <= otherRange.offset) {
+      return false;
+    }
+    if (offset >= otherRange.end) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Return `true` if this source range starts in the [otherRange].
+   */
+  bool startsIn(SourceRange otherRange) => otherRange.contains(offset);
+
+  @override
+  String toString() => '[offset=$offset, length=$length]';
+}
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
new file mode 100644
index 0000000..550f3e3
--- /dev/null
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:core';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/source_resource.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/util/yaml.dart';
+import 'package:source_span/source_span.dart';
+import 'package:yaml/yaml.dart';
+
+/// Provide the options found in the analysis options file.
+class AnalysisOptionsProvider {
+  /// The source factory used to resolve include declarations
+  /// in analysis options files or `null` if include is not supported.
+  SourceFactory sourceFactory;
+
+  AnalysisOptionsProvider([this.sourceFactory]);
+
+  /// Provide the options found in either
+  /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_FILE] or
+  /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE].
+  /// Recursively merge options referenced by an include directive
+  /// and remove the include directive from the resulting options map.
+  /// Return an empty options map if the file does not exist.
+  YamlMap getOptions(Folder root, {bool crawlUp: false}) {
+    File optionsFile = getOptionsFile(root, crawlUp: crawlUp);
+    if (optionsFile == null) {
+      return new YamlMap();
+    }
+    return getOptionsFromFile(optionsFile);
+  }
+
+  /// Return the analysis options file from which options should be read, or
+  /// `null` if there is no analysis options file for code in the given [root].
+  ///
+  /// The given [root] directory will be searched first. If no file is found and
+  /// if [crawlUp] is `true`, then enclosing directories will be searched.
+  File getOptionsFile(Folder root, {bool crawlUp: false}) {
+    Resource resource = null;
+    for (Folder folder = root; folder != null; folder = folder.parent) {
+      resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
+      if (resource.exists) {
+        break;
+      }
+      resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+      if (resource.exists || !crawlUp) {
+        break;
+      }
+    }
+    if (resource is File && resource.exists) {
+      return resource;
+    }
+    return null;
+  }
+
+  /// Provide the options found in [file].
+  /// Recursively merge options referenced by an include directive
+  /// and remove the include directive from the resulting options map.
+  /// Return an empty options map if the file does not exist.
+  YamlMap getOptionsFromFile(File file) {
+    return getOptionsFromSource(new FileSource(file));
+  }
+
+  /// Provide the options found in [source].
+  /// Recursively merge options referenced by an include directive
+  /// and remove the include directive from the resulting options map.
+  /// Return an empty options map if the file does not exist.
+  YamlMap getOptionsFromSource(Source source) {
+    YamlMap options = getOptionsFromString(_readAnalysisOptions(source));
+    YamlNode node = getValue(options, AnalyzerOptions.include);
+    if (sourceFactory != null && node is YamlScalar) {
+      var path = node.value;
+      if (path is String) {
+        Source parent = sourceFactory.resolveUri(source, path);
+        options = merge(getOptionsFromSource(parent), options);
+      }
+    }
+    return options;
+  }
+
+  /// Provide the options found in [optionsSource].
+  /// An include directive, if present, will be left as-is,
+  /// and the referenced options will NOT be merged into the result.
+  /// Return an empty options map if the source is null.
+  YamlMap getOptionsFromString(String optionsSource) {
+    if (optionsSource == null) {
+      return new YamlMap();
+    }
+    try {
+      YamlNode doc = loadYamlNode(optionsSource);
+      if (doc is YamlMap) {
+        return doc;
+      }
+      return new YamlMap();
+    } on YamlException catch (e) {
+      throw new OptionsFormatException(e.message, e.span);
+    } catch (e) {
+      throw new OptionsFormatException('Unable to parse YAML document.');
+    }
+  }
+
+  /// Merge the given options contents where the values in [defaults] may be
+  /// overridden by [overrides].
+  ///
+  /// Some notes about merge semantics:
+  ///
+  ///   * lists are merged (without duplicates).
+  ///   * lists of scalar values can be promoted to simple maps when merged with
+  ///     maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes
+  ///     {'opt1': true, 'opt2': true}.
+  ///   * maps are merged recursively.
+  ///   * if map values cannot be merged, the overriding value is taken.
+  ///
+  YamlMap merge(YamlMap defaults, YamlMap overrides) =>
+      new Merger().mergeMap(defaults, overrides);
+
+  /// Read the contents of [source] as a string.
+  /// Returns null if source is null or does not exist.
+  String _readAnalysisOptions(Source source) {
+    try {
+      return source.contents.data;
+    } catch (e) {
+      // Source can't be read.
+      return null;
+    }
+  }
+}
+
+/// Thrown on options format exceptions.
+class OptionsFormatException implements Exception {
+  final String message;
+  final SourceSpan span;
+  OptionsFormatException(this.message, [this.span]);
+
+  @override
+  String toString() =>
+      'OptionsFormatException: ${message?.toString()}, ${span?.toString()}';
+}
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 29d84ce..2aee1c4 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -5,18 +5,18 @@
 import 'dart:collection';
 import 'dart:core';
 
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/command_line/arguments.dart'
     show
         applyAnalysisOptionFlags,
         bazelAnalysisOptionsPath,
         flutterAnalysisOptionsPath;
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart'
     show AnalysisDriver, AnalysisDriverScheduler;
 import 'package:analyzer/src/dart/analysis/file_state.dart';
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 1a86195..40a2d9e 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.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.
 
-library analyzer.src.context.cache;
-
 import 'dart:async';
 import 'dart:collection';
 
@@ -12,8 +10,8 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
 
 /**
  * The cache results visiting function type.
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 200ed96..a70c50e5 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.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.
 
-library analyzer.src.context.context;
-
 import 'dart:async';
 import 'dart:collection';
 
@@ -12,7 +10,6 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/plugin/task.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
 import 'package:analyzer/src/context/cache.dart';
@@ -23,14 +20,15 @@
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/plugin/task.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/dart_work_manager.dart';
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart' show Document;
 
 /**
diff --git a/pkg/analyzer/lib/context/context_root.dart b/pkg/analyzer/lib/src/context/context_root.dart
similarity index 100%
rename from pkg/analyzer/lib/context/context_root.dart
rename to pkg/analyzer/lib/src/context/context_root.dart
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index ff0ecb0..628d28c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -2,7 +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:analyzer/context/context_root.dart' as old;
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/context_builder.dart';
 import 'package:analyzer/dart/analysis/context_root.dart';
@@ -11,6 +10,7 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/context/builder.dart' as old
     show ContextBuilder, ContextBuilderOptions;
+import 'package:analyzer/src/context/context_root.dart' as old;
 import 'package:analyzer/src/dart/analysis/driver.dart'
     show AnalysisDriver, AnalysisDriverScheduler;
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 83147d0..e53835f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -4,7 +4,6 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/context/context_root.dart' as old;
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/context_locator.dart';
 import 'package:analyzer/dart/analysis/context_root.dart';
@@ -13,6 +12,7 @@
     show PhysicalResourceProvider;
 import 'package:analyzer/src/context/builder.dart'
     show ContextBuilder, ContextBuilderOptions;
+import 'package:analyzer/src/context/context_root.dart' as old;
 import 'package:analyzer/src/dart/analysis/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart'
     show AnalysisDriver, AnalysisDriverScheduler;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index da83c22..91c19a8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -6,7 +6,6 @@
 import 'dart:collection';
 import 'dart:typed_data';
 
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/results.dart' as results;
 import 'package:analyzer/dart/analysis/session.dart';
@@ -17,6 +16,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/file_tracker.dart';
 import 'package:analyzer/src/dart/analysis/frontend_resolution.dart';
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index c6032e3..b82ab39 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -82,6 +82,11 @@
  * should be called.
  */
 class FileState {
+  /**
+   * The next value for [_exportDeclarationsId].
+   */
+  static int _exportDeclarationsNextId = 0;
+
   final FileSystemState _fsState;
 
   /**
@@ -116,11 +121,12 @@
   String _content;
   String _contentHash;
   LineInfo _lineInfo;
-  Set<String> _definedTopLevelNames;
   Set<String> _definedClassMemberNames;
+  Set<String> _definedTopLevelNames;
   Set<String> _referencedNames;
   Set<String> _subtypedNames;
   String _unlinkedKey;
+  AnalysisDriverUnlinkedUnit _driverUnlinkedUnit;
   UnlinkedUnit _unlinked;
   List<int> _apiSignature;
 
@@ -135,6 +141,7 @@
 
   Map<String, TopLevelDeclaration> _topLevelDeclarations;
   Map<String, TopLevelDeclaration> _exportedTopLevelDeclarations;
+  int _exportDeclarationsId = 0;
 
   /**
    * The flag that shows whether the file has an error or warning that
@@ -172,12 +179,18 @@
   /**
    * The class member names defined by the file.
    */
-  Set<String> get definedClassMemberNames => _definedClassMemberNames;
+  Set<String> get definedClassMemberNames {
+    return _definedClassMemberNames ??=
+        _driverUnlinkedUnit.definedClassMemberNames.toSet();
+  }
 
   /**
    * The top-level names defined by the file.
    */
-  Set<String> get definedTopLevelNames => _definedTopLevelNames;
+  Set<String> get definedTopLevelNames {
+    return _definedTopLevelNames ??=
+        _driverUnlinkedUnit.definedTopLevelNames.toSet();
+  }
 
   /**
    * Return the set of all directly referenced files - imported, exported or
@@ -200,44 +213,8 @@
    * keys to the map are names of declarations.
    */
   Map<String, TopLevelDeclaration> get exportedTopLevelDeclarations {
-    if (_exportedTopLevelDeclarations == null) {
-      _exportedTopLevelDeclarations = <String, TopLevelDeclaration>{};
-
-      Set<FileState> seenLibraries = new Set<FileState>();
-
-      /**
-       * Compute [TopLevelDeclaration]s exported from the [library].
-       */
-      Map<String, TopLevelDeclaration> computeExported(FileState library) {
-        var declarations = <String, TopLevelDeclaration>{};
-        if (seenLibraries.add(library)) {
-          // Append the exported declarations.
-          for (int i = 0; i < library._exportedFiles.length; i++) {
-            Map<String, TopLevelDeclaration> exported =
-                computeExported(library._exportedFiles[i]);
-            for (TopLevelDeclaration t in exported.values) {
-              if (library._exportFilters[i].accepts(t.name)) {
-                declarations[t.name] = t;
-              }
-            }
-          }
-
-          // Append the library declarations.
-          declarations.addAll(library.topLevelDeclarations);
-          for (FileState part in library.partedFiles) {
-            declarations.addAll(part.topLevelDeclarations);
-          }
-
-          // We're done with this library.
-          seenLibraries.remove(library);
-        }
-
-        return declarations;
-      }
-
-      _exportedTopLevelDeclarations = computeExported(this);
-    }
-    return _exportedTopLevelDeclarations;
+    _exportDeclarationsNextId = 1;
+    return _computeExportedDeclarations().declarations;
   }
 
   @override
@@ -281,13 +258,17 @@
   /**
    * The external names referenced by the file.
    */
-  Set<String> get referencedNames => _referencedNames;
+  Set<String> get referencedNames {
+    return _referencedNames ??= _driverUnlinkedUnit.referencedNames.toSet();
+  }
 
   /**
    * The names which are used in `extends`, `with` or `implements` clauses in
    * the file. Import prefixes and type arguments are not included.
    */
-  Set<String> get subtypedNames => _subtypedNames;
+  Set<String> get subtypedNames {
+    return _subtypedNames ??= _driverUnlinkedUnit.subtypedNames.toSet();
+  }
 
   @visibleForTesting
   FileStateTestView get test => new FileStateTestView(this);
@@ -415,24 +396,20 @@
    * Read the file content and ensure that all of the file properties are
    * consistent with the read content, including API signature.
    *
+   * If [allowCached] is `true`, don't read the content of the file if it
+   * is already cached (in another [FileSystemState], because otherwise we
+   * would not create this new instance of [FileState] and refresh it).
+   *
    * Return `true` if the API signature changed since the last refresh.
    */
-  bool refresh() {
-    // Read the content.
-    try {
-      _content = _fsState._contentOverlay[path];
-      _content ??= _fsState._resourceProvider.getFile(path).readAsStringSync();
-      _exists = true;
-    } catch (_) {
-      _content = '';
-      _exists = false;
-    }
-
-    // Compute the content hash.
-    List<int> contentBytes = utf8.encode(_content);
+  bool refresh({bool allowCached: false}) {
+    List<int> contentBytes;
     {
-      List<int> hashBytes = md5.convert(contentBytes).bytes;
-      _contentHash = hex.encode(hashBytes);
+      var rawFileState = _fsState._fileContentCache.get(path, allowCached);
+      _content = rawFileState.content;
+      _exists = rawFileState.exists;
+      contentBytes = rawFileState.contentBytes;
+      _contentHash = rawFileState.contentHash;
     }
 
     // Prepare the unlinked bundle key.
@@ -469,14 +446,15 @@
     }
 
     // Read the unlinked bundle.
-    var driverUnlinkedUnit = new AnalysisDriverUnlinkedUnit.fromBuffer(bytes);
-    _definedTopLevelNames = driverUnlinkedUnit.definedTopLevelNames.toSet();
-    _definedClassMemberNames =
-        driverUnlinkedUnit.definedClassMemberNames.toSet();
-    _referencedNames = driverUnlinkedUnit.referencedNames.toSet();
-    _subtypedNames = driverUnlinkedUnit.subtypedNames.toSet();
-    _unlinked = driverUnlinkedUnit.unit;
+    _driverUnlinkedUnit = new AnalysisDriverUnlinkedUnit.fromBuffer(bytes);
+    _unlinked = _driverUnlinkedUnit.unit;
     _lineInfo = new LineInfo(_unlinked.lineStarts);
+
+    // Invalidate unlinked information.
+    _definedTopLevelNames = null;
+    _definedClassMemberNames = null;
+    _referencedNames = null;
+    _subtypedNames = null;
     _topLevelDeclarations = null;
 
     // Prepare API signature.
@@ -558,6 +536,70 @@
   @override
   String toString() => path;
 
+  /**
+   * Compute the full or partial map of exported declarations for this library.
+   */
+  _ExportedDeclarations _computeExportedDeclarations() {
+    // If we know exported declarations, return them.
+    if (_exportedTopLevelDeclarations != null) {
+      return new _ExportedDeclarations(0, _exportedTopLevelDeclarations);
+    }
+
+    // If we are already computing exported declarations for this library,
+    // report that we found a cycle.
+    if (_exportDeclarationsId != 0) {
+      return new _ExportedDeclarations(_exportDeclarationsId, null);
+    }
+
+    var declarations = <String, TopLevelDeclaration>{};
+
+    // Give each library a unique identifier.
+    _exportDeclarationsId = _exportDeclarationsNextId++;
+
+    // Append the exported declarations.
+    int firstCycleId = 0;
+    for (int i = 0; i < _exportedFiles.length; i++) {
+      var exported = _exportedFiles[i]._computeExportedDeclarations();
+      if (exported.declarations != null) {
+        for (TopLevelDeclaration t in exported.declarations.values) {
+          if (_exportFilters[i].accepts(t.name)) {
+            declarations[t.name] = t;
+          }
+        }
+      }
+      if (exported.firstCycleId > 0) {
+        if (firstCycleId == 0 || firstCycleId > exported.firstCycleId) {
+          firstCycleId = exported.firstCycleId;
+        }
+      }
+    }
+
+    // If this library is the first component of the cycle, then we are at
+    // the beginning of this cycle, and combination of partial export
+    // namespaces of other exported libraries and declarations of this library
+    // is the full export namespace of this library.
+    if (firstCycleId != 0 && firstCycleId == _exportDeclarationsId) {
+      firstCycleId = 0;
+    }
+
+    // We're done with this library, successfully or not.
+    _exportDeclarationsId = 0;
+
+    // Append the library declarations.
+    declarations.addAll(topLevelDeclarations);
+    for (FileState part in partedFiles) {
+      declarations.addAll(part.topLevelDeclarations);
+    }
+
+    // Record the declarations only if it is the full result.
+    if (firstCycleId == 0) {
+      _exportedTopLevelDeclarations = declarations;
+    }
+
+    // Return the full or partial result.
+    return new _ExportedDeclarations(firstCycleId, declarations);
+  }
+
   CompilationUnit _createEmptyCompilationUnit() {
     var token = new Token.eof(0);
     return astFactory.compilationUnit(token, null, [], [], token)
@@ -708,6 +750,12 @@
    */
   FileState _unresolvedFile;
 
+  /**
+   * The cache of content of files, possibly shared with other file system
+   * states with the same resource provider and the content overlay.
+   */
+  _FileContentCache _fileContentCache;
+
   FileSystemStateTestView _testView;
 
   FileSystemState(
@@ -720,6 +768,8 @@
       this._salt,
       {this.externalSummaries,
       this.parseExceptionHandler}) {
+    _fileContentCache =
+        _FileContentCache.getInstance(_resourceProvider, _contentOverlay);
     _testView = new FileSystemStateTestView(this);
   }
 
@@ -770,7 +820,7 @@
       _uriToFile[uri] = file;
       _addFileWithPath(path, file);
       _pathToCanonicalFile[path] = file;
-      file.refresh();
+      file.refresh(allowCached: true);
     }
     return file;
   }
@@ -810,7 +860,7 @@
       file = new FileState._(this, path, uri, fileUri, source);
       _uriToFile[uri] = file;
       _addFileWithPath(path, file);
-      file.refresh();
+      file.refresh(allowCached: true);
     }
     return file;
   }
@@ -851,9 +901,18 @@
   }
 
   /**
+   * The file with the given [path] might have changed, so ensure that it is
+   * read the next time it is refreshed.
+   */
+  void markFileForReading(String path) {
+    _fileContentCache.remove(path);
+  }
+
+  /**
    * Remove the file with the given [path].
    */
   void removeFile(String path) {
+    markFileForReading(path);
     _uriToFile.clear();
     knownFilePaths.clear();
     _pathToFiles.clear();
@@ -889,4 +948,107 @@
         .where((f) => f._transitiveSignature == null)
         .toSet();
   }
+
+  Set<FileState> get librariesWithComputedExportedDeclarations {
+    return state._uriToFile.values
+        .where((f) => !f.isPart && f._exportedTopLevelDeclarations != null)
+        .toSet();
+  }
+}
+
+/**
+ * The result of computing exported top-level declarations.
+ * It can be full (when [firstCycleId] is zero), or partial (when a cycle)
+ */
+class _ExportedDeclarations {
+  final int firstCycleId;
+  final Map<String, TopLevelDeclaration> declarations;
+
+  _ExportedDeclarations(this.firstCycleId, this.declarations);
+}
+
+/**
+ * Information about the content of a file.
+ */
+class _FileContent {
+  final String path;
+  final bool exists;
+  final String content;
+  final List<int> contentBytes;
+  final String contentHash;
+
+  _FileContent(this.path, this.exists, this.content, this.contentBytes,
+      this.contentHash);
+}
+
+/**
+ * The cache of information about content of files.
+ */
+class _FileContentCache {
+  /**
+   * Weak map of cache instances.
+   *
+   * Outer key is a [FileContentOverlay].
+   * Inner key is a [ResourceProvider].
+   */
+  static final _instances = new Expando<Expando<_FileContentCache>>();
+
+  final ResourceProvider _resourceProvider;
+  final FileContentOverlay _contentOverlay;
+  final Map<String, _FileContent> _pathToFile = {};
+
+  _FileContentCache(this._resourceProvider, this._contentOverlay);
+
+  /**
+   * Return the content of the file with the given [path].
+   *
+   * If [allowCached] is `true`, and the file is in the cache, return the
+   * cached data. Otherwise read the file, compute and cache the data.
+   */
+  _FileContent get(String path, bool allowCached) {
+    var file = allowCached ? _pathToFile[path] : null;
+    if (file == null) {
+      String content;
+      bool exists;
+      try {
+        content = _contentOverlay[path];
+        content ??= _resourceProvider.getFile(path).readAsStringSync();
+        exists = true;
+      } catch (_) {
+        content = '';
+        exists = false;
+      }
+
+      List<int> contentBytes = utf8.encode(content);
+
+      List<int> contentHashBytes = md5.convert(contentBytes).bytes;
+      String contentHash = hex.encode(contentHashBytes);
+
+      file = new _FileContent(path, exists, content, contentBytes, contentHash);
+      _pathToFile[path] = file;
+    }
+    return file;
+  }
+
+  /**
+   * Remove the file with the given [path] from the cache.
+   */
+  void remove(String path) {
+    _pathToFile.remove(path);
+  }
+
+  static _FileContentCache getInstance(
+      ResourceProvider resourceProvider, FileContentOverlay contentOverlay) {
+    var providerToInstance = _instances[contentOverlay];
+    if (providerToInstance == null) {
+      providerToInstance = new Expando<_FileContentCache>();
+      _instances[contentOverlay] = providerToInstance;
+    }
+    var instance = providerToInstance[resourceProvider];
+    if (instance == null) {
+      instance = new _FileContentCache(resourceProvider, contentOverlay);
+      providerToInstance[resourceProvider] = instance;
+    }
+    return instance;
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
index 5cfb130..6c08079 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
@@ -144,6 +144,7 @@
    * Adds the given [path] to the set of "added files".
    */
   void addFile(String path) {
+    _fsState.markFileForReading(path);
     addedFiles.add(path);
     _pendingFiles.add(path);
     _changeHook();
@@ -166,6 +167,7 @@
     if (addedFiles.contains(path)) {
       _pendingChangedFiles.add(path);
     }
+    _fsState.markFileForReading(path);
     _changeHook();
   }
 
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 3156fe9..56eb475 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -1667,6 +1667,7 @@
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.keyword, other.keyword) &&
         isEqualNodes(node.uri, other.uri) &&
+        _isEqualNodeLists(node.configurations, other.configurations) &&
         isEqualTokens(node.deferredKeyword, other.deferredKeyword) &&
         isEqualTokens(node.asKeyword, other.asKeyword) &&
         isEqualNodes(node.prefix, other.prefix) &&
diff --git a/pkg/analyzer/lib/src/dart/sdk/patch.dart b/pkg/analyzer/lib/src/dart/sdk/patch.dart
index 8057686..657fde0 100644
--- a/pkg/analyzer/lib/src/dart/sdk/patch.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/patch.dart
@@ -2,12 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.src.dart.sdk.patch;
-
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/parser.dart';
@@ -95,7 +94,7 @@
   }
 
   String _getLocationDesc3(CompilationUnit unit, int offset) {
-    LineInfo_Location location = unit.lineInfo.getLocation(offset);
+    CharacterLocation location = unit.lineInfo.getLocation(offset);
     return 'the line ${location.lineNumber}';
   }
 
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 9e84278..63cfad3 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -3735,7 +3735,8 @@
   static const StaticWarningCode IMPORT_DUPLICATED_LIBRARY_NAMED =
       const StaticWarningCode('IMPORT_DUPLICATED_LIBRARY_NAMED',
           "The imported libraries '{0}' and '{1}' can't have the same name '{2}'.",
-          correction: "Try adding a hide clause to one of the imports.");
+          correction: "Try adding a hide clause to one of the imports.",
+          isStrongModeError: false);
 
   /**
    * 14.1 Imports: It is a static warning if the specified URI of a deferred
@@ -5027,19 +5028,6 @@
       "The type of '{0}' can't be inferred because {1} expressions aren't supported.",
       correction: "Try adding an explicit type for '{0}'.");
 
-  /**
-   * This warning is generated when a function type is assigned to a function
-   * typed location, and the assignment will be invalid after fuzzy arrows
-   * (the treatment of dynamic as bottom in certain locations) is removed.
-   *
-   */
-  static const StrongModeCode USES_DYNAMIC_AS_BOTTOM = const StrongModeCode(
-      ErrorType.STATIC_TYPE_WARNING,
-      'USES_DYNAMIC_AS_BOTTOM',
-      "A function of type '{0}' can't be assigned to a location of type '{1}'.",
-      correction: "Try changing the parameter types of the function or of the "
-          " receiving location.");
-
   @override
   final ErrorType type;
 
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 742643d..997767c 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -874,8 +874,17 @@
     Expression condition = pop();
     switch (kind) {
       case Assert.Expression:
-        throw new UnimplementedError(
-            'assert expressions are not yet supported');
+        // The parser has already reported an error indicating that assert
+        // cannot be used in an expression. Insert a placeholder.
+        List<Expression> arguments = <Expression>[condition];
+        if (message != null) {
+          arguments.add(message);
+        }
+        push(ast.functionExpressionInvocation(
+            ast.simpleIdentifier(assertKeyword),
+            null,
+            ast.argumentList(
+                leftParenthesis, arguments, leftParenthesis?.endGroup)));
         break;
       case Assert.Initializer:
         push(ast.assertInitializer(assertKeyword, leftParenthesis, condition,
@@ -1097,6 +1106,15 @@
     }
   }
 
+  @override
+  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+      Token varFinalOrConst) {
+    push(new _Modifiers()
+      ..covariantKeyword = covariantToken
+      ..finalConstOrVarKeyword = varFinalOrConst);
+  }
+
+  @override
   void endFormalParameter(Token thisKeyword, Token periodAfterThis,
       Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
     assert(optionalOrNull('this', thisKeyword));
@@ -1460,23 +1478,6 @@
     push(ast.postfixExpression(expression, operator));
   }
 
-  void handleModifier(Token token) {
-    assert(token.isModifier);
-    debugEvent("Modifier");
-
-    push(token);
-  }
-
-  void handleModifiers(int count) {
-    debugEvent("Modifiers");
-
-    if (count == 0) {
-      push(NullValue.Modifiers);
-    } else {
-      push(new _Modifiers(popTypedList(count)));
-    }
-  }
-
   void beginTopLevelMethod(Token lastConsumed, Token externalToken) {
     push(new _Modifiers()..externalKeyword = externalToken);
   }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index ad983e9..45b1794 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.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.
 
-library analyzer.src.generated.engine;
-
 import 'dart:async';
 import 'dart:collection';
 import 'dart:typed_data';
@@ -27,14 +25,14 @@
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
 import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/general.dart';
 import 'package:analyzer/src/task/html.dart';
 import 'package:analyzer/src/task/manager.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/task/yaml.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:front_end/src/base/api_signature.dart';
 import 'package:front_end/src/base/timestamped_data.dart';
 import 'package:front_end/src/fasta/scanner/token.dart';
diff --git a/pkg/analyzer/lib/src/generated/gn.dart b/pkg/analyzer/lib/src/generated/gn.dart
index b55f96b..51440cb 100644
--- a/pkg/analyzer/lib/src/generated/gn.dart
+++ b/pkg/analyzer/lib/src/generated/gn.dart
@@ -234,8 +234,9 @@
     File config = provider.getFile(pathContext.join(root, '.config'));
     if (config.exists) {
       String content = config.readAsStringSync();
-      Match match = new RegExp(r'^FUCHSIA_BUILD_DIR="(.+)"$', multiLine: true)
-          .firstMatch(content);
+      Match match =
+          new RegExp(r'^FUCHSIA_BUILD_DIR=["\x27](.+)["\x27]$', multiLine: true)
+              .firstMatch(content);
       if (match != null) {
         String path = match.group(1);
         if (pathContext.isRelative(path)) {
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index de9c88f..d693693 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -2,15 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.src.generated.source;
-
 import 'dart:collection';
-import "dart:math" as math;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
@@ -19,6 +15,8 @@
 import 'package:package_config/packages.dart';
 import 'package:path/path.dart' as pathos;
 
+export 'package:analyzer/source/line_info.dart' show LineInfo;
+export 'package:analyzer/source/source_range.dart';
 export 'package:front_end/src/base/source.dart' show Source;
 export 'package:front_end/src/base/uri_kind.dart' show UriKind;
 
@@ -199,107 +197,10 @@
 }
 
 /**
- * Information about line and column information within a source file.
- */
-class LineInfo {
-  /**
-   * A list containing the offsets of the first character of each line in the
-   * source code.
-   */
-  final List<int> lineStarts;
-
-  /**
-   * The zero-based [lineStarts] index resulting from the last call to
-   * [getLocation].
-   */
-  int _previousLine = 0;
-
-  /**
-   * Initialize a newly created set of line information to represent the data
-   * encoded in the given list of [lineStarts].
-   */
-  LineInfo(this.lineStarts) {
-    if (lineStarts == null) {
-      throw new ArgumentError("lineStarts must be non-null");
-    } else if (lineStarts.length < 1) {
-      throw new ArgumentError("lineStarts must be non-empty");
-    }
-  }
-
-  /**
-   * Initialize a newly created set of line information corresponding to the
-   * given file [content].
-   */
-  factory LineInfo.fromContent(String content) =>
-      new LineInfo(StringUtilities.computeLineStarts(content));
-
-  /**
-   * The number of lines.
-   */
-  int get lineCount => lineStarts.length;
-
-  /**
-   * Return the location information for the character at the given [offset].
-   */
-  LineInfo_Location getLocation(int offset) {
-    var min = 0;
-    var max = lineStarts.length - 1;
-
-    // Subsequent calls to [getLocation] are often for offsets near each other.
-    // To take advantage of that, we cache the index of the line start we found
-    // when this was last called. If the current offset is on that line or
-    // later, we'll skip those early indices completely when searching.
-    if (offset >= lineStarts[_previousLine]) {
-      min = _previousLine;
-
-      // Before kicking off a full binary search, do a quick check here to see
-      // if the new offset is on that exact line.
-      if (min == lineStarts.length - 1 || offset < lineStarts[min + 1]) {
-        return new LineInfo_Location(min + 1, offset - lineStarts[min] + 1);
-      }
-    }
-
-    // Binary search to fine the line containing this offset.
-    while (min < max) {
-      var midpoint = (max - min + 1) ~/ 2 + min;
-
-      if (lineStarts[midpoint] > offset) {
-        max = midpoint - 1;
-      } else {
-        min = midpoint;
-      }
-    }
-
-    _previousLine = min;
-
-    return new LineInfo_Location(min + 1, offset - lineStarts[min] + 1);
-  }
-
-  /**
-   * Return the offset of the first character on the line with the given
-   * [lineNumber].
-   */
-  int getOffsetOfLine(int lineNumber) {
-    if (lineNumber < 0 || lineNumber >= lineCount) {
-      throw new ArgumentError(
-          'Invalid line number: $lineNumber; must be between 0 and ${lineCount - 1}');
-    }
-    return lineStarts[lineNumber];
-  }
-
-  /**
-   * Return the offset of the first character on the line following the line
-   * containing the given [offset].
-   */
-  int getOffsetOfLineAfter(int offset) {
-    return getOffsetOfLine(getLocation(offset).lineNumber + 1);
-  }
-}
-
-/**
  * Instances of the class `Location` represent the location of a character as a line and
  * column pair.
  */
+@deprecated
 class LineInfo_Location {
   /**
    * The one-based index of the line containing the character.
@@ -312,11 +213,8 @@
   final int columnNumber;
 
   /**
-   * Initialize a newly created location to represent the location of the character at the given
-   * line and column position.
-   *
-   * @param lineNumber the one-based index of the line containing the character
-   * @param columnNumber the one-based index of the column containing the character
+   * Initialize a newly created location to represent the location of the
+   * character at the given [lineNumber] and [columnNumber].
    */
   LineInfo_Location(this.lineNumber, this.columnNumber);
 
@@ -607,131 +505,6 @@
 }
 
 /**
- * A source range defines an [Element]'s source coordinates relative to its [Source].
- */
-class SourceRange {
-  /**
-   * An empty [SourceRange] with offset `0` and length `0`.
-   */
-  static SourceRange EMPTY = new SourceRange(0, 0);
-
-  /**
-   * The 0-based index of the first character of the source code for this element, relative to the
-   * source buffer in which this element is contained.
-   */
-  final int offset;
-
-  /**
-   * The number of characters of the source code for this element, relative to the source buffer in
-   * which this element is contained.
-   */
-  final int length;
-
-  /**
-   * Initialize a newly created source range using the given offset and the given length.
-   *
-   * @param offset the given offset
-   * @param length the given length
-   */
-  SourceRange(this.offset, this.length);
-
-  /**
-   * @return the 0-based index of the after-last character of the source code for this element,
-   *         relative to the source buffer in which this element is contained.
-   */
-  int get end => offset + length;
-
-  @override
-  int get hashCode => 31 * offset + length;
-
-  @override
-  bool operator ==(Object other) {
-    return other is SourceRange &&
-        other.offset == offset &&
-        other.length == length;
-  }
-
-  /**
-   * @return `true` if <code>x</code> is in [offset, offset + length) interval.
-   */
-  bool contains(int x) => offset <= x && x < offset + length;
-
-  /**
-   * @return `true` if <code>x</code> is in (offset, offset + length) interval.
-   */
-  bool containsExclusive(int x) => offset < x && x < offset + length;
-
-  /**
-   * @return `true` if <code>otherRange</code> covers this [SourceRange].
-   */
-  bool coveredBy(SourceRange otherRange) => otherRange.covers(this);
-
-  /**
-   * @return `true` if this [SourceRange] covers <code>otherRange</code>.
-   */
-  bool covers(SourceRange otherRange) =>
-      offset <= otherRange.offset && otherRange.end <= end;
-
-  /**
-   * @return `true` if this [SourceRange] ends in <code>otherRange</code>.
-   */
-  bool endsIn(SourceRange otherRange) {
-    int thisEnd = end;
-    return otherRange.contains(thisEnd);
-  }
-
-  /**
-   * @return the expanded instance of [SourceRange], which has the same center.
-   */
-  SourceRange getExpanded(int delta) =>
-      new SourceRange(offset - delta, delta + length + delta);
-
-  /**
-   * @return the instance of [SourceRange] with end moved on "delta".
-   */
-  SourceRange getMoveEnd(int delta) => new SourceRange(offset, length + delta);
-
-  /**
-   * @return the expanded translated of [SourceRange], with moved start and the same length.
-   */
-  SourceRange getTranslated(int delta) =>
-      new SourceRange(offset + delta, length);
-
-  /**
-   * @return the minimal [SourceRange] that cover this and the given [SourceRange]s.
-   */
-  SourceRange getUnion(SourceRange other) {
-    int newOffset = math.min(offset, other.offset);
-    int newEnd = math.max(offset + length, other.offset + other.length);
-    return new SourceRange(newOffset, newEnd - newOffset);
-  }
-
-  /**
-   * @return `true` if this [SourceRange] intersects with given.
-   */
-  bool intersects(SourceRange other) {
-    if (other == null) {
-      return false;
-    }
-    if (end <= other.offset) {
-      return false;
-    }
-    if (offset >= other.end) {
-      return false;
-    }
-    return true;
-  }
-
-  /**
-   * Return `true` if this [SourceRange] starts in the [otherRange].
-   */
-  bool startsIn(SourceRange otherRange) => otherRange.contains(offset);
-
-  @override
-  String toString() => '[offset=$offset, length=$length]';
-}
-
-/**
  * The abstract class `UriResolver` defines the behavior of objects that are used to resolve
  * URI's for a source factory. Subclasses of this class are expected to resolve a single scheme of
  * absolute URI.
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 06b9b36..16ad79b 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -103,12 +103,6 @@
     return ft.parameters.any((p) => predicate(p.type));
   }
 
-  FunctionType functionTypeToConcreteType(FunctionType t) =>
-      _replaceDynamicParameters(t, typeProvider.objectType);
-
-  FunctionType functionTypeToFuzzyType(FunctionType t) =>
-      _replaceDynamicParameters(t, typeProvider.nullType);
-
   /// Given a type t, if t is an interface type with a call method
   /// defined, return the function type for the call method, otherwise
   /// return null.
@@ -445,12 +439,6 @@
       }
     }
 
-    // A fuzzy arrow subtype
-    if (toType is FunctionType &&
-        isSubtypeOf(fromType, functionTypeToFuzzyType(toType))) {
-      return true;
-    }
-
     if (isDeclarationCast) {
       if (!declarationCasts) {
         return false;
@@ -487,14 +475,6 @@
       return true;
     }
 
-    // A reverse fuzzy arrow subtype.  We want to disallow this soon, but
-    // we have to let this pass for now because of
-    // https://github.com/dart-lang/sdk/issues/32114
-    if (fromType is FunctionType &&
-        isSubtypeOf(toType, functionTypeToFuzzyType(fromType))) {
-      return true;
-    }
-
     return false;
   }
 
@@ -804,9 +784,6 @@
   }
 
   /// Check that [f1] is a subtype of [f2].
-  ///
-  /// This will always assume function types use fuzzy arrows, in other words
-  /// that dynamic parameters of f1 and f2 are treated as bottom.
   bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2) {
     return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds,
         parameterRelation: (p1, p2) => isSubtypeOf(p2.type, p1.type));
@@ -959,31 +936,6 @@
     return _isFunctionSubtypeOf(t1, t2);
   }
 
-  FunctionType _replaceDynamicParameters(FunctionType t, DartType replaceWith) {
-    if (!t.parameters.any((p) => p.type.isDynamic)) {
-      return t;
-    }
-    ParameterElement shave(ParameterElement p) {
-      if (p.type.isDynamic) {
-        return new ParameterElementImpl.synthetic(
-            // ignore: deprecated_member_use
-            p.name,
-            replaceWith,
-            // ignore: deprecated_member_use
-            p.parameterKind);
-      }
-      return p;
-    }
-
-    List<ParameterElement> parameters = t.parameters.map(shave).toList();
-    FunctionElementImpl function = new FunctionElementImpl("", -1);
-    function.isSynthetic = true;
-    function.returnType = t.returnType;
-    function.shareTypeParameters(t.typeFormals);
-    function.shareParameters(parameters);
-    return function.type = new FunctionTypeImpl(function);
-  }
-
   DartType _substituteForUnknownType(DartType type, {bool lowerBound: false}) {
     if (identical(type, UnknownInferredType.instance)) {
       if (lowerBound) {
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 302e7fc..8f774d5 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -208,7 +208,7 @@
   }
 }
 
-/// Filtered lints are ommitted from linter output.
+/// Filtered lints are omitted from linter output.
 abstract class LintFilter {
   bool filter(AnalysisError lint);
 }
diff --git a/pkg/analyzer/lib/src/lint/options_rule_validator.dart b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
index 622aa31..2d6911a 100644
--- a/pkg/analyzer/lib/src/lint/options_rule_validator.dart
+++ b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/plugin/options.dart';
 import 'package:analyzer/src/util/yaml.dart';
 import 'package:yaml/yaml.dart';
 
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index fc652f0..7d5a4a3 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -3,15 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/error/error.dart' show AnalysisError;
-import 'package:analyzer/plugin/task.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show InternalAnalysisContext;
+import 'package:analyzer/src/plugin/task.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/dart_work_manager.dart';
 import 'package:analyzer/src/task/html.dart';
 import 'package:analyzer/src/task/html_work_manager.dart';
 import 'package:analyzer/src/task/options_work_manager.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:plugin/plugin.dart';
 
 /**
@@ -172,8 +172,8 @@
 
 /**
  * Annotation describing the relationship between a getter in [EnginePlugin]
- * and the associated identifier (in '../../plugin/task.dart') which can be
- * passed to the extension manager to populate it.
+ * and the associated identifier (in 'task.dart') which can be passed to the
+ * extension manager to populate it.
  *
  * This annotation is not used at runtime; it is used to aid in static analysis
  * of the task model during development.
diff --git a/pkg/analyzer/lib/plugin/options.dart b/pkg/analyzer/lib/src/plugin/options.dart
similarity index 100%
rename from pkg/analyzer/lib/plugin/options.dart
rename to pkg/analyzer/lib/src/plugin/options.dart
diff --git a/pkg/analyzer/lib/plugin/task.dart b/pkg/analyzer/lib/src/plugin/task.dart
similarity index 96%
rename from pkg/analyzer/lib/plugin/task.dart
rename to pkg/analyzer/lib/src/plugin/task.dart
index a9059af..8292485 100644
--- a/pkg/analyzer/lib/plugin/task.dart
+++ b/pkg/analyzer/lib/src/plugin/task.dart
@@ -6,11 +6,9 @@
  * Support for client code that extends the analysis engine by adding new
  * analysis tasks.
  */
-library analyzer.plugin.task;
-
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:plugin/plugin.dart';
 
 /**
diff --git a/pkg/analyzer/lib/src/source/custom_resolver.dart b/pkg/analyzer/lib/src/source/custom_resolver.dart
new file mode 100644
index 0000000..c50c77e
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/custom_resolver.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+class CustomUriResolver extends UriResolver {
+  final ResourceProvider resourceProvider;
+  final Map<String, String> _urlMappings;
+
+  CustomUriResolver(this.resourceProvider, this._urlMappings);
+
+  @override
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+    String mapping = _urlMappings[uri.toString()];
+    if (mapping == null) {
+      return null;
+    }
+    Uri fileUri = new Uri.file(mapping);
+    if (!fileUri.isAbsolute) {
+      return null;
+    }
+    return resourceProvider
+        .getFile(resourceProvider.pathContext.fromUri(fileUri))
+        .createSource(actualUri ?? uri);
+  }
+}
diff --git a/pkg/analyzer/lib/src/source/package_map_provider.dart b/pkg/analyzer/lib/src/source/package_map_provider.dart
new file mode 100644
index 0000000..dff066c
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/package_map_provider.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+
+/**
+ * Data structure output by PackageMapProvider.  This contains both the package
+ * map and dependency information.
+ */
+class PackageMapInfo {
+  /**
+   * The package map itself.  This is a map from package name to a list of
+   * the folders containing source code for the package.
+   *
+   * `null` if an error occurred.
+   */
+  Map<String, List<Folder>> packageMap;
+
+  /**
+   * Dependency information.  This is a set of the paths which were consulted
+   * in order to generate the package map.  If any of these files is
+   * modified, the package map will need to be regenerated.
+   */
+  Set<String> dependencies;
+
+  PackageMapInfo(this.packageMap, this.dependencies);
+}
+
+/**
+ * A PackageMapProvider is an entity capable of determining the mapping from
+ * package name to source directory for a given folder.
+ */
+abstract class PackageMapProvider {
+  /**
+   * Compute a package map for the given folder, if possible.
+   *
+   * If a package map can't be computed (e.g. because an error occurred), a
+   * [PackageMapInfo] will still be returned, but its packageMap will be null.
+   */
+  PackageMapInfo computePackageMap(Folder folder);
+}
diff --git a/pkg/analyzer/lib/src/source/path_filter.dart b/pkg/analyzer/lib/src/source/path_filter.dart
new file mode 100644
index 0000000..c43cae1
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/path_filter.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/util/glob.dart';
+import 'package:path/path.dart' as path;
+
+/// Filter paths against a set of [_ignorePatterns] relative to a [root]
+/// directory. Paths outside of [root] are also ignored.
+class PathFilter {
+  /// The path context to use when manipulating paths.
+  final path.Context pathContext;
+
+  /// Path that all ignore patterns are relative to.
+  final String root;
+
+  /// List of ignore patterns that paths are tested against.
+  final List<Glob> _ignorePatterns = new List<Glob>();
+
+  /// Construct a new path filter rooted at [root] with [ignorePatterns].
+  /// If [pathContext] is not specified, then the system path context is used.
+  PathFilter(this.root, List<String> ignorePatterns, [path.Context pathContext])
+      : this.pathContext = pathContext ?? path.context {
+    setIgnorePatterns(ignorePatterns);
+  }
+
+  /// Returns true if [path] should be ignored. A path is ignored if it is not
+  /// contained in [root] or matches one of the ignore patterns.
+  /// [path] is absolute or relative to [root].
+  bool ignored(String path) {
+    path = _canonicalize(path);
+    return !_contained(path) || _match(path);
+  }
+
+  /// Set the ignore patterns.
+  void setIgnorePatterns(List<String> ignorePatterns) {
+    _ignorePatterns.clear();
+    if (ignorePatterns != null) {
+      for (var ignorePattern in ignorePatterns) {
+        _ignorePatterns.add(new Glob(pathContext.separator, ignorePattern));
+      }
+    }
+  }
+
+  @override
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    for (Glob pattern in _ignorePatterns) {
+      sb.write('$pattern ');
+    }
+    sb.writeln('');
+    return sb.toString();
+  }
+
+  /// Returns the absolute path of [path], relative to [root].
+  String _canonicalize(String path) =>
+      pathContext.normalize(pathContext.join(root, path));
+
+  /// Returns true when [path] is contained inside [root].
+  bool _contained(String path) => path.startsWith(root);
+
+  /// Returns true if [path] matches any ignore patterns.
+  bool _match(String path) {
+    path = _relative(path);
+    for (Glob glob in _ignorePatterns) {
+      if (glob.matches(path)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Returns the relative portion of [path] from [root].
+  String _relative(String path) => pathContext.relative(path, from: root);
+}
diff --git a/pkg/analyzer/lib/src/source/pub_package_map_provider.dart b/pkg/analyzer/lib/src/source/pub_package_map_provider.dart
new file mode 100644
index 0000000..bcff683
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/pub_package_map_provider.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:core';
+import 'dart:io' as io;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+
+/**
+ * The function used to run pub list.
+ */
+typedef io.ProcessResult RunPubList(Folder folder);
+
+/**
+ * Implementation of PackageMapProvider that operates by executing pub.
+ */
+class PubPackageMapProvider implements PackageMapProvider {
+  static const String PUB_LIST_COMMAND = 'list-package-dirs';
+
+  /**
+   * The name of the 'pubspec.lock' file, which we assume is the dependency
+   * in the event that [PUB_LIST_COMMAND] fails.
+   */
+  static const String PUBSPEC_LOCK_NAME = 'pubspec.lock';
+
+  /**
+   * [ResourceProvider] that is used to create the [Folder]s that populate the
+   * package map.
+   */
+  final ResourceProvider resourceProvider;
+
+  /**
+   * Sdk that we use to find the pub executable.
+   */
+  final FolderBasedDartSdk sdk;
+
+  /**
+   * The function used to run pub list.
+   */
+  RunPubList _runPubList;
+
+  /**
+   * Construct a new instance.
+   * A [RunPubList] implementation may be injected for testing
+   */
+  PubPackageMapProvider(this.resourceProvider, this.sdk, [this._runPubList]) {
+    if (_runPubList == null) {
+      _runPubList = _runPubListDefault;
+    }
+  }
+
+  @override
+  PackageMapInfo computePackageMap(Folder folder) {
+    // If the pubspec.lock file does not exist, no need to run anything.
+    {
+      String lockPath = getPubspecLockPath(folder);
+      if (!resourceProvider.getFile(lockPath).exists) {
+        return computePackageMapError(folder);
+      }
+    }
+    // TODO(paulberry) make this asynchronous so that we can (a) do other
+    // analysis while it's in progress, and (b) time out if it takes too long
+    // to respond.
+    io.ProcessResult result;
+    try {
+      result = _runPubList(folder);
+    } on io.ProcessException catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Error running pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
+    }
+    if (result == null || result.exitCode != 0) {
+      String exitCode =
+          result != null ? 'exit code ${result.exitCode}' : 'null';
+      AnalysisEngine.instance.logger
+          .logInformation("pub $PUB_LIST_COMMAND failed: $exitCode");
+      return computePackageMapError(folder);
+    }
+    try {
+      PackageMapInfo packageMap =
+          parsePackageMap(json.decode(result.stdout), folder);
+      return packageMap;
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logError(
+          "Malformed output from pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
+    }
+
+    return computePackageMapError(folder);
+  }
+
+  /**
+   * Create a PackageMapInfo object representing an error condition.
+   */
+  PackageMapInfo computePackageMapError(Folder folder) {
+    // Even if an error occurs, we still need to know the dependencies, so that
+    // we'll know when to try running "pub list-package-dirs" again.
+    // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when
+    // an error occurs, so just assume there is one dependency, "pubspec.lock".
+    String lockPath = getPubspecLockPath(folder);
+    List<String> dependencies = <String>[lockPath];
+    return new PackageMapInfo(null, dependencies.toSet());
+  }
+
+  /**
+   * Return the path to the `pubspec.lock` file in the given [folder].
+   */
+  String getPubspecLockPath(Folder folder) =>
+      resourceProvider.pathContext.join(folder.path, PUBSPEC_LOCK_NAME);
+
+  /**
+   * Decode the JSON output from pub into a package map.  Paths in the
+   * output are considered relative to [folder].
+   */
+  PackageMapInfo parsePackageMap(Map obj, Folder folder) {
+    // The output of pub looks like this:
+    // {
+    //   "packages": {
+    //     "foo": "path/to/foo",
+    //     "bar": ["path/to/bar1", "path/to/bar2"],
+    //     "myapp": "path/to/myapp",  // self link is included
+    //   },
+    //   "input_files": [
+    //     "path/to/myapp/pubspec.lock"
+    //   ]
+    // }
+    Map<String, List<Folder>> packageMap = new HashMap<String, List<Folder>>();
+    Map packages = obj['packages'];
+    processPaths(String packageName, List paths) {
+      List<Folder> folders = <Folder>[];
+      for (var path in paths) {
+        if (path is String) {
+          Resource resource = folder.getChildAssumingFolder(path);
+          if (resource is Folder) {
+            folders.add(resource);
+          }
+        }
+      }
+      if (folders.isNotEmpty) {
+        packageMap[packageName] = folders;
+      }
+    }
+
+    packages.forEach((key, value) {
+      if (value is String) {
+        processPaths(key, [value]);
+      } else if (value is List) {
+        processPaths(key, value);
+      }
+    });
+    Set<String> dependencies = new Set<String>();
+    List inputFiles = obj['input_files'];
+    if (inputFiles != null) {
+      for (var path in inputFiles) {
+        if (path is String) {
+          dependencies.add(folder.canonicalizePath(path));
+        }
+      }
+    }
+    return new PackageMapInfo(packageMap, dependencies);
+  }
+
+  /**
+   * Run pub list to determine the packages and input files.
+   */
+  io.ProcessResult _runPubListDefault(Folder folder) {
+    String executablePath = sdk.pubExecutable.path;
+    List<String> arguments = [PUB_LIST_COMMAND];
+    String workingDirectory = folder.path;
+    int subprocessId = AnalysisEngine.instance.instrumentationService
+        .logSubprocessStart(executablePath, arguments, workingDirectory);
+    io.ProcessResult result = io.Process
+        .runSync(executablePath, arguments, workingDirectory: workingDirectory);
+    AnalysisEngine.instance.instrumentationService.logSubprocessResult(
+        subprocessId, result.exitCode, result.stdout, result.stderr);
+    return result;
+  }
+}
diff --git a/pkg/analyzer/lib/src/source/sdk_ext.dart b/pkg/analyzer/lib/src/source/sdk_ext.dart
new file mode 100644
index 0000000..30be82a
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/sdk_ext.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:core';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
+import 'package:analyzer/src/source/package_map_provider.dart'
+    show PackageMapProvider;
+import 'package:path/path.dart' as pathos;
+
+/// Given a packageMap (see [PackageMapProvider]), check in each package's lib
+/// directory for the existence of a `_sdkext` file. This file must contain a
+/// JSON encoded map. Each key in the map is a `dart:` library name. Each value
+/// is a path (relative to the directory containing `_sdkext`) to a dart script
+/// for the given library. For example:
+/// {
+///   "dart:sky": "../sdk_ext/dart_sky.dart"
+/// }
+///
+/// If a key doesn't begin with `dart:` it is ignored.
+class SdkExtUriResolver extends UriResolver {
+  static const String SDK_EXT_NAME = '_sdkext';
+  static const String DART_COLON_PREFIX = 'dart:';
+
+  final Map<String, String> _urlMappings = <String, String>{};
+
+  /**
+   * The absolute paths of the extension files that contributed to the
+   * [_urlMappings].
+   */
+  final List<String> extensionFilePaths = <String>[];
+
+  /// Construct a [SdkExtUriResolver] from a package map
+  /// (see [PackageMapProvider]).
+  SdkExtUriResolver(Map<String, List<Folder>> packageMap) {
+    if (packageMap == null) {
+      return;
+    }
+    packageMap.forEach(_processPackage);
+  }
+
+  /// Number of sdk extensions.
+  int get length => _urlMappings.length;
+
+  /**
+   * Return a table mapping the names of extensions to the paths where those
+   * extensions can be found.
+   */
+  Map<String, String> get urlMappings =>
+      new Map<String, String>.from(_urlMappings);
+
+  /// Return the path mapping for [libName] or null if there is none.
+  String operator [](String libName) => _urlMappings[libName];
+
+  /// Programmatically add a new SDK extension given a JSON description
+  /// ([sdkExtJSON]) and a lib directory ([libDir]).
+  void addSdkExt(String sdkExtJSON, Folder libDir) {
+    _processSdkExt(sdkExtJSON, libDir);
+  }
+
+  @override
+  Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
+    String libraryName = _libraryName(importUri);
+    String partPath = _partPath(importUri);
+    // Lookup library name in mappings.
+    String mapping = _urlMappings[libraryName];
+    if (mapping == null) {
+      // Not found.
+      return null;
+    }
+    // This mapping points to the main entry file of the sdk extension.
+    Uri libraryEntry = new Uri.file(mapping);
+    if (!libraryEntry.isAbsolute) {
+      // We expect an absolute path.
+      return null;
+    }
+
+    if (partPath != null) {
+      return _resolvePart(libraryEntry, partPath, importUri);
+    } else {
+      return _resolveEntry(libraryEntry, importUri);
+    }
+  }
+
+  @override
+  Uri restoreAbsolute(Source source) {
+    String extensionName = _findExtensionNameFor(source.fullName);
+    if (extensionName != null) {
+      return Uri.parse(extensionName);
+    }
+    // TODO(johnmccutchan): Handle restoring parts.
+    return null;
+  }
+
+  /// Return the extension name for [fullName] or `null`.
+  String _findExtensionNameFor(String fullName) {
+    var result;
+    _urlMappings.forEach((extensionName, pathMapping) {
+      if (pathMapping == fullName) {
+        result = extensionName;
+      }
+    });
+    return result;
+  }
+
+  /// Return the library name of [importUri].
+  String _libraryName(Uri importUri) {
+    var uri = importUri.toString();
+    int index = uri.indexOf('/');
+    if (index >= 0) {
+      return uri.substring(0, index);
+    }
+    return uri;
+  }
+
+  /// Return the part path of [importUri].
+  String _partPath(Uri importUri) {
+    var uri = importUri.toString();
+    int index = uri.indexOf('/');
+    if (index >= 0) {
+      return uri.substring(index + 1);
+    }
+    return null;
+  }
+
+  /// Given a package [name] and a list of folders ([libDirs]),
+  /// add any found sdk extensions.
+  void _processPackage(String name, List<Folder> libDirs) {
+    for (var libDir in libDirs) {
+      var sdkExt = _readDotSdkExt(libDir);
+      if (sdkExt != null) {
+        _processSdkExt(sdkExt, libDir);
+      }
+    }
+  }
+
+  /// Given the JSON for an SDK extension ([sdkExtJSON]) and a folder
+  /// ([libDir]), setup the uri mapping.
+  void _processSdkExt(String sdkExtJSON, Folder libDir) {
+    var sdkExt;
+    try {
+      sdkExt = json.decode(sdkExtJSON);
+    } catch (e) {
+      return;
+    }
+    if ((sdkExt == null) || (sdkExt is! Map)) {
+      return;
+    }
+    bool contributed = false;
+    sdkExt.forEach((k, v) {
+      if (_processSdkExtension(k, v, libDir)) {
+        contributed = true;
+      }
+    });
+    if (contributed) {
+      extensionFilePaths.add(libDir.getChild(SDK_EXT_NAME).path);
+    }
+  }
+
+  /// Install the mapping from [name] to [libDir]/[file].
+  bool _processSdkExtension(String name, String file, Folder libDir) {
+    if (!name.startsWith(DART_COLON_PREFIX)) {
+      // SDK extensions must begin with 'dart:'.
+      return false;
+    }
+    var key = name;
+    var value = libDir.canonicalizePath(file);
+    _urlMappings[key] = value;
+    return true;
+  }
+
+  /// Read the contents of [libDir]/[SDK_EXT_NAME] as a string.
+  /// Returns null if the file doesn't exist.
+  String _readDotSdkExt(Folder libDir) {
+    File file = libDir.getChild(SDK_EXT_NAME);
+    try {
+      return file.readAsStringSync();
+    } on FileSystemException {
+      // File can't be read.
+      return null;
+    }
+  }
+
+  /// Resolve an import of an sdk extension.
+  Source _resolveEntry(Uri libraryEntry, Uri importUri) {
+    // Library entry.
+    JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
+    return new FileBasedSource(javaFile, importUri);
+  }
+
+  /// Resolve a 'part' statement inside an sdk extension.
+  Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
+    // Library part.
+    var directory = pathos.dirname(libraryEntry.path);
+    var partUri = new Uri.file(pathos.join(directory, partPath));
+    assert(partUri.isAbsolute);
+    JavaFile javaFile = new JavaFile.fromUri(partUri);
+    return new FileBasedSource(javaFile, importUri);
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/expr_builder.dart b/pkg/analyzer/lib/src/summary/expr_builder.dart
index 1a57d3c..63bd2b3 100644
--- a/pkg/analyzer/lib/src/summary/expr_builder.dart
+++ b/pkg/analyzer/lib/src/summary/expr_builder.dart
@@ -426,12 +426,12 @@
   PropertyAccessorElement _getStringLengthElement() =>
       resynthesizer.typeProvider.stringType.getGetter('length');
 
-  FormalParameter _makeParameter(ParameterElementImpl param) {
+  FormalParameter _makeParameter(ParameterElement param) {
     SimpleFormalParameterImpl simpleParam =
         AstTestFactory.simpleFormalParameter(null, param.name);
     simpleParam.identifier.staticElement = param;
     simpleParam.element = param;
-    var unlinkedParam = param.unlinkedParam;
+    var unlinkedParam = (param as ParameterElementImpl).unlinkedParam;
     if (unlinkedParam.kind == UnlinkedParamKind.positional) {
       return AstTestFactory.positionalFormalParameter(simpleParam, null);
     } else if (unlinkedParam.kind == UnlinkedParamKind.named) {
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 7554f34..fa604ed 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -4130,6 +4130,27 @@
   @override
   bool get isExplicitlyCovariant => enclosingElement.variable.isCovariant;
 
+  bool get isInitializingFormal => unlinkedParam.isInitializingFormal;
+
+  @override
+  bool get isNamed => parameterKind == ParameterKind.NAMED;
+
+  @override
+  bool get isNotOptional => parameterKind == ParameterKind.REQUIRED;
+
+  @override
+  bool get isOptional =>
+      parameterKind == ParameterKind.NAMED ||
+      parameterKind == ParameterKind.POSITIONAL;
+
+  @override
+  bool get isOptionalPositional => parameterKind == ParameterKind.POSITIONAL;
+
+  @override
+  bool get isPositional =>
+      parameterKind == ParameterKind.POSITIONAL ||
+      parameterKind == ParameterKind.REQUIRED;
+
   @override
   bool get isSynthetic => true;
 
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 1b88697..3744121 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -13,10 +13,10 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:front_end/src/base/source.dart';
 
 /**
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
index e3c4401..15c4b7c 100644
--- a/pkg/analyzer/lib/src/summary/prelink.dart
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -62,6 +62,33 @@
 }
 
 /**
+ * A node in computing exported namespaces.
+ */
+class _ExportNamespace {
+  static int nextId = 0;
+
+  /**
+   * The export namespace, full (with all exports included), or partial (with
+   * public namespace, and only some of the exports included).
+   */
+  final _Namespace namespace;
+
+  /**
+   * This field is set to non-zero when we start computing the export namespace
+   * for the corresponding library, and is set back to zero when we finish
+   * computation.
+   */
+  int id = 0;
+
+  /**
+   * Whether the [namespace] is full, so we don't need chasing exports.
+   */
+  bool isFull = false;
+
+  _ExportNamespace(this.namespace);
+}
+
+/**
  * A [_Meaning] stores all the information necessary to find the declaration
  * referred to by a name in a namespace.
  */
@@ -230,6 +257,11 @@
    */
   final List<_Namespace> dependencyToPublicNamespace = <_Namespace>[];
 
+  /**
+   * Map from absolute URI of a library to its export namespace.
+   */
+  final Map<String, _ExportNamespace> exportNamespaces = {};
+
   _Prelinker(this.definingUnitUri, this.definingUnit, this.getPart,
       this.getImport, this.getDeclaredVariable) {
     partCache[definingUnitUri] = definingUnit;
@@ -296,35 +328,76 @@
    * information from the library and the transitive closure of its exports.
    */
   _Namespace computeExportNamespace(String absoluteUri) {
-    Set<String> seenUris = new Set<String>();
-    _Namespace chaseExports(String absoluteUri, NameFilter filter) {
-      _Namespace exportedNamespace = aggregatePublicNamespace(absoluteUri);
-      if (seenUris.add(absoluteUri)) {
-        UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
-        if (publicNamespace != null) {
-          for (UnlinkedExportPublic export in publicNamespace.exports) {
-            String unlinkedExportUri =
-                _selectUri(export.uri, export.configurations);
-            String exportUri = resolveUri(absoluteUri, unlinkedExportUri);
-            if (exportUri != null) {
-              NameFilter newFilter = filter.merge(
-                  new NameFilter.forUnlinkedCombinators(export.combinators));
-              _Namespace exportNamespace = chaseExports(exportUri, newFilter);
-              exportNamespace.forEach((String name, _Meaning meaning) {
-                if (newFilter.accepts(name) &&
-                    !exportedNamespace.definesLibraryName(name)) {
-                  exportedNamespace.add(name, meaning);
-                }
-              });
+    int firstCycleIdOfLastCall = 0;
+    _Namespace chaseExports(String absoluteUri) {
+      _ExportNamespace exportNamespace = getExportNamespace(absoluteUri);
+
+      // If the export namespace is ready, return it.
+      if (exportNamespace.isFull) {
+        firstCycleIdOfLastCall = 0;
+        return exportNamespace.namespace;
+      }
+
+      // If we are computing the export namespace for this library, and we
+      // reached here, then we found a cycle.
+      if (exportNamespace.id != 0) {
+        firstCycleIdOfLastCall = exportNamespace.id;
+        return null;
+      }
+
+      // Give each library a unique identifier.
+      exportNamespace.id = _ExportNamespace.nextId++;
+
+      // Append from exports.
+      int firstCycleId = 0;
+      UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
+      if (publicNamespace != null) {
+        for (UnlinkedExportPublic export in publicNamespace.exports) {
+          String unlinkedExportUri =
+              _selectUri(export.uri, export.configurations);
+          String exportUri = resolveUri(absoluteUri, unlinkedExportUri);
+          if (exportUri != null) {
+            NameFilter filter =
+                new NameFilter.forUnlinkedCombinators(export.combinators);
+            _Namespace exported = chaseExports(exportUri);
+            exported?.forEach((String name, _Meaning meaning) {
+              if (filter.accepts(name) &&
+                  !exportNamespace.namespace.definesLibraryName(name)) {
+                exportNamespace.namespace.add(name, meaning);
+              }
+            });
+            if (firstCycleIdOfLastCall != 0) {
+              if (firstCycleId == 0 || firstCycleId > firstCycleIdOfLastCall) {
+                firstCycleId = firstCycleIdOfLastCall;
+              }
             }
           }
         }
-        seenUris.remove(absoluteUri);
       }
-      return exportedNamespace;
+
+      // If this library is the first component of the cycle, then we are at
+      // the beginning of this cycle, and combination of partial export
+      // namespaces of other exported libraries and declarations of this
+      // library is the full export namespace of this library.
+      if (firstCycleId != 0 && firstCycleId == exportNamespace.id) {
+        firstCycleId = 0;
+      }
+
+      // We're done with this library, successfully or not.
+      exportNamespace.id = 0;
+
+      // If no cycle detected in exports, mark the export namespace as full.
+      if (firstCycleId == 0) {
+        exportNamespace.isFull = true;
+      }
+
+      // Return the full or partial result.
+      firstCycleIdOfLastCall = firstCycleId;
+      return exportNamespace.namespace;
     }
 
-    return chaseExports(absoluteUri, NameFilter.identity);
+    _ExportNamespace.nextId = 1;
+    return chaseExports(absoluteUri);
   }
 
   /**
@@ -431,6 +504,21 @@
   }
 
   /**
+   * Return the [_ExportNamespace] for the library with the given [absoluteUri].
+   * The export namespace might be full (will all exports included), or
+   * partial (with public namespace, and only some of the exports included).
+   */
+  _ExportNamespace getExportNamespace(String absoluteUri) {
+    _ExportNamespace exportNamespace = exportNamespaces[absoluteUri];
+    if (exportNamespace == null) {
+      _Namespace publicNamespace = aggregatePublicNamespace(absoluteUri);
+      exportNamespace = new _ExportNamespace(publicNamespace);
+      exportNamespaces[absoluteUri] = exportNamespace;
+    }
+    return exportNamespace;
+  }
+
+  /**
    * Wrapper around [getImport] that caches the return value in [importCache].
    */
   UnlinkedPublicNamespace getImportCached(String absoluteUri) {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index e03b7aa..f15fcd2 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/expr_builder.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
@@ -82,8 +83,10 @@
     });
     // Add all the names from [exportNames].
     for (LinkedExportName exportName in exportNames) {
-      definedNames.putIfAbsent(
-          exportName.name, () => buildExportName(exportName));
+      String name = exportName.name;
+      if (!definedNames.containsKey(name)) {
+        definedNames[name] = buildExportName(exportName);
+      }
     }
     return new Namespace(definedNames);
   }
@@ -584,7 +587,12 @@
   /**
    * The URI of [librarySource].
    */
-  String libraryUri;
+  Uri libraryUri;
+
+  /**
+   * The URI of [librarySource].
+   */
+  String libraryUriStr;
 
   /**
    * Indicates whether [librarySource] is the `dart:core` library.
@@ -605,8 +613,9 @@
 
   _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
       this.unlinkedUnits, this.librarySource) {
-    libraryUri = librarySource.uri.toString();
-    isCoreLibrary = libraryUri == 'dart:core';
+    libraryUri = librarySource.uri;
+    libraryUriStr = libraryUri.toString();
+    isCoreLibrary = libraryUriStr == 'dart:core';
   }
 
   @override
@@ -752,28 +761,23 @@
   List<String> getReferencedLocationComponents(
       int dependencyIndex, int unit, String name) {
     if (dependencyIndex == 0) {
-      String referencedLibraryUri = libraryUri;
       String partUri;
       if (unit != 0) {
         String uri = unlinkedUnits[0].publicNamespace.parts[unit - 1];
-        Source partSource =
-            summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
-        partUri = partSource.uri.toString();
+        partUri = _resolveRelativeUri(uri);
       } else {
-        partUri = referencedLibraryUri;
+        partUri = libraryUriStr;
       }
-      return <String>[referencedLibraryUri, partUri, name];
+      return <String>[libraryUriStr, partUri, name];
     }
+
     LinkedDependency dependency = linkedLibrary.dependencies[dependencyIndex];
-    Source referencedLibrarySource = summaryResynthesizer.sourceFactory
-        .resolveUri(librarySource, dependency.uri);
-    String referencedLibraryUri = referencedLibrarySource.uri.toString();
+    String referencedLibraryUri = _resolveRelativeUri(dependency.uri);
+
     String partUri;
     if (unit != 0) {
       String uri = dependency.parts[unit - 1];
-      Source partSource =
-          summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
-      partUri = partSource.uri.toString();
+      partUri = _resolveRelativeUri(uri);
     } else {
       partUri = referencedLibraryUri;
     }
@@ -791,6 +795,15 @@
       resynthesizedUnits[absoluteUri] = unit;
     }
   }
+
+  /**
+   * Resolve the [relativeUriStr] against [libraryUri] using Dart rules.
+   */
+  String _resolveRelativeUri(String relativeUriStr) {
+    Uri relativeUri = Uri.parse(relativeUriStr);
+    Uri resolvedUri = resolveRelativeUri(libraryUri, relativeUri);
+    return resolvedUri.toString();
+  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/task/dart.dart b/pkg/analyzer/lib/src/task/api/dart.dart
similarity index 98%
rename from pkg/analyzer/lib/task/dart.dart
rename to pkg/analyzer/lib/src/task/api/dart.dart
index d4a651b..44ef9b8 100644
--- a/pkg/analyzer/lib/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/api/dart.dart
@@ -2,16 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.task.dart;
-
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/model.dart';
 
 /**
  * The analysis errors associated with a [Source] representing a compilation
diff --git a/pkg/analyzer/lib/task/general.dart b/pkg/analyzer/lib/src/task/api/general.dart
similarity index 90%
rename from pkg/analyzer/lib/task/general.dart
rename to pkg/analyzer/lib/src/task/api/general.dart
index c40ff4c..2f7ab11 100644
--- a/pkg/analyzer/lib/task/general.dart
+++ b/pkg/analyzer/lib/src/task/api/general.dart
@@ -2,10 +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.
 
-library analyzer.task.general;
-
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 
 /**
  * The content of a [Source].
diff --git a/pkg/analyzer/lib/task/html.dart b/pkg/analyzer/lib/src/task/api/html.dart
similarity index 92%
rename from pkg/analyzer/lib/task/html.dart
rename to pkg/analyzer/lib/src/task/api/html.dart
index 9df8394..4005bcc 100644
--- a/pkg/analyzer/lib/task/html.dart
+++ b/pkg/analyzer/lib/src/task/api/html.dart
@@ -2,11 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.task.html;
-
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:html/dom.dart';
 
 /**
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/src/task/api/model.dart
similarity index 100%
rename from pkg/analyzer/lib/task/model.dart
rename to pkg/analyzer/lib/src/task/api/model.dart
diff --git a/pkg/analyzer/lib/task/yaml.dart b/pkg/analyzer/lib/src/task/api/yaml.dart
similarity index 90%
rename from pkg/analyzer/lib/task/yaml.dart
rename to pkg/analyzer/lib/src/task/api/yaml.dart
index 3888bf7..8bfe390 100644
--- a/pkg/analyzer/lib/task/yaml.dart
+++ b/pkg/analyzer/lib/src/task/api/yaml.dart
@@ -2,11 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.task.yaml;
-
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:yaml/yaml.dart';
 
 /**
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index f2e8703..d117708 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/dart/ast/ast.dart'
     show NamespaceDirectiveImpl, UriBasedDirectiveImpl, UriValidationCode;
@@ -38,6 +39,9 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
 import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/general.dart';
 import 'package:analyzer/src/task/html.dart';
@@ -45,9 +49,6 @@
 import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
 
 /**
  * The [ResultCachingPolicy] for ASTs.
@@ -3075,7 +3076,7 @@
           .group(1)
           .split(',')
           .map((String code) => code.trim().toLowerCase());
-      LineInfo_Location location = info.getLocation(match.start);
+      CharacterLocation location = info.getLocation(match.start);
       int lineNumber = location.lineNumber;
       String beforeMatch = content.substring(
           info.getOffsetOfLine(lineNumber - 1),
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 0a56cd8..5225f5e 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.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.
 
-library analyzer.src.task.dart_work_manager;
-
 import 'dart:collection';
 
 import 'package:analyzer/error/error.dart';
@@ -12,10 +10,10 @@
     show AnalysisEngine, AnalysisErrorInfo, CacheState, InternalAnalysisContext;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/html.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart';
 
 /**
  * The manager for Dart specific analysis.
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index c92370d..66eba45 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.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.
 
-library analyzer.src.task.driver;
-
 import 'dart:async';
 import 'dart:collection';
 
@@ -12,9 +10,9 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/task/model.dart';
 
 final PerformanceTag analysisDriverProcessOutputs =
     _taskDriverTag.createChild('processOutputs');
diff --git a/pkg/analyzer/lib/src/task/general.dart b/pkg/analyzer/lib/src/task/general.dart
index 064fd20..446f14a 100644
--- a/pkg/analyzer/lib/src/task/general.dart
+++ b/pkg/analyzer/lib/src/task/general.dart
@@ -2,13 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.src.task.general;
-
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 
 /**
  * A task that gets the contents of the source associated with an analysis
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index 76ef914..8de0347e 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.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.
 
-library analyzer.src.task.html;
-
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/context/cache.dart';
@@ -12,11 +10,11 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/general.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart';
 import 'package:html/parser.dart';
 import 'package:source_span/source_span.dart';
diff --git a/pkg/analyzer/lib/src/task/html_work_manager.dart b/pkg/analyzer/lib/src/task/html_work_manager.dart
index d8bc76f..a7038d1 100644
--- a/pkg/analyzer/lib/src/task/html_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/html_work_manager.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.
 
-library analyzer.src.task.html_work_manager;
-
 import 'dart:collection';
 
 import 'package:analyzer/error/error.dart';
@@ -12,9 +10,9 @@
     show AnalysisEngine, AnalysisErrorInfo, CacheState, InternalAnalysisContext;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/html.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
 
 /**
  * The manager for HTML specific analysis.
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index 66650c3..d490238 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -4,7 +4,7 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 
 /**
  * A function that converts an object of the type [B] into a [TaskInput].
diff --git a/pkg/analyzer/lib/src/task/manager.dart b/pkg/analyzer/lib/src/task/manager.dart
index 059257f..40778cb 100644
--- a/pkg/analyzer/lib/src/task/manager.dart
+++ b/pkg/analyzer/lib/src/task/manager.dart
@@ -2,12 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.src.task.manager;
-
 import 'dart:collection';
 
 import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 
 /**
  * An object that manages the information about the tasks that have been
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index 4f99b8c..a84a960 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -2,11 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.src.task.model;
-
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/inputs.dart';
-import 'package:analyzer/task/model.dart';
 
 /**
  * The default [ResultCachingPolicy], results are never flushed.
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 0c23e88..dcc5210 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -5,9 +5,8 @@
 import 'dart:collection';
 
 import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/plugin/options.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -16,10 +15,11 @@
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/options_rule_validator.dart';
 import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/plugin/options.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/general.dart';
 import 'package:analyzer/src/util/yaml.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:source_span/source_span.dart';
 import 'package:yaml/yaml.dart';
 
@@ -156,9 +156,6 @@
   /// Lazily populated set of error codes (hashed for speedy lookup).
   static HashSet<String> _errorCodes;
 
-  /// Lazily populated set of lint codes.
-  Set<String> _lintCodes;
-
   /// Legal error code names.
   static Set<String> get errorCodes {
     if (_errorCodes == null) {
@@ -169,6 +166,9 @@
     return _errorCodes;
   }
 
+  /// Lazily populated set of lint codes.
+  Set<String> _lintCodes;
+
   Set<String> get lintCodes {
     if (_lintCodes == null) {
       _lintCodes = new Set.from(
diff --git a/pkg/analyzer/lib/src/task/options_work_manager.dart b/pkg/analyzer/lib/src/task/options_work_manager.dart
index d78a21c..fab4ebe 100644
--- a/pkg/analyzer/lib/src/task/options_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/options_work_manager.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.
 
-library analyzer.src.task.options_work_manager;
-
 import 'dart:collection';
 
 import 'package:analyzer/error/error.dart';
@@ -11,8 +9,8 @@
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisEngine, AnalysisErrorInfo, CacheState, InternalAnalysisContext;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/task/model.dart';
 
 /// The manager for analysis options specific analysis.
 class OptionsWorkManager implements WorkManager {
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index b6f3d3e..6cfa78a 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -72,45 +72,6 @@
   return expression.staticType;
 }
 
-bool hasStrictArrow(Expression expression) {
-  var element = _getKnownElement(expression);
-  return element is FunctionElement || element is MethodElement;
-}
-
-/// Given a generic class [element] find its covariant upper bound, using
-/// the type system [rules].
-///
-/// Unlike [TypeSystem.instantiateToBounds], this will change `dynamic` into
-/// `Object` to work around an issue with fuzzy arrows.
-InterfaceType _getCovariantUpperBound(TypeSystem rules, ClassElement element) {
-  var upperBound = rules.instantiateToBounds(element.type) as InterfaceType;
-  var typeArgs = upperBound.typeArguments;
-  // TODO(jmesserly): remove this. It is a workaround for fuzzy arrows.
-  // To prevent extra checks due to fuzzy arrows, we need to instantiate with
-  // `Object` rather than `dynamic`. Consider a case like:
-  //
-  //     class C<T> {
-  //       void forEach(f(T t)) {}
-  //     }
-  //
-  // If we try `(dynamic) ~> void <: (T) ~> void` with fuzzy arrows, we will
-  // treat `dynamic` as `bottom` and get `(bottom) -> void <: (T) -> void`
-  // which indicates that a check is required on the parameter `f`. This check
-  // is not sufficient when `T` is `dynamic`, however, because calling a
-  // function with a fuzzy arrow type is not safe and requires a dynamic call.
-  // See: https://github.com/dart-lang/sdk/issues/29295
-  //
-  // For all other values of T, the check is unnecessary: it is sound to pass
-  // a function that accepts any Object.
-  if (typeArgs.any((t) => t.isDynamic)) {
-    var newTypeArgs = typeArgs
-        .map((t) => t.isDynamic ? rules.typeProvider.objectType : t)
-        .toList();
-    upperBound = element.type.instantiate(newTypeArgs);
-  }
-  return upperBound;
-}
-
 DartType _elementType(Element e) {
   if (e == null) {
     // Malformed code - just return dynamic.
@@ -1084,77 +1045,34 @@
   /// Returns `true` if the expression is a dynamic function call or method
   /// invocation.
   bool _isDynamicCall(InvocationExpression call, FunctionType ft) {
-    if (ft == null) return true;
-    // Dynamic as the parameter type is treated as bottom.  A function with
-    // a dynamic parameter type requires a dynamic call in general.
-    // However, as an optimization, if we have an original definition, we know
-    // dynamic is reified as Object - in this case a regular call is fine.
-    if (hasStrictArrow(call.function)) {
-      return false;
-    }
-    // TODO(leafp): Get rid of this case when we stop ignoring fuzzy arrows.
-    // We're already not doing this everywhere we would need to for soundness
-    // (because of generics), but for now we catch most cases here.
-    return rules.anyParameterType(ft, (pt) => pt.isDynamic);
+    return ft == null;
   }
 
   /// Given an expression [expr] of type [fromType], returns true if an implicit
   /// downcast is required, false if it is not, or null if the types are
   /// unrelated.
-  ///
-  /// This also issues fuzzy arrow hints (if any).
   bool _checkFunctionTypeCasts(
       Expression expr, FunctionType to, DartType fromType) {
-    var strict = hasStrictArrow(expr);
-    var toFuzzy = rules.functionTypeToFuzzyType(to);
     bool callTearoff = false;
     FunctionType from;
     if (fromType is FunctionType) {
       from = fromType;
     } else if (fromType is InterfaceType) {
       from = rules.getCallMethodType(fromType);
-      // Methods are always strict
-      strict = true;
       callTearoff = true;
     }
     if (from == null) {
       return null; // unrelated
     }
 
-    var fromFuzzy = strict ? from : rules.functionTypeToFuzzyType(from);
-
     if (rules.isSubtypeOf(from, to)) {
-      // Sound subtype, so no fuzzy arrow warning.
-      //
-      // However we may still need cast, because the from type is fuzzy and the
-      // to type isn't. Or if we have an call tearoff.
-      return callTearoff || !rules.isSubtypeOf(fromFuzzy, toFuzzy);
-    }
-
-    // If it's a subtype in the fuzzy system, don't cast, since we do
-    // dynamic calls for the check.
-    if (rules.isSubtypeOf(fromFuzzy, toFuzzy)) {
-      // A subtype in the fuzzy system, but reverse subtype in sound system.
-      // This will eventually become a downcast (which will probably fail).
-      // But for the transition, it is better to issue a fuzzy arrow hint
-      // since we still do the dynamic calls anyway.
-      _recordMessage(
-          expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [fromType, to]);
+      // Sound subtype.
+      // However we may still need cast if we have a call tearoff.
       return callTearoff;
     }
 
     if (rules.isSubtypeOf(to, from)) {
-      // Assignable in the sound system, but needs cast.
-      //
-      // Either unrelated in fuzzy system, or already a cast, so just cast
-      // and don't warn.
-      return true;
-    }
-
-    // Only assignable with fuzzy arrows, and it needs a cast
-    if (rules.isSubtypeOf(toFuzzy, fromFuzzy)) {
-      _recordMessage(
-          expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [fromType, to]);
+      // Assignable, but needs cast.
       return true;
     }
 
@@ -1230,14 +1148,6 @@
   /// the AST node.
   void _recordImplicitCast(Expression expr, DartType to,
       {DartType from, bool opAssign: false}) {
-    // We place record some legacy casts on places that had them for fuzzy
-    // arrows, but where they aren't required using sound subtyping.  We
-    // don't want to issue any of the warnings below for these.
-    if (rules.isSubtypeOf(from, to)) {
-      _markImplicitCast(expr, to, opAssign: opAssign);
-      return;
-    }
-
     // If this is an implicit tearoff, we need to mark the cast, but we don't
     // want to warn if it's a legal subtype.
     if (from is InterfaceType && rules.acceptsFunctionType(to)) {
@@ -1523,7 +1433,8 @@
     if (members.isEmpty) return covariantChecks;
 
     for (var iface in covariantInterfaces) {
-      var unsafeSupertype = _getCovariantUpperBound(rules, iface);
+      var unsafeSupertype =
+          rules.instantiateToBounds(iface.type) as InterfaceType;
       for (var m in members) {
         _findCovariantChecksForMember(m, unsafeSupertype, covariantChecks);
       }
diff --git a/pkg/analyzer/lib/src/task/yaml.dart b/pkg/analyzer/lib/src/task/yaml.dart
index 4024039..431cf30 100644
--- a/pkg/analyzer/lib/src/task/yaml.dart
+++ b/pkg/analyzer/lib/src/task/yaml.dart
@@ -2,18 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.src.task.yaml;
-
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
+import 'package:analyzer/src/task/api/yaml.dart';
 import 'package:analyzer/src/task/general.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
-import 'package:analyzer/task/yaml.dart';
 import 'package:source_span/source_span.dart';
 import 'package:yaml/yaml.dart';
 
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 48ec171..1444d1b 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -14,7 +14,6 @@
   front_end: 0.1.0-alpha.11
   glob: ^1.0.3
   html: '>=0.12.0 <1.14.0'
-  isolate: '>=0.2.2 <2.0.0'
   kernel: 0.3.0-alpha.11
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
@@ -23,7 +22,6 @@
   source_span: ^1.2.0
   watcher: '>=0.9.6 <0.10.0'
   yaml: ^2.1.2
-  cli_util: ^0.1.0
 dev_dependencies:
-  test_reflective_loader: ^0.1.0
   test: ^0.12.0
+  test_reflective_loader: ^0.1.0
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 4bd1324..746ca53 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -192,7 +192,7 @@
 foo(x) => 1;
 var v = const A(foo);''');
     await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.INVALID_CAST_FUNCTION]);
+    assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
     verify([source]);
   }
 
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index b2f5e2d..5809f09 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.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.
 
-library engine.declaration_resolver_test;
-
 import 'dart:async';
 
 import 'package:analyzer/dart/ast/ast.dart';
@@ -14,8 +12,8 @@
 import 'package:analyzer/src/generated/declaration_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/dart.dart';
 import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 59dd90c..043f1a3 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.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.
 
-library analyzer.test.generated.engine_test;
-
 import 'dart:async';
 
 import 'package:analyzer/dart/ast/ast.dart';
@@ -20,7 +18,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:html/dom.dart' show Document;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index 7ffd79f..a7b6f00 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -244,8 +244,9 @@
   }
 
   @override
-  void beginFormalParameter(Token token, MemberKind kind) {
-    super.beginFormalParameter(token, kind);
+  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+      Token varFinalOrConst) {
+    super.beginFormalParameter(token, kind, covariantToken, varFinalOrConst);
     begin('FormalParameter');
   }
 
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 8190532..b47a19e 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1453,7 +1453,7 @@
   }
 
   @override
-  declare(String name, Builder builder, int charOffset, Uri fileUri) {
+  declare(String name, Builder builder, Uri fileUri) {
     _locals[name] = builder;
     return null;
   }
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 0a53f95..0454057 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -2,9 +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.
 
-library analyzer.test.generated.scanner_test;
-
 import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -79,19 +78,6 @@
 
 @reflectiveTest
 class LineInfoTest extends EngineTestCase {
-  void test_translate_missing_closing_gt_error() {
-    // Ensure that the UnmatchedToken error for missing '>' is translated
-    // to the correct analyzer error code.
-    // See https://github.com/dart-lang/sdk/issues/30320
-    String source = '<!-- @Component(';
-    GatheringErrorListener listener = new GatheringErrorListener();
-    _scanWithListener(source, listener);
-    listener.assertErrorsWithCodes(const [
-      ScannerErrorCode.EXPECTED_TOKEN,
-      ScannerErrorCode.EXPECTED_TOKEN,
-    ]);
-  }
-
   void test_lineInfo_multilineComment() {
     String source = "/*\r\n *\r\n */";
     _assertLineInfo(source, [
@@ -149,6 +135,19 @@
         lineStarts, orderedEquals([0, 5, 7, 9, fe.Scanner.useFasta ? 12 : 11]));
   }
 
+  void test_translate_missing_closing_gt_error() {
+    // Ensure that the UnmatchedToken error for missing '>' is translated
+    // to the correct analyzer error code.
+    // See https://github.com/dart-lang/sdk/issues/30320
+    String source = '<!-- @Component(';
+    GatheringErrorListener listener = new GatheringErrorListener();
+    _scanWithListener(source, listener);
+    listener.assertErrorsWithCodes(const [
+      ScannerErrorCode.EXPECTED_TOKEN,
+      ScannerErrorCode.EXPECTED_TOKEN,
+    ]);
+  }
+
   void _assertLineInfo(
       String source, List<ScannerTest_ExpectedLocation> expectedLocations) {
     GatheringErrorListener listener = new GatheringErrorListener();
@@ -159,7 +158,7 @@
     int count = expectedLocations.length;
     for (int i = 0; i < count; i++) {
       ScannerTest_ExpectedLocation expectedLocation = expectedLocations[i];
-      LineInfo_Location location = info.getLocation(expectedLocation._offset);
+      CharacterLocation location = info.getLocation(expectedLocation._offset);
       expect(location.lineNumber, expectedLocation._lineNumber,
           reason: 'Line number in location $i');
       expect(location.columnNumber, expectedLocation._columnNumber,
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 0194fd9..b7ead13 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -1533,10 +1533,10 @@
 }
  ''');
     await computeAnalysisResult(source);
-    _expectInferenceError(
-        source,
-        [StrongModeCode.COULD_NOT_INFER, StrongModeCode.INVALID_CAST_FUNCTION],
-        r'''
+    _expectInferenceError(source, [
+      StrongModeCode.COULD_NOT_INFER,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ], r'''
 Couldn't infer type parameter 'T'.
 
 Tried to infer 'dynamic' for 'T' which doesn't work:
@@ -1704,8 +1704,10 @@
 num test(Iterable values) => values.fold(values.first as num, max);
     ''');
     var analysisResult = await computeAnalysisResult(source);
-    assertErrors(source,
-        [StrongModeCode.COULD_NOT_INFER, StrongModeCode.INVALID_CAST_FUNCTION]);
+    assertErrors(source, [
+      StrongModeCode.COULD_NOT_INFER,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
     verify([source]);
     var unit = analysisResult.unit;
     var fold = (AstFinder
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index c184019..7781977 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2,14 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.generated.utilities_test;
-
 import 'dart:collection';
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
@@ -2549,21 +2548,21 @@
 
   void test_firstLine() {
     LineInfo info = new LineInfo(<int>[0, 12, 34]);
-    LineInfo_Location location = info.getLocation(4);
+    CharacterLocation location = info.getLocation(4);
     expect(location.lineNumber, 1);
     expect(location.columnNumber, 5);
   }
 
   void test_lastLine() {
     LineInfo info = new LineInfo(<int>[0, 12, 34]);
-    LineInfo_Location location = info.getLocation(36);
+    CharacterLocation location = info.getLocation(36);
     expect(location.lineNumber, 3);
     expect(location.columnNumber, 3);
   }
 
   void test_middleLine() {
     LineInfo info = new LineInfo(<int>[0, 12, 34]);
-    LineInfo_Location location = info.getLocation(12);
+    CharacterLocation location = info.getLocation(12);
     expect(location.lineNumber, 2);
     expect(location.columnNumber, 1);
   }
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 1b53283..00e24ad 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -6,7 +6,7 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/util/yaml.dart';
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
index 7cf74fc..d631f72 100644
--- a/pkg/analyzer/test/source/error_processor_test.dart
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/test/source/package_map_provider_test.dart b/pkg/analyzer/test/source/package_map_provider_test.dart
index 5959e42..7d78522 100644
--- a/pkg/analyzer/test/source/package_map_provider_test.dart
+++ b/pkg/analyzer/test/source/package_map_provider_test.dart
@@ -2,14 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.source.package_map_provider_test;
-
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/source/path_filter_test.dart b/pkg/analyzer/test/source/path_filter_test.dart
index 172a421..0dcba2e 100644
--- a/pkg/analyzer/test/source/path_filter_test.dart
+++ b/pkg/analyzer/test/source/path_filter_test.dart
@@ -2,9 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.source.path_filter_test;
-
-import 'package:analyzer/source/path_filter.dart';
+import 'package:analyzer/src/source/path_filter.dart';
 import 'package:path/path.dart';
 import 'package:test/test.dart';
 
diff --git a/pkg/analyzer/test/source/sdk_ext_test.dart b/pkg/analyzer/test/source/sdk_ext_test.dart
index 0e7fff9..b09c36b 100644
--- a/pkg/analyzer/test/source/sdk_ext_test.dart
+++ b/pkg/analyzer/test/source/sdk_ext_test.dart
@@ -2,11 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.source.sdk_ext_test;
-
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/source/sdk_ext.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index 0e60d81..103433e 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.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.
 
-library analyzer.test.src.context.abstract_context;
-
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
@@ -14,8 +12,8 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/driver.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:plugin/manager.dart';
 import 'package:plugin/plugin.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 9fb27cd..01fbb86 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -2,14 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.src.context.context_builder_test;
-
-import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/command_line/arguments.dart';
 import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/generated/bazel.dart';
 import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 235e254..32b2cbd 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -12,8 +12,8 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index dea470e..14565dc 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.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.
 
-library analyzer.test.src.context.context_test;
-
 import 'dart:async';
 import 'dart:collection';
 
@@ -25,10 +23,10 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/html.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart' show Document;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index 3cae769..7dc865f 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -98,6 +98,97 @@
         unorderedEquals(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']));
   }
 
+  test_exportedTopLevelDeclarations_cycle() {
+    String a = _p('/aaa/lib/a.dart');
+    String b = _p('/aaa/lib/b.dart');
+    String c = _p('/aaa/lib/c.dart');
+    provider.newFile(a, r'''
+export 'b.dart';
+class A {}
+''');
+    provider.newFile(b, r'''
+export 'c.dart';
+class B {}
+''');
+    provider.newFile(c, r'''
+export 'a.dart';
+class C {}
+''');
+    _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C']);
+
+    // We asked for 'a', and it was computed.
+    // But 'b' and 'c' are not computed, because we detect that there is
+    // cycle with 'a', so we cannot get all exported declarations of 'a'.
+    _assertHasComputedExportedDeclarations([a]);
+  }
+
+  test_exportedTopLevelDeclarations_cycle_anotherOutsideCycle() {
+    String a = _p('/aaa/lib/a.dart');
+    String b = _p('/aaa/lib/b.dart');
+    String c = _p('/aaa/lib/c.dart');
+    String d = _p('/aaa/lib/d.dart');
+    provider.newFile(a, r'''
+export 'b.dart';
+class A {}
+''');
+    provider.newFile(b, r'''
+export 'c.dart';
+class B {}
+''');
+    provider.newFile(c, r'''
+export 'b.dart';
+export 'd.dart';
+class C {}
+''');
+    provider.newFile(d, r'''
+class D {}
+''');
+    _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C', 'D']);
+
+    // To compute 'a' we compute 'b'.
+    // But 'c' is not computed, because of the cycle [b, c].
+    // However 'd' is not a part of a cycle, so it is computed too.
+    _assertHasComputedExportedDeclarations([a, b, d]);
+  }
+
+  test_exportedTopLevelDeclarations_cycle_onSequence() {
+    String a = _p('/aaa/lib/a.dart');
+    String b = _p('/aaa/lib/b.dart');
+    String c = _p('/aaa/lib/c.dart');
+    String d = _p('/aaa/lib/d.dart');
+    String e = _p('/aaa/lib/e.dart');
+    provider.newFile(a, r'''
+export 'b.dart';
+class A {}
+''');
+    provider.newFile(b, r'''
+export 'c.dart';
+class B {}
+''');
+    provider.newFile(c, r'''
+export 'd.dart';
+class C {}
+''');
+    provider.newFile(d, r'''
+export 'e.dart';
+class D {}
+''');
+    provider.newFile(e, r'''
+export 'c.dart';
+class E {}
+''');
+    // We compute 'a'.
+    // To compute it we also compute 'b' and 'c'.
+    // But 'd' and 'e' are not computed, because of the cycle [c, d, e].
+    _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C', 'D', 'E']);
+    _assertHasComputedExportedDeclarations([a, b, c]);
+
+    // We compute 'd', and try to compute 'e', because 'd' needs 'e'; 'e' can
+    // be computed because 'c' is ready, so the cycle [c, d, e] is broken.
+    _assertExportedTopLevelDeclarations(d, ['C', 'D', 'E']);
+    _assertHasComputedExportedDeclarations([a, b, c, d, e]);
+  }
+
   test_exportedTopLevelDeclarations_export() {
     String a = _p('/aaa/lib/a.dart');
     String b = _p('/aaa/lib/b.dart');
@@ -108,10 +199,8 @@
 export 'a.dart';
 class B {}
 ''');
-    FileState file = fileSystemState.getFileForPath(b);
-    Map<String, TopLevelDeclaration> declarations =
-        file.exportedTopLevelDeclarations;
-    expect(declarations.keys, unorderedEquals(['A', 'B']));
+    _assertExportedTopLevelDeclarations(b, ['A', 'B']);
+    _assertHasComputedExportedDeclarations([a, b]);
   }
 
   test_exportedTopLevelDeclarations_export2_show() {
@@ -133,6 +222,7 @@
 class C {}
 ''');
     _assertExportedTopLevelDeclarations(c, ['A2', 'B1', 'C']);
+    _assertHasComputedExportedDeclarations([a, b, c]);
   }
 
   test_exportedTopLevelDeclarations_export_flushOnChange() {
@@ -763,6 +853,12 @@
     expect(_excludeSdk(actual), unorderedEquals(expected));
   }
 
+  void _assertHasComputedExportedDeclarations(List<String> expectedPathList) {
+    FileSystemStateTestView test = fileSystemState.test;
+    expect(test.librariesWithComputedExportedDeclarations.map((f) => f.path),
+        unorderedEquals(expectedPathList));
+  }
+
   void _assertIsUnresolvedFile(FileState file) {
     expect(file.path, isNull);
     expect(file.uri, isNull);
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/assert_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/assert_statement_test.dart
index 6163277..f169558 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/assert_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/assert_statement_test.dart
@@ -12,61 +12,52 @@
 
 class AssertStatementTest extends PartialCodeTest {
   buildAll() {
+    List<String> allExceptEof =
+        PartialCodeTest.statementSuffixes.map((t) => t.name).toList();
     buildTests(
         'assert_statement',
         [
           new TestDescriptor(
               'keyword',
               'assert',
-              [
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "assert (_s_);",
-              allFailing: true),
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              "assert (_s_);"),
           new TestDescriptor(
               'leftParen',
               'assert (',
               [
                 ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
+                ScannerErrorCode.EXPECTED_TOKEN,
                 ParserErrorCode.EXPECTED_TOKEN
               ],
               "assert (_s_);",
-              allFailing: true),
+              failing: allExceptEof),
           new TestDescriptor(
               'condition',
               'assert (a',
-              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
               "assert (a);",
-              allFailing: true),
+              failing: allExceptEof),
           new TestDescriptor(
               'comma',
               'assert (a,',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "assert (a, _s_);",
-              allFailing: true),
+              [ScannerErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              "assert (a,);",
+              failing: allExceptEof),
           new TestDescriptor(
               'message',
               'assert (a, b',
-              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
               "assert (a, b);",
-              allFailing: true),
+              failing: allExceptEof),
           new TestDescriptor(
               'trailingComma',
               'assert (a, b,',
-              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
               "assert (a, b,);",
-              allFailing: true),
+              failing: allExceptEof),
           new TestDescriptor('rightParen', 'assert (a, b)',
-              [ParserErrorCode.EXPECTED_TOKEN], "assert (a, b);",
-              allFailing: true),
+              [ParserErrorCode.EXPECTED_TOKEN], "assert (a, b);"),
         ],
         PartialCodeTest.statementSuffixes,
         head: 'f() { ',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index 9ba13da..5f08265 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -34,12 +34,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class _s_ {}',
-              failing: <String>[
-                'typedef',
-                'functionNonVoid',
-                'getter',
-                'setter'
-              ]),
+              failing: ['functionNonVoid', 'getter']),
           new TestDescriptor('named', 'class A',
               [ParserErrorCode.MISSING_CLASS_BODY], 'class A {}'),
           new TestDescriptor(
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
index 75a64f1..799cf53 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
@@ -12,6 +12,8 @@
 
 class ForEachStatementTest extends PartialCodeTest {
   buildAll() {
+    List<String> allExceptEof =
+        PartialCodeTest.statementSuffixes.map((t) => t.name).toList();
     //
     // Without a preceding 'await', anything that doesn't contain the `in`
     // keyword will be interpreted as a normal for statement.
@@ -25,16 +27,21 @@
               [
                 ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
                 ScannerErrorCode.EXPECTED_TOKEN
               ],
-              'for (var a in _s_) {}',
-              allFailing: true),
+              'for (var a in _s_) _s_;',
+              failing: allExceptEof),
           new TestDescriptor(
               'iterator',
               'for (var a in b',
-              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
-              'for (var a in b) {}',
-              allFailing: true),
+              [
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              'for (var a in b) _s_;',
+              failing: allExceptEof),
         ],
         PartialCodeTest.statementSuffixes,
         head: 'f() { ',
@@ -46,69 +53,66 @@
     buildTests(
         'forEach_statement',
         [
-          new TestDescriptor(
-              'await_keyword',
-              'await for',
-              [
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ScannerErrorCode.EXPECTED_TOKEN
-              ],
-              'await for (_s_ in _s_) {}',
-              allFailing: true),
+          new TestDescriptor('await_keyword', 'await for',
+              [ParserErrorCode.EXPECTED_TOKEN], 'await for (_s_ in _s_) _s_;'),
           new TestDescriptor(
               'await_leftParen',
               'await for (',
               [
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ScannerErrorCode.EXPECTED_TOKEN
+                ParserErrorCode.EXPECTED_TOKEN
               ],
-              "await for (_s_ in _s_) {}",
-              allFailing: true),
+              "await for (_s_ in _s_) _s_;",
+              failing: allExceptEof),
           new TestDescriptor(
               'await_variableName',
               'await for (a',
               [
-                ParserErrorCode.EXPECTED_TOKEN,
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.EXPECTED_TOKEN,
-                ScannerErrorCode.EXPECTED_TOKEN
+                ParserErrorCode.EXPECTED_TOKEN
               ],
-              "await for (a in _s_) {}",
-              allFailing: true),
+              "await for (a in _s_) _s_;",
+              failing: allExceptEof),
           new TestDescriptor(
               'await_typeAndVariableName',
               'await for (A a',
               [
-                ParserErrorCode.EXPECTED_TOKEN,
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.EXPECTED_TOKEN,
-                ScannerErrorCode.EXPECTED_TOKEN
+                ParserErrorCode.EXPECTED_TOKEN
               ],
-              "await for (a in _s_) {}",
-              allFailing: true),
+              "await for (A a in _s_) _s_;",
+              failing: allExceptEof),
           new TestDescriptor(
               'await_in',
               'await for (A a in',
               [
+                ScannerErrorCode.EXPECTED_TOKEN,
                 ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ScannerErrorCode.EXPECTED_TOKEN
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN
               ],
-              "await for (a in _s_) {}",
-              allFailing: true),
+              "await for (A a in _s_) _s_;",
+              failing: allExceptEof),
           new TestDescriptor(
               'await_stream',
               'await for (A a in b',
-              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
-              "await for (a in b) {}",
-              allFailing: true),
+              [
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "await for (A a in b) _s_;",
+              failing: allExceptEof),
         ],
         PartialCodeTest.statementSuffixes,
         head: 'f() async { ',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/for_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/for_statement_test.dart
index 9aac678..4106cdf 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/for_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/for_statement_test.dart
@@ -18,7 +18,7 @@
         'for_statement',
         [
           new TestDescriptor('keyword', 'for', [ParserErrorCode.EXPECTED_TOKEN],
-              'for (;;) {}'),
+              'for (;;) _s_;'),
           new TestDescriptor(
               'emptyParen',
               'for ()',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
index d3764ef..eb6dfc6 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
@@ -12,6 +12,8 @@
 
 class ImportDirectivesTest extends PartialCodeTest {
   buildAll() {
+    List<String> allExceptEof =
+        PartialCodeTest.prePartSuffixes.map((t) => t.name).toList();
     buildTests(
         'import_directive',
         [
@@ -25,6 +27,55 @@
               [ParserErrorCode.EXPECTED_TOKEN], "import '';"),
           new TestDescriptor('fullUri', "import 'a.dart'",
               [ParserErrorCode.EXPECTED_TOKEN], "import 'a.dart';"),
+          new TestDescriptor(
+              'if',
+              "import 'a.dart' if",
+              [
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_STRING_LITERAL
+              ],
+              "import 'a.dart' if (_s_) '';"),
+          new TestDescriptor(
+              'ifParen',
+              "import 'a.dart' if (",
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_STRING_LITERAL,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "import 'a.dart' if (_s_) '';",
+              failing: allExceptEof),
+          new TestDescriptor(
+              'ifId',
+              "import 'a.dart' if (b",
+              [
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_STRING_LITERAL
+              ],
+              "import 'a.dart' if (b) '';",
+              failing: allExceptEof),
+          new TestDescriptor(
+              'ifEquals',
+              "import 'a.dart' if (b ==",
+              [
+                ParserErrorCode.EXPECTED_STRING_LITERAL,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_STRING_LITERAL
+              ],
+              "import 'a.dart' if (b == '') '';",
+              failing: allExceptEof),
+          new TestDescriptor(
+              'ifCondition',
+              "import 'a.dart' if (b)",
+              [
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_STRING_LITERAL
+              ],
+              "import 'a.dart' if (b) '';"),
         ],
         PartialCodeTest.prePartSuffixes);
   }
diff --git a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
index db16be7..fde9bac 100644
--- a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
+++ b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
@@ -7,9 +7,9 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
 import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 05648d9..2965261 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.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.
 
-library analyzer.test.src.summary.resynthesize_ast_test;
-
 import 'dart:async';
 
 import 'package:analyzer/dart/ast/ast.dart';
@@ -22,8 +20,8 @@
 import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart'
     show PackageBundleAssembler;
-import 'package:analyzer/task/dart.dart' show PARSED_UNIT;
-import 'package:analyzer/task/general.dart';
+import 'package:analyzer/src/task/api/dart.dart' show PARSED_UNIT;
+import 'package:analyzer/src/task/api/general.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 5961afb..0362a9f 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9154,6 +9154,35 @@
 ''');
   }
 
+  test_setter_inferred_type_conflictingInheritance() async {
+    var library = await checkLibrary('''
+class A {
+  int t;
+}
+class B extends A {
+  double t;
+}
+class C extends A implements B {
+}
+class D extends C {
+  void set t(p) {}
+}
+''');
+    checkElementText(library, r'''
+class A {
+  int t;
+}
+class B extends A {
+  double t;
+}
+class C extends A implements B {
+}
+class D extends C {
+  void set t(dynamic p) {}
+}
+''');
+  }
+
   test_setter_inferred_type_nonStatic_implicit_param() async {
     var library =
         await checkLibrary('class C extends D { void set f(value) {} }'
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 7e36ed3..d6e3c01 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.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.
 
-library analyzer.test.src.task.dart_test;
-
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -21,12 +19,12 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/html.dart';
 import 'package:analyzer/src/task/strong/ast_properties.dart' as strong_ast;
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:front_end/src/scanner/scanner.dart' as fe;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index cc4fa43..1a83d55 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -20,11 +20,11 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/dart_work_manager.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 55a613d5..5834950 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -5,10 +5,10 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/task/general_test.dart b/pkg/analyzer/test/src/task/general_test.dart
index 0caea7e..e5e3b2b 100644
--- a/pkg/analyzer/test/src/task/general_test.dart
+++ b/pkg/analyzer/test/src/task/general_test.dart
@@ -4,9 +4,9 @@
 
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/general.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/task/html_test.dart b/pkg/analyzer/test/src/task/html_test.dart
index 3095299..eb1b24d 100644
--- a/pkg/analyzer/test/src/task/html_test.dart
+++ b/pkg/analyzer/test/src/task/html_test.dart
@@ -2,13 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.src.task.html_test;
-
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/html.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -312,19 +311,19 @@
       expect(lineInfo, isNotNull);
       {
         int offset = code.indexOf('<!DOCTYPE');
-        LineInfo_Location location = lineInfo.getLocation(offset);
+        CharacterLocation location = lineInfo.getLocation(offset);
         expect(location.lineNumber, 1);
         expect(location.columnNumber, 1);
       }
       {
         int offset = code.indexOf('<html>');
-        LineInfo_Location location = lineInfo.getLocation(offset);
+        CharacterLocation location = lineInfo.getLocation(offset);
         expect(location.lineNumber, 2);
         expect(location.columnNumber, 1);
       }
       {
         int offset = code.indexOf('<title>');
-        LineInfo_Location location = lineInfo.getLocation(offset);
+        CharacterLocation location = lineInfo.getLocation(offset);
         expect(location.lineNumber, 4);
         expect(location.columnNumber, 5);
       }
diff --git a/pkg/analyzer/test/src/task/html_work_manager_test.dart b/pkg/analyzer/test/src/task/html_work_manager_test.dart
index b09a365..714894a 100644
--- a/pkg/analyzer/test/src/task/html_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/html_work_manager_test.dart
@@ -17,12 +17,12 @@
         ChangeNoticeImpl,
         InternalAnalysisContext;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/html.dart';
 import 'package:analyzer/src/task/html_work_manager.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index bdbf9ae..7bde7f7 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -2,9 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/task/manager_test.dart b/pkg/analyzer/test/src/task/manager_test.dart
index 3a406b0..662e940 100644
--- a/pkg/analyzer/test/src/task/manager_test.dart
+++ b/pkg/analyzer/test/src/task/manager_test.dart
@@ -2,11 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.src.task.manager_test;
-
 import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/task/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
index e698152..e364dc3 100644
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ b/pkg/analyzer/test/src/task/model_test.dart
@@ -2,12 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.src.task.model_test;
-
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 98a9fcf..0b6ec9f 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -7,15 +7,15 @@
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:yaml/yaml.dart';
@@ -255,7 +255,6 @@
         removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER);
         removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD);
         removeCode(StrongModeCode.TOP_LEVEL_UNSUPPORTED);
-        removeCode(StrongModeCode.USES_DYNAMIC_AS_BOTTOM);
       } else if (errorType == TodoCode) {
         declaredNames.remove('TODO_REGEX');
       }
@@ -544,15 +543,6 @@
     ''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
   }
 
-  test_analyzer_lint_codes_recognized() {
-    Registry.ruleRegistry.register(new TestRule());
-    validate('''
-analyzer:
-  errors:
-    fantastic_test_rule: ignore
-    ''', []);
-  }
-
   test_analyzer_language_supported() {
     validate('''
 analyzer:
@@ -577,6 +567,15 @@
 ''', [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
   }
 
+  test_analyzer_lint_codes_recognized() {
+    Registry.ruleRegistry.register(new TestRule());
+    validate('''
+analyzer:
+  errors:
+    fantastic_test_rule: ignore
+    ''', []);
+  }
+
   test_analyzer_strong_mode_error_code_supported() {
     validate('''
 analyzer:
diff --git a/pkg/analyzer/test/src/task/options_work_manager_test.dart b/pkg/analyzer/test/src/task/options_work_manager_test.dart
index d8a0ec7..8845781 100644
--- a/pkg/analyzer/test/src/task/options_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/options_work_manager_test.dart
@@ -15,11 +15,11 @@
         ChangeNoticeImpl,
         InternalAnalysisContext;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/task/options_work_manager.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index dc58944..3852241 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -482,24 +482,24 @@
 void main() {
   var a = new A();
   bar(a);
-  (/*info:DYNAMIC_INVOKE*/bar1(a));
+  (bar1(a));
   var b = bar;
-  (/*info:DYNAMIC_INVOKE*/b(a));
+  (b(a));
   var f1 = foo;
   f1("hello");
   dynamic f2 = foo;
   (/*info:DYNAMIC_INVOKE*/f2("hello"));
-  DynFun f3 = /*warning:USES_DYNAMIC_AS_BOTTOM*/foo;
-  (/*info:DYNAMIC_INVOKE*/f3("hello"));
-  (/*info:DYNAMIC_INVOKE*/f3(42));
+  DynFun f3 = /*error:INVALID_CAST_FUNCTION*/foo;
+  (f3("hello"));
+  (f3(42));
   StrFun f4 = foo;
   f4("hello");
   a.baz1("hello");
   var b1 = a.baz1;
-  (/*info:DYNAMIC_INVOKE*/b1("hello"));
+  (b1("hello"));
   A.baz2("hello");
   var b2 = A.baz2;
-  (/*info:DYNAMIC_INVOKE*/b2("hello"));
+  (b2("hello"));
 
   dynamic a1 = new B();
   (/*info:DYNAMIC_INVOKE*/a1.x);
@@ -673,14 +673,14 @@
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(3);
   }
   {
-    A f = /*warning:USES_DYNAMIC_AS_BOTTOM,error:INVALID_CAST_NEW_EXPR*/new B();
+    A f = /*error:INVALID_ASSIGNMENT*/new B();
     B b = new B();
-    f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/b;
+    f = /* error:INVALID_ASSIGNMENT*/b;
     int x;
     double y;
-    x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
-    y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
-    /*info:DYNAMIC_INVOKE*/f(3.0);
+    x = /*info:DYNAMIC_CAST*/f(3);
+    y = /*info:DYNAMIC_CAST*/f(3);
+    f(3.0);
   }
   {
     dynamic g = new B();
@@ -688,9 +688,9 @@
     /*info:DYNAMIC_INVOKE*/g.col(42.0);
     /*info:DYNAMIC_INVOKE*/g.foo(42.0);
     /*info:DYNAMIC_INVOKE*/g.x;
-    A f = /*warning:USES_DYNAMIC_AS_BOTTOM, error:INVALID_CAST_NEW_EXPR*/new B();
+    A f = /* error:INVALID_ASSIGNMENT*/new B();
     B b = new B();
-    f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/b;
+    f = /*error:INVALID_ASSIGNMENT*/b;
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(42.0);
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/foo(42.0);
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_GETTER*/x;
@@ -1196,14 +1196,14 @@
   {
     BotA f;
     f = topA;
-    f = /*error:INVALID_CAST_FUNCTION*/topTop;
+    f = /*error:INVALID_ASSIGNMENT*/topTop;
     f = aa;
     f = /*error:INVALID_ASSIGNMENT*/aTop;
     f = botA;
     f = /*info:DOWN_CAST_COMPOSITE*/botTop;
     apply<BotA>(
         topA,
-        /*error:INVALID_CAST_FUNCTION*/topTop,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/topTop,
         aa,
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/aTop,
         botA,
@@ -1221,14 +1221,14 @@
   {
     AA f;
     f = topA;
-    f = /*error:INVALID_CAST_FUNCTION*/topTop;
+    f = /*error:INVALID_ASSIGNMENT*/topTop;
     f = aa;
     f = /*error:INVALID_CAST_FUNCTION*/aTop; // known function
     f = /*info:DOWN_CAST_COMPOSITE*/botA;
     f = /*info:DOWN_CAST_COMPOSITE*/botTop;
     apply<AA>(
         topA,
-        /*error:INVALID_CAST_FUNCTION*/topTop,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/topTop,
         aa,
         /*error:INVALID_CAST_FUNCTION*/aTop, // known function
         /*info:DOWN_CAST_COMPOSITE*/botA,
@@ -1297,212 +1297,6 @@
 ''');
   }
 
-  test_fuzzyArrowLegacyAssignability_GlobalInference() async {
-    // Test for legacy fuzzy arrow support on assignability, pending
-    // cleanup.  https://github.com/dart-lang/sdk/issues/29630
-    // Tests impact of https://github.com/dart-lang/sdk/issues/32114
-    // on fuzzy arrow warnings
-    await checkFile('''
-    typedef T Fn<T>(T x);
-    typedef T FnB<T extends int>(T x);
-
-    class I2i {
-      int call(int x) => x;
-    }
-    class D2i {
-      int call(dynamic x) => x as int;
-    }
-    class I2d {
-      dynamic call(int x) => x;
-    }
-    class D2d {
-      dynamic call(dynamic x) => x;
-    }
-    Fn global0;
-    var inferred0 = global0;
-    FnB global1;
-    var inferred1 = global1;
-
-    void test0() {
-      int Function(int) i2i;
-      int Function(dynamic) d2i;
-      dynamic Function(int) i2d;
-      dynamic Function(dynamic) d2d;
-      I2i ci2i;
-      D2i cd2i;
-      I2d ci2d;
-      D2d cd2d;
-
-      { 
-        var f = inferred0;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2i;
-        f = d2i;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2d;
-        f = d2d;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/ci2i;
-        f = cd2i;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/ci2d;
-        f = cd2d;
-      }
-      {
-        var f = inferred1; 
-        f = i2i;
-        f = d2i;
-        f = /*info:DOWN_CAST_COMPOSITE*/i2d; // Real downcast
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/d2d; // Fuzzy downcast
-        f = ci2i;
-        f = cd2i;
-        f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
-        f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
-      }
-    }
-  ''');
-  }
-
-  test_fuzzyArrowLegacyAssignability() async {
-    // Test for legacy fuzzy arrow support on assignability, pending
-    // cleanup.  https://github.com/dart-lang/sdk/issues/29630
-    await checkFile('''
-
-    class I2i {
-      int call(int x) => x;
-    }
-    class D2i {
-      int call(dynamic x) => x as int;
-    }
-    class I2d {
-      dynamic call(int x) => x;
-    }
-    class D2d {
-      dynamic call(dynamic x) => x;
-    }
-
-    void test0() {
-      int Function(int) i2i;
-      int Function(dynamic) d2i;
-      dynamic Function(int) i2d;
-      dynamic Function(dynamic) d2d;
-      I2i ci2i;
-      D2i cd2i;
-      I2d ci2d;
-      D2d cd2d;
-
-      { 
-        int Function(int) f;
-        f = i2i;
-        f = d2i;
-        f = /*info:DOWN_CAST_COMPOSITE*/i2d;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/d2d;
-        f = ci2i;
-        f = cd2i;
-        f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
-        f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
-      }
-      { 
-        int Function(dynamic) f;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2i;
-        f = d2i;
-        f = /*info:DOWN_CAST_COMPOSITE*/i2d;
-        f = /*info:DOWN_CAST_COMPOSITE*/d2d;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2i;
-        f = cd2i;
-        f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
-        f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
-      }
-      { 
-        dynamic Function(int) f;
-        f = i2i;
-        f = d2i;
-        f = i2d;
-        f = d2d;
-        f = ci2i;
-        f = cd2i;
-        f = ci2d;
-        f = cd2d;
-      }
-      { 
-        dynamic Function(dynamic) f;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2i;
-        f = d2i;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2d;
-        f = d2d;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2i;
-        f = cd2i;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2d;
-        f = cd2d;
-      }
-    }
-  ''');
-  }
-
-  test_functionTypingAndSubtyping_dynamicFunctions_closuresAreNotFuzzy() async {
-    // Regression test for definite function cases
-    // https://github.com/dart-lang/sdk/issues/26118
-    // https://github.com/dart-lang/sdk/issues/26156
-    // https://github.com/dart-lang/sdk/issues/28087
-    await checkFile('''
-void takesF(void f(int x)) {}
-
-typedef void TakesInt(int x);
-
-void update(_) {}
-void updateOpt([_]) {}
-void updateOptNum([num x]) {}
-
-class Callable {
-  void call(_) {}
-}
-
-class A {
-  TakesInt f;
-  A(TakesInt g) {
-    f = update;
-    f = updateOpt;
-    f = updateOptNum;
-    f = new Callable();
-  }
-  TakesInt g(bool a, bool b) {
-    if (a) {
-      return update;
-    } else if (b) {
-      return updateOpt;
-    } else if (a) {
-      return updateOptNum;
-    } else {
-      return new Callable();
-    }
-  }
-}
-
-void test0() {
-  takesF(update);
-  takesF(updateOpt);
-  takesF(updateOptNum);
-  takesF(new Callable());
-  TakesInt f;
-  f = update;
-  f = updateOpt;
-  f = updateOptNum;
-  f = new Callable();
-  new A(update);
-  new A(updateOpt);
-  new A(updateOptNum);
-  new A(new Callable());
-}
-
-void test1() {
-  void takesF(f(int x)) => null;
-  takesF(/*info:INFERRED_TYPE_CLOSURE*/(dynamic y) => 3);
-}
-
-void test2() {
-  int x;
-  int f<T>(T t, callback(T x)) { return 3; }
-  f(x, /*info:INFERRED_TYPE_CLOSURE*/(y) => 3);
-}
-''');
-  }
-
   test_functionTypingAndSubtyping_functionLiteralVariance() async {
     await checkFile('''
 class A {}
@@ -3228,20 +3022,6 @@
 ''');
   }
 
-  test_leastUpperBounds_fuzzyArrows() async {
-    await checkFile(r'''
-typedef String TakesA<T>(T item);
-
-void main() {
-  TakesA<int> f;
-  TakesA<dynamic> g;
-  TakesA<String> h;
-  g = /*warning:USES_DYNAMIC_AS_BOTTOM*/h;
-  f = f ?? g;
-}
-''');
-  }
-
   test_loadLibrary() async {
     addFile('''library lib1;''', name: '/lib1.dart');
     await checkFile(r'''
@@ -4609,11 +4389,6 @@
     await super.test_covariantOverride_fields();
   }
 
-  @override
-  test_fuzzyArrowLegacyAssignability_GlobalInference() async {
-    await super.test_fuzzyArrowLegacyAssignability_GlobalInference();
-  }
-
   @override // Passes with driver
   test_interfacesFromMixinsUsedTwiceAreChecked() =>
       super.test_interfacesFromMixinsUsedTwiceAreChecked();
diff --git a/pkg/analyzer/test/src/task/test_support.dart b/pkg/analyzer/test/src/task/test_support.dart
index f501e54..7415324 100644
--- a/pkg/analyzer/test/src/task/test_support.dart
+++ b/pkg/analyzer/test/src/task/test_support.dart
@@ -2,11 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.src.task.test_support;
-
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
 
 /**
  * A configurable analysis task that can be used by tests.
diff --git a/pkg/analyzer/test/src/task/yaml_test.dart b/pkg/analyzer/test/src/task/yaml_test.dart
index 4601360..e8f8352 100644
--- a/pkg/analyzer/test/src/task/yaml_test.dart
+++ b/pkg/analyzer/test/src/task/yaml_test.dart
@@ -2,12 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.src.task.yaml_test;
-
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/yaml.dart';
 import 'package:analyzer/src/task/yaml.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/yaml.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:yaml/yaml.dart';
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index f2bbd10..6866377 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -458,16 +458,6 @@
   }
 
   @override
-  void handleModifier(Token token) {
-    debugEvent("Modifier");
-  }
-
-  @override
-  void handleModifiers(int count) {
-    debugEvent("Modifiers");
-  }
-
-  @override
   void handleQualified(Token period) {
     debugEvent("Qualified");
     String suffix = pop();
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index dbb7b1d..e3ddb67 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -199,8 +199,9 @@
     TypeProvider typeProvider = await driver.currentSession.typeProvider;
 
     String dartDartPath = path.join(rootDir, 'lib', 'src', 'task', 'dart.dart');
-    String taskPath = path.join(rootDir, 'lib', 'plugin', 'task.dart');
-    String modelPath = path.join(rootDir, 'lib', 'task', 'model.dart');
+    String taskPath = path.join(rootDir, 'lib', 'src', 'plugin', 'task.dart');
+    String modelPath =
+        path.join(rootDir, 'lib', 'src', 'task', 'api', 'model.dart');
     String enginePluginPath =
         path.join(rootDir, 'lib', 'src', 'plugin', 'engine_plugin.dart');
 
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 9dcf36b..ca20983 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -10,11 +10,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/source/path_filter.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
-import 'package:analyzer/source/sdk_ext.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -30,6 +26,10 @@
 import 'package:analyzer/src/generated/utilities_general.dart'
     show PerformanceTag;
 import 'package:analyzer/src/pubspec/pubspec_validator.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/path_filter.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
+import 'package:analyzer/src/source/sdk_ext.dart';
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index cb023c4..0c84618 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -2,9 +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.
 
-library analyzer_cli.src.error_formatter;
-
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_cli/src/ansi.dart';
@@ -263,7 +262,7 @@
   void formatError(
       Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
     Source source = error.source;
-    LineInfo_Location location = errorToLine[error].getLocation(error.offset);
+    CharacterLocation location = errorToLine[error].getLocation(error.offset);
 
     ErrorSeverity severity = _severityProcessor(error);
 
@@ -324,7 +323,7 @@
   void formatError(
       Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
     Source source = error.source;
-    LineInfo_Location location = errorToLine[error].getLocation(error.offset);
+    CharacterLocation location = errorToLine[error].getLocation(error.offset);
     int length = error.length;
 
     ErrorSeverity severity = _severityProcessor(error);
diff --git a/pkg/analyzer_cli/lib/src/perf_report.dart b/pkg/analyzer_cli/lib/src/perf_report.dart
index 60acdf1..110fa0f 100644
--- a/pkg/analyzer_cli/lib/src/perf_report.dart
+++ b/pkg/analyzer_cli/lib/src/perf_report.dart
@@ -2,14 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer_cli.src.perf_report;
-
 import 'dart:convert' show JsonEncoder;
 import 'dart:io' show Platform;
 
 import 'package:analyzer/src/generated/utilities_general.dart'
     show PerformanceTag;
-import 'package:analyzer/task/model.dart' show AnalysisTask;
+import 'package:analyzer/src/task/api/model.dart' show AnalysisTask;
 import 'package:analyzer_cli/src/error_formatter.dart';
 import 'package:analyzer_cli/src/options.dart' show CommandLineOptions;
 
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index f0e587d..4943ea9 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -9,7 +9,6 @@
   analyzer: ^0.27.0
   args: '>=0.13.0 <2.0.0'
   bazel_worker: ^0.1.0
-  cli_util: ^0.1.0
   collection: ^1.14.1
   linter: ^0.1.16
   package_config: '>=0.1.5 <2.0.0'
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 78f7a70..9fb32f4 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -6,8 +6,8 @@
 import 'dart:io';
 
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 84bd9a3..985464c 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_cli/src/options.dart';
@@ -84,7 +85,7 @@
 }
 
 class MockLineInfo implements LineInfo {
-  MockLineInfo_Location defaultLocation;
+  CharacterLocation defaultLocation;
 
   MockLineInfo({this.defaultLocation});
 
@@ -99,7 +100,7 @@
   }
 
   @override
-  LineInfo_Location getLocation(int offset) {
+  CharacterLocation getLocation(int offset) {
     if (defaultLocation != null) {
       return defaultLocation;
     }
@@ -117,16 +118,6 @@
   }
 }
 
-class MockLineInfo_Location implements LineInfo_Location {
-  @override
-  int lineNumber;
-
-  @override
-  int columnNumber;
-
-  MockLineInfo_Location(this.lineNumber, this.columnNumber);
-}
-
 class MockSource implements Source {
   @override
   String fullName;
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index 4f4bc85..a86c03d 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
 import 'package:analyzer_cli/src/error_formatter.dart';
@@ -71,7 +72,7 @@
 
 MockAnalysisErrorInfo mockError(ErrorType type, ErrorSeverity severity) {
   // ErrorInfo
-  var location = new MockLineInfo_Location(3, 3);
+  var location = new CharacterLocation(3, 3);
   var lineInfo = new MockLineInfo(defaultLocation: location);
 
   // Details
diff --git a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
index ba03cb8..5778af8 100644
--- a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
@@ -277,9 +277,11 @@
     if (json is int) {
       return json;
     } else if (json is String) {
-      return int.parse(json, onError: (String value) {
+      int value = int.tryParse(json);
+      if (value == null) {
         throw mismatch(jsonPath, 'int', json);
-      });
+      }
+      return value;
     }
     throw mismatch(jsonPath, 'int', json);
   }
diff --git a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
index e562071..66b0ed6 100644
--- a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
+++ b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/error/error.dart' as analyzer;
 import 'package:analyzer/exception/exception.dart' as analyzer;
 import 'package:analyzer/source/error_processor.dart' as analyzer;
+import 'package:analyzer/source/line_info.dart' as analyzer;
 import 'package:analyzer/src/generated/engine.dart' as analyzer;
 import 'package:analyzer/src/generated/source.dart' as analyzer;
 import 'package:analyzer/src/generated/utilities_dart.dart' as analyzer;
@@ -35,7 +36,7 @@
     int startLine = -1;
     int startColumn = -1;
     if (lineInfo != null) {
-      analyzer.LineInfo_Location lineLocation = lineInfo.getLocation(offset);
+      analyzer.CharacterLocation lineLocation = lineInfo.getLocation(offset);
       if (lineLocation != null) {
         startLine = lineLocation.lineNumber;
         startColumn = lineLocation.columnNumber;
@@ -338,7 +339,7 @@
     try {
       analyzer.LineInfo lineInfo = unitElement.lineInfo;
       if (lineInfo != null) {
-        analyzer.LineInfo_Location offsetLocation =
+        analyzer.CharacterLocation offsetLocation =
             lineInfo.getLocation(range.offset);
         startLine = offsetLocation.lineNumber;
         startColumn = offsetLocation.columnNumber;
diff --git a/pkg/analyzer_plugin/test/plugin/mocks.dart b/pkg/analyzer_plugin/test/plugin/mocks.dart
index a9ff4d8..1ccb601 100644
--- a/pkg/analyzer_plugin/test/plugin/mocks.dart
+++ b/pkg/analyzer_plugin/test/plugin/mocks.dart
@@ -7,6 +7,7 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/timestamped_data.dart';
@@ -22,8 +23,15 @@
   Set<String> addedFiles = new HashSet<String>();
 
   MockAnalysisDriver()
-      : super(new AnalysisDriverScheduler(null), null, null, null, null, null,
-            new SourceFactory([]), new AnalysisOptionsImpl());
+      : super(
+            new AnalysisDriverScheduler(null),
+            null,
+            new MockResourceProvider(),
+            null,
+            new FileContentOverlay(),
+            null,
+            new SourceFactory([]),
+            new AnalysisOptionsImpl());
 
   @override
   bool get hasFilesToAnalyze => false;
@@ -115,6 +123,11 @@
   }
 }
 
+class MockResourceProvider implements ResourceProvider {
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
 /**
  * A concrete implementation of a server plugin that is suitable for testing.
  */
diff --git a/pkg/compiler/README.md b/pkg/compiler/README.md
index 6764816..16abf7b 100644
--- a/pkg/compiler/README.md
+++ b/pkg/compiler/README.md
@@ -390,11 +390,6 @@
     representation of JSInt31, JSArray, and other implementation-specific
     elements.
 
-* `lib/src/dart2js_resolver.dart`: a script to run the compiler up to resolution
-  and to generate a serialized json representation of the element model.
-
-  AI: delete.
-
 * `lib/src/deferred_load.dart`: general analysis for deferred loading. This is
   where we compute how to split the code in different JS chunks or fragments.
   This is run after resolution, but at a time when no code is generated yet, so
@@ -608,11 +603,6 @@
    * `lib/src/inferrer/map_tracer.dart`
    * `lib/src/inferrer/builder.dart`
 
-* Serialization (`lib/src/serialization/*`: the compiler had support to emit a
-  serialized form of the element model. This is likely going to be deleted in
-  the near future (it was created before we had the intent to use kernel as a
-  serialization format).
-
 ---------
 
 _TODO: complete the documentation for the following files_.
@@ -782,7 +772,6 @@
 `lib/src/js_backend/no_such_method_registry.dart`
 `lib/src/js_backend/constant_system_javascript.dart`
 `lib/src/js_backend/backend.dart`
-`lib/src/js_backend/backend_serialization.dart`
 `lib/src/js_backend/checked_mode_helpers.dart`
 `lib/src/js_backend/constant_handler_javascript.dart`
 
diff --git a/pkg/compiler/lib/compiler_new.dart b/pkg/compiler/lib/compiler_new.dart
index 23dda02..7d0fd23 100644
--- a/pkg/compiler/lib/compiler_new.dart
+++ b/pkg/compiler/lib/compiler_new.dart
@@ -25,7 +25,7 @@
 enum InputKind {
   /// Data is read as UTF8 either as a [String] or a zero-terminated
   /// `List<int>`.
-  utf8,
+  UTF8,
 
   /// Data is read as bytes in a `List<int>`.
   binary,
@@ -49,7 +49,7 @@
   /// Returns a future that completes to the source corresponding to [uri].
   /// If an exception occurs, the future completes with this exception.
   ///
-  /// If [inputKind] is `InputKind.utf8` the source can be represented either as
+  /// If [inputKind] is `InputKind.UTF8` the source can be represented either as
   /// a zero-terminated `List<int>` of UTF-8 bytes or as a [String]. If
   /// [inputKind] is `InputKind.binary` the source is a read a `List<int>`.
   ///
@@ -59,7 +59,7 @@
   /// scanner is more efficient in this case. In either case, the data structure
   /// is expected to hold a zero element at the last position. If this is not
   /// the case, the entire data structure is copied before scanning.
-  Future<Input> readFromUri(Uri uri, {InputKind inputKind: InputKind.utf8});
+  Future<Input> readFromUri(Uri uri, {InputKind inputKind: InputKind.UTF8});
 }
 
 /// Output types used in `CompilerOutput.createOutputSink`.
@@ -73,9 +73,6 @@
   /// A source map for a JavaScript output.
   sourceMap,
 
-  /// Serialization data output.
-  serializationData,
-
   /// Additional information requested by the user, such dump info or a deferred
   /// map.
   info,
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index cfeecb1..8ff3879 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -116,7 +116,7 @@
     // [Future] to ensure that we never execute an asynchronous action without
     // setting up the current element of the compiler.
     return new Future.sync(
-            () => callUserProvider(resourceUri, api.InputKind.utf8))
+            () => callUserProvider(resourceUri, api.InputKind.UTF8))
         .then((api.Input sourceFile) {
       // We use [readableUri] as the URI for the script since need to preserve
       // the scheme in the script because [Script.uri] is used for resolving
@@ -223,17 +223,6 @@
 
   Future<Null> setupSdk() {
     Future future = new Future.value(null);
-    if (options.resolutionInputs != null) {
-      future = Future.forEach(options.resolutionInputs, (Uri resolutionInput) {
-        reporter.log('Reading serialized data from ${resolutionInput}');
-        Future<SourceFile> future =
-            callUserProvider(resolutionInput, api.InputKind.utf8);
-        return future.then((SourceFile sourceFile) {
-          serialization.deserializeFromText(
-              resolutionInput, sourceFile.slowText());
-        });
-      });
-    }
     if (resolvedUriTranslator.isNotSet) {
       future = future.then((_) {
         return platform_configuration
@@ -276,11 +265,11 @@
     timings.writeln("Timings:");
     Duration totalDuration = measurer.wallClock.elapsed;
     Duration asyncDuration = measurer.asyncWallClock.elapsed;
-    Duration cumulatedDuration = Duration.ZERO;
+    Duration cumulatedDuration = Duration.zero;
     for (final task in tasks) {
       String running = task.isRunning ? "*" : "";
       Duration duration = task.duration;
-      if (duration != Duration.ZERO) {
+      if (duration != Duration.zero) {
         cumulatedDuration += duration;
         timings.writeln('    $running${task.name} took'
             ' ${duration.inMilliseconds}msec');
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index 1c761db..0ab7475 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -8,8 +8,6 @@
 import '../constants/expressions.dart' show ConstantExpression;
 import '../elements/resolution_types.dart'
     show ResolutionDartType, ResolutionInterfaceType;
-import '../serialization/serialization.dart'
-    show DeserializerPlugin, SerializerPlugin;
 import '../tree/tree.dart' show Node;
 import '../universe/world_impact.dart' show WorldImpact;
 
@@ -45,11 +43,3 @@
     return worldImpact;
   }
 }
-
-/// Interface for serialization of backend specific data.
-class BackendSerialization {
-  const BackendSerialization();
-
-  SerializerPlugin get serializer => const SerializerPlugin();
-  DeserializerPlugin get deserializer => const DeserializerPlugin();
-}
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 3e4bd26..3965ba8 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -151,9 +151,6 @@
       Element element, TypeAnnotation node);
 
   /// Returns `true` if [element] has been resolved.
-  // TODO(johnniwinther): Normalize semantics between normal and deserialized
-  // elements; deserialized elements are always resolved but the method will
-  // return `false`.
   bool hasBeenResolved(Element element);
 
   /// Resolve [element] if it has not already been resolved.
diff --git a/pkg/compiler/lib/src/common/tasks.dart b/pkg/compiler/lib/src/common/tasks.dart
index 79fc988..5c75e93 100644
--- a/pkg/compiler/lib/src/common/tasks.dart
+++ b/pkg/compiler/lib/src/common/tasks.dart
@@ -49,7 +49,7 @@
   }
 
   Duration get duration {
-    if (_isDisabled) return Duration.ZERO;
+    if (_isDisabled) return Duration.zero;
     Duration total = _watch.elapsed;
     for (GenericTask subtask in _subtasks.values) {
       total += subtask.duration;
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 693f8fd..8a93589 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -199,9 +199,6 @@
     }
     if (element.hasConstant) {
       if (element.constant != null) {
-        if (compiler.serialization.supportsDeserialization) {
-          evaluate(element.constant);
-        }
         assert(
             hasConstantValue(element.constant),
             failedAt(
@@ -331,11 +328,6 @@
         expression != null,
         failedAt(CURRENT_ELEMENT_SPANNABLE,
             "ConstantExpression is null in getConstantValue."));
-    // TODO(johnniwinther): ensure expressions have been evaluated at this
-    // point. This can't be enabled today due to dartbug.com/26406.
-    if (compiler.serialization.supportsDeserialization) {
-      evaluate(expression);
-    }
     ConstantValue value = constantValueMap[expression];
     if (value == null &&
         expression != null &&
@@ -971,16 +963,6 @@
     if (constructor.isFromEnvironmentConstructor) {
       return createFromEnvironmentConstant(node, constructedType, constructor,
           callStructure, normalizedArguments, concreteArguments);
-    } else if (compiler.serialization.isDeserialized(constructor)) {
-      ConstructedConstantExpression expression =
-          new ConstructedConstantExpression(type, constructor, callStructure,
-              concreteArguments.map((c) => c.expression).toList());
-      return new AstConstant(
-          context,
-          node,
-          expression,
-          expression.evaluate(
-              new AstEvaluationEnvironment(compiler), constantSystem));
     } else {
       return makeConstructedConstant(
           compiler,
@@ -1262,30 +1244,13 @@
       CallStructure callStructure, ConstructorElement targetConstructor) {
     ResolutionInterfaceType type =
         constructedType.asInstanceOf(targetConstructor.enclosingClass);
-    if (compiler.serialization.isDeserialized(targetConstructor)) {
-      List<ConstantExpression> arguments =
-          compiledArguments.map((c) => c.expression).toList();
-      ConstructedConstantExpression expression =
-          new ConstructedConstantExpression(
-              type, targetConstructor, callStructure, arguments);
-
-      InstanceData instanceData = expression
-          .computeInstanceData(new AstEvaluationEnvironment(compiler));
-      instanceData.fieldMap.forEach((_field, ConstantExpression expression) {
-        FieldElement field = _field;
-        ConstantValue value = expression.evaluate(
-            new AstEvaluationEnvironment(compiler), constantSystem);
-        fieldValues[field] = new AstConstant(context, null, expression, value);
-      });
-    } else {
-      ConstructorEvaluator evaluator =
-          new ConstructorEvaluator(type, targetConstructor, handler, compiler);
-      evaluator.evaluateConstructorFieldValues(compiledArguments);
-      // Copy over the fieldValues from the super/redirect-constructor.
-      // No need to go through [updateFieldValue] because the
-      // assignments have already been checked in checked mode.
-      evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
-    }
+    ConstructorEvaluator evaluator =
+        new ConstructorEvaluator(type, targetConstructor, handler, compiler);
+    evaluator.evaluateConstructorFieldValues(compiledArguments);
+    // Copy over the fieldValues from the super/redirect-constructor.
+    // No need to go through [updateFieldValue] because the
+    // assignments have already been checked in checked mode.
+    evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
   }
 
   /**
@@ -1469,7 +1434,7 @@
   }
 
   @override
-  ResolutionInterfaceType substByContext(
+  ResolutionDartType substByContext(
       ResolutionDartType base, ResolutionInterfaceType target) {
     return base.substByContext(target);
   }
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 1767742..e63edc3 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -60,7 +60,6 @@
 import 'resolved_uri_translator.dart';
 import 'scanner/scanner_task.dart' show ScannerTask;
 import 'script.dart' show Script;
-import 'serialization/task.dart' show SerializationTask;
 import 'ssa/nodes.dart' show HInstruction;
 import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token;
 import 'tree/tree.dart' show Node, TypeAnnotation;
@@ -142,7 +141,6 @@
   ParserTask parser;
   PatchParserTask patchParser;
   LibraryLoaderTask libraryLoader;
-  SerializationTask serialization;
   ResolverTask resolver;
   TypeCheckerTask checker;
   GlobalTypeInferenceTask globalInference;
@@ -213,16 +211,12 @@
     tasks = [
       dietParser = new DietParserTask(idGenerator, backend, reporter, measurer),
       scanner = createScannerTask(),
-      serialization = new SerializationTask(this),
       patchParser = new PatchParserTask(this),
       libraryLoader = frontendStrategy.createLibraryLoader(
           resolvedUriTranslator,
-          options.compileOnly
-              ? new _NoScriptLoader(this)
-              : new _ScriptLoader(this),
+          new _ScriptLoader(this),
           provider,
           new _ElementScanner(scanner),
-          serialization,
           resolvePatchUri,
           patchParser,
           environment,
@@ -242,9 +236,6 @@
       selfTask,
     ];
     if (options.useKernel) tasks.add(kernelFrontEndTask);
-    if (options.resolveOnly) {
-      serialization.supportSerialization = true;
-    }
 
     _parsingContext =
         new ParsingContext(reporter, parser, scanner, patchParser, backend);
@@ -544,19 +535,11 @@
         deferredLoadTask.beforeResolution(rootLibrary);
         impactStrategy = backend.createImpactStrategy(
             supportDeferredLoad: deferredLoadTask.isProgramSplit,
-            supportDumpInfo: options.dumpInfo,
-            supportSerialization: serialization.supportSerialization);
+            supportDumpInfo: options.dumpInfo);
 
         phase = PHASE_RESOLVING;
         resolutionEnqueuer.applyImpact(mainImpact);
-        if (options.resolveOnly) {
-          libraryLoader.libraries.where((LibraryEntity library) {
-            return !serialization.isDeserialized(library);
-          }).forEach((LibraryEntity library) {
-            reporter.log('Enqueuing ${library.canonicalUri}');
-            resolutionEnqueuer.applyImpact(computeImpactForLibrary(library));
-          });
-        } else if (analyzeAll) {
+        if (analyzeAll) {
           libraryLoader.libraries.forEach((LibraryEntity library) {
             reporter.log('Enqueuing ${library.canonicalUri}');
             resolutionEnqueuer.applyImpact(computeImpactForLibrary(library));
@@ -599,15 +582,6 @@
           }
         }
 
-        if (options.resolveOnly && !compilationFailed) {
-          reporter.log('Serializing to ${options.resolutionOutput}');
-          serialization.serializeToSink(
-              outputProvider.createOutputSink(
-                  '', 'data', api.OutputType.serializationData),
-              libraryLoader.libraries.where((LibraryEntity library) {
-            return !serialization.isDeserialized(library);
-          }));
-        }
         if (options.analyzeOnly) return;
         assert(mainFunction != null);
 
@@ -717,24 +691,7 @@
             registerStaticUse(loadLibrary);
           }
         }
-        if (serialization.supportSerialization) {
-          for (MetadataAnnotation metadata in import.metadata) {
-            metadata.ensureResolved(resolution);
-          }
-        }
       });
-      if (serialization.supportSerialization) {
-        library.exports.forEach((ExportElement export) {
-          for (MetadataAnnotation metadata in export.metadata) {
-            metadata.ensureResolved(resolution);
-          }
-        });
-        library.compilationUnits.forEach((CompilationUnitElement unit) {
-          for (MetadataAnnotation metadata in unit.metadata) {
-            metadata.ensureResolved(resolution);
-          }
-        });
-      }
     } else {
       ElementEnvironment elementEnvironment =
           frontendStrategy.elementEnvironment;
@@ -1418,17 +1375,12 @@
 
   @override
   void ensureResolved(Element element) {
-    if (_compiler.serialization.isDeserialized(element)) {
-      return;
-    }
     computeWorldImpact(element);
   }
 
   @override
   void ensureClassMembers(ClassElement element) {
-    if (!_compiler.serialization.isDeserialized(element)) {
-      _compiler.resolver.checkClass(element);
-    }
+    _compiler.resolver.checkClass(element);
   }
 
   @override
@@ -1439,9 +1391,6 @@
   bool hasResolvedAst(ExecutableElement element) {
     assert(element.isDeclaration,
         failedAt(element, "Element $element must be the declaration."));
-    if (_compiler.serialization.isDeserialized(element)) {
-      return _compiler.serialization.hasResolvedAst(element);
-    }
     return hasBeenResolved(element.memberContext.declaration) &&
         element.hasResolvedAst;
   }
@@ -1452,9 +1401,6 @@
         failedAt(element, "Element $element must be the declaration."));
     assert(hasResolvedAst(element),
         failedAt(element, "ResolvedAst not available for $element."));
-    if (_compiler.serialization.isDeserialized(element)) {
-      return _compiler.serialization.getResolvedAst(element);
-    }
     return element.resolvedAst;
   }
 
@@ -1468,9 +1414,6 @@
   bool hasResolutionImpact(Element element) {
     assert(element.isDeclaration,
         failedAt(element, "Element $element must be the declaration."));
-    if (_compiler.serialization.isDeserialized(element)) {
-      return _compiler.serialization.hasResolutionImpact(element);
-    }
     return _resolutionImpactCache.containsKey(element);
   }
 
@@ -1478,12 +1421,7 @@
   ResolutionImpact getResolutionImpact(Element element) {
     assert(element.isDeclaration,
         failedAt(element, "Element $element must be the declaration."));
-    ResolutionImpact resolutionImpact;
-    if (_compiler.serialization.isDeserialized(element)) {
-      resolutionImpact = _compiler.serialization.getResolutionImpact(element);
-    } else {
-      resolutionImpact = _resolutionImpactCache[element];
-    }
+    ResolutionImpact resolutionImpact = _resolutionImpactCache[element];
     assert(resolutionImpact != null,
         failedAt(element, "ResolutionImpact not available for $element."));
     return resolutionImpact;
@@ -1525,8 +1463,7 @@
         assert(!element.isSynthesized || tree == null, failedAt(element));
         ResolutionImpact resolutionImpact = _compiler.resolver.resolve(element);
 
-        if (_compiler.serialization.supportSerialization ||
-            retainCachesForTesting) {
+        if (retainCachesForTesting) {
           // [ResolutionImpact] is currently only used by serialization. The
           // enqueuer uses the [WorldImpact] which is always cached.
           // TODO(johnniwinther): Align these use cases better; maybe only
@@ -1559,7 +1496,6 @@
     assert(element.isDeclaration,
         failedAt(element, "Element $element must be the declaration."));
     if (retainCachesForTesting) return;
-    if (_compiler.serialization.isDeserialized(element)) return;
     assert(_worldImpactCache[element] != null,
         failedAt(element, "WorldImpact not computed for $element."));
     _worldImpactCache[element] = const WorldImpact();
@@ -1582,11 +1518,7 @@
 
   @override
   ResolutionWorkItem createWorkItem(MemberElement element) {
-    if (_compiler.serialization.isDeserialized(element)) {
-      return _compiler.serialization.createResolutionWorkItem(element);
-    } else {
-      return new ResolutionWorkItem(this, element);
-    }
+    return new ResolutionWorkItem(this, element);
   }
 
   ConstantValue _proxyConstant;
@@ -1637,23 +1569,6 @@
       compiler.readBinary(uri, spannable);
 }
 
-/// [ScriptLoader] used to ensure that scripts are not loaded accidentally
-/// through the [LibraryLoader] when `CompilerOptions.compileOnly` is `true`.
-class _NoScriptLoader implements ScriptLoader {
-  Compiler compiler;
-  _NoScriptLoader(this.compiler);
-
-  Future<Script> readScript(Uri uri, [Spannable spannable]) {
-    throw compiler.reporter
-        .internalError(spannable, "Script loading of '$uri' is not enabled.");
-  }
-
-  Future<Binary> readBinary(Uri uri, [Spannable spannable]) {
-    throw compiler.reporter
-        .internalError(spannable, "Script loading of '$uri' is not enabled.");
-  }
-}
-
 class _ElementScanner implements ElementScanner {
   ScannerTask scanner;
   _ElementScanner(this.scanner);
diff --git a/pkg/compiler/lib/src/constants/evaluation.dart b/pkg/compiler/lib/src/constants/evaluation.dart
index 7a20827..92dca21 100644
--- a/pkg/compiler/lib/src/constants/evaluation.dart
+++ b/pkg/compiler/lib/src/constants/evaluation.dart
@@ -39,7 +39,7 @@
 
   /// Performs the substitution of the type arguments of [target] for their
   /// corresponding type variables in [type].
-  InterfaceType substByContext(
+  DartType substByContext(
       covariant DartType base, covariant InterfaceType target);
 
   void reportWarning(
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 2a6813c..b86d8e7 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -847,16 +847,55 @@
   @override
   ConstantValue evaluate(
       EvaluationEnvironment environment, ConstantSystem constantSystem) {
+    // Running example for comments:
+    //
+    //     class A<T> {
+    //       final T t;
+    //       const A(dynamic t) : this.t = t; // implicitly `t as A.T`
+    //     }
+    //     class B<S> extends A<S> {
+    //       const B(dynamic s) : super(s);
+    //     }
+    //     main() => const B<num>(0);
+    //
+    // We visit `t as A.T` while evaluating `const B<num>(0)`.
+
+    // The expression value is `0`.
     ConstantValue expressionValue =
         expression.evaluate(environment, constantSystem);
+
+    // The expression type is `int`.
     DartType expressionType =
         expressionValue.getType(environment.commonElements);
+
+    // The `as` type is `A.T`.
+    DartType typeInContext = type;
+
+    // The enclosing type is `B<num>`.
     DartType enclosingType = environment.enclosingConstructedType;
-    DartType superType = enclosingType != null
-        ? environment.substByContext(type, enclosingType)
-        : type;
+    if (enclosingType != null) {
+      ClassEntity contextClass;
+      type.forEachTypeVariable((TypeVariableType type) {
+        if (type.element.typeDeclaration is ClassEntity) {
+          // We find `A` from `A.T`. Since we don't have nested classes, class
+          // based type variables can only come from the same class.
+          contextClass = type.element.typeDeclaration;
+        }
+      });
+      if (contextClass != null) {
+        // The enclosing type `B<num>` as an instance of `A` is `A<num>`.
+        enclosingType =
+            environment.types.asInstanceOf(enclosingType, contextClass);
+      }
+      // `A.T` in the context of the enclosing type `A<num>` is `num`.
+      typeInContext = enclosingType != null
+          ? environment.substByContext(typeInContext, enclosingType)
+          : typeInContext;
+    }
+    // Check that the expression type, `int`, is a subtype of the type in
+    // context, `num`.
     if (!constantSystem.isSubtype(
-        environment.types, expressionType, superType)) {
+        environment.types, expressionType, typeInContext)) {
       // TODO(sigmund): consider reporting different messages and error
       // locations for implicit vs explicit casts.
       environment.reportError(expression, MessageKind.INVALID_CONSTANT_CAST,
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 230350a..9fd6a9b 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -278,11 +278,11 @@
 
   factory DoubleConstantValue(double value) {
     if (value.isNaN) {
-      return const DoubleConstantValue._internal(double.NAN);
-    } else if (value == double.INFINITY) {
-      return const DoubleConstantValue._internal(double.INFINITY);
-    } else if (value == -double.INFINITY) {
-      return const DoubleConstantValue._internal(-double.INFINITY);
+      return const DoubleConstantValue._internal(double.nan);
+    } else if (value == double.infinity) {
+      return const DoubleConstantValue._internal(double.infinity);
+    } else if (value == -double.infinity) {
+      return const DoubleConstantValue._internal(-double.infinity);
     } else if (value == 0.0 && !value.isNegative) {
       return const DoubleConstantValue._internal(0.0);
     } else if (value == 1.0) {
@@ -305,9 +305,9 @@
 
   bool get isOne => doubleValue == 1.0;
 
-  bool get isPositiveInfinity => doubleValue == double.INFINITY;
+  bool get isPositiveInfinity => doubleValue == double.infinity;
 
-  bool get isNegativeInfinity => doubleValue == -double.INFINITY;
+  bool get isNegativeInfinity => doubleValue == -double.infinity;
 
   DartType getType(CommonElements types) => types.doubleType;
 
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index c1d77eb..b73c362 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -5,7 +5,7 @@
 library dart2js.cmdline;
 
 import 'dart:async' show Future;
-import 'dart:convert' show UTF8, LineSplitter;
+import 'dart:convert' show utf8, LineSplitter;
 import 'dart:io' show exit, File, FileMode, Platform, stdin, stderr;
 
 import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
@@ -15,10 +15,7 @@
 
 import '../compiler_new.dart' as api;
 import 'commandline_options.dart';
-import 'common/names.dart' show Uris;
 import 'filenames.dart';
-import 'io/source_file.dart';
-import 'null_compiler_output.dart';
 import 'options.dart' show CompilerOptions;
 import 'source_file_provider.dart';
 import 'util/command_line.dart';
@@ -832,11 +829,7 @@
     throw _EXIT_SIGNAL;
   };
 
-  if (USE_SERIALIZED_DART_CORE) {
-    _useSerializedDataForDartCore(compileFunc);
-  }
-
-  var stream = stdin.transform(UTF8.decoder).transform(new LineSplitter());
+  var stream = stdin.transform(utf8.decoder).transform(new LineSplitter());
   var subscription;
   fe.InitializedCompilerState kernelInitializedCompilerState;
   subscription = stream.listen((line) {
@@ -872,189 +865,3 @@
     });
   });
 }
-
-// TODO(johnniwinther): Add corresponding options to the test script and change
-// these to use 'bool.fromEnvironment'.
-final bool USE_SERIALIZED_DART_CORE =
-    Platform.environment['USE_SERIALIZED_DART_CORE'] == 'true';
-
-final bool SERIALIZED_COMPILATION =
-    Platform.environment['SERIALIZED_COMPILATION'] == 'true';
-
-/// Mock URI used only in testing when [USE_SERIALIZED_DART_CORE] or
-/// [SERIALIZED_COMPILATION] is enabled.
-final Uri _SERIALIZED_DART_CORE_URI = Uri.parse('file:core.data');
-final Uri _SERIALIZED_TEST_URI = Uri.parse('file:test.data');
-
-void _useSerializedDataForDartCore(CompileFunc oldCompileFunc) {
-  /// Run the [oldCompileFunc] with [serializedData] added as resolution input.
-  Future<api.CompilationResult> compileWithSerializedData(
-      CompilerOptions compilerOptions,
-      api.CompilerInput compilerInput,
-      api.CompilerDiagnostics compilerDiagnostics,
-      api.CompilerOutput compilerOutput,
-      List<_SerializedData> serializedData,
-      {bool compileOnly: false}) {
-    api.CompilerInput input = compilerInput;
-    CompilerOptions options = compilerOptions;
-    if (serializedData != null && serializedData.isNotEmpty) {
-      Map<Uri, String> dataMap = <Uri, String>{};
-      for (_SerializedData data in serializedData) {
-        dataMap[data.uri] = data.data;
-      }
-      input = new _CompilerInput(input, dataMap);
-      List<Uri> resolutionInputs = dataMap.keys.toList();
-      if (compilerOptions.resolutionInputs != null) {
-        for (Uri uri in compilerOptions.resolutionInputs) {
-          if (!dataMap.containsKey(uri)) {
-            resolutionInputs.add(uri);
-          }
-        }
-      }
-      options
-        ..resolutionInputs = resolutionInputs
-        ..compileOnly = compileOnly;
-    }
-    return oldCompileFunc(options, input, compilerDiagnostics, compilerOutput);
-  }
-
-  /// Serialize [entryPoint] using [serializedData] if provided.
-  Future<api.CompilationResult> serialize(
-      Uri entryPoint,
-      Uri serializedUri,
-      CompilerOptions compilerOptions,
-      api.CompilerInput compilerInput,
-      api.CompilerDiagnostics compilerDiagnostics,
-      api.CompilerOutput compilerOutput,
-      [List<_SerializedData> serializedData]) {
-    compilerOptions
-      ..entryPoint = entryPoint
-      ..resolutionOutput = serializedUri
-      ..analyzeAll = true
-      ..analyzeOnly = true
-      ..resolveOnly = true;
-    return compileWithSerializedData(compilerOptions, compilerInput,
-        compilerDiagnostics, compilerOutput, serializedData);
-  }
-
-  // Local cache for the serialized data for dart:core.
-  _SerializedData serializedDartCore;
-
-  /// Serialize the entry point using serialized data from dart:core and run
-  /// [oldCompileFunc] using serialized data for whole program.
-  Future<api.CompilationResult> compileFromSerializedData(
-      CompilerOptions compilerOptions,
-      api.CompilerInput compilerInput,
-      api.CompilerDiagnostics compilerDiagnostics,
-      api.CompilerOutput compilerOutput) async {
-    _CompilerOutput output = new _CompilerOutput(_SERIALIZED_TEST_URI);
-    api.CompilationResult result = await serialize(
-        compilerOptions.entryPoint,
-        output.uri,
-        compilerOptions,
-        compilerInput,
-        compilerDiagnostics,
-        output,
-        [serializedDartCore]);
-    if (!result.isSuccess) {
-      return result;
-    }
-    return compileWithSerializedData(
-        compilerOptions,
-        compilerInput,
-        compilerDiagnostics,
-        compilerOutput,
-        [serializedDartCore, output.serializedData],
-        compileOnly: true);
-  }
-
-  /// Compiles the entry point using the serialized data from dart:core.
-  Future<api.CompilationResult> compileWithSerializedDartCoreData(
-      CompilerOptions compilerOptions,
-      api.CompilerInput compilerInput,
-      api.CompilerDiagnostics compilerDiagnostics,
-      api.CompilerOutput compilerOutput) async {
-    return compileWithSerializedData(compilerOptions, compilerInput,
-        compilerDiagnostics, compilerOutput, [serializedDartCore]);
-  }
-
-  /// Serialize dart:core data into [serializedDartCore] and setup the
-  /// [compileFunc] to run the compiler using this data.
-  Future<api.CompilationResult> generateSerializedDataForDartCore(
-      CompilerOptions compilerOptions,
-      api.CompilerInput compilerInput,
-      api.CompilerDiagnostics compilerDiagnostics,
-      api.CompilerOutput compilerOutput) async {
-    _CompilerOutput output = new _CompilerOutput(_SERIALIZED_DART_CORE_URI);
-    await serialize(Uris.dart_core, output.uri, compilerOptions, compilerInput,
-        compilerDiagnostics, output);
-    serializedDartCore = output.serializedData;
-    if (SERIALIZED_COMPILATION) {
-      compileFunc = compileFromSerializedData;
-    } else {
-      compileFunc = compileWithSerializedDartCoreData;
-    }
-    return compileFunc(
-        compilerOptions, compilerInput, compilerDiagnostics, compilerOutput);
-  }
-
-  compileFunc = generateSerializedDataForDartCore;
-}
-
-class _CompilerInput implements api.CompilerInput {
-  final api.CompilerInput _input;
-  final Map<Uri, String> _data;
-
-  _CompilerInput(this._input, this._data);
-
-  @override
-  Future<api.Input> readFromUri(Uri uri,
-      {api.InputKind inputKind: api.InputKind.utf8}) {
-    String data = _data[uri];
-    if (data != null) {
-      return new Future.value(new StringSourceFile.fromUri(uri, data));
-    }
-    return _input.readFromUri(uri, inputKind: inputKind);
-  }
-}
-
-class _SerializedData {
-  final Uri uri;
-  final String data;
-
-  _SerializedData(this.uri, this.data);
-}
-
-class _CompilerOutput extends NullCompilerOutput {
-  final Uri uri;
-  _BufferedOutputSink sink;
-
-  _CompilerOutput(this.uri);
-
-  @override
-  api.OutputSink createOutputSink(
-      String name, String extension, api.OutputType type) {
-    if (name == '' && extension == 'data') {
-      return sink = new _BufferedOutputSink();
-    }
-    return super.createOutputSink(name, extension, type);
-  }
-
-  _SerializedData get serializedData {
-    return new _SerializedData(uri, sink.sb.toString());
-  }
-}
-
-class _BufferedOutputSink implements api.OutputSink {
-  StringBuffer sb = new StringBuffer();
-
-  @override
-  void add(String event) {
-    sb.write(event);
-  }
-
-  @override
-  void close() {
-    // Do nothing.
-  }
-}
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index afceb3d..ad5e6f2 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -474,6 +474,8 @@
         impact,
         new WorldImpactVisitorImpl(visitDynamicUse: (dynamicUse) {
           selections.addAll(closedWorld
+              // TODO(het): Handle `call` on `Closure` through
+              // `world.includesClosureCall`.
               .locateMembers(dynamicUse.selector, dynamicUse.mask)
               .map((MemberEntity e) => new Selection(e, dynamicUse.mask)));
         }, visitStaticUse: (staticUse) {
diff --git a/pkg/compiler/lib/src/frontend_strategy.dart b/pkg/compiler/lib/src/frontend_strategy.dart
index e06ed4f..b6943cb 100644
--- a/pkg/compiler/lib/src/frontend_strategy.dart
+++ b/pkg/compiler/lib/src/frontend_strategy.dart
@@ -28,7 +28,6 @@
 import 'native/resolver.dart';
 import 'patch_parser.dart';
 import 'resolved_uri_translator.dart';
-import 'serialization/task.dart';
 import 'universe/class_hierarchy_builder.dart';
 import 'universe/world_builder.dart';
 import 'universe/world_impact.dart';
@@ -42,7 +41,6 @@
       ScriptLoader scriptLoader,
       api.CompilerInput compilerInput,
       ElementScanner scriptScanner,
-      LibraryDeserializer deserializer,
       PatchResolverFunction patchResolverFunc,
       PatchParserTask patchParser,
       Environment environment,
@@ -153,8 +151,7 @@
 }
 
 /// Class that deletes the contents of an [WorldImpact] cache.
-// TODO(redemption): this can be deleted when we sunset the old front end and
-// delete serialization.
+// TODO(redemption): this can be deleted when we sunset the old front end.
 abstract class ImpactCacheDeleter {
   bool retainCachesForTesting;
 
diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart
index 6deee5e..bf8b69d 100644
--- a/pkg/compiler/lib/src/inferrer/builder.dart
+++ b/pkg/compiler/lib/src/inferrer/builder.dart
@@ -1206,28 +1206,34 @@
 
   void checkIfExposesThis(Selector selector, TypeMask mask) {
     if (isThisExposed) return;
-    inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
-      if (element.isField) {
-        FieldElement field = element;
-        ResolvedAst elementResolvedAst = field.resolvedAst;
-        if (!selector.isSetter &&
-            isInClassOrSubclass(field) &&
-            !field.isFinal &&
-            locals.fieldScope.readField(field) == null &&
-            elementResolvedAst.body == null) {
-          // If the field is being used before this constructor
-          // actually had a chance to initialize it, say it can be
-          // null.
-          inferrer.recordTypeOfField(field, types.nullType);
-        }
-        // Accessing a field does not expose [:this:].
-        return true;
-      }
+    if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
       // TODO(ngeoffray): We could do better here if we knew what we
       // are calling does not expose this.
       isThisExposed = true;
-      return false;
-    });
+    } else {
+      inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
+        if (element.isField) {
+          FieldElement field = element;
+          ResolvedAst elementResolvedAst = field.resolvedAst;
+          if (!selector.isSetter &&
+              isInClassOrSubclass(field) &&
+              !field.isFinal &&
+              locals.fieldScope.readField(field) == null &&
+              elementResolvedAst.body == null) {
+            // If the field is being used before this constructor
+            // actually had a chance to initialize it, say it can be
+            // null.
+            inferrer.recordTypeOfField(field, types.nullType);
+          }
+          // Accessing a field does not expose [:this:].
+          return true;
+        }
+        // TODO(ngeoffray): We could do better here if we knew what we
+        // are calling does not expose this.
+        isThisExposed = true;
+        return false;
+      });
+    }
   }
 
   bool get inInstanceContext {
@@ -2004,16 +2010,19 @@
           (node.asSendSet() != null) &&
           (node.asSendSet().receiver != null) &&
           node.asSendSet().receiver.isThis()) {
-        Iterable<MemberEntity> targets = closedWorld.locateMembers(
-            setterSelector, types.newTypedSelector(thisType, setterMask));
-        // We just recognized a field initialization of the form:
-        // `this.foo = 42`. If there is only one target, we can update
-        // its type.
-        if (targets.length == 1) {
-          MemberElement single = targets.first;
-          if (single.isField) {
-            FieldElement field = single;
-            locals.updateField(field, rhsType);
+        TypeMask typedMask = types.newTypedSelector(thisType, setterMask);
+        if (!closedWorld.includesClosureCall(setterSelector, typedMask)) {
+          Iterable<MemberEntity> targets =
+              closedWorld.locateMembers(setterSelector, typedMask);
+          // We just recognized a field initialization of the form:
+          // `this.foo = 42`. If there is only one target, we can update
+          // its type.
+          if (targets.length == 1) {
+            MemberElement single = targets.first;
+            if (single.isField) {
+              FieldElement field = single;
+              locals.updateField(field, rhsType);
+            }
           }
         }
       }
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 367e64e..100fbdb 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -129,27 +129,33 @@
       // We already consider `this` to have been exposed.
       return;
     }
-    _inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
-      if (element.isField) {
-        FieldEntity field = element;
-        if (!selector.isSetter &&
-            _isInClassOrSubclass(field) &&
-            field.isAssignable &&
-            _locals.fieldScope.readField(field) == null &&
-            getFieldInitializer(_elementMap, field) == null) {
-          // If the field is being used before this constructor
-          // actually had a chance to initialize it, say it can be
-          // null.
-          _inferrer.recordTypeOfField(field, _types.nullType);
-        }
-        // Accessing a field does not expose `this`.
-        return true;
-      }
+    if (_inferrer.closedWorld.includesClosureCall(selector, mask)) {
       // TODO(ngeoffray): We could do better here if we knew what we
       // are calling does not expose this.
       _markThisAsExposed();
-      return false;
-    });
+    } else {
+      _inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
+        if (element != null && element.isField) {
+          FieldEntity field = element;
+          if (!selector.isSetter &&
+              _isInClassOrSubclass(field) &&
+              field.isAssignable &&
+              _locals.fieldScope.readField(field) == null &&
+              getFieldInitializer(_elementMap, field) == null) {
+            // If the field is being used before this constructor
+            // actually had a chance to initialize it, say it can be
+            // null.
+            _inferrer.recordTypeOfField(field, _types.nullType);
+          }
+          // Accessing a field does not expose `this`.
+          return true;
+        }
+        // TODO(ngeoffray): We could do better here if we knew what we
+        // are calling does not expose this.
+        _markThisAsExposed();
+        return false;
+      });
+    }
   }
 
   TypeInformation run() {
@@ -1209,16 +1215,19 @@
     }
 
     if (_inGenerativeConstructor && node.receiver is ir.ThisExpression) {
-      Iterable<MemberEntity> targets = _closedWorld.locateMembers(
-          selector, _types.newTypedSelector(receiverType, mask));
-      // We just recognized a field initialization of the form:
-      // `this.foo = 42`. If there is only one target, we can update
-      // its type.
-      if (targets.length == 1) {
-        MemberEntity single = targets.first;
-        if (single.isField) {
-          FieldEntity field = single;
-          _locals.updateField(field, rhsType);
+      TypeMask typedMask = _types.newTypedSelector(receiverType, mask);
+      if (!_closedWorld.includesClosureCall(selector, typedMask)) {
+        Iterable<MemberEntity> targets =
+            _closedWorld.locateMembers(selector, typedMask);
+        // We just recognized a field initialization of the form:
+        // `this.foo = 42`. If there is only one target, we can update
+        // its type.
+        if (targets.length == 1) {
+          MemberEntity single = targets.first;
+          if (single.isField) {
+            FieldEntity field = single;
+            _locals.updateField(field, rhsType);
+          }
         }
       }
     }
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index 174089d..1c131cb 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -115,13 +115,14 @@
     super.visitDynamicCallSiteTypeInformation(info);
     if (info.selector.isCall) {
       if (info.arguments.contains(currentUser)) {
-        if (!info.targets.every((element) => element.isFunction)) {
+        if (info.hasClosureCallTargets ||
+            info.concreteTargets.any((element) => !element.isFunction)) {
           bailout('Passed to a closure');
         }
-        if (info.targets.any(_checkIfFunctionApply)) {
+        if (info.concreteTargets.any(_checkIfFunctionApply)) {
           _tagAsFunctionApplyTarget("dynamic call");
         }
-      } else if (info.targets.any((element) => _checkIfCurrentUser(element))) {
+      } else if (info.concreteTargets.any(_checkIfCurrentUser)) {
         _registerCallForLaterAnalysis(info);
       }
     } else if (info.selector.isGetter &&
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 02f075e..44c7969 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -635,13 +635,16 @@
           print('${info.getInferredSignature(types)} for '
               '${info.debugName}');
         } else if (info is DynamicCallSiteTypeInformation) {
-          for (MemberEntity target in info.targets) {
+          if (info.hasClosureCallTargets) {
+            print('<Closure.call>');
+          }
+          for (MemberEntity target in info.concreteTargets) {
             if (target is FunctionEntity) {
-              print(
-                  '${types.getInferredSignatureOfMethod(target)} for ${target}');
+              print('${types.getInferredSignatureOfMethod(target)} '
+                  'for ${target}');
             } else {
-              print(
-                  '${types.getInferredTypeOfMember(target).type} for ${target}');
+              print('${types.getInferredTypeOfMember(target).type} '
+                  'for ${target}');
             }
           }
         } else if (info is StaticCallSiteTypeInformation) {
@@ -1034,6 +1037,9 @@
           inLoop: inLoop);
     }
 
+    if (closedWorld.includesClosureCall(selector, mask)) {
+      sideEffectsBuilder.setAllSideEffectsAndDependsOnSomething();
+    }
     closedWorld.locateMembers(selector, mask).forEach((callee) {
       updateSideEffects(sideEffectsBuilder, selector, callee);
     });
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index 2659ae7..7043105 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -206,7 +206,8 @@
         assignments.add(inferrer.types.nullType);
       }
     } else if (selector.isCall &&
-        !info.targets.every((element) => element.isFunction)) {
+        (info.hasClosureCallTargets ||
+            info.concreteTargets.any((element) => !element.isFunction))) {
       bailout('Passed to a closure');
       return;
     }
diff --git a/pkg/compiler/lib/src/inferrer/map_tracer.dart b/pkg/compiler/lib/src/inferrer/map_tracer.dart
index c4e8dd6..83ad71c 100644
--- a/pkg/compiler/lib/src/inferrer/map_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/map_tracer.dart
@@ -122,7 +122,8 @@
         }
       }
     } else if (selector.isCall &&
-        !info.targets.every((element) => element.isFunction)) {
+        (info.hasClosureCallTargets ||
+            info.concreteTargets.any((element) => !element.isFunction))) {
       bailout('Passed to a closure');
       return;
     }
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index 5b199eb..b1ed67d 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -388,7 +388,7 @@
     }
 
     Iterable<TypeInformation> inferredTargetTypes =
-        info.targets.map((MemberEntity entity) {
+        info.concreteTargets.map((MemberEntity entity) {
       return inferrer.types.getInferredTypeOfMember(entity);
     });
     if (inferredTargetTypes.any((user) => user == currentUser)) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 19410c0..d0d98eb 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -131,11 +131,16 @@
     }
 
     TypeMask result = const TypeMask.nonNullEmpty();
-    Iterable<MemberEntity> elements =
-        inferrer.closedWorld.locateMembers(selector, mask);
-    for (MemberEntity element in elements) {
-      TypeMask type = inferrer.typeOfMemberWithSelector(element, selector).type;
-      result = result.union(type, inferrer.closedWorld);
+    if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
+      result = inferrer.commonMasks.dynamicType;
+    } else {
+      Iterable<MemberEntity> elements =
+          inferrer.closedWorld.locateMembers(selector, mask);
+      for (MemberEntity element in elements) {
+        TypeMask type =
+            inferrer.typeOfMemberWithSelector(element, selector).type;
+        result = result.union(type, inferrer.closedWorld);
+      }
     }
     return result;
   }
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 1ad7fc5..a5ea018 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -789,11 +789,34 @@
   TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
     if (inferrer.options.parameterCheckPolicy.isTrusted ||
         inferrer.trustTypeAnnotations(_method)) {
-      // When type assertions are enabled (aka checked mode), we have to always
-      // ignore type annotations to ensure that the checks are actually inserted
-      // into the function body and retained until runtime.
-      // TODO(sigmund): is this still applicable? investigate if we can use also
-      // narrow when isChecked is true.
+      // In checked or strong mode we don't trust the types of the arguments
+      // passed to a parameter. The means that the checking of a parameter is
+      // based on the actual arguments.
+      //
+      // With --trust-type-annotations or --omit-implicit-checks we _do_ trust
+      // the arguments passed to a parameter - and we never check them.
+      //
+      // In all these cases we _do_ trust the static type of a parameter within
+      // the method itself. For instance:
+      //
+      //     method(int i) => i;
+      //     main() {
+      //       dynamic f = method;
+      //       f(0); // valid call
+      //       f(''); // invalid call
+      //     }
+      //
+      // Here, in all cases, we infer the returned value of `method` to be an
+      // `int`. In checked and strong mode we infer the parameter of `method` to
+      // be either `int` or `String` and therefore insert a check at the entry
+      // of 'method'. With --trust-type-annotations or --omit-implicit-checks we
+      // (unsoundly) infer the parameter to be `int` and leave the parameter
+      // unchecked, and `method` will at runtime actually return a `String` from
+      // the second invocation.
+      //
+      // The trusting of the parameter types within the body of the method is
+      // is done through `LocalsHandler.update` called in
+      // `KernelTypeGraphBuilder.handleParameter`.
       assert(!inferrer.options.enableTypeAssertions);
       return _narrowType(inferrer.closedWorld, mask, _type);
     }
@@ -978,9 +1001,10 @@
   final CallType _callType;
   final TypeInformation receiver;
   final bool isConditional;
+  bool _hasClosureCallTargets;
 
-  /// Cached targets of this call.
-  Iterable<MemberEntity> targets;
+  /// Cached concrete targets of this call.
+  Iterable<MemberEntity> _concreteTargets;
 
   DynamicCallSiteTypeInformation(
       MemberTypeInformation context,
@@ -1000,12 +1024,14 @@
   void addToGraph(InferrerEngine inferrer) {
     assert(receiver != null);
     TypeMask typeMask = computeTypedSelector(inferrer);
-    targets = inferrer.closedWorld.locateMembers(selector, typeMask);
+    _hasClosureCallTargets =
+        inferrer.closedWorld.includesClosureCall(selector, typeMask);
+    _concreteTargets = inferrer.closedWorld.locateMembers(selector, typeMask);
     receiver.addUser(this);
     if (arguments != null) {
       arguments.forEach((info) => info.addUser(this));
     }
-    for (MemberEntity element in targets) {
+    for (MemberEntity element in _concreteTargets) {
       MemberTypeInformation callee =
           inferrer.types.getInferredTypeOfMember(element);
       callee.addCall(caller, _call);
@@ -1016,7 +1042,15 @@
     }
   }
 
-  Iterable<MemberEntity> get callees => targets;
+  /// `true` if this invocation can hit a 'call' method on a closure.
+  bool get hasClosureCallTargets => _hasClosureCallTargets;
+
+  /// All concrete targets of this invocation. If [hasClosureCallTargets] is
+  /// `true` the invocation can additional target an unknown set of 'call'
+  /// methods on closures.
+  Iterable<MemberEntity> get concreteTargets => _concreteTargets;
+
+  Iterable<MemberEntity> get callees => _concreteTargets;
 
   TypeMask computeTypedSelector(InferrerEngine inferrer) {
     TypeMask receiverType = receiver.type;
@@ -1031,7 +1065,7 @@
   }
 
   bool targetsIncludeComplexNoSuchMethod(InferrerEngine inferrer) {
-    return targets.any((MemberEntity e) {
+    return _concreteTargets.any((MemberEntity e) {
       return e.isFunction &&
           e.isInstanceMember &&
           e.name == Identifiers.noSuchMethod_ &&
@@ -1146,7 +1180,7 @@
   }
 
   TypeMask computeType(InferrerEngine inferrer) {
-    Iterable<MemberEntity> oldTargets = targets;
+    Iterable<MemberEntity> oldTargets = _concreteTargets;
     TypeMask typeMask = computeTypedSelector(inferrer);
     inferrer.updateSelectorInMember(
         caller, _callType, _call, selector, typeMask);
@@ -1160,15 +1194,17 @@
     // the untyped selector (through noSuchMethod's `Invocation`
     // and a call to `delegate`), we iterate over all these methods to
     // update their parameter types.
-    targets = inferrer.closedWorld.locateMembers(selector, maskToUse);
+    _hasClosureCallTargets =
+        inferrer.closedWorld.includesClosureCall(selector, maskToUse);
+    _concreteTargets = inferrer.closedWorld.locateMembers(selector, maskToUse);
     Iterable<MemberEntity> typedTargets = canReachAll
         ? inferrer.closedWorld.locateMembers(selector, typeMask)
-        : targets;
+        : _concreteTargets;
 
     // Update the call graph if the targets could have changed.
-    if (!identical(targets, oldTargets)) {
+    if (!identical(_concreteTargets, oldTargets)) {
       // Add calls to new targets to the graph.
-      targets
+      _concreteTargets
           .where((target) => !oldTargets.contains(target))
           .forEach((MemberEntity element) {
         MemberTypeInformation callee =
@@ -1182,7 +1218,7 @@
 
       // Walk over the old targets, and remove calls that cannot happen anymore.
       oldTargets
-          .where((target) => !targets.contains(target))
+          .where((target) => !_concreteTargets.contains(target))
           .forEach((MemberEntity element) {
         MemberTypeInformation callee =
             inferrer.types.getInferredTypeOfMember(element);
@@ -1196,55 +1232,59 @@
 
     // Walk over the found targets, and compute the joined union type mask
     // for all these targets.
-    TypeMask result =
-        inferrer.types.joinTypeMasks(targets.map((MemberEntity element) {
-      // If [canReachAll] is true, then we are iterating over all
-      // targets that satisfy the untyped selector. We skip the return
-      // type of the targets that can only be reached through
-      // `Invocation.delegate`. Note that the `noSuchMethod` targets
-      // are included in [typedTargets].
-      if (canReachAll && !typedTargets.contains(element)) {
-        return const TypeMask.nonNullEmpty();
-      }
-      if (inferrer.returnsListElementType(selector, typeMask)) {
-        ContainerTypeMask containerTypeMask = receiver.type;
-        return containerTypeMask.elementType;
-      } else if (inferrer.returnsMapValueType(selector, typeMask)) {
-        if (typeMask.isDictionary) {
-          TypeMask arg = arguments.positional[0].type;
-          if (arg is ValueTypeMask && arg.value.isString) {
-            DictionaryTypeMask dictionaryTypeMask = typeMask;
-            StringConstantValue value = arg.value;
-            String key = value.stringValue;
-            if (dictionaryTypeMask.typeMap.containsKey(key)) {
-              if (debug.VERBOSE) {
-                print("Dictionary lookup for $key yields "
-                    "${dictionaryTypeMask.typeMap[key]}.");
+    TypeMask result;
+    if (_hasClosureCallTargets) {
+      result = inferrer.commonMasks.dynamicType;
+    } else {
+      result = inferrer.types
+          .joinTypeMasks(_concreteTargets.map((MemberEntity element) {
+        // If [canReachAll] is true, then we are iterating over all
+        // targets that satisfy the untyped selector. We skip the return
+        // type of the targets that can only be reached through
+        // `Invocation.delegate`. Note that the `noSuchMethod` targets
+        // are included in [typedTargets].
+        if (canReachAll && !typedTargets.contains(element)) {
+          return const TypeMask.nonNullEmpty();
+        }
+        if (inferrer.returnsListElementType(selector, typeMask)) {
+          ContainerTypeMask containerTypeMask = receiver.type;
+          return containerTypeMask.elementType;
+        } else if (inferrer.returnsMapValueType(selector, typeMask)) {
+          if (typeMask.isDictionary) {
+            TypeMask arg = arguments.positional[0].type;
+            if (arg is ValueTypeMask && arg.value.isString) {
+              DictionaryTypeMask dictionaryTypeMask = typeMask;
+              StringConstantValue value = arg.value;
+              String key = value.stringValue;
+              if (dictionaryTypeMask.typeMap.containsKey(key)) {
+                if (debug.VERBOSE) {
+                  print("Dictionary lookup for $key yields "
+                      "${dictionaryTypeMask.typeMap[key]}.");
+                }
+                return dictionaryTypeMask.typeMap[key];
+              } else {
+                // The typeMap is precise, so if we do not find the key, the lookup
+                // will be [null] at runtime.
+                if (debug.VERBOSE) {
+                  print("Dictionary lookup for $key yields [null].");
+                }
+                return inferrer.types.nullType.type;
               }
-              return dictionaryTypeMask.typeMap[key];
-            } else {
-              // The typeMap is precise, so if we do not find the key, the lookup
-              // will be [null] at runtime.
-              if (debug.VERBOSE) {
-                print("Dictionary lookup for $key yields [null].");
-              }
-              return inferrer.types.nullType.type;
             }
           }
+          MapTypeMask mapTypeMask = typeMask;
+          if (debug.VERBOSE) {
+            print("Map lookup for $selector yields ${mapTypeMask.valueType}.");
+          }
+          return mapTypeMask.valueType;
+        } else {
+          TypeInformation info =
+              handleIntrisifiedSelector(selector, typeMask, inferrer);
+          if (info != null) return info.type;
+          return inferrer.typeOfMemberWithSelector(element, selector).type;
         }
-        MapTypeMask mapTypeMask = typeMask;
-        if (debug.VERBOSE) {
-          print("Map lookup for $selector yields ${mapTypeMask.valueType}.");
-        }
-        return mapTypeMask.valueType;
-      } else {
-        TypeInformation info =
-            handleIntrisifiedSelector(selector, typeMask, inferrer);
-        if (info != null) return info.type;
-        return inferrer.typeOfMemberWithSelector(element, selector).type;
-      }
-    }));
-
+      }));
+    }
     if (isConditional && receiver.type.isNullable) {
       // Conditional call sites (e.g. `a?.b`) may be null if the receiver is
       // null.
@@ -1256,9 +1296,11 @@
   void giveUp(InferrerEngine inferrer, {bool clearAssignments: true}) {
     if (!abandonInferencing) {
       inferrer.updateSelectorInMember(caller, _callType, _call, selector, mask);
-      Iterable<MemberEntity> oldTargets = targets;
-      targets = inferrer.closedWorld.locateMembers(selector, mask);
-      for (MemberEntity element in targets) {
+      Iterable<MemberEntity> oldTargets = _concreteTargets;
+      _hasClosureCallTargets =
+          inferrer.closedWorld.includesClosureCall(selector, mask);
+      _concreteTargets = inferrer.closedWorld.locateMembers(selector, mask);
+      for (MemberEntity element in _concreteTargets) {
         if (!oldTargets.contains(element)) {
           MemberTypeInformation callee =
               inferrer.types.getInferredTypeOfMember(element);
@@ -1273,7 +1315,7 @@
   }
 
   void removeAndClearReferences(InferrerEngine inferrer) {
-    for (MemberEntity element in targets) {
+    for (MemberEntity element in _concreteTargets) {
       MemberTypeInformation callee =
           inferrer.types.getInferredTypeOfMember(element);
       callee.removeUser(this);
@@ -1292,9 +1334,8 @@
 
   bool hasStableType(InferrerEngine inferrer) {
     return receiver.isStable &&
-        targets.every((MemberEntity element) {
-          return inferrer.types.getInferredTypeOfMember(element).isStable;
-        }) &&
+        _concreteTargets.every((MemberEntity element) =>
+            inferrer.types.getInferredTypeOfMember(element).isStable) &&
         (arguments == null || arguments.every((info) => info.isStable)) &&
         super.hasStableType(inferrer);
   }
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart
index 494111d..8cfa41e 100644
--- a/pkg/compiler/lib/src/io/source_file.dart
+++ b/pkg/compiler/lib/src/io/source_file.dart
@@ -4,7 +4,7 @@
 
 library dart2js.io.source_file;
 
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
 import 'dart:math';
 import 'dart:typed_data' show Uint8List;
 
@@ -19,7 +19,7 @@
   /// The absolute URI of the source file.
   Uri get uri;
 
-  InputKind get inputKind => InputKind.utf8;
+  InputKind get inputKind => InputKind.UTF8;
 
   kernel.Source cachedKernelSource;
 
@@ -188,7 +188,7 @@
 
   String slowText() {
     // Don't convert the trailing zero byte.
-    return UTF8.decoder
+    return utf8.decoder
         .convert(zeroTerminatedContent, 0, zeroTerminatedContent.length - 1);
   }
 
@@ -248,7 +248,7 @@
   String slowText() => text;
 
   List<int> slowUtf8ZeroTerminatedBytes() {
-    return _zeroTerminateIfNecessary(UTF8.encode(text));
+    return _zeroTerminateIfNecessary(utf8.encode(text));
   }
 
   String slowSubstring(int start, int end) => text.substring(start, end);
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 798fd5c..4043360 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -57,7 +57,6 @@
 import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
 import 'annotations.dart' as optimizerHints;
 import 'backend_impact.dart';
-import 'backend_serialization.dart' show JavaScriptBackendSerialization;
 import 'backend_usage.dart';
 import 'checked_mode_helpers.dart';
 import 'codegen_listener.dart';
@@ -414,9 +413,6 @@
   /// The strategy used for collecting and emitting source information.
   SourceInformationStrategy sourceInformationStrategy;
 
-  /// Interface for serialization of backend specific data.
-  JavaScriptBackendSerialization serialization;
-
   NativeDataBuilderImpl _nativeDataBuilder;
   NativeDataBuilder get nativeDataBuilder => _nativeDataBuilder;
   final NativeDataResolver _nativeDataResolver;
@@ -461,7 +457,6 @@
     patchResolverTask = new PatchResolverTask(compiler);
     functionCompiler = new SsaFunctionCompiler(
         this, compiler.measurer, sourceInformationStrategy);
-    serialization = new JavaScriptBackendSerialization(this);
   }
 
   /// The [ConstantSystem] used to interpret compile-time constants for this
@@ -943,14 +938,12 @@
   /// This method is called immediately after the [library] and its parts have
   /// been loaded.
   void setAnnotations(LibraryEntity library) {
-    if (!compiler.serialization.isDeserialized(library)) {
-      AnnotationProcessor processor =
-          compiler.frontendStrategy.annotationProcesser;
-      if (canLibraryUseNative(library)) {
-        processor.extractNativeAnnotations(library);
-      }
-      processor.extractJsInteropAnnotations(library);
+    AnnotationProcessor processor =
+        compiler.frontendStrategy.annotationProcesser;
+    if (canLibraryUseNative(library)) {
+      processor.extractNativeAnnotations(library);
     }
+    processor.extractJsInteropAnnotations(library);
     Uri uri = library.canonicalUri;
     if (uri == Uris.dart_html) {
       htmlLibraryIsLoaded = true;
@@ -1229,14 +1222,11 @@
 
   /// Creates an impact strategy to use for compilation.
   ImpactStrategy createImpactStrategy(
-      {bool supportDeferredLoad: true,
-      bool supportDumpInfo: true,
-      bool supportSerialization: true}) {
+      {bool supportDeferredLoad: true, bool supportDumpInfo: true}) {
     return new JavaScriptImpactStrategy(
         impactCacheDeleter, compiler.dumpInfoTask,
         supportDeferredLoad: supportDeferredLoad,
-        supportDumpInfo: supportDumpInfo,
-        supportSerialization: supportSerialization);
+        supportDumpInfo: supportDumpInfo);
   }
 
   EnqueueTask makeEnqueuer() => new EnqueueTask(compiler);
@@ -1247,19 +1237,16 @@
   final DumpInfoTask dumpInfoTask;
   final bool supportDeferredLoad;
   final bool supportDumpInfo;
-  final bool supportSerialization;
 
   JavaScriptImpactStrategy(this.impactCacheDeleter, this.dumpInfoTask,
-      {this.supportDeferredLoad,
-      this.supportDumpInfo,
-      this.supportSerialization});
+      {this.supportDeferredLoad, this.supportDumpInfo});
 
   @override
   void visitImpact(var impactSource, WorldImpact impact,
       WorldImpactVisitor visitor, ImpactUseCase impactUse) {
     // TODO(johnniwinther): Compute the application strategy once for each use.
     if (impactUse == ResolutionEnqueuer.IMPACT_USE) {
-      if (supportDeferredLoad || supportSerialization) {
+      if (supportDeferredLoad) {
         impact.apply(visitor);
       } else {
         impact.apply(visitor);
@@ -1280,9 +1267,7 @@
 
   @override
   void onImpactUsed(ImpactUseCase impactUse) {
-    if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) {
-      // TODO(johnniwinther): Allow emptying when serialization has been
-      // performed.
+    if (impactUse == DeferredLoadTask.IMPACT_USE) {
       impactCacheDeleter.emptyCache();
     }
   }
diff --git a/pkg/compiler/lib/src/js_backend/backend_serialization.dart b/pkg/compiler/lib/src/js_backend/backend_serialization.dart
deleted file mode 100644
index 5d46196..0000000
--- a/pkg/compiler/lib/src/js_backend/backend_serialization.dart
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library js_backend.serialization;
-
-import '../common/backend_api.dart' show BackendSerialization;
-import '../elements/elements.dart';
-import '../elements/resolution_types.dart';
-import '../elements/types.dart';
-import '../js/js.dart' as js;
-import '../native/native.dart';
-import '../resolution/resolution_strategy.dart';
-import '../serialization/keys.dart';
-import '../serialization/serialization.dart'
-    show DeserializerPlugin, ObjectDecoder, ObjectEncoder, SerializerPlugin;
-import '../universe/side_effects.dart';
-import 'js_backend.dart';
-import 'native_data.dart';
-
-const String _BACKEND_DATA_TAG = 'jsBackendData';
-const Key DART_TYPES_RETURNED = const Key('dartTypesReturned');
-const Key THIS_TYPES_RETURNED = const Key('thisTypesReturned');
-const Key SPECIAL_TYPES_RETURNED = const Key('specialTypesReturned');
-const Key DART_TYPES_INSTANTIATED = const Key('dartTypesInstantiated');
-const Key THIS_TYPES_INSTANTIATED = const Key('thisTypesInstantiated');
-const Key SPECIAL_TYPES_INSTANTIATED = const Key('specialTypesInstantiated');
-const Key CODE_TEMPLATE = const Key('codeTemplate');
-const Key SIDE_EFFECTS = const Key('sideEffects');
-const Key THROW_BEHAVIOR = const Key('throwBehavior');
-const Key IS_ALLOCATION = const Key('isAllocation');
-const Key USE_GVN = const Key('useGvn');
-
-class JavaScriptBackendSerialization implements BackendSerialization {
-  final JavaScriptBackendSerializer serializer;
-  final JavaScriptBackendDeserializer deserializer;
-
-  JavaScriptBackendSerialization(JavaScriptBackend backend)
-      : serializer = new JavaScriptBackendSerializer(backend),
-        deserializer = new JavaScriptBackendDeserializer(backend);
-}
-
-const Key JS_INTEROP_LIBRARY_NAME = const Key('jsInteropLibraryName');
-const Key JS_INTEROP_CLASS_NAME = const Key('jsInteropClassName');
-const Key JS_INTEROP_MEMBER_NAME = const Key('jsInteropMemberName');
-const Key NATIVE_MEMBER_NAME = const Key('nativeMemberName');
-const Key NATIVE_CLASS_TAG_INFO = const Key('nativeClassTagInfo');
-const Key NATIVE_METHOD_BEHAVIOR = const Key('nativeMethodBehavior');
-const Key NATIVE_FIELD_LOAD_BEHAVIOR = const Key('nativeFieldLoadBehavior');
-const Key NATIVE_FIELD_STORE_BEHAVIOR = const Key('nativeFieldStoreBehavior');
-
-class JavaScriptBackendSerializer implements SerializerPlugin {
-  final JavaScriptBackend _backend;
-
-  JavaScriptBackendSerializer(this._backend);
-
-  NativeBasicDataImpl get nativeBasicData =>
-      _backend.compiler.frontendStrategy.nativeBasicData;
-  NativeDataBuilderImpl get nativeData => _backend.nativeDataBuilder;
-
-  @override
-  void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
-    ObjectEncoder encoder;
-    ObjectEncoder getEncoder() {
-      return encoder ??= createEncoder(_BACKEND_DATA_TAG);
-    }
-
-    String jsInteropLibraryName = nativeData.jsInteropLibraries[element];
-    if (jsInteropLibraryName != null) {
-      getEncoder().setString(JS_INTEROP_LIBRARY_NAME, jsInteropLibraryName);
-    }
-    String jsInteropClassName = nativeData.jsInteropClasses[element];
-    if (jsInteropClassName != null) {
-      getEncoder().setString(JS_INTEROP_CLASS_NAME, jsInteropClassName);
-    }
-    String jsInteropMemberName = nativeData.jsInteropMembers[element];
-    if (jsInteropMemberName != null) {
-      getEncoder().setString(JS_INTEROP_MEMBER_NAME, jsInteropMemberName);
-    }
-    String nativeMemberName = nativeData.nativeMemberName[element];
-    if (nativeMemberName != null) {
-      getEncoder().setString(NATIVE_MEMBER_NAME, nativeMemberName);
-    }
-    NativeClassTag nativeClassTagInfo =
-        nativeBasicData.nativeClassTagInfo[element];
-    if (nativeClassTagInfo != null) {
-      getEncoder().setString(NATIVE_CLASS_TAG_INFO, nativeClassTagInfo.text);
-    }
-    NativeBehavior nativeMethodBehavior =
-        nativeData.nativeMethodBehavior[element];
-    if (nativeMethodBehavior != null) {
-      NativeBehaviorSerialization.serializeNativeBehavior(nativeMethodBehavior,
-          getEncoder().createObject(NATIVE_METHOD_BEHAVIOR));
-    }
-    NativeBehavior nativeFieldLoadBehavior =
-        nativeData.nativeFieldLoadBehavior[element];
-    if (nativeFieldLoadBehavior != null) {
-      NativeBehaviorSerialization.serializeNativeBehavior(
-          nativeFieldLoadBehavior,
-          getEncoder().createObject(NATIVE_FIELD_LOAD_BEHAVIOR));
-    }
-    NativeBehavior nativeFieldStoreBehavior =
-        nativeData.nativeFieldStoreBehavior[element];
-    if (nativeFieldStoreBehavior != null) {
-      NativeBehaviorSerialization.serializeNativeBehavior(
-          nativeFieldStoreBehavior,
-          getEncoder().createObject(NATIVE_FIELD_STORE_BEHAVIOR));
-    }
-  }
-
-  @override
-  void onData(covariant NativeBehavior behavior, ObjectEncoder encoder) {
-    NativeBehaviorSerialization.serializeNativeBehavior(behavior, encoder);
-  }
-}
-
-class JavaScriptBackendDeserializer implements DeserializerPlugin {
-  final JavaScriptBackend _backend;
-
-  JavaScriptBackendDeserializer(this._backend);
-
-  NativeBasicDataBuilderImpl get nativeBasicData {
-    ResolutionFrontEndStrategy frontendStrategy =
-        _backend.compiler.frontendStrategy;
-    return frontendStrategy.nativeBasicDataBuilder;
-  }
-
-  NativeDataBuilderImpl get nativeData => _backend.nativeDataBuilder;
-
-  @override
-  void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
-    ObjectDecoder decoder = getDecoder(_BACKEND_DATA_TAG);
-    if (decoder != null) {
-      if (element is LibraryElement) {
-        String jsInteropLibraryName =
-            decoder.getString(JS_INTEROP_LIBRARY_NAME, isOptional: true);
-        if (jsInteropLibraryName != null) {
-          nativeData.jsInteropLibraries[element] = jsInteropLibraryName;
-        }
-      } else if (element is ClassElement) {
-        String jsInteropClassName =
-            decoder.getString(JS_INTEROP_CLASS_NAME, isOptional: true);
-        if (jsInteropClassName != null) {
-          nativeData.jsInteropClasses[element] = jsInteropClassName;
-        }
-        String nativeClassTagInfo =
-            decoder.getString(NATIVE_CLASS_TAG_INFO, isOptional: true);
-        if (nativeClassTagInfo != null) {
-          nativeBasicData.nativeClassTagInfo[element] =
-              new NativeClassTag(nativeClassTagInfo);
-        }
-      } else if (element is MemberElement) {
-        String jsInteropMemberName =
-            decoder.getString(JS_INTEROP_MEMBER_NAME, isOptional: true);
-        if (jsInteropMemberName != null) {
-          nativeData.jsInteropMembers[element] = jsInteropMemberName;
-        }
-        String nativeMemberName =
-            decoder.getString(NATIVE_MEMBER_NAME, isOptional: true);
-        if (nativeMemberName != null) {
-          nativeData.nativeMemberName[element] = nativeMemberName;
-        }
-
-        if (element is MethodElement) {
-          ObjectDecoder nativeMethodBehavior =
-              decoder.getObject(NATIVE_METHOD_BEHAVIOR, isOptional: true);
-          if (nativeMethodBehavior != null) {
-            nativeData.nativeMethodBehavior[element] =
-                NativeBehaviorSerialization
-                    .deserializeNativeBehavior(nativeMethodBehavior);
-          }
-        } else if (element is FieldElement) {
-          ObjectDecoder nativeFieldLoadBehavior =
-              decoder.getObject(NATIVE_FIELD_LOAD_BEHAVIOR, isOptional: true);
-          if (nativeFieldLoadBehavior != null) {
-            nativeData.nativeFieldLoadBehavior[element] =
-                NativeBehaviorSerialization
-                    .deserializeNativeBehavior(nativeFieldLoadBehavior);
-          }
-          ObjectDecoder nativeFieldStoreBehavior =
-              decoder.getObject(NATIVE_FIELD_STORE_BEHAVIOR, isOptional: true);
-          if (nativeFieldStoreBehavior != null) {
-            nativeData.nativeFieldStoreBehavior[element] =
-                NativeBehaviorSerialization
-                    .deserializeNativeBehavior(nativeFieldStoreBehavior);
-          }
-        }
-      }
-    }
-  }
-
-  @override
-  NativeBehavior onData(ObjectDecoder decoder) {
-    return NativeBehaviorSerialization.deserializeNativeBehavior(decoder);
-  }
-}
-
-class NativeBehaviorSerialization {
-  static const int NORMAL_TYPE = 0;
-  static const int THIS_TYPE = 1;
-  static const int SPECIAL_TYPE = 2;
-
-  static int getTypeKind(var type) {
-    if (type is DartType) {
-      // TODO(johnniwinther): Remove this when annotation are no longer resolved
-      // to this-types.
-      if (type is InterfaceType &&
-          type.typeArguments.isNotEmpty &&
-          type.typeArguments.first is TypeVariableType) {
-        return THIS_TYPE;
-      }
-      return NORMAL_TYPE;
-    }
-    return SPECIAL_TYPE;
-  }
-
-  /// Returns a list of the non-this-type [ResolutionDartType]s in [types].
-  static List<ResolutionDartType> filterDartTypes(List types) {
-    return types.where((type) => getTypeKind(type) == NORMAL_TYPE).toList();
-  }
-
-  // TODO(johnniwinther): Remove this when annotation are no longer resolved
-  // to this-types.
-  /// Returns a list of the classes of this-types in [types].
-  static List<Element> filterThisTypes(List types) {
-    return types
-        .where((type) => getTypeKind(type) == THIS_TYPE)
-        .map((type) => type.element)
-        .toList();
-  }
-
-  /// Returns a list of the names of the [SpecialType]s in [types].
-  static List<String> filterSpecialTypes(List types) {
-    return types.where((type) => getTypeKind(type) == SPECIAL_TYPE).map((t) {
-      SpecialType type = t;
-      return type.name;
-    }).toList();
-  }
-
-  static void serializeNativeBehavior(
-      NativeBehavior behavior, ObjectEncoder encoder) {
-    encoder.setTypes(
-        DART_TYPES_RETURNED, filterDartTypes(behavior.typesReturned));
-    encoder.setElements(
-        THIS_TYPES_RETURNED, filterThisTypes(behavior.typesReturned));
-    encoder.setStrings(
-        SPECIAL_TYPES_RETURNED, filterSpecialTypes(behavior.typesReturned));
-
-    encoder.setTypes(
-        DART_TYPES_INSTANTIATED, filterDartTypes(behavior.typesInstantiated));
-    encoder.setElements(
-        THIS_TYPES_INSTANTIATED, filterThisTypes(behavior.typesInstantiated));
-    encoder.setStrings(SPECIAL_TYPES_INSTANTIATED,
-        filterSpecialTypes(behavior.typesInstantiated));
-
-    if (behavior.codeTemplateText != null) {
-      encoder.setString(CODE_TEMPLATE, behavior.codeTemplateText);
-    }
-
-    encoder.setInt(SIDE_EFFECTS, behavior.sideEffects.flags);
-    encoder.setEnum(THROW_BEHAVIOR, behavior.throwBehavior);
-    encoder.setBool(IS_ALLOCATION, behavior.isAllocation);
-    encoder.setBool(USE_GVN, behavior.useGvn);
-  }
-
-  static NativeBehavior deserializeNativeBehavior(ObjectDecoder decoder) {
-    SideEffects sideEffects =
-        new SideEffects.fromFlags(decoder.getInt(SIDE_EFFECTS));
-    NativeBehavior behavior = new NativeBehavior.internal(sideEffects);
-
-    behavior.typesReturned
-        .addAll(decoder.getTypes(DART_TYPES_RETURNED, isOptional: true));
-    behavior.typesReturned.addAll(decoder
-        .getElements(THIS_TYPES_RETURNED, isOptional: true)
-        .map((dynamic element) => element.thisType)
-        .toList());
-    behavior.typesReturned.addAll(decoder
-        .getStrings(SPECIAL_TYPES_RETURNED, isOptional: true)
-        .map(SpecialType.fromName));
-
-    behavior.typesInstantiated
-        .addAll(decoder.getTypes(DART_TYPES_INSTANTIATED, isOptional: true));
-    behavior.typesInstantiated.addAll(decoder
-        .getElements(THIS_TYPES_INSTANTIATED, isOptional: true)
-        .map((dynamic element) => element.thisType)
-        .toList());
-    behavior.typesInstantiated.addAll(decoder
-        .getStrings(SPECIAL_TYPES_INSTANTIATED, isOptional: true)
-        .map(SpecialType.fromName));
-
-    behavior.codeTemplateText =
-        decoder.getString(CODE_TEMPLATE, isOptional: true);
-    if (behavior.codeTemplateText != null) {
-      behavior.codeTemplate = js.js.parseForeignJS(behavior.codeTemplateText);
-    }
-
-    behavior.throwBehavior =
-        decoder.getEnum(THROW_BEHAVIOR, NativeThrowBehavior.values);
-    behavior.isAllocation = decoder.getBool(IS_ALLOCATION);
-    behavior.useGvn = decoder.getBool(USE_GVN);
-    return behavior;
-  }
-}
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 12ef4a4..064aa93 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -146,9 +146,9 @@
     double value = constant.doubleValue;
     if (value.isNaN) {
       return js("0/0");
-    } else if (value == double.INFINITY) {
+    } else if (value == double.infinity) {
       return js("1/0");
-    } else if (value == -double.INFINITY) {
+    } else if (value == -double.infinity) {
       return js("-1/0");
     } else {
       String shortened = _shortenExponentialRepresentation("$value");
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index cbeefd6..a2bd855 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -203,7 +203,7 @@
     if (constant.isInt) {
       IntConstantValue intConstant = constant;
       int value = intConstant.intValue;
-      if (value >= -double.MAX_FINITE && value <= double.MAX_FINITE) {
+      if (value >= -double.maxFinite && value <= double.maxFinite) {
         return tryToRound(value);
       }
     }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 9cfe111..813ea76 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -1667,20 +1667,16 @@
       }
     });
 
-    codegenWorldBuilder.instantiatedTypes.forEach((t) {
-      liveTypeVisitor.visitType(t, false);
+    codegenWorldBuilder.instantiatedTypes.forEach((InterfaceType type) {
+      liveTypeVisitor.visitType(type, false);
       ClassUse classUse =
-          classUseMap.putIfAbsent(t.element, () => new ClassUse());
+          classUseMap.putIfAbsent(type.element, () => new ClassUse());
       classUse.instance = true;
-    });
-
-    for (InterfaceType instantiatedType
-        in codegenWorldBuilder.instantiatedTypes) {
-      FunctionType callType = _types.getCallType(instantiatedType);
+      FunctionType callType = _types.getCallType(type);
       if (callType != null) {
         testedTypeVisitor.visitType(callType, false);
       }
-    }
+    });
 
     for (FunctionEntity element
         in codegenWorldBuilder.staticFunctionsNeedingGetter) {
@@ -2409,6 +2405,9 @@
 }
 
 class TypeVisitor extends ResolutionDartTypeVisitor<void, bool> {
+  Set<FunctionTypeVariable> _visitedFunctionTypeVariables =
+      new Set<FunctionTypeVariable>();
+
   final void Function(ClassEntity entity, {bool inTypeArgument}) onClass;
   final void Function(TypeVariableEntity entity, {bool inTypeArgument})
       onTypeVariable;
@@ -2451,6 +2450,7 @@
     visitTypes(type.parameterTypes, true);
     visitTypes(type.optionalParameterTypes, true);
     visitTypes(type.namedParameterTypes, true);
+    _visitedFunctionTypeVariables.removeAll(type.typeVariables);
   }
 
   @override
@@ -2460,7 +2460,9 @@
 
   @override
   visitFunctionTypeVariable(FunctionTypeVariable type, bool inTypeArgument) {
-    visitType(type.bound, inTypeArgument);
+    if (_visitedFunctionTypeVariables.add(type)) {
+      visitType(type.bound, inTypeArgument);
+    }
   }
 }
 
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 2561648..ad8f33b 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
@@ -5,7 +5,7 @@
 library dart2js.js_emitter.program_builder;
 
 import 'dart:io';
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode;
 
 import '../../closure.dart' show ClosureConversionTask, ClosureFieldElement;
 import '../../common.dart';
@@ -315,7 +315,7 @@
       }
 
       String data = new File(allocatedClassesPath).readAsStringSync();
-      Set<String> allocatedClassesKeys = JSON.decode(data).keys.toSet();
+      Set<String> allocatedClassesKeys = jsonDecode(data).keys.toSet();
       Set<ClassEntity> allocatedClasses = new Set<ClassEntity>();
 
       // Collects all super and mixin classes of a class.
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 15e1ad0..ecf8d0a 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -1817,7 +1817,7 @@
   DartTypes get types => _elementMap.types;
 
   @override
-  InterfaceType substByContext(DartType base, InterfaceType target) {
+  DartType substByContext(DartType base, InterfaceType target) {
     return _elementMap._substByContext(base, target);
   }
 
diff --git a/pkg/compiler/lib/src/kernel/front_end_adapter.dart b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
index 9a4097f..2b00b61 100644
--- a/pkg/compiler/lib/src/kernel/front_end_adapter.dart
+++ b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
@@ -37,7 +37,7 @@
     api.Input input;
     try {
       input = await fs.inputProvider
-          .readFromUri(uri, inputKind: api.InputKind.utf8);
+          .readFromUri(uri, inputKind: api.InputKind.UTF8);
     } catch (e) {
       throw new fe.FileSystemException(uri, '$e');
     }
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index ef19c0b..1872ee8 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -36,7 +36,6 @@
 import '../options.dart';
 import '../patch_parser.dart';
 import '../resolved_uri_translator.dart';
-import '../serialization/task.dart';
 import '../universe/class_hierarchy_builder.dart';
 import '../universe/world_builder.dart';
 import '../universe/world_impact.dart';
@@ -77,7 +76,6 @@
       ScriptLoader scriptLoader,
       api.CompilerInput compilerInput,
       ElementScanner scriptScanner,
-      LibraryDeserializer deserializer,
       PatchResolverFunction patchResolverFunc,
       PatchParserTask patchParser,
       env.Environment environment,
diff --git a/pkg/compiler/lib/src/kernel/types.dart b/pkg/compiler/lib/src/kernel/types.dart
index b4be3ff..3f6a1a6 100644
--- a/pkg/compiler/lib/src/kernel/types.dart
+++ b/pkg/compiler/lib/src/kernel/types.dart
@@ -95,9 +95,8 @@
   final KernelToElementMapBase elementMap;
 
   _KernelOrderedTypeSetBuilder(this.elementMap, ClassEntity cls)
-      : super(cls,
-            reporter: elementMap.reporter,
-            objectType: elementMap.commonElements.objectType);
+      : super(cls, elementMap.commonElements.objectType,
+            reporter: elementMap.reporter);
 
   // TODO(sigmund): delete once Issue #31118 is fixed.
   @override
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 33ca393..b96adbd 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -45,7 +45,6 @@
 import 'patch_parser.dart' show PatchParserTask;
 import 'resolved_uri_translator.dart';
 import 'script.dart';
-import 'serialization/serialization.dart' show LibraryDeserializer;
 import 'tree/tree.dart';
 import 'util/util.dart' show Link, LinkBuilder;
 
@@ -217,9 +216,7 @@
   }
 }
 
-/// Interface for an entity that provide libraries. For instance from normal
-/// library loading or from deserialization.
-// TODO(johnniwinther): Use this to integrate deserialized libraries better.
+/// Interface for an entity that provide libraries.
 abstract class LibraryProvider {
   /// Looks up the library with the [canonicalUri].
   LibraryEntity lookupLibrary(Uri canonicalUri);
@@ -335,10 +332,6 @@
   /// about imports and exports. Used when loading libraries from source.
   final ElementScanner scanner;
 
-  /// Provides a diet element model for a library. Used when loading libraries
-  /// from a serialized form.
-  final LibraryDeserializer deserializer;
-
   /// Definitions provided via the `-D` command line flags. Used to resolve
   /// conditional imports.
   final Environment environment;
@@ -360,7 +353,6 @@
       this.uriTranslator,
       this.scriptLoader,
       this.scanner,
-      this.deserializer,
       this._patchResolverFunc,
       this._patchParserTask,
       this.environment,
@@ -671,29 +663,6 @@
     });
   }
 
-  /// Loads the deserialized [library] with the [handler].
-  ///
-  /// All libraries imported or exported transitively from [library] will be
-  /// loaded as well.
-  Future<LibraryElement> loadDeserializedLibrary(
-      LibraryDependencyHandler handler, LibraryElement library) {
-    libraryCanonicalUriMap[library.canonicalUri] = library;
-    handler.registerNewLibrary(library);
-    return Future.forEach(library.imports, (ImportElement import) {
-      Uri resolvedUri = library.canonicalUri.resolveUri(import.uri);
-      return createLibrary(handler, library, resolvedUri, library);
-    }).then((_) {
-      return Future.forEach(library.exports, (ExportElement export) {
-        Uri resolvedUri = library.canonicalUri.resolveUri(export.uri);
-        return createLibrary(handler, library, resolvedUri, library);
-      }).then((_) {
-        // TODO(johnniwinther): Shouldn't there be an [ImportElement] for the
-        // implicit import of dart:core?
-        return createLibrary(handler, library, Uris.dart_core, library);
-      }).then((_) => library);
-    });
-  }
-
   Future<Script> _readScript(
       Spannable spannable, Uri readableUri, Uri resolvedUri) {
     if (readableUri == null) {
@@ -718,10 +687,6 @@
     if (library != null) {
       return new Future.value(library);
     }
-    library = await deserializer.readLibrary(resolvedUri);
-    if (library != null) {
-      return loadDeserializedLibrary(handler, library);
-    }
     return reporter.withCurrentElement(importingLibrary, () {
       return _readScript(spannable, readableUri, resolvedUri)
           .then((Script script) async {
@@ -770,9 +735,7 @@
     if (element.isPlatformLibrary &&
         // Don't patch library currently disallowed.
         !element.isSynthesized &&
-        !element.isPatched &&
-        // Don't patch deserialized libraries.
-        !deserializer.isDeserialized(element)) {
+        !element.isPatched) {
       // Apply patch, if any.
       Uri patchUri = _patchResolverFunc(element.canonicalUri.path);
       if (patchUri != null) {
@@ -1690,44 +1653,6 @@
   String toString() => 'root=$rootLibrary,libraries=${_newLibraries}';
 }
 
-// TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems
-// rather low-level. It might be more practical to split the library-loading
-// task itself.  The task would continue to do the work of recursively loading
-// dependencies, but it can delegate to a set of subloaders how to do the actual
-// loading. We would then have a list of subloaders that use different
-// implementations: in-memory cache, deserialization, scanning from files.
-//
-// For example, the API might look like this:
-//
-// /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's
-// /// URI.
-// abstract class SubLoader {
-//   /// Return the library corresponding to the script at [uri].
-//   ///
-//   /// Use [spannable] for error reporting.
-//   Future<LibraryElement> createLibrary(Uri uri, [Spannable spannable]);
-//
-//   /// Return the compilation unit at [uri] that is a part of [library].
-//   Future<CompilationUnitElement> createUnit(Uri uri, LibraryElement library,
-//       [Spannable spannable]);
-// }
-//
-// /// A [SubLoader] that parses a serialized form of the element model to
-// /// produce the results.
-// class DeserializingUnitElementCreator implements SubLoader {
-// ...
-// }
-//
-// /// A [SubLoader] that finds the script sources and does a diet parse
-// /// on them to produces the results.
-// class ScanningUnitElementCreator implements SubLoader {
-// ...
-// }
-//
-// Each subloader would internally create what they need (a scanner, a
-// deserializer), and we wouldn't need to create abstractions to pass in
-// something that is only used by the loader.
-
 /// API used by the library loader to request scripts from the compiler system.
 abstract class ScriptLoader {
   /// Load script from a readable [uri], report any errors using the location of
diff --git a/pkg/compiler/lib/src/native/resolver.dart b/pkg/compiler/lib/src/native/resolver.dart
index 5ecdf95..9f7ff83 100644
--- a/pkg/compiler/lib/src/native/resolver.dart
+++ b/pkg/compiler/lib/src/native/resolver.dart
@@ -280,22 +280,6 @@
   }
 
   @override
-  bool _processMethodAnnotations(MethodElement method) {
-    if (_compiler.serialization.isDeserialized(method)) {
-      return false;
-    }
-    return super._processMethodAnnotations(method);
-  }
-
-  @override
-  bool _processFieldAnnotations(FieldElement element) {
-    if (_compiler.serialization.isDeserialized(element)) {
-      return false;
-    }
-    return super._processFieldAnnotations(element);
-  }
-
-  @override
   NativeBehavior resolveJsCall(Send node, ForeignResolver resolver) {
     return NativeBehavior.ofJsCallSend(
         node, _reporter, _compiler.parsingContext, commonElements, resolver);
diff --git a/pkg/compiler/lib/src/old_to_new_api.dart b/pkg/compiler/lib/src/old_to_new_api.dart
index 78f85d1..0363419 100644
--- a/pkg/compiler/lib/src/old_to_new_api.dart
+++ b/pkg/compiler/lib/src/old_to_new_api.dart
@@ -22,10 +22,10 @@
   LegacyCompilerInput(this._inputProvider);
 
   @override
-  Future<Input> readFromUri(Uri uri, {InputKind inputKind: InputKind.utf8}) {
+  Future<Input> readFromUri(Uri uri, {InputKind inputKind: InputKind.UTF8}) {
     return _inputProvider(uri).then((/*String|List<int>*/ data) {
       switch (inputKind) {
-        case InputKind.utf8:
+        case InputKind.UTF8:
           SourceFile sourceFile;
           if (data is List<int>) {
             sourceFile = new Utf8BytesSourceFile(uri, data);
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 607e8e6..f72edf3 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -187,18 +187,6 @@
   /// Location of the kernel platform `.dill` files.
   Uri platformBinaries;
 
-  /// The locations of serialized data used for resolution.
-  List<Uri> resolutionInputs;
-
-  /// The location of the serialized data from resolution.
-  Uri resolutionOutput;
-
-  /// If `true`, sources are resolved and serialized.
-  bool resolveOnly = false;
-
-  /// If `true`, sources are only available from serialized data.
-  bool compileOnly = false;
-
   /// URI where the compiler should generate the output source map file.
   Uri sourceMapUri;
 
@@ -339,7 +327,6 @@
       ..librariesSpecificationUri = _resolveLibrariesSpecification(libraryRoot)
       ..platformBinaries =
           platformBinaries ?? _extractUriOption(options, '--platform-binaries=')
-      ..resolveOnly = _hasOption(options, Flags.resolveOnly)
       ..sourceMapUri = _extractUriOption(options, '--source-map=')
       ..strongMode = _hasOption(options, Flags.strongMode)
       ..omitImplicitChecks = _hasOption(options, Flags.omitImplicitChecks)
@@ -383,8 +370,7 @@
   }
 
   void deriveOptions() {
-    if (resolveOnly) analyzeAll = true;
-    if (analyzeSignaturesOnly || analyzeAll || resolveOnly) analyzeOnly = true;
+    if (analyzeSignaturesOnly || analyzeAll) analyzeOnly = true;
     if (useKernel) generateCodeWithCompileTimeErrors = false;
     if (platformConfigUri == null) {
       platformConfigUri = _resolvePlatformConfig(libraryRoot, null, const []);
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index a134269..860d67f 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -164,12 +164,9 @@
 
   final DiagnosticReporter reporter;
   final ClassEntity cls;
-  InterfaceType _objectType;
+  final InterfaceType _objectType;
 
-  // TODO(johnniwinther): Provide access to `Object` in deserialization and
-  // make [objectType] mandatory.
-  OrderedTypeSetBuilderBase(this.cls, {this.reporter, InterfaceType objectType})
-      : this._objectType = objectType;
+  OrderedTypeSetBuilderBase(this.cls, this._objectType, {this.reporter});
 
   InterfaceType getThisType(covariant ClassEntity cls);
   InterfaceType substByContext(
@@ -311,9 +308,9 @@
 }
 
 class ResolutionOrderedTypeSetBuilder extends OrderedTypeSetBuilderBase {
-  ResolutionOrderedTypeSetBuilder(ClassElement cls,
-      {DiagnosticReporter reporter, InterfaceType objectType})
-      : super(cls, reporter: reporter, objectType: objectType);
+  ResolutionOrderedTypeSetBuilder(ClassElement cls, InterfaceType objectType,
+      {DiagnosticReporter reporter})
+      : super(cls, objectType, reporter: reporter);
 
   InterfaceType getThisType(ClassElement cls) => cls.thisType;
 
@@ -326,18 +323,4 @@
 
   OrderedTypeSet getOrderedTypeSet(ClassElement cls) =>
       cls.allSupertypesAndSelf;
-
-  OrderedTypeSet createOrderedTypeSet(
-      InterfaceType supertype, Link<DartType> interfaces) {
-    if (_objectType == null) {
-      // Find `Object` through in hierarchy. This is used for serialization
-      // where it is assumed that the hierarchy is valid.
-      ResolutionInterfaceType objectType = supertype;
-      while (!objectType.isObject) {
-        objectType = objectType.element.supertype;
-      }
-      _objectType = objectType;
-    }
-    return super.createOrderedTypeSet(supertype, interfaces);
-  }
 }
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 3f77774..71ea505 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -569,21 +569,6 @@
   }
 
   @override
-  void handleModifier(Token token) {
-    pushNode(new Identifier(token));
-  }
-
-  @override
-  void handleModifiers(int count) {
-    if (count == 0) {
-      pushNode(Modifiers.EMPTY);
-    } else {
-      NodeList modifierNodes = makeNodeList(count, null, null, ' ');
-      pushNode(new Modifiers(modifierNodes));
-    }
-  }
-
-  @override
   Token handleUnrecoverableError(Token token, Message message) {
     Token next = handleError(token, message);
     if (next == null &&
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
index bb0925d..4ac6f34 100644
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ b/pkg/compiler/lib/src/parser/node_listener.dart
@@ -273,6 +273,24 @@
   }
 
   @override
+  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+      Token varFinalOrConst) {
+    if (covariantToken == null && varFinalOrConst == null) {
+      pushNode(Modifiers.EMPTY);
+    } else {
+      Link<Node> poppedNodes = const Link<Node>();
+      if (covariantToken != null) {
+        poppedNodes = poppedNodes.prepend(new Identifier(covariantToken));
+      }
+      if (varFinalOrConst != null) {
+        poppedNodes = poppedNodes.prepend(new Identifier(varFinalOrConst));
+      }
+      NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
+      pushNode(new Modifiers(modifierNodes));
+    }
+  }
+
+  @override
   void endFormalParameter(Token thisKeyword, Token periodAfterThis,
       Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
     Expression name = popNode();
@@ -1080,7 +1098,12 @@
       pushNode(factoryNode);
       ++modifierCount;
     }
-    handleModifiers(modifierCount);
+    if (modifierCount == 0) {
+      pushNode(Modifiers.EMPTY);
+    } else {
+      NodeList modifierNodes = makeNodeList(modifierCount, null, null, ' ');
+      pushNode(new Modifiers(modifierNodes));
+    }
     modifiers = popNode();
 
     pushNode(new FunctionExpression(
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index 9ba287b..30e5f0d 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -546,8 +546,9 @@
     if (cls.allSupertypesAndSelf != null) return;
     final ResolutionInterfaceType supertype = cls.supertype;
     if (supertype != null) {
-      cls.allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(cls,
-              reporter: reporter, objectType: commonElements.objectType)
+      cls.allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(
+              cls, commonElements.objectType,
+              reporter: reporter)
           .createOrderedTypeSet(supertype, cls.interfaces);
     } else {
       assert(cls == resolution.commonElements.objectClass);
diff --git a/pkg/compiler/lib/src/resolution/deferred_load.dart b/pkg/compiler/lib/src/resolution/deferred_load.dart
index 1ed033a..e826a25 100644
--- a/pkg/compiler/lib/src/resolution/deferred_load.dart
+++ b/pkg/compiler/lib/src/resolution/deferred_load.dart
@@ -161,12 +161,6 @@
     treeElements
         .forEachConstantNode((ast.Node node, ConstantExpression expression) {
       if (metadataNodes.contains(node)) return;
-      if (compiler.serialization.isDeserialized(element)) {
-        if (!expression.isPotential) {
-          // Enforce evaluation of [expression].
-          backend.constants.getConstantValue(expression);
-        }
-      }
 
       // Explicitly depend on the backend constants.
       if (backend.constants.hasConstantValue(expression)) {
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
index 7691c5a..c4bfb96 100644
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
@@ -39,7 +39,6 @@
 import '../native/resolver.dart';
 import '../patch_parser.dart';
 import '../resolved_uri_translator.dart';
-import '../serialization/task.dart';
 import '../tree/tree.dart' show Node;
 import '../universe/call_structure.dart';
 import '../universe/class_hierarchy_builder.dart';
@@ -81,7 +80,6 @@
       ScriptLoader scriptLoader,
       api.CompilerInput compilerInput,
       ElementScanner scriptScanner,
-      LibraryDeserializer deserializer,
       PatchResolverFunction patchResolverFunc,
       PatchParserTask patchParser,
       Environment environment,
@@ -91,7 +89,6 @@
         uriTranslator,
         scriptLoader,
         scriptScanner,
-        deserializer,
         patchResolverFunc,
         patchParser,
         environment,
diff --git a/pkg/compiler/lib/src/serialization/constant_serialization.dart b/pkg/compiler/lib/src/serialization/constant_serialization.dart
deleted file mode 100644
index 46fade8..0000000
--- a/pkg/compiler/lib/src/serialization/constant_serialization.dart
+++ /dev/null
@@ -1,459 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.constants;
-
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../elements/elements.dart'
-    show
-        ConstructorElement,
-        FieldElement,
-        LocalVariableElement,
-        MethodElement,
-        ImportElement;
-import '../elements/entities.dart' show FieldEntity;
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import 'keys.dart';
-import 'serialization.dart';
-
-/// Visitor that serializes a [ConstantExpression] by encoding it into an
-/// [ObjectEncoder].
-///
-/// This class is called from the [Serializer] when a [ConstantExpression] needs
-/// serialization. The [ObjectEncoder] ensures that any [Element],
-/// [ResolutionDartType], and other [ConstantExpression] that the serialized
-/// [ConstantExpression] depends upon are also serialized.
-class ConstantSerializer
-    extends ConstantExpressionVisitor<dynamic, ObjectEncoder> {
-  const ConstantSerializer();
-
-  @override
-  void visitBinary(BinaryConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setEnum(Key.OPERATOR, exp.operator.kind);
-    encoder.setConstant(Key.LEFT, exp.left);
-    encoder.setConstant(Key.RIGHT, exp.right);
-  }
-
-  @override
-  void visitConcatenate(
-      ConcatenateConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setConstants(Key.ARGUMENTS, exp.expressions);
-  }
-
-  @override
-  void visitConditional(
-      ConditionalConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setConstant(Key.CONDITION, exp.condition);
-    encoder.setConstant(Key.TRUE, exp.trueExp);
-    encoder.setConstant(Key.FALSE, exp.falseExp);
-  }
-
-  @override
-  void visitConstructed(
-      ConstructedConstantExpression exp, ObjectEncoder encoder) {
-    ConstructorElement constructor = exp.target;
-    ResolutionInterfaceType type = exp.type;
-    encoder.setElement(Key.ELEMENT, constructor);
-    encoder.setType(Key.TYPE, type);
-    encoder.setStrings(Key.NAMES, exp.callStructure.namedArguments);
-    encoder.setConstants(Key.ARGUMENTS, exp.arguments);
-  }
-
-  @override
-  void visitFunction(FunctionConstantExpression exp, ObjectEncoder encoder) {
-    MethodElement function = exp.element;
-    encoder.setElement(Key.ELEMENT, function);
-  }
-
-  @override
-  void visitIdentical(IdenticalConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setConstant(Key.LEFT, exp.left);
-    encoder.setConstant(Key.RIGHT, exp.right);
-  }
-
-  @override
-  void visitList(ListConstantExpression exp, ObjectEncoder encoder) {
-    ResolutionInterfaceType type = exp.type;
-    encoder.setType(Key.TYPE, type);
-    encoder.setConstants(Key.VALUES, exp.values);
-  }
-
-  @override
-  void visitMap(MapConstantExpression exp, ObjectEncoder encoder) {
-    ResolutionInterfaceType type = exp.type;
-    encoder.setType(Key.TYPE, type);
-    encoder.setConstants(Key.KEYS, exp.keys);
-    encoder.setConstants(Key.VALUES, exp.values);
-  }
-
-  @override
-  void visitBool(BoolConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setBool(Key.VALUE, exp.boolValue);
-  }
-
-  @override
-  void visitInt(IntConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setInt(Key.VALUE, exp.intValue);
-  }
-
-  @override
-  void visitDouble(DoubleConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setDouble(Key.VALUE, exp.doubleValue);
-  }
-
-  @override
-  void visitString(StringConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setString(Key.VALUE, exp.stringValue);
-  }
-
-  @override
-  void visitNull(NullConstantExpression exp, ObjectEncoder encoder) {
-    // No additional data needed.
-  }
-
-  @override
-  void visitSymbol(SymbolConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setString(Key.NAME, exp.name);
-  }
-
-  @override
-  void visitType(TypeConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setType(Key.TYPE, exp.type);
-    encoder.setString(Key.NAME, exp.name);
-  }
-
-  @override
-  void visitUnary(UnaryConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setEnum(Key.OPERATOR, exp.operator.kind);
-    encoder.setConstant(Key.EXPRESSION, exp.expression);
-  }
-
-  @override
-  void visitField(FieldConstantExpression exp, ObjectEncoder encoder) {
-    FieldElement field = exp.element;
-    encoder.setElement(Key.ELEMENT, field);
-  }
-
-  @override
-  void visitLocalVariable(
-      LocalVariableConstantExpression exp, ObjectEncoder encoder) {
-    LocalVariableElement local = exp.element;
-    encoder.setElement(Key.ELEMENT, local);
-  }
-
-  @override
-  void visitPositional(PositionalArgumentReference exp, ObjectEncoder encoder) {
-    encoder.setInt(Key.INDEX, exp.index);
-  }
-
-  @override
-  void visitNamed(NamedArgumentReference exp, ObjectEncoder encoder) {
-    encoder.setString(Key.NAME, exp.name);
-  }
-
-  @override
-  void visitBoolFromEnvironment(
-      BoolFromEnvironmentConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setConstant(Key.NAME, exp.name);
-    if (exp.defaultValue != null) {
-      encoder.setConstant(Key.DEFAULT, exp.defaultValue);
-    }
-  }
-
-  @override
-  void visitIntFromEnvironment(
-      IntFromEnvironmentConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setConstant(Key.NAME, exp.name);
-    if (exp.defaultValue != null) {
-      encoder.setConstant(Key.DEFAULT, exp.defaultValue);
-    }
-  }
-
-  @override
-  void visitStringFromEnvironment(
-      StringFromEnvironmentConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setConstant(Key.NAME, exp.name);
-    if (exp.defaultValue != null) {
-      encoder.setConstant(Key.DEFAULT, exp.defaultValue);
-    }
-  }
-
-  @override
-  void visitStringLength(
-      StringLengthConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setConstant(Key.EXPRESSION, exp.expression);
-  }
-
-  @override
-  void visitDeferred(DeferredConstantExpression exp, ObjectEncoder encoder) {
-    encoder.setElement(Key.IMPORT, exp.import as ImportElement);
-    encoder.setConstant(Key.EXPRESSION, exp.expression);
-  }
-
-  @override
-  void visitAssert(AssertConstantExpression exp, ObjectEncoder context) {
-    throw new UnsupportedError("AssertConstantExpression is not supported.");
-  }
-
-  @override
-  void visitAs(AsConstantExpression exp, ObjectEncoder encoder) {
-    throw new UnsupportedError("AsConstantExpression is not supported.");
-  }
-}
-
-/// Utility class for deserializing [ConstantExpression]s.
-///
-/// This is used by the [Deserializer].
-class ConstantDeserializer {
-  /// Deserializes a [ConstantExpression] from an [ObjectDecoder].
-  ///
-  /// The class is called from the [Deserializer] when a [ConstantExpression]
-  /// needs deserialization. The [ObjectDecoder] ensures that any [Element],
-  /// [ResolutionDartType], and other [ConstantExpression] that the deserialized
-  /// [ConstantExpression] depends upon are available.
-  static ConstantExpression deserialize(ObjectDecoder decoder) {
-    ConstantExpressionKind kind =
-        decoder.getEnum(Key.KIND, ConstantExpressionKind.values);
-    switch (kind) {
-      case ConstantExpressionKind.BINARY:
-        BinaryOperator operator = BinaryOperator
-            .fromKind(decoder.getEnum(Key.OPERATOR, BinaryOperatorKind.values));
-        return new BinaryConstantExpression(decoder.getConstant(Key.LEFT),
-            operator, decoder.getConstant(Key.RIGHT));
-      case ConstantExpressionKind.BOOL:
-        return new BoolConstantExpression(decoder.getBool(Key.VALUE));
-      case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
-        return new BoolFromEnvironmentConstantExpression(
-            decoder.getConstant(Key.NAME),
-            decoder.getConstant(Key.DEFAULT, isOptional: true));
-      case ConstantExpressionKind.CONCATENATE:
-        return new ConcatenateConstantExpression(
-            decoder.getConstants(Key.ARGUMENTS));
-      case ConstantExpressionKind.CONDITIONAL:
-        return new ConditionalConstantExpression(
-            decoder.getConstant(Key.CONDITION),
-            decoder.getConstant(Key.TRUE),
-            decoder.getConstant(Key.FALSE));
-      case ConstantExpressionKind.CONSTRUCTED:
-        ResolutionInterfaceType type = decoder.getType(Key.TYPE);
-        ConstructorElement constructor = decoder.getElement(Key.ELEMENT);
-        List<String> names = decoder.getStrings(Key.NAMES, isOptional: true);
-        List<ConstantExpression> arguments =
-            decoder.getConstants(Key.ARGUMENTS, isOptional: true);
-        return new ConstructedConstantExpression(type, constructor,
-            new CallStructure(arguments.length, names), arguments);
-      case ConstantExpressionKind.DOUBLE:
-        return new DoubleConstantExpression(decoder.getDouble(Key.VALUE));
-      case ConstantExpressionKind.ERRONEOUS:
-        break;
-      case ConstantExpressionKind.FUNCTION:
-        MethodElement function = decoder.getElement(Key.ELEMENT);
-        return new FunctionConstantExpression(function, function.type);
-      case ConstantExpressionKind.IDENTICAL:
-        return new IdenticalConstantExpression(
-            decoder.getConstant(Key.LEFT), decoder.getConstant(Key.RIGHT));
-      case ConstantExpressionKind.INT:
-        return new IntConstantExpression(decoder.getInt(Key.VALUE));
-      case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
-        return new IntFromEnvironmentConstantExpression(
-            decoder.getConstant(Key.NAME),
-            decoder.getConstant(Key.DEFAULT, isOptional: true));
-      case ConstantExpressionKind.LIST:
-        ResolutionInterfaceType type = decoder.getType(Key.TYPE);
-        return new ListConstantExpression(
-            type, decoder.getConstants(Key.VALUES, isOptional: true));
-      case ConstantExpressionKind.MAP:
-        ResolutionInterfaceType type = decoder.getType(Key.TYPE);
-        return new MapConstantExpression(
-            type,
-            decoder.getConstants(Key.KEYS, isOptional: true),
-            decoder.getConstants(Key.VALUES, isOptional: true));
-      case ConstantExpressionKind.NULL:
-        return new NullConstantExpression();
-      case ConstantExpressionKind.STRING:
-        return new StringConstantExpression(decoder.getString(Key.VALUE));
-      case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
-        return new StringFromEnvironmentConstantExpression(
-            decoder.getConstant(Key.NAME),
-            decoder.getConstant(Key.DEFAULT, isOptional: true));
-      case ConstantExpressionKind.STRING_LENGTH:
-        return new StringLengthConstantExpression(
-            decoder.getConstant(Key.EXPRESSION));
-      case ConstantExpressionKind.SYMBOL:
-        return new SymbolConstantExpression(decoder.getString(Key.NAME));
-      case ConstantExpressionKind.TYPE:
-        return new TypeConstantExpression(
-            decoder.getType(Key.TYPE), decoder.getString(Key.NAME));
-      case ConstantExpressionKind.UNARY:
-        UnaryOperator operator = UnaryOperator
-            .fromKind(decoder.getEnum(Key.OPERATOR, UnaryOperatorKind.values));
-        return new UnaryConstantExpression(
-            operator, decoder.getConstant(Key.EXPRESSION));
-      case ConstantExpressionKind.FIELD:
-        FieldElement field = decoder.getElement(Key.ELEMENT);
-        return new FieldConstantExpression(field);
-      case ConstantExpressionKind.LOCAL_VARIABLE:
-        LocalVariableElement local = decoder.getElement(Key.ELEMENT);
-        return new LocalVariableConstantExpression(local);
-
-      case ConstantExpressionKind.POSITIONAL_REFERENCE:
-        return new PositionalArgumentReference(decoder.getInt(Key.INDEX));
-      case ConstantExpressionKind.NAMED_REFERENCE:
-        return new NamedArgumentReference(decoder.getString(Key.NAME));
-      case ConstantExpressionKind.DEFERRED:
-        return new DeferredConstantExpression(
-            decoder.getConstant(Key.EXPRESSION),
-            decoder.getElement(Key.IMPORT) as ImportElement);
-      case ConstantExpressionKind.SYNTHETIC:
-      case ConstantExpressionKind.ASSERT:
-      case ConstantExpressionKind.AS:
-    }
-    throw new UnsupportedError("Unexpected constant kind: ${kind} in $decoder");
-  }
-}
-
-/// Visitor that serializes a [ConstantConstructor] by encoding it into an
-/// [ObjectEncoder].
-///
-/// This class is called from the [ConstructorSerializer] when the [Serializer]
-/// is serializing constant constructor. The [ObjectEncoder] ensures that any
-/// [Element], [ResolutionDartType], and [ConstantExpression] that the
-/// serialized [ConstantConstructor] depends upon are also serialized.
-class ConstantConstructorSerializer
-    extends ConstantConstructorVisitor<dynamic, ObjectEncoder> {
-  const ConstantConstructorSerializer();
-
-  @override
-  void visit(ConstantConstructor constantConstructor, ObjectEncoder encoder) {
-    encoder.setEnum(Key.KIND, constantConstructor.kind);
-    constantConstructor.accept(this, encoder);
-  }
-
-  @override
-  void visitGenerative(
-      GenerativeConstantConstructor constructor, ObjectEncoder encoder) {
-    ResolutionInterfaceType type = constructor.type;
-    encoder.setType(Key.TYPE, type);
-    MapEncoder defaults = encoder.createMap(Key.DEFAULTS);
-    constructor.defaultValues.forEach((key, e) {
-      defaults.setConstant('$key', e);
-    });
-    ListEncoder fields = encoder.createList(Key.FIELDS);
-    constructor.fieldMap.forEach((FieldEntity _f, ConstantExpression e) {
-      FieldElement f = _f;
-      ObjectEncoder fieldSerializer = fields.createObject();
-      fieldSerializer.setElement(Key.FIELD, f);
-      fieldSerializer.setConstant(Key.CONSTANT, e);
-    });
-    if (constructor.superConstructorInvocation != null) {
-      encoder.setConstant(
-          Key.CONSTRUCTOR, constructor.superConstructorInvocation);
-    }
-  }
-
-  @override
-  void visitRedirectingFactory(
-      RedirectingFactoryConstantConstructor constructor,
-      ObjectEncoder encoder) {
-    encoder.setConstant(
-        Key.CONSTRUCTOR, constructor.targetConstructorInvocation);
-  }
-
-  @override
-  void visitRedirectingGenerative(
-      RedirectingGenerativeConstantConstructor constructor,
-      ObjectEncoder encoder) {
-    MapEncoder defaults = encoder.createMap(Key.DEFAULTS);
-    constructor.defaultValues.forEach((key, ConstantExpression e) {
-      defaults.setConstant('$key', e);
-    });
-    encoder.setConstant(Key.CONSTRUCTOR, constructor.thisConstructorInvocation);
-  }
-
-  @override
-  void visitErroneous(
-      ErroneousConstantConstructor constructor, ObjectEncoder arg) {
-    throw new UnsupportedError("ConstantConstructorSerializer.visitErroneous");
-  }
-}
-
-/// Utility class for deserializing [ConstantConstructor]s.
-///
-/// This is used by the [ConstructorElementZ].
-class ConstantConstructorDeserializer {
-  /// Deserializes a [ConstantConstructor] from an [ObjectDecoder].
-  ///
-  /// The class is called from the [Deserializer] when a constant constructor
-  /// needs deserialization. The [ObjectDecoder] ensures that any [Element],
-  /// [ResolutionDartType], and [ConstantExpression] that the deserialized
-  /// [ConstantConstructor] depends upon are available.
-  // ignore: MISSING_RETURN
-  static ConstantConstructor deserialize(ObjectDecoder decoder) {
-    ConstantConstructorKind kind =
-        decoder.getEnum(Key.KIND, ConstantConstructorKind.values);
-
-    ResolutionDartType readType() {
-      return decoder.getType(Key.TYPE);
-    }
-
-    Map<dynamic /*int|String*/, ConstantExpression> readDefaults() {
-      Map<dynamic, ConstantExpression> defaultValues =
-          <dynamic, ConstantExpression>{};
-      if (decoder.containsKey(Key.DEFAULTS)) {
-        MapDecoder defaultsMap = decoder.getMap(Key.DEFAULTS);
-        defaultsMap.forEachKey((String key) {
-          int index = int.parse(key, onError: (_) => null);
-          if (index != null) {
-            defaultValues[index] = defaultsMap.getConstant(key);
-          } else {
-            defaultValues[key] = defaultsMap.getConstant(key);
-          }
-        });
-      }
-      return defaultValues;
-    }
-
-    Map<FieldElement, ConstantExpression> readFields() {
-      Map<FieldElement, ConstantExpression> fieldMap =
-          <FieldElement, ConstantExpression>{};
-      if (decoder.containsKey(Key.FIELDS)) {
-        ListDecoder fieldsList = decoder.getList(Key.FIELDS);
-        for (int i = 0; i < fieldsList.length; i++) {
-          ObjectDecoder object = fieldsList.getObject(i);
-          FieldElement field = object.getElement(Key.FIELD);
-          ConstantExpression constant = object.getConstant(Key.CONSTANT);
-          fieldMap[field] = constant;
-        }
-      }
-      return fieldMap;
-    }
-
-    ConstructedConstantExpression readConstructorInvocation() {
-      return decoder.getConstant(Key.CONSTRUCTOR, isOptional: true);
-    }
-
-    switch (kind) {
-      case ConstantConstructorKind.GENERATIVE:
-        ResolutionInterfaceType type = readType();
-        return new GenerativeConstantConstructor(
-            type,
-            readDefaults(),
-            readFields(),
-            const <AssertConstantExpression>[],
-            readConstructorInvocation());
-      case ConstantConstructorKind.REDIRECTING_GENERATIVE:
-        return new RedirectingGenerativeConstantConstructor(
-            readDefaults(), readConstructorInvocation());
-      case ConstantConstructorKind.REDIRECTING_FACTORY:
-        return new RedirectingFactoryConstantConstructor(
-            readConstructorInvocation());
-      case ConstantConstructorKind.ERRONEOUS:
-        throw new UnsupportedError(
-            'Unsupported constant constructor kind: $kind');
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
deleted file mode 100644
index 5fa61a0..0000000
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ /dev/null
@@ -1,958 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.elements;
-
-import '../common.dart';
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../diagnostics/messages.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart'
-    show
-        AmbiguousImportX,
-        DeferredLoaderGetterElementX,
-        ErroneousElementX,
-        WarnOnUseElementX,
-        WrappedMessage;
-import 'constant_serialization.dart';
-import 'keys.dart';
-import 'modelz.dart';
-import 'serialization.dart';
-import 'serialization_util.dart';
-
-/// Enum kinds used for encoding [Element]s.
-enum SerializedElementKind {
-  ERROR,
-  LIBRARY,
-  COMPILATION_UNIT,
-  CLASS,
-  ENUM,
-  NAMED_MIXIN_APPLICATION,
-  GENERATIVE_CONSTRUCTOR,
-  DEFAULT_CONSTRUCTOR,
-  FACTORY_CONSTRUCTOR,
-  REDIRECTING_FACTORY_CONSTRUCTOR,
-  FORWARDING_CONSTRUCTOR,
-  TOPLEVEL_FIELD,
-  STATIC_FIELD,
-  INSTANCE_FIELD,
-  ENUM_CONSTANT,
-  TOPLEVEL_FUNCTION,
-  TOPLEVEL_GETTER,
-  TOPLEVEL_SETTER,
-  STATIC_FUNCTION,
-  STATIC_GETTER,
-  STATIC_SETTER,
-  INSTANCE_FUNCTION,
-  INSTANCE_GETTER,
-  INSTANCE_SETTER,
-  LOCAL_FUNCTION,
-  TYPEDEF,
-  TYPEVARIABLE,
-  PARAMETER,
-  INITIALIZING_FORMAL,
-  IMPORT,
-  EXPORT,
-  PREFIX,
-  DEFERRED_LOAD_LIBRARY,
-  LOCAL_VARIABLE,
-  WARN_ON_USE,
-  AMBIGUOUS,
-  EXTERNAL_LIBRARY,
-  EXTERNAL_LIBRARY_MEMBER,
-  EXTERNAL_CLASS_MEMBER,
-  EXTERNAL_CONSTRUCTOR,
-}
-
-/// Set of serializers used to serialize different kinds of elements by
-/// encoding into them into [ObjectEncoder]s.
-///
-/// This class is called from the [Serializer] when an [Element] needs
-/// serialization. The [ObjectEncoder] ensures that any [Element],
-/// [ResolutionDartType], and [ConstantExpression] that the serialized [Element]
-/// depends upon are also serialized.
-const List<ElementSerializer> ELEMENT_SERIALIZERS = const [
-  const ErrorSerializer(),
-  const LibrarySerializer(),
-  const CompilationUnitSerializer(),
-  const PrefixSerializer(),
-  const DeferredLoadLibrarySerializer(),
-  const ClassSerializer(),
-  const ConstructorSerializer(),
-  const FieldSerializer(),
-  const FunctionSerializer(),
-  const TypedefSerializer(),
-  const TypeVariableSerializer(),
-  const ParameterSerializer(),
-  const ImportSerializer(),
-  const ExportSerializer(),
-  const LocalVariableSerializer(),
-  const WarnOnUseSerializer(),
-  const AmbiguousSerializer(),
-];
-
-/// Interface for a function that can serialize a set of element kinds.
-abstract class ElementSerializer {
-  /// Returns the [SerializedElementKind] for [element] if this serializer
-  /// supports serialization of [element] or `null` otherwise.
-  SerializedElementKind getSerializedKind(Element element);
-
-  /// Serializes [element] into the [encoder] using the [kind] computed
-  /// by [getSerializedKind].
-  void serialize(covariant Element element, ObjectEncoder encoder,
-      SerializedElementKind kind);
-}
-
-class SerializerUtil {
-  /// Serialize the declared members of [element] into [encoder].
-  static void serializeMembers(
-      Iterable<Element> members, ObjectEncoder encoder) {
-    MapEncoder mapEncoder = encoder.createMap(Key.MEMBERS);
-    for (Element member in members) {
-      String name = member.name;
-      if (member.isSetter) {
-        name = '$name,=';
-      }
-      mapEncoder.setElement(name, member);
-    }
-  }
-
-  /// Serialize the source position of [element] into [encoder].
-  static void serializePosition(Element element, ObjectEncoder encoder) {
-    if (element.sourcePosition != null) {
-      SourceSpan position = element.sourcePosition;
-      encoder.setInt(Key.OFFSET, position.begin);
-      // TODO(johnniwinther): What is the base URI in the case?
-      if (position.uri != element.compilationUnit.script.resourceUri) {
-        encoder.setUri(Key.URI, element.library.canonicalUri, position.uri);
-      }
-      int length = position.end - position.begin;
-      if (element.name.length != length) {
-        encoder.setInt(Key.LENGTH, length);
-      }
-    }
-  }
-
-  /// Serialize the metadata of [element] into [encoder].
-  static void serializeMetadata(Element element, ObjectEncoder encoder) {
-    ListEncoder list;
-
-    void encodeAnnotation(MetadataAnnotation metadata) {
-      ObjectEncoder object = list.createObject();
-      object.setElement(Key.ELEMENT, metadata.annotatedElement);
-      SourceSpan sourcePosition = metadata.sourcePosition;
-      // TODO(johnniwinther): What is the base URI here?
-      object.setUri(Key.URI, sourcePosition.uri, sourcePosition.uri);
-      object.setInt(Key.OFFSET, sourcePosition.begin);
-      object.setInt(Key.LENGTH, sourcePosition.end - sourcePosition.begin);
-      object.setConstant(Key.CONSTANT, metadata.constant);
-    }
-
-    if (element.metadata.isNotEmpty) {
-      list = encoder.createList(Key.METADATA);
-      element.metadata.forEach(encodeAnnotation);
-    }
-    if (element.isPatched && element.implementation.metadata.isNotEmpty) {
-      list ??= encoder.createList(Key.METADATA);
-      element.implementation.metadata.forEach(encodeAnnotation);
-    }
-  }
-
-  /// Serialize the parent relation for [element] into [encoder], i.e library,
-  /// enclosing class, and compilation unit references.
-  static void serializeParentRelation(Element element, ObjectEncoder encoder) {
-    if (element.enclosingClass != null) {
-      encoder.setElement(Key.CLASS, element.enclosingClass);
-      if (element.enclosingClass.compilationUnit != element.compilationUnit) {
-        encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
-      }
-    } else {
-      encoder.setElement(Key.LIBRARY, element.library);
-      encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
-    }
-  }
-
-  /// Serialize the parameters of [element] into [encoder].
-  static void serializeParameters(
-      FunctionElement element, ObjectEncoder encoder) {
-    ResolutionFunctionType type = element.type;
-    encoder.setType(Key.RETURN_TYPE, type.returnType);
-    encoder.setElements(Key.PARAMETERS, element.parameters);
-  }
-
-  /// Returns a function that adds the underlying declared elements for a
-  /// particular element into [set].
-  ///
-  /// For instance, for an [AbstractFieldElement] the getter and setter elements
-  /// are added, if available.
-  static flattenElements(Set<Element> set) {
-    return (Element element) {
-      if (element.isPatch) return;
-      // TODO(johnniwinther): Handle ambiguous elements.
-      if (element.isAmbiguous) return;
-      if (element.isAbstractField) {
-        AbstractFieldElement abstractField = element;
-        if (abstractField.getter != null) {
-          set.add(abstractField.getter);
-        }
-        if (abstractField.setter != null) {
-          set.add(abstractField.setter);
-        }
-      } else {
-        set.add(element);
-      }
-    };
-  }
-}
-
-class ErrorSerializer implements ElementSerializer {
-  const ErrorSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isError) {
-      return SerializedElementKind.ERROR;
-    }
-    return null;
-  }
-
-  void serialize(ErroneousElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setElement(Key.ENCLOSING, element.enclosingElement);
-    encoder.setString(Key.NAME, element.name);
-    encoder.setEnum(Key.MESSAGE_KIND, element.messageKind);
-    serializeMessageArguments(encoder, Key.ARGUMENTS, element.messageArguments);
-  }
-}
-
-class LibrarySerializer implements ElementSerializer {
-  const LibrarySerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isLibrary) {
-      return SerializedElementKind.LIBRARY;
-    }
-    return null;
-  }
-
-  static List<Element> getMembers(LibraryElement element) {
-    List<Element> members = <Element>[];
-    element.implementation.forEachLocalMember((Element member) {
-      if (!member.isPatch) {
-        members.add(member);
-      }
-    });
-    return members;
-  }
-
-  static List<CompilationUnitElement> getCompilationUnits(
-      LibraryElement element) {
-    List<CompilationUnitElement> compilationUnits = <CompilationUnitElement>[];
-    compilationUnits.addAll(element.compilationUnits.toList());
-    if (element.isPatched) {
-      compilationUnits.addAll(element.implementation.compilationUnits.toList());
-    }
-    return compilationUnits;
-  }
-
-  static List<ImportElement> getImports(LibraryElement element) {
-    List<ImportElement> imports = <ImportElement>[];
-    imports.addAll(element.imports);
-    if (element.isPatched) {
-      imports.addAll(element.implementation.imports);
-    }
-    return imports;
-  }
-
-  static List<Element> getImportedElements(LibraryElement element) {
-    Set<Element> importedElements = new Set<Element>();
-    element.forEachImport(SerializerUtil.flattenElements(importedElements));
-    if (element.isPatched) {
-      element.implementation
-          .forEachImport(SerializerUtil.flattenElements(importedElements));
-    }
-    return importedElements.toList();
-  }
-
-  static List<Element> getExportedElements(LibraryElement element) {
-    Set<Element> exportedElements = new Set<Element>();
-    element.forEachExport(SerializerUtil.flattenElements(exportedElements));
-    return exportedElements.toList();
-  }
-
-  void serialize(LibraryElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    SerializerUtil.serializeMetadata(element, encoder);
-    encoder.setUri(
-        Key.CANONICAL_URI, element.canonicalUri, element.canonicalUri);
-    encoder.setString(Key.LIBRARY_NAME, element.libraryName);
-    SerializerUtil.serializeMembers(getMembers(element), encoder);
-    encoder.setElement(Key.COMPILATION_UNIT, element.entryCompilationUnit);
-    encoder.setElements(Key.COMPILATION_UNITS, getCompilationUnits(element));
-    encoder.setElements(Key.IMPORTS, getImports(element));
-    encoder.setElements(Key.EXPORTS, element.exports);
-
-    List<Element> importedElements = getImportedElements(element);
-    encoder.setElements(Key.IMPORT_SCOPE, importedElements);
-    encoder.setElements(Key.EXPORT_SCOPE, getExportedElements(element));
-
-    Map<Element, Iterable<ImportElement>> importsForMap =
-        <Element, Iterable<ImportElement>>{};
-
-    /// Map imports for [importedElement] in importsForMap.
-    ///
-    /// Imports are mapped to [AbstractFieldElement] which are not serialized
-    /// so we use getter (or setter if there is no getter) as the key.
-    void addImportsForElement(Element importedElement) {
-      Element key = importedElement;
-      if (importedElement.isDeferredLoaderGetter) {
-        // Use [importedElement].
-      } else if (importedElement.isGetter) {
-        GetterElement getter = importedElement;
-        importedElement = getter.abstractField;
-      } else if (importedElement.isSetter) {
-        SetterElement setter = importedElement;
-        if (setter.getter != null) {
-          return;
-        }
-        importedElement = setter.abstractField;
-      }
-      importsForMap.putIfAbsent(
-          key, () => element.getImportsFor(importedElement));
-    }
-
-    for (ImportElement import in getImports(element)) {
-      if (import.prefix != null) {
-        Set<Element> importedElements = new Set<Element>();
-        import.prefix.forEachLocalMember(
-            SerializerUtil.flattenElements(importedElements));
-        importedElements.forEach(addImportsForElement);
-      }
-    }
-    importedElements.forEach(addImportsForElement);
-
-    ListEncoder importsForEncoder = encoder.createList(Key.IMPORTS_FOR);
-    importsForMap
-        .forEach((Element importedElement, Iterable<ImportElement> imports) {
-      ObjectEncoder objectEncoder = importsForEncoder.createObject();
-      objectEncoder.setElement(Key.ELEMENT, importedElement);
-      objectEncoder.setElements(Key.IMPORTS, imports);
-    });
-  }
-}
-
-class CompilationUnitSerializer implements ElementSerializer {
-  const CompilationUnitSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isCompilationUnit) {
-      return SerializedElementKind.COMPILATION_UNIT;
-    }
-    return null;
-  }
-
-  void serialize(CompilationUnitElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    SerializerUtil.serializeMetadata(element, encoder);
-    encoder.setElement(Key.LIBRARY, element.library);
-    encoder.setUri(
-        Key.URI, element.library.canonicalUri, element.script.resourceUri);
-    List<Element> elements = <Element>[];
-    element.forEachLocalMember((e) {
-      if (!element.isPatch) {
-        elements.add(e);
-      }
-    });
-    encoder.setElements(Key.ELEMENTS, elements);
-  }
-}
-
-class ClassSerializer implements ElementSerializer {
-  const ClassSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isClass) {
-      ClassElement cls = element;
-      if (cls.isEnumClass) {
-        return SerializedElementKind.ENUM;
-      } else if (cls.isMixinApplication) {
-        if (!cls.isUnnamedMixinApplication) {
-          return SerializedElementKind.NAMED_MIXIN_APPLICATION;
-        }
-      } else {
-        return SerializedElementKind.CLASS;
-      }
-    }
-    return null;
-  }
-
-  static List<Element> getMembers(ClassElement element) {
-    List<Element> members = <Element>[];
-    element.forEachLocalMember(members.add);
-    if (element.isPatched) {
-      element.implementation.forEachLocalMember((Element member) {
-        if (!member.isPatch) {
-          members.add(member);
-        }
-      });
-    }
-    return members;
-  }
-
-  void serialize(
-      ClassElement element, ObjectEncoder encoder, SerializedElementKind kind) {
-    SerializerUtil.serializeMetadata(element, encoder);
-    encoder.setElement(Key.LIBRARY, element.library);
-    encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
-    encoder.setString(Key.NAME, element.name);
-    SerializerUtil.serializePosition(element, encoder);
-    encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
-    encoder.setBool(Key.IS_ABSTRACT, element.isAbstract);
-    SerializerUtil.serializeMembers(getMembers(element), encoder);
-    encoder.setBool(Key.IS_PROXY, element.isProxy);
-    encoder.setBool(Key.IS_INJECTED, element.isInjected);
-    if (kind == SerializedElementKind.ENUM) {
-      EnumClassElement enumClass = element;
-      encoder.setElements(Key.FIELDS, enumClass.enumValues);
-    }
-    if (element.isObject) return;
-
-    List<ResolutionInterfaceType> mixins = <ResolutionInterfaceType>[];
-    ClassElement superclass = element.superclass;
-    while (superclass.isUnnamedMixinApplication) {
-      MixinApplicationElement mixinElement = superclass;
-      mixins.add(element.thisType.asInstanceOf(mixinElement.mixin));
-      superclass = mixinElement.superclass;
-    }
-    mixins = mixins.reversed.toList();
-    ResolutionInterfaceType supertype =
-        element.thisType.asInstanceOf(superclass);
-
-    encoder.setType(Key.SUPERTYPE, supertype);
-    encoder.setTypes(Key.MIXINS, mixins);
-    encoder.setTypes(Key.INTERFACES, element.interfaces.toList());
-    ResolutionFunctionType callType = element.declaration.callType;
-    if (callType != null) {
-      encoder.setType(Key.CALL_TYPE, element.callType);
-    }
-
-    if (element.isMixinApplication) {
-      MixinApplicationElement mixinElement = element;
-      encoder.setType(Key.MIXIN, mixinElement.mixinType);
-    }
-  }
-}
-
-class ConstructorSerializer implements ElementSerializer {
-  const ConstructorSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isGenerativeConstructor) {
-      ConstructorElement constructor = element;
-      if (constructor.enclosingClass.isNamedMixinApplication) {
-        return SerializedElementKind.FORWARDING_CONSTRUCTOR;
-      } else if (constructor.definingConstructor != null) {
-        return SerializedElementKind.DEFAULT_CONSTRUCTOR;
-      } else {
-        return SerializedElementKind.GENERATIVE_CONSTRUCTOR;
-      }
-    } else if (element.isFactoryConstructor) {
-      ConstructorElement constructor = element;
-      if (constructor.isRedirectingFactory) {
-        return SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR;
-      } else {
-        return SerializedElementKind.FACTORY_CONSTRUCTOR;
-      }
-    }
-    return null;
-  }
-
-  void serialize(ConstructorElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    SerializerUtil.serializeParentRelation(element, encoder);
-    if (kind == SerializedElementKind.FORWARDING_CONSTRUCTOR) {
-      serializeElementReference(element.enclosingClass, Key.ELEMENT, Key.NAME,
-          encoder, element.definingConstructor);
-    } else {
-      SerializerUtil.serializeMetadata(element, encoder);
-      encoder.setType(Key.TYPE, element.type);
-      encoder.setString(Key.NAME, element.name);
-      SerializerUtil.serializePosition(element, encoder);
-      SerializerUtil.serializeParameters(element, encoder);
-      encoder.setBool(Key.IS_CONST, element.isConst);
-      encoder.setBool(Key.IS_EXTERNAL, element.isExternal);
-      encoder.setBool(Key.IS_INJECTED, element.isInjected);
-      if (element.isConst && !element.isFromEnvironmentConstructor) {
-        ConstantConstructor constantConstructor = element.constantConstructor;
-        ObjectEncoder constantEncoder = encoder.createObject(Key.CONSTRUCTOR);
-        const ConstantConstructorSerializer()
-            .visit(constantConstructor, constantEncoder);
-      }
-      if (kind == SerializedElementKind.GENERATIVE_CONSTRUCTOR) {
-        encoder.setBool(Key.IS_REDIRECTING, element.isRedirectingGenerative);
-      }
-      encoder.setElement(Key.EFFECTIVE_TARGET, element.effectiveTarget);
-      if (kind == SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR) {
-        encoder.setType(
-            Key.EFFECTIVE_TARGET_TYPE,
-            element
-                .computeEffectiveTargetType(element.enclosingClass.thisType));
-        encoder.setElement(Key.IMMEDIATE_REDIRECTION_TARGET,
-            element.immediateRedirectionTarget);
-        encoder.setBool(Key.EFFECTIVE_TARGET_IS_MALFORMED,
-            element.isEffectiveTargetMalformed);
-        if (element.redirectionDeferredPrefix != null) {
-          encoder.setElement(Key.PREFIX, element.redirectionDeferredPrefix);
-        }
-      }
-    }
-  }
-}
-
-class FieldSerializer implements ElementSerializer {
-  const FieldSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isField) {
-      if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_FIELD;
-      if (element.isStatic) {
-        if (element is EnumConstantElement) {
-          return SerializedElementKind.ENUM_CONSTANT;
-        }
-        return SerializedElementKind.STATIC_FIELD;
-      }
-      if (element.isInstanceMember) return SerializedElementKind.INSTANCE_FIELD;
-    }
-    return null;
-  }
-
-  void serialize(
-      FieldElement element, ObjectEncoder encoder, SerializedElementKind kind) {
-    encoder.setString(Key.NAME, element.name);
-    SerializerUtil.serializeMetadata(element, encoder);
-    SerializerUtil.serializePosition(element, encoder);
-    encoder.setType(Key.TYPE, element.type);
-    encoder.setBool(Key.IS_FINAL, element.isFinal);
-    encoder.setBool(Key.IS_CONST, element.isConst);
-    encoder.setBool(Key.IS_INJECTED, element.isInjected);
-    ConstantExpression constant = element.constant;
-    if (constant != null) {
-      encoder.setConstant(Key.CONSTANT, constant);
-    }
-    SerializerUtil.serializeParentRelation(element, encoder);
-    if (element is EnumConstantElement) {
-      EnumConstantElement enumConstant = element;
-      encoder.setInt(Key.INDEX, enumConstant.index);
-    }
-  }
-}
-
-class FunctionSerializer implements ElementSerializer {
-  const FunctionSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isDeferredLoaderGetter) {
-      return null;
-    }
-    if (element.isFunction) {
-      if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_FUNCTION;
-      if (element.isStatic) return SerializedElementKind.STATIC_FUNCTION;
-      if (element.isInstanceMember) {
-        return SerializedElementKind.INSTANCE_FUNCTION;
-      }
-      if (element.isLocal) {
-        return SerializedElementKind.LOCAL_FUNCTION;
-      }
-    }
-    if (element.isGetter) {
-      if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_GETTER;
-      if (element.isStatic) return SerializedElementKind.STATIC_GETTER;
-      if (element.isInstanceMember) {
-        return SerializedElementKind.INSTANCE_GETTER;
-      }
-    }
-    if (element.isSetter) {
-      if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_SETTER;
-      if (element.isStatic) return SerializedElementKind.STATIC_SETTER;
-      if (element.isInstanceMember) {
-        return SerializedElementKind.INSTANCE_SETTER;
-      }
-    }
-    return null;
-  }
-
-  void serialize(FunctionElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setString(Key.NAME, element.name);
-    SerializerUtil.serializeMetadata(element, encoder);
-    SerializerUtil.serializePosition(element, encoder);
-    SerializerUtil.serializeParameters(element, encoder);
-    encoder.setType(Key.TYPE, element.type);
-    if (element.isFunction) {
-      encoder.setBool(Key.IS_OPERATOR, element.isOperator);
-      encoder.setEnum(Key.ASYNC_MARKER, element.asyncMarker);
-    } else if (element.isGetter) {
-      encoder.setEnum(Key.ASYNC_MARKER, element.asyncMarker);
-    }
-    SerializerUtil.serializeParentRelation(element, encoder);
-    encoder.setBool(Key.IS_EXTERNAL, element.isExternal);
-    encoder.setBool(Key.IS_ABSTRACT, element.isAbstract);
-    encoder.setBool(Key.IS_INJECTED, element.isInjected);
-    if (element.isLocal) {
-      LocalFunctionElement localFunction = element;
-      encoder.setElement(
-          Key.EXECUTABLE_CONTEXT, localFunction.executableContext);
-    }
-    encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
-  }
-}
-
-class TypedefSerializer implements ElementSerializer {
-  const TypedefSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isTypedef) {
-      return SerializedElementKind.TYPEDEF;
-    }
-    return null;
-  }
-
-  void serialize(TypedefElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setString(Key.NAME, element.name);
-    SerializerUtil.serializeMetadata(element, encoder);
-    SerializerUtil.serializePosition(element, encoder);
-    encoder.setType(Key.ALIAS, element.alias);
-    encoder.setElement(Key.LIBRARY, element.library);
-    encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
-    encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
-  }
-}
-
-class TypeVariableSerializer implements ElementSerializer {
-  const TypeVariableSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isTypeVariable) {
-      return SerializedElementKind.TYPEVARIABLE;
-    }
-    return null;
-  }
-
-  void serialize(TypeVariableElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setElement(Key.TYPE_DECLARATION, element.typeDeclaration);
-    encoder.setString(Key.NAME, element.name);
-    SerializerUtil.serializeMetadata(element, encoder);
-    SerializerUtil.serializePosition(element, encoder);
-    encoder.setType(Key.TYPE, element.type);
-    encoder.setInt(Key.INDEX, element.index);
-    encoder.setType(Key.BOUND, element.bound);
-  }
-}
-
-class ParameterSerializer implements ElementSerializer {
-  const ParameterSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isRegularParameter) {
-      return SerializedElementKind.PARAMETER;
-    } else if (element.isInitializingFormal) {
-      return SerializedElementKind.INITIALIZING_FORMAL;
-    }
-    return null;
-  }
-
-  void serialize(ParameterElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setElement(Key.FUNCTION, element.functionDeclaration);
-    encoder.setString(Key.NAME, element.name);
-    SerializerUtil.serializeMetadata(element, encoder);
-    SerializerUtil.serializePosition(element, encoder);
-    encoder.setType(Key.TYPE, element.type);
-    encoder.setBool(Key.IS_OPTIONAL, element.isOptional);
-    encoder.setBool(Key.IS_NAMED, element.isNamed);
-    encoder.setBool(Key.IS_FINAL, element.isFinal);
-    if (element.isOptional) {
-      encoder.setConstant(Key.CONSTANT, element.constant);
-    }
-    if (element.isInitializingFormal) {
-      InitializingFormalElement initializingFormal = element;
-      encoder.setElement(Key.FIELD, initializingFormal.fieldElement);
-    }
-  }
-}
-
-class LocalVariableSerializer implements ElementSerializer {
-  const LocalVariableSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isVariable) {
-      return SerializedElementKind.LOCAL_VARIABLE;
-    }
-    return null;
-  }
-
-  void serialize(LocalVariableElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setString(Key.NAME, element.name);
-    SerializerUtil.serializeMetadata(element, encoder);
-    SerializerUtil.serializePosition(element, encoder);
-    encoder.setType(Key.TYPE, element.type);
-    encoder.setBool(Key.IS_FINAL, element.isFinal);
-    encoder.setBool(Key.IS_CONST, element.isConst);
-    if (element.isConst) {
-      ConstantExpression constant = element.constant;
-      encoder.setConstant(Key.CONSTANT, constant);
-    }
-    encoder.setElement(Key.EXECUTABLE_CONTEXT, element.executableContext);
-  }
-}
-
-class ImportSerializer implements ElementSerializer {
-  const ImportSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isImport) {
-      return SerializedElementKind.IMPORT;
-    }
-    return null;
-  }
-
-  void serialize(ImportElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    SerializerUtil.serializeMetadata(element, encoder);
-    encoder.setElement(Key.LIBRARY, element.library);
-    encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
-    encoder.setElement(Key.LIBRARY_DEPENDENCY, element.importedLibrary);
-    if (element.prefix != null) {
-      encoder.setElement(Key.PREFIX, element.prefix);
-    }
-    encoder.setBool(Key.IS_DEFERRED, element.isDeferred);
-    // TODO(johnniwinther): What is the base for the URI?
-    encoder.setUri(Key.URI, element.uri, element.uri);
-  }
-}
-
-class ExportSerializer implements ElementSerializer {
-  const ExportSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isExport) {
-      return SerializedElementKind.EXPORT;
-    }
-    return null;
-  }
-
-  void serialize(ExportElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    SerializerUtil.serializeMetadata(element, encoder);
-    encoder.setElement(Key.LIBRARY, element.library);
-    encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
-    encoder.setElement(Key.LIBRARY_DEPENDENCY, element.exportedLibrary);
-    // TODO(johnniwinther): What is the base for the URI?
-    encoder.setUri(Key.URI, element.uri, element.uri);
-  }
-}
-
-class PrefixSerializer implements ElementSerializer {
-  const PrefixSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isPrefix) {
-      return SerializedElementKind.PREFIX;
-    }
-    return null;
-  }
-
-  void serialize(PrefixElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setString(Key.NAME, element.name);
-    encoder.setElement(Key.LIBRARY, element.library);
-    encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
-    encoder.setBool(Key.IS_DEFERRED, element.isDeferred);
-    Set<Element> members = new Set<Element>();
-    element.forEachLocalMember(SerializerUtil.flattenElements(members));
-    encoder.setElements(Key.MEMBERS, members);
-    if (element.isDeferred) {
-      encoder.setElement(Key.IMPORT, element.deferredImport);
-      encoder.setElement(Key.GETTER, element.loadLibrary);
-    }
-  }
-}
-
-class DeferredLoadLibrarySerializer implements ElementSerializer {
-  const DeferredLoadLibrarySerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isDeferredLoaderGetter) {
-      return SerializedElementKind.DEFERRED_LOAD_LIBRARY;
-    }
-    return null;
-  }
-
-  void serialize(GetterElement element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setElement(Key.PREFIX, element.enclosingElement);
-  }
-}
-
-class WarnOnUseSerializer implements ElementSerializer {
-  const WarnOnUseSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isWarnOnUse) {
-      return SerializedElementKind.WARN_ON_USE;
-    }
-    return null;
-  }
-
-  void serialize(WarnOnUseElementX element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    encoder.setElement(Key.ENCLOSING, element.enclosingElement);
-    encoder.setElement(Key.ELEMENT, element.wrappedElement);
-    serializeWrappedMessage(encoder, Key.WARNING, element.warning);
-    serializeWrappedMessage(encoder, Key.INFO, element.info);
-  }
-}
-
-class AmbiguousSerializer implements ElementSerializer {
-  const AmbiguousSerializer();
-
-  SerializedElementKind getSerializedKind(Element element) {
-    if (element.isAmbiguous) {
-      return SerializedElementKind.AMBIGUOUS;
-    }
-    return null;
-  }
-
-  void serialize(AmbiguousImportX element, ObjectEncoder encoder,
-      SerializedElementKind kind) {
-    // TODO(johnniwinther): Also support [DuplicateElementX] if serialization
-    // of code with compile-time errors is supported.
-    encoder.setElement(Key.ENCLOSING, element.enclosingElement);
-    encoder.setElement(Key.EXISTING, element.existingElement);
-    encoder.setElement(Key.NEW, element.newElement);
-    encoder.setEnum(Key.MESSAGE_KIND, element.messageKind);
-    serializeMessageArguments(encoder, Key.ARGUMENTS, element.messageArguments);
-  }
-}
-
-/// Utility class for deserializing [Element]s.
-///
-/// This is used by the [Deserializer].
-class ElementDeserializer {
-  /// Deserializes an [Element] from an [ObjectDecoder].
-  ///
-  /// The class is called from the [Deserializer] when an [Element]
-  /// needs deserialization. The [ObjectDecoder] ensures that any [Element],
-  /// [ResolutionDartType], and [ConstantExpression] that the deserialized
-  /// [Element] depends upon are available.
-  static Element deserialize(
-      ObjectDecoder decoder, SerializedElementKind elementKind) {
-    switch (elementKind) {
-      case SerializedElementKind.ERROR:
-        Element enclosing = decoder.getElement(Key.ENCLOSING);
-        String name = decoder.getString(Key.NAME);
-        MessageKind messageKind =
-            decoder.getEnum(Key.MESSAGE_KIND, MessageKind.values);
-        Map<String, String> arguments =
-            deserializeMessageArguments(decoder, Key.ARGUMENTS);
-        return new ErroneousElementX(messageKind, arguments, name, enclosing);
-      case SerializedElementKind.LIBRARY:
-        return new LibraryElementZ(decoder);
-      case SerializedElementKind.COMPILATION_UNIT:
-        return new CompilationUnitElementZ(decoder);
-      case SerializedElementKind.CLASS:
-        return new ClassElementZ(decoder);
-      case SerializedElementKind.ENUM:
-        return new EnumClassElementZ(decoder);
-      case SerializedElementKind.NAMED_MIXIN_APPLICATION:
-        return new NamedMixinApplicationElementZ(decoder);
-      case SerializedElementKind.TOPLEVEL_FIELD:
-        return new TopLevelFieldElementZ(decoder);
-      case SerializedElementKind.STATIC_FIELD:
-        return new StaticFieldElementZ(decoder);
-      case SerializedElementKind.ENUM_CONSTANT:
-        return new EnumConstantElementZ(decoder);
-      case SerializedElementKind.INSTANCE_FIELD:
-        return new InstanceFieldElementZ(decoder);
-      case SerializedElementKind.GENERATIVE_CONSTRUCTOR:
-        return new GenerativeConstructorElementZ(decoder);
-      case SerializedElementKind.DEFAULT_CONSTRUCTOR:
-        return new DefaultConstructorElementZ(decoder);
-      case SerializedElementKind.FACTORY_CONSTRUCTOR:
-        return new FactoryConstructorElementZ(decoder);
-      case SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR:
-        return new RedirectingFactoryConstructorElementZ(decoder);
-      case SerializedElementKind.FORWARDING_CONSTRUCTOR:
-        ClassElement cls = decoder.getElement(Key.CLASS);
-        Element definingConstructor =
-            deserializeElementReference(cls, Key.ELEMENT, Key.NAME, decoder);
-        return new ForwardingConstructorElementZ(cls, definingConstructor);
-      case SerializedElementKind.TOPLEVEL_FUNCTION:
-        return new TopLevelFunctionElementZ(decoder);
-      case SerializedElementKind.STATIC_FUNCTION:
-        return new StaticFunctionElementZ(decoder);
-      case SerializedElementKind.INSTANCE_FUNCTION:
-        return new InstanceFunctionElementZ(decoder);
-      case SerializedElementKind.LOCAL_FUNCTION:
-        return new LocalFunctionElementZ(decoder);
-      case SerializedElementKind.TOPLEVEL_GETTER:
-        return new TopLevelGetterElementZ(decoder);
-      case SerializedElementKind.STATIC_GETTER:
-        return new StaticGetterElementZ(decoder);
-      case SerializedElementKind.INSTANCE_GETTER:
-        return new InstanceGetterElementZ(decoder);
-      case SerializedElementKind.TOPLEVEL_SETTER:
-        return new TopLevelSetterElementZ(decoder);
-      case SerializedElementKind.STATIC_SETTER:
-        return new StaticSetterElementZ(decoder);
-      case SerializedElementKind.INSTANCE_SETTER:
-        return new InstanceSetterElementZ(decoder);
-      case SerializedElementKind.TYPEDEF:
-        return new TypedefElementZ(decoder);
-      case SerializedElementKind.TYPEVARIABLE:
-        return new TypeVariableElementZ(decoder);
-      case SerializedElementKind.PARAMETER:
-        return new LocalParameterElementZ(decoder);
-      case SerializedElementKind.INITIALIZING_FORMAL:
-        return new InitializingFormalElementZ(decoder);
-      case SerializedElementKind.IMPORT:
-        return new ImportElementZ(decoder);
-      case SerializedElementKind.EXPORT:
-        return new ExportElementZ(decoder);
-      case SerializedElementKind.PREFIX:
-        return new PrefixElementZ(decoder);
-      case SerializedElementKind.DEFERRED_LOAD_LIBRARY:
-        return new DeferredLoaderGetterElementX(decoder.getElement(Key.PREFIX));
-      case SerializedElementKind.LOCAL_VARIABLE:
-        return new LocalVariableElementZ(decoder);
-      case SerializedElementKind.WARN_ON_USE:
-        Element enclosing = decoder.getElement(Key.ENCLOSING);
-        Element element = decoder.getElement(Key.ELEMENT);
-        WrappedMessage warning =
-            deserializeWrappedMessage(decoder, Key.WARNING);
-        WrappedMessage info = deserializeWrappedMessage(decoder, Key.INFO);
-        return new WarnOnUseElementX(warning, info, enclosing, element);
-      case SerializedElementKind.AMBIGUOUS:
-        Element enclosingElement = decoder.getElement(Key.ENCLOSING);
-        Element existingElement = decoder.getElement(Key.EXISTING);
-        Element newElement = decoder.getElement(Key.NEW);
-        MessageKind messageKind =
-            decoder.getEnum(Key.MESSAGE_KIND, MessageKind.values);
-        Map messageArguments =
-            deserializeMessageArguments(decoder, Key.ARGUMENTS);
-        return new AmbiguousImportX(messageKind, messageArguments,
-            enclosingElement, existingElement, newElement);
-      case SerializedElementKind.EXTERNAL_LIBRARY:
-      case SerializedElementKind.EXTERNAL_LIBRARY_MEMBER:
-      case SerializedElementKind.EXTERNAL_CLASS_MEMBER:
-      case SerializedElementKind.EXTERNAL_CONSTRUCTOR:
-        break;
-    }
-    throw new UnsupportedError("Unexpected element kind '${elementKind}.");
-  }
-}
diff --git a/pkg/compiler/lib/src/serialization/impact_serialization.dart b/pkg/compiler/lib/src/serialization/impact_serialization.dart
deleted file mode 100644
index 1d14bb7..0000000
--- a/pkg/compiler/lib/src/serialization/impact_serialization.dart
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.impact;
-
-import '../common/resolution.dart';
-import '../constants/expressions.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/resolution_types.dart';
-import '../universe/call_structure.dart';
-import '../universe/feature.dart';
-import '../universe/selector.dart';
-import '../universe/use.dart';
-import '../universe/world_impact.dart';
-import '../util/enumset.dart';
-import 'keys.dart';
-import 'serialization.dart';
-import 'serialization_util.dart';
-
-/// Visitor that serializes a [ResolutionImpact] object using an
-/// [ObjectEncoder].
-class ImpactSerializer implements WorldImpactVisitor {
-  final Element element;
-  final ObjectEncoder objectEncoder;
-  final ListEncoder staticUses;
-  final ListEncoder dynamicUses;
-  final ListEncoder typeUses;
-  final SerializerPlugin nativeDataSerializer;
-
-  ImpactSerializer(
-      this.element, ObjectEncoder objectEncoder, this.nativeDataSerializer)
-      : this.objectEncoder = objectEncoder,
-        staticUses = objectEncoder.createList(Key.STATIC_USES),
-        dynamicUses = objectEncoder.createList(Key.DYNAMIC_USES),
-        typeUses = objectEncoder.createList(Key.TYPE_USES);
-
-  void serialize(ResolutionImpact resolutionImpact) {
-    resolutionImpact.apply(this);
-    objectEncoder.setStrings(Key.SYMBOLS, resolutionImpact.constSymbolNames);
-    objectEncoder.setConstants(
-        Key.CONSTANTS, resolutionImpact.constantLiterals);
-    objectEncoder.setEnums(Key.FEATURES, resolutionImpact.features);
-    if (resolutionImpact.listLiterals.isNotEmpty) {
-      ListEncoder encoder = objectEncoder.createList(Key.LISTS);
-      for (ListLiteralUse use in resolutionImpact.listLiterals) {
-        ObjectEncoder useEncoder = encoder.createObject();
-        ResolutionInterfaceType type = use.type;
-        useEncoder.setType(Key.TYPE, type);
-        useEncoder.setBool(Key.IS_CONST, use.isConstant);
-        useEncoder.setBool(Key.IS_EMPTY, use.isEmpty);
-      }
-    }
-    if (resolutionImpact.mapLiterals.isNotEmpty) {
-      ListEncoder encoder = objectEncoder.createList(Key.MAPS);
-      for (MapLiteralUse use in resolutionImpact.mapLiterals) {
-        ObjectEncoder useEncoder = encoder.createObject();
-        ResolutionInterfaceType type = use.type;
-        useEncoder.setType(Key.TYPE, type);
-        useEncoder.setBool(Key.IS_CONST, use.isConstant);
-        useEncoder.setBool(Key.IS_EMPTY, use.isEmpty);
-      }
-    }
-    if (resolutionImpact.nativeData.isNotEmpty) {
-      ListEncoder encoder = objectEncoder.createList(Key.NATIVE);
-      for (dynamic data in resolutionImpact.nativeData) {
-        nativeDataSerializer.onData(data, encoder.createObject());
-      }
-    }
-  }
-
-  @override
-  void visitDynamicUse(DynamicUse dynamicUse) {
-    ObjectEncoder object = dynamicUses.createObject();
-    serializeSelector(dynamicUse.selector, object);
-  }
-
-  @override
-  void visitStaticUse(StaticUse staticUse) {
-    ObjectEncoder object = staticUses.createObject();
-    object.setEnum(Key.KIND, staticUse.kind);
-    serializeElementReference(
-        element, Key.ELEMENT, Key.NAME, object, staticUse.element);
-    ResolutionInterfaceType type = staticUse.type;
-    if (type != null) {
-      object.setType(Key.TYPE, type);
-    }
-    if (staticUse.callStructure != null) {
-      serializeCallStructure(
-          staticUse.callStructure, object.createObject(Key.CALL_STRUCTURE));
-    }
-  }
-
-  @override
-  void visitTypeUse(TypeUse typeUse) {
-    ObjectEncoder object = typeUses.createObject();
-    object.setEnum(Key.KIND, typeUse.kind);
-    object.setType(Key.TYPE, typeUse.type);
-  }
-
-  @override
-  void visitConstantUse(ConstantUse typeUse) {
-    throw new UnsupportedError("ConstantUse serialization is not supported.");
-  }
-}
-
-/// A deserialized [WorldImpact] object.
-class DeserializedResolutionImpact extends WorldImpact
-    implements ResolutionImpact {
-  final Iterable<String> constSymbolNames;
-  final Iterable<ConstantExpression> constantLiterals;
-  final Iterable<DynamicUse> dynamicUses;
-  final EnumSet<Feature> _features;
-  final Iterable<ListLiteralUse> listLiterals;
-  final Iterable<MapLiteralUse> mapLiterals;
-  final Iterable<StaticUse> staticUses;
-  final Iterable<TypeUse> typeUses;
-  final Iterable<dynamic> nativeData;
-  final Iterable<ClassEntity> seenClasses;
-
-  DeserializedResolutionImpact(
-      {this.constSymbolNames: const <String>[],
-      this.constantLiterals: const <ConstantExpression>[],
-      this.dynamicUses: const <DynamicUse>[],
-      EnumSet<Feature> features,
-      this.listLiterals: const <ListLiteralUse>[],
-      this.mapLiterals: const <MapLiteralUse>[],
-      this.staticUses: const <StaticUse>[],
-      this.typeUses: const <TypeUse>[],
-      this.nativeData: const <dynamic>[],
-      this.seenClasses: const <ClassEntity>[]})
-      : this._features = features;
-
-  @override
-  bool get isEmpty => false;
-
-  Iterable<Feature> get features {
-    return _features != null
-        ? _features.iterable(Feature.values)
-        : const <Feature>[];
-  }
-}
-
-class ImpactDeserializer {
-  /// Deserializes a [WorldImpact] from [objectDecoder].
-  static ResolutionImpact deserializeImpact(Element element,
-      ObjectDecoder objectDecoder, DeserializerPlugin nativeDataDeserializer) {
-    ListDecoder staticUseDecoder = objectDecoder.getList(Key.STATIC_USES);
-    List<StaticUse> staticUses = <StaticUse>[];
-    for (int index = 0; index < staticUseDecoder.length; index++) {
-      ObjectDecoder object = staticUseDecoder.getObject(index);
-      StaticUseKind kind = object.getEnum(Key.KIND, StaticUseKind.values);
-      Element usedElement =
-          deserializeElementReference(element, Key.ELEMENT, Key.NAME, object);
-      ResolutionInterfaceType type = object.getType(Key.TYPE, isOptional: true);
-      ObjectDecoder callStructureObject =
-          object.getObject(Key.CALL_STRUCTURE, isOptional: true);
-      CallStructure callStructure;
-      if (callStructureObject != null) {
-        callStructure = deserializeCallStructure(callStructureObject);
-      }
-      staticUses.add(new StaticUse.internal(usedElement, kind,
-          type: type, callStructure: callStructure));
-    }
-
-    ListDecoder dynamicUseDecoder = objectDecoder.getList(Key.DYNAMIC_USES);
-    List<DynamicUse> dynamicUses = <DynamicUse>[];
-    for (int index = 0; index < dynamicUseDecoder.length; index++) {
-      ObjectDecoder object = dynamicUseDecoder.getObject(index);
-      Selector selector = deserializeSelector(object);
-      dynamicUses.add(new DynamicUse(selector));
-    }
-
-    ListDecoder typeUseDecoder = objectDecoder.getList(Key.TYPE_USES);
-    List<TypeUse> typeUses = <TypeUse>[];
-    for (int index = 0; index < typeUseDecoder.length; index++) {
-      ObjectDecoder object = typeUseDecoder.getObject(index);
-      TypeUseKind kind = object.getEnum(Key.KIND, TypeUseKind.values);
-      ResolutionDartType type = object.getType(Key.TYPE);
-      typeUses.add(new TypeUse.internal(type, kind));
-    }
-
-    List<String> constSymbolNames =
-        objectDecoder.getStrings(Key.SYMBOLS, isOptional: true);
-
-    List<ConstantExpression> constantLiterals =
-        objectDecoder.getConstants(Key.CONSTANTS, isOptional: true);
-
-    EnumSet<Feature> features =
-        objectDecoder.getEnums(Key.FEATURES, isOptional: true);
-
-    ListDecoder listLiteralDecoder =
-        objectDecoder.getList(Key.LISTS, isOptional: true);
-    List<ListLiteralUse> listLiterals = const <ListLiteralUse>[];
-    if (listLiteralDecoder != null) {
-      listLiterals = <ListLiteralUse>[];
-      for (int i = 0; i < listLiteralDecoder.length; i++) {
-        ObjectDecoder useDecoder = listLiteralDecoder.getObject(i);
-        ResolutionInterfaceType type = useDecoder.getType(Key.TYPE);
-        bool isConstant = useDecoder.getBool(Key.IS_CONST);
-        bool isEmpty = useDecoder.getBool(Key.IS_EMPTY);
-        listLiterals.add(
-            new ListLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty));
-      }
-    }
-
-    ListDecoder mapLiteralDecoder =
-        objectDecoder.getList(Key.MAPS, isOptional: true);
-    List<MapLiteralUse> mapLiterals = const <MapLiteralUse>[];
-    if (mapLiteralDecoder != null) {
-      mapLiterals = <MapLiteralUse>[];
-      for (int i = 0; i < mapLiteralDecoder.length; i++) {
-        ObjectDecoder useDecoder = mapLiteralDecoder.getObject(i);
-        ResolutionInterfaceType type = useDecoder.getType(Key.TYPE);
-        bool isConstant = useDecoder.getBool(Key.IS_CONST);
-        bool isEmpty = useDecoder.getBool(Key.IS_EMPTY);
-        mapLiterals.add(
-            new MapLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty));
-      }
-    }
-
-    ListDecoder nativeDataDecoder =
-        objectDecoder.getList(Key.NATIVE, isOptional: true);
-    List<dynamic> nativeData = const <dynamic>[];
-    if (nativeDataDecoder != null) {
-      nativeData = <dynamic>[];
-      for (int i = 0; i < nativeDataDecoder.length; i++) {
-        dynamic data =
-            nativeDataDeserializer.onData(nativeDataDecoder.getObject(i));
-        if (data != null) {
-          nativeData.add(data);
-        }
-      }
-    }
-
-    return new DeserializedResolutionImpact(
-        constSymbolNames: constSymbolNames,
-        constantLiterals: constantLiterals,
-        dynamicUses: dynamicUses,
-        features: features,
-        listLiterals: listLiterals,
-        mapLiterals: mapLiterals,
-        staticUses: staticUses,
-        typeUses: typeUses,
-        nativeData: nativeData);
-  }
-}
diff --git a/pkg/compiler/lib/src/serialization/json_serializer.dart b/pkg/compiler/lib/src/serialization/json_serializer.dart
deleted file mode 100644
index b075e5b..0000000
--- a/pkg/compiler/lib/src/serialization/json_serializer.dart
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.json;
-
-import 'dart:convert';
-
-import 'keys.dart';
-import 'serialization.dart';
-import 'values.dart';
-
-/// Serialization encoder for JSON.
-class JsonSerializationEncoder implements SerializationEncoder {
-  const JsonSerializationEncoder();
-
-  String encode(ObjectValue objectValue) {
-    try {
-      return new JsonEncoder.withIndent(' ')
-          .convert(const JsonValueEncoder().convert(objectValue));
-    } on JsonUnsupportedObjectError catch (e) {
-      throw 'Error encoding `${e.unsupportedObject}` '
-          '(${e.unsupportedObject.runtimeType})';
-    }
-  }
-}
-
-/// Serialization decoder for JSON.
-class JsonSerializationDecoder implements SerializationDecoder {
-  const JsonSerializationDecoder();
-
-  Map decode(String text) => JSON.decode(text);
-
-  /// Returns the name of the [key] which used for to store a [Key] into a
-  /// [Map]; corresponding to the encoding of object properties in
-  /// [JsonValueEncoder.visitObject].
-  getObjectPropertyValue(Key key) => key.name;
-}
-
-/// A [ValueVisitor] that computes a JSON object value.
-class JsonValueEncoder implements ValueVisitor {
-  const JsonValueEncoder();
-
-  convert(Value value) => visit(value, null);
-
-  @override
-  visit(Value value, [arg]) => value.accept(this, arg);
-
-  @override
-  bool visitBool(BoolValue value, arg) => value.value;
-
-  @override
-  visitConstant(ConstantValue value, arg) => visit(value.id);
-
-  @override
-  visitDouble(DoubleValue value, arg) {
-    double d = value.value;
-    if (d.isNaN) {
-      return 'NaN';
-    } else if (d.isInfinite) {
-      if (d.isNegative) {
-        return '-Infinity';
-      } else {
-        return 'Infinity';
-      }
-    }
-    return d;
-  }
-
-  @override
-  visitElement(ElementValue value, arg) => visit(value.id);
-
-  @override
-  visitEnum(EnumValue value, arg) => value.value.index;
-
-  @override
-  int visitInt(IntValue value, arg) => value.value;
-
-  @override
-  List visitList(ListValue value, arg) => value.values.map(visit).toList();
-
-  @override
-  Map visitMap(MapValue value, arg) {
-    Map<String, dynamic> map = <String, dynamic>{};
-    value.map.forEach((String key, Value value) {
-      map[key] = visit(value);
-    });
-    return map;
-  }
-
-  @override
-  Map visitObject(ObjectValue value, arg) {
-    Map<String, dynamic> map = <String, dynamic>{};
-    value.map.forEach((Key key, Value value) {
-      map[key.name] = visit(value);
-    });
-    return map;
-  }
-
-  @override
-  String visitString(StringValue value, arg) => value.value;
-
-  @override
-  visitType(TypeValue value, arg) => visit(value.id);
-
-  @override
-  visitUri(UriValue value, arg) => '${value.value}';
-}
-
-/// [ValueVisitor] that generates a verbose JSON-like output.
-class PrettyPrintEncoder implements ValueVisitor<dynamic, String> {
-  StringBuffer buffer;
-
-  String toText(Value value) {
-    buffer = new StringBuffer();
-    visit(value, '');
-    String text = buffer.toString();
-    buffer = null;
-    return text;
-  }
-
-  @override
-  void visit(Value value, String indentation) {
-    value.accept(this, indentation);
-  }
-
-  @override
-  void visitBool(BoolValue value, String indentation) {
-    buffer.write(value.value);
-  }
-
-  @override
-  void visitConstant(ConstantValue value, String indentation) {
-    buffer.write('Constant(${value.id}):${value.constant.toDartText()}');
-  }
-
-  @override
-  void visitDouble(DoubleValue value, String indentation) {
-    buffer.write(value.value);
-  }
-
-  @override
-  void visitElement(ElementValue value, String indentation) {
-    buffer.write('Element(${value.id}):${value.element}');
-  }
-
-  @override
-  void visitEnum(EnumValue value, String indentation) {
-    buffer.write(value.value);
-  }
-
-  @override
-  void visitInt(IntValue value, String indentation) {
-    buffer.write(value.value);
-  }
-
-  @override
-  void visitList(ListValue value, String indentation) {
-    if (value.values.isEmpty) {
-      buffer.write('[]');
-    } else {
-      buffer.write('[');
-      bool needsComma = false;
-      String nextIndentation = '${indentation}  ';
-      for (Value element in value.values) {
-        if (needsComma) {
-          buffer.write(',');
-        }
-        buffer.write('\n$nextIndentation');
-        visit(element, nextIndentation);
-        needsComma = true;
-      }
-      buffer.write('\n$indentation]');
-    }
-  }
-
-  @override
-  void visitMap(MapValue value, String indentation) {
-    if (value.map.isEmpty) {
-      buffer.write('{}');
-    } else {
-      buffer.write('{');
-      bool needsComma = false;
-      String nextIndentation = '${indentation}  ';
-      value.map.forEach((String key, Value subvalue) {
-        if (needsComma) {
-          buffer.write(',');
-        }
-        buffer.write('\n$nextIndentation$key: ');
-        visit(subvalue, nextIndentation);
-        needsComma = true;
-      });
-      buffer.write('\n$indentation}');
-    }
-  }
-
-  @override
-  void visitObject(ObjectValue value, String indentation) {
-    if (value.map.isEmpty) {
-      buffer.write('{}');
-    } else {
-      buffer.write('{');
-      bool needsComma = false;
-      String nextIndentation = '${indentation}  ';
-      value.map.forEach((Key key, Value subvalue) {
-        if (needsComma) {
-          buffer.write(',');
-        }
-        buffer.write('\n$nextIndentation$key: ');
-        visit(subvalue, nextIndentation);
-        needsComma = true;
-      });
-      buffer.write('\n$indentation}');
-    }
-  }
-
-  @override
-  void visitString(StringValue value, String indentation) {
-    buffer.write('"${value.value}"');
-  }
-
-  @override
-  void visitType(TypeValue value, String indentation) {
-    buffer.write('Type(${value.id}):${value.type}');
-  }
-
-  @override
-  void visitUri(UriValue value, String indentation) {
-    buffer.write('Uri(${value.value})');
-  }
-}
diff --git a/pkg/compiler/lib/src/serialization/keys.dart b/pkg/compiler/lib/src/serialization/keys.dart
deleted file mode 100644
index 928bbc7..0000000
--- a/pkg/compiler/lib/src/serialization/keys.dart
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.keys;
-
-/// Keys used for serialization.
-class Key {
-  static const Key ALIAS = const Key('alias');
-  static const Key ARGUMENTS = const Key('arguments');
-  static const Key ASYNC_MARKER = const Key('asyncMarker');
-  static const Key BODY = const Key('body');
-  static const Key BOUND = const Key('bound');
-  static const Key CACHED_TYPE = const Key('cachedType');
-  static const Key CALL_STRUCTURE = const Key('callStructure');
-  static const Key CALL_TYPE = const Key('callType');
-  static const Key CANONICAL_URI = const Key('canonicalUri');
-  static const Key CLASS = const Key('class');
-  static const Key COMPILATION_UNIT = const Key('compilation-unit');
-  static const Key COMPILATION_UNITS = const Key('compilation-units');
-  static const Key CONDITION = const Key('condition');
-  static const Key CONSTANT = const Key('constant');
-  static const Key CONSTANTS = const Key('constants');
-  static const Key CONSTRUCTOR = const Key('constructor');
-  static const Key CONTAINS_TRY = const Key('containsTryStatement');
-  static const Key DATA = const Key('data');
-  static const Key DEFAULT = const Key('default');
-  static const Key DEFAULTS = const Key('defaults');
-  static const Key DYNAMIC_USES = const Key('dynamic-uses');
-  static const Key EFFECTIVE_TARGET = const Key('effectiveTarget');
-  static const Key EFFECTIVE_TARGET_TYPE = const Key('effectiveTargetType');
-  static const Key EFFECTIVE_TARGET_IS_MALFORMED =
-      const Key('effectiveTargetIsMalformed');
-  static const Key ELEMENT = const Key('element');
-  static const Key ELEMENTS = const Key('elements');
-  static const Key ENCLOSING = const Key('enclosing');
-  static const Key EXECUTABLE_CONTEXT = const Key('executable-context');
-  static const Key EXISTING = const Key('existing');
-  static const Key EXPORTS = const Key('exports');
-  static const Key EXPORT_SCOPE = const Key('export-scope');
-  static const Key EXPRESSION = const Key('expression');
-  static const Key FALSE = const Key('false');
-  static const Key FEATURES = const Key('features');
-  static const Key FIELD = const Key('field');
-  static const Key FIELDS = const Key('fields');
-  static const Key FUNCTION = const Key('function');
-  static const Key GET_OR_SET = const Key('getOrSet');
-  static const Key GETTER = const Key('getter');
-  static const Key ID = const Key('id');
-  static const Key IMMEDIATE_REDIRECTION_TARGET =
-      const Key('immediateRedirectionTarget');
-  static const Key IMPACTS = const Key('impacts');
-  static const Key IMPORT = const Key('import');
-  static const Key IMPORTS = const Key('imports');
-  static const Key IMPORTS_FOR = const Key('importsFor');
-  static const Key IMPORT_SCOPE = const Key('import-scope');
-  static const Key INDEX = const Key('index');
-  static const Key INFO = const Key('info');
-  static const Key INTERFACES = const Key('interfaces');
-  static const Key IS_ABSTRACT = const Key('isAbstract');
-  static const Key IS_BREAK_TARGET = const Key('isBreakTarget');
-  static const Key IS_CONST = const Key('isConst');
-  static const Key IS_CONTINUE_TARGET = const Key('isContinueTarget');
-  static const Key IS_DEFERRED = const Key('isDeferred');
-  static const Key IS_EMPTY = const Key('isEmpty');
-  static const Key IS_EXTERNAL = const Key('isExternal');
-  static const Key IS_FINAL = const Key('isFinal');
-  static const Key IS_INJECTED = const Key('isInjected');
-  static const Key IS_METHOD_TYPE_VARIABLE_TYPE =
-      const Key('isMethodTypeVariableType');
-  static const Key IS_NAMED = const Key('isNamed');
-  static const Key IS_OPERATOR = const Key('isOperator');
-  static const Key IS_OPTIONAL = const Key('isOptional');
-  static const Key IS_PROXY = const Key('isProxy');
-  static const Key IS_REDIRECTING = const Key('isRedirecting');
-  static const Key IS_SETTER = const Key('isSetter');
-  static const Key IS_UNNAMED_MIXIN_APPLICATION =
-      const Key('isUnnamedMixinApplication');
-  static const Key JUMP_TARGET = const Key('jumpTarget');
-  static const Key JUMP_TARGETS = const Key('jumpTargets');
-  static const Key JUMP_TARGET_DEFINITION = const Key('jumpTargetDefinition');
-  static const Key KEYS = const Key('keys');
-  static const Key KIND = const Key('kind');
-  static const Key LABEL_DEFINITION = const Key('labelDefinition');
-  static const Key LABEL_DEFINITIONS = const Key('labelDefinitions');
-  static const Key LABELS = const Key('labels');
-  static const Key LEFT = const Key('left');
-  static const Key LENGTH = const Key('length');
-  static const Key LIBRARY = const Key('library');
-  static const Key LIBRARY_DEPENDENCY = const Key('library-dependency');
-  static const Key LIBRARY_NAME = const Key('library-name');
-  static const Key LISTS = const Key('lists');
-  static const Key MAPS = const Key('maps');
-  static const Key MEMBERS = const Key('members');
-  static const Key MESSAGE_KIND = const Key('messageKind');
-  static const Key METADATA = const Key('metadata');
-  static const Key MIXIN = const Key('mixin');
-  static const Key MIXINS = const Key('mixins');
-  static const Key NAME = const Key('name');
-  static const Key NAMES = const Key('names');
-  static const Key NAMED_ARGUMENTS = const Key('named-arguments');
-  static const Key NAMED_PARAMETERS = const Key('named-parameters');
-  static const Key NAMED_PARAMETER_TYPES = const Key('named-parameter-types');
-  static const Key NATIVE = const Key('native');
-  static const Key NESTING_LEVEL = const Key('nestingLevel');
-  static const Key NEW = const Key('new');
-  static const Key NEW_STRUCTURE = const Key('newStructure');
-  static const Key NODE = const Key('node');
-  static const Key OFFSET = const Key('offset');
-  static const Key OPERATOR = const Key('operator');
-  static const Key OPTIONAL_PARAMETER_TYPES =
-      const Key('optional-parameter-types');
-  static const Key PARAMETERS = const Key('parameters');
-  static const Key PARAMETER_TYPES = const Key('parameter-types');
-  static const Key PREFIX = const Key('prefix');
-  static const Key RETURN_TYPE = const Key('return-type');
-  static const Key RIGHT = const Key('right');
-  static const Key SELECTOR = const Key('selector');
-  static const Key SEMANTICS = const Key('semantics');
-  static const Key SEND_STRUCTURE = const Key('sendStructure');
-  static const Key SETTER = const Key('setter');
-  static const Key SOURCE_SPAN = const Key('sourceSpan');
-  static const Key STATIC_USES = const Key('static-uses');
-  static const Key SUB_KIND = const Key('subKind');
-  static const Key SUPERTYPE = const Key('supertype');
-  static const Key SUPERTYPES = const Key('supertypes');
-  static const Key SYMBOLS = const Key('symbols');
-  static const Key TAGS = const Key('tags');
-  static const Key TARGET_LABEL = const Key('targetLabel');
-  static const Key TRUE = const Key('true');
-  static const Key TYPE = const Key('type');
-  static const Key TYPES = const Key('types');
-  static const Key TYPE_ARGUMENTS = const Key('type-arguments');
-  static const Key TYPE_DECLARATION = const Key('type-declaration');
-  static const Key TYPE_USES = const Key('type-uses');
-  static const Key TYPE_VARIABLES = const Key('type-variables');
-  static const Key URI = const Key('uri');
-  static const Key VALUE = const Key('value');
-  static const Key VALUES = const Key('values');
-  static const Key WARNING = const Key('warning');
-
-  final String name;
-
-  const Key(this.name);
-
-  String toString() => name;
-}
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
deleted file mode 100644
index 34549ec..0000000
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ /dev/null
@@ -1,2487 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Implementation of the element model used for deserialiation.
-///
-/// These classes are created by [ElementDeserializer] triggered by the
-/// [Deserializer].
-
-library dart2js.serialization.modelz;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/common.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/modelx.dart' show FunctionSignatureX;
-import '../elements/names.dart';
-import '../elements/visitor.dart';
-import '../io/source_file.dart';
-import '../ordered_typeset.dart';
-import '../resolution/class_members.dart' as class_members;
-import '../resolution/scope.dart' show Scope;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../script.dart';
-import '../serialization/constant_serialization.dart';
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link, LinkBuilder;
-import 'keys.dart';
-import 'serialization.dart';
-
-/// Compute a [Link] from an [Iterable].
-Link toLink(Iterable iterable) {
-  LinkBuilder builder = new LinkBuilder();
-  for (var element in iterable) {
-    builder.addLast(element);
-  }
-  return builder.toLink();
-}
-
-abstract class ElementZ extends Element with ElementCommon {
-  String toString() {
-    if (enclosingElement == null || isTopLevel) return 'Z$kind($name)';
-    return 'Z$kind(${enclosingElement.name}#$name)';
-  }
-
-  _unsupported(text) => throw new UnsupportedError('${this}.$text');
-
-  @override
-  AnalyzableElement get analyzableElement {
-    Element element = this;
-    if (element is AnalyzableElement) {
-      return element;
-    } else if (enclosingElement != null) {
-      return enclosingElement.analyzableElement;
-    }
-    return null;
-  }
-
-  @override
-  FunctionElement asFunctionElement() => null;
-
-  @override
-  Scope buildScope() => _unsupported('buildScope');
-
-  @override
-  ClassElement get enclosingClass => null;
-
-  @override
-  LibraryElement get implementationLibrary => library;
-
-  @override
-  bool get isAbstract => false;
-
-  @override
-  bool get isClassMember => false;
-
-  @override
-  bool get isClosure => false;
-
-  @override
-  bool get isConst => false;
-
-  @override
-  bool get isDeferredLoaderGetter => false;
-
-  @override
-  bool get isFinal => false;
-
-  @override
-  bool get isInstanceMember => false;
-
-  @override
-  bool get isLocal => false;
-
-  @override
-  bool get isMixinApplication => false;
-
-  @override
-  bool get isOperator => false;
-
-  @override
-  bool get isStatic => false;
-
-  @override
-  bool get isSynthesized => false;
-
-  @override
-  bool get isTopLevel => false;
-
-  @override
-  Iterable<MetadataAnnotation> get metadata => const <MetadataAnnotation>[];
-
-  @override
-  Token get position => _unsupported('position');
-}
-
-abstract class DeserializedElementZ extends ElementZ {
-  ObjectDecoder _decoder;
-  List<MetadataAnnotation> _metadata;
-
-  DeserializedElementZ(this._decoder);
-
-  @override
-  String get name => _decoder.getString(Key.NAME);
-
-  // TODO(johnniwinther): Should this be cached?
-  @override
-  int get sourceOffset => _decoder.getInt(Key.OFFSET, isOptional: true);
-
-  @override
-  SourceSpan get sourcePosition {
-    // TODO(johnniwinther): Should this be cached?
-    int offset = sourceOffset;
-    if (offset == null) return null;
-    Uri uri = _decoder.getUri(Key.URI, isOptional: true);
-    if (uri == null) {
-      uri = compilationUnit.script.readableUri;
-    }
-    int length = _decoder.getInt(Key.LENGTH, isOptional: true);
-    if (length == null) {
-      length = name.length;
-    }
-    return new SourceSpan(uri, offset, offset + length);
-  }
-
-  @override
-  Iterable<MetadataAnnotation> get metadata {
-    if (_metadata == null) {
-      _metadata = <MetadataAnnotation>[];
-      ListDecoder list = _decoder.getList(Key.METADATA, isOptional: true);
-      if (list != null) {
-        for (int index = 0; index < list.length; index++) {
-          ObjectDecoder object = list.getObject(index);
-          Element element = object.getElement(Key.ELEMENT);
-          Uri uri = object.getUri(Key.URI);
-          int offset = object.getInt(Key.OFFSET);
-          int length = object.getInt(Key.LENGTH);
-          ConstantExpression constant = object.getConstant(Key.CONSTANT);
-          _metadata.add(new MetadataAnnotationZ(
-              element, new SourceSpan(uri, offset, offset + length), constant));
-        }
-      }
-    }
-    return _metadata;
-  }
-}
-
-/// Deserializer for a collection of member elements serialized as a map from
-/// names to element declarations.
-///
-/// The serialized data contains the declared getters and setters but lookup
-/// into the map returns an [AbstractFieldElement] for pairs of corresponding
-/// getters and setters.
-///
-/// The underlying map encoding allows for lazy computation of the members upon
-/// query.
-class MappedContainer {
-  Map<String, Element> _lookupCache = {};
-
-  Element lookup(String name, MapDecoder members) {
-    if (_lookupCache.containsKey(name)) {
-      Element element = _lookupCache[name];
-      if (element != null) {
-        return element;
-      }
-    }
-    if (members == null) {
-      return null;
-    }
-    bool hasId = members.containsKey(name);
-    String setterName = '$name,=';
-    bool hasSetterId = members.containsKey(setterName);
-    Element element;
-    SetterElement setterElement;
-    if (!hasId && !hasSetterId) {
-      _lookupCache[name] = null;
-      return null;
-    }
-    bool isAccessor = false;
-    if (hasId) {
-      element = members.getElement(name);
-      isAccessor = element.isGetter;
-    }
-    if (hasSetterId) {
-      setterElement = members.getElement(setterName);
-      isAccessor = true;
-    }
-    if (isAccessor) {
-      element = new AbstractFieldElementZ(name, element, setterElement);
-    }
-    _lookupCache[name] = element;
-    return element;
-  }
-}
-
-/// Deserializer for a collection of member elements serialized as a list of
-/// element declarations.
-///
-/// The serialized data contains the declared getters and setters but lookup
-/// into the map returns an [AbstractFieldElement] for pairs of corresponding
-/// getters and setters.
-///
-/// The underlying list encoding requires the complete lookup map to be computed
-/// before query.
-class ListedContainer {
-  final Map<String, Element> _lookupMap = <String, Element>{};
-
-  ListedContainer(List<Element> elements) {
-    Set<String> accessorNames = new Set<String>();
-    Map<String, Element> getters = <String, Element>{};
-    Map<String, Element> setters = <String, Element>{};
-    for (Element element in elements) {
-      String name = element.name;
-      if (element.isDeferredLoaderGetter) {
-        // Store directly.
-        // TODO(johnniwinther): Should modelx be normalized to put `loadLibrary`
-        // in an [AbstractFieldElement] instead?
-        _lookupMap[name] = element;
-      } else if (element.isGetter) {
-        accessorNames.add(name);
-        getters[name] = element;
-        // Inserting [element] here to ensure insert order of [name].
-        _lookupMap[name] = element;
-      } else if (element.isSetter) {
-        accessorNames.add(name);
-        setters[name] = element;
-        // Inserting [element] here to ensure insert order of [name].
-        _lookupMap[name] = element;
-      } else {
-        _lookupMap[name] = element;
-      }
-    }
-    for (String name in accessorNames) {
-      _lookupMap[name] =
-          new AbstractFieldElementZ(name, getters[name], setters[name]);
-    }
-  }
-
-  Element lookup(String name) => _lookupMap[name];
-
-  void forEach(f(Element element)) => _lookupMap.values.forEach(f);
-
-  Iterable<Element> get values => _lookupMap.values;
-}
-
-abstract class AnalyzableElementMixin implements AnalyzableElement, ElementZ {
-  @override
-  bool get hasTreeElements => _unsupported('hasTreeElements');
-
-  @override
-  TreeElements get treeElements => _unsupported('treeElements');
-}
-
-abstract class AstElementMixinZ<N extends Node>
-    implements AstElement, ElementZ {
-  ResolvedAst _resolvedAst;
-
-  // TODO(johnniwinther): This is needed for the token invariant assertion. Find
-  // another way to bypass the test for modelz.
-  @override
-  bool get hasNode => false;
-
-  @override
-  bool get hasResolvedAst => _resolvedAst != null;
-
-  @override
-  N get node => _unsupported('node');
-
-  @override
-  ResolvedAst get resolvedAst {
-    assert(_resolvedAst != null,
-        failedAt(this, "ResolvedAst has not been set for $this."));
-    return _resolvedAst;
-  }
-
-  void set resolvedAst(ResolvedAst value) {
-    assert(_resolvedAst == null,
-        failedAt(this, "ResolvedAst has already been set for $this."));
-    _resolvedAst = value;
-  }
-}
-
-abstract class ContainerMixin
-    implements DeserializedElementZ, ScopeContainerElement {
-  MappedContainer _membersMap = new MappedContainer();
-
-  @override
-  Element localLookup(String name) {
-    return _membersMap.lookup(
-        name, _decoder.getMap(Key.MEMBERS, isOptional: true));
-  }
-
-  @override
-  void forEachLocalMember(f(Element element)) {
-    MapDecoder members = _decoder.getMap(Key.MEMBERS, isOptional: true);
-    if (members == null) return;
-    members.forEachKey((String key) {
-      Element member = members.getElement(key);
-      if (member != null) {
-        f(member);
-      }
-    });
-  }
-}
-
-class AbstractFieldElementZ extends ElementZ
-    with AbstractFieldElementCommon
-    implements AbstractFieldElement {
-  final String name;
-  final GetterElementZ getter;
-  final SetterElementZ setter;
-
-  factory AbstractFieldElementZ(
-      String name, GetterElement getter, SetterElement setter) {
-    if (getter?.abstractField != null) {
-      return getter.abstractField;
-    } else if (setter?.abstractField != null) {
-      return setter.abstractField;
-    } else {
-      return new AbstractFieldElementZ._(name, getter, setter);
-    }
-  }
-
-  AbstractFieldElementZ._(this.name, this.getter, this.setter) {
-    if (getter != null) {
-      getter.abstractField = this;
-      getter.setter = setter;
-    }
-    if (setter != null) {
-      setter.abstractField = this;
-      setter.getter = getter;
-    }
-  }
-
-  FunctionElement get _canonicalElement => getter != null ? getter : setter;
-
-  @override
-  ElementKind get kind => ElementKind.ABSTRACT_FIELD;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitAbstractFieldElement(this, arg);
-  }
-
-  @override
-  LibraryElement get library => _canonicalElement.library;
-
-  @override
-  CompilationUnitElement get compilationUnit {
-    return _canonicalElement.compilationUnit;
-  }
-
-  @override
-  Element get enclosingElement => _canonicalElement.enclosingElement;
-
-  @override
-  int get sourceOffset => _canonicalElement.sourceOffset;
-
-  @override
-  SourceSpan get sourcePosition => _canonicalElement.sourcePosition;
-
-  @override
-  ClassElement get enclosingClass => _canonicalElement.enclosingClass;
-
-  @override
-  bool get isClassMember => _canonicalElement.isClassMember;
-
-  @override
-  bool get isInstanceMember => _canonicalElement.isInstanceMember;
-
-  @override
-  bool get isStatic => _canonicalElement.isStatic;
-
-  @override
-  bool get isTopLevel => _canonicalElement.isTopLevel;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class LibraryElementZ extends DeserializedElementZ
-    with AnalyzableElementMixin, ContainerMixin, LibraryElementCommon
-    implements LibraryElement {
-  Uri _canonicalUri;
-  CompilationUnitElement _entryCompilationUnit;
-  Link<CompilationUnitElement> _compilationUnits;
-  List<ImportElement> _imports;
-  List<ExportElement> _exports;
-  ListedContainer _exportsMap;
-  ListedContainer _importsMap;
-  Map<Element, List<ImportElement>> _importsFor;
-
-  LibraryElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.LIBRARY;
-
-  @override
-  Element get enclosingElement => null;
-
-  @override
-  SourceSpan get sourcePosition => entryCompilationUnit.sourcePosition;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitLibraryElement(this, arg);
-  }
-
-  @override
-  LibraryElement get library => this;
-
-  @override
-  CompilationUnitElement get compilationUnit => entryCompilationUnit;
-
-  @override
-  Uri get canonicalUri {
-    if (_canonicalUri == null) {
-      _canonicalUri = _decoder.getUri(Key.CANONICAL_URI);
-    }
-    return _canonicalUri;
-  }
-
-  @override
-  CompilationUnitElement get entryCompilationUnit {
-    if (_entryCompilationUnit == null) {
-      _entryCompilationUnit = _decoder.getElement(Key.COMPILATION_UNIT);
-    }
-    return _entryCompilationUnit;
-  }
-
-  @override
-  Link<CompilationUnitElement> get compilationUnits {
-    if (_compilationUnits == null) {
-      _compilationUnits = toLink(_decoder.getElements(Key.COMPILATION_UNITS));
-    }
-    return _compilationUnits;
-  }
-
-  @override
-  bool get hasLibraryName {
-    return libraryName != '';
-  }
-
-  @override
-  String get libraryName {
-    return _decoder.getString(Key.LIBRARY_NAME);
-  }
-
-  @override
-  bool get exportsHandled => true;
-
-  void _ensureExports() {
-    if (_exportsMap == null) {
-      _exportsMap = new ListedContainer(
-          _decoder.getElements(Key.EXPORT_SCOPE, isOptional: true));
-    }
-  }
-
-  @override
-  void forEachExport(f(Element element)) {
-    _ensureExports();
-    _exportsMap.forEach(f);
-  }
-
-  @override
-  Element find(String elementName) {
-    Element element = localLookup(elementName);
-    if (element == null) {
-      _ensureImports();
-      element = _importsMap.lookup(elementName);
-    }
-    return element;
-  }
-
-  @override
-  Element findLocal(String elementName) {
-    return localLookup(elementName);
-  }
-
-  @override
-  Element findExported(String elementName) {
-    _ensureExports();
-    return _exportsMap.lookup(elementName);
-  }
-
-  void _ensureImports() {
-    if (_importsMap == null) {
-      _importsMap = new ListedContainer(
-          _decoder.getElements(Key.IMPORT_SCOPE, isOptional: true));
-      _importsFor = <Element, List<ImportElement>>{};
-
-      ListDecoder importsDecoder = _decoder.getList(Key.IMPORTS_FOR);
-      for (int index = 0; index < importsDecoder.length; index++) {
-        ObjectDecoder objectDecoder = importsDecoder.getObject(index);
-        Element key = objectDecoder.getElement(Key.ELEMENT);
-        List<ImportElement> imports =
-            objectDecoder.getElements(Key.IMPORTS, isOptional: true);
-
-        // Imports are mapped to [AbstractFieldElement] which are not serialized
-        // so we use getter (or setter if there is no getter) as the key.
-        Element importedElement = key;
-        if (key.isDeferredLoaderGetter) {
-          // Use as [importedElement].
-        } else if (key.isAccessor) {
-          AccessorElement accessor = key;
-          importedElement = accessor.abstractField;
-        }
-        _importsFor[importedElement] = imports;
-      }
-    }
-  }
-
-  @override
-  void forEachImport(f(Element element)) {
-    _ensureImports();
-    _importsMap.forEach(f);
-  }
-
-  @override
-  Iterable<ImportElement> getImportsFor(Element element) {
-    _ensureImports();
-    return _importsFor[element] ?? const <ImportElement>[];
-  }
-
-  String toString() {
-    return 'Zlibrary(${canonicalUri})';
-  }
-
-  @override
-  Iterable<ExportElement> get exports {
-    if (_exports == null) {
-      _exports = _decoder.getElements(Key.EXPORTS, isOptional: true);
-    }
-    return _exports;
-  }
-
-  @override
-  Iterable<ImportElement> get imports {
-    if (_imports == null) {
-      _imports = _decoder.getElements(Key.IMPORTS, isOptional: true);
-    }
-    return _imports;
-  }
-}
-
-class ScriptZ implements Script {
-  final Uri resourceUri;
-  SourceFile _file;
-  bool _isSynthesized = false;
-
-  ScriptZ(this.resourceUri);
-
-  @override
-  Script copyWithFile(SourceFile file) {
-    throw new UnsupportedError('ScriptZ.copyWithFile');
-  }
-
-  @override
-  SourceFile get file {
-    if (_file == null) {
-      throw new UnsupportedError('ScriptZ.file');
-    }
-    return _file;
-  }
-
-  void set file(SourceFile value) {
-    _file = value;
-  }
-
-  // TODO(johnniwinther): Decide if it is meaningful to serialize erroneous
-  // elements.
-  @override
-  bool get isSynthesized => _isSynthesized;
-
-  void set isSynthesized(bool value) {
-    _isSynthesized = value;
-  }
-
-  @override
-  String get name {
-    if (_file != null) {
-      return _file.filename;
-    }
-    return resourceUri.toString();
-  }
-
-  // TODO(johnniwinther): Support the distinction between [readableUri] and
-  // [resourceUri]; needed for platform libraries.
-  @override
-  Uri get readableUri => resourceUri;
-
-  @override
-  String get text {
-    if (_file != null) {
-      return _file.slowText();
-    }
-    throw new UnsupportedError('ScriptZ.text');
-  }
-}
-
-class CompilationUnitElementZ extends DeserializedElementZ
-    with LibraryMemberMixin, CompilationUnitElementCommon
-    implements CompilationUnitElement {
-  List<Element> _members;
-  Script _script;
-
-  CompilationUnitElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.COMPILATION_UNIT;
-
-  @override
-  CompilationUnitElement get compilationUnit => this;
-
-  @override
-  Element get enclosingElement => library;
-
-  @override
-  SourceSpan get sourcePosition => new SourceSpan(script.resourceUri, 0, 0);
-
-  @override
-  bool get isTopLevel => false;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitCompilationUnitElement(this, arg);
-  }
-
-  @override
-  void forEachLocalMember(f(Element element)) {
-    if (_members == null) {
-      _members = _decoder.getElements(Key.ELEMENTS, isOptional: true);
-    }
-    _members.forEach(f);
-  }
-
-  @override
-  Script get script {
-    if (_script == null) {
-      Uri resolvedUri = _decoder.getUri(Key.URI);
-      _script = new ScriptZ(resolvedUri);
-    }
-    return _script;
-  }
-
-  @override
-  String get name => script.name;
-}
-
-abstract class LibraryMemberMixin implements DeserializedElementZ {
-  LibraryElement _library;
-  CompilationUnitElement _compilationUnit;
-
-  @override
-  LibraryElement get library {
-    if (_library == null) {
-      _library = _decoder.getElement(Key.LIBRARY);
-    }
-    return _library;
-  }
-
-  @override
-  CompilationUnitElement get compilationUnit {
-    if (_compilationUnit == null) {
-      _compilationUnit = _decoder.getElement(Key.COMPILATION_UNIT);
-    }
-    return _compilationUnit;
-  }
-
-  @override
-  Element get enclosingElement => compilationUnit;
-
-  @override
-  ClassElement get enclosingClass => null;
-
-  @override
-  bool get isTopLevel => true;
-
-  @override
-  bool get isStatic => false;
-}
-
-abstract class ClassMemberMixin implements DeserializedElementZ {
-  ClassElement _class;
-  CompilationUnitElement _compilationUnit;
-
-  @override
-  Element get enclosingElement => enclosingClass;
-
-  @override
-  ClassElement get enclosingClass {
-    if (_class == null) {
-      _class = _decoder.getElement(Key.CLASS);
-    }
-    return _class;
-  }
-
-  @override
-  bool get isClassMember => true;
-
-  @override
-  LibraryElement get library => enclosingClass.library;
-
-  @override
-  CompilationUnitElement get compilationUnit {
-    if (_compilationUnit == null) {
-      _compilationUnit =
-          _decoder.getElement(Key.COMPILATION_UNIT, isOptional: true);
-      if (_compilationUnit == null) {
-        _compilationUnit = enclosingClass.compilationUnit;
-      }
-    }
-    return _compilationUnit;
-  }
-}
-
-abstract class InstanceMemberMixin implements DeserializedElementZ {
-  @override
-  bool get isTopLevel => false;
-
-  @override
-  bool get isStatic => false;
-
-  @override
-  bool get isInstanceMember => true;
-
-  @override
-  bool get isClassMember => true;
-}
-
-abstract class StaticMemberMixin implements DeserializedElementZ {
-  @override
-  bool get isTopLevel => false;
-
-  @override
-  bool get isStatic => true;
-
-  @override
-  bool get isClassMember => true;
-}
-
-abstract class TypedElementMixin<T extends ResolutionDartType>
-    implements DeserializedElementZ, TypedElement {
-  T _type;
-
-  @override
-  T get type {
-    if (_type == null) {
-      _type = _decoder.getType(Key.TYPE);
-    }
-    return _type;
-  }
-
-  @override
-  T computeType(Resolution resolution) => type;
-}
-
-abstract class ParametersMixin
-    implements DeserializedElementZ, FunctionTypedElement {
-  FunctionSignature _functionSignature;
-  List<ParameterElement> _parameters;
-
-  bool get hasFunctionSignature => true;
-
-  @override
-  FunctionSignature get functionSignature {
-    if (_functionSignature == null) {
-      List<Element> requiredParameters = [];
-      List<Element> optionalParameters = [];
-      List<Element> orderedOptionalParameters = [];
-      int requiredParameterCount = 0;
-      int optionalParameterCount = 0;
-      bool optionalParametersAreNamed = false;
-      List<ResolutionDartType> parameterTypes = <ResolutionDartType>[];
-      List<ResolutionDartType> optionalParameterTypes = <ResolutionDartType>[];
-      for (ParameterElement parameter in parameters) {
-        if (parameter.isOptional) {
-          optionalParameterCount++;
-          optionalParameters.add(parameter);
-          orderedOptionalParameters.add(parameter);
-          if (parameter.isNamed) {
-            optionalParametersAreNamed = true;
-          } else {
-            optionalParameterTypes.add(parameter.type);
-          }
-        } else {
-          requiredParameterCount++;
-          requiredParameters.add(parameter);
-          parameterTypes.add(parameter.type);
-        }
-      }
-      List<String> namedParameters = const <String>[];
-      List<ResolutionDartType> namedParameterTypes =
-          const <ResolutionDartType>[];
-      if (optionalParametersAreNamed) {
-        namedParameters = <String>[];
-        namedParameterTypes = <ResolutionDartType>[];
-        orderedOptionalParameters.sort((Element a, Element b) {
-          return a.name.compareTo(b.name);
-        });
-        for (ParameterElement parameter in orderedOptionalParameters) {
-          namedParameters.add(parameter.name);
-          namedParameterTypes.add(parameter.type);
-        }
-      }
-      List<ResolutionDartType> typeVariables =
-          _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
-
-      ResolutionFunctionType type = new ResolutionFunctionType(
-          this,
-          _decoder.getType(Key.RETURN_TYPE),
-          parameterTypes,
-          optionalParameterTypes,
-          namedParameters,
-          namedParameterTypes);
-      _functionSignature = new FunctionSignatureX(
-          typeVariables: typeVariables,
-          requiredParameters: requiredParameters,
-          requiredParameterCount: requiredParameterCount,
-          optionalParameters: optionalParameters,
-          optionalParameterCount: optionalParameterCount,
-          optionalParametersAreNamed: optionalParametersAreNamed,
-          orderedOptionalParameters: orderedOptionalParameters,
-          type: type);
-    }
-    return _functionSignature;
-  }
-
-  List<ParameterElement> get parameters {
-    if (_parameters == null) {
-      _parameters = _decoder.getElements(Key.PARAMETERS, isOptional: true);
-    }
-    return _parameters;
-  }
-
-  ParameterStructure get parameterStructure =>
-      functionSignature.parameterStructure;
-}
-
-abstract class FunctionTypedElementMixin
-    implements FunctionElement, DeserializedElementZ {
-  @override
-  FunctionElement asFunctionElement() => this;
-
-  @override
-  bool get isExternal {
-    return _decoder.getBool(Key.IS_EXTERNAL,
-        isOptional: true, defaultValue: false);
-  }
-
-  @override
-  List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-}
-
-abstract class ClassElementMixin
-    implements ElementZ, ClassElement, class_members.ClassMemberMixin {
-  bool _isResolved = false;
-
-  ResolutionInterfaceType _createType(List<ResolutionDartType> typeArguments) {
-    return new ResolutionInterfaceType(this, typeArguments);
-  }
-
-  @override
-  ElementKind get kind => ElementKind.CLASS;
-
-  @override
-  bool get hasConstructor => _unsupported('hasConstructor');
-
-  @override
-  bool get hasIncompleteHierarchy => _unsupported('hasIncompleteHierarchy');
-
-  @override
-  bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
-
-  @override
-  bool get isEnumClass => false;
-
-  @override
-  ConstructorElement lookupDefaultConstructor() {
-    ConstructorElement constructor = lookupConstructor("");
-    if (constructor != null &&
-        constructor.functionSignature.requiredParameterCount == 0) {
-      return constructor;
-    }
-    return null;
-  }
-
-  @override
-  ClassElement get superclass => supertype != null ? supertype.element : null;
-
-  @override
-  void ensureResolved(Resolution resolution) {
-    if (!_isResolved) {
-      _isResolved = true;
-      // TODO(johnniwinther): Avoid eager computation of all members. `call` is
-      // always needed, but the remaining should be computed on-demand or on
-      // type instantiation.
-      class_members.MembersCreator.computeAllClassMembers(resolution, this);
-      resolution.registerClass(this);
-    }
-  }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class ClassElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ,
-        ClassElementCommon,
-        class_members.ClassMemberMixin,
-        ContainerMixin,
-        LibraryMemberMixin,
-        TypeDeclarationMixin,
-        ClassElementMixin
-    implements ClassElement {
-  bool _isObject;
-  ResolutionInterfaceType _supertype;
-  OrderedTypeSet _allSupertypesAndSelf;
-  Link<ResolutionDartType> _interfaces;
-  ResolutionFunctionType _callType;
-
-  ClassElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  List<ResolutionDartType> _getTypeVariables() {
-    return _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
-  }
-
-  void _ensureSuperHierarchy() {
-    if (_interfaces == null) {
-      ResolutionInterfaceType supertype =
-          _decoder.getType(Key.SUPERTYPE, isOptional: true);
-      if (supertype == null) {
-        _isObject = true;
-        _allSupertypesAndSelf = new OrderedTypeSet.singleton(thisType);
-        _interfaces = const Link<ResolutionDartType>();
-      } else {
-        _isObject = false;
-        _interfaces =
-            toLink(_decoder.getTypes(Key.INTERFACES, isOptional: true));
-        List<ResolutionInterfaceType> mixins =
-            _decoder.getTypes(Key.MIXINS, isOptional: true);
-        for (ResolutionInterfaceType mixin in mixins) {
-          MixinApplicationElement mixinElement =
-              new UnnamedMixinApplicationElementZ(this, supertype, mixin);
-          supertype = mixinElement.thisType
-              .subst(typeVariables, mixinElement.typeVariables);
-        }
-        _supertype = supertype;
-        _allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(this)
-            .createOrderedTypeSet(_supertype, _interfaces);
-        _callType = _decoder.getType(Key.CALL_TYPE, isOptional: true);
-      }
-    }
-  }
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitClassElement(this, arg);
-  }
-
-  @override
-  ResolutionDartType get supertype {
-    _ensureSuperHierarchy();
-    return _supertype;
-  }
-
-  @override
-  bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
-
-  @override
-  bool get isObject {
-    _ensureSuperHierarchy();
-    return _isObject;
-  }
-
-  @override
-  OrderedTypeSet get allSupertypesAndSelf {
-    _ensureSuperHierarchy();
-    return _allSupertypesAndSelf;
-  }
-
-  @override
-  Link<ResolutionDartType> get interfaces {
-    _ensureSuperHierarchy();
-    return _interfaces;
-  }
-
-  @override
-  bool get isProxy => _decoder.getBool(Key.IS_PROXY);
-
-  @override
-  bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
-
-  @override
-  bool get isUnnamedMixinApplication => false;
-
-  @override
-  ResolutionFunctionType get callType {
-    _ensureSuperHierarchy();
-    // TODO(johnniwinther): Why can't this always be computed in ensureResolved?
-    return _callType;
-  }
-
-  ResolutionInterfaceType get thisType => super.thisType;
-
-  ResolutionInterfaceType get rawType => super.rawType;
-}
-
-abstract class MixinApplicationElementMixin
-    implements ElementZ, MixinApplicationElement {
-  @override
-  bool get isMixinApplication => true;
-
-  @override
-  ClassElement get mixin => mixinType.element;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class NamedMixinApplicationElementZ extends ClassElementZ
-    with MixinApplicationElementMixin {
-  Link<Element> _constructors;
-  ResolutionInterfaceType _mixinType;
-
-  NamedMixinApplicationElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ResolutionInterfaceType get mixinType =>
-      _mixinType ??= _decoder.getType(Key.MIXIN);
-
-  @override
-  ClassElement get subclass => null;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class UnnamedMixinApplicationElementZ extends ElementZ
-    with
-        ClassElementCommon,
-        ClassElementMixin,
-        class_members.ClassMemberMixin,
-        // ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_MIXIN
-        TypeDeclarationMixin,
-        AnalyzableElementMixin,
-        AstElementMixinZ,
-        MixinApplicationElementCommon,
-        MixinApplicationElementMixin {
-  final String name;
-  final ClassElement subclass;
-  final ResolutionInterfaceType _supertypeBase;
-  final ResolutionInterfaceType _mixinBase;
-  ResolutionInterfaceType _supertype;
-  Link<ResolutionDartType> _interfaces;
-  OrderedTypeSet _allSupertypesAndSelf;
-  Link<ConstructorElement> _constructors;
-
-  UnnamedMixinApplicationElementZ(this.subclass,
-      ResolutionInterfaceType supertype, ResolutionInterfaceType mixin)
-      : this._supertypeBase = supertype,
-        this._mixinBase = mixin,
-        this.name = "${supertype.name}+${mixin.name}";
-
-  @override
-  CompilationUnitElement get compilationUnit => subclass.compilationUnit;
-
-  @override
-  bool get isTopLevel => true;
-
-  @override
-  bool get isAbstract => true;
-
-  @override
-  bool get isUnnamedMixinApplication => true;
-
-  Link<ConstructorElement> get constructors {
-    if (_constructors == null) {
-      LinkBuilder<ConstructorElement> builder =
-          new LinkBuilder<ConstructorElement>();
-      for (ConstructorElement definingConstructor in superclass.constructors) {
-        if (definingConstructor.isGenerativeConstructor &&
-            definingConstructor.memberName.isAccessibleFrom(library)) {
-          ForwardingConstructorElementZ constructor =
-              new ForwardingConstructorElementZ(this, definingConstructor);
-          constructor.resolvedAst = new SynthesizedResolvedAst(
-              constructor, ResolvedAstKind.FORWARDING_CONSTRUCTOR);
-          builder.addLast(constructor);
-        }
-      }
-      _constructors = builder.toLink();
-    }
-    return _constructors;
-  }
-
-  @override
-  List<ResolutionDartType> _getTypeVariables() {
-    // Create synthetic type variables for the mixin application.
-    List<ResolutionDartType> typeVariables = <ResolutionDartType>[];
-    int index = 0;
-    for (ResolutionTypeVariableType type in subclass.typeVariables) {
-      SyntheticTypeVariableElementZ typeVariableElement =
-          new SyntheticTypeVariableElementZ(this, index, type.name);
-      ResolutionTypeVariableType typeVariable =
-          new ResolutionTypeVariableType(typeVariableElement);
-      typeVariables.add(typeVariable);
-      index++;
-    }
-    // Setup bounds on the synthetic type variables.
-    for (ResolutionTypeVariableType type in subclass.typeVariables) {
-      ResolutionTypeVariableType typeVariable =
-          typeVariables[type.element.index];
-      SyntheticTypeVariableElementZ typeVariableElement = typeVariable.element;
-      typeVariableElement._type = typeVariable;
-      typeVariableElement._bound =
-          type.element.bound.subst(typeVariables, subclass.typeVariables);
-    }
-    return typeVariables;
-  }
-
-  @override
-  ResolutionInterfaceType get supertype {
-    if (_supertype == null) {
-      // Substitute the type variables in [_supertypeBase] provided by
-      // [_subclass] with the type variables in this unnamed mixin application.
-      //
-      // For instance
-      //    class S<S.T> {}
-      //    class M<M.T> {}
-      //    class C<C.T> extends S<C.T> with M<C.T> {}
-      // the unnamed mixin application should be
-      //    abstract class S+M<S+M.T> extends S<S+M.T> implements M<S+M.T> {}
-      // but the supertype is provided as S<C.T> and we need to substitute S+M.T
-      // for C.T.
-      _supertype = _supertypeBase.subst(typeVariables, subclass.typeVariables);
-    }
-    return _supertype;
-  }
-
-  @override
-  Link<ResolutionDartType> get interfaces {
-    if (_interfaces == null) {
-      // Substitute the type variables in [_mixinBase] provided by
-      // [_subclass] with the type variables in this unnamed mixin application.
-      //
-      // For instance
-      //    class S<S.T> {}
-      //    class M<M.T> {}
-      //    class C<C.T> extends S<C.T> with M<C.T> {}
-      // the unnamed mixin application should be
-      //    abstract class S+M<S+M.T> extends S<S+M.T> implements M<S+M.T> {}
-      // but the mixin is provided as M<C.T> and we need to substitute S+M.T
-      // for C.T.
-      _interfaces = const Link<ResolutionDartType>()
-          .prepend(_mixinBase.subst(typeVariables, subclass.typeVariables));
-    }
-    return _interfaces;
-  }
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitMixinApplicationElement(this, arg);
-  }
-
-  @override
-  OrderedTypeSet get allSupertypesAndSelf {
-    if (_allSupertypesAndSelf == null) {
-      _allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(this)
-          .createOrderedTypeSet(supertype, interfaces);
-    }
-    return _allSupertypesAndSelf;
-  }
-
-  @override
-  Element get enclosingElement => subclass.enclosingElement;
-
-  @override
-  bool get isObject => false;
-
-  @override
-  bool get isProxy => false;
-
-  @override
-  LibraryElement get library => enclosingElement.library;
-
-  @override
-  ResolutionInterfaceType get mixinType => interfaces.head;
-
-  @override
-  int get sourceOffset => subclass.sourceOffset;
-
-  @override
-  SourceSpan get sourcePosition => subclass.sourcePosition;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class EnumClassElementZ extends ClassElementZ implements EnumClassElement {
-  List<FieldElement> _enumValues;
-
-  EnumClassElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  bool get isEnumClass => true;
-
-  @override
-  List<EnumConstantElement> get enumValues {
-    if (_enumValues == null) {
-      _enumValues = _decoder.getElements(Key.FIELDS);
-    }
-    return _enumValues;
-  }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class ConstructorElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<FunctionExpression>,
-        ClassMemberMixin,
-        FunctionTypedElementMixin,
-        ParametersMixin,
-        TypedElementMixin<ResolutionFunctionType>,
-        MemberElementMixin,
-        ConstructorElementCommon
-    implements
-        ConstructorElement,
-        // TODO(johnniwinther): Sort out whether a constructor is a method.
-        MethodElement {
-  ConstantConstructor _constantConstructor;
-  ConstructorElement _effectiveTarget;
-
-  ConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitConstructorElement(this, arg);
-  }
-
-  @override
-  bool get isConst => _decoder.getBool(Key.IS_CONST);
-
-  @override
-  bool get isExternal => _decoder.getBool(Key.IS_EXTERNAL);
-
-  @override
-  bool get isMarkedExternal => isExternal;
-
-  @override
-  bool get isDefaultConstructor => false;
-
-  ConstantConstructor get constantConstructor {
-    if (isConst && _constantConstructor == null) {
-      ObjectDecoder data =
-          _decoder.getObject(Key.CONSTRUCTOR, isOptional: true);
-      if (data == null) {
-        assert(isFromEnvironmentConstructor || isExternal);
-        return null;
-      }
-      _constantConstructor = ConstantConstructorDeserializer.deserialize(data);
-    }
-    return _constantConstructor;
-  }
-
-  @override
-  AsyncMarker get asyncMarker => AsyncMarker.SYNC;
-
-  @override
-  ConstructorElement get definingConstructor => null;
-
-  @override
-  bool get hasEffectiveTarget => true;
-
-  @override
-  ConstructorElement get effectiveTarget {
-    if (_effectiveTarget == null) {
-      _effectiveTarget =
-          _decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
-      if (_effectiveTarget == null) {
-        _effectiveTarget = this;
-      }
-    }
-    return _effectiveTarget;
-  }
-
-  @override
-  ConstructorElement get immediateRedirectionTarget => null;
-
-  // TODO(johnniwinther): Should serialization support erroneous element
-  // relations?
-  @override
-  bool get isEffectiveTargetMalformed => false;
-
-  @override
-  bool get isCyclicRedirection => false;
-
-  @override
-  bool get isRedirectingFactory => false;
-
-  @override
-  bool get isRedirectingGenerative => false;
-
-  @override
-  PrefixElement get redirectionDeferredPrefix => null;
-
-  @override
-  ResolutionDartType computeEffectiveTargetType(
-          ResolutionInterfaceType newType) =>
-      newType;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class GenerativeConstructorElementZ extends ConstructorElementZ {
-  GenerativeConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
-
-  @override
-  bool get isRedirectingGenerative => _decoder.getBool(Key.IS_REDIRECTING);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class DefaultConstructorElementZ extends ConstructorElementZ {
-  DefaultConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
-
-  @override
-  bool get isSynthesized => true;
-
-  @override
-  bool get isDefaultConstructor => true;
-
-  @override
-  ConstructorElement get definingConstructor {
-    return enclosingClass.superclass.lookupConstructor('');
-  }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class FactoryConstructorElementZ extends ConstructorElementZ {
-  FactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class RedirectingFactoryConstructorElementZ extends ConstructorElementZ {
-  ResolutionDartType _effectiveTargetType;
-  ConstructorElement _immediateRedirectionTarget;
-  PrefixElement _redirectionDeferredPrefix;
-  bool _effectiveTargetIsMalformed;
-
-  RedirectingFactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
-
-  @override
-  bool get isRedirectingFactory => true;
-
-  void _ensureEffectiveTarget() {
-    if (_effectiveTarget == null) {
-      _effectiveTarget =
-          _decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
-      if (_effectiveTarget == null) {
-        _effectiveTarget = this;
-        _effectiveTargetType = enclosingClass.thisType;
-        _effectiveTargetIsMalformed = false;
-      } else {
-        _effectiveTargetType = _decoder.getType(Key.EFFECTIVE_TARGET_TYPE);
-        _effectiveTargetIsMalformed =
-            _decoder.getBool(Key.EFFECTIVE_TARGET_IS_MALFORMED);
-      }
-    }
-  }
-
-  bool get isEffectiveTargetMalformed {
-    _ensureEffectiveTarget();
-    return _effectiveTargetIsMalformed;
-  }
-
-  @override
-  ConstructorElement get effectiveTarget {
-    _ensureEffectiveTarget();
-    return _effectiveTarget;
-  }
-
-  @override
-  ResolutionDartType computeEffectiveTargetType(
-      ResolutionInterfaceType newType) {
-    _ensureEffectiveTarget();
-    return _effectiveTargetType.substByContext(newType);
-  }
-
-  void _ensureRedirection() {
-    if (_immediateRedirectionTarget == null) {
-      _immediateRedirectionTarget =
-          _decoder.getElement(Key.IMMEDIATE_REDIRECTION_TARGET);
-      _redirectionDeferredPrefix =
-          _decoder.getElement(Key.PREFIX, isOptional: true);
-    }
-  }
-
-  @override
-  ConstructorElement get immediateRedirectionTarget {
-    _ensureRedirection();
-    return _immediateRedirectionTarget;
-  }
-
-  @override
-  PrefixElement get redirectionDeferredPrefix {
-    _ensureRedirection();
-    return _redirectionDeferredPrefix;
-  }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class ForwardingConstructorElementZ extends ElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<FunctionExpression>
-    implements
-        ConstructorElement,
-        // TODO(johnniwinther): Sort out whether a constructor is a method.
-        MethodElement {
-  final MixinApplicationElement enclosingClass;
-  final ConstructorElement definingConstructor;
-
-  ForwardingConstructorElementZ(this.enclosingClass, this.definingConstructor);
-
-  @override
-  CompilationUnitElement get compilationUnit => enclosingClass.compilationUnit;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitConstructorElement(this, arg);
-  }
-
-  @override
-  AsyncMarker get asyncMarker => AsyncMarker.SYNC;
-
-  @override
-  ResolutionDartType computeEffectiveTargetType(
-      ResolutionInterfaceType newType) {
-    return enclosingClass.thisType.substByContext(newType);
-  }
-
-  @override
-  ResolutionDartType computeType(Resolution resolution) => type;
-
-  @override
-  bool get isConst => false;
-
-  @override
-  bool get isClassMember => true;
-
-  @override
-  bool get isDefaultConstructor => false;
-
-  @override
-  ConstantConstructor get constantConstructor => null;
-
-  @override
-  bool get hasEffectiveTarget => true;
-
-  @override
-  ConstructorElement get effectiveTarget => this;
-
-  @override
-  Element get enclosingElement => enclosingClass;
-
-  @override
-  FunctionSignature get functionSignature {
-    // TODO(johnniwinther): Ensure that the function signature (and with it the
-    // function type) substitutes type variables correctly.
-    return definingConstructor.functionSignature;
-  }
-
-  @override
-  ParameterStructure get parameterStructure {
-    return functionSignature.parameterStructure;
-  }
-
-  @override
-  bool get hasFunctionSignature {
-    return _unsupported('hasFunctionSignature');
-  }
-
-  @override
-  ConstructorElement get immediateRedirectionTarget => null;
-
-  @override
-  bool get isCyclicRedirection => false;
-
-  @override
-  bool get isEffectiveTargetMalformed => false;
-
-  @override
-  bool get isExternal => false;
-
-  @override
-  bool get isMarkedExternal => false;
-
-  @override
-  bool get isFromEnvironmentConstructor => false;
-
-  @override
-  bool get isIntFromEnvironmentConstructor => false;
-
-  @override
-  bool get isBoolFromEnvironmentConstructor => false;
-
-  @override
-  bool get isStringFromEnvironmentConstructor => false;
-
-  @override
-  bool get isRedirectingFactory => false;
-
-  @override
-  bool get isRedirectingGenerative => false;
-
-  @override
-  bool get isSynthesized => true;
-
-  @override
-  ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
-
-  @override
-  LibraryElement get library => enclosingClass.library;
-
-  @override
-  MemberElement get memberContext => this;
-
-  @override
-  Name get memberName => definingConstructor.memberName;
-
-  @override
-  String get name => definingConstructor.name;
-
-  @override
-  List<MethodElement> get nestedClosures => const <MethodElement>[];
-
-  @override
-  List<ParameterElement> get parameters {
-    // TODO(johnniwinther): We need to create synthetic parameters that
-    // substitute type variables.
-    return definingConstructor.parameters;
-  }
-
-  // TODO: implement redirectionDeferredPrefix
-  @override
-  PrefixElement get redirectionDeferredPrefix => null;
-
-  @override
-  int get sourceOffset => enclosingClass.sourceOffset;
-
-  @override
-  SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-
-  @override
-  ResolutionFunctionType get type {
-    // TODO(johnniwinther): Ensure that the function type substitutes type
-    // variables correctly.
-    return definingConstructor.type;
-  }
-
-  @override
-  List<ResolutionDartType> get typeVariables => _unsupported("typeVariables");
-}
-
-abstract class MemberElementMixin
-    implements DeserializedElementZ, MemberElement {
-  final List<MethodElement> nestedClosures = <MethodElement>[];
-
-  @override
-  MemberElement get memberContext => this;
-
-  @override
-  Name get memberName => new Name(name, library);
-
-  @override
-  bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
-}
-
-abstract class FieldElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<VariableDefinitions>,
-        TypedElementMixin,
-        MemberElementMixin
-    implements FieldElement {
-  bool _isConst;
-  ConstantExpression _constant;
-
-  FieldElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.FIELD;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitFieldElement(this, arg);
-  }
-
-  @override
-  bool get isFinal => _decoder.getBool(Key.IS_FINAL);
-
-  void _ensureConstant() {
-    if (_isConst == null) {
-      _isConst = _decoder.getBool(Key.IS_CONST);
-      _constant = _decoder.getConstant(Key.CONSTANT, isOptional: true);
-    }
-  }
-
-  @override
-  bool get isConst {
-    _ensureConstant();
-    return _isConst;
-  }
-
-  @override
-  bool get hasConstant => true;
-
-  @override
-  ConstantExpression get constant {
-    _ensureConstant();
-    return _constant;
-  }
-
-  @override
-  Expression get initializer => _unsupported('initializer');
-}
-
-class TopLevelFieldElementZ extends FieldElementZ with LibraryMemberMixin {
-  TopLevelFieldElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-class StaticFieldElementZ extends FieldElementZ
-    with ClassMemberMixin, StaticMemberMixin {
-  StaticFieldElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class EnumConstantElementZ extends StaticFieldElementZ
-    implements EnumConstantElement {
-  EnumConstantElementZ(ObjectDecoder decoder) : super(decoder);
-
-  int get index => _decoder.getInt(Key.INDEX);
-}
-
-class InstanceFieldElementZ extends FieldElementZ
-    with ClassMemberMixin, InstanceMemberMixin {
-  InstanceFieldElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class FunctionElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<FunctionExpression>,
-        ParametersMixin,
-        FunctionTypedElementMixin,
-        TypedElementMixin<ResolutionFunctionType>,
-        MemberElementMixin
-    implements MethodElement {
-  FunctionElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.FUNCTION;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitMethodElement(this, arg);
-  }
-
-  @override
-  AsyncMarker get asyncMarker {
-    return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
-  }
-
-  @override
-  bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
-
-  @override
-  bool get isOperator => _decoder.getBool(Key.IS_OPERATOR);
-
-  @override
-  bool get isMarkedExternal => isExternal;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class TopLevelFunctionElementZ extends FunctionElementZ
-    with LibraryMemberMixin {
-  TopLevelFunctionElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class StaticFunctionElementZ extends FunctionElementZ
-    with ClassMemberMixin, StaticMemberMixin {
-  StaticFunctionElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class InstanceFunctionElementZ extends FunctionElementZ
-    with ClassMemberMixin, InstanceMemberMixin {
-  InstanceFunctionElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-abstract class LocalExecutableMixin
-    implements DeserializedElementZ, ExecutableElement, LocalElement {
-  ExecutableElement _executableContext;
-
-  @override
-  Element get enclosingElement => executableContext;
-
-  @override
-  ClassElementZ get enclosingClass => memberContext.enclosingClass;
-
-  @override
-  ExecutableElement get executableContext {
-    if (_executableContext == null) {
-      _executableContext = _decoder.getElement(Key.EXECUTABLE_CONTEXT);
-    }
-    return _executableContext;
-  }
-
-  @override
-  MemberElement get memberContext => executableContext.memberContext;
-
-  @override
-  bool get isLocal => true;
-
-  @override
-  LibraryElement get library => memberContext.library;
-
-  @override
-  CompilationUnitElement get compilationUnit {
-    return memberContext.compilationUnit;
-  }
-
-  @override
-  bool get hasTreeElements => memberContext.hasTreeElements;
-
-  @override
-  TreeElements get treeElements => memberContext.treeElements;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class LocalFunctionElementZ extends DeserializedElementZ
-    with
-        LocalExecutableMixin,
-        AstElementMixinZ<FunctionExpression>,
-        ParametersMixin,
-        FunctionTypedElementMixin,
-        TypedElementMixin<ResolutionFunctionType>
-    implements LocalFunctionElement {
-  LocalFunctionElementZ(ObjectDecoder decoder) : super(decoder);
-
-  MethodElement callMethod;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitLocalFunctionElement(this, arg);
-  }
-
-  @override
-  ElementKind get kind => ElementKind.FUNCTION;
-
-  @override
-  AsyncMarker get asyncMarker {
-    return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
-  }
-
-  @override
-  bool get isMarkedExternal => false;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class GetterElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<FunctionExpression>,
-        FunctionTypedElementMixin,
-        ParametersMixin,
-        TypedElementMixin<ResolutionFunctionType>,
-        MemberElementMixin
-    implements GetterElement {
-  AbstractFieldElement abstractField;
-  SetterElement setter;
-
-  GetterElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.GETTER;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitGetterElement(this, arg);
-  }
-
-  @override
-  bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
-
-  @override
-  bool get isMarkedExternal => isExternal;
-
-  @override
-  AsyncMarker get asyncMarker {
-    return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
-  }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class TopLevelGetterElementZ extends GetterElementZ with LibraryMemberMixin {
-  TopLevelGetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class StaticGetterElementZ extends GetterElementZ
-    with ClassMemberMixin, StaticMemberMixin {
-  StaticGetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class InstanceGetterElementZ extends GetterElementZ
-    with ClassMemberMixin, InstanceMemberMixin {
-  InstanceGetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class SetterElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<FunctionExpression>,
-        FunctionTypedElementMixin,
-        ParametersMixin,
-        TypedElementMixin<ResolutionFunctionType>,
-        MemberElementMixin
-    implements SetterElement {
-  AbstractFieldElement abstractField;
-  GetterElement getter;
-
-  SetterElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  ElementKind get kind => ElementKind.SETTER;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitSetterElement(this, arg);
-  }
-
-  @override
-  bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
-
-  @override
-  bool get isMarkedExternal => isExternal;
-
-  @override
-  AsyncMarker get asyncMarker => AsyncMarker.SYNC;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class TopLevelSetterElementZ extends SetterElementZ with LibraryMemberMixin {
-  TopLevelSetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class StaticSetterElementZ extends SetterElementZ
-    with ClassMemberMixin, StaticMemberMixin {
-  StaticSetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class InstanceSetterElementZ extends SetterElementZ
-    with ClassMemberMixin, InstanceMemberMixin {
-  InstanceSetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-abstract class TypeDeclarationMixin
-    implements ElementZ, TypeDeclarationElement {
-  List<ResolutionDartType> _typeVariables;
-  GenericType _rawType;
-  GenericType _thisType;
-  Name _memberName;
-
-  Name get memberName {
-    if (_memberName == null) {
-      _memberName = new Name(name, library);
-    }
-    return _memberName;
-  }
-
-  List<ResolutionDartType> _getTypeVariables();
-
-  void _ensureTypes() {
-    if (_typeVariables == null) {
-      _typeVariables = _getTypeVariables();
-      _rawType = _createType(new List<ResolutionDartType>.filled(
-          _typeVariables.length, const ResolutionDynamicType()));
-      _thisType = _createType(_typeVariables);
-    }
-  }
-
-  GenericType _createType(List<ResolutionDartType> typeArguments);
-
-  @override
-  List<ResolutionDartType> get typeVariables {
-    _ensureTypes();
-    return _typeVariables;
-  }
-
-  @override
-  GenericType get rawType {
-    _ensureTypes();
-    return _rawType;
-  }
-
-  @override
-  GenericType get thisType {
-    _ensureTypes();
-    return _thisType;
-  }
-
-  @override
-  GenericType computeType(Resolution resolution) => thisType;
-
-  @override
-  bool get isResolved => true;
-}
-
-class TypedefElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<Node>,
-        LibraryMemberMixin,
-        ParametersMixin,
-        TypeDeclarationMixin
-    implements TypedefElement {
-  ResolutionDartType _alias;
-
-  TypedefElementZ(ObjectDecoder decoder) : super(decoder);
-
-  ResolutionTypedefType _createType(List<ResolutionDartType> typeArguments) {
-    return new ResolutionTypedefType(this, typeArguments);
-  }
-
-  @override
-  List<ResolutionDartType> _getTypeVariables() {
-    return _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
-  }
-
-  @override
-  ElementKind get kind => ElementKind.TYPEDEF;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitTypedefElement(this, arg);
-  }
-
-  @override
-  ResolutionDartType get alias {
-    if (_alias == null) {
-      _alias = _decoder.getType(Key.ALIAS);
-    }
-    return _alias;
-  }
-
-  @override
-  void ensureResolved(Resolution resolution) {}
-
-  @override
-  void checkCyclicReference(Resolution resolution) {}
-
-  ResolutionTypedefType get thisType => super.thisType;
-
-  ResolutionTypedefType get rawType => super.rawType;
-}
-
-class TypeVariableElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<Node>,
-        TypedElementMixin<ResolutionTypeVariableType>
-    implements TypeVariableElement {
-  GenericElement _typeDeclaration;
-  ResolutionTypeVariableType _type;
-  ResolutionDartType _bound;
-  Name _memberName;
-
-  TypeVariableElementZ(ObjectDecoder decoder) : super(decoder);
-
-  Name get memberName {
-    if (_memberName == null) {
-      _memberName = new Name(name, library);
-    }
-    return _memberName;
-  }
-
-  @override
-  ElementKind get kind => ElementKind.TYPE_VARIABLE;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitTypeVariableElement(this, arg);
-  }
-
-  @override
-  CompilationUnitElement get compilationUnit {
-    return typeDeclaration.compilationUnit;
-  }
-
-  @override
-  Element get enclosingElement => typeDeclaration;
-
-  @override
-  ClassElementZ get enclosingClass => typeDeclaration;
-
-  @override
-  int get index => _decoder.getInt(Key.INDEX);
-
-  @override
-  GenericElement get typeDeclaration {
-    if (_typeDeclaration == null) {
-      _typeDeclaration = _decoder.getElement(Key.TYPE_DECLARATION);
-    }
-    return _typeDeclaration;
-  }
-
-  ResolutionDartType get bound {
-    if (_bound == null) {
-      _bound = _decoder.getType(Key.BOUND);
-    }
-    return _bound;
-  }
-
-  @override
-  LibraryElement get library => typeDeclaration.library;
-}
-
-class SyntheticTypeVariableElementZ extends ElementZ
-    with AnalyzableElementMixin, AstElementMixinZ<Node>
-    implements TypeVariableElement {
-  final TypeDeclarationElement typeDeclaration;
-  final int index;
-  final String name;
-  ResolutionTypeVariableType _type;
-  ResolutionDartType _bound;
-  Name _memberName;
-
-  SyntheticTypeVariableElementZ(this.typeDeclaration, this.index, this.name);
-
-  Name get memberName {
-    if (_memberName == null) {
-      _memberName = new Name(name, library);
-    }
-    return _memberName;
-  }
-
-  @override
-  ElementKind get kind => ElementKind.TYPE_VARIABLE;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitTypeVariableElement(this, arg);
-  }
-
-  @override
-  CompilationUnitElement get compilationUnit {
-    return typeDeclaration.compilationUnit;
-  }
-
-  @override
-  ResolutionTypeVariableType get type {
-    assert(_type != null,
-        failedAt(this, "Type variable type has not been set on $this."));
-    return _type;
-  }
-
-  @override
-  ResolutionTypeVariableType computeType(Resolution resolution) => type;
-
-  @override
-  Element get enclosingElement => typeDeclaration;
-
-  @override
-  ClassElementZ get enclosingClass => typeDeclaration;
-
-  ResolutionDartType get bound {
-    assert(_bound != null,
-        failedAt(this, "Type variable bound has not been set on $this."));
-    return _bound;
-  }
-
-  @override
-  LibraryElement get library => typeDeclaration.library;
-
-  @override
-  int get sourceOffset => typeDeclaration.sourceOffset;
-
-  @override
-  SourceSpan get sourcePosition => typeDeclaration.sourcePosition;
-}
-
-abstract class ParameterElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<VariableDefinitions>,
-        TypedElementMixin
-    implements ParameterElement {
-  FunctionElement _functionDeclaration;
-  ConstantExpression _constant;
-  ResolutionDartType _type;
-
-  ParameterElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  bool get isFinal => _decoder.getBool(Key.IS_FINAL);
-
-  @override
-  bool get isConst => false;
-
-  @override
-  bool get hasConstant => true;
-
-  @override
-  ConstantExpression get constant {
-    if (isOptional) {
-      if (_constant == null) {
-        _constant = _decoder.getConstant(Key.CONSTANT);
-      }
-      return _constant;
-    }
-    return null;
-  }
-
-  @override
-  CompilationUnitElement get compilationUnit {
-    return functionDeclaration.compilationUnit;
-  }
-
-  @override
-  ExecutableElement get executableContext => functionDeclaration;
-
-  @override
-  Element get enclosingElement => functionDeclaration;
-
-  @override
-  FunctionElement get functionDeclaration {
-    if (_functionDeclaration == null) {
-      _functionDeclaration = _decoder.getElement(Key.FUNCTION);
-    }
-    return _functionDeclaration;
-  }
-
-  @override
-  FunctionSignature get functionSignature => _unsupported('functionSignature');
-
-  // TODO(johnniwinther): Remove [initializer] and [node] on
-  // [ParameterElementZ] when the inference does need these.
-  @override
-  Expression initializer;
-
-  @override
-  VariableDefinitions node;
-
-  @override
-  bool get isNamed => _decoder.getBool(Key.IS_NAMED);
-
-  @override
-  bool get isOptional => _decoder.getBool(Key.IS_OPTIONAL);
-
-  @override
-  LibraryElement get library => executableContext.library;
-
-  @override
-  MemberElement get memberContext => executableContext.memberContext;
-
-  @override
-  List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-}
-
-class LocalParameterElementZ extends ParameterElementZ
-    implements LocalParameterElement {
-  LocalParameterElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitParameterElement(this, arg);
-  }
-
-  @override
-  bool get isLocal => true;
-
-  @override
-  ElementKind get kind => ElementKind.PARAMETER;
-
-  @override
-  bool get isUnnamed => false;
-}
-
-class InitializingFormalElementZ extends LocalParameterElementZ
-    implements InitializingFormalElement {
-  FieldElement _fieldElement;
-
-  InitializingFormalElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  FieldElement get fieldElement {
-    if (_fieldElement == null) {
-      _fieldElement = _decoder.getElement(Key.FIELD);
-    }
-    return _fieldElement;
-  }
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitFieldParameterElement(this, arg);
-  }
-
-  @override
-  ElementKind get kind => ElementKind.INITIALIZING_FORMAL;
-
-  @override
-  bool get isLocal => true;
-
-  ConstructorElementZ get functionDeclaration => super.functionDeclaration;
-}
-
-class LocalVariableElementZ extends DeserializedElementZ
-    with
-        AnalyzableElementMixin,
-        AstElementMixinZ<VariableDefinitions>,
-        LocalExecutableMixin,
-        TypedElementMixin
-    implements LocalVariableElement {
-  bool _isConst;
-  ConstantExpression _constant;
-
-  LocalVariableElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitLocalVariableElement(this, arg);
-  }
-
-  @override
-  ElementKind get kind => ElementKind.VARIABLE;
-
-  @override
-  bool get isFinal => _decoder.getBool(Key.IS_FINAL);
-
-  @override
-  bool get isConst {
-    if (_isConst == null) {
-      _constant = _decoder.getConstant(Key.CONSTANT, isOptional: true);
-      _isConst = _constant != null;
-    }
-    return _isConst;
-  }
-
-  @override
-  bool get hasConstant => true;
-
-  @override
-  ConstantExpression get constant {
-    if (isConst) {
-      return _constant;
-    }
-    return null;
-  }
-
-  @override
-  Expression get initializer => _unsupported('initializer');
-}
-
-class ImportElementZ extends DeserializedElementZ
-    with LibraryMemberMixin
-    implements ImportElement {
-  bool _isDeferred;
-  PrefixElement _prefix;
-  LibraryElement _importedLibrary;
-  Uri _uri;
-
-  ImportElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  String get name => '';
-
-  @override
-  accept(ElementVisitor visitor, arg) => visitor.visitImportElement(this, arg);
-
-  @override
-  ElementKind get kind => ElementKind.IMPORT;
-
-  @override
-  LibraryElement get importedLibrary {
-    if (_importedLibrary == null) {
-      _importedLibrary = _decoder.getElement(Key.LIBRARY_DEPENDENCY);
-    }
-    return _importedLibrary;
-  }
-
-  void _ensurePrefixResolved() {
-    if (_isDeferred == null) {
-      _isDeferred = _decoder.getBool(Key.IS_DEFERRED);
-      _prefix = _decoder.getElement(Key.PREFIX, isOptional: true);
-    }
-  }
-
-  LibraryElement get enclosingLibrary => library;
-
-  @override
-  bool get isDeferred {
-    _ensurePrefixResolved();
-    return _isDeferred;
-  }
-
-  @override
-  PrefixElement get prefix {
-    _ensurePrefixResolved();
-    return _prefix;
-  }
-
-  @override
-  Uri get uri {
-    if (_uri == null) {
-      _uri = _decoder.getUri(Key.URI);
-    }
-    return _uri;
-  }
-
-  @override
-  Import get node => _unsupported('node');
-
-  String toString() => 'Z$kind($uri)';
-}
-
-class ExportElementZ extends DeserializedElementZ
-    with LibraryMemberMixin
-    implements ExportElement {
-  LibraryElement _exportedLibrary;
-  Uri _uri;
-
-  ExportElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  String get name => '';
-
-  @override
-  accept(ElementVisitor visitor, arg) => visitor.visitExportElement(this, arg);
-
-  @override
-  ElementKind get kind => ElementKind.EXPORT;
-
-  @override
-  LibraryElement get exportedLibrary {
-    if (_exportedLibrary == null) {
-      _exportedLibrary = _decoder.getElement(Key.LIBRARY_DEPENDENCY);
-    }
-    return _exportedLibrary;
-  }
-
-  @override
-  Uri get uri {
-    if (_uri == null) {
-      _uri = _decoder.getUri(Key.URI);
-    }
-    return _uri;
-  }
-
-  @override
-  Export get node => _unsupported('node');
-
-  String toString() => 'Z$kind($uri)';
-}
-
-class PrefixElementZ extends DeserializedElementZ
-    with LibraryMemberMixin
-    implements PrefixElement {
-  bool _isDeferred;
-  ImportElement _deferredImport;
-  GetterElement _loadLibrary;
-  ListedContainer _members;
-
-  PrefixElementZ(ObjectDecoder decoder) : super(decoder);
-
-  @override
-  accept(ElementVisitor visitor, arg) => visitor.visitPrefixElement(this, arg);
-
-  @override
-  bool get isTopLevel => false;
-
-  void _ensureDeferred() {
-    if (_isDeferred == null) {
-      _isDeferred = _decoder.getBool(Key.IS_DEFERRED);
-      if (_isDeferred) {
-        _deferredImport = _decoder.getElement(Key.IMPORT);
-        _loadLibrary = _decoder.getElement(Key.GETTER);
-      }
-    }
-  }
-
-  @override
-  ImportElement get deferredImport {
-    _ensureDeferred();
-    return _deferredImport;
-  }
-
-  @override
-  bool get isDeferred {
-    _ensureDeferred();
-    return _isDeferred;
-  }
-
-  @override
-  GetterElement get loadLibrary {
-    return _loadLibrary;
-  }
-
-  @override
-  ElementKind get kind => ElementKind.PREFIX;
-
-  void _ensureMembers() {
-    if (_members == null) {
-      _members = new ListedContainer(
-          _decoder.getElements(Key.MEMBERS, isOptional: true));
-    }
-  }
-
-  @override
-  Element lookupLocalMember(String memberName) {
-    _ensureMembers();
-    return _members.lookup(memberName);
-  }
-
-  @override
-  void forEachLocalMember(void f(Element member)) {
-    _ensureMembers();
-    _members.forEach(f);
-  }
-}
-
-class MetadataAnnotationZ implements MetadataAnnotation {
-  final Element annotatedElement;
-  final SourceSpan sourcePosition;
-  final ConstantExpression constant;
-
-  MetadataAnnotationZ(
-      this.annotatedElement, this.sourcePosition, this.constant);
-
-  @override
-  MetadataAnnotation ensureResolved(Resolution resolution) {
-    // Do nothing.
-    return this;
-  }
-
-  @override
-  Node get node => throw new UnsupportedError('${this}.node');
-
-  @override
-  bool get hasNode => false;
-
-  String toString() => 'MetadataAnnotationZ(${constant.toDartText()})';
-}
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
deleted file mode 100644
index 3983391..0000000
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ /dev/null
@@ -1,718 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.resolved_ast;
-
-import 'package:front_end/src/fasta/parser.dart' show Parser, ParserError;
-import 'package:front_end/src/fasta/scanner.dart';
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../constants/expressions.dart';
-import '../diagnostics/diagnostic_listener.dart';
-import '../elements/elements.dart';
-import '../elements/jumps.dart';
-import '../elements/modelx.dart';
-import '../elements/resolution_types.dart';
-import '../parser/node_listener.dart' show NodeListener;
-import '../resolution/enum_creator.dart';
-import '../resolution/send_structure.dart';
-import '../resolution/tree_elements.dart';
-import '../tree/tree.dart';
-import '../universe/selector.dart';
-import 'keys.dart';
-import 'modelz.dart';
-import 'serialization.dart';
-import 'serialization_util.dart';
-
-/// Visitor that computes a node-index mapping.
-class AstIndexComputer extends Visitor {
-  final Map<Node, int> nodeIndices = <Node, int>{};
-  final List<Node> nodeList = <Node>[];
-
-  @override
-  visitNode(Node node) {
-    nodeIndices.putIfAbsent(node, () {
-      // Some nodes (like Modifier and empty NodeList) can be reused.
-      nodeList.add(node);
-      return nodeIndices.length;
-    });
-    node.visitChildren(this);
-  }
-}
-
-/// The kind of AST node. Used for determining how to deserialize
-/// [ResolvedAst]s.
-enum AstKind {
-  ENUM_CONSTRUCTOR,
-  ENUM_CONSTANT,
-  ENUM_INDEX_FIELD,
-  ENUM_NAME_FIELD,
-  ENUM_VALUES_FIELD,
-  ENUM_TO_STRING,
-  FACTORY,
-  FIELD,
-  FUNCTION,
-}
-
-/// Serializer for [ResolvedAst]s.
-class ResolvedAstSerializer extends Visitor {
-  final SerializerPlugin nativeDataSerializer;
-  final ObjectEncoder objectEncoder;
-  final ResolvedAst resolvedAst;
-  final AstIndexComputer indexComputer = new AstIndexComputer();
-  final Map<int, ObjectEncoder> nodeData = <int, ObjectEncoder>{};
-  ListEncoder _nodeDataEncoder;
-
-  ResolvedAstSerializer(
-      this.objectEncoder, this.resolvedAst, this.nativeDataSerializer);
-
-  AstElement get element => resolvedAst.element;
-
-  TreeElements get elements => resolvedAst.elements;
-
-  Node get root => resolvedAst.node;
-
-  Map<Node, int> get nodeIndices => indexComputer.nodeIndices;
-  List<Node> get nodeList => indexComputer.nodeList;
-
-  Map<JumpTarget, int> jumpTargetMap = <JumpTarget, int>{};
-  Map<LabelDefinition, int> labelDefinitionMap = <LabelDefinition, int>{};
-
-  /// Returns the unique id for [jumpTarget], creating it if necessary.
-  int getJumpTargetId(JumpTarget jumpTarget) {
-    return jumpTargetMap.putIfAbsent(jumpTarget, () => jumpTargetMap.length);
-  }
-
-  /// Returns the unique id for [labelDefinition], creating it if necessary.
-  int getLabelDefinitionId(LabelDefinition labelDefinition) {
-    return labelDefinitionMap.putIfAbsent(
-        labelDefinition, () => labelDefinitionMap.length);
-  }
-
-  /// Serializes [resolvedAst] into [objectEncoder].
-  void serialize() {
-    objectEncoder.setEnum(Key.KIND, resolvedAst.kind);
-    switch (resolvedAst.kind) {
-      case ResolvedAstKind.PARSED:
-        serializeParsed();
-        break;
-      case ResolvedAstKind.DEFAULT_CONSTRUCTOR:
-      case ResolvedAstKind.FORWARDING_CONSTRUCTOR:
-      case ResolvedAstKind.DEFERRED_LOAD_LIBRARY:
-        // No additional properties.
-        break;
-    }
-  }
-
-  /// Serialize [ResolvedAst] that is defined in terms of an AST together with
-  /// [TreeElements].
-  void serializeParsed() {
-    objectEncoder.setUri(Key.URI, resolvedAst.sourceUri, resolvedAst.sourceUri);
-    AstKind kind;
-    if (element.enclosingClass is EnumClassElement) {
-      if (element.name == 'index') {
-        kind = AstKind.ENUM_INDEX_FIELD;
-      } else if (element.name == '_name') {
-        kind = AstKind.ENUM_NAME_FIELD;
-      } else if (element.name == 'values') {
-        kind = AstKind.ENUM_VALUES_FIELD;
-      } else if (element.name == 'toString') {
-        kind = AstKind.ENUM_TO_STRING;
-      } else if (element.isConstructor) {
-        kind = AstKind.ENUM_CONSTRUCTOR;
-      } else {
-        assert(element.isConst,
-            failedAt(element, "Unexpected enum member: $element"));
-        kind = AstKind.ENUM_CONSTANT;
-      }
-    } else {
-      // [element] has a body that we'll need to re-parse. We store where to
-      // start parsing from.
-      objectEncoder.setInt(Key.OFFSET, root.getBeginToken().charOffset);
-      if (element.isFactoryConstructor) {
-        kind = AstKind.FACTORY;
-      } else if (element.isField) {
-        kind = AstKind.FIELD;
-      } else {
-        kind = AstKind.FUNCTION;
-        FunctionExpression functionExpression = root.asFunctionExpression();
-        if (functionExpression.getOrSet != null) {
-          // Getters/setters need the get/set token to be parsed.
-          objectEncoder.setInt(
-              Key.GET_OR_SET, functionExpression.getOrSet.charOffset);
-        }
-      }
-    }
-    objectEncoder.setEnum(Key.SUB_KIND, kind);
-    root.accept(indexComputer);
-    objectEncoder.setBool(Key.CONTAINS_TRY, elements.containsTryStatement);
-    if (resolvedAst.body != null) {
-      int index = nodeIndices[resolvedAst.body];
-      assert(
-          index != null,
-          failedAt(
-              element,
-              "No index for body of $element: "
-              "${resolvedAst.body} ($nodeIndices)."));
-      objectEncoder.setInt(Key.BODY, index);
-    }
-    root.accept(this);
-    if (jumpTargetMap.isNotEmpty) {
-      ListEncoder list = objectEncoder.createList(Key.JUMP_TARGETS);
-      for (JumpTarget jumpTarget in jumpTargetMap.keys) {
-        serializeJumpTarget(jumpTarget, list.createObject());
-      }
-    }
-    if (labelDefinitionMap.isNotEmpty) {
-      ListEncoder list = objectEncoder.createList(Key.LABEL_DEFINITIONS);
-      for (LabelDefinition labelDefinition in labelDefinitionMap.keys) {
-        serializeLabelDefinition(labelDefinition, list.createObject());
-      }
-    }
-
-    if (element is FunctionElement) {
-      serializeParameterNodes(element);
-    }
-  }
-
-  void serializeParameterNodes(FunctionElement function) {
-    function.functionSignature.forEachParameter((_parameter) {
-      ParameterElement parameter = _parameter;
-      ParameterElement parameterImpl = parameter.implementation;
-      // TODO(johnniwinther): Should we support element->node mapping as well?
-      getNodeDataEncoder(parameterImpl.node)
-          .setElement(PARAMETER_NODE, parameter);
-      if (parameter.initializer != null) {
-        getNodeDataEncoder(parameterImpl.initializer)
-            .setElement(PARAMETER_INITIALIZER, parameter);
-      }
-    });
-  }
-
-  /// Serialize [target] into [encoder].
-  void serializeJumpTarget(JumpTargetX jumpTarget, ObjectEncoder encoder) {
-    encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext);
-    encoder.setInt(Key.NODE, nodeIndices[jumpTarget.statement]);
-    encoder.setInt(Key.NESTING_LEVEL, jumpTarget.nestingLevel);
-    encoder.setBool(Key.IS_BREAK_TARGET, jumpTarget.isBreakTarget);
-    encoder.setBool(Key.IS_CONTINUE_TARGET, jumpTarget.isContinueTarget);
-    if (jumpTarget.labels.isNotEmpty) {
-      List<int> labelIdList = <int>[];
-      for (LabelDefinition label in jumpTarget.labels) {
-        labelIdList.add(getLabelDefinitionId(label));
-      }
-      encoder.setInts(Key.LABELS, labelIdList);
-    }
-  }
-
-  /// Serialize [label] into [encoder].
-  void serializeLabelDefinition(
-      LabelDefinitionX labelDefinition, ObjectEncoder encoder) {
-    encoder.setInt(Key.NODE, nodeIndices[labelDefinition.label]);
-    encoder.setString(Key.NAME, labelDefinition.labelName);
-    encoder.setBool(Key.IS_BREAK_TARGET, labelDefinition.isBreakTarget);
-    encoder.setBool(Key.IS_CONTINUE_TARGET, labelDefinition.isContinueTarget);
-    encoder.setInt(Key.JUMP_TARGET, getJumpTargetId(labelDefinition.target));
-  }
-
-  /// Computes the [ListEncoder] for serializing data for nodes.
-  ListEncoder get nodeDataEncoder {
-    if (_nodeDataEncoder == null) {
-      _nodeDataEncoder = objectEncoder.createList(Key.DATA);
-    }
-    return _nodeDataEncoder;
-  }
-
-  /// Computes the [ObjectEncoder] for serializing data for [node].
-  ObjectEncoder getNodeDataEncoder(Node node) {
-    assert(node != null, failedAt(element, "Node must be non-null."));
-    int id = nodeIndices[node];
-    assert(id != null, failedAt(element, "Node without id: $node"));
-    return nodeData.putIfAbsent(id, () {
-      ObjectEncoder objectEncoder = nodeDataEncoder.createObject();
-      objectEncoder.setInt(Key.ID, id);
-      return objectEncoder;
-    });
-  }
-
-  @override
-  visitNode(Node node) {
-    Element nodeElement = elements[node];
-    if (nodeElement != null) {
-      serializeElementReference(element, Key.ELEMENT, Key.NAME,
-          getNodeDataEncoder(node), nodeElement);
-    }
-    ResolutionDartType type = elements.getType(node);
-    if (type != null) {
-      getNodeDataEncoder(node).setType(Key.TYPE, type);
-    }
-    Selector selector = elements.getSelector(node);
-    if (selector != null) {
-      serializeSelector(
-          selector, getNodeDataEncoder(node).createObject(Key.SELECTOR));
-    }
-    ConstantExpression constant = elements.getConstant(node);
-    if (constant != null) {
-      getNodeDataEncoder(node).setConstant(Key.CONSTANT, constant);
-    }
-    ResolutionDartType cachedType = elements.typesCache[node];
-    if (cachedType != null) {
-      getNodeDataEncoder(node).setType(Key.CACHED_TYPE, cachedType);
-    }
-    JumpTarget jumpTargetDefinition = elements.getTargetDefinition(node);
-    if (jumpTargetDefinition != null) {
-      getNodeDataEncoder(node).setInt(
-          Key.JUMP_TARGET_DEFINITION, getJumpTargetId(jumpTargetDefinition));
-    }
-    var nativeData = elements.getNativeData(node);
-    if (nativeData != null) {
-      nativeDataSerializer.onData(
-          nativeData, getNodeDataEncoder(node).createObject(Key.NATIVE));
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  visitSend(Send node) {
-    visitExpression(node);
-    SendStructure structure = elements.getSendStructure(node);
-    if (structure != null) {
-      serializeSendStructure(
-          structure, getNodeDataEncoder(node).createObject(Key.SEND_STRUCTURE));
-    }
-  }
-
-  @override
-  visitNewExpression(NewExpression node) {
-    visitExpression(node);
-    NewStructure structure = elements.getNewStructure(node);
-    if (structure != null) {
-      serializeNewStructure(
-          structure, getNodeDataEncoder(node).createObject(Key.NEW_STRUCTURE));
-    }
-  }
-
-  @override
-  visitGotoStatement(GotoStatement node) {
-    visitStatement(node);
-    JumpTarget jumpTarget = elements.getTargetOf(node);
-    if (jumpTarget != null) {
-      getNodeDataEncoder(node)
-          .setInt(Key.JUMP_TARGET, getJumpTargetId(jumpTarget));
-    }
-    if (node.target != null) {
-      LabelDefinition targetLabel = elements.getTargetLabel(node);
-      if (targetLabel != null) {
-        getNodeDataEncoder(node)
-            .setInt(Key.TARGET_LABEL, getLabelDefinitionId(targetLabel));
-      }
-    }
-  }
-
-  @override
-  visitLabel(Label node) {
-    visitNode(node);
-    LabelDefinition labelDefinition = elements.getLabelDefinition(node);
-    if (labelDefinition != null) {
-      getNodeDataEncoder(node)
-          .setInt(Key.LABEL_DEFINITION, getLabelDefinitionId(labelDefinition));
-    }
-  }
-
-  @override
-  visitFunctionExpression(FunctionExpression node) {
-    visitExpression(node);
-    Element function = elements.getFunctionDefinition(node);
-    if (function != null && function.isFunction && function.isLocal) {
-      // Mark root nodes of local functions; these need their own ResolvedAst.
-      getNodeDataEncoder(node).setElement(Key.FUNCTION, function);
-      serializeParameterNodes(function);
-    }
-  }
-}
-
-class ResolvedAstDeserializer {
-  /// Find the [Token] at [offset] searching through successors of [token].
-  static Token findTokenInStream(Token token, int offset) {
-    while (token.charOffset <= offset && token.next != token) {
-      if (token.charOffset == offset) {
-        return token;
-      }
-      token = token.next;
-    }
-    return null;
-  }
-
-  /// Deserializes the [ResolvedAst]s for [element] and its nested local
-  /// functions from [objectDecoder] and adds these to [resolvedAstMap].
-  /// [parsing] and [getBeginToken] are used for parsing the [Node] for
-  /// [element] from its source code.
-  static void deserialize(
-      Element element,
-      ObjectDecoder objectDecoder,
-      ParsingContext parsing,
-      Token getBeginToken(Uri uri, int charOffset),
-      DeserializerPlugin nativeDataDeserializer) {
-    ResolvedAstKind kind =
-        objectDecoder.getEnum(Key.KIND, ResolvedAstKind.values);
-    switch (kind) {
-      case ResolvedAstKind.PARSED:
-        deserializeParsed(element, objectDecoder, parsing, getBeginToken,
-            nativeDataDeserializer);
-        break;
-      case ResolvedAstKind.DEFAULT_CONSTRUCTOR:
-      case ResolvedAstKind.FORWARDING_CONSTRUCTOR:
-        (element as AstElementMixinZ).resolvedAst =
-            new SynthesizedResolvedAst(element, kind);
-        break;
-      case ResolvedAstKind.DEFERRED_LOAD_LIBRARY:
-        break;
-    }
-  }
-
-  /// Deserialize the [ResolvedAst]s for the member [element] (constructor,
-  /// method, or field) and its nested closures. The [ResolvedAst]s are added
-  /// to [resolvedAstMap].
-  static void deserializeParsed(
-      AstElementMixinZ element,
-      ObjectDecoder objectDecoder,
-      ParsingContext parsing,
-      Token getBeginToken(Uri uri, int charOffset),
-      DeserializerPlugin nativeDataDeserializer) {
-    DiagnosticReporter reporter = parsing.reporter;
-    Uri uri = objectDecoder.getUri(Key.URI);
-
-    /// Returns the first [Token] for parsing the [Node] for [element].
-    Token readBeginToken() {
-      int charOffset = objectDecoder.getInt(Key.OFFSET);
-      Token beginToken = getBeginToken(uri, charOffset);
-      if (beginToken == null) {
-        // TODO(johnniwinther): Handle unfound tokens by adding an erroneous
-        // resolved ast kind.
-        reporter.internalError(
-            element, "No token found for $element in $uri @ $charOffset");
-      }
-      return beginToken;
-    }
-
-    /// Create the [Node] for the element by parsing the source code.
-    Node doParse(parse(Parser parser)) {
-      return parsing.measure(() {
-        return reporter.withCurrentElement(element, () {
-          NodeListener listener = new NodeListener(
-              parsing.getScannerOptionsFor(element), reporter, null);
-          listener.memberErrors = listener.memberErrors.prepend(false);
-          try {
-            Parser parser = new Parser(listener);
-            parse(parser);
-          } on ParserError catch (e) {
-            reporter.internalError(element, '$e');
-          }
-          return listener.popNode();
-        });
-      });
-    }
-
-    /// Computes the [Node] for the element based on the [AstKind].
-    // ignore: MISSING_RETURN
-    Node computeNode(AstKind kind) {
-      switch (kind) {
-        case AstKind.ENUM_INDEX_FIELD:
-          AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
-          Identifier identifier = builder.identifier('index');
-          VariableDefinitions node = new VariableDefinitions(
-              null,
-              builder.modifiers(isFinal: true),
-              new NodeList.singleton(identifier));
-          return node;
-        case AstKind.ENUM_NAME_FIELD:
-          AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
-          Identifier identifier = builder.identifier('_name');
-          VariableDefinitions node = new VariableDefinitions(
-              null,
-              builder.modifiers(isFinal: true),
-              new NodeList.singleton(identifier));
-          return node;
-        case AstKind.ENUM_VALUES_FIELD:
-          EnumClassElement enumClass = element.enclosingClass;
-          AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
-          List<Node> valueReferences = <Node>[];
-          for (EnumConstantElement enumConstant in enumClass.enumValues) {
-            AstBuilder valueBuilder =
-                new AstBuilder(enumConstant.sourcePosition.begin);
-            Identifier name = valueBuilder.identifier(enumConstant.name);
-
-            // Add reference for the `values` field.
-            valueReferences.add(valueBuilder.reference(name));
-          }
-
-          Identifier valuesIdentifier = builder.identifier('values');
-          // TODO(johnniwinther): Add type argument.
-          Expression initializer =
-              builder.listLiteral(valueReferences, isConst: true);
-
-          Node definition =
-              builder.createDefinition(valuesIdentifier, initializer);
-          VariableDefinitions node = new VariableDefinitions(
-              null,
-              builder.modifiers(isStatic: true, isConst: true),
-              new NodeList.singleton(definition));
-          return node;
-        case AstKind.ENUM_TO_STRING:
-          EnumClassElement enumClass = element.enclosingClass;
-          AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
-          List<LiteralMapEntry> mapEntries = <LiteralMapEntry>[];
-          for (EnumConstantElement enumConstant in enumClass.enumValues) {
-            AstBuilder valueBuilder =
-                new AstBuilder(enumConstant.sourcePosition.begin);
-            Identifier name = valueBuilder.identifier(enumConstant.name);
-
-            // Add map entry for `toString` implementation.
-            mapEntries.add(valueBuilder.mapLiteralEntry(
-                valueBuilder.literalInt(enumConstant.index),
-                valueBuilder
-                    .literalString('${enumClass.name}.${name.source}')));
-          }
-
-          // TODO(johnniwinther): Support return type. Note `String` might be
-          // prefixed or not imported within the current library.
-          FunctionExpression toStringNode = builder.functionExpression(
-              Modifiers.EMPTY,
-              'toString',
-              null,
-              builder.argumentList([]),
-              builder.returnStatement(
-                  builder.reference(builder.identifier('_name'))));
-          return toStringNode;
-        case AstKind.ENUM_CONSTRUCTOR:
-          AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
-          VariableDefinitions indexDefinition =
-              builder.initializingFormal('index');
-          VariableDefinitions nameDefinition =
-              builder.initializingFormal('_name');
-          FunctionExpression constructorNode = builder.functionExpression(
-              builder.modifiers(isConst: true),
-              element.enclosingClass.name,
-              null,
-              builder.argumentList([indexDefinition, nameDefinition]),
-              builder.emptyStatement());
-          return constructorNode;
-        case AstKind.ENUM_CONSTANT:
-          EnumConstantElementZ enumConstant = element;
-          EnumClassElement enumClass = element.enclosingClass;
-          int index = enumConstant.index;
-          AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
-          Identifier name = builder.identifier(element.name);
-
-          String enumString = "${enumClass.name}.${element.name}";
-          Expression initializer = builder.newExpression(
-              enumClass.name,
-              builder.argumentList([
-                builder.literalInt(index),
-                builder.literalString(enumString)
-              ]),
-              isConst: true);
-          SendSet definition = builder.createDefinition(name, initializer);
-
-          VariableDefinitions node = new VariableDefinitions(
-              null,
-              builder.modifiers(isStatic: true, isConst: true),
-              new NodeList.singleton(definition));
-          return node;
-        case AstKind.FACTORY:
-          Token beginToken = readBeginToken();
-          return doParse((parser) => parser.parseClassMember(beginToken));
-        case AstKind.FIELD:
-          Token beginToken = readBeginToken();
-          return doParse((parser) => parser.parseClassMember(beginToken));
-        case AstKind.FUNCTION:
-          Token beginToken = readBeginToken();
-          int getOrSetOffset =
-              objectDecoder.getInt(Key.GET_OR_SET, isOptional: true);
-          Token getOrSet;
-          if (getOrSetOffset != null) {
-            getOrSet = findTokenInStream(beginToken, getOrSetOffset);
-            if (getOrSet == null) {
-              reporter.internalError(
-                  element,
-                  "No token found for $element in "
-                  "${uri} @ $getOrSetOffset");
-            }
-          }
-          return doParse((parser) {
-            parser.parseClassMember(beginToken);
-          });
-      }
-    }
-
-    AstKind kind = objectDecoder.getEnum(Key.SUB_KIND, AstKind.values);
-    Node root = computeNode(kind);
-    TreeElementMapping elements = new TreeElementMapping(element);
-    AstIndexComputer indexComputer = new AstIndexComputer();
-    List<Node> nodeList = indexComputer.nodeList;
-    root.accept(indexComputer);
-    elements.containsTryStatement = objectDecoder.getBool(Key.CONTAINS_TRY);
-
-    Node body;
-    int bodyNodeIndex = objectDecoder.getInt(Key.BODY, isOptional: true);
-    if (bodyNodeIndex != null) {
-      assert(
-          bodyNodeIndex < nodeList.length,
-          failedAt(
-              element,
-              "Body node index ${bodyNodeIndex} out of range. "
-              "Node count: ${nodeList.length}"));
-      body = nodeList[bodyNodeIndex];
-    }
-
-    List<JumpTarget> jumpTargets = <JumpTarget>[];
-    Map<JumpTarget, List<int>> jumpTargetLabels = <JumpTarget, List<int>>{};
-    List<LabelDefinition> labelDefinitions = <LabelDefinition>[];
-
-    ListDecoder jumpTargetsDecoder =
-        objectDecoder.getList(Key.JUMP_TARGETS, isOptional: true);
-    if (jumpTargetsDecoder != null) {
-      for (int i = 0; i < jumpTargetsDecoder.length; i++) {
-        ObjectDecoder decoder = jumpTargetsDecoder.getObject(i);
-        ExecutableElement executableContext =
-            decoder.getElement(Key.EXECUTABLE_CONTEXT);
-        Node statement = nodeList[decoder.getInt(Key.NODE)];
-        int nestingLevel = decoder.getInt(Key.NESTING_LEVEL);
-        JumpTargetX jumpTarget =
-            new JumpTargetX(statement, nestingLevel, executableContext);
-        jumpTarget.isBreakTarget = decoder.getBool(Key.IS_BREAK_TARGET);
-        jumpTarget.isContinueTarget = decoder.getBool(Key.IS_CONTINUE_TARGET);
-        jumpTargetLabels[jumpTarget] =
-            decoder.getInts(Key.LABELS, isOptional: true);
-        jumpTargets.add(jumpTarget);
-      }
-    }
-
-    ListDecoder labelDefinitionsDecoder =
-        objectDecoder.getList(Key.LABEL_DEFINITIONS, isOptional: true);
-    if (labelDefinitionsDecoder != null) {
-      for (int i = 0; i < labelDefinitionsDecoder.length; i++) {
-        ObjectDecoder decoder = labelDefinitionsDecoder.getObject(i);
-        Label label = nodeList[decoder.getInt(Key.NODE)];
-        String labelName = decoder.getString(Key.NAME);
-        JumpTarget target = jumpTargets[decoder.getInt(Key.JUMP_TARGET)];
-        LabelDefinitionX labelDefinition =
-            new LabelDefinitionX(label, labelName, target);
-        labelDefinition.isBreakTarget = decoder.getBool(Key.IS_BREAK_TARGET);
-        labelDefinition.isContinueTarget =
-            decoder.getBool(Key.IS_CONTINUE_TARGET);
-        labelDefinitions.add(labelDefinition);
-      }
-    }
-    jumpTargetLabels.forEach((JumpTarget jumpTarget, List<int> labelIds) {
-      if (labelIds.isEmpty) return;
-      List<LabelDefinition> labels = <LabelDefinition>[];
-      for (int labelId in labelIds) {
-        labels.add(labelDefinitions[labelId]);
-      }
-      JumpTargetX target = jumpTarget;
-      target.labels = labels;
-    });
-
-    ListDecoder dataDecoder = objectDecoder.getList(Key.DATA, isOptional: true);
-    if (dataDecoder != null) {
-      for (int i = 0; i < dataDecoder.length; i++) {
-        ObjectDecoder objectDecoder = dataDecoder.getObject(i);
-        int id = objectDecoder.getInt(Key.ID);
-        Node node = nodeList[id];
-        Element nodeElement = deserializeElementReference(
-            element, Key.ELEMENT, Key.NAME, objectDecoder,
-            isOptional: true);
-        if (nodeElement != null) {
-          elements[node] = nodeElement;
-        }
-        ResolutionDartType type =
-            objectDecoder.getType(Key.TYPE, isOptional: true);
-        if (type != null) {
-          elements.setType(node, type);
-        }
-        ObjectDecoder selectorDecoder =
-            objectDecoder.getObject(Key.SELECTOR, isOptional: true);
-        if (selectorDecoder != null) {
-          elements.setSelector(node, deserializeSelector(selectorDecoder));
-        }
-        ConstantExpression constant =
-            objectDecoder.getConstant(Key.CONSTANT, isOptional: true);
-        if (constant != null) {
-          elements.setConstant(node, constant);
-        }
-        ResolutionDartType cachedType =
-            objectDecoder.getType(Key.CACHED_TYPE, isOptional: true);
-        if (cachedType != null) {
-          elements.typesCache[node] = cachedType;
-        }
-        ObjectDecoder sendStructureDecoder =
-            objectDecoder.getObject(Key.SEND_STRUCTURE, isOptional: true);
-        if (sendStructureDecoder != null) {
-          elements.setSendStructure(
-              node, deserializeSendStructure(sendStructureDecoder));
-        }
-        ObjectDecoder newStructureDecoder =
-            objectDecoder.getObject(Key.NEW_STRUCTURE, isOptional: true);
-        if (newStructureDecoder != null) {
-          elements.setNewStructure(
-              node, deserializeNewStructure(newStructureDecoder));
-        }
-        int targetDefinitionId =
-            objectDecoder.getInt(Key.JUMP_TARGET_DEFINITION, isOptional: true);
-        if (targetDefinitionId != null) {
-          elements.defineTarget(node, jumpTargets[targetDefinitionId]);
-        }
-        int targetOfId =
-            objectDecoder.getInt(Key.JUMP_TARGET, isOptional: true);
-        if (targetOfId != null) {
-          elements.registerTargetOf(node, jumpTargets[targetOfId]);
-        }
-        int labelDefinitionId =
-            objectDecoder.getInt(Key.LABEL_DEFINITION, isOptional: true);
-        if (labelDefinitionId != null) {
-          elements.defineLabel(node, labelDefinitions[labelDefinitionId]);
-        }
-        int targetLabelId =
-            objectDecoder.getInt(Key.TARGET_LABEL, isOptional: true);
-        if (targetLabelId != null) {
-          elements.registerTargetLabel(node, labelDefinitions[targetLabelId]);
-        }
-        ObjectDecoder nativeDataDecoder =
-            objectDecoder.getObject(Key.NATIVE, isOptional: true);
-        if (nativeDataDecoder != null) {
-          var nativeData = nativeDataDeserializer.onData(nativeDataDecoder);
-          if (nativeData != null) {
-            elements.registerNativeData(node, nativeData);
-          }
-        }
-        LocalFunctionElementZ function =
-            objectDecoder.getElement(Key.FUNCTION, isOptional: true);
-        if (function != null) {
-          FunctionExpression functionExpression = node;
-          function.resolvedAst = new ParsedResolvedAst(function,
-              functionExpression, functionExpression.body, elements, uri);
-        }
-        // TODO(johnniwinther): Remove these when inference doesn't need `.node`
-        // and `.initializer` of [ParameterElement]s.
-        ParameterElementZ parameter =
-            objectDecoder.getElement(PARAMETER_NODE, isOptional: true);
-        if (parameter != null) {
-          parameter.node = node;
-        }
-        parameter =
-            objectDecoder.getElement(PARAMETER_INITIALIZER, isOptional: true);
-        if (parameter != null) {
-          parameter.initializer = node;
-        }
-      }
-    }
-    element.resolvedAst =
-        new ParsedResolvedAst(element, root, body, elements, uri);
-  }
-}
-
-const Key PARAMETER_NODE = const Key('parameter.node');
-const Key PARAMETER_INITIALIZER = const Key('parameter.initializer');
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
deleted file mode 100644
index 592687e..0000000
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ /dev/null
@@ -1,1163 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization;
-
-import 'package:front_end/src/scanner/token.dart' show TokenType;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../library_loader.dart' show LibraryProvider;
-import '../util/enumset.dart';
-import 'constant_serialization.dart';
-import 'element_serialization.dart';
-import 'json_serializer.dart';
-import 'keys.dart';
-import 'type_serialization.dart';
-import 'values.dart';
-
-export 'task.dart' show LibraryDeserializer;
-
-final Map<String, String> canonicalNames = computeCanonicalNames();
-
-Map<String, String> computeCanonicalNames() {
-  Map<String, String> result = <String, String>{};
-  for (TokenType type in TokenType.all) {
-    result[type.value] = type.value;
-  }
-  return result;
-}
-
-/// An object that supports the encoding an [ObjectValue] for serialization.
-///
-/// The [ObjectEncoder] ensures that nominality and circularities of
-/// non-primitive values like [Element], [ResolutionDartType] and
-/// [ConstantExpression] are handled.
-class ObjectEncoder extends AbstractEncoder<Key> {
-  /// Creates an [ObjectEncoder] in the scope of [serializer] that uses [map]
-  /// as its internal storage.
-  ObjectEncoder(Serializer serializer, Map<dynamic, Value> map)
-      : super(serializer, map);
-
-  String get _name => 'Object';
-}
-
-/// An object that supports the encoding a [MapValue] for serialization.
-///
-/// The [MapEncoder] ensures that nominality and circularities of
-/// non-primitive values like [Element], [ResolutionDartType] and
-/// [ConstantExpression] are handled.
-class MapEncoder extends AbstractEncoder<String> {
-  /// Creates an [MapEncoder] in the scope of [serializer] that uses [map]
-  /// as its internal storage.
-  MapEncoder(Serializer serializer, Map<String, Value> map)
-      : super(serializer, map);
-
-  String get _name => 'Map';
-}
-
-/// An object that supports the encoding a [ListValue] containing [ObjectValue]s
-/// or [MapValue]s.
-///
-/// The [ListEncoder] ensures that nominality and circularities of
-/// non-primitive values like [Element], [ResolutionDartType] and
-/// [ConstantExpression] are handled.
-class ListEncoder {
-  final Serializer _serializer;
-  final List<Value> _list;
-
-  /// Creates an [ListEncoder] in the scope of [_serializer] that uses [_list]
-  /// as its internal storage.
-  ListEncoder(this._serializer, this._list);
-
-  /// Creates an [ObjectEncoder] and adds it to the encoded list.
-  ObjectEncoder createObject() {
-    Map<Key, Value> map = <Key, Value>{};
-    _list.add(new ObjectValue(map));
-    return new ObjectEncoder(_serializer, map);
-  }
-
-  /// Creates an [ObjectEncoder] and adds it to the encoded list.
-  MapEncoder createMap() {
-    Map<String, Value> map = {};
-    _list.add(new MapValue(map));
-    return new MapEncoder(_serializer, map);
-  }
-}
-
-/// Abstract base implementation for [ObjectEncoder] and [MapEncoder].
-abstract class AbstractEncoder<K> {
-  final Serializer _serializer;
-  final Map<K, Value> _map;
-
-  AbstractEncoder(this._serializer, this._map);
-
-  /// The name of the encoder kind. Use for error reporting.
-  String get _name;
-
-  void _checkKey(K key) {
-    if (_map.containsKey(key)) {
-      throw new StateError("$_name value '$key' already in $_map.");
-    }
-  }
-
-  /// Maps the [key] entry to the [value] in the encoded object.
-  void setValue(K key, Value value) {
-    _checkKey(key);
-    _map[key] = value;
-  }
-
-  /// Maps the [key] entry to the enum [value] in the encoded object.
-  void setEnum(K key, var value) {
-    _checkKey(key);
-    _map[key] = new EnumValue(value);
-  }
-
-  /// Maps the [key] entry to the set of enum [values] in the encoded object.
-  void setEnums(K key, Iterable values) {
-    setEnumSet(key, new EnumSet.fromValues(values));
-  }
-
-  /// Maps the [key] entry to the enum [set] in the encoded object.
-  void setEnumSet(K key, EnumSet set) {
-    _checkKey(key);
-    _map[key] = new IntValue(set.value);
-  }
-
-  /// Maps the [key] entry to the [element] in the encoded object.
-  void setElement(K key, Element element) {
-    _checkKey(key);
-    _map[key] = _serializer.createElementValue(element);
-  }
-
-  /// Maps the [key] entry to the [elements] in the encoded object.
-  ///
-  /// If [elements] is empty, it is skipped.
-  void setElements(K key, Iterable<Element> elements) {
-    _checkKey(key);
-    if (elements.isNotEmpty) {
-      _map[key] =
-          new ListValue(elements.map(_serializer.createElementValue).toList());
-    }
-  }
-
-  /// Maps the [key] entry to the [constant] in the encoded object.
-  void setConstant(K key, ConstantExpression constant) {
-    _checkKey(key);
-    _map[key] = _serializer.createConstantValue(constant);
-  }
-
-  /// Maps the [key] entry to the [constants] in the encoded object.
-  ///
-  /// If [constants] is empty, it is skipped.
-  void setConstants(K key, Iterable<ConstantExpression> constants) {
-    _checkKey(key);
-    if (constants.isNotEmpty) {
-      _map[key] = new ListValue(
-          constants.map(_serializer.createConstantValue).toList());
-    }
-  }
-
-  /// Maps the [key] entry to the [type] in the encoded object.
-  void setType(K key, ResolutionDartType type) {
-    _checkKey(key);
-    _map[key] = _serializer.createTypeValue(type);
-  }
-
-  /// Maps the [key] entry to the [types] in the encoded object.
-  ///
-  /// If [types] is empty, it is skipped.
-  void setTypes(K key, Iterable<ResolutionDartType> types) {
-    _checkKey(key);
-    if (types.isNotEmpty) {
-      _map[key] =
-          new ListValue(types.map(_serializer.createTypeValue).toList());
-    }
-  }
-
-  /// Maps the [key] entry to the [uri] in the encoded object using [baseUri] to
-  /// relatives the encoding.
-  ///
-  /// For instance, a source file like `sdk/lib/core/string.dart` should be
-  /// serialized relative to the library root.
-  void setUri(K key, Uri baseUri, Uri uri) {
-    _checkKey(key);
-    _map[key] = new UriValue(baseUri, uri);
-  }
-
-  /// Maps the [key] entry to the string [value] in the encoded object.
-  void setString(K key, String value) {
-    _checkKey(key);
-    _map[key] = new StringValue(value);
-  }
-
-  /// Maps the [key] entry to the string [values] in the encoded object.
-  ///
-  /// If [values] is empty, it is skipped.
-  void setStrings(K key, Iterable<String> values) {
-    _checkKey(key);
-    if (values.isNotEmpty) {
-      _map[key] = new ListValue(values.map((v) => new StringValue(v)).toList());
-    }
-  }
-
-  /// Maps the [key] entry to the bool [value] in the encoded object.
-  void setBool(K key, bool value) {
-    _checkKey(key);
-    _map[key] = new BoolValue(value);
-  }
-
-  /// Maps the [key] entry to the int [value] in the encoded object.
-  void setInt(K key, int value) {
-    _checkKey(key);
-    _map[key] = new IntValue(value);
-  }
-
-  /// Maps the [key] entry to the int [values] in this serializer.
-  ///
-  /// If [values] is empty, it is skipped.
-  void setInts(K key, Iterable<int> values) {
-    _checkKey(key);
-    if (values.isNotEmpty) {
-      _map[key] = new ListValue(values.map((v) => new IntValue(v)).toList());
-    }
-  }
-
-  /// Maps the [key] entry to the double [value] in the encoded object.
-  void setDouble(K key, double value) {
-    _checkKey(key);
-    _map[key] = new DoubleValue(value);
-  }
-
-  /// Creates and returns an [ObjectEncoder] that is mapped to the [key]
-  /// entry in the encoded object.
-  ObjectEncoder createObject(K key) {
-    Map<Key, Value> map = <Key, Value>{};
-    _map[key] = new ObjectValue(map);
-    return new ObjectEncoder(_serializer, map);
-  }
-
-  /// Creates and returns a [MapEncoder] that is mapped to the [key] entry
-  /// in the encoded object.
-  MapEncoder createMap(K key) {
-    Map<String, Value> map = <String, Value>{};
-    _map[key] = new MapValue(map);
-    return new MapEncoder(_serializer, map);
-  }
-
-  /// Creates and returns a [ListEncoder] that is mapped to the [key] entry
-  /// in the encoded object.
-  ListEncoder createList(K key) {
-    List<Value> list = <Value>[];
-    _map[key] = new ListValue(list);
-    return new ListEncoder(_serializer, list);
-  }
-
-  String toString() => _map.toString();
-}
-
-/// [ObjectDecoder] reads serialized values from a [Map] encoded from an
-/// [ObjectValue] where properties are stored using [Key] values as keys.
-class ObjectDecoder extends AbstractDecoder<dynamic, Key> {
-  /// Creates an [ObjectDecoder] that decodes [map] into deserialized values
-  /// using [deserializer] to create canonicalized values.
-  ObjectDecoder(Deserializer deserializer, Map map) : super(deserializer, map);
-
-  @override
-  _getKeyValue(Key key) => _deserializer.decoder.getObjectPropertyValue(key);
-}
-
-/// [MapDecoder] reads serialized values from a [Map] encoded from an
-/// [MapValue] where entries are stored using [String] values as keys.
-class MapDecoder extends AbstractDecoder<String, String> {
-  /// Creates an [MapDecoder] that decodes [map] into deserialized values
-  /// using [deserializer] to create canonicalized values.
-  MapDecoder(Deserializer deserializer, Map<String, dynamic> map)
-      : super(deserializer, map);
-
-  @override
-  String _getKeyValue(String key) => key;
-
-  /// Applies [f] to every key in the decoded [Map].
-  void forEachKey(f(String key)) {
-    _map.keys.forEach(f);
-  }
-}
-
-/// [ListDecoder] reads serialized map or object values from a [List].
-class ListDecoder {
-  final Deserializer _deserializer;
-  final List _list;
-
-  /// Creates a [ListDecoder] that decodes [_list] using [_deserializer] to
-  /// create canonicalized values.
-  ListDecoder(this._deserializer, this._list);
-
-  /// The number of values in the decoded list.
-  int get length => _list.length;
-
-  /// Returns an [ObjectDecoder] for the [index]th object value in the decoded
-  /// list.
-  ObjectDecoder getObject(int index) {
-    return new ObjectDecoder(_deserializer, _list[index]);
-  }
-
-  /// Returns an [MapDecoder] for the [index]th map value in the decoded list.
-  MapDecoder getMap(int index) {
-    return new MapDecoder(_deserializer, _list[index]);
-  }
-}
-
-/// Abstract base implementation for [ObjectDecoder] and [MapDecoder].
-abstract class AbstractDecoder<M, K> {
-  final Deserializer _deserializer;
-  final Map<M, dynamic> _map;
-
-  AbstractDecoder(this._deserializer, this._map) {
-    assert(_deserializer != null);
-    assert(_map != null);
-  }
-
-  /// Returns the value for [key] defined by the [SerializationDecoder] in used
-  /// [_deserializer].
-  M _getKeyValue(K key);
-
-  /// Returns `true` if [key] has an associated value in the decoded object.
-  bool containsKey(K key) => _map.containsKey(_getKeyValue(key));
-
-  /// Returns the enum value from the [enumValues] associated with [key] in the
-  /// decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// [defaultValue] is returned, otherwise an exception is thrown.
-  getEnum(K key, List enumValues, {bool isOptional: false, defaultValue}) {
-    int value = _map[_getKeyValue(key)];
-    if (value == null) {
-      if (isOptional || defaultValue != null) {
-        return defaultValue;
-      }
-      throw new StateError("enum value '$key' not found in $_map.");
-    }
-    return enumValues[value];
-  }
-
-  /// Returns the set of enum values associated with [key] in the decoded
-  /// object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// [defaultValue] is returned, otherwise an exception is thrown.
-  EnumSet getEnums(K key, {bool isOptional: false}) {
-    int value = _map[_getKeyValue(key)];
-    if (value == null) {
-      if (isOptional) {
-        return const EnumSet.fixed(0);
-      }
-      throw new StateError("enum values '$key' not found in $_map.");
-    }
-    return new EnumSet.fixed(value);
-  }
-
-  /// Returns the [Element] value associated with [key] in the decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// `null` is returned, otherwise an exception is thrown.
-  Element getElement(K key, {bool isOptional: false}) {
-    int id = _map[_getKeyValue(key)];
-    if (id == null) {
-      if (isOptional) {
-        return null;
-      }
-      throw new StateError("Element value '$key' not found in $_map.");
-    }
-    return _deserializer.deserializeElement(id);
-  }
-
-  /// Returns the list of [Element] values associated with [key] in the decoded
-  /// object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// and empty [List] is returned, otherwise an exception is thrown.
-  List<Element> getElements(K key, {bool isOptional: false}) {
-    List<int> list = _map[_getKeyValue(key)];
-    if (list == null) {
-      if (isOptional) {
-        return const [];
-      }
-      throw new StateError("Elements value '$key' not found in $_map.");
-    }
-    return list.map(_deserializer.deserializeElement).toList();
-  }
-
-  /// Returns the [ConstantExpression] value associated with [key] in the
-  /// decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// `null` is returned, otherwise an exception is thrown.
-  ConstantExpression getConstant(K key, {bool isOptional: false}) {
-    int id = _map[_getKeyValue(key)];
-    if (id == null) {
-      if (isOptional) {
-        return null;
-      }
-      throw new StateError("Constant value '$key' not found in $_map.");
-    }
-    return _deserializer.deserializeConstant(id);
-  }
-
-  /// Returns the list of [ConstantExpression] values associated with [key] in
-  /// the decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// and empty [List] is returned, otherwise an exception is thrown.
-  List<ConstantExpression> getConstants(K key, {bool isOptional: false}) {
-    List<int> list = _map[_getKeyValue(key)];
-    if (list == null) {
-      if (isOptional) {
-        return const [];
-      }
-      throw new StateError("Constants value '$key' not found in $_map.");
-    }
-    return list.map(_deserializer.deserializeConstant).toList();
-  }
-
-  /// Returns the [ResolutionDartType] value associated with [key] in the
-  /// decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// `null` is returned, otherwise an exception is thrown.
-  ResolutionDartType getType(K key, {bool isOptional: false}) {
-    int id = _map[_getKeyValue(key)];
-    if (id == null) {
-      if (isOptional) {
-        return null;
-      }
-      throw new StateError("Type value '$key' not found in $_map.");
-    }
-    return _deserializer.deserializeType(id);
-  }
-
-  /// Returns the list of [ResolutionDartType] values associated with [key] in
-  /// the decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// and empty [List] is returned, otherwise an exception is thrown.
-  List<ResolutionDartType> getTypes(K key, {bool isOptional: false}) {
-    List<int> list = _map[_getKeyValue(key)];
-    if (list == null) {
-      if (isOptional) {
-        return const [];
-      }
-      throw new StateError("Types value '$key' not found in $_map.");
-    }
-    return list.map(_deserializer.deserializeType).toList();
-  }
-
-  /// Returns the [Uri] value associated with [key] in the decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// [defaultValue] is returned, otherwise an exception is thrown.
-  Uri getUri(K key, {bool isOptional: false, Uri defaultValue}) {
-    String value = _map[_getKeyValue(key)];
-    if (value == null) {
-      if (isOptional || defaultValue != null) {
-        return defaultValue;
-      }
-      throw new StateError("Uri value '$key' not found in $_map.");
-    }
-    return Uri.parse(value);
-  }
-
-  /// Returns the [String] value associated with [key] in the decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// [defaultValue] is returned, otherwise an exception is thrown.
-  String getString(K key, {bool isOptional: false, String defaultValue}) {
-    String value = _map[_getKeyValue(key)];
-    if (value == null) {
-      if (isOptional || defaultValue != null) {
-        return defaultValue;
-      }
-      throw new StateError("String value '$key' not found in $_map.");
-    }
-    return canonicalNames[value] ?? value;
-  }
-
-  /// Returns the list of [String] values associated with [key] in the decoded
-  /// object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// and empty [List] is returned, otherwise an exception is thrown.
-  List<String> getStrings(K key, {bool isOptional: false}) {
-    List list = _map[_getKeyValue(key)];
-    if (list == null) {
-      if (isOptional) {
-        return const [];
-      }
-      throw new StateError("Strings value '$key' not found in $_map.");
-    }
-    return list;
-  }
-
-  /// Returns the [bool] value associated with [key] in the decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// [defaultValue] is returned, otherwise an exception is thrown.
-  bool getBool(K key, {bool isOptional: false, bool defaultValue}) {
-    bool value = _map[_getKeyValue(key)];
-    if (value == null) {
-      if (isOptional || defaultValue != null) {
-        return defaultValue;
-      }
-      throw new StateError("bool value '$key' not found in $_map.");
-    }
-    return value;
-  }
-
-  /// Returns the [int] value associated with [key] in the decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// [defaultValue] is returned, otherwise an exception is thrown.
-  int getInt(K key, {bool isOptional: false, int defaultValue}) {
-    int value = _map[_getKeyValue(key)];
-    if (value == null) {
-      if (isOptional || defaultValue != null) {
-        return defaultValue;
-      }
-      throw new StateError("int value '$key' not found in $_map.");
-    }
-    return value;
-  }
-
-  /// Returns the list of [int] values associated with [key] in the decoded
-  /// object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// and empty [List] is returned, otherwise an exception is thrown.
-  List<int> getInts(K key, {bool isOptional: false}) {
-    List list = _map[_getKeyValue(key)];
-    if (list == null) {
-      if (isOptional) {
-        return const [];
-      }
-      throw new StateError("Ints value '$key' not found in $_map.");
-    }
-    return list;
-  }
-
-  /// Returns the [double] value associated with [key] in the decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// [defaultValue] is returned, otherwise an exception is thrown.
-  double getDouble(K key, {bool isOptional: false, double defaultValue}) {
-    var value = _map[_getKeyValue(key)];
-    if (value == null) {
-      if (isOptional || defaultValue != null) {
-        return defaultValue;
-      }
-      throw new StateError("double value '$key' not found in $_map.");
-    }
-    // Support alternative encoding of NaN and +/- infinity for JSON.
-    if (value == 'NaN') {
-      return double.NAN;
-    } else if (value == '-Infinity') {
-      return double.NEGATIVE_INFINITY;
-    } else if (value == 'Infinity') {
-      return double.INFINITY;
-    }
-    return value;
-  }
-
-  /// Returns an [ObjectDecoder] for the map value associated with [key] in the
-  /// decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// `null` is returned, otherwise an exception is thrown.
-  ObjectDecoder getObject(K key, {bool isOptional: false}) {
-    Map map = _map[_getKeyValue(key)];
-    if (map == null) {
-      if (isOptional) {
-        return null;
-      }
-      throw new StateError("Object value '$key' not found in $_map.");
-    }
-    return new ObjectDecoder(_deserializer, map);
-  }
-
-  /// Returns an [MapDecoder] for the map value associated with [key] in the
-  /// decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// `null` is returned, otherwise an exception is thrown.
-  MapDecoder getMap(K key, {bool isOptional: false}) {
-    Map map = _map[_getKeyValue(key)];
-    if (map == null) {
-      if (isOptional) {
-        return null;
-      }
-      throw new StateError("Map value '$key' not found in $_map.");
-    }
-    return new MapDecoder(_deserializer, map);
-  }
-
-  /// Returns an [ListDecoder] for the list value associated with [key] in the
-  /// decoded object.
-  ///
-  /// If no value is associated with [key], then if [isOptional] is `true`,
-  /// `null` is returned, otherwise an exception is thrown.
-  ListDecoder getList(K key, {bool isOptional: false}) {
-    List list = _map[_getKeyValue(key)];
-    if (list == null) {
-      if (isOptional) {
-        return null;
-      }
-      throw new StateError("List value '$key' not found in $_map.");
-    }
-    return new ListDecoder(_deserializer, list);
-  }
-}
-
-/// A nominal object containing its serialized value.
-class DataObject {
-  /// The id for the object.
-  final Value id;
-
-  /// The serialized value of the object.
-  final ObjectValue objectValue;
-
-  DataObject(Value id, EnumValue kind)
-      : this.id = id,
-        this.objectValue =
-            new ObjectValue(<Key, Value>{Key.ID: id, Key.KIND: kind});
-
-  Map<Key, Value> get map => objectValue.map;
-}
-
-/// Function used to filter which element serialized.
-typedef bool ElementMatcher(Element element);
-
-bool includeAllElements(Element element) => true;
-
-/// Serializer for the transitive closure of a collection of libraries.
-///
-/// The serializer creates an [ObjectValue] model of the [Element],
-/// [ResolutionDartType] and [ConstantExpression] values in the transitive
-/// closure of the serialized libraries.
-///
-/// The model layout of the produced [objectValue] is:
-///
-///     { // Header object
-///       Key.ELEMENTS: [
-///         {...}, // [ObjectValue] of the 0th [Element].
-///         ...
-///         {...}, // [ObjectValue] of the n-th [Element].
-///       ],
-///       Key.TYPES: [
-///         {...}, // [ObjectValue] of the 0th [DartType].
-///         ...
-///         {...}, // [ObjectValue] of the n-th [DartType].
-///       ],
-///       Key.CONSTANTS: [
-///         {...}, // [ObjectValue] of the 0th [ConstantExpression].
-///         ...
-///         {...}, // [ObjectValue] of the n-th [ConstantExpression].
-///       ],
-///     }
-///
-// TODO(johnniwinther): Support dependencies between serialized subcomponent.
-class Serializer {
-  List<SerializerPlugin> plugins = <SerializerPlugin>[];
-
-  Map<Element, DataObject> _elementMap = <Element, DataObject>{};
-  Map<ConstantExpression, DataObject> _constantMap =
-      <ConstantExpression, DataObject>{};
-  Map<ResolutionDartType, DataObject> _typeMap =
-      <ResolutionDartType, DataObject>{};
-  List _pendingList = [];
-  ElementMatcher shouldInclude;
-
-  // TODO(johnniwinther): Replace [includeElement] with a general strategy.
-  Serializer({this.shouldInclude: includeAllElements});
-
-  /// Add the transitive closure of [library] to this serializer.
-  void serialize(LibraryElement library) {
-    // Call [_getElementId] for its side-effect: To create a
-    // [DataObject] for [library]. If not already created, this will
-    // put the serialization of [library] in the work queue.
-    _getElementId(library);
-  }
-
-  void _emptyWorklist() {
-    while (_pendingList.isNotEmpty) {
-      _pendingList.removeLast()();
-    }
-  }
-
-  /// Returns the id [Value] for [element].
-  ///
-  /// If [element] has no [DataObject], a new [DataObject] is created and
-  /// encoding the [ObjectValue] for [element] is put into the work queue of
-  /// this serializer.
-  Value _getElementId(Element element) {
-    if (element == null) {
-      throw new ArgumentError('Serializer._getElementDataObject(null)');
-    }
-    element = element.declaration;
-    DataObject dataObject = _elementMap[element];
-    if (dataObject == null) {
-      if (!shouldInclude(element)) {
-        /// Helper used to check that external references are serialized by
-        /// the right kind.
-        bool verifyElement(var found, var expected) {
-          if (found == null) return false;
-          found = found.declaration;
-          if (found == expected) return true;
-          if (found.isAbstractField && expected.isGetter) {
-            return found.getter == expected;
-          }
-          if (found.isAbstractField && expected.isSetter) {
-            return found.setter == expected;
-          }
-          return false;
-        }
-
-        if (element.isLibrary) {
-          LibraryElement library = element;
-          _elementMap[element] = dataObject = new DataObject(
-              new IntValue(_elementMap.length),
-              new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY));
-          ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
-          encoder.setUri(Key.URI, library.canonicalUri, library.canonicalUri);
-        } else if (element.isConstructor) {
-          assert(
-              verifyElement(
-                  element.enclosingClass.implementation
-                      .lookupConstructor(element.name),
-                  element),
-              failedAt(
-                  element,
-                  "Element $element is not found as a "
-                  "constructor of ${element.enclosingClass.implementation}."));
-          Value classId = _getElementId(element.enclosingClass);
-          _elementMap[element] = dataObject = new DataObject(
-              new IntValue(_elementMap.length),
-              new EnumValue(SerializedElementKind.EXTERNAL_CONSTRUCTOR));
-          ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
-          encoder.setValue(Key.CLASS, classId);
-          encoder.setString(Key.NAME, element.name);
-        } else if (element.isClassMember) {
-          assert(
-              verifyElement(
-                  element.enclosingClass.lookupLocalMember(element.name),
-                  element),
-              failedAt(
-                  element,
-                  "Element $element is not found as a "
-                  "class member of ${element.enclosingClass}."));
-          Value classId = _getElementId(element.enclosingClass);
-          _elementMap[element] = dataObject = new DataObject(
-              new IntValue(_elementMap.length),
-              new EnumValue(SerializedElementKind.EXTERNAL_CLASS_MEMBER));
-          ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
-          encoder.setValue(Key.CLASS, classId);
-          encoder.setString(Key.NAME, element.name);
-          if (element.isAccessor) {
-            encoder.setBool(Key.GETTER, element.isGetter);
-          }
-        } else {
-          assert(
-              verifyElement(
-                  element.library.implementation.find(element.name), element),
-              failedAt(
-                  element,
-                  "Element $element is not found as a "
-                  "library member of ${element.library.implementation}."));
-          Value libraryId = _getElementId(element.library);
-          _elementMap[element] = dataObject = new DataObject(
-              new IntValue(_elementMap.length),
-              new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY_MEMBER));
-          ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
-          encoder.setValue(Key.LIBRARY, libraryId);
-          encoder.setString(Key.NAME, element.name);
-          if (element.isAccessor) {
-            encoder.setBool(Key.GETTER, element.isGetter);
-          }
-        }
-      } else {
-        // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that
-        // deals with [element].
-        for (ElementSerializer serializer in ELEMENT_SERIALIZERS) {
-          SerializedElementKind kind = serializer.getSerializedKind(element);
-          if (kind != null) {
-            _elementMap[element] = dataObject = new DataObject(
-                new IntValue(_elementMap.length), new EnumValue(kind));
-            // Delay the serialization of the element itself to avoid loops, and
-            // to keep the call stack small.
-            _pendingList.add(() {
-              ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
-              serializer.serialize(element, encoder, kind);
-
-              MapEncoder pluginData;
-              for (SerializerPlugin plugin in plugins) {
-                plugin.onElement(element, (String tag) {
-                  if (pluginData == null) {
-                    pluginData = encoder.createMap(Key.DATA);
-                  }
-                  return pluginData.createObject(tag);
-                });
-              }
-            });
-          }
-        }
-      }
-    }
-    if (dataObject == null) {
-      throw new UnsupportedError(
-          'Unsupported element: $element (${element.kind})');
-    }
-    return dataObject.id;
-  }
-
-  /// Creates the [ElementValue] for [element].
-  ///
-  /// If [element] has not already been serialized, it is added to the work
-  /// queue of this serializer.
-  ElementValue createElementValue(Element element) {
-    return new ElementValue(element, _getElementId(element));
-  }
-
-  /// Returns the id [Value] for [constant].
-  ///
-  /// If [constant] has no [DataObject], a new [DataObject] is created and
-  /// encoding the [ObjectValue] for [constant] is put into the work queue of
-  /// this serializer.
-  Value _getConstantId(ConstantExpression constant) {
-    return _constantMap.putIfAbsent(constant, () {
-      DataObject dataObject = new DataObject(
-          new IntValue(_constantMap.length), new EnumValue(constant.kind));
-      // Delay the serialization of the constant itself to avoid loops, and to
-      // keep the call stack small.
-      _pendingList.add(() => _encodeConstant(constant, dataObject));
-      return dataObject;
-    }).id;
-  }
-
-  /// Encodes [constant] into the [ObjectValue] of [dataObject].
-  void _encodeConstant(ConstantExpression constant, DataObject dataObject) {
-    const ConstantSerializer()
-        .visit(constant, new ObjectEncoder(this, dataObject.map));
-  }
-
-  /// Creates the [ConstantValue] for [constant].
-  ///
-  /// If [constant] has not already been serialized, it is added to the work
-  /// queue of this serializer.
-  ConstantValue createConstantValue(ConstantExpression constant) {
-    return new ConstantValue(constant, _getConstantId(constant));
-  }
-
-  /// Returns the id [Value] for [type].
-  ///
-  /// If [type] has no [DataObject], a new [DataObject] is created and
-  /// encoding the [ObjectValue] for [type] is put into the work queue of this
-  /// serializer.
-  Value _getTypeId(ResolutionDartType type) {
-    DataObject dataObject = _typeMap[type];
-    if (dataObject == null) {
-      _typeMap[type] = dataObject = new DataObject(
-          new IntValue(_typeMap.length), new EnumValue(type.kind));
-      // Delay the serialization of the type itself to avoid loops, and to keep
-      // the call stack small.
-      _pendingList.add(() => _encodeType(type, dataObject));
-    }
-    return dataObject.id;
-  }
-
-  /// Encodes [type] into the [ObjectValue] of [dataObject].
-  void _encodeType(ResolutionDartType type, DataObject dataObject) {
-    const TypeSerializer().visit(type, new ObjectEncoder(this, dataObject.map));
-  }
-
-  /// Creates the [TypeValue] for [type].
-  ///
-  /// If [type] has not already been serialized, it is added to the work
-  /// queue of this serializer.
-  TypeValue createTypeValue(ResolutionDartType type) {
-    return new TypeValue(type, _getTypeId(type));
-  }
-
-  ObjectValue get objectValue {
-    _emptyWorklist();
-
-    Map<Key, Value> map = <Key, Value>{};
-    map[Key.ELEMENTS] =
-        new ListValue(_elementMap.values.map((l) => l.objectValue).toList());
-    if (_typeMap.isNotEmpty) {
-      map[Key.TYPES] =
-          new ListValue(_typeMap.values.map((l) => l.objectValue).toList());
-    }
-    if (_constantMap.isNotEmpty) {
-      map[Key.CONSTANTS] =
-          new ListValue(_constantMap.values.map((l) => l.objectValue).toList());
-    }
-    return new ObjectValue(map);
-  }
-
-  String toText(SerializationEncoder encoder) {
-    return encoder.encode(objectValue);
-  }
-
-  String prettyPrint() {
-    PrettyPrintEncoder encoder = new PrettyPrintEncoder();
-    return encoder.toText(objectValue);
-  }
-}
-
-/// Plugin for serializing additional data for an [Element].
-class SerializerPlugin {
-  const SerializerPlugin();
-
-  /// Called upon the serialization of [element].
-  ///
-  /// Use [creatorEncoder] to create a data object with id [tag] for storing
-  /// additional data for [element].
-  void onElement(Element element, ObjectEncoder createEncoder(String tag)) {}
-
-  /// Called to serialize custom [data].
-  void onData(var data, ObjectEncoder encoder) {}
-}
-
-/// Plugin for deserializing additional data for an [Element].
-class DeserializerPlugin {
-  const DeserializerPlugin();
-
-  /// Called upon the deserialization of [element].
-  ///
-  /// Use [getDecoder] to retrieve the data object with id [tag] stored for
-  /// [element]. If not object is stored for [tag], [getDecoder] returns `null`.
-  void onElement(Element element, ObjectDecoder getDecoder(String tag)) {}
-
-  /// Called to deserialize custom data from [decoder].
-  dynamic onData(ObjectDecoder decoder) => null;
-}
-
-/// Context for parallel deserialization.
-class DeserializationContext {
-  final DiagnosticReporter reporter;
-  final Resolution resolution;
-  final LibraryProvider libraryProvider;
-  Map<Uri, LibraryElement> _uriMap = <Uri, LibraryElement>{};
-  List<Deserializer> deserializers = <Deserializer>[];
-  List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
-
-  DeserializationContext(this.reporter, this.resolution, this.libraryProvider);
-
-  LibraryElement lookupLibrary(Uri uri) {
-    // TODO(johnniwinther): Move this to the library loader by making a
-    // [Deserializer] a [LibraryProvider].
-    return _uriMap.putIfAbsent(uri, () {
-      Uri foundUri;
-      LibraryElement foundLibrary;
-      for (Deserializer deserializer in deserializers) {
-        LibraryElement library = deserializer.lookupLibrary(uri);
-        if (library != null) {
-          if (foundLibrary != null) {
-            reporter.reportErrorMessage(NO_LOCATION_SPANNABLE,
-                MessageKind.DUPLICATE_SERIALIZED_LIBRARY, {
-              'libraryUri': uri,
-              'sourceUri1': foundUri,
-              'sourceUri2': deserializer.sourceUri
-            });
-          }
-          foundUri = deserializer.sourceUri;
-          foundLibrary = library;
-        }
-      }
-      return foundLibrary;
-    });
-  }
-
-  LibraryElement findLibrary(Uri uri) {
-    LibraryElement library = lookupLibrary(uri);
-    return library ?? libraryProvider.lookupLibrary(uri);
-  }
-}
-
-/// Deserializer for a closed collection of libraries.
-// TODO(johnniwinther): Support per-library deserialization and dependencies
-// between deserialized subcomponent.
-class Deserializer {
-  final DeserializationContext context;
-  final SerializationDecoder decoder;
-  final Uri sourceUri;
-  ObjectDecoder _headerObject;
-  ListDecoder _elementList;
-  ListDecoder _typeList;
-  ListDecoder _constantList;
-  Map<int, Element> _elementMap = {};
-  Map<int, ResolutionDartType> _typeMap = {};
-  Map<int, ConstantExpression> _constantMap = {};
-
-  Deserializer.fromText(
-      this.context, this.sourceUri, String text, this.decoder) {
-    _headerObject = new ObjectDecoder(this, decoder.decode(text));
-  }
-
-  /// Returns the [ListDecoder] for the [Element]s in this deserializer.
-  ListDecoder get elements {
-    if (_elementList == null) {
-      _elementList = _headerObject.getList(Key.ELEMENTS);
-    }
-    return _elementList;
-  }
-
-  /// Returns the [ListDecoder] for the [ResolutionDartType]s in this
-  /// deserializer.
-  ListDecoder get types {
-    if (_typeList == null) {
-      _typeList = _headerObject.getList(Key.TYPES);
-    }
-    return _typeList;
-  }
-
-  /// Returns the [ListDecoder] for the [ConstantExpression]s in this
-  /// deserializer.
-  ListDecoder get constants {
-    if (_constantList == null) {
-      _constantList = _headerObject.getList(Key.CONSTANTS);
-    }
-    return _constantList;
-  }
-
-  /// Returns the [LibraryElement] for [uri] if part of the deserializer.
-  LibraryElement lookupLibrary(Uri uri) {
-    // TODO(johnniwinther): Libraries should be stored explicitly in the header.
-    ListDecoder list = elements;
-    for (int i = 0; i < list.length; i++) {
-      ObjectDecoder object = list.getObject(i);
-      SerializedElementKind kind =
-          object.getEnum(Key.KIND, SerializedElementKind.values);
-      if (kind == SerializedElementKind.LIBRARY) {
-        Uri libraryUri = object.getUri(Key.CANONICAL_URI);
-        if (libraryUri == uri) {
-          return deserializeElement(object.getInt(Key.ID));
-        }
-      }
-    }
-    return null;
-  }
-
-  /// Returns the deserialized [Element] for [id].
-  Element deserializeElement(int id) {
-    if (id == null) throw new ArgumentError('Deserializer.getElement(null)');
-    Element element = _elementMap[id];
-    if (element == null) {
-      ObjectDecoder decoder = elements.getObject(id);
-      SerializedElementKind elementKind =
-          decoder.getEnum(Key.KIND, SerializedElementKind.values);
-      if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY) {
-        Uri uri = decoder.getUri(Key.URI);
-        element = context.findLibrary(uri);
-        if (element == null) {
-          throw new StateError("Missing library for $uri.");
-        }
-      } else if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY_MEMBER) {
-        LibraryElement library = decoder.getElement(Key.LIBRARY);
-        String name = decoder.getString(Key.NAME);
-        bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
-        element = library.find(name);
-        if (element == null) {
-          throw new StateError("Missing library member for $name in $library.");
-        }
-        if (isGetter != null) {
-          AbstractFieldElement abstractField = element;
-          element = isGetter ? abstractField.getter : abstractField.setter;
-          if (element == null) {
-            throw new StateError(
-                "Missing ${isGetter ? 'getter' : 'setter'} for "
-                "$name in $library.");
-          }
-        }
-      } else if (elementKind == SerializedElementKind.EXTERNAL_CLASS_MEMBER) {
-        ClassElement cls = decoder.getElement(Key.CLASS);
-        cls.ensureResolved(context.resolution);
-        String name = decoder.getString(Key.NAME);
-        bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
-        element = cls.lookupLocalMember(name);
-        if (element == null) {
-          throw new StateError("Missing class member for $name in $cls.");
-        }
-        if (isGetter != null) {
-          AbstractFieldElement abstractField = element;
-          element = isGetter ? abstractField.getter : abstractField.setter;
-          if (element == null) {
-            throw new StateError(
-                "Missing ${isGetter ? 'getter' : 'setter'} for $name in $cls.");
-          }
-        }
-      } else if (elementKind == SerializedElementKind.EXTERNAL_CONSTRUCTOR) {
-        ClassElement cls = decoder.getElement(Key.CLASS);
-        cls.ensureResolved(context.resolution);
-        String name = decoder.getString(Key.NAME);
-        element = cls.lookupConstructor(name);
-        if (element == null) {
-          throw new StateError("Missing constructor for $name in $cls.");
-        }
-      } else {
-        element = ElementDeserializer.deserialize(decoder, elementKind);
-      }
-      _elementMap[id] = element;
-
-      MapDecoder pluginData = decoder.getMap(Key.DATA, isOptional: true);
-      // Call plugins even when there is no data, so they can take action in
-      // this case.
-      for (DeserializerPlugin plugin in context.plugins) {
-        plugin.onElement(element,
-            (String tag) => pluginData?.getObject(tag, isOptional: true));
-      }
-    }
-    return element;
-  }
-
-  /// Returns the deserialized [ResolutionDartType] for [id].
-  ResolutionDartType deserializeType(int id) {
-    if (id == null) throw new ArgumentError('Deserializer.getType(null)');
-    return _typeMap.putIfAbsent(id, () {
-      return TypeDeserializer.deserialize(types.getObject(id));
-    });
-  }
-
-  /// Returns the deserialized [ConstantExpression] for [id].
-  ConstantExpression deserializeConstant(int id) {
-    if (id == null) throw new ArgumentError('Deserializer.getConstant(null)');
-    return _constantMap.putIfAbsent(id, () {
-      return ConstantDeserializer.deserialize(constants.getObject(id));
-    });
-  }
-}
-
-/// Strategy used by [Serializer] to define the memory and output encoding.
-abstract class SerializationEncoder {
-  /// Encode [objectValue] into text.
-  String encode(ObjectValue objectValue);
-}
-
-/// Strategy used by [Deserializer] for decoding and reading data from a
-/// serialized output.
-abstract class SerializationDecoder {
-  /// Decode [text] into [Map] containing the data corresponding to an encoding
-  /// of the serializer header object.
-  Map decode(String text);
-
-  /// Returns the value used to store [key] as a property in the encoding an
-  /// [ObjectValue].
-  ///
-  /// Different encodings have different restrictions and capabilities as how
-  /// to store a [Key] value. For instance: A JSON encoding needs to convert
-  /// [Key] to a [String] to store it in a JSON object; a Dart encoding can
-  /// choose to store a [Key] as an [int] or as the [Key] itself.
-  getObjectPropertyValue(Key key);
-}
diff --git a/pkg/compiler/lib/src/serialization/serialization_util.dart b/pkg/compiler/lib/src/serialization/serialization_util.dart
deleted file mode 100644
index 16e1e4e..0000000
--- a/pkg/compiler/lib/src/serialization/serialization_util.dart
+++ /dev/null
@@ -1,613 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.util;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../diagnostics/messages.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart' show WrappedMessage;
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../resolution/access_semantics.dart';
-import '../resolution/send_structure.dart';
-import '../universe/call_structure.dart';
-import '../universe/selector.dart';
-import 'keys.dart';
-import 'serialization.dart';
-
-/// Serialize [name] into [encoder].
-void serializeName(Name name, ObjectEncoder encoder) {
-  encoder.setString(Key.NAME, name.text);
-  encoder.setBool(Key.IS_SETTER, name.isSetter);
-  if (name.library != null) {
-    LibraryElement library = name.library;
-    encoder.setElement(Key.LIBRARY, library);
-  }
-}
-
-/// Deserialize a [Name] from [decoder].
-Name deserializeName(ObjectDecoder decoder) {
-  String name = decoder.getString(Key.NAME);
-  bool isSetter = decoder.getBool(Key.IS_SETTER);
-  LibraryElement library = decoder.getElement(Key.LIBRARY, isOptional: true);
-  return new Name(name, library, isSetter: isSetter);
-}
-
-/// Serialize [callStructure] into [encoder].
-void serializeCallStructure(
-    CallStructure callStructure, ObjectEncoder encoder) {
-  encoder.setInt(Key.ARGUMENTS, callStructure.argumentCount);
-  encoder.setStrings(Key.NAMED_ARGUMENTS, callStructure.namedArguments);
-}
-
-/// Serialize [selector] into [encoder].
-void serializeSelector(Selector selector, ObjectEncoder encoder) {
-  encoder.setEnum(Key.KIND, selector.kind);
-  serializeCallStructure(selector.callStructure, encoder);
-  serializeName(selector.memberName, encoder);
-}
-
-/// Deserialize a [CallStructure] from [decoder].
-CallStructure deserializeCallStructure(ObjectDecoder decoder) {
-  int argumentCount = decoder.getInt(Key.ARGUMENTS);
-  List<String> namedArguments =
-      decoder.getStrings(Key.NAMED_ARGUMENTS, isOptional: true);
-  return new CallStructure(argumentCount, namedArguments);
-}
-
-/// Deserialize a [Selector] from [decoder].
-Selector deserializeSelector(ObjectDecoder decoder) {
-  SelectorKind kind = decoder.getEnum(Key.KIND, SelectorKind.values);
-  CallStructure callStructure = deserializeCallStructure(decoder);
-  return new Selector(kind, deserializeName(decoder), callStructure);
-}
-
-/// Serialize [sendStructure] into [encoder].
-void serializeSendStructure(
-    SendStructure sendStructure, ObjectEncoder encoder) {
-  encoder.setEnum(Key.KIND, sendStructure.kind);
-  switch (sendStructure.kind) {
-    case SendStructureKind.IF_NULL:
-    case SendStructureKind.LOGICAL_AND:
-    case SendStructureKind.LOGICAL_OR:
-    case SendStructureKind.NOT:
-    case SendStructureKind.INVALID_UNARY:
-    case SendStructureKind.INVALID_BINARY:
-      // No additional properties.
-      break;
-    case SendStructureKind.IS:
-      IsStructure structure = sendStructure;
-      encoder.setType(Key.TYPE, structure.type);
-      break;
-    case SendStructureKind.IS_NOT:
-      IsNotStructure structure = sendStructure;
-      encoder.setType(Key.TYPE, structure.type);
-      break;
-    case SendStructureKind.AS:
-      AsStructure structure = sendStructure;
-      encoder.setType(Key.TYPE, structure.type);
-      break;
-    case SendStructureKind.INVOKE:
-      InvokeStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
-      break;
-    case SendStructureKind.INCOMPATIBLE_INVOKE:
-      IncompatibleInvokeStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
-      break;
-    case SendStructureKind.GET:
-      GetStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      break;
-    case SendStructureKind.SET:
-      SetStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      break;
-    case SendStructureKind.UNARY:
-      UnaryStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
-      break;
-    case SendStructureKind.INDEX:
-      IndexStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      break;
-    case SendStructureKind.EQUALS:
-      EqualsStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      break;
-    case SendStructureKind.NOT_EQUALS:
-      NotEqualsStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      break;
-    case SendStructureKind.BINARY:
-      BinaryStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
-      break;
-    case SendStructureKind.INDEX_SET:
-      IndexSetStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      break;
-    case SendStructureKind.INDEX_PREFIX:
-      IndexPrefixStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
-      break;
-    case SendStructureKind.INDEX_POSTFIX:
-      IndexPostfixStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
-      break;
-    case SendStructureKind.COMPOUND:
-      CompoundStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
-      break;
-    case SendStructureKind.SET_IF_NULL:
-      SetIfNullStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      break;
-    case SendStructureKind.COMPOUND_INDEX_SET:
-      CompoundIndexSetStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
-      break;
-    case SendStructureKind.INDEX_SET_IF_NULL:
-      IndexSetIfNullStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      break;
-    case SendStructureKind.PREFIX:
-      PrefixStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
-      break;
-    case SendStructureKind.POSTFIX:
-      PostfixStructure structure = sendStructure;
-      serializeAccessSemantics(
-          structure.semantics, encoder.createObject(Key.SEMANTICS));
-      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
-      break;
-    case SendStructureKind.DEFERRED_PREFIX:
-      DeferredPrefixStructure structure = sendStructure;
-      encoder.setElement(Key.PREFIX, structure.prefix);
-      serializeSendStructure(
-          structure.sendStructure, encoder.createObject(Key.SEND_STRUCTURE));
-      break;
-  }
-}
-
-/// Deserialize a [SendStructure] from [decoder].
-// ignore: MISSING_RETURN
-SendStructure deserializeSendStructure(ObjectDecoder decoder) {
-  SendStructureKind kind = decoder.getEnum(Key.KIND, SendStructureKind.values);
-  switch (kind) {
-    case SendStructureKind.IF_NULL:
-      return const IfNullStructure();
-    case SendStructureKind.LOGICAL_AND:
-      return const LogicalAndStructure();
-    case SendStructureKind.LOGICAL_OR:
-      return const LogicalOrStructure();
-    case SendStructureKind.IS:
-      return new IsStructure(decoder.getType(Key.TYPE));
-    case SendStructureKind.IS_NOT:
-      return new IsNotStructure(decoder.getType(Key.TYPE));
-    case SendStructureKind.AS:
-      return new AsStructure(decoder.getType(Key.TYPE));
-    case SendStructureKind.INVOKE:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
-      return new InvokeStructure(semantics, selector);
-    case SendStructureKind.INCOMPATIBLE_INVOKE:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
-      return new IncompatibleInvokeStructure(semantics, selector);
-    case SendStructureKind.GET:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new GetStructure(semantics);
-    case SendStructureKind.SET:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new SetStructure(semantics);
-    case SendStructureKind.NOT:
-      return const NotStructure();
-    case SendStructureKind.UNARY:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new UnaryStructure(
-          semantics,
-          UnaryOperator.fromKind(
-              decoder.getEnum(Key.OPERATOR, UnaryOperatorKind.values)));
-    case SendStructureKind.INVALID_UNARY:
-      return new InvalidUnaryStructure();
-    case SendStructureKind.INDEX:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new IndexStructure(semantics);
-    case SendStructureKind.EQUALS:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new EqualsStructure(semantics);
-    case SendStructureKind.NOT_EQUALS:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new NotEqualsStructure(semantics);
-    case SendStructureKind.BINARY:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new BinaryStructure(
-          semantics,
-          BinaryOperator.fromKind(
-              decoder.getEnum(Key.OPERATOR, BinaryOperatorKind.values)));
-    case SendStructureKind.INVALID_BINARY:
-      return const InvalidBinaryStructure();
-    case SendStructureKind.INDEX_SET:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new IndexSetStructure(semantics);
-    case SendStructureKind.INDEX_PREFIX:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new IndexPrefixStructure(
-          semantics,
-          IncDecOperator.fromKind(
-              decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
-    case SendStructureKind.INDEX_POSTFIX:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new IndexPostfixStructure(
-          semantics,
-          IncDecOperator.fromKind(
-              decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
-    case SendStructureKind.COMPOUND:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new CompoundStructure(
-          semantics,
-          AssignmentOperator.fromKind(
-              decoder.getEnum(Key.OPERATOR, AssignmentOperatorKind.values)));
-    case SendStructureKind.SET_IF_NULL:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new SetIfNullStructure(semantics);
-    case SendStructureKind.COMPOUND_INDEX_SET:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new CompoundIndexSetStructure(
-          semantics,
-          AssignmentOperator.fromKind(
-              decoder.getEnum(Key.OPERATOR, AssignmentOperatorKind.values)));
-    case SendStructureKind.INDEX_SET_IF_NULL:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new IndexSetIfNullStructure(semantics);
-    case SendStructureKind.PREFIX:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new PrefixStructure(
-          semantics,
-          IncDecOperator.fromKind(
-              decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
-    case SendStructureKind.POSTFIX:
-      AccessSemantics semantics =
-          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
-      return new PostfixStructure(
-          semantics,
-          IncDecOperator.fromKind(
-              decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
-    case SendStructureKind.DEFERRED_PREFIX:
-      PrefixElement prefix = decoder.getElement(Key.PREFIX);
-      SendStructure sendStructure =
-          deserializeSendStructure(decoder.getObject(Key.SEND_STRUCTURE));
-      return new DeferredPrefixStructure(prefix, sendStructure);
-  }
-}
-
-/// Serialize [newStructure] into [encoder].
-void serializeNewStructure(NewStructure newStructure, ObjectEncoder encoder) {
-  encoder.setEnum(Key.KIND, newStructure.kind);
-  switch (newStructure.kind) {
-    case NewStructureKind.NEW_INVOKE:
-      NewInvokeStructure structure = newStructure;
-      encoder.setEnum(Key.SUB_KIND, structure.semantics.kind);
-      encoder.setElement(Key.ELEMENT, structure.semantics.element);
-      encoder.setType(Key.TYPE, structure.semantics.type);
-      serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
-      break;
-    case NewStructureKind.CONST_INVOKE:
-      ConstInvokeStructure structure = newStructure;
-      encoder.setEnum(Key.SUB_KIND, structure.constantInvokeKind);
-      encoder.setConstant(Key.CONSTANT, structure.constant);
-      break;
-    case NewStructureKind.LATE_CONST:
-      throw new UnsupportedError(
-          'Unsupported NewStructure kind ${newStructure.kind}.');
-  }
-}
-
-/// Deserialize a [NewStructure] from [decoder].
-// ignore: MISSING_RETURN
-NewStructure deserializeNewStructure(ObjectDecoder decoder) {
-  NewStructureKind kind = decoder.getEnum(Key.KIND, NewStructureKind.values);
-  switch (kind) {
-    case NewStructureKind.NEW_INVOKE:
-      ConstructorAccessKind constructorAccessKind =
-          decoder.getEnum(Key.SUB_KIND, ConstructorAccessKind.values);
-      Element element = decoder.getElement(Key.ELEMENT);
-      ResolutionDartType type = decoder.getType(Key.TYPE);
-      ConstructorAccessSemantics semantics =
-          new ConstructorAccessSemantics(constructorAccessKind, element, type);
-      Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
-      return new NewInvokeStructure(semantics, selector);
-
-    case NewStructureKind.CONST_INVOKE:
-      ConstantInvokeKind constantInvokeKind =
-          decoder.getEnum(Key.SUB_KIND, ConstantInvokeKind.values);
-      ConstantExpression constant = decoder.getConstant(Key.CONSTANT);
-      return new ConstInvokeStructure(constantInvokeKind, constant);
-    case NewStructureKind.LATE_CONST:
-      throw new UnsupportedError('Unsupported NewStructure kind $kind.');
-  }
-}
-
-/// Serialize [semantics] into [encoder].
-void serializeAccessSemantics(
-    AccessSemantics semantics, ObjectEncoder encoder) {
-  encoder.setEnum(Key.KIND, semantics.kind);
-  switch (semantics.kind) {
-    case AccessKind.EXPRESSION:
-    case AccessKind.THIS:
-      // No additional properties.
-      break;
-    case AccessKind.THIS_PROPERTY:
-    case AccessKind.DYNAMIC_PROPERTY:
-    case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-      serializeName(semantics.name, encoder);
-      break;
-    case AccessKind.CLASS_TYPE_LITERAL:
-    case AccessKind.TYPEDEF_TYPE_LITERAL:
-    case AccessKind.DYNAMIC_TYPE_LITERAL:
-      encoder.setConstant(Key.CONSTANT, semantics.constant);
-      break;
-    case AccessKind.LOCAL_FUNCTION:
-    case AccessKind.LOCAL_VARIABLE:
-    case AccessKind.FINAL_LOCAL_VARIABLE:
-    case AccessKind.PARAMETER:
-    case AccessKind.FINAL_PARAMETER:
-    case AccessKind.STATIC_FIELD:
-    case AccessKind.FINAL_STATIC_FIELD:
-    case AccessKind.STATIC_METHOD:
-    case AccessKind.STATIC_GETTER:
-    case AccessKind.STATIC_SETTER:
-    case AccessKind.TOPLEVEL_FIELD:
-    case AccessKind.FINAL_TOPLEVEL_FIELD:
-    case AccessKind.TOPLEVEL_METHOD:
-    case AccessKind.TOPLEVEL_GETTER:
-    case AccessKind.TOPLEVEL_SETTER:
-    case AccessKind.SUPER_FIELD:
-    case AccessKind.SUPER_FINAL_FIELD:
-    case AccessKind.SUPER_METHOD:
-    case AccessKind.SUPER_GETTER:
-    case AccessKind.SUPER_SETTER:
-    case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-    case AccessKind.UNRESOLVED:
-    case AccessKind.UNRESOLVED_SUPER:
-    case AccessKind.INVALID:
-      encoder.setElement(Key.ELEMENT, semantics.element);
-      break;
-    case AccessKind.COMPOUND:
-      CompoundAccessSemantics compoundAccess = semantics;
-      encoder.setEnum(Key.SUB_KIND, compoundAccess.compoundAccessKind);
-      encoder.setElement(Key.GETTER, semantics.getter);
-      encoder.setElement(Key.SETTER, semantics.setter);
-      break;
-    case AccessKind.CONSTANT:
-      throw new UnsupportedError('Unsupported access kind: ${semantics.kind}');
-  }
-}
-
-/// Deserialize a [AccessSemantics] from [decoder].
-// ignore: MISSING_RETURN
-AccessSemantics deserializeAccessSemantics(ObjectDecoder decoder) {
-  AccessKind kind = decoder.getEnum(Key.KIND, AccessKind.values);
-  switch (kind) {
-    case AccessKind.EXPRESSION:
-      return const DynamicAccess.expression();
-    case AccessKind.THIS:
-      return const DynamicAccess.thisAccess();
-    case AccessKind.THIS_PROPERTY:
-      return new DynamicAccess.thisProperty(deserializeName(decoder));
-    case AccessKind.DYNAMIC_PROPERTY:
-      return new DynamicAccess.dynamicProperty(deserializeName(decoder));
-    case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-      return new DynamicAccess.ifNotNullProperty(deserializeName(decoder));
-    case AccessKind.CLASS_TYPE_LITERAL:
-    case AccessKind.TYPEDEF_TYPE_LITERAL:
-    case AccessKind.DYNAMIC_TYPE_LITERAL:
-      return new ConstantAccess(kind, decoder.getConstant(Key.CONSTANT));
-
-    case AccessKind.LOCAL_FUNCTION:
-    case AccessKind.LOCAL_VARIABLE:
-    case AccessKind.FINAL_LOCAL_VARIABLE:
-    case AccessKind.PARAMETER:
-    case AccessKind.FINAL_PARAMETER:
-    case AccessKind.STATIC_FIELD:
-    case AccessKind.FINAL_STATIC_FIELD:
-    case AccessKind.STATIC_METHOD:
-    case AccessKind.STATIC_GETTER:
-    case AccessKind.STATIC_SETTER:
-    case AccessKind.TOPLEVEL_FIELD:
-    case AccessKind.FINAL_TOPLEVEL_FIELD:
-    case AccessKind.TOPLEVEL_METHOD:
-    case AccessKind.TOPLEVEL_GETTER:
-    case AccessKind.TOPLEVEL_SETTER:
-    case AccessKind.SUPER_FIELD:
-    case AccessKind.SUPER_FINAL_FIELD:
-    case AccessKind.SUPER_METHOD:
-    case AccessKind.SUPER_GETTER:
-    case AccessKind.SUPER_SETTER:
-    case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-    case AccessKind.UNRESOLVED:
-    case AccessKind.UNRESOLVED_SUPER:
-    case AccessKind.INVALID:
-      return new StaticAccess.internal(kind, decoder.getElement(Key.ELEMENT));
-
-    case AccessKind.COMPOUND:
-      CompoundAccessKind compoundAccessKind =
-          decoder.getEnum(Key.SUB_KIND, CompoundAccessKind.values);
-      Element getter = decoder.getElement(Key.GETTER);
-      Element setter = decoder.getElement(Key.SETTER);
-      return new CompoundAccessSemantics(compoundAccessKind, getter, setter);
-    case AccessKind.CONSTANT:
-      throw new UnsupportedError('Unsupported access kind: $kind');
-  }
-}
-
-/// Serialize a reference from [context] to an [element] which might be a member
-/// of an unnamed mixin application. If it is, [element] is by serialized
-/// indirectly by name in the [nameKey] of [encoder], otherwise [element] is
-/// serialized directly in [elementKey] in [encoder].
-void serializeElementReference(Element context, Key elementKey, Key nameKey,
-    ObjectEncoder encoder, Element element) {
-  if (element.isGenerativeConstructor &&
-      element.enclosingClass.isUnnamedMixinApplication) {
-    assert(
-        element.isConstructor,
-        failedAt(
-            element,
-            "Unexpected reference of forwarding constructor "
-            "${element} from $context."));
-    encoder.setString(nameKey, element.name);
-  } else {
-    encoder.setElement(elementKey, element);
-  }
-}
-
-/// Deserialize a reference from [context] to an [Element] which might be a
-/// member of an unnamed mixin application. If it is, the [Element] is by
-/// deserialized indirectly by name from [nameKey] in [decoder], otherwise
-/// the [Element] is deserialized directly from [elementKey] in [encoder].
-Element deserializeElementReference(
-    Element context, Key elementKey, Key nameKey, ObjectDecoder decoder,
-    {bool isOptional: false}) {
-  Element element = decoder.getElement(elementKey, isOptional: true);
-  if (element == null) {
-    String elementName = decoder.getString(nameKey, isOptional: isOptional);
-    if (elementName == null) {
-      return null;
-    }
-    ClassElement cls;
-    if (context is ClassElement) {
-      assert(
-          context.isNamedMixinApplication,
-          failedAt(
-              NO_LOCATION_SPANNABLE,
-              "Unexpected reference of forwarding constructor "
-              "'${elementName}' from $context."));
-      cls = context;
-    } else {
-      assert(
-          context.isConstructor,
-          failedAt(
-              NO_LOCATION_SPANNABLE,
-              "Unexpected reference of forwarding constructor "
-              "'${elementName}' from $context."));
-      cls = context.enclosingClass;
-    }
-    ClassElement superclass = cls.superclass;
-    element = superclass.lookupConstructor(elementName);
-    assert(
-        element != null,
-        failedAt(
-            NO_LOCATION_SPANNABLE,
-            "Unresolved reference of forwarding constructor "
-            "'${elementName}' from $context."));
-  }
-  return element;
-}
-
-void serializeMessageArguments(
-    ObjectEncoder encoder, Key key, Map<String, dynamic> messageArguments) {
-  if (messageArguments.isNotEmpty) {
-    MapEncoder mapEncoder = encoder.createMap(Key.ARGUMENTS);
-    messageArguments.forEach((String key, var value) {
-      mapEncoder.setString(key, Message.convertToString(value));
-    });
-  }
-}
-
-Map<String, String> deserializeMessageArguments(
-    ObjectDecoder decoder, Key key) {
-  Map<String, String> arguments = <String, String>{};
-  MapDecoder mapDecoder = decoder.getMap(key, isOptional: true);
-  if (mapDecoder != null) {
-    mapDecoder.forEachKey((String key) {
-      arguments[key] = mapDecoder.getString(key);
-    });
-  }
-  return arguments;
-}
-
-void serializeSourceSpan(ObjectEncoder encoder, SourceSpan sourceSpan) {
-  encoder.setUri(Key.URI, sourceSpan.uri, sourceSpan.uri);
-  encoder.setInt(Key.OFFSET, sourceSpan.begin);
-  encoder.setInt(Key.LENGTH, sourceSpan.end - sourceSpan.begin);
-}
-
-SourceSpan deserializeSourceSpan(ObjectDecoder decoder) {
-  Uri uri = decoder.getUri(Key.URI);
-  int offset = decoder.getInt(Key.OFFSET);
-  int length = decoder.getInt(Key.LENGTH);
-  return new SourceSpan(uri, offset, offset + length);
-}
-
-void serializeWrappedMessage(
-    ObjectEncoder encoder, Key key, WrappedMessage message) {
-  ObjectEncoder object = encoder.createObject(key);
-  if (message.sourceSpan != null) {
-    serializeSourceSpan(
-        object.createObject(Key.SOURCE_SPAN), message.sourceSpan);
-  }
-  object.setEnum(Key.KIND, message.messageKind);
-  serializeMessageArguments(object, Key.ARGUMENTS, message.messageArguments);
-}
-
-WrappedMessage deserializeWrappedMessage(ObjectDecoder decoder, Key key) {
-  ObjectDecoder object = decoder.getObject(key);
-  SourceSpan sourceSpan;
-  ObjectDecoder sourceSpanDecoder =
-      object.getObject(Key.SOURCE_SPAN, isOptional: true);
-  if (sourceSpanDecoder != null) {
-    sourceSpan = deserializeSourceSpan(sourceSpanDecoder);
-  }
-  MessageKind messageKind = object.getEnum(Key.KIND, MessageKind.values);
-  Map<String, dynamic> messageArguments =
-      deserializeMessageArguments(object, Key.ARGUMENTS);
-  return new WrappedMessage(sourceSpan, messageKind, messageArguments);
-}
diff --git a/pkg/compiler/lib/src/serialization/system.dart b/pkg/compiler/lib/src/serialization/system.dart
deleted file mode 100644
index 8ae4efc..0000000
--- a/pkg/compiler/lib/src/serialization/system.dart
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_system;
-
-import 'dart:async';
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../compiler.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../script.dart';
-import '../serialization/impact_serialization.dart';
-import 'package:front_end/src/fasta/scanner.dart';
-import '../universe/call_structure.dart';
-import '../universe/use.dart';
-import '../universe/world_impact.dart';
-import 'modelz.dart';
-import 'resolved_ast_serialization.dart';
-import 'serialization.dart';
-import 'task.dart';
-
-class ResolutionDeserializerSystem extends DeserializerSystem {
-  final Compiler _compiler;
-  final Resolution resolution;
-  final DeserializationContext deserializationContext;
-  final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
-
-  factory ResolutionDeserializerSystem(Compiler compiler,
-      {bool deserializeCompilationDataForTesting: false}) {
-    DeserializationContext context = new DeserializationContext(
-        compiler.reporter, compiler.resolution, compiler.libraryLoader);
-    DeserializerPlugin backendDeserializer =
-        compiler.backend.serialization.deserializer;
-    context.plugins.add(backendDeserializer);
-    if (compiler.options.resolveOnly && !deserializeCompilationDataForTesting) {
-      return new ResolutionDeserializerSystem._(
-          compiler, compiler.resolution, context);
-    } else {
-      ResolutionImpactDeserializer resolutionImpactDeserializer =
-          new ResolutionImpactDeserializer(backendDeserializer);
-      context.plugins.add(resolutionImpactDeserializer);
-      ResolvedAstDeserializerPlugin resolvedAstDeserializer =
-          new ResolvedAstDeserializerPlugin(
-              compiler.parsingContext, backendDeserializer);
-      context.plugins.add(resolvedAstDeserializer);
-      return new CompilationDeserializerSystem._(compiler, compiler.resolution,
-          context, resolutionImpactDeserializer, resolvedAstDeserializer);
-    }
-  }
-
-  ResolutionDeserializerSystem._(
-      this._compiler, this.resolution, this.deserializationContext);
-
-  @override
-  Future<LibraryElement> readLibrary(Uri resolvedUri) {
-    LibraryElement library = deserializationContext.lookupLibrary(resolvedUri);
-    if (library != null) {
-      deserializedLibraries.add(library);
-      return onReadLibrary(library);
-    }
-    return new Future<LibraryElement>.value(library);
-  }
-
-  Future<LibraryElement> onReadLibrary(LibraryElement library) {
-    return new Future<LibraryElement>.value(library);
-  }
-
-  // TODO(johnniwinther): Remove the need for this method.
-  @override
-  bool hasResolvedAst(ExecutableElement element) {
-    return getResolvedAst(element) != null;
-  }
-
-  @override
-  ResolvedAst getResolvedAst(ExecutableElement element) => null;
-
-  @override
-  bool hasResolutionImpact(Element element) => true;
-
-  @override
-  ResolutionImpact getResolutionImpact(Element element) {
-    return const ResolutionImpact();
-  }
-
-  @override
-  WorldImpact computeWorldImpact(Element element) {
-    ResolutionImpact resolutionImpact = getResolutionImpact(element);
-    assert(resolutionImpact != null,
-        failedAt(element, 'No impact found for $element (${element.library})'));
-    if (element is ExecutableElement) {
-      getResolvedAst(element);
-    }
-    if (element.isField && !element.isConst) {
-      FieldElement field = element;
-      if (field.isTopLevel || field.isStatic) {
-        if (field.constant == null) {
-          // TODO(johnniwinther): Find a cleaner way to do this. Maybe
-          // `Feature.LAZY_FIELD` of the resolution impact should be used
-          // instead.
-          _compiler.backend.constants.registerLazyStatic(field);
-        }
-      }
-    }
-    return resolution.transformResolutionImpact(element, resolutionImpact);
-  }
-
-  @override
-  bool isDeserialized(Entity entity) {
-    Element element = entity;
-    return deserializedLibraries.contains(element.library);
-  }
-}
-
-class CompilationDeserializerSystem extends ResolutionDeserializerSystem {
-  final ResolutionImpactDeserializer _resolutionImpactDeserializer;
-  final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
-
-  CompilationDeserializerSystem._(
-      Compiler compiler,
-      Resolution resolution,
-      DeserializationContext deserializationContext,
-      this._resolutionImpactDeserializer,
-      this._resolvedAstDeserializer)
-      : super._(compiler, resolution, deserializationContext);
-
-  @override
-  Future<LibraryElement> onReadLibrary(LibraryElement library) {
-    return Future.forEach(library.compilationUnits,
-        (CompilationUnitElement compilationUnit) {
-      ScriptZ script = compilationUnit.script;
-      return _compiler.readScript(script.readableUri).then((Script newScript) {
-        script.file = newScript.file;
-        script.isSynthesized = newScript.isSynthesized;
-        _resolvedAstDeserializer.scripts[script.resourceUri] = script;
-      });
-    }).then((_) => library);
-  }
-
-  @override
-  ResolvedAst getResolvedAst(ExecutableElement element) {
-    return _resolvedAstDeserializer.getResolvedAst(element);
-  }
-
-  @override
-  bool hasResolutionImpact(Element element) {
-    if (element.isConstructor &&
-        element.enclosingClass.isUnnamedMixinApplication) {
-      return true;
-    }
-    return _resolutionImpactDeserializer.hasResolutionImpact(element);
-  }
-
-  @override
-  ResolutionImpact getResolutionImpact(Element element) {
-    if (element.isConstructor &&
-        element.enclosingClass.isUnnamedMixinApplication) {
-      ConstructorElement constructor = element;
-      ClassElement superclass = constructor.enclosingClass.superclass;
-      ConstructorElement superclassConstructor =
-          superclass.lookupConstructor(constructor.name);
-      assert(
-          superclassConstructor != null,
-          failedAt(
-              element,
-              "Superclass constructor '${constructor.name}' called from "
-              "${element} not found in ${superclass}."));
-      // TODO(johnniwinther): Compute callStructure. Currently not used.
-      CallStructure callStructure;
-      return _resolutionImpactDeserializer.registerResolutionImpact(constructor,
-          () {
-        List<TypeUse> typeUses = <TypeUse>[];
-        void addCheckedModeCheck(ResolutionDartType type) {
-          if (!type.isDynamic) {
-            typeUses.add(new TypeUse.checkedModeCheck(type));
-          }
-        }
-
-        ResolutionFunctionType type = constructor.type;
-        // TODO(johnniwinther): Remove this substitution when synthesized
-        // constructors handle type variables correctly.
-        type = type.substByContext(constructor.enclosingClass
-            .asInstanceOf(constructor.enclosingClass));
-        type.parameterTypes.forEach(addCheckedModeCheck);
-        type.optionalParameterTypes.forEach(addCheckedModeCheck);
-        type.namedParameterTypes.forEach(addCheckedModeCheck);
-        return new DeserializedResolutionImpact(staticUses: <StaticUse>[
-          new StaticUse.superConstructorInvoke(
-              superclassConstructor, callStructure)
-        ], typeUses: typeUses);
-      });
-    }
-    return _resolutionImpactDeserializer.getResolutionImpact(element);
-  }
-}
-
-const String WORLD_IMPACT_TAG = 'worldImpact';
-
-class ResolutionImpactSerializer extends SerializerPlugin {
-  final Resolution resolution;
-  final SerializerPlugin nativeDataSerializer;
-
-  ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer);
-
-  @override
-  void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
-    if (resolution.hasBeenResolved(element)) {
-      ResolutionImpact impact = resolution.getResolutionImpact(element);
-      ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
-      new ImpactSerializer(element, encoder, nativeDataSerializer)
-          .serialize(impact);
-    }
-  }
-}
-
-class ResolutionImpactDeserializer extends DeserializerPlugin {
-  Map<Element, ObjectDecoder> _decoderMap = <Element, ObjectDecoder>{};
-  Map<Element, ResolutionImpact> _impactMap = <Element, ResolutionImpact>{};
-  final DeserializerPlugin nativeDataDeserializer;
-
-  ResolutionImpactDeserializer(this.nativeDataDeserializer);
-
-  @override
-  void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
-    ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
-    if (decoder != null) {
-      _decoderMap[element] = decoder;
-    }
-  }
-
-  bool hasResolutionImpact(Element element) {
-    return _impactMap.containsKey(element) || _decoderMap.containsKey(element);
-  }
-
-  ResolutionImpact registerResolutionImpact(
-      Element element, ResolutionImpact ifAbsent()) {
-    return _impactMap.putIfAbsent(element, ifAbsent);
-  }
-
-  ResolutionImpact getResolutionImpact(Element element) {
-    return registerResolutionImpact(element, () {
-      ObjectDecoder decoder = _decoderMap[element];
-      if (decoder != null) {
-        _decoderMap.remove(element);
-        return ImpactDeserializer.deserializeImpact(
-            element, decoder, nativeDataDeserializer);
-      }
-      return null;
-    });
-  }
-}
-
-const String RESOLVED_AST_TAG = 'resolvedAst';
-
-class ResolvedAstSerializerPlugin extends SerializerPlugin {
-  final Resolution resolution;
-  final SerializerPlugin nativeDataSerializer;
-
-  ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer);
-
-  @override
-  void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
-    assert(element.isDeclaration,
-        failedAt(element, "Element $element must be the declaration"));
-    if (element.isError) return;
-    if (element is MemberElement) {
-      assert(resolution.hasResolvedAst(element),
-          failedAt(element, "Element $element must have a resolved ast"));
-      ResolvedAst resolvedAst = resolution.getResolvedAst(element);
-      ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG);
-      new ResolvedAstSerializer(
-              objectEncoder, resolvedAst, nativeDataSerializer)
-          .serialize();
-    }
-  }
-}
-
-class ResolvedAstDeserializerPlugin extends DeserializerPlugin {
-  final ParsingContext parsingContext;
-  final DeserializerPlugin nativeDataDeserializer;
-  final Map<Uri, Script> scripts = <Uri, Script>{};
-
-  Map<MemberElement, ObjectDecoder> _decoderMap =
-      <MemberElement, ObjectDecoder>{};
-  Map<Uri, Token> beginTokenMap = <Uri, Token>{};
-
-  ResolvedAstDeserializerPlugin(
-      this.parsingContext, this.nativeDataDeserializer);
-
-  bool hasResolvedAst(ExecutableElement element) {
-    return getResolvedAst(element) != null;
-  }
-
-  ResolvedAst getResolvedAst(ExecutableElement element) {
-    if (element.hasResolvedAst) {
-      return element.resolvedAst;
-    }
-
-    ObjectDecoder decoder = _decoderMap[element.memberContext];
-    if (decoder != null) {
-      ResolvedAstDeserializer.deserialize(element.memberContext, decoder,
-          parsingContext, findToken, nativeDataDeserializer);
-      _decoderMap.remove(element);
-      assert(element.hasResolvedAst,
-          failedAt(element, "ResolvedAst not computed for $element."));
-      return element.resolvedAst;
-    }
-    return null;
-  }
-
-  Token findToken(Uri uri, int offset) {
-    Token beginToken = beginTokenMap.putIfAbsent(uri, () {
-      Script script = scripts[uri];
-      if (script == null) {
-        parsingContext.reporter.internalError(NO_LOCATION_SPANNABLE,
-            'No source file found for $uri in:\n ${scripts.keys.join('\n ')}');
-      }
-      if (script.isSynthesized) return null;
-      return parsingContext.scanner.scanFile(script.file);
-    });
-    if (beginToken == null) return null;
-    return ResolvedAstDeserializer.findTokenInStream(beginToken, offset);
-  }
-
-  @override
-  void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
-    ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG);
-    if (decoder != null) {
-      _decoderMap[element] = decoder;
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
deleted file mode 100644
index d052e4e..0000000
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.task;
-
-import 'dart:async' show Future;
-
-import '../../compiler_new.dart';
-import '../common/resolution.dart' show ResolutionImpact, ResolutionWorkItem;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
-import '../elements/elements.dart';
-import '../elements/entities.dart' show Entity;
-import '../universe/world_impact.dart' show WorldImpact;
-import 'json_serializer.dart';
-import 'serialization.dart';
-import 'system.dart';
-
-/// A deserializer that can load a library element by reading it's information
-/// from a serialized form.
-abstract class LibraryDeserializer {
-  /// Loads the [LibraryElement] associated with a library under [uri], or null
-  /// if no serialized information is available for the given library.
-  Future<LibraryElement> readLibrary(Uri uri);
-
-  /// Returns `true` if [element] has been deserialized.
-  bool isDeserialized(Entity element);
-}
-
-/// Task that supports deserialization of elements.
-class SerializationTask extends CompilerTask implements LibraryDeserializer {
-  final Compiler compiler;
-  SerializationTask(Compiler compiler)
-      : compiler = compiler,
-        super(compiler.measurer);
-
-  DeserializerSystem deserializer;
-
-  String get name => 'Serialization';
-
-  /// If `true`, data must be retained to support serialization.
-  // TODO(johnniwinther): Make this more precise in terms of what needs to be
-  // retained, for instance impacts, resolution data etc.
-  bool supportSerialization = false;
-
-  /// Set this flag to also deserialize [ResolvedAst]s and [ResolutionImpact]s
-  /// in `resolveOnly` mode. Use this for testing only.
-  bool deserializeCompilationDataForTesting = false;
-
-  /// If `true`, deserialized data is supported.
-  bool get supportsDeserialization => deserializer != null;
-
-  /// Returns the [LibraryElement] for [resolvedUri] if available from
-  /// serialization.
-  Future<LibraryElement> readLibrary(Uri resolvedUri) {
-    if (deserializer == null) return new Future<LibraryElement>.value();
-    return deserializer.readLibrary(resolvedUri);
-  }
-
-  /// Returns `true` if [element] has been deserialized.
-  bool isDeserialized(Entity element) {
-    return deserializer != null && deserializer.isDeserialized(element);
-  }
-
-  bool hasResolutionImpact(Element element) {
-    return deserializer != null && deserializer.hasResolutionImpact(element);
-  }
-
-  ResolutionImpact getResolutionImpact(Element element) {
-    return deserializer != null
-        ? deserializer.getResolutionImpact(element)
-        : null;
-  }
-
-  /// Creates the [ResolutionWorkItem] for the deserialized [element].
-  ResolutionWorkItem createResolutionWorkItem(MemberElement element) {
-    assert(deserializer != null);
-    assert(isDeserialized(element));
-    return new DeserializedResolutionWorkItem(
-        element, deserializer.computeWorldImpact(element));
-  }
-
-  bool hasResolvedAst(ExecutableElement element) {
-    return deserializer != null ? deserializer.hasResolvedAst(element) : false;
-  }
-
-  ResolvedAst getResolvedAst(ExecutableElement element) {
-    return deserializer != null ? deserializer.getResolvedAst(element) : null;
-  }
-
-  Serializer createSerializer(Iterable<LibraryElement> libraries) {
-    return measure(() {
-      assert(supportSerialization);
-
-      Serializer serializer =
-          new Serializer(shouldInclude: (e) => libraries.contains(e.library));
-      SerializerPlugin backendSerializer =
-          compiler.backend.serialization.serializer;
-      serializer.plugins.add(backendSerializer);
-      serializer.plugins.add(new ResolutionImpactSerializer(
-          compiler.resolution, backendSerializer));
-      serializer.plugins.add(new ResolvedAstSerializerPlugin(
-          compiler.resolution, backendSerializer));
-
-      for (LibraryElement library in libraries) {
-        serializer.serialize(library);
-      }
-      return serializer;
-    });
-  }
-
-  void serializeToSink(OutputSink sink, Iterable<LibraryElement> libraries) {
-    measure(() {
-      sink
-        ..add(createSerializer(libraries)
-            .toText(const JsonSerializationEncoder()))
-        ..close();
-    });
-  }
-
-  void deserializeFromText(Uri sourceUri, String serializedData) {
-    measure(() {
-      if (deserializer == null) {
-        deserializer = new ResolutionDeserializerSystem(compiler,
-            deserializeCompilationDataForTesting:
-                deserializeCompilationDataForTesting);
-      }
-      ResolutionDeserializerSystem deserializerImpl = deserializer;
-      DeserializationContext context = deserializerImpl.deserializationContext;
-      Deserializer dataDeserializer = new Deserializer.fromText(
-          context, sourceUri, serializedData, const JsonSerializationDecoder());
-      context.deserializers.add(dataDeserializer);
-    });
-  }
-}
-
-/// A [ResolutionWorkItem] for a deserialized element.
-///
-/// This will not resolve the element but only compute the [WorldImpact].
-class DeserializedResolutionWorkItem implements ResolutionWorkItem {
-  final MemberElement element;
-  final WorldImpact worldImpact;
-
-  DeserializedResolutionWorkItem(this.element, this.worldImpact);
-
-  @override
-  WorldImpact run() {
-    return worldImpact;
-  }
-}
-
-/// The interface for a system that supports deserialization of libraries and
-/// elements.
-abstract class DeserializerSystem {
-  Future<LibraryElement> readLibrary(Uri resolvedUri);
-  bool isDeserialized(Entity element);
-  bool hasResolvedAst(ExecutableElement element);
-  ResolvedAst getResolvedAst(ExecutableElement element);
-  bool hasResolutionImpact(Element element);
-  ResolutionImpact getResolutionImpact(Element element);
-  WorldImpact computeWorldImpact(Element element);
-}
diff --git a/pkg/compiler/lib/src/serialization/type_serialization.dart b/pkg/compiler/lib/src/serialization/type_serialization.dart
deleted file mode 100644
index 5702f3b..0000000
--- a/pkg/compiler/lib/src/serialization/type_serialization.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.types;
-
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import 'keys.dart';
-import 'serialization.dart';
-
-/// Visitor that serializes a [ResolutionDartType] by encoding it into an
-/// [ObjectEncoder].
-///
-/// This class is called from the [Serializer] when a [ResolutionDartType] needs
-/// serialization. The [ObjectEncoder] ensures that any [Element], and other
-/// [ResolutionDartType] that the serialized [ResolutionDartType] depends upon
-/// are also serialized.
-class TypeSerializer extends ResolutionDartTypeVisitor<dynamic, ObjectEncoder> {
-  const TypeSerializer();
-
-  void visitType(ResolutionDartType type, ObjectEncoder encoder) {
-    throw new UnsupportedError('Unsupported type: $type');
-  }
-
-  void visitVoidType(ResolutionVoidType type, ObjectEncoder encoder) {}
-
-  void visitTypeVariableType(
-      ResolutionTypeVariableType type, ObjectEncoder encoder) {
-    encoder.setElement(Key.ELEMENT, type.element);
-    encoder.setBool(
-        Key.IS_METHOD_TYPE_VARIABLE_TYPE, type is MethodTypeVariableType);
-  }
-
-  void visitFunctionType(ResolutionFunctionType type, ObjectEncoder encoder) {
-    // TODO(johnniwinther): Support encoding of `type.element`.
-    encoder.setType(Key.RETURN_TYPE, type.returnType);
-    encoder.setTypes(Key.PARAMETER_TYPES, type.parameterTypes);
-    encoder.setTypes(Key.OPTIONAL_PARAMETER_TYPES, type.optionalParameterTypes);
-    encoder.setStrings(Key.NAMED_PARAMETERS, type.namedParameters);
-    encoder.setTypes(Key.NAMED_PARAMETER_TYPES, type.namedParameterTypes);
-  }
-
-  void visitMalformedType(MalformedType type, ObjectEncoder encoder) {
-    encoder.setElement(Key.ELEMENT, type.element);
-  }
-
-  void visitInterfaceType(ResolutionInterfaceType type, ObjectEncoder encoder) {
-    encoder.setElement(Key.ELEMENT, type.element);
-    encoder.setTypes(Key.TYPE_ARGUMENTS, type.typeArguments);
-  }
-
-  void visitTypedefType(ResolutionTypedefType type, ObjectEncoder encoder) {
-    encoder.setElement(Key.ELEMENT, type.element);
-    encoder.setTypes(Key.TYPE_ARGUMENTS, type.typeArguments);
-  }
-
-  void visitDynamicType(ResolutionDynamicType type, ObjectEncoder encoder) {}
-}
-
-/// Utility class for deserializing [ResolutionDartType]s.
-///
-/// This is used by the [Deserializer].
-class TypeDeserializer {
-  /// Deserializes a [ResolutionDartType] from an [ObjectDecoder].
-  ///
-  /// The class is called from the [Deserializer] when a [ResolutionDartType]
-  /// needs deserialization. The [ObjectDecoder] ensures that any [Element],
-  /// other [ResolutionDartType] that the deserialized [ResolutionDartType]
-  /// depends upon are available.
-  // ignore: MISSING_RETURN
-  static ResolutionDartType deserialize(ObjectDecoder decoder) {
-    ResolutionTypeKind typeKind =
-        decoder.getEnum(Key.KIND, ResolutionTypeKind.values);
-    switch (typeKind) {
-      case ResolutionTypeKind.INTERFACE:
-        return new ResolutionInterfaceType(decoder.getElement(Key.ELEMENT),
-            decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
-      case ResolutionTypeKind.FUNCTION:
-        // TODO(johnniwinther): Support decoding of `type.element`.
-        return new ResolutionFunctionType.synthesized(
-            decoder.getType(Key.RETURN_TYPE),
-            decoder.getTypes(Key.PARAMETER_TYPES, isOptional: true),
-            decoder.getTypes(Key.OPTIONAL_PARAMETER_TYPES, isOptional: true),
-            decoder.getStrings(Key.NAMED_PARAMETERS, isOptional: true),
-            decoder.getTypes(Key.NAMED_PARAMETER_TYPES, isOptional: true));
-      case ResolutionTypeKind.TYPE_VARIABLE:
-        TypeVariableElement element = decoder.getElement(Key.ELEMENT);
-        if (decoder.getBool(Key.IS_METHOD_TYPE_VARIABLE_TYPE)) {
-          return new MethodTypeVariableType(element);
-        }
-        return new ResolutionTypeVariableType(element);
-      case ResolutionTypeKind.TYPEDEF:
-        return new ResolutionTypedefType(decoder.getElement(Key.ELEMENT),
-            decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
-      case ResolutionTypeKind.MALFORMED_TYPE:
-        // TODO(johnniwinther): Do we need the 'userProvidedBadType' or maybe
-        // just a toString of it?
-        return new MalformedType(decoder.getElement(Key.ELEMENT), null);
-      case ResolutionTypeKind.DYNAMIC:
-        return const ResolutionDynamicType();
-      case ResolutionTypeKind.VOID:
-        return const ResolutionVoidType();
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/serialization/values.dart b/pkg/compiler/lib/src/serialization/values.dart
deleted file mode 100644
index e0c712b..0000000
--- a/pkg/compiler/lib/src/serialization/values.dart
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Class hierarchy for semantic wrapping of serializable values.
-
-library dart2js.serialization.values;
-
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import 'keys.dart';
-
-/// Intermediate representation of a serializable value.
-///
-/// Serializable values are
-///    * [bool],
-///    * [int],
-///    * [double],
-///    * [String],
-///    * enum values,
-///    * [ConstantExpression],
-///    * [DartType],
-///    * [Element],
-///    * [Uri],
-///    * lists of serializeable values,
-///    * maps from arbitrary strings to serializable values; these are called
-///         `Map` values, and
-///    * maps from [Key] to serializable values; these are called `Object`
-///         values.
-///
-/// The distinction between map and object values is chosen to provide a more
-/// robust and checkable implementation of the latter; since the keys are drawn
-/// from a fixed typed set of values, consistency between serialization and
-/// deserialization is more easily maintained.
-abstract class Value {
-  accept(ValueVisitor visitor, arg);
-}
-
-class ElementValue implements Value {
-  final Element element;
-  final Value id;
-
-  ElementValue(this.element, this.id);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitElement(this, arg);
-
-  String toString() => element.toString();
-}
-
-class TypeValue implements Value {
-  final ResolutionDartType type;
-  final Value id;
-
-  TypeValue(this.type, this.id);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitType(this, arg);
-
-  String toString() => type.toString();
-}
-
-class ConstantValue implements Value {
-  final ConstantExpression constant;
-  final Value id;
-
-  ConstantValue(this.constant, this.id);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitConstant(this, arg);
-
-  String toString() => constant.toDartText();
-}
-
-abstract class PrimitiveValue implements Value {
-  get value;
-
-  String toString() => value.toString();
-}
-
-class BoolValue extends PrimitiveValue {
-  final bool value;
-
-  BoolValue(this.value);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitBool(this, arg);
-}
-
-class IntValue extends PrimitiveValue {
-  final int value;
-
-  IntValue(this.value);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitInt(this, arg);
-}
-
-class DoubleValue extends PrimitiveValue {
-  final double value;
-
-  DoubleValue(this.value);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitDouble(this, arg);
-}
-
-class StringValue extends PrimitiveValue {
-  final String value;
-
-  StringValue(this.value);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitString(this, arg);
-}
-
-class ObjectValue implements Value {
-  final Map<Key, Value> map;
-
-  ObjectValue(this.map);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitObject(this, arg);
-
-  String toString() => map.toString();
-}
-
-class MapValue implements Value {
-  final Map<String, Value> map;
-
-  MapValue(this.map);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitMap(this, arg);
-
-  String toString() => map.toString();
-}
-
-class ListValue implements Value {
-  final List<Value> values;
-
-  ListValue(this.values);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitList(this, arg);
-
-  String toString() => values.toString();
-}
-
-class EnumValue implements Value {
-  final value;
-
-  EnumValue(this.value);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitEnum(this, arg);
-
-  String toString() => value.toString();
-}
-
-class UriValue implements Value {
-  final Uri baseUri;
-  final Uri value;
-
-  UriValue(this.baseUri, this.value);
-
-  accept(ValueVisitor visitor, arg) => visitor.visitUri(this, arg);
-
-  String toString() => value.toString();
-}
-
-/// Visitor for the [Value] class hierarchy.
-abstract class ValueVisitor<R, A> {
-  R visit(Value value, A arg);
-
-  R visitElement(ElementValue value, A arg);
-  R visitType(TypeValue value, A arg);
-  R visitConstant(ConstantValue value, A arg);
-  R visitBool(BoolValue value, A arg);
-  R visitInt(IntValue value, A arg);
-  R visitDouble(DoubleValue value, A arg);
-  R visitString(StringValue value, A arg);
-  R visitObject(ObjectValue value, A arg);
-  R visitMap(MapValue value, A arg);
-  R visitList(ListValue value, A arg);
-  R visitEnum(EnumValue value, A arg);
-  R visitUri(UriValue value, A arg);
-}
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index 638a8a1..e7c0f61 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -28,7 +28,7 @@
   Future<api.Input> readBytesFromUri(Uri resourceUri, api.InputKind inputKind) {
     api.Input input;
     switch (inputKind) {
-      case api.InputKind.utf8:
+      case api.InputKind.UTF8:
         input = utf8SourceFiles[resourceUri];
         break;
       case api.InputKind.binary:
@@ -51,7 +51,7 @@
     List<int> source;
     try {
       source = readAll(resourceUri.toFilePath(),
-          zeroTerminated: inputKind == api.InputKind.utf8);
+          zeroTerminated: inputKind == api.InputKind.UTF8);
     } on FileSystemException catch (ex) {
       String message = ex.osError?.message;
       String detail = message != null ? ' ($message)' : '';
@@ -60,7 +60,7 @@
     dartCharactersRead += source.length;
     api.Input input;
     switch (inputKind) {
-      case api.InputKind.utf8:
+      case api.InputKind.UTF8:
         input = utf8SourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
             resourceUri, relativizeUri(resourceUri), source);
         break;
@@ -76,7 +76,7 @@
   /// returned.
   api.Input autoReadFromFile(Uri resourceUri) {
     try {
-      return _readFromFileSync(resourceUri, InputKind.utf8);
+      return _readFromFileSync(resourceUri, InputKind.UTF8);
     } catch (e) {
       // Silence the error. The [resourceUri] was not requested by the user and
       // was only needed to give better error messages.
@@ -120,7 +120,7 @@
       dartCharactersRead += totalLength;
       api.Input input;
       switch (inputKind) {
-        case api.InputKind.utf8:
+        case api.InputKind.UTF8:
           input = utf8SourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
               resourceUri, resourceUri.toString(), result);
           break;
@@ -175,7 +175,7 @@
 
   @override
   Future<api.Input<List<int>>> readFromUri(Uri uri,
-          {InputKind inputKind: InputKind.utf8}) =>
+          {InputKind inputKind: InputKind.UTF8}) =>
       readBytesFromUri(uri, inputKind);
 }
 
@@ -311,7 +311,6 @@
 class RandomAccessFileOutputProvider implements CompilerOutput {
   final Uri out;
   final Uri sourceMapOut;
-  final Uri resolutionOutput;
   final MessageCallback onInfo;
   final MessageCallback onFailure;
 
@@ -322,7 +321,7 @@
   List<String> allOutputFiles = <String>[];
 
   RandomAccessFileOutputProvider(this.out, this.sourceMapOut,
-      {this.onInfo, this.onFailure, this.resolutionOutput});
+      {this.onInfo, this.onFailure});
 
   Uri createUri(String name, String extension, OutputType type) {
     Uri uri;
@@ -346,12 +345,6 @@
       case OutputType.jsPart:
         uri = out.resolve('$name.$extension');
         break;
-      case OutputType.serializationData:
-        if (resolutionOutput == null) {
-          onFailure('Serialization target unspecified.');
-        }
-        uri = resolutionOutput;
-        break;
       case OutputType.info:
         if (name == '') {
           name = out.pathSegments.last;
@@ -473,7 +466,7 @@
 
   @override
   Future<api.Input> readFromUri(Uri uri,
-      {InputKind inputKind: InputKind.utf8}) async {
+      {InputKind inputKind: InputKind.UTF8}) async {
     var resolvedUri = uri;
     var path = uri.path;
     if (path.startsWith('/bazel-root')) {
@@ -488,7 +481,7 @@
     }
     api.Input result = await readBytesFromUri(resolvedUri, inputKind);
     switch (inputKind) {
-      case InputKind.utf8:
+      case InputKind.UTF8:
         utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
         break;
       case InputKind.binary:
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index f16c027..37c4541 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -4142,7 +4142,7 @@
       return false;
     }
 
-    MemberElement element = closedWorld.locateSingleElement(selector, mask);
+    MemberElement element = closedWorld.locateSingleMember(selector, mask);
     if (element != null &&
         !element.isField &&
         !(element.isGetter && selector.isCall) &&
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index ff53f88..efed6ee 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -3817,7 +3817,7 @@
       return false;
     }
 
-    MemberEntity element = closedWorld.locateSingleElement(selector, mask);
+    MemberEntity element = closedWorld.locateSingleMember(selector, mask);
     if (element != null &&
         !element.isField &&
         !(element.isGetter && selector.isCall) &&
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 24193c7..f108912 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -2907,18 +2907,18 @@
     HInstruction input = node.checkedInput;
     TypeMask inputType = node.inputType ?? input.instructionType;
     TypeMask checkedType = node.checkedType;
-    // Figure out if it is beneficial to turn this into a null check.
-    // V8 generally prefers 'typeof' checks, but for integers and
-    // indexable primitives we cannot compile this test into a single
-    // typeof check so the null check is cheaper.
+    // This path is no longer used for indexable primitive types.
+    assert(
+        !checkedType.satisfies(_commonElements.jsIndexableClass, _closedWorld));
+    // Figure out if it is beneficial to use a null check.  V8 generally prefers
+    // 'typeof' checks, but for integers we cannot compile this test into a
+    // single typeof check so the null check is cheaper.
     bool isIntCheck = checkedType.containsOnlyInt(_closedWorld);
     bool turnIntoNumCheck =
         isIntCheck && inputType.containsOnlyInt(_closedWorld);
     bool turnIntoNullCheck = !turnIntoNumCheck &&
         (checkedType.nullable() == inputType) &&
-        (isIntCheck ||
-            checkedType.satisfies(
-                _commonElements.jsIndexableClass, _closedWorld));
+        isIntCheck;
 
     if (turnIntoNullCheck) {
       use(input);
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index d98db39..c476754 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -970,6 +970,10 @@
     if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) {
       return newBuiltinVariant(instruction, closedWorld);
     }
+    if (closedWorld.includesClosureCall(
+        instruction.selector, instructionType)) {
+      return null;
+    }
     Iterable<MemberEntity> matches =
         closedWorld.locateMembers(instruction.selector, instructionType);
     // This test relies on `Object.==` and `Interceptor.==` always being
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 9960352..fbe8edd 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -3151,7 +3151,9 @@
   }
 
   bool get hasTypeRepresentation {
-    return typeExpression.isInterfaceType && inputs.length > 1;
+    return typeExpression != null &&
+        typeExpression.isInterfaceType &&
+        inputs.length > 1;
   }
 
   HInstruction get typeRepresentation => inputs[1];
@@ -3194,8 +3196,8 @@
         receiverTypeCheckSelector == other.receiverTypeCheckSelector;
   }
 
-  String toString() => 'HTypeConversion(type=$typeExpression,kind=$kind,'
-      '${hasTypeRepresentation ? 'representation=$typeRepresentation,' : ''}'
+  String toString() => 'HTypeConversion(type=$typeExpression, kind=$kind, '
+      '${hasTypeRepresentation ? 'representation=$typeRepresentation, ' : ''}'
       'checkedInput=$checkedInput)';
 }
 
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 889cddf..40c6687 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -534,7 +534,7 @@
 
     TypeMask receiverType = node.getDartReceiver(_closedWorld).instructionType;
     MemberEntity element =
-        _closedWorld.locateSingleElement(node.selector, receiverType);
+        _closedWorld.locateSingleMember(node.selector, receiverType);
     // TODO(ngeoffray): Also fold if it's a getter or variable.
     if (element != null &&
         element.isFunction
@@ -1056,7 +1056,7 @@
     if (field != null) return directFieldGet(receiver, field);
 
     if (node.element == null) {
-      MemberEntity element = _closedWorld.locateSingleElement(
+      MemberEntity element = _closedWorld.locateSingleMember(
           node.selector, receiver.instructionType);
       if (element != null && element.name == node.selector.name) {
         node.element = element;
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index 6c0df7e..02bdb6b 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -508,7 +508,24 @@
       assert(node.inputs.length == 1);
       rest = "";
     }
-    return "TypeConversion: $checkedInput to ${node.instructionType}$rest";
+    String kind = _typeConversionKind(node);
+    return "TypeConversion: $kind $checkedInput to ${node.instructionType}$rest";
+  }
+
+  String _typeConversionKind(HTypeConversion node) {
+    switch (node.kind) {
+      case HTypeConversion.CHECKED_MODE_CHECK:
+        return 'CHECKED_MODE';
+      case HTypeConversion.ARGUMENT_TYPE_CHECK:
+        return 'ARGUMENT';
+      case HTypeConversion.CAST_TYPE_CHECK:
+        return 'CAST';
+      case HTypeConversion.BOOLEAN_CONVERSION_CHECK:
+        return 'BOOLEAN_CONVERSION';
+      case HTypeConversion.RECEIVER_TYPE_CHECK:
+        return 'RECEIVER';
+    }
+    return '?';
   }
 
   String visitTypeKnown(HTypeKnown node) {
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 0831c6e..1d4a182 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -11,6 +11,22 @@
 import 'nodes.dart';
 import 'optimize.dart';
 
+/// Type propagation and conditioning check insertion.
+///
+/// 1. Type propagation (dataflow) to determine the types of all nodes.
+///
+/// 2. HTypeKnown node insertion captures type strengthening.
+///
+/// 3. Conditioning check insertion inserts receiver and argument checks on
+///    calls where that call is expected to be replaced with an instruction with
+///    a narrower domain. For example `{Null,int} + {int}` would insert an
+///    receiver check to strengthen the types to `{int} + {int}` to allow the
+///    call of `operator+` to be replaced with a HAdd instruction.
+///
+/// Analysis and node insertion are done together, since insertion improves the
+/// type propagation results.
+// TODO(sra): The InvokeDynamicSpecializer should be consulted for better
+// targeted conditioning checks.
 class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase {
   final Map<int, HInstruction> workmap = new Map<int, HInstruction>();
   final List<int> worklist = new List<int>();
@@ -21,7 +37,7 @@
   final CompilerOptions options;
   final CommonElements commonElements;
   final ClosedWorld closedWorld;
-  String get name => 'type propagator';
+  String get name => 'SsaTypePropagator';
 
   SsaTypePropagator(
       this.results, this.options, this.commonElements, this.closedWorld);
@@ -283,16 +299,18 @@
           HTypeConversion.RECEIVER_TYPE_CHECK);
       return true;
     } else if (instruction.element == null) {
+      if (closedWorld.includesClosureCall(
+          instruction.selector, instruction.mask)) {
+        return false;
+      }
       Iterable<MemberEntity> targets =
           closedWorld.locateMembers(instruction.selector, instruction.mask);
       if (targets.length == 1) {
         MemberEntity target = targets.first;
         ClassEntity cls = target.enclosingClass;
         TypeMask type = new TypeMask.nonNullSubclass(cls, closedWorld);
-        // TODO(ngeoffray): We currently only optimize on primitive
-        // types.
-        if (!type.satisfies(commonElements.jsIndexableClass, closedWorld) &&
-            !type.containsOnlyNum(closedWorld) &&
+        // We currently only optimize on some primitive types.
+        if (!type.containsOnlyNum(closedWorld) &&
             !type.containsOnlyBool(closedWorld)) {
           return false;
         }
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 1bd4289..932a128 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -540,8 +540,9 @@
     return closedWorld.needsNoSuchMethod(base, selector, _classQuery);
   }
 
-  MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld) {
+  MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld) {
     if (isEmptyOrNull) return null;
+    if (closedWorld.includesClosureCall(selector, this)) return null;
     Iterable<MemberEntity> targets = closedWorld.locateMembers(selector, this);
     if (targets.length != 1) return null;
     MemberEntity result = targets.first;
diff --git a/pkg/compiler/lib/src/types/forwarding_type_mask.dart b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
index 974f255..0bfed426 100644
--- a/pkg/compiler/lib/src/types/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
@@ -103,8 +103,8 @@
     return forwardTo.canHit(element, selector, closedWorld);
   }
 
-  MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld) {
-    return forwardTo.locateSingleElement(selector, closedWorld);
+  MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld) {
+    return forwardTo.locateSingleMember(selector, closedWorld);
   }
 
   bool equalsDisregardNull(other) {
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index dd8a7b0..7af49b4 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -370,5 +370,5 @@
    * on this mask. Returns null if there is none.
    */
   // TODO(johnniwinther): Move this method to [World].
-  MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld);
+  MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld);
 }
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 543ee11..178f878 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -338,10 +338,10 @@
     return disjointMasks.any((e) => e.canHit(element, selector, closedWorld));
   }
 
-  MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld) {
+  MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld) {
     MemberEntity candidate;
     for (FlatTypeMask mask in disjointMasks) {
-      MemberEntity current = mask.locateSingleElement(selector, closedWorld);
+      MemberEntity current = mask.locateSingleMember(selector, closedWorld);
       if (current == null) {
         return null;
       } else if (candidate == null) {
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 8ef7d5b..183575c 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -7,8 +7,9 @@
 import 'dart:collection' show Queue;
 import 'closure.dart';
 import 'common.dart';
-import 'constants/constant_system.dart';
+import 'common/names.dart';
 import 'common_elements.dart' show CommonElements, ElementEnvironment;
+import 'constants/constant_system.dart';
 import 'elements/entities.dart';
 import 'elements/elements.dart'
     show
@@ -300,6 +301,14 @@
   /// Returns all resolved typedefs.
   Iterable<TypedefEntity> get allTypedefs;
 
+  /// Returns `true` if [selector] on [mask] 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);
+
   /// Returns the mask for the potential receivers of a dynamic call to
   /// [selector] on [mask].
   ///
@@ -316,7 +325,7 @@
 
   /// Returns the single [MemberEntity] that matches a call to [selector] on a
   /// receiver of type [mask]. If multiple targets exist, `null` is returned.
-  MemberEntity locateSingleElement(Selector selector, TypeMask mask);
+  MemberEntity locateSingleMember(Selector selector, TypeMask mask);
 
   /// Returns the single field that matches a call to [selector] on a
   /// receiver of type [mask]. If multiple targets exist or the single target
@@ -1036,8 +1045,23 @@
     }
   }
 
+  /// Returns `true` if [selector] on [mask] 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) {
+    return selector.name == Identifiers.call &&
+        (mask == null ||
+            mask.containsMask(commonMasks.functionType, closedWorld));
+  }
+
   TypeMask computeReceiverType(Selector selector, TypeMask mask) {
     _ensureFunctionSet();
+    if (includesClosureCall(selector, mask)) {
+      return commonMasks.dynamicType;
+    }
     return _allFunctions.receiverType(selector, mask, this);
   }
 
@@ -1054,13 +1078,16 @@
   }
 
   FieldEntity locateSingleField(Selector selector, TypeMask mask) {
-    MemberEntity result = locateSingleElement(selector, mask);
+    MemberEntity result = locateSingleMember(selector, mask);
     return (result != null && result.isField) ? result : null;
   }
 
-  MemberEntity locateSingleElement(Selector selector, TypeMask mask) {
+  MemberEntity locateSingleMember(Selector selector, TypeMask mask) {
+    if (includesClosureCall(selector, mask)) {
+      return null;
+    }
     mask ??= commonMasks.dynamicType;
-    return mask.locateSingleElement(selector, this);
+    return mask.locateSingleMember(selector, this);
   }
 
   TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
@@ -1093,7 +1120,9 @@
 
   SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask) {
     // We're not tracking side effects of closures.
-    if (selector.isClosureCall) return new SideEffects();
+    if (selector.isClosureCall || includesClosureCall(selector, mask)) {
+      return new SideEffects();
+    }
     SideEffects sideEffects = new SideEffects.empty();
     _ensureFunctionSet();
     for (MemberEntity e in _allFunctions.filter(selector, mask, this)) {
diff --git a/pkg/compiler/testing_dart.json b/pkg/compiler/testing_dart.json
index aa78e3e..f36c8ad 100644
--- a/pkg/compiler/testing_dart.json
+++ b/pkg/compiler/testing_dart.json
@@ -63,12 +63,6 @@
       "^tests/compiler/dart2js/rti/emission/future_or_future_or_generic_strong\\.dart",
       "^tests/compiler/dart2js/rti/emission/future_or_future_or_strong\\.dart",
       "^tests/compiler/dart2js/rti/emission/future_or_generic2_strong\\.dart",
-      "^tests/compiler/dart2js/serialization/analysis_test_helper\\.dart",
-      "^tests/compiler/dart2js/serialization/compilation_test_helper\\.dart",
-      "^tests/compiler/dart2js/serialization/duplicate_library_test\\.dart",
-      "^tests/compiler/dart2js/serialization/equivalence_test\\.dart",
-      "^tests/compiler/dart2js/serialization/model_test_helper\\.dart",
-      "^tests/compiler/dart2js/serialization/test_helper\\.dart",
       "^tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper\\.dart",
       "^tests/compiler/dart2js/sourcemaps/diff_view\\.dart",
       "^tests/compiler/dart2js/sourcemaps/html_parts\\.dart",
diff --git a/pkg/compiler/tool/track_memory.dart b/pkg/compiler/tool/track_memory.dart
index 75d6d14..f6ef38d 100644
--- a/pkg/compiler/tool/track_memory.dart
+++ b/pkg/compiler/tool/track_memory.dart
@@ -66,7 +66,7 @@
 Future _sendMessage(String method, [Map args = const {}]) {
   var id = _requestId++;
   _pendingResponses[id] = new Completer();
-  socket.add(JSON.encode({
+  socket.add(jsonEncode({
     'jsonrpc': '2.0',
     'id': '$id',
     'method': '$method',
@@ -77,7 +77,7 @@
 
 /// Handle all responses
 void _handleResponse(Object s) {
-  var json = JSON.decode(s);
+  var json = jsonDecode(s);
   if (json['method'] != 'streamNotify') {
     var id = json['id'];
     if (id is String) id = int.parse(id);
diff --git a/pkg/dart_messages/bin/publish.dart b/pkg/dart_messages/bin/publish.dart
index cf4ac90..2b609e6 100644
--- a/pkg/dart_messages/bin/publish.dart
+++ b/pkg/dart_messages/bin/publish.dart
@@ -47,7 +47,7 @@
 ///
 /// The parameter [str] may be `null` in which case the result is "null".
 String escapeString(String str) {
-  return JSON.encode(str);
+  return jsonEncode(str);
 }
 
 /// Emits the messages in dart2js format.
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 9c93e2c..48eaedb 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -129,9 +129,6 @@
   JS.Identifier _extensionSymbolsModule;
   final _extensionSymbols = new Map<String, JS.TemporaryId>();
 
-  JS.Identifier _runtimeModule;
-  final namedArgumentTemp = new JS.TemporaryId('opts');
-
   /// The  type provider from the current Analysis [context].
   final TypeProvider types;
 
@@ -341,14 +338,14 @@
     if (isBuildingSdk) {
       // Don't allow these to be renamed when we're building the SDK.
       // There is JS code in dart:* that depends on their names.
-      _runtimeModule = new JS.Identifier('dart');
+      runtimeModule = new JS.Identifier('dart');
       _extensionSymbolsModule = new JS.Identifier('dartx');
     } else {
       // Otherwise allow these to be renamed so users can write them.
-      _runtimeModule = new JS.TemporaryId('dart');
+      runtimeModule = new JS.TemporaryId('dart');
       _extensionSymbolsModule = new JS.TemporaryId('dartx');
     }
-    _typeTable = new TypeTable(_runtimeModule);
+    _typeTable = new TypeTable(runtimeModule);
 
     // Initialize our library variables.
     var exports = <JS.NameSpecifier>[];
@@ -362,7 +359,7 @@
       if (unit.element != library.definingCompilationUnit) continue;
 
       var libraryTemp = isSdkInternalRuntime(library)
-          ? _runtimeModule
+          ? runtimeModule
           : new JS.TemporaryId(jsLibraryName(_libraryRoot, library));
       _libraries[library] = libraryTemp;
       emitLibrary(libraryTemp);
@@ -446,7 +443,7 @@
     // This data is only required for debugging.
     _moduleItems.add(js
         .statement('#.trackLibraries(#, #, ${JSModuleFile.sourceMapHoleID});', [
-      _runtimeModule,
+      runtimeModule,
       js.string(name),
       new JS.ObjectInitializer(properties, multiline: true)
     ]));
@@ -503,7 +500,7 @@
     JS.PropertyAccess access;
     for (var part in parts) {
       access = new JS.PropertyAccess(
-          access ?? _callHelper('global'), js.escapedString(part, "'"));
+          access ?? runtimeCall('global'), js.escapedString(part, "'"));
     }
     return access;
   }
@@ -575,7 +572,7 @@
       var imports =
           libraries.map((l) => new JS.NameSpecifier(_imports[l])).toList();
       if (module == coreModuleName) {
-        imports.add(new JS.NameSpecifier(_runtimeModule));
+        imports.add(new JS.NameSpecifier(runtimeModule));
         imports.add(new JS.NameSpecifier(_extensionSymbolsModule));
       }
 
@@ -780,7 +777,7 @@
       var callMethod = from.lookUpInheritedMethod('call');
       if (callMethod != null) {
         var callName = _emitMemberName('call', type: from, element: callMethod);
-        var callTearoff = _callHelper('bindCall(#, #)', [jsFrom, callName]);
+        var callTearoff = runtimeCall('bindCall(#, #)', [jsFrom, callName]);
         if (rules.isSubtypeOf(callMethod.type, to)) return callTearoff;
 
         // We may still need an implicit coercion as well, if another downcast
@@ -796,7 +793,7 @@
         // TODO(jmesserly): fuse this with notNull check.
         // TODO(jmesserly): this does not correctly distinguish user casts from
         // required-for-soundness casts.
-        return _callHelper('asInt(#)', jsFrom);
+        return runtimeCall('asInt(#)', jsFrom);
       }
 
       // A no-op in JavaScript.
@@ -858,7 +855,7 @@
     }
 
     JS.Expression body = closureAnnotate(
-        _callHelper('typedef(#, () => #)', [
+        runtimeCall('typedef(#, () => #)', [
           js.string(element.name, "'"),
           _emitFunctionType(type, nameType: false)
         ]),
@@ -965,8 +962,8 @@
     var jsPeerNames = _extensionTypes.getNativePeers(classElem);
     if (jsPeerNames.length == 1 && classElem.typeParameters.isNotEmpty) {
       // Special handling for JSArray<E>
-      body.add(_callHelperStatement('setExtensionBaseClass(#, #.global.#);',
-          [className, _runtimeModule, jsPeerNames[0]]));
+      body.add(runtimeStatement('setExtensionBaseClass(#, #.global.#)',
+          [className, runtimeModule, jsPeerNames[0]]));
     }
 
     var finishGenericTypeTest = _emitClassTypeTests(classElem, className, body);
@@ -1009,7 +1006,7 @@
           case 'Future':
           case 'Stream':
           case 'StreamSubscription':
-            return _callHelper('is' + c.name);
+            return runtimeCall('is' + c.name);
         }
       }
       return null;
@@ -1044,13 +1041,13 @@
             '  if (typeof o == "string" || o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_String(o) {'
             '  if (typeof o == "string" || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (classElem == functionClass) {
@@ -1062,13 +1059,13 @@
             '  if (typeof o == "function" || o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_Function(o) {'
             '  if (typeof o == "function" || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (classElem == intClass) {
@@ -1083,14 +1080,14 @@
             '    return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_int(o) {'
             '  if ((typeof o == "number" && Math.floor(o) == o) || o == null)'
             '    return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (classElem == nullClass) {
@@ -1101,13 +1098,13 @@
             '  if (o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_Null(o) {'
             '  if (o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (classElem == numClass || classElem == doubleClass) {
@@ -1119,13 +1116,13 @@
             '  if (typeof o == "number" || o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_num(o) {'
             '  if (typeof o == "number" || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (classElem == boolClass) {
@@ -1137,13 +1134,13 @@
             '  if (o === true || o === false || o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_bool(o) {'
             '  if (o === true || o === false || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
     }
@@ -1164,18 +1161,18 @@
               if (o == null || #.is(o) || #.is(o)) return o;
               return #.as(o, this, false);
             }
-            ''', [className, typeT, futureOfT, _runtimeModule]));
+            ''', [className, typeT, futureOfT, runtimeModule]));
         body.add(js.statement('''
             #._check = function check_FutureOr(o) {
               if (o == null || #.is(o) || #.is(o)) return o;
               return #.as(o, this, true);
             }
-            ''', [className, typeT, futureOfT, _runtimeModule]));
+            ''', [className, typeT, futureOfT, runtimeModule]));
         return null;
       }
     }
 
-    body.add(_callHelperStatement('addTypeTests(#);', [className]));
+    body.add(runtimeStatement('addTypeTests(#)', [className]));
 
     if (classElem.typeParameters.isEmpty) return null;
 
@@ -1200,8 +1197,7 @@
 
     // Return this `addTypeTests` call so we can emit it outside of the generic
     // type parameter scope.
-    return _callHelperStatement(
-        'addTypeTests(#, #);', [defaultInst, isClassSymbol]);
+    return runtimeStatement('addTypeTests(#, #)', [defaultInst, isClassSymbol]);
   }
 
   void _emitSymbols(Iterable<JS.TemporaryId> vars, List<JS.ModuleItem> body) {
@@ -1266,7 +1262,7 @@
       genericArgs.add(js.call('(#) => { #; }', [jsFormals, deferredBaseClass]));
     }
 
-    var genericCall = _callHelper('generic(#)', [genericArgs]);
+    var genericCall = runtimeCall('generic(#)', [genericArgs]);
 
     var genericName = _emitTopLevelNameNoInterop(element, suffix: '\$');
     return js.statement('{ # = #; # = #(); }',
@@ -1357,7 +1353,7 @@
         mixinCtor = js.statement('#.#.call(this);', [
           emitClassRef(mixin),
           _usesMixinNew(mixin.element)
-              ? _callHelper('mixinNew')
+              ? runtimeCall('mixinNew')
               : _constructorName('')
         ]);
       }
@@ -1381,7 +1377,7 @@
     // Unroll mixins.
     var mixinLength = classElem.mixins.length;
     if (shouldDefer(supertype)) {
-      deferredSupertypes.add(_callHelperStatement('setBaseClass(#, #)', [
+      deferredSupertypes.add(runtimeStatement('setBaseClass(#, #)', [
         getBaseClass(isMixinAliasClass(classElem) ? 0 : mixinLength),
         emitDeferredType(supertype),
       ]));
@@ -1403,8 +1399,8 @@
       var mixinClass = deferMixin ? emitDeferredType(m) : emitClassRef(m);
       var classExpr = deferMixin ? getBaseClass(0) : className;
 
-      mixinBody.add(
-          _callHelperStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
+      mixinBody
+          .add(runtimeStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
 
       _topLevelClass = savedTopLevel;
 
@@ -1415,7 +1411,7 @@
         // We do this with the following pattern:
         //
         //     mixinMembers(C, class C$ extends M { <methods>  });
-        mixinBody.add(_callHelperStatement('mixinMembers(#, #)', [
+        mixinBody.add(runtimeStatement('mixinMembers(#, #)', [
           classExpr,
           new JS.ClassExpression(
               new JS.TemporaryId(classElem.name), mixinClass, methods)
@@ -1447,11 +1443,11 @@
       hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(m.element);
 
       if (shouldDefer(m)) {
-        deferredSupertypes.add(_callHelperStatement('mixinMembers(#, #)',
+        deferredSupertypes.add(runtimeStatement('mixinMembers(#, #)',
             [getBaseClass(mixinLength - i), emitDeferredType(m)]));
       } else {
-        body.add(_callHelperStatement(
-            'mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
+        body.add(
+            runtimeStatement('mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
       }
 
       baseClass = mixinId;
@@ -1513,7 +1509,7 @@
           new JS.Method(_propertyName('constructor'), js.fun(r'''function() {
                   throw Error("use `new " + #.typeName(#.getReifiedType(this)) +
                       ".new(...)` to create a Dart object");
-              }''', [_runtimeModule, _runtimeModule])));
+              }''', [runtimeModule, runtimeModule])));
     } else if (classElem.isEnum) {
       // Generate Enum.toString()
       var fields = classElem.fields.where((f) => f.type == type).toList();
@@ -1733,34 +1729,42 @@
       invocationProps.add(new JS.Property(js.string(name), value));
     }
 
-    var args = _emitParametersForElement(method);
     var typeParams = _emitTypeFormals(method.type.typeFormals);
-    var fnArgs = new List<JS.Parameter>.from(typeParams)..addAll(args);
-
+    var fnArgs = new List<JS.Parameter>.from(typeParams);
     JS.Expression positionalArgs;
-    List<JS.Statement> optionalArgInit = [];
-    if (method.type.optionalParameterTypes.isNotEmpty) {
-      positionalArgs = new JS.TemporaryId('args');
-      var requiredParameterCount = method.type.normalParameterTypes.length;
-      optionalArgInit.add(js.statement(
-          'let # = [#]', [positionalArgs, args.take(requiredParameterCount)]));
-      optionalArgInit.addAll(args.skip(requiredParameterCount).map((p) =>
-          js.statement('if (# !== void 0) #.push(#)', [p, positionalArgs, p])));
-    } else {
-      if (method.type.namedParameterTypes.isNotEmpty) {
-        addProperty('namedArguments', args.removeLast());
-      }
-      positionalArgs = new JS.ArrayInitializer(args);
-    }
 
-    if (method is MethodElement) {
-      addProperty('isMethod', js.boolean(true));
-    } else {
-      var property = method as PropertyAccessorElement;
-      if (property.isGetter) {
+    if (method is PropertyAccessorElement) {
+      if (method.isGetter) {
         addProperty('isGetter', js.boolean(true));
-      } else if (property.isSetter) {
+        positionalArgs = new JS.ArrayInitializer([]);
+      } else {
+        assert(method.isSetter);
         addProperty('isSetter', js.boolean(true));
+        var valueArg = new JS.TemporaryId('value');
+        positionalArgs = new JS.ArrayInitializer([valueArg]);
+        fnArgs.add(valueArg);
+      }
+    } else {
+      addProperty('isMethod', js.boolean(true));
+      if (method.type.namedParameterTypes.isNotEmpty) {
+        // Named parameters need to be emitted in the correct position (after
+        // positional arguments) so we can detect them reliably.
+        var args = _emitParametersForElement(method);
+        fnArgs.addAll(args);
+        addProperty('namedArguments', args.removeLast());
+        positionalArgs = new JS.ArrayInitializer(args);
+      } else {
+        // In case we have optional parameters, we need to use rest args,
+        // because sometimes mocks want to detect whether optional arguments
+        // were passed, and this does not work reliably with undefined (should
+        // not normally appear in DDC, but it can result from JS interop).
+        //
+        // TODO(jmesserly): perhaps we need to use rest args or destructuring
+        // to get reliable optional argument passing in other scenarios? It
+        // doesn't seem to occur outside of tests, perhaps due to the
+        // combination of mockito and protobufs.
+        positionalArgs = new JS.TemporaryId('args');
+        fnArgs.add(new JS.RestParameter(positionalArgs));
       }
     }
 
@@ -1770,7 +1774,7 @@
 
     var fnBody =
         js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
-      _runtimeModule,
+      runtimeModule,
       _declareMemberName(method),
       positionalArgs,
       new JS.ObjectInitializer(invocationProps)
@@ -1780,9 +1784,8 @@
       fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]);
     }
 
-    var fn = new JS.Fun(
-        fnArgs, js.block('{ #; return #; }', [optionalArgInit, fnBody]),
-        typeParams: typeParams);
+    var fn =
+        new JS.Fun(fnArgs, fnBody.toReturn().toBlock(), typeParams: typeParams);
 
     return new JS.Method(
         _declareMemberName(method,
@@ -1899,7 +1902,7 @@
     return new JS.Method(
         js.call('Symbol.iterator'),
         js.call('function() { return new #.JsIterator(this.#); }',
-            [_runtimeModule, _emitMemberName('iterator', type: t)]) as JS.Fun);
+            [runtimeModule, _emitMemberName('iterator', type: t)]) as JS.Fun);
   }
 
   JS.Expression _instantiateAnnotation(Annotation node) {
@@ -1920,11 +1923,11 @@
       ClassElement classElem, String jsPeerName, List<JS.Statement> body) {
     var className = _emitTopLevelName(classElem);
     if (isPrimitiveType(classElem.type)) {
-      body.add(_callHelperStatement(
-          'definePrimitiveHashCode(#.prototype)', className));
+      body.add(
+          runtimeStatement('definePrimitiveHashCode(#.prototype)', className));
     }
-    body.add(_callHelperStatement(
-        'registerExtension(#, #);', [js.string(jsPeerName), className]));
+    body.add(runtimeStatement(
+        'registerExtension(#, #)', [js.string(jsPeerName), className]));
   }
 
   /// Defines all constructors for this class as ES5 constructors.
@@ -1986,7 +1989,7 @@
       body.add(
           js.statement('(#[#] = function() { # }).prototype = #.prototype;', [
         className,
-        _callHelper('mixinNew'),
+        runtimeCall('mixinNew'),
         [_initializeFields(fields)],
         className
       ]));
@@ -2009,7 +2012,7 @@
     var ctorName = _constructorName(name);
     if (JS.invalidStaticFieldName(name)) {
       jsCtor =
-          _callHelper('defineValue(#, #, #)', [className, ctorName, jsCtor]);
+          runtimeCall('defineValue(#, #, #)', [className, ctorName, jsCtor]);
     } else {
       jsCtor = js.call('#.# = #', [className, ctorName, jsCtor]);
     }
@@ -2031,7 +2034,7 @@
         ];
         // TODO(jmesserly): should this be the job of `declareMemberName`?
         if (JS.invalidStaticFieldName(e.name)) {
-          body.add(_callHelperStatement('defineValue(#, #, #)', args));
+          body.add(runtimeStatement('defineValue(#, #, #)', args));
         } else {
           body.add(js.statement('#.# = #', args));
         }
@@ -2044,7 +2047,7 @@
         // static const E id_i = const E(i);
         values.add(new JS.PropertyAccess(
             _emitStaticClassName(classElem), _declareMemberName(f.getter)));
-        var enumValue = _callHelper('const(new (#.#)(#))', [
+        var enumValue = runtimeCall('const(new (#.#)(#))', [
           _emitConstructorAccess(type),
           _constructorName(''),
           js.number(index++)
@@ -2071,7 +2074,7 @@
     // Metadata
     if (options.emitMetadata && metadata.isNotEmpty) {
       body.add(js.statement('#[#.metadata] = () => [#];',
-          [className, _runtimeModule, metadata.map(_instantiateAnnotation)]));
+          [className, runtimeModule, metadata.map(_instantiateAnnotation)]));
     }
   }
 
@@ -2100,7 +2103,7 @@
           .map((e) => _propertyName(JS.memberNameForDartMember(e)))
           .toList();
       body.add(js.statement('#.#(#, #);', [
-        _runtimeModule,
+        runtimeModule,
         helperName,
         className,
         new JS.ArrayInitializer(names, multiline: names.length > 4)
@@ -2117,7 +2120,7 @@
       Map<Element, Declaration> annotatedMembers, List<JS.Statement> body) {
     if (classElem.interfaces.isNotEmpty) {
       body.add(js.statement('#[#.implements] = () => [#];',
-          [className, _runtimeModule, classElem.interfaces.map(_emitType)]));
+          [className, runtimeModule, classElem.interfaces.map(_emitType)]));
     }
 
     void emitSignature(String name, List<JS.Property> elements) {
@@ -2126,10 +2129,10 @@
       if (!name.startsWith('Static')) {
         var proto = classElem.type.isObject
             ? js.call('Object.create(null)')
-            : _callHelper('get${name}s(#.__proto__)', [className]);
+            : runtimeCall('get${name}s(#.__proto__)', [className]);
         elements.insert(0, new JS.Property(_propertyName('__proto__'), proto));
       }
-      body.add(_callHelperStatement('set${name}Signature(#, () => #)', [
+      body.add(runtimeStatement('set${name}Signature(#, () => #)', [
         className,
         new JS.ObjectInitializer(elements, multiline: elements.length > 1)
       ]));
@@ -2291,9 +2294,10 @@
     }
 
     // Add static property dart._runtimeType to Object.
+    //
     // All other Dart classes will (statically) inherit this property.
     if (classElem == objectClass) {
-      body.add(_callHelperStatement('tagComputed(#, () => #.#);',
+      body.add(runtimeStatement('lazyFn(#, () => #.#)',
           [className, emitLibraryName(coreLibrary), 'Type']));
     }
   }
@@ -2669,8 +2673,8 @@
         }
         props.add(pairCode);
       }
-      return _callHelperStatement('copyProperties(#, { # });',
-          [emitLibraryName(currentLibrary), props]);
+      return runtimeStatement(
+          'copyProperties(#, { # })', [emitLibraryName(currentLibrary), props]);
     }
 
     var body = <JS.Statement>[];
@@ -2754,7 +2758,7 @@
       {bool topLevel: false}) {
     var lazy = topLevel && !_typeIsLoaded(type);
     var typeRep = _emitFunctionType(type, lazy: lazy);
-    return _callHelper(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
+    return runtimeCall(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
   }
 
   /// Emits an arrow FunctionExpression node.
@@ -2874,7 +2878,7 @@
     for (var t in typeFormals) {
       t = covariantParams.lookup(t) as TypeParameterElement;
       if (t != null) {
-        body.add(_callHelperStatement('checkTypeBound(#, #, #)',
+        body.add(runtimeStatement('checkTypeBound(#, #, #)',
             [_emitType(t.type), _emitType(t.bound), _propertyName(t.name)]));
       }
     }
@@ -2960,7 +2964,7 @@
       // dart:_runtime/generators.dart has an example of the generated code.
       var asyncStarParam = new JS.TemporaryId('stream');
       var gen = emitGeneratorFn([asyncStarParam], asyncStarParam);
-      return _callHelper('asyncStar(#, #)', [_emitType(returnType), gen]);
+      return runtimeCall('asyncStar(#, #)', [_emitType(returnType), gen]);
     }
 
     // `async` works similar to `sync*`:
@@ -3019,7 +3023,7 @@
       simpleId.receiver.sourceInformation = _nodeSpan(prefix.prefix);
     }
     if (typeArgs == null) return simpleId;
-    return _callHelper('gbind(#, #)', [simpleId, typeArgs]);
+    return runtimeCall('gbind(#, #)', [simpleId, typeArgs]);
   }
 
   /// Emits a simple identifier, handling implicit `this` as well as
@@ -3059,7 +3063,7 @@
       // If the type is a type literal expression in Dart code, wrap the raw
       // runtime type in a "Type" instance.
       if (!_isInForeignJS && _isTypeLiteral(node)) {
-        typeName = _callHelper('wrapType(#)', typeName);
+        typeName = runtimeCall('wrapType(#)', typeName);
       }
 
       return typeName;
@@ -3101,7 +3105,7 @@
         var nativeName = _extensionTypes.getNativePeers(classElem);
         if (nativeName.isNotEmpty) {
           var memberName = getAnnotationName(element, isJSName) ?? member;
-          return _callHelper('global.#.#', [nativeName[0], memberName]);
+          return runtimeCall('global.#.#', [nativeName[0], memberName]);
         }
       }
 
@@ -3116,7 +3120,7 @@
           return _emitFunctionTagged(
               new JS.PropertyAccess(target, member), element.type);
         }
-        return _callHelper('bind(#, #)', [target, member]);
+        return runtimeCall('bind(#, #)', [target, member]);
       }
       return new JS.PropertyAccess(target, member);
     }
@@ -3198,7 +3202,7 @@
       args.add(new JS.ArrayInitializer(
           metadata.map(_instantiateAnnotation).toList()));
     }
-    return _callHelper(isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
+    return runtimeCall(isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
   }
 
   JS.ArrayInitializer _emitTypeNames(
@@ -3277,7 +3281,7 @@
     } else {
       helperCall = 'fnType(#)';
     }
-    fullType = _callHelper(helperCall, [typeParts]);
+    fullType = runtimeCall(helperCall, [typeParts]);
     if (!nameType) return fullType;
     return _typeTable.nameFunctionType(type, fullType, lazy: lazy);
   }
@@ -3310,11 +3314,11 @@
   JS.Expression _emitType(DartType type, {bool nameType: true}) {
     // The void and dynamic types are not defined in core.
     if (type.isVoid) {
-      return _callHelper('void');
+      return runtimeCall('void');
     } else if (type.isDynamic) {
-      return _callHelper('dynamic');
+      return runtimeCall('dynamic');
     } else if (type.isBottom) {
-      return _callHelper('bottom');
+      return runtimeCall('bottom');
     }
 
     var element = type.element;
@@ -3336,11 +3340,11 @@
     // Anonymous JS types do not have a corresponding concrete JS type so we
     // have to use a helper to define them.
     if (_isObjectLiteral(element)) {
-      return _callHelper('anonymousJSType(#)', js.escapedString(element.name));
+      return runtimeCall('anonymousJSType(#)', js.escapedString(element.name));
     }
     var jsName = _getJSNameWithoutGlobal(element);
     if (jsName != null) {
-      return _callHelper('lazyJSType(() => #, #)',
+      return runtimeCall('lazyJSType(() => #, #)',
           [_emitJSInteropForGlobal(jsName), js.escapedString(jsName)]);
     }
 
@@ -3481,7 +3485,7 @@
     }
 
     if (isDynamicInvoke(target)) {
-      return _callHelper('dput$_replSuffix(#, #, #)', [
+      return runtimeCall('dput$_replSuffix(#, #, #)', [
         _visitExpression(target),
         _emitMemberName(id.name),
         _visitExpression(right)
@@ -3499,16 +3503,16 @@
     return _badAssignment('Unhandled assignment', left, right);
   }
 
-  // TODO(jmesserly): remove this. Instead handle REPL private name lookups in
-  // _emitMemberName (by using `dart.privateName` if we're in REPL mode,
-  // refactored from the current `dart._dhelperRepl`).
+  // TODO(jmesserly): can we encapsulate REPL name lookups and remove this?
+  // _emitMemberName would be a nice place to handle it, but we don't have
+  // access to the target expression there (needed for `dart.replNameLookup`).
   String get _replSuffix => options.replCompile ? 'Repl' : '';
 
   JS.Expression _badAssignment(String problem, Expression lhs, Expression rhs) {
     // TODO(sra): We should get here only for compiler bugs or weirdness due to
     // --unsafe-force-compile. Once those paths have been addressed, throw at
     // compile time.
-    return _callHelper('throwUnimplementedError((#, #, #))',
+    return runtimeCall('throwUnimplementedError((#, #, #))',
         [js.string('$lhs ='), _visitExpression(rhs), js.string(problem)]);
   }
 
@@ -3627,7 +3631,7 @@
   visitMethodInvocation(MethodInvocation node) {
     if (_isDeferredLoadLibrary(node.target, node.methodName)) {
       // We are calling loadLibrary() on a deferred library prefix.
-      return _callHelper('loadLibrary()');
+      return runtimeCall('loadLibrary()');
     }
 
     if (node.operator?.lexeme == '?.' && isNullable(node.target)) {
@@ -3768,7 +3772,7 @@
     JS.Expression jsTarget = _emitTarget(target, element, isStatic);
     if (_isObjectMemberCall(target, name)) {
       assert(typeArgs == null); // Object methods don't take type args.
-      return _callHelper('#(#, #)', [name, jsTarget, args]);
+      return runtimeCall('#(#, #)', [name, jsTarget, args]);
     }
 
     jsTarget = _emitTargetAccess(jsTarget, jsName, element, node.methodName);
@@ -3823,7 +3827,7 @@
       jsCode += ', [#])';
     }
 
-    return _callHelper(jsCode, jsArgs);
+    return runtimeCall(jsCode, jsArgs);
   }
 
   bool _doubleEqIsIdentity(Expression left, Expression right) {
@@ -3856,7 +3860,7 @@
       {bool negated = false}) {
     if (arguments.length != 2) {
       // Shouldn't happen in typechecked code
-      return _callHelper(
+      return runtimeCall(
           'throw(Error("compile error: calls to `identical` require 2 args")');
     }
     var left = arguments[0];
@@ -4168,6 +4172,7 @@
       _emitAssert(node.condition, node.message);
 
   JS.Statement _emitAssert(Expression condition, Expression message) {
+    if (!options.enableAsserts) return new JS.EmptyStatement();
     // TODO(jmesserly): only emit in checked mode.
     var conditionType = condition.staticType;
     var jsCondition = _visitExpression(condition);
@@ -4175,15 +4180,15 @@
     if (conditionType is FunctionType &&
         conditionType.parameters.isEmpty &&
         conditionType.returnType == types.boolType) {
-      jsCondition = _callHelper('test(#())', jsCondition);
+      jsCondition = runtimeCall('test(#())', jsCondition);
     } else if (conditionType != types.boolType) {
-      jsCondition = _callHelper('dassert(#)', jsCondition);
+      jsCondition = runtimeCall('dassert(#)', jsCondition);
     } else if (isNullable(condition)) {
-      jsCondition = _callHelper('test(#)', jsCondition);
+      jsCondition = runtimeCall('test(#)', jsCondition);
     }
     return js.statement(' if (!#) #.assertFailed(#);', [
       jsCondition,
-      _runtimeModule,
+      runtimeModule,
       message != null ? [_visitExpression(message)] : []
     ]);
   }
@@ -4378,7 +4383,7 @@
       }
     }
 
-    return _callHelperStatement('defineLazy(#, { # });', [objExpr, accessors]);
+    return runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]);
   }
 
   PropertyAccessorElement _findAccessor(VariableElement element,
@@ -4584,7 +4589,7 @@
   }
 
   JS.Statement _nullParameterCheck(JS.Expression param) {
-    var call = _callHelper('argumentError((#))', [param]);
+    var call = runtimeCall('argumentError((#))', [param]);
     return js.statement('if (# == null) #;', [param, call]);
   }
 
@@ -4592,7 +4597,7 @@
     if (expr == null) return null;
     var jsExpr = _visitExpression(expr);
     if (!isNullable(expr)) return jsExpr;
-    return _callHelper('notNull(#)', jsExpr);
+    return runtimeCall('notNull(#)', jsExpr);
   }
 
   JS.Expression _emitEqualityOperator(BinaryExpression node, Token op) {
@@ -4640,7 +4645,7 @@
     if (isNullable(left)) {
       var code = negated ? '!#.equals(#, #)' : '#.equals(#, #)';
       return js.call(code,
-          [_runtimeModule, _visitExpression(left), _visitExpression(right)]);
+          [runtimeModule, _visitExpression(left), _visitExpression(right)]);
     }
 
     // Otherwise we emit a call to the == method.
@@ -4974,7 +4979,7 @@
   }
 
   JS.Expression _emitConst(JS.Expression expr()) =>
-      _cacheConst(() => _callHelper('const(#)', expr()));
+      _cacheConst(() => runtimeCall('const(#)', expr()));
 
   /// Returns a new expression, which can be be used safely *once* on the
   /// left hand side, and *once* on the right side of an assignment.
@@ -5193,7 +5198,7 @@
   visitPrefixedIdentifier(PrefixedIdentifier node) {
     if (_isDeferredLoadLibrary(node.prefix, node.identifier)) {
       // We are tearing off "loadLibrary" on a library prefix.
-      return _callHelper('loadLibrary');
+      return runtimeCall('loadLibrary');
     }
 
     if (isLibraryPrefix(node.prefix)) {
@@ -5277,7 +5282,7 @@
     var jsName = _emitMemberName(memberName,
         type: receiverType, isStatic: isStatic, element: accessor);
     if (isDynamicInvoke(receiver)) {
-      return _callHelper(
+      return runtimeCall(
           'dload$_replSuffix(#, #)', [_visitExpression(receiver), jsName]);
     }
 
@@ -5295,9 +5300,9 @@
     JS.Expression result;
     if (_isObjectMemberCall(receiver, memberName)) {
       if (_isObjectMethod(memberName)) {
-        result = _callHelper('bind(#, #)', [jsTarget, jsName]);
+        result = runtimeCall('bind(#, #)', [jsTarget, jsName]);
       } else {
-        result = _callHelper('#(#)', [memberName, jsTarget]);
+        result = runtimeCall('#(#)', [memberName, jsTarget]);
       }
     } else if (accessor is MethodElement &&
         _reifyTearoff(accessor, accessNode)) {
@@ -5306,10 +5311,10 @@
             _emitTargetAccess(jsTarget, jsName, accessor, memberId),
             accessor.type);
       } else if (isSuper) {
-        result = _callHelper('bind(this, #, #)',
+        result = runtimeCall('bind(this, #, #)',
             [jsName, _emitTargetAccess(jsTarget, jsName, accessor, memberId)]);
       } else {
-        result = _callHelper('bind(#, #)', [jsTarget, jsName]);
+        result = runtimeCall('bind(#, #)', [jsTarget, jsName]);
       }
     } else {
       result = _emitTargetAccess(jsTarget, jsName, accessor, memberId);
@@ -5318,7 +5323,7 @@
     var typeArgs = _getTypeArgs(accessor, resultType);
     return typeArgs == null
         ? result
-        : _callHelper('gbind(#, #)', [result, typeArgs]);
+        : runtimeCall('gbind(#, #)', [result, typeArgs]);
   }
 
   bool _reifyTearoff(ExecutableElement element, Expression node) {
@@ -5353,10 +5358,10 @@
       // dynamic dispatch
       var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name];
       if (dynamicHelper != null) {
-        return _callHelper('$dynamicHelper(#, #)',
+        return runtimeCall('$dynamicHelper(#, #)',
             [_visitExpression(target), _visitExpressionList(args)]);
       } else {
-        return _callHelper('dsend(#, #, [#])',
+        return runtimeCall('dsend(#, #, [#])',
             [_visitExpression(target), memberName, _visitExpressionList(args)]);
       }
     }
@@ -5408,12 +5413,12 @@
 
   @override
   JS.Expression visitThrowExpression(ThrowExpression node) {
-    return _callHelper('throw(#)', _visitExpression(node.expression));
+    return runtimeCall('throw(#)', _visitExpression(node.expression));
   }
 
   @override
   JS.Expression visitRethrowExpression(RethrowExpression node) {
-    return _callHelper('rethrow(#)', _visitExpression(_catchParameter));
+    return runtimeCall('rethrow(#)', _visitExpression(_catchParameter));
   }
 
   /// Visits a statement, and ensures the resulting AST handles block scope
@@ -5627,7 +5632,7 @@
         vars.add(stackVar.name);
         body.add(js.statement('let # = #.stackTrace(#);', [
           _emitVariableDef(stackVar),
-          _runtimeModule,
+          runtimeModule,
           _emitSimpleIdentifier(name)
         ]));
       }
@@ -5737,7 +5742,7 @@
       DartType elementType, List<JS.Expression> elements) {
     // dart.constList helper internally depends on _interceptors.JSArray.
     _declareBeforeUse(_jsArray);
-    return _callHelper('constList([#], #)', [elements, _emitType(elementType)]);
+    return runtimeCall('constList([#], #)', [elements, _emitType(elementType)]);
   }
 
   JS.Expression _emitList(DartType itemType, List<JS.Expression> items) {
@@ -5773,7 +5778,7 @@
       return js.call('new #.from(#)', [mapType, emitEntries()]);
     }
     var typeArgs = type.typeArguments;
-    return _cacheConst(() => _callHelper('constMap(#, #, #)',
+    return _cacheConst(() => runtimeCall('constMap(#, #, #)',
         [_emitType(typeArgs[0]), _emitType(typeArgs[1]), emitEntries()]));
   }
 
@@ -5826,7 +5831,7 @@
       }
     }
     return new JS.TaggedTemplate(
-        _callHelper('str'), new JS.TemplateString(strings, interpolations));
+        runtimeCall('str'), new JS.TemplateString(strings, interpolations));
   }
 
   @override
@@ -5977,10 +5982,10 @@
     }
     if (node is AsExpression && CoercionReifier.isImplicit(node)) {
       assert(node.staticType == types.boolType);
-      return _callHelper('dtest(#)', _visitExpression(node.expression));
+      return runtimeCall('dtest(#)', _visitExpression(node.expression));
     }
     var result = _visitExpression(node);
-    if (isNullable(node)) result = _callHelper('test(#)', result);
+    if (isNullable(node)) result = runtimeCall('test(#)', result);
     return result;
   }
 
@@ -6277,27 +6282,7 @@
     return DynamicTypeImpl.instance;
   }
 
-  JS.Expression _callHelper(String code, [args]) {
-    if (args is List) {
-      args.insert(0, _runtimeModule);
-    } else if (args != null) {
-      args = [_runtimeModule, args];
-    } else {
-      args = _runtimeModule;
-    }
-    return js.call('#.$code', args);
-  }
-
-  JS.Statement _callHelperStatement(String code, args) {
-    if (args is List) {
-      args.insert(0, _runtimeModule);
-    } else {
-      args = [_runtimeModule, args];
-    }
-    return js.statement('#.$code', args);
-  }
-
-  JS.Expression _throwUnsafe(String message) => _callHelper(
+  JS.Expression _throwUnsafe(String message) => runtimeCall(
       'throw(Error(#))', js.escapedString("compile error: $message"));
 
   JS.Node _unreachable(AstNode node) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index c06fbec..3b3ad50 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -8,6 +8,7 @@
 
 import 'package:analyzer/analyzer.dart'
     show AnalysisError, CompilationUnit, ErrorSeverity;
+import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/element/element.dart' show LibraryElement;
 import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
 import 'package:analyzer/file_system/physical_file_system.dart'
@@ -112,16 +113,19 @@
       context.resultProvider =
           new InputPackagesResultProvider(context, summaryData);
     }
-    options.declaredVariables.forEach(context.declaredVariables.define);
-    context.declaredVariables
-      ..define('dart.isVM', 'false')
+    var variables = <String, String>{};
+    variables.addAll(options.declaredVariables);
+    variables.addAll({
+      'dart.isVM': 'false',
       // TODO(vsm): Should this be hardcoded?
-      ..define('dart.library.html', 'true')
-      ..define('dart.library.io', 'false')
-      ..define('dart.library.ui', 'false')
-      ..define('dart.library.mirrors', 'false')
-      ..define('dart.library.isolate', 'false');
+      'dart.library.html': 'true',
+      'dart.library.io': 'false',
+      'dart.library.ui': 'false',
+      'dart.library.mirrors': 'false',
+      'dart.library.isolate': 'false'
+    });
 
+    context.declaredVariables = new DeclaredVariables.fromMap(variables);
     if (!context.analysisOptions.strongMode) {
       throw new ArgumentError('AnalysisContext must be strong mode');
     }
@@ -260,6 +264,9 @@
   /// Whether to preserve metdata only accessible via mirrors.
   final bool emitMetadata;
 
+  // Whether to enable assertions.
+  final bool enableAsserts;
+
   /// Whether to force compilation of code with static errors.
   final bool unsafeForceCompile;
 
@@ -287,6 +294,7 @@
       this.unsafeForceCompile: false,
       this.replCompile: false,
       this.emitMetadata: false,
+      this.enableAsserts: true,
       this.closure: false,
       this.bazelMapping: const {},
       this.summaryOutPath});
@@ -300,6 +308,7 @@
         unsafeForceCompile = args['unsafe-force-compile'] as bool,
         replCompile = args['repl-compile'] as bool,
         emitMetadata = args['emit-metadata'] as bool,
+        enableAsserts = args['enable-asserts'] as bool,
         closure = args['closure-experimental'] as bool,
         bazelMapping =
             _parseBazelMappings(args['bazel-mapping'] as List<String>),
@@ -323,22 +332,19 @@
       ..addFlag('inline-source-map',
           help: 'emit source mapping inline', defaultsTo: false, hide: hide)
       ..addFlag('emit-metadata',
-          help: 'emit metadata annotations queriable via mirrors',
-          defaultsTo: false,
-          hide: hide)
+          help: 'emit metadata annotations queriable via mirrors', hide: hide)
+      ..addFlag('enable-asserts',
+          help: 'enable assertions', defaultsTo: true, hide: hide)
       ..addFlag('closure-experimental',
           help: 'emit Closure Compiler-friendly code (experimental)',
-          defaultsTo: false,
           hide: hide)
       ..addFlag('unsafe-force-compile',
           help: 'Compile code even if it has errors. ಠ_ಠ\n'
               'This has undefined behavior!',
-          defaultsTo: false,
           hide: hide)
       ..addFlag('repl-compile',
           help: 'Compile code more permissively when in REPL mode\n'
               'allowing access to private members across library boundaries.',
-          defaultsTo: false,
           hide: hide)
       ..addMultiOption('bazel-mapping',
           help:
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 165028a..10e9782 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -19,6 +19,9 @@
   /// This lets DDC use the setter method's return value directly.
   final List<JS.Identifier> _operatorSetResultStack = [];
 
+  JS.Identifier runtimeModule;
+  final namedArgumentTemp = new JS.TemporaryId('opts');
+
   /// When compiling the body of a `operator []=` method, this will be non-null
   /// and will indicate the the value that should be returned from any `return;`
   /// statements.
@@ -87,4 +90,36 @@
     }
     return value != null ? value.toReturn() : new JS.Return();
   }
+
+  /// Prepends the `dart.` and then uses [js.call] to parse the specified JS
+  /// [code] template, passing [args].
+  ///
+  /// For example:
+  ///
+  ///     runtimeCall('asInt(#)', expr)
+  ///
+  /// Generates a JS AST representing:
+  ///
+  ///     dart.asInt(<expr>)
+  ///
+  JS.Expression runtimeCall(String code, [args]) {
+    if (args != null) {
+      var newArgs = <Object>[runtimeModule];
+      if (args is Iterable) {
+        newArgs.addAll(args);
+      } else {
+        newArgs.add(args);
+      }
+      args = newArgs;
+    } else {
+      args = runtimeModule;
+    }
+    return js.call('#.$code', args);
+  }
+
+  /// Calls [runtimeCall] and uses `toStatement()` to convert the resulting
+  /// expression into a statement.
+  JS.Statement runtimeStatement(String code, [args]) {
+    return runtimeCall(code, args).toStatement();
+  }
 }
diff --git a/pkg/dev_compiler/lib/src/compiler/type_utilities.dart b/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
index 23b34e7d..c33df46 100644
--- a/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
+++ b/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
@@ -193,7 +193,7 @@
   /// Given a type [type], and a JS expression [typeRep] which implements it,
   /// add the type and its representation to the table, returning an
   /// expression which implements the type (but which caches the value).
-  JS.Expression nameType(InterfaceType type, JS.Expression typeRep) {
+  JS.Expression nameType(ParameterizedType type, JS.Expression typeRep) {
     if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
       return typeRep;
     }
diff --git a/pkg/dev_compiler/lib/src/js_ast/template.dart b/pkg/dev_compiler/lib/src/js_ast/template.dart
index c52a3eb..5a06359 100644
--- a/pkg/dev_compiler/lib/src/js_ast/template.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/template.dart
@@ -154,14 +154,14 @@
   static Instantiator<T> same<T extends Node>(T node) => (arguments) => node;
   static Null makeNull(arguments) => null;
 
-  Instantiator visit(Node node) {
+  Instantiator visit<T extends Node>(T node) {
     if (forceCopy || analysis.containsInterpolatedNodes(node)) {
       return node.accept(this);
     }
-    return same(node);
+    return same<T>(node);
   }
 
-  Instantiator visitNullable(Node node) {
+  Instantiator visitNullable<T extends Node>(T node) {
     return node == null ? makeNull : visit(node);
   }
 
@@ -498,7 +498,7 @@
         node.keyword, declarationMakers.map((m) => m(a)).toList());
   }
 
-  Instantiator visitAssignment(Assignment node) {
+  Instantiator<Expression> visitAssignment(Assignment node) {
     Instantiator makeLeftHandSide = visit(node.leftHandSide);
     String op = node.op;
     Instantiator makeValue = visitNullable(node.value);
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index a3be2ea..f19890f 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -106,11 +106,13 @@
 
 Future<CompilerResult> _compile(List<String> args,
     {fe.InitializedCompilerState compilerState}) async {
+  // TODO(jmesserly): refactor options to share code with dartdevc CLI.
   var argParser = new ArgParser(allowTrailingOptions: true)
     ..addFlag('help',
         abbr: 'h', help: 'Display this message.', negatable: false)
     ..addOption('out', abbr: 'o', help: 'Output file (required).')
     ..addOption('packages', help: 'The package spec file to use.')
+    // TODO(jmesserly): add verbose help to show hidden options
     ..addOption('dart-sdk-summary',
         help: 'The path to the Dart SDK summary file.', hide: true)
     ..addMultiOption('summary',
@@ -120,7 +122,11 @@
     ..addFlag('source-map', help: 'emit source mapping', defaultsTo: true)
     ..addMultiOption('summary-input-dir')
     ..addOption('custom-app-scheme', defaultsTo: 'org-dartlang-app')
+    ..addFlag('emit-metadata',
+        help: '(deprecated) enables dart:mirrors for this module', hide: true)
+    ..addFlag('enable-asserts', help: 'enable assertions', defaultsTo: true)
     // Ignore dart2js options that we don't support in DDC.
+    // TODO(jmesserly): add ignore-unrecognized-flag support.
     ..addFlag('enable-enum', hide: true)
     ..addFlag('experimental-trust-js-interop-type-annotations', hide: true)
     ..addFlag('trust-type-annotations', hide: true)
@@ -200,8 +206,15 @@
 
   // TODO(jmesserly): Save .dill file so other modules can link in this one.
   //await writeComponentToBinary(component, output);
-  var jsModule = compileToJSModule(
-      result.component, result.inputSummaries, summaryUris, declaredVariables);
+  var component = result.component;
+
+  var compiler = new ProgramCompiler(component,
+      declaredVariables: declaredVariables,
+      emitMetadata: argResults['emit-metadata'] as bool,
+      enableAsserts: argResults['enable-asserts'] as bool);
+  var jsModule =
+      compiler.emitProgram(component, result.inputSummaries, summaryUris);
+
   var jsCode = jsProgramToCode(jsModule, moduleFormat,
       buildSourceMap: argResults['source-map'] as bool,
       jsUrl: path.toUri(output).toString(),
@@ -218,12 +231,6 @@
   return new CompilerResult(compilerState, true);
 }
 
-JS.Program compileToJSModule(Component p, List<Component> summaries,
-    List<Uri> summaryUris, Map<String, String> declaredVariables) {
-  var compiler = new ProgramCompiler(p, declaredVariables: declaredVariables);
-  return compiler.emitProgram(p, summaries, summaryUris);
-}
-
 /// The output of compiling a JavaScript module in a particular format.
 /// This was copied from module_compiler.dart class "JSModuleCode".
 class JSCode {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index a6e12f2..7b95975 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -66,9 +66,6 @@
   JS.Identifier _extensionSymbolsModule;
   final _extensionSymbols = new Map<String, JS.TemporaryId>();
 
-  JS.Identifier _runtimeModule;
-  final namedArgumentTemp = new JS.TemporaryId('opts');
-
   Set<Class> _pendingClasses;
 
   /// Temporary variables mapped to their corresponding JavaScript variable.
@@ -134,6 +131,7 @@
   final _superHelpers = new Map<String, JS.Method>();
 
   final bool emitMetadata;
+  final bool enableAsserts;
   final bool replCompile;
 
   final Map<String, String> declaredVariables;
@@ -206,9 +204,9 @@
   final NullableInference _nullableInference;
 
   factory ProgramCompiler(Component component,
-      // TODO(jmesserly): emitMetadata should default to false
-      {bool emitMetadata: true,
+      {bool emitMetadata: false,
       bool replCompile: false,
+      bool enableAsserts: true,
       Map<String, String> declaredVariables: const {}}) {
     var nativeTypes = new NativeTypeSet(component);
     var types = new TypeSchemaEnvironment(
@@ -216,12 +214,16 @@
     return new ProgramCompiler._(
         nativeTypes, new JSTypeRep(types, nativeTypes.sdk),
         emitMetadata: emitMetadata,
+        enableAsserts: enableAsserts,
         replCompile: replCompile,
         declaredVariables: declaredVariables);
   }
 
   ProgramCompiler._(NativeTypeSet nativeTypes, this._typeRep,
-      {this.emitMetadata, this.replCompile, this.declaredVariables})
+      {this.emitMetadata,
+      this.enableAsserts,
+      this.replCompile,
+      this.declaredVariables})
       : _extensionTypes = nativeTypes,
         types = _typeRep.types,
         coreTypes = nativeTypes.coreTypes,
@@ -276,15 +278,15 @@
     if (ddcRuntime != null) {
       // Don't allow these to be renamed when we're building the SDK.
       // There is JS code in dart:* that depends on their names.
-      _runtimeModule = new JS.Identifier('dart');
+      runtimeModule = new JS.Identifier('dart');
       _extensionSymbolsModule = new JS.Identifier('dartx');
       _nullableInference.allowNotNullDeclarations = true;
     } else {
       // Otherwise allow these to be renamed so users can write them.
-      _runtimeModule = new JS.TemporaryId('dart');
+      runtimeModule = new JS.TemporaryId('dart');
       _extensionSymbolsModule = new JS.TemporaryId('dartx');
     }
-    _typeTable = new TypeTable(_runtimeModule);
+    _typeTable = new TypeTable(runtimeModule);
 
     // Initialize our library variables.
     var items = <JS.ModuleItem>[];
@@ -299,7 +301,7 @@
 
     for (var library in libraries) {
       var libraryTemp = library == ddcRuntime
-          ? _runtimeModule
+          ? runtimeModule
           : new JS.TemporaryId(jsLibraryName(library));
       _libraries[library] = libraryTemp;
       emitLibrary(libraryTemp);
@@ -421,7 +423,7 @@
       var imports =
           libraries.map((l) => new JS.NameSpecifier(_imports[l])).toList();
       if (module == coreModuleName) {
-        imports.add(new JS.NameSpecifier(_runtimeModule));
+        imports.add(new JS.NameSpecifier(runtimeModule));
         imports.add(new JS.NameSpecifier(_extensionSymbolsModule));
       }
 
@@ -569,8 +571,8 @@
     var jsPeerNames = _extensionTypes.getNativePeers(c);
     if (jsPeerNames.length == 1 && c.typeParameters.isNotEmpty) {
       // Special handling for JSArray<E>
-      body.add(_callHelperStatement('setExtensionBaseClass(#, #.global.#);',
-          [className, _runtimeModule, jsPeerNames[0]]));
+      body.add(runtimeStatement('setExtensionBaseClass(#, #.global.#)',
+          [className, runtimeModule, jsPeerNames[0]]));
     }
 
     var finishGenericTypeTest = _emitClassTypeTests(c, className, body);
@@ -620,7 +622,7 @@
       genericArgs.add(js.call('(#) => { #; }', [jsFormals, deferredBaseClass]));
     }
 
-    var genericCall = _callHelper('generic(#)', [genericArgs]);
+    var genericCall = runtimeCall('generic(#)', [genericArgs]);
 
     var genericName = _emitTopLevelNameNoInterop(c, suffix: '\$');
     return js.statement('{ # = #; # = #(); }',
@@ -719,13 +721,16 @@
         mixinCtor = js.statement('#.#.call(this);', [
           emitClassRef(mixin),
           _usesMixinNew(mixin.classNode)
-              ? _callHelper('mixinNew')
+              ? runtimeCall('mixinNew')
               : _constructorName('')
         ]);
       }
 
       for (var ctor in superclass.constructors) {
+        var savedUri = _currentUri;
+        _currentUri = ctor.enclosingClass.fileUri;
         var jsParams = _emitFormalParameters(ctor.function);
+        _currentUri = savedUri;
         var ctorBody = <JS.Statement>[];
         if (mixinCtor != null) ctorBody.add(mixinCtor);
         var name = ctor.name.name;
@@ -742,7 +747,7 @@
 
     // Unroll mixins.
     if (shouldDefer(supertype)) {
-      deferredSupertypes.add(_callHelperStatement('setBaseClass(#, #)', [
+      deferredSupertypes.add(runtimeStatement('setBaseClass(#, #)', [
         getBaseClass(isMixinAliasClass(c) ? 0 : mixins.length),
         emitDeferredType(supertype),
       ]));
@@ -764,8 +769,8 @@
       var mixinClass = deferMixin ? emitDeferredType(m) : emitClassRef(m);
       var classExpr = deferMixin ? getBaseClass(0) : className;
 
-      mixinBody.add(
-          _callHelperStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
+      mixinBody
+          .add(runtimeStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
 
       if (methods.isNotEmpty) {
         // However we may need to add some methods to this class that call
@@ -774,7 +779,7 @@
         // We do this with the following pattern:
         //
         //     mixinMembers(C, class C$ extends M { <methods>  });
-        mixinBody.add(_callHelperStatement('mixinMembers(#, #)', [
+        mixinBody.add(runtimeStatement('mixinMembers(#, #)', [
           classExpr,
           new JS.ClassExpression(
               new JS.TemporaryId(getLocalClassName(c)), mixinClass, methods)
@@ -809,11 +814,11 @@
       hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(m.classNode);
 
       if (shouldDefer(m)) {
-        deferredSupertypes.add(_callHelperStatement('mixinMembers(#, #)',
+        deferredSupertypes.add(runtimeStatement('mixinMembers(#, #)',
             [getBaseClass(mixins.length - i), emitDeferredType(m)]));
       } else {
-        body.add(_callHelperStatement(
-            'mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
+        body.add(
+            runtimeStatement('mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
       }
 
       baseClass = mixinId;
@@ -848,7 +853,7 @@
       body.add(
           js.statement('(#[#] = function() { # }).prototype = #.prototype;', [
         className,
-        _callHelper('mixinNew'),
+        runtimeCall('mixinNew'),
         [_initializeFields(fields)],
         className
       ]));
@@ -870,7 +875,7 @@
           case 'Future':
           case 'Stream':
           case 'StreamSubscription':
-            return _callHelper('is' + interface.name);
+            return runtimeCall('is' + interface.name);
         }
       }
       return null;
@@ -908,13 +913,13 @@
             '  if (typeof o == "string" || o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_String(o) {'
             '  if (typeof o == "string" || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (c == coreTypes.functionClass) {
@@ -926,13 +931,13 @@
             '  if (typeof o == "function" || o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_String(o) {'
             '  if (typeof o == "function" || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (c == coreTypes.intClass) {
@@ -947,14 +952,14 @@
             '    return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_int(o) {'
             '  if ((typeof o == "number" && Math.floor(o) == o) || o == null)'
             '    return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (c == coreTypes.nullClass) {
@@ -965,13 +970,13 @@
             '  if (o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_Null(o) {'
             '  if (o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (c == coreTypes.numClass || c == coreTypes.doubleClass) {
@@ -983,13 +988,13 @@
             '  if (typeof o == "number" || o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_num(o) {'
             '  if (typeof o == "number" || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
       if (c == coreTypes.boolClass) {
@@ -1001,13 +1006,13 @@
             '  if (o === true || o === false || o == null) return o;'
             '  return #.as(o, #, false);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         body.add(js.statement(
             '#._check = function check_bool(o) {'
             '  if (o === true || o === false || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
-            [className, _runtimeModule, className]));
+            [className, runtimeModule, className]));
         return null;
       }
     }
@@ -1029,18 +1034,18 @@
               if (o == null || #.is(o) || #.is(o)) return o;
               return #.as(o, this, false);
             }
-            ''', [className, typeT, futureOfT, _runtimeModule]));
+            ''', [className, typeT, futureOfT, runtimeModule]));
         body.add(js.statement('''
             #._check = function check_FutureOr(o) {
               if (o == null || #.is(o) || #.is(o)) return o;
               return #.as(o, this, true);
             }
-            ''', [className, typeT, futureOfT, _runtimeModule]));
+            ''', [className, typeT, futureOfT, runtimeModule]));
         return null;
       }
     }
 
-    body.add(_callHelperStatement('addTypeTests(#);', [className]));
+    body.add(runtimeStatement('addTypeTests(#)', [className]));
 
     if (c.typeParameters.isEmpty) return null;
 
@@ -1065,8 +1070,7 @@
 
     // Return this `addTypeTests` call so we can emit it outside of the generic
     // type parameter scope.
-    return _callHelperStatement(
-        'addTypeTests(#, #);', [defaultInst, isClassSymbol]);
+    return runtimeStatement('addTypeTests(#, #)', [defaultInst, isClassSymbol]);
   }
 
   void _emitSymbols(Iterable<JS.TemporaryId> vars, List<JS.ModuleItem> body) {
@@ -1112,7 +1116,7 @@
     if (emitMetadata && metadata.isNotEmpty) {
       body.add(js.statement('#[#.metadata] = #;', [
         className,
-        _runtimeModule,
+        runtimeModule,
         _arrowFunctionWithLetScope(() => new JS.ArrayInitializer(
             metadata.map(_instantiateAnnotation).toList()))
       ]));
@@ -1141,7 +1145,7 @@
           .map((e) => _propertyName(JS.memberNameForDartMember(e)))
           .toList();
       body.add(js.statement('#.#(#, #);', [
-        _runtimeModule,
+        runtimeModule,
         helperName,
         className,
         new JS.ArrayInitializer(names, multiline: names.length > 4)
@@ -1162,7 +1166,7 @@
     if (c.implementedTypes.isNotEmpty) {
       body.add(js.statement('#[#.implements] = () => [#];', [
         className,
-        _runtimeModule,
+        runtimeModule,
         c.implementedTypes.map((i) => _emitType(i.asInterfaceType))
       ]));
     }
@@ -1173,10 +1177,10 @@
       if (!name.startsWith('Static')) {
         var proto = c == coreTypes.objectClass
             ? js.call('Object.create(null)')
-            : _callHelper('get${name}s(#.__proto__)', [className]);
+            : runtimeCall('get${name}s(#.__proto__)', [className]);
         elements.insert(0, new JS.Property(_propertyName('__proto__'), proto));
       }
-      body.add(_callHelperStatement('set${name}Signature(#, () => #)', [
+      body.add(runtimeStatement('set${name}Signature(#, () => #)', [
         className,
         new JS.ObjectInitializer(elements, multiline: elements.length > 1)
       ]));
@@ -1297,7 +1301,7 @@
     // Add static property dart._runtimeType to Object.
     // All other Dart classes will (statically) inherit this property.
     if (c == coreTypes.objectClass) {
-      body.add(_callHelperStatement('tagComputed(#, () => #.#);',
+      body.add(runtimeStatement('lazyFn(#, () => #.#)',
           [className, emitLibraryName(coreTypes.coreLibrary), 'Type']));
     }
 
@@ -1315,7 +1319,7 @@
           annotations.map(_instantiateAnnotation).toList()));
       _currentUri = savedUri;
     }
-    return _callHelper(
+    return runtimeCall(
         field.isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
   }
 
@@ -1540,7 +1544,7 @@
     if (expr == null) return null;
     var jsExpr = _visitExpression(expr);
     if (!isNullable(expr)) return jsExpr;
-    return _callHelper('notNull(#)', jsExpr);
+    return runtimeCall('notNull(#)', jsExpr);
   }
 
   /// If the class has only factory constructors, and it can be mixed in,
@@ -1562,7 +1566,7 @@
     var args = [className, name, value];
     if (name is JS.LiteralString &&
         JS.invalidStaticFieldName(name.valueWithoutQuotes)) {
-      return _callHelper('defineValue(#, #, #)', args);
+      return runtimeCall('defineValue(#, #, #)', args);
     }
     return js.call('#.# = #', args);
   }
@@ -1581,7 +1585,7 @@
           new JS.Method(_propertyName('constructor'), js.fun(r'''function() {
                   throw Error("use `new " + #.typeName(#.getReifiedType(this)) +
                       ".new(...)` to create a Dart object");
-              }''', [_runtimeModule, _runtimeModule])));
+              }''', [runtimeModule, runtimeModule])));
     }
 
     for (var m in c.fields) {
@@ -1624,9 +1628,10 @@
       }
     }
 
-    for (Member m in _classProperties.mockMembers.values) {
-      _addMockMembers(m, c, jsMethods);
-    }
+    _classProperties.mockMembers.forEach((String name, Member member) {
+      jsMethods
+          .add(_implementMockMember(member, c, isSetter: name.endsWith('=')));
+    });
 
     // If the type doesn't have an `iterator`, but claims to implement Iterable,
     // we inject the adaptor method here, as it's less code size to put the
@@ -1818,49 +1823,51 @@
   ///
   /// Same technique is applied if interface I has fields, and C doesn't declare
   /// neither the fields nor the corresponding getters and setters.
-  void _addMockMembers(Member member, Class c, List<JS.Method> jsMethods) {
+  JS.Method _implementMockMember(Member member, Class c, {bool isSetter}) {
     JS.Method implementMockMember(
-        List<TypeParameter> typeParameters,
+        ProcedureKind procedureKind, DartType returnType,
+        [List<TypeParameter> typeParameters,
         List<JS.Parameter> positionalParameters,
-        List<VariableDeclaration> namedParameters,
-        int requiredParameterCount,
-        ProcedureKind mockMemberKind,
-        DartType returnType) {
-      assert(mockMemberKind != ProcedureKind.Factory);
+        List<VariableDeclaration> namedParameters]) {
+      assert(procedureKind != ProcedureKind.Factory);
 
       var invocationProps = <JS.Property>[];
       addProperty(String name, JS.Expression value) {
         invocationProps.add(new JS.Property(js.string(name), value));
       }
 
-      var args = positionalParameters;
-      var typeParams = _emitTypeFormals(typeParameters);
-      var fnArgs = new List<JS.Parameter>.from(typeParams)..addAll(args);
-
+      var typeParams = _emitTypeFormals(typeParameters ?? []);
+      var fnArgs = new List<JS.Parameter>.from(typeParams);
       JS.Expression positionalArgs;
-      List<JS.Statement> optionalArgInit = [];
-      if (positionalParameters.length != requiredParameterCount) {
-        positionalArgs = new JS.TemporaryId('args');
-        optionalArgInit.add(js.statement('let # = [#]',
-            [positionalArgs, args.take(requiredParameterCount)]));
-        optionalArgInit.addAll(args.skip(requiredParameterCount).map((p) => js
-            .statement('if (# !== void 0) #.push(#)', [p, positionalArgs, p])));
+      if (procedureKind == ProcedureKind.Getter) {
+        addProperty('isGetter', js.boolean(true));
+        positionalArgs = new JS.ArrayInitializer([]);
+      } else if (procedureKind == ProcedureKind.Setter) {
+        addProperty('isSetter', js.boolean(true));
+        var valueArg = new JS.TemporaryId('value');
+        positionalArgs = new JS.ArrayInitializer([valueArg]);
+        fnArgs.add(valueArg);
       } else {
-        positionalArgs = new JS.ArrayInitializer(args);
-        if (namedParameters.isNotEmpty) {
-          fnArgs.add(namedArgumentTemp);
-          addProperty('namedArguments', namedArgumentTemp);
-        }
-      }
-
-      if (mockMemberKind != ProcedureKind.Getter &&
-          mockMemberKind != ProcedureKind.Setter) {
         addProperty('isMethod', js.boolean(true));
-      } else {
-        if (mockMemberKind == ProcedureKind.Getter) {
-          addProperty('isGetter', js.boolean(true));
-        } else if (mockMemberKind == ProcedureKind.Setter) {
-          addProperty('isSetter', js.boolean(true));
+        if (namedParameters.isNotEmpty) {
+          // Named parameters need to be emitted in the correct position (after
+          // positional arguments) so we can detect them reliably.
+          addProperty('namedArguments', namedArgumentTemp);
+          positionalArgs = new JS.ArrayInitializer(positionalParameters);
+          fnArgs.addAll(positionalParameters);
+          fnArgs.add(namedArgumentTemp);
+        } else {
+          // In case we have optional parameters, we need to use rest args,
+          // because sometimes mocks want to detect whether optional arguments
+          // were passed, and this does not work reliably with undefined (should
+          // not normally appear in DDC, but it can result from JS interop).
+          //
+          // TODO(jmesserly): perhaps we need to use rest args or destructuring
+          // to get reliable optional argument passing in other scenarios? It
+          // doesn't seem to occur outside of tests, perhaps due to the
+          // combination of mockito and protobufs.
+          positionalArgs = new JS.TemporaryId('args');
+          fnArgs.add(new JS.RestParameter(positionalArgs));
         }
       }
 
@@ -1870,7 +1877,7 @@
 
       var fnBody =
           js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
-        _runtimeModule,
+        runtimeModule,
         _declareMemberName(member),
         positionalArgs,
         new JS.ObjectInitializer(invocationProps)
@@ -1881,36 +1888,34 @@
         fnBody = js.call('#._check(#)', [_emitType(returnType), fnBody]);
       }
 
-      var fn = new JS.Fun(
-          fnArgs, js.block('{ #; return #; }', [optionalArgInit, fnBody]),
+      var fn = new JS.Fun(fnArgs, fnBody.toReturn().toBlock(),
           typeParams: typeParams);
 
       return new JS.Method(
           _declareMemberName(member,
               useExtension: _extensionTypes.isNativeClass(c)),
           fn,
-          isGetter: mockMemberKind == ProcedureKind.Getter,
-          isSetter: mockMemberKind == ProcedureKind.Setter,
+          isGetter: procedureKind == ProcedureKind.Getter,
+          isSetter: procedureKind == ProcedureKind.Setter,
           isStatic: false);
     }
 
     if (member is Field) {
-      jsMethods.add(implementMockMember(
-          [], [], [], 0, ProcedureKind.Getter, member.type));
-      if (!member.isFinal) {
-        jsMethods.add(implementMockMember([], [new JS.TemporaryId('value')], [],
-            1, ProcedureKind.Setter, new VoidType()));
+      if (isSetter) {
+        return implementMockMember(ProcedureKind.Setter, new VoidType());
+      } else {
+        return implementMockMember(ProcedureKind.Getter, member.type);
       }
     } else {
       var procedure = member as Procedure;
       var f = procedure.function;
-      jsMethods.add(implementMockMember(
+      assert(procedure.isSetter == isSetter);
+      return implementMockMember(
+          procedure.kind,
+          f.returnType,
           f.typeParameters,
           f.positionalParameters.map(_emitVariableRef).toList(),
-          f.namedParameters,
-          f.requiredParameterCount,
-          procedure.kind,
-          f.returnType));
+          f.namedParameters);
     }
   }
 
@@ -2044,7 +2049,7 @@
     return new JS.Method(
         js.call('Symbol.iterator'),
         js.call('function() { return new #.JsIterator(this.#); }', [
-          _runtimeModule,
+          runtimeModule,
           _emitMemberName('iterator', type: iterable.asInterfaceType)
         ]) as JS.Fun);
   }
@@ -2056,11 +2061,11 @@
       Class c, String jsPeerName, List<JS.Statement> body) {
     var className = _emitTopLevelName(c);
     if (isPrimitiveType(c.rawType)) {
-      body.add(_callHelperStatement(
-          'definePrimitiveHashCode(#.prototype)', className));
+      body.add(
+          runtimeStatement('definePrimitiveHashCode(#.prototype)', className));
     }
-    body.add(_callHelperStatement(
-        'registerExtension(#, #);', [js.string(jsPeerName), className]));
+    body.add(runtimeStatement(
+        'registerExtension(#, #)', [js.string(jsPeerName), className]));
   }
 
   JS.Statement _emitJSType(Class c) {
@@ -2077,7 +2082,7 @@
   void _emitTypedef(Typedef t) {
     var savedUri = _currentUri;
     _currentUri = t.fileUri;
-    var body = _callHelper('typedef(#, () => #)',
+    var body = runtimeCall('typedef(#, () => #)',
         [js.string(t.name, "'"), visitFunctionType(t.type)]);
 
     JS.Statement result;
@@ -2151,7 +2156,7 @@
     _currentUri = _currentLibrary.fileUri;
 
     _currentUri = savedUri;
-    return _callHelperStatement('defineLazy(#, { # });', [objExpr, accessors]);
+    return runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]);
   }
 
   JS.Fun _emitStaticFieldInitializer(Field field) {
@@ -2446,7 +2451,7 @@
     JS.PropertyAccess access;
     for (var part in parts) {
       access = new JS.PropertyAccess(
-          access ?? _callHelper('global'), js.escapedString(part, "'"));
+          access ?? runtimeCall('global'), js.escapedString(part, "'"));
     }
     return access;
   }
@@ -2464,7 +2469,7 @@
 
   void _emitLibraryAccessors(Iterable<Procedure> accessors) {
     if (accessors.isEmpty) return;
-    _moduleItems.add(_callHelperStatement('copyProperties(#, { # });', [
+    _moduleItems.add(runtimeStatement('copyProperties(#, { # })', [
       emitLibraryName(_currentLibrary),
       accessors.map(_emitLibraryAccessor).toList()
     ]));
@@ -2499,7 +2504,11 @@
 
     var nameExpr = _emitTopLevelName(p);
     body.add(js.statement('# = #', [nameExpr, fn]));
-    if (!isSdkInternalRuntime(_currentLibrary)) {
+    // Function types of top-level/static functions are only needed when
+    // dart:mirrors is enabled.
+    // TODO(jmesserly): do we even need this for mirrors, since statics are not
+    // commonly reflected on?
+    if (emitMetadata && _reifyFunctionType(p.function)) {
       body.add(
           _emitFunctionTagged(nameExpr, p.function.functionType, topLevel: true)
               .toStatement());
@@ -2513,7 +2522,7 @@
       {bool topLevel: false}) {
     var lazy = topLevel && !_typeIsLoaded(type);
     var typeRep = visitFunctionType(type, lazy: lazy);
-    return _callHelper(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
+    return runtimeCall(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
   }
 
   bool _typeIsLoaded(DartType type) {
@@ -2537,7 +2546,7 @@
 
   JS.Expression _emitInvalidNode(Node node, [String message = '']) {
     if (message.isNotEmpty) message += ' ';
-    return _callHelper('throwUnimplementedError(#)',
+    return runtimeCall('throwUnimplementedError(#)',
         [js.escapedString('node <${node.runtimeType}> $message`$node`')]);
   }
 
@@ -2548,13 +2557,13 @@
   visitInvalidType(type) => defaultDartType(type);
 
   @override
-  visitDynamicType(type) => _callHelper('dynamic');
+  visitDynamicType(type) => runtimeCall('dynamic');
 
   @override
-  visitVoidType(type) => _callHelper('void');
+  visitVoidType(type) => runtimeCall('void');
 
   @override
-  visitBottomType(type) => _callHelper('bottom');
+  visitBottomType(type) => runtimeCall('bottom');
 
   @override
   visitInterfaceType(type, {bool lowerGeneric: false}) {
@@ -2575,12 +2584,12 @@
     // Anonymous JS types do not have a corresponding concrete JS type so we
     // have to use a helper to define them.
     if (isJSAnonymousType(c)) {
-      return _callHelper(
+      return runtimeCall(
           'anonymousJSType(#)', js.escapedString(getLocalClassName(c)));
     }
     var jsName = _getJSNameWithoutGlobal(c);
     if (jsName != null) {
-      return _callHelper('lazyJSType(() => #, #)',
+      return runtimeCall('lazyJSType(() => #, #)',
           [_emitJSInteropForGlobal(jsName), js.escapedString(jsName)]);
     }
 
@@ -2674,7 +2683,7 @@
     } else {
       helperCall = 'fnType(#)';
     }
-    var typeRep = _callHelper(helperCall, [typeParts]);
+    var typeRep = runtimeCall(helperCall, [typeParts]);
     return _cacheTypes
         ? _typeTable.nameFunctionType(type, typeRep, lazy: lazy)
         : typeRep;
@@ -2896,7 +2905,7 @@
       var gen = emitGeneratorFn((_) => [_asyncStarController]);
 
       var returnType = _getExpectedReturnType(function, coreTypes.streamClass);
-      return _callHelper('asyncStar(#, #)', [_emitType(returnType), gen]);
+      return runtimeCall('asyncStar(#, #)', [_emitType(returnType), gen]);
     }
 
     assert(function.asyncMarker == AsyncMarker.Async);
@@ -3023,7 +3032,7 @@
       annotations.any(_nullableInference.isNullCheckAnnotation);
 
   JS.Statement _nullParameterCheck(JS.Expression param) {
-    var call = _callHelper('argumentError((#))', [param]);
+    var call = runtimeCall('argumentError((#))', [param]);
     return js.statement('if (# == null) #;', [param, call]);
   }
 
@@ -3049,7 +3058,7 @@
       List<TypeParameter> typeFormals, List<JS.Statement> body) {
     for (var t in typeFormals) {
       if (t.isGenericCovariantImpl) {
-        body.add(_callHelperStatement('checkTypeBound(#, #, #)', [
+        body.add(runtimeStatement('checkTypeBound(#, #, #)', [
           _emitType(new TypeParameterType(t)),
           _emitType(t.bound),
           _propertyName(t.name)
@@ -3058,26 +3067,6 @@
     }
   }
 
-  JS.Expression _callHelper(String code, [args]) {
-    if (args is List) {
-      args.insert(0, _runtimeModule);
-    } else if (args != null) {
-      args = [_runtimeModule, args];
-    } else {
-      args = _runtimeModule;
-    }
-    return js.call('#.$code', args);
-  }
-
-  JS.Statement _callHelperStatement(String code, args) {
-    if (args is List) {
-      args.insert(0, _runtimeModule);
-    } else {
-      args = [_runtimeModule, args];
-    }
-    return js.statement('#.$code', args);
-  }
-
   JS.Statement _visitStatement(Statement s) {
     if (s == null) return null;
     var result = s.accept(this) as JS.Statement;
@@ -3139,11 +3128,11 @@
 
     if (node is AsExpression && node.isTypeError) {
       assert(node.getStaticType(types) == types.boolType);
-      return _callHelper('dtest(#)', _visitExpression(node.operand));
+      return runtimeCall('dtest(#)', _visitExpression(node.operand));
     }
 
     var result = _visitExpression(node);
-    if (isNullable(node)) result = _callHelper('test(#)', result);
+    if (isNullable(node)) result = runtimeCall('test(#)', result);
     return result;
   }
 
@@ -3241,7 +3230,7 @@
 
   @override
   visitAssertStatement(AssertStatement node) {
-    // TODO(jmesserly): only emit in checked mode.
+    if (!enableAsserts) return new JS.EmptyStatement();
     var condition = node.condition;
     var conditionType = condition.getStaticType(types);
     var jsCondition = _visitExpression(condition);
@@ -3250,15 +3239,15 @@
     if (conditionType is FunctionType &&
         conditionType.requiredParameterCount == 0 &&
         conditionType.returnType == boolType) {
-      jsCondition = _callHelper('test(#())', jsCondition);
+      jsCondition = runtimeCall('test(#())', jsCondition);
     } else if (conditionType != boolType) {
-      jsCondition = _callHelper('dassert(#)', jsCondition);
+      jsCondition = runtimeCall('dassert(#)', jsCondition);
     } else if (isNullable(condition)) {
-      jsCondition = _callHelper('test(#)', jsCondition);
+      jsCondition = runtimeCall('test(#)', jsCondition);
     }
     return js.statement(' if (!#) #.assertFailed(#);', [
       jsCondition,
-      _runtimeModule,
+      runtimeModule,
       node.message != null ? [_visitExpression(node.message)] : []
     ]);
   }
@@ -3606,7 +3595,7 @@
         vars.add(stackTrace.name);
         body.add(js.statement('let # = #.stackTrace(#);', [
           _emitVariableDef(stackTrace),
-          _runtimeModule,
+          runtimeModule,
           _emitVariableRef(name)
         ]));
       }
@@ -3691,11 +3680,7 @@
     } else {
       declareFn = new JS.FunctionDeclaration(name, fn);
     }
-    // Function types of top-level/static functions are only needed when
-    // dart:mirrors is enabled.
-    // TODO(jmesserly): do we even need this for mirrors, since statics are not
-    // commonly reflected on?
-    if (emitMetadata && _reifyFunctionType(func)) {
+    if (_reifyFunctionType(func)) {
       declareFn = new JS.Block([
         declareFn,
         _emitFunctionTagged(_emitVariableRef(node.variable), func.functionType)
@@ -3804,25 +3789,25 @@
     // they can be hovered. Unfortunately this is not possible as Kernel does
     // not store this data.
     if (member == null) {
-      return _callHelper('dload$_replSuffix(#, #)', [jsReceiver, jsName]);
+      return runtimeCall('dload$_replSuffix(#, #)', [jsReceiver, jsName]);
     }
 
     if (_isObjectMemberCall(receiver, memberName)) {
       if (_isObjectMethod(memberName)) {
-        return _callHelper('bind(#, #)', [jsReceiver, jsName]);
+        return runtimeCall('bind(#, #)', [jsReceiver, jsName]);
       } else {
-        return _callHelper('#(#)', [memberName, jsReceiver]);
+        return runtimeCall('#(#)', [memberName, jsReceiver]);
       }
     } else if (_reifyTearoff(member)) {
-      return _callHelper('bind(#, #)', [jsReceiver, jsName]);
+      return runtimeCall('bind(#, #)', [jsReceiver, jsName]);
     } else {
       return new JS.PropertyAccess(jsReceiver, jsName);
     }
   }
 
-  // TODO(jmesserly): remove this. Instead handle REPL private name lookups in
-  // _emitMemberName (by using `dart.privateName` if we're in REPL mode,
-  // refactored from the current `dart._dhelperRepl`).
+  // TODO(jmesserly): can we encapsulate REPL name lookups and remove this?
+  // _emitMemberName would be a nice place to handle it, but we don't have
+  // access to the target expression there (needed for `dart.replNameLookup`).
   String get _replSuffix => replCompile ? 'Repl' : '';
 
   JS.Expression _emitPropertySet(
@@ -3835,7 +3820,7 @@
     var jsValue = _visitExpression(value);
 
     if (member == null) {
-      return _callHelper(
+      return runtimeCall(
           'dput$_replSuffix(#, #, #)', [jsReceiver, jsName, jsValue]);
     }
     return js.call('#.# = #', [jsReceiver, jsName, jsValue]);
@@ -3846,7 +3831,7 @@
     var target = node.interfaceTarget;
     var jsTarget = _emitSuperTarget(target);
     if (_reifyTearoff(target)) {
-      return _callHelper('bind(this, #, #)', [jsTarget.selector, jsTarget]);
+      return runtimeCall('bind(this, #, #)', [jsTarget.selector, jsTarget]);
     }
     return jsTarget;
   }
@@ -3924,7 +3909,7 @@
     }
     if (_isObjectMemberCall(receiver, name)) {
       assert(arguments.types.isEmpty); // Object methods don't take type args.
-      return _callHelper('#(#, #)', [name, jsReceiver, args]);
+      return runtimeCall('#(#, #)', [name, jsReceiver, args]);
     }
     // TODO(jmesserly): remove when Kernel desugars this for us.
     // Handle `o.m(a)` where `o.m` is a getter returning a class with `call`.
@@ -3972,7 +3957,7 @@
       jsCode += ', [#])';
     }
 
-    return _callHelper(jsCode, jsArgs);
+    return runtimeCall(jsCode, jsArgs);
   }
 
   bool _isDirectCallable(DartType t) =>
@@ -4269,7 +4254,7 @@
     // a measurable performance effect (possibly the helper is simple enough to
     // be inlined).
     if (isNullable(left)) {
-      return _callHelper(
+      return runtimeCall(
           'equals(#, #)', [_visitExpression(left), _visitExpression(right)]);
     }
 
@@ -4296,10 +4281,10 @@
       // dynamic dispatch
       var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name];
       if (dynamicHelper != null) {
-        return _callHelper('$dynamicHelper(#, #)',
+        return runtimeCall('$dynamicHelper(#, #)',
             [_visitExpression(receiver), _visitExpressionList(args)]);
       } else {
-        return _callHelper('dsend(#, #, [#])', [
+        return runtimeCall('dsend(#, #, [#])', [
           _visitExpression(receiver),
           memberName,
           _visitExpressionList(args)
@@ -4605,7 +4590,7 @@
       {bool negated = false}) {
     if (args.length != 2) {
       // Shouldn't happen in typechecked code
-      return _callHelper(
+      return runtimeCall(
           'throw(Error("compile error: calls to `identical` require 2 args")');
     }
     var left = args[0];
@@ -4799,7 +4784,7 @@
     }
     if (expectString) strings.add('');
     return new JS.TaggedTemplate(
-        _callHelper('str'), new JS.TemplateString(strings, interpolations));
+        runtimeCall('str'), new JS.TemplateString(strings, interpolations));
   }
 
   @override
@@ -4871,7 +4856,7 @@
         // TODO(jmesserly): fuse this with notNull check.
         // TODO(jmesserly): this does not correctly distinguish user casts from
         // required-for-soundness casts.
-        return _callHelper('asInt(#)', jsFrom);
+        return runtimeCall('asInt(#)', jsFrom);
       }
 
       // A no-op in JavaScript.
@@ -4924,14 +4909,14 @@
   }
 
   JS.Expression _emitConst(JS.Expression expr()) =>
-      _cacheConst(() => _callHelper('const(#)', expr()));
+      _cacheConst(() => runtimeCall('const(#)', expr()));
 
   @override
   visitTypeLiteral(TypeLiteral node) {
     var typeRep = _emitType(node.type);
     // If the type is a type literal expression in Dart code, wrap the raw
     // runtime type in a "Type" instance.
-    return _isInForeignJS ? typeRep : _callHelper('wrapType(#)', typeRep);
+    return _isInForeignJS ? typeRep : runtimeCall('wrapType(#)', typeRep);
   }
 
   @override
@@ -4939,12 +4924,12 @@
 
   @override
   visitRethrow(Rethrow node) {
-    return _callHelper('rethrow(#)', _emitVariableRef(_catchParameter));
+    return runtimeCall('rethrow(#)', _emitVariableRef(_catchParameter));
   }
 
   @override
   visitThrow(Throw node) =>
-      _callHelper('throw(#)', _visitExpression(node.expression));
+      runtimeCall('throw(#)', _visitExpression(node.expression));
 
   @override
   visitListLiteral(ListLiteral node) {
@@ -4960,7 +4945,7 @@
       DartType elementType, List<JS.Expression> elements) {
     // dart.constList helper internally depends on _interceptors.JSArray.
     _declareBeforeUse(_jsArrayClass);
-    return _callHelper('constList([#], #)', [elements, _emitType(elementType)]);
+    return runtimeCall('constList([#], #)', [elements, _emitType(elementType)]);
   }
 
   JS.Expression _emitList(DartType itemType, List<JS.Expression> items) {
@@ -4995,7 +4980,7 @@
       }
       return js.call('new #.from(#)', [mapType, emitEntries()]);
     }
-    return _cacheConst(() => _callHelper('constMap(#, #, #)',
+    return _cacheConst(() => runtimeCall('constMap(#, #, #)',
         [_emitType(node.keyType), _emitType(node.valueType), emitEntries()]));
   }
 
@@ -5068,14 +5053,14 @@
 
   @override
   visitInstantiation(Instantiation node) {
-    return _callHelper('gbind(#, #)', [
+    return runtimeCall('gbind(#, #)', [
       _visitExpression(node.expression),
       node.typeArguments.map(_emitType).toList()
     ]);
   }
 
   @override
-  visitLoadLibrary(LoadLibrary node) => _callHelper('loadLibrary()');
+  visitLoadLibrary(LoadLibrary node) => runtimeCall('loadLibrary()');
 
   // TODO(jmesserly): DDC loads all libraries eagerly.
   // See
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index 84fc2e4..9f49edb 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -281,6 +281,16 @@
     // called at runtime.)
     var concreteMembers = new HashSet<String>();
 
+    void addMember(Member m, bool classIsAbstract, {bool isSetter: false}) {
+      var name = m.name.name;
+      if (isSetter) name += '=';
+      if (classIsAbstract || m.isAbstract) {
+        mockMembers[name] = m;
+      } else {
+        concreteMembers.add(name);
+      }
+    }
+
     void visit(Class c, bool classIsAbstract) {
       if (c == null) return;
       visit(c.superclass, classIsAbstract);
@@ -288,13 +298,13 @@
       for (var i in c.implementedTypes) visit(i.classNode, true);
 
       for (var m in c.members) {
-        if (m is Constructor) continue;
-        if (m is Procedure && m.isStatic) continue;
-
-        if (classIsAbstract || m.isAbstract) {
-          mockMembers[m.name.name] = m;
-        } else {
-          concreteMembers.add(m.name.name);
+        if (m is Field) {
+          if (m.isStatic) continue;
+          addMember(m, classIsAbstract);
+          if (m.hasSetter) addMember(m, classIsAbstract, isSetter: true);
+        } else if (m is Procedure) {
+          if (m.isStatic) continue;
+          addMember(m, classIsAbstract, isSetter: m.isSetter);
         }
       }
     }
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
index 1b1e938..a3de057 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
@@ -510,7 +510,7 @@
       _isBrowserType(o)) {
     return o;
   } else if (JS('bool', '# instanceof Date', o)) {
-    var ms = JS('num', '#.getTime()', o);
+    num ms = JS('!', '#.getTime()', o);
     return new DateTime.fromMillisecondsSinceEpoch(ms);
   } else if (o is _DartObject &&
       JS('bool', 'dart.jsobject != dart.getReifiedType(#)', o)) {
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/js_util/dart2js/js_util_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/js_util/dart2js/js_util_dart2js.dart
index bb31232..0dfb1e5 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/js_util/dart2js/js_util_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/js_util/dart2js/js_util_dart2js.dart
@@ -72,7 +72,7 @@
   }
 
   if (JS('bool', '# instanceof Array', arguments)) {
-    int argumentCount = JS('int', '#.length', arguments);
+    int argumentCount = JS('!', '#.length', arguments);
     switch (argumentCount) {
       case 0:
         return JS('Object', 'new #()', constr);
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/collection_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/collection_patch.dart
index 546c00b..4af9548 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/collection_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/collection_patch.dart
@@ -186,7 +186,7 @@
       var k = key;
       var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
       if (buckets != null) {
-        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
           k = JS('', '#[#]', buckets, i);
           if (k == key) return true;
         }
@@ -204,7 +204,7 @@
       var k = key;
       var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
       if (buckets != null) {
-        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
           k = JS('', '#[#]', buckets, i);
           if (k == key) return JS('', '#', k);
         }
@@ -224,12 +224,12 @@
       var keyMap = _keyMap;
       @notNull
       var k = key;
-      var hash = JS('int', '# & 0x3ffffff', k.hashCode);
+      int hash = JS('!', '# & 0x3ffffff', k.hashCode);
       var buckets = JS('', '#.get(#)', keyMap, hash);
       if (buckets == null) {
         JS('', '#.set(#, [#])', keyMap, hash, key);
       } else {
-        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
           k = JS('', '#[#]', buckets, i);
           if (k == key) return false;
         }
@@ -255,7 +255,7 @@
       }
       JS('', '#.add(#)', map, key);
     }
-    if (length != JS('int', '#.size', map)) {
+    if (length != JS<int>('!', '#.size', map)) {
       _modifications = (_modifications + 1) & 0x3ffffff;
     }
   }
@@ -267,10 +267,10 @@
         dart.identityEquals)) {
       @notNull
       var k = key;
-      var hash = JS('int', '# & 0x3ffffff', k.hashCode);
+      int hash = JS('!', '# & 0x3ffffff', k.hashCode);
       var buckets = JS('', '#.get(#)', _keyMap, hash);
       if (buckets == null) return false; // not found
-      for (int i = 0, n = JS('int', '#.length', buckets);;) {
+      for (int i = 0, n = JS('!', '#.length', buckets);;) {
         k = JS('', '#[#]', buckets, i);
         if (k == key) {
           key = k;
@@ -294,7 +294,7 @@
 
   void clear() {
     var map = _map;
-    if (JS('int', '#.size', map) > 0) {
+    if (JS<int>('!', '#.size', map) > 0) {
       JS('', '#.clear()', map);
       JS('', '#.clear()', _keyMap);
       _modifications = (_modifications + 1) & 0x3ffffff;
@@ -339,7 +339,7 @@
     for (E key in objects) {
       JS('', '#.add(#)', map, key);
     }
-    if (length != JS('int', '#.size', map)) {
+    if (length != JS<int>('!', '#.size', map)) {
       _modifications = (_modifications + 1) & 0x3ffffff;
     }
   }
@@ -354,7 +354,7 @@
 
   void clear() {
     var map = _map;
-    if (JS('int', '#.size', map) > 0) {
+    if (JS<int>('!', '#.size', map) > 0) {
       JS('', '#.clear()', map);
       _modifications = (_modifications + 1) & 0x3ffffff;
     }
@@ -425,7 +425,7 @@
       var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
       if (buckets != null) {
         var equals = _equals;
-        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
           E k = JS('', '#[#]', buckets, i);
           if (equals(k, key)) return true;
         }
@@ -439,7 +439,7 @@
       var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
       if (buckets != null) {
         var equals = _equals;
-        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
           E k = JS('', '#[#]', buckets, i);
           if (equals(k, key)) return JS('', '#', k);
         }
@@ -450,13 +450,13 @@
 
   bool add(E key) {
     var keyMap = _keyMap;
-    var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+    var hash = JS<int>('!', '# & 0x3ffffff', _hashCode(key));
     var buckets = JS('', '#.get(#)', keyMap, hash);
     if (buckets == null) {
       JS('', '#.set(#, [#])', keyMap, hash, key);
     } else {
       var equals = _equals;
-      for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+      for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
         E k = JS('', '#[#]', buckets, i);
         if (equals(k, key)) return false;
       }
@@ -474,12 +474,12 @@
 
   bool remove(Object key) {
     if (key is E) {
-      var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+      var hash = JS<int>('!', '# & 0x3ffffff', _hashCode(key));
       var keyMap = _keyMap;
       var buckets = JS('', '#.get(#)', keyMap, hash);
       if (buckets == null) return false; // not found
       var equals = _equals;
-      for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+      for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
         E k = JS('', '#[#]', buckets, i);
         if (equals(k, key)) {
           if (n == 1) {
@@ -498,7 +498,7 @@
 
   void clear() {
     var map = _map;
-    if (JS('int', '#.size', map) > 0) {
+    if (JS<int>('!', '#.size', map) > 0) {
       JS('', '#.clear()', map);
       JS('', '#.clear()', _keyMap);
       _modifications = (_modifications + 1) & 0x3ffffff;
@@ -517,7 +517,7 @@
   int get _modifications;
 
   @notNull
-  int get length => JS('int', '#.size', _map);
+  int get length => JS<int>('!', '#.size', _map);
 
   @notNull
   bool get isEmpty => JS('bool', '#.size == 0', _map);
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index 21da3ab..b8ad752 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -368,7 +368,7 @@
     if (JS('bool', '# === void 0', _length)) {
       list = JS('', '[]');
     } else {
-      var length = JS('int', '#', _length);
+      int length = JS('!', '#', _length);
       if (_length == null || length < 0) {
         throw new ArgumentError(
             "Length must be a non-negative integer: $_length");
@@ -2603,7 +2603,7 @@
     var resultBits = new Uint8List(8);
 
     var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
-    if (length - 53 > maxDoubleExponent) return double.INFINITY;
+    if (length - 53 > maxDoubleExponent) return double.infinity;
 
     // The most significant bit is for the sign.
     if (_isNegative) resultBits[7] = 0x80;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/custom_hash_map.dart b/pkg/dev_compiler/tool/input_sdk/private/custom_hash_map.dart
index 3fa774e..578fbc1 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/custom_hash_map.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/custom_hash_map.dart
@@ -110,7 +110,7 @@
 
   void operator []=(K key, V value) {
     var keyMap = _keyMap;
-    var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+    int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
     var buckets = JS('', '#.get(#)', keyMap, hash);
     if (buckets == null) {
       JS('', '#.set(#, [#])', keyMap, hash, key);
@@ -134,7 +134,7 @@
 
   V putIfAbsent(K key, V ifAbsent()) {
     var keyMap = _keyMap;
-    var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+    int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
     var buckets = JS('', '#.get(#)', keyMap, hash);
     if (buckets == null) {
       JS('', '#.set(#, [#])', keyMap, hash, key);
@@ -154,7 +154,7 @@
 
   V remove(Object key) {
     if (key is K) {
-      var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+      int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
       var keyMap = _keyMap;
       var buckets = JS('', '#.get(#)', keyMap, hash);
       if (buckets == null) return null; // not found
@@ -180,7 +180,7 @@
 
   void clear() {
     var map = _map;
-    if (JS('int', '#.size', map) > 0) {
+    if (JS<int>('!', '#.size', map) > 0) {
       JS('', '#.clear()', map);
       JS('', '#.clear()', _keyMap);
       _modifications = (_modifications + 1) & 0x3ffffff;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
index 48ef1ea..0f0c078 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
@@ -314,8 +314,8 @@
   // symbol name.
   var coreObjProto = JS('', '#.prototype', Object);
   var names = getOwnPropertyNames(coreObjProto);
-  for (int i = 0; i < JS('int', '#.length', names); ++i) {
-    var name = JS('String', '#[#]', names, i);
+  for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
+    var name = JS<String>('!', '#[#]', names, i);
     if (name == 'constructor') continue;
     var desc = getOwnPropertyDescriptor(coreObjProto, name);
     defineProperty(jsProto, JS('', '#.#', dartx, name), desc);
@@ -413,10 +413,10 @@
     var member;
     var p = proto;
     for (;; p = JS('', '#.__proto__', p)) {
-      member = JS('', 'Object.getOwnPropertyDescriptor(#, #)', p, name);
+      member = getOwnPropertyDescriptor(p, name);
       if (member != null) break;
     }
-    JS('', 'Object.defineProperty(#, dartx[#], #)', proto, name, member);
+    defineProperty(proto, JS('', 'dartx[#]', name), member);
   }
 }
 
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index f094a48..6a36f63 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -91,6 +91,8 @@
   return result;
 }
 
+dloadRepl(obj, field) => dload(obj, replNameLookup(obj, field), false);
+
 // Warning: dload, dput, and dsend assume they are never called on methods
 // implemented by the Object base class as those methods can always be
 // statically resolved.
@@ -131,6 +133,9 @@
 // PageLoader code can generate the correct reified generic types.
 dputMirror(obj, field, value) => dput(obj, field, value, true);
 
+dputRepl(obj, field, value) =>
+    dput(obj, replNameLookup(obj, field), value, false);
+
 dput(obj, field, value, [mirrors = undefined]) {
   var f = _canonicalMember(obj, field);
   trackCall(obj);
@@ -153,12 +158,7 @@
 
 /// Check that a function of a given type can be applied to
 /// actuals.
-bool _checkApply(ftype, List actuals, namedActuals) {
-  // TODO(vsm): Remove when we no longer need mirrors metadata.
-  // An array is used to encode annotations attached to the type.
-  FunctionType type =
-      JS('!', '# instanceof Array ? #[0] : #', ftype, ftype, ftype);
-
+bool _checkApply(FunctionType type, List actuals, namedActuals) {
   // Check for too few required arguments.
   var actualsCount = JS('int', '#.length', actuals);
   var required = type.args;
@@ -274,6 +274,10 @@
     return $f.apply($obj, $args);
   }
 
+  // TODO(vsm): Remove when we no longer need mirrors metadata.
+  // An array is used to encode annotations attached to the type.
+  if ($ftype instanceof Array) $ftype = $ftype[0];
+
   // Apply type arguments
   if ($ftype instanceof $GenericFunctionType) {
     let formalCount = $ftype.formalCount;
@@ -290,7 +294,7 @@
     return callNSM();
   }
 
-  if (${_checkApply(ftype, args, named)}) {
+  if ($_checkApply($ftype, $args, $named)) {
     if ($typeArgs != null) $args = $typeArgs.concat($args);
     if ($named != null) $args.push($named);
     return $f.apply($obj, $args);
@@ -306,11 +310,11 @@
 
 /// Helper for REPL dynamic invocation variants that make a best effort to
 /// enable accessing private members across library boundaries.
-_dhelperRepl(object, field, callback) => JS('', '''(() => {
+replNameLookup(object, field) => JS('', '''(() => {
   let rawField = $field;
   if (typeof(field) == 'symbol') {
     // test if the specified field exists in which case it is safe to use it.
-    if ($field in $object) return $callback($field);
+    if ($field in $object) return $field;
 
     // Symbol is from a different library. Make a best effort to
     $field = $field.toString();
@@ -318,11 +322,11 @@
 
   } else if ($field.charAt(0) != '_') {
     // Not a private member so default call path is safe.
-    return $callback($field);
+    return $field;
   }
 
   // If the exact field name is present, invoke callback with it.
-  if ($field in $object) return $callback($field);
+  if ($field in $object) return $field;
 
   // TODO(jacobr): warn if there are multiple private members with the same
   // name which could happen if super classes in different libraries have
@@ -335,28 +339,21 @@
 
     for (let s = 0; s < symbols.length; s++) {
       let sym = symbols[s];
-      if (target == sym.toString()) return $callback(sym);
+      if (target == sym.toString()) return sym;
     }
     proto = proto.__proto__;
   }
   // We didn't find a plausible alternate private symbol so just fall back
   // to the regular field.
-  return $callback(rawField);
+  return rawField;
 })()''');
 
-dloadRepl(obj, field) => _dhelperRepl(obj, field, (f) => dload(obj, f, false));
-
-dputRepl(obj, field, value) =>
-    _dhelperRepl(obj, field, (f) => dput(obj, f, value, false));
-
-callMethodRepl(obj, method, typeArgs, args, named) => _dhelperRepl(
-    obj, method, (f) => callMethod(obj, f, typeArgs, args, method, named));
-
-dsendRepl(obj, method, args, [named = undefined]) =>
-    callMethodRepl(obj, method, null, args, named);
-
-dgsendRepl(obj, typeArgs, method, args, [named = undefined]) =>
-    callMethodRepl(obj, method, typeArgs, args, named);
+// TODO(jmesserly): the debugger extension hardcodes a call to this private
+// function. Fix that.
+@Deprecated('use replNameLookup')
+_dhelperRepl(obj, field, Function(Object) callback) {
+  return callback(replNameLookup(obj, field));
+}
 
 /// Shared code for dsend, dindex, and dsetindex.
 callMethod(obj, name, typeArgs, args, named, displayName) {
@@ -381,6 +378,12 @@
 dgsend(obj, typeArgs, method, args, [named = undefined]) =>
     callMethod(obj, method, typeArgs, args, named, method);
 
+dsendRepl(obj, method, args, [named = undefined]) =>
+    callMethod(obj, replNameLookup(obj, method), null, args, named, method);
+
+dgsendRepl(obj, typeArgs, method, args, [named = undefined]) =>
+    callMethod(obj, replNameLookup(obj, method), typeArgs, args, named, method);
+
 dindex(obj, index) => callMethod(obj, '_get', null, [index], null, '[]');
 
 dsetindex(obj, index, value) =>
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
index b1db5b6..874a3fa 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
@@ -44,16 +44,27 @@
 /// different from the above objects, and are created by calling `wrapType()`
 /// on a runtime type.
 
-/// Tag a closure with a type:
+/// Tag a closure with a type.
 ///
-/// `dart.fn(closure, t)` marks [closure] has having the runtime type [t].
-fn(closure, t) {
-  JS('', '#[#] = #', closure, _runtimeType, t);
+/// `dart.fn(closure, type)` marks [closure] with the provided runtime [type].
+fn(closure, type) {
+  JS('', '#[#] = #', closure, _runtimeType, type);
   return closure;
 }
 
-lazyFn(closure, computeType) {
-  defineLazyGetter(closure, _runtimeType, computeType);
+/// Tag a closure with a type that's computed lazily.
+///
+/// `dart.fn(closure, type)` marks [closure] with a getter that uses
+/// [computeType] to return the runtime type.
+///
+/// The getter/setter replaces the property with a value property, so the
+/// resulting function is compatible with [fn] and the type can be set again
+/// safely.
+lazyFn(closure, Object Function() computeType) {
+  defineAccessor(closure, _runtimeType,
+      get: () => defineValue(closure, _runtimeType, computeType()),
+      set: (value) => defineValue(closure, _runtimeType, value),
+      configurable: true);
   return closure;
 }
 
@@ -64,7 +75,7 @@
 
 getFunctionType(obj) {
   // TODO(vsm): Encode this properly on the function for Dart-generated code.
-  var args = JS('List', 'Array(#.length).fill(#)', obj, dynamic);
+  var args = JS<List>('!', 'Array(#.length).fill(#)', obj, dynamic);
   return fnType(bottom, args, JS('', 'void 0'));
 }
 
@@ -113,16 +124,15 @@
   return JS('Type', '#[#] = #', type, _typeObject, new WrappedType(type));
 }
 
+/// The symbol used to store the cached `Type` object associated with a class.
+final _typeObject = JS('', 'Symbol("typeObject")');
+
 /// Given a WrappedType, return the internal runtime type object.
 unwrapType(WrappedType obj) => obj._wrappedType;
 
 /// Return the module name for a raw library object.
 getModuleName(value) => JS('', '#[#]', value, _moduleName);
 
-void tagComputed(value, compute) {
-  defineGetter(value, _runtimeType, compute);
-}
-
 var _loadedModules = JS('', 'new Map()');
 var _loadedSourceMaps = JS('', 'new Map()');
 
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
index e9b6a27..3215fa5 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
@@ -7,9 +7,6 @@
 
 final metadata = JS('', 'Symbol("metadata")');
 
-/// The symbol used to store the cached `Type` object associated with a class.
-final _typeObject = JS('', 'Symbol("typeObject")');
-
 /// Types in dart are represented internally at runtime as follows.
 ///
 ///   - Normal nominal types, produced from classes, are represented
@@ -445,7 +442,7 @@
 
     var result = name + '<';
     var allDynamic = true;
-    for (var i = 0, n = JS('int', '#.length', typeArgs); i < n; ++i) {
+    for (int i = 0, n = JS('!', '#.length', typeArgs); i < n; ++i) {
       if (i > 0) result += ', ';
       var typeArg = JS('', '#[#]', typeArgs, i);
       if (JS('bool', '# !== #', typeArg, _dynamic)) allDynamic = false;
@@ -503,7 +500,7 @@
     // purposes, such as when an error happens or if someone calls
     // `Type.toString()`. So we could recover them lazily rather than eagerly.
     // Alternatively we could synthesize new names.
-    var str = JS('String', '#.toString()', _instantiateTypeParts);
+    String str = JS('!', '#.toString()', _instantiateTypeParts);
     var hasParens = str[0] == '(';
     var end = str.indexOf(hasParens ? ')' : '=>');
     if (hasParens) {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
index 590f850..80a84de 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
@@ -16,23 +16,16 @@
     JS('', 'Object.defineProperty');
 
 defineValue(obj, name, value) {
-  defineProperty(obj, name,
-      JS('', '{ value: #, configurable: true, writable: true }', value));
+  defineAccessor(obj, name, value: value, configurable: true, writable: true);
   return value;
 }
 
-void defineGetter(obj, name, getter) {
-  defineProperty(obj, name, JS('', '{get: #}', getter));
-}
-
-void defineLazyGetter(obj, name, compute) {
-  var x = null;
-  defineProperty(
-      obj,
-      name,
-      JS('', '{ get: () => # != null ? # : # = #(), configurable: true }', x, x,
-          x, compute));
-}
+final Function(Object, Object,
+    {Object get,
+    Object set,
+    Object value,
+    bool configurable,
+    bool writable}) defineAccessor = JS('', 'Object.defineProperty');
 
 final Function(Object, Object) getOwnPropertyDescriptor =
     JS('', 'Object.getOwnPropertyDescriptor');
@@ -71,9 +64,7 @@
 /// After initial get or set, it will replace itself with a value property.
 // TODO(jmesserly): reusing descriptor objects has been shown to improve
 // performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
-defineLazyField(to, name, desc) => JS(
-    '',
-    '''(() => {
+defineLazyField(to, name, desc) => JS('', '''(() => {
   let init = $desc.get;
   let value = null;
   $desc.get = function() {
@@ -99,7 +90,7 @@
 })()''');
 
 copyTheseProperties(to, from, names) {
-  for (var i = 0, n = JS('int', '#.length', names); i < n; ++i) {
+  for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
     var name = JS('', '#[#]', names, i);
     if (name == 'constructor') continue;
     copyProperty(to, from, name);
diff --git a/pkg/dev_compiler/tool/input_sdk/private/identity_hash_map.dart b/pkg/dev_compiler/tool/input_sdk/private/identity_hash_map.dart
index 8de3f2f..c2671eb 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/identity_hash_map.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/identity_hash_map.dart
@@ -60,7 +60,7 @@
 
   void operator []=(K key, V value) {
     var map = _map;
-    var length = JS('int', '#.size', map);
+    int length = JS('!', '#.size', map);
     JS('', '#.set(#, #)', map, key, value);
     if (length != JS('int', '#.size', map)) {
       _modifications = (_modifications + 1) & 0x3ffffff;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
index 32da1d3..20aee27 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
@@ -126,7 +126,7 @@
   // TODO(jmesserly): remove these once we canonicalize tearoffs.
   operator ==(other) {
     if (other == null) return false;
-    var boundObj = JS('Object|Null', '#._boundObject', this);
+    var boundObj = JS<Object>('', '#._boundObject', this);
     if (boundObj == null) return JS('bool', '# === #', this, other);
     return JS(
         'bool',
@@ -138,10 +138,10 @@
   }
 
   get hashCode {
-    var boundObj = JS('Object|Null', '#._boundObject', this);
+    var boundObj = JS<Object>('', '#._boundObject', this);
     if (boundObj == null) return identityHashCode(this);
 
-    var boundMethod = JS('Object', '#._boundMethod', this);
+    var boundMethod = JS<Object>('!', '#._boundMethod', this);
     int hash = (17 * 31 + boundObj.hashCode) & 0x1fffffff;
     return (hash * 31 + identityHashCode(boundMethod)) & 0x1fffffff;
   }
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
index 089d959..7157533 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
@@ -166,7 +166,7 @@
         source)) {
       return _parseDoubleError(source, handleError);
     }
-    var result = JS('num', r'parseFloat(#)', source);
+    num result = JS('!', r'parseFloat(#)', source);
     if (result.isNaN) {
       var trimmed = source.trim();
       if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
@@ -194,7 +194,7 @@
     if (performance == null) return;
     if (JS('bool', 'typeof #.now != "function"', performance)) return;
     timerFrequency = 1000000;
-    timerTicks = () => (1000 * JS('num', '#.now()', performance)).floor();
+    timerTicks = () => (1000 * JS<num>('!', '#.now()', performance)).floor();
   }
 
   static int timerFrequency;
@@ -359,10 +359,10 @@
     var jsMonth = month - 1;
     num value;
     if (isUtc) {
-      value = JS('num', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day,
+      value = JS('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day,
           hours, minutes, seconds, milliseconds);
     } else {
-      value = JS('num', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
+      value = JS('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
           jsMonth, day, hours, minutes, seconds, milliseconds);
     }
     if (value.isNaN ||
@@ -374,14 +374,14 @@
     return value;
   }
 
-  static patchUpY2K(value, years, isUtc) {
+  static num patchUpY2K(value, years, isUtc) {
     var date = JS('', r'new Date(#)', value);
     if (isUtc) {
-      JS('num', r'#.setUTCFullYear(#)', date, years);
+      JS('', r'#.setUTCFullYear(#)', date, years);
     } else {
-      JS('num', r'#.setFullYear(#)', date, years);
+      JS('', r'#.setFullYear(#)', date, years);
     }
-    return JS('num', r'#.valueOf()', date);
+    return JS('!', r'#.valueOf()', date);
   }
 
   // Lazily keep a JS Date stored in the JS object.
@@ -397,49 +397,49 @@
   // that the result is really an integer, because the JavaScript implementation
   // may return -0.0 instead of 0.
 
-  static getYear(DateTime receiver) {
+  static int getYear(DateTime receiver) {
     return (receiver.isUtc)
         ? JS('int', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver))
         : JS('int', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getMonth(DateTime receiver) {
+  static int getMonth(DateTime receiver) {
     return (receiver.isUtc)
         ? JS('int', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver))
         : JS('int', r'#.getMonth() + 1', lazyAsJsDate(receiver));
   }
 
-  static getDay(DateTime receiver) {
+  static int getDay(DateTime receiver) {
     return (receiver.isUtc)
         ? JS('int', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver))
         : JS('int', r'(#.getDate() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getHours(DateTime receiver) {
+  static int getHours(DateTime receiver) {
     return (receiver.isUtc)
         ? JS('int', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver))
         : JS('int', r'(#.getHours() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getMinutes(DateTime receiver) {
+  static int getMinutes(DateTime receiver) {
     return (receiver.isUtc)
         ? JS('int', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver))
         : JS('int', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getSeconds(DateTime receiver) {
+  static int getSeconds(DateTime receiver) {
     return (receiver.isUtc)
         ? JS('int', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver))
         : JS('int', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getMilliseconds(DateTime receiver) {
+  static int getMilliseconds(DateTime receiver) {
     return (receiver.isUtc)
         ? JS('int', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver))
         : JS('int', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getWeekday(DateTime receiver) {
+  static int getWeekday(DateTime receiver) {
     int weekday = (receiver.isUtc)
         ? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver))
         : JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver));
@@ -447,9 +447,9 @@
     return (weekday + 6) % 7 + 1;
   }
 
-  static valueFromDateString(str) {
+  static num valueFromDateString(str) {
     if (str is! String) throw argumentErrorValue(str);
-    var value = JS('num', r'Date.parse(#)', str);
+    num value = JS('!', r'Date.parse(#)', str);
     if (value.isNaN) throw argumentErrorValue(str);
     return value;
   }
@@ -572,7 +572,7 @@
 final _stackTrace = JS('', 'Symbol("_stackTrace")');
 StackTrace getTraceFromException(exception) {
   var error = dart.recordJsError(exception);
-  var trace = JS('StackTrace|Null', '#[#]', error, _stackTrace);
+  StackTrace trace = JS('', '#[#]', error, _stackTrace);
   if (trace != null) return trace;
   trace = new _StackTrace(error);
   JS('', '#[#] = #', error, _stackTrace, trace);
@@ -599,7 +599,7 @@
     String trace;
     if (JS('bool', '# !== null', _exception) &&
         JS('bool', 'typeof # === "object"', _exception)) {
-      trace = JS("String|Null", r"#.stack", _exception);
+      trace = JS("", r"#.stack", _exception);
       if (trace != null && stackTraceMapper != null) {
         trace = stackTraceMapper(trace);
       }
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
index 1694f8e..270f571 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
@@ -246,8 +246,8 @@
       var unwrapped = dart.unwrapType(_cls);
       // Only get metadata directly embedded on this class, not its
       // superclasses.
-      var fn = JS(
-          'Function|Null',
+      Function fn = JS(
+          '',
           'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null',
           unwrapped,
           unwrapped);
@@ -288,53 +288,64 @@
         _declarations[symbol] =
             new JsMethodMirror._instanceMethod(this, symbol, ft);
       });
+
+      getterType(type) {
+        if (JS('bool', '# instanceof Array', type)) {
+          var array = JS('', '#.slice()', type);
+          type = JS('', '#[0]', array);
+          JS('', '#[0] = #', array, dart.fnType(type, []));
+          return array;
+        } else {
+          return dart.fnType(type, []);
+        }
+      }
+
       var getters = _toDartMap(dart.getGetters(unwrapped));
       getters.forEach((symbol, type) {
-        var name = getName(symbol);
-        if (JS('bool', '# instanceof Array', type)) {
-          JS('', '#[0] = #(#[0], [])', type, dart.fnType, type);
-        } else {
-          type = dart.fnType(type, []);
-        }
         _declarations[symbol] =
-            new JsMethodMirror._instanceMethod(this, symbol, type);
+            new JsMethodMirror._instanceMethod(this, symbol, getterType(type));
       });
+
+      setterType(type) {
+        if (JS('bool', '# instanceof Array', type)) {
+          var array = JS('', '#.slice()', type);
+          type = JS('', '#[0]', array);
+          JS('', '#[0] = #', array, dart.fnType(dart.void_, [type]));
+          return array;
+        } else {
+          return dart.fnType(dart.void_, [type]);
+        }
+      }
+
       var setters = _toDartMap(dart.getSetters(unwrapped));
       setters.forEach((symbol, type) {
         var name = getName(symbol) + '=';
         // Create a separate symbol for the setter.
         symbol = new PrivateSymbol(name, _getESSymbol(symbol));
-        var ft = dart.fnType(dart.void_, [type]);
         _declarations[symbol] =
-            new JsMethodMirror._instanceMethod(this, symbol, ft);
+            new JsMethodMirror._instanceMethod(this, symbol, setterType(type));
       });
+
       var staticFields = _toDartMap(dart.getStaticFields(unwrapped));
       staticFields.forEach((symbol, t) {
         _declarations[symbol] = new JsVariableMirror._fromField(symbol, t);
       });
       var statics = _toDartMap(dart.getStaticMethods(unwrapped));
       statics.forEach((symbol, ft) {
-        var name = getName(symbol);
         _declarations[symbol] =
             new JsMethodMirror._staticMethod(this, symbol, ft);
       });
+
       var staticGetters = _toDartMap(dart.getStaticGetters(unwrapped));
       staticGetters.forEach((symbol, type) {
-        var name = getName(symbol);
-        if (JS('bool', '# instanceof Array', type)) {
-          JS('', '#[0] = #(#[0], [])', type, dart.fnType, type);
-        } else {
-          type = dart.fnType(type, []);
-        }
         _declarations[symbol] =
-            new JsMethodMirror._staticMethod(this, symbol, type);
+            new JsMethodMirror._staticMethod(this, symbol, getterType(type));
       });
+
       var staticSetters = _toDartMap(dart.getStaticSetters(unwrapped));
       staticSetters.forEach((symbol, type) {
-        var name = getName(symbol);
-        var ft = dart.fnType(dart.void_, [type]);
         _declarations[symbol] =
-            new JsMethodMirror._staticMethod(this, symbol, ft);
+            new JsMethodMirror._staticMethod(this, symbol, setterType(type));
       });
       _declarations =
           new Map<Symbol, DeclarationMirror>.unmodifiable(_declarations);
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_number.dart b/pkg/dev_compiler/tool/input_sdk/private/js_number.dart
index eb86702..31a5f5d 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_number.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_number.dart
@@ -192,16 +192,16 @@
   static String _handleIEtoString(String result) {
     // Result is probably IE's untraditional format for large numbers,
     // e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16).
-    var match = JS('List|Null',
-        r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
+    var match = JS<List>(
+        '', r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
     if (match == null) {
       // Then we don't know how to handle it at all.
       throw new UnsupportedError("Unexpected toString result: $result");
     }
-    result = JS('String', '#', match[1]);
-    int exponent = JS("int", "+#", match[3]);
+    result = JS('!', '#', match[1]);
+    int exponent = JS("!", "+#", match[3]);
     if (match[2] != null) {
-      result = JS('String', '# + #', result, match[2]);
+      result = JS('!', '# + #', result, match[2]);
       exponent -= JS<int>('!', '#.length', match[2]);
     }
     return result + "0" * exponent;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_string.dart b/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
index 65b77a8..9b57bf3 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
@@ -36,11 +36,11 @@
   }
 
   Match matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) {
-    final stringLength = JS('int', '#.length', string);
+    int stringLength = JS('!', '#.length', string);
     if (start < 0 || start > stringLength) {
       throw new RangeError.range(start, 0, stringLength);
     }
-    final thisLength = JS('int', '#.length', this);
+    int thisLength = JS('!', '#.length', this);
     if (start + thisLength > stringLength) return null;
     for (int i = 0; i < thisLength; i++) {
       if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) {
@@ -286,7 +286,7 @@
 
     // Start by doing JS trim. Then check if it leaves a NEL at
     // either end of the string.
-    final result = JS('String', '#.trim()', this);
+    String result = JS('!', '#.trim()', this);
     final length = result.length;
     if (length == 0) return result;
     int firstCode = result.codeUnitAt(0);
@@ -454,7 +454,7 @@
   }
 
   @notNull
-  bool get isEmpty => JS('int', '#.length', this) == 0;
+  bool get isEmpty => JS<int>('!', '#.length', this) == 0;
 
   @notNull
   bool get isNotEmpty => !isEmpty;
@@ -479,9 +479,9 @@
     // TODO(ahe): This method shouldn't have to use JS. Update when our
     // optimizations are smarter.
     int hash = 0;
-    int length = JS('int', '#.length', this);
+    int length = JS('!', '#.length', this);
     for (int i = 0; i < length; i++) {
-      hash = 0x1fffffff & (hash + JS('int', r'#.charCodeAt(#)', this, i));
+      hash = 0x1fffffff & (hash + JS<int>('!', r'#.charCodeAt(#)', this, i));
       hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
       hash = JS('int', '# ^ (# >> 6)', hash, hash);
     }
diff --git a/pkg/dev_compiler/tool/input_sdk/private/linked_hash_map.dart b/pkg/dev_compiler/tool/input_sdk/private/linked_hash_map.dart
index 8cc2af5..ea366ca 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/linked_hash_map.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/linked_hash_map.dart
@@ -68,7 +68,7 @@
   LinkedMap.from(JSArray entries) {
     var map = _map;
     var keyMap = _keyMap;
-    for (int i = 0, n = JS('int', '#.length', entries); i < n; i += 2) {
+    for (int i = 0, n = JS('!', '#.length', entries); i < n; i += 2) {
       K key = JS('', '#[#]', entries, i);
       V value = JS('', '#[#]', entries, i + 1);
       if (key == null) {
@@ -82,7 +82,7 @@
   }
 
   @notNull
-  int get length => JS('int', '#.size', _map);
+  int get length => JS<int>('!', '#.size', _map);
 
   @notNull
   bool get isEmpty => JS('bool', '#.size == 0', _map);
@@ -103,7 +103,7 @@
       var k = key;
       var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
       if (buckets != null) {
-        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
           k = JS('', '#[#]', buckets, i);
           if (k == key) return true;
         }
@@ -132,7 +132,7 @@
       }
       JS('', '#.set(#, #)', _map, key, value);
     });
-    if (length != JS('int', '#.size', map)) {
+    if (length != JS<int>('!', '#.size', map)) {
       _modifications = (_modifications + 1) & 0x3ffffff;
     }
   }
@@ -146,7 +146,7 @@
       var k = key;
       var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
       if (buckets != null) {
-        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
           k = JS('', '#[#]', buckets, i);
           if (k == key) return JS('', '#.get(#)', _map, k);
         }
@@ -166,7 +166,7 @@
     var map = _map;
     int length = JS('', '#.size', map);
     JS('', '#.set(#, #)', map, key, value);
-    if (length != JS('int', '#.size', map)) {
+    if (length != JS<int>('!', '#.size', map)) {
       _modifications = (_modifications + 1) & 0x3ffffff;
     }
   }
@@ -180,12 +180,12 @@
         dart.identityEquals)) {
       @notNull
       K k = key;
-      var hash = JS('int', '# & 0x3ffffff', k.hashCode);
+      var hash = JS<int>('!', '# & 0x3ffffff', k.hashCode);
       var buckets = JS('', '#.get(#)', _keyMap, hash);
       if (buckets == null) {
         JS('', '#.set(#, [#])', _keyMap, hash, key);
       } else {
-        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+        for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
           k = JS('', '#[#]', buckets, i);
           if (k == key) return JS('', '#.get(#)', map, k);
         }
@@ -207,10 +207,10 @@
         dart.identityEquals)) {
       @notNull
       var k = key;
-      var hash = JS('int', '# & 0x3ffffff', k.hashCode);
+      var hash = JS<int>('!', '# & 0x3ffffff', k.hashCode);
       var buckets = JS('', '#.get(#)', _keyMap, hash);
       if (buckets == null) return null; // not found
-      for (int i = 0, n = JS('int', '#.length', buckets);;) {
+      for (int i = 0, n = JS('!', '#.length', buckets);;) {
         k = JS('', '#[#]', buckets, i);
         if (k == key) {
           key = k;
@@ -234,7 +234,7 @@
 
   void clear() {
     var map = _map;
-    if (JS('int', '#.size', map) > 0) {
+    if (JS<int>('!', '#.size', map) > 0) {
       JS('', '#.clear()', map);
       JS('', '#.clear()', _keyMap);
       _modifications = (_modifications + 1) & 0x3ffffff;
@@ -244,13 +244,13 @@
 
 @NoReifyGeneric()
 K putLinkedMapKey<K>(@notNull K key, keyMap) {
-  var hash = JS('int', '# & 0x3ffffff', key.hashCode);
+  var hash = JS<int>('!', '# & 0x3ffffff', key.hashCode);
   var buckets = JS('', '#.get(#)', keyMap, hash);
   if (buckets == null) {
     JS('', '#.set(#, [#])', keyMap, hash, key);
     return key;
   }
-  for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+  for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
     @notNull
     K k = JS('', '#[#]', buckets, i);
     if (k == key) return k;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/native_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/native_helper.dart
index 063edc7..cc214e8 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/native_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/native_helper.dart
@@ -4,19 +4,6 @@
 
 part of dart._js_helper;
 
-/**
- * Sets a JavaScript property on an object.
- */
-void defineProperty(var obj, String property, var value) {
-  JS(
-      'void',
-      'Object.defineProperty(#, #, '
-      '{value: #, enumerable: false, writable: true, configurable: true})',
-      obj,
-      property,
-      value);
-}
-
 // Obsolete in dart dev compiler. Added only so that the same version of
 // dart:html can be used in dart2js an dev compiler.
 F convertDartClosureToJS<F>(F closure, int arity) {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart b/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
index 73b1741..b108a7c 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
@@ -151,7 +151,7 @@
 
   int get offsetInBytes => _storage.offsetInBytes;
 
-  int get elementSizeInBytes => Float32x4List.BYTES_PER_ELEMENT;
+  int get elementSizeInBytes => Float32x4List.bytesPerElement;
 
   int get length => _storage.length ~/ 4;
 
@@ -229,7 +229,7 @@
 
   int get offsetInBytes => _storage.offsetInBytes;
 
-  int get elementSizeInBytes => Int32x4List.BYTES_PER_ELEMENT;
+  int get elementSizeInBytes => Int32x4List.bytesPerElement;
 
   int get length => _storage.length ~/ 4;
 
@@ -306,7 +306,7 @@
 
   int get offsetInBytes => _storage.offsetInBytes;
 
-  int get elementSizeInBytes => Float64x2List.BYTES_PER_ELEMENT;
+  int get elementSizeInBytes => Float64x2List.bytesPerElement;
 
   int get length => _storage.length ~/ 2;
 
@@ -451,9 +451,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 4` is greater than the length of this object.
    */
-  double getFloat32(int byteOffset,
-          [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _getFloat32(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+  double getFloat32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getFloat32(byteOffset, Endian.little == endian);
 
   @JSName('getFloat32')
   @Returns('double')
@@ -467,9 +466,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 8` is greater than the length of this object.
    */
-  double getFloat64(int byteOffset,
-          [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _getFloat64(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+  double getFloat64(int byteOffset, [Endian endian = Endian.big]) =>
+      _getFloat64(byteOffset, Endian.little == endian);
 
   @JSName('getFloat64')
   @Returns('double')
@@ -485,8 +483,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 2` is greater than the length of this object.
    */
-  int getInt16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _getInt16(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+  int getInt16(int byteOffset, [Endian endian = Endian.big]) =>
+      _getInt16(byteOffset, Endian.little == endian);
 
   @JSName('getInt16')
   @Returns('int')
@@ -502,8 +500,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 4` is greater than the length of this object.
    */
-  int getInt32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _getInt32(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+  int getInt32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getInt32(byteOffset, Endian.little == endian);
 
   @JSName('getInt32')
   @Returns('int')
@@ -519,7 +517,7 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 8` is greater than the length of this object.
    */
-  int getInt64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
+  int getInt64(int byteOffset, [Endian endian = Endian.big]) {
     throw new UnsupportedError('Int64 accessor not supported by dart2js.');
   }
 
@@ -542,8 +540,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 2` is greater than the length of this object.
    */
-  int getUint16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _getUint16(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+  int getUint16(int byteOffset, [Endian endian = Endian.big]) =>
+      _getUint16(byteOffset, Endian.little == endian);
 
   @JSName('getUint16')
   @Returns('int')
@@ -558,8 +556,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 4` is greater than the length of this object.
    */
-  int getUint32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _getUint32(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+  int getUint32(int byteOffset, [Endian endian = Endian.big]) =>
+      _getUint32(byteOffset, Endian.little == endian);
 
   @JSName('getUint32')
   @Returns('int')
@@ -574,7 +572,7 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 8` is greater than the length of this object.
    */
-  int getUint64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
+  int getUint64(int byteOffset, [Endian endian = Endian.big]) {
     throw new UnsupportedError('Uint64 accessor not supported by dart2js.');
   }
 
@@ -605,9 +603,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 4` is greater than the length of this object.
    */
-  void setFloat32(int byteOffset, num value,
-          [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _setFloat32(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+  void setFloat32(int byteOffset, num value, [Endian endian = Endian.big]) =>
+      _setFloat32(byteOffset, value, Endian.little == endian);
 
   @JSName('setFloat32')
   void _setFloat32(int byteOffset, num value, [bool littleEndian]) native;
@@ -620,9 +617,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 8` is greater than the length of this object.
    */
-  void setFloat64(int byteOffset, num value,
-          [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _setFloat64(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+  void setFloat64(int byteOffset, num value, [Endian endian = Endian.big]) =>
+      _setFloat64(byteOffset, value, Endian.little == endian);
 
   @JSName('setFloat64')
   void _setFloat64(int byteOffset, num value, [bool littleEndian]) native;
@@ -636,9 +632,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 2` is greater than the length of this object.
    */
-  void setInt16(int byteOffset, int value,
-          [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _setInt16(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setInt16(byteOffset, value, Endian.little == endian);
 
   @JSName('setInt16')
   void _setInt16(int byteOffset, int value, [bool littleEndian]) native;
@@ -652,9 +647,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 4` is greater than the length of this object.
    */
-  void setInt32(int byteOffset, int value,
-          [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _setInt32(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setInt32(byteOffset, value, Endian.little == endian);
 
   @JSName('setInt32')
   void _setInt32(int byteOffset, int value, [bool littleEndian]) native;
@@ -668,8 +662,7 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 8` is greater than the length of this object.
    */
-  void setInt64(int byteOffset, int value,
-      [Endianness endian = Endianness.BIG_ENDIAN]) {
+  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) {
     throw new UnsupportedError('Int64 accessor not supported by dart2js.');
   }
 
@@ -693,9 +686,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 2` is greater than the length of this object.
    */
-  void setUint16(int byteOffset, int value,
-          [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _setUint16(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setUint16(byteOffset, value, Endian.little == endian);
 
   @JSName('setUint16')
   void _setUint16(int byteOffset, int value, [bool littleEndian]) native;
@@ -709,9 +701,8 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 4` is greater than the length of this object.
    */
-  void setUint32(int byteOffset, int value,
-          [Endianness endian = Endianness.BIG_ENDIAN]) =>
-      _setUint32(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _setUint32(byteOffset, value, Endian.little == endian);
 
   @JSName('setUint32')
   void _setUint32(int byteOffset, int value, [bool littleEndian]) native;
@@ -725,8 +716,7 @@
    * Throws [RangeError] if [byteOffset] is negative, or
    * `byteOffset + 8` is greater than the length of this object.
    */
-  void setUint64(int byteOffset, int value,
-      [Endianness endian = Endianness.BIG_ENDIAN]) {
+  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) {
     throw new UnsupportedError('Uint64 accessor not supported by dart2js.');
   }
 
diff --git a/pkg/dev_compiler/tool/input_sdk/private/profile.dart b/pkg/dev_compiler/tool/input_sdk/private/profile.dart
index a325e27..8e3dd82 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/profile.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/profile.dart
@@ -59,7 +59,7 @@
     // Ratio between total record count and sampled records count.
     var recordRatio = _totalCallRecords / _callMethodRecords.length;
     for (var record in _callMethodRecords) {
-      var stackStr = JS('String', '#.stack', record.jsError);
+      String stackStr = JS<String>('!', '#.stack', record.jsError);
       var frames = stackStr.split('\n');
       // Skip first two lines as the first couple frames are from the dart
       // runtime.
diff --git a/pkg/dev_compiler/tool/input_sdk/private/string_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/string_helper.dart
index c6f26fc..354716a 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/string_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/string_helper.dart
@@ -11,12 +11,12 @@
 
 @notNull
 String substring1Unchecked(receiver, startIndex) {
-  return JS('String', '#.substring(#)', receiver, startIndex);
+  return JS('!', '#.substring(#)', receiver, startIndex);
 }
 
 @notNull
 String substring2Unchecked(receiver, startIndex, endIndex) {
-  return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex);
+  return JS('!', '#.substring(#, #)', receiver, startIndex, endIndex);
 }
 
 @notNull
@@ -119,7 +119,7 @@
 }
 
 @notNull
-String stringReplaceJS(receiver, replacer, replacement) {
+String stringReplaceJS(String receiver, replacer, String replacement) {
   // The JavaScript String.replace method recognizes replacement
   // patterns in the replacement string. Dart does not have that
   // behavior.
@@ -292,7 +292,7 @@
 @notNull
 String stringReplaceRangeUnchecked(
     String receiver, int start, int end, String replacement) {
-  var prefix = JS('String', '#.substring(0, #)', receiver, start);
-  var suffix = JS('String', '#.substring(#)', receiver, end);
+  String prefix = JS('!', '#.substring(0, #)', receiver, start);
+  String suffix = JS('!', '#.substring(#)', receiver, end);
   return "$prefix$replacement$suffix";
 }
diff --git a/pkg/dev_compiler/tool/kernel_sdk.dart b/pkg/dev_compiler/tool/kernel_sdk.dart
index 2cc7b9c..f8cb4e7 100755
--- a/pkg/dev_compiler/tool/kernel_sdk.dart
+++ b/pkg/dev_compiler/tool/kernel_sdk.dart
@@ -10,6 +10,7 @@
 import 'package:dev_compiler/src/compiler/module_builder.dart';
 import 'package:dev_compiler/src/kernel/target.dart';
 import 'package:dev_compiler/src/kernel/command.dart';
+import 'package:dev_compiler/src/kernel/compiler.dart';
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 import 'package:front_end/src/api_prototype/kernel_generator.dart';
 import 'package:kernel/kernel.dart';
@@ -45,7 +46,8 @@
   await new Directory(outputDir).create(recursive: true);
   await writeComponentToBinary(component, outputPath);
 
-  var jsModule = compileToJSModule(component, [], [], {});
+  var jsModule = new ProgramCompiler(component, declaredVariables: {})
+      .emitProgram(component, [], []);
   var moduleFormats = {
     'amd': ModuleFormat.amd,
     'common': ModuleFormat.common,
diff --git a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
index f5066ed..45bec4f 100644
--- a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
@@ -97,7 +97,7 @@
   Future<String> readAsString() async {
     List<int> bytes = await readAsBytes();
     try {
-      return UTF8.decode(bytes);
+      return utf8.decode(bytes);
     } on FormatException catch (e) {
       throw new FileSystemException(uri, e.message);
     }
@@ -118,10 +118,10 @@
   /// If no file exists, one is created.  If a file exists already, it is
   /// overwritten.
   void writeAsStringSync(String s) {
-    // Note: the return type of UTF8.encode is List<int>, but in practice it
+    // Note: the return type of utf8.encode is List<int>, but in practice it
     // always returns Uint8List.  We rely on that for efficiency, so that we
     // don't have to make an extra copy.
-    _update(uri, UTF8.encode(s) as Uint8List);
+    _update(uri, utf8.encode(s) as Uint8List);
   }
 
   void _update(Uri uri, Uint8List data) {
diff --git a/pkg/front_end/lib/src/base/api_signature.dart b/pkg/front_end/lib/src/base/api_signature.dart
index f809dbb..80937d6 100644
--- a/pkg/front_end/lib/src/base/api_signature.dart
+++ b/pkg/front_end/lib/src/base/api_signature.dart
@@ -83,7 +83,7 @@
    */
   void addDouble(double d) {
     _makeRoom(8);
-    _data.setFloat64(_offset, d, Endianness.LITTLE_ENDIAN);
+    _data.setFloat64(_offset, d, Endian.little);
     _offset += 8;
   }
 
@@ -92,7 +92,7 @@
    */
   void addInt(int i) {
     _makeRoom(4);
-    _data.setUint32(_offset, i, Endianness.LITTLE_ENDIAN);
+    _data.setUint32(_offset, i, Endian.little);
     _offset += 4;
   }
 
@@ -100,7 +100,7 @@
    * Collect a string.
    */
   void addString(String s) {
-    List<int> bytes = UTF8.encode(s);
+    List<int> bytes = utf8.encode(s);
     addInt(bytes.length);
     addBytes(bytes);
   }
diff --git a/pkg/front_end/lib/src/base/flat_buffers.dart b/pkg/front_end/lib/src/base/flat_buffers.dart
index 6733ae1..3449a3b 100644
--- a/pkg/front_end/lib/src/base/flat_buffers.dart
+++ b/pkg/front_end/lib/src/base/flat_buffers.dart
@@ -57,19 +57,15 @@
   Uint8List _asUint8LIst(int offset, int length) =>
       _buffer.buffer.asUint8List(_buffer.offsetInBytes + offset, length);
 
-  double _getFloat64(int offset) =>
-      _buffer.getFloat64(offset, Endianness.LITTLE_ENDIAN);
+  double _getFloat64(int offset) => _buffer.getFloat64(offset, Endian.little);
 
-  int _getInt32(int offset) =>
-      _buffer.getInt32(offset, Endianness.LITTLE_ENDIAN);
+  int _getInt32(int offset) => _buffer.getInt32(offset, Endian.little);
 
   int _getInt8(int offset) => _buffer.getInt8(offset);
 
-  int _getUint16(int offset) =>
-      _buffer.getUint16(offset, Endianness.LITTLE_ENDIAN);
+  int _getUint16(int offset) => _buffer.getUint16(offset, Endian.little);
 
-  int _getUint32(int offset) =>
-      _buffer.getUint32(offset, Endianness.LITTLE_ENDIAN);
+  int _getUint32(int offset) => _buffer.getUint32(offset, Endian.little);
 
   int _getUint8(int offset) => _buffer.getUint8(offset);
 
@@ -453,7 +449,7 @@
     if (value != def) {
       return _strings.putIfAbsent(value, () {
         // TODO(scheglov) optimize for ASCII strings
-        List<int> bytes = UTF8.encode(value);
+        List<int> bytes = utf8.encode(value);
         int length = bytes.length;
         _prepare(4, 1, additionalBytes: length);
         Offset<String> result = new Offset(_tail);
@@ -528,15 +524,15 @@
   }
 
   static void _setFloat64AtTail(ByteData _buf, int tail, double x) {
-    _buf.setFloat64(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+    _buf.setFloat64(_buf.lengthInBytes - tail, x, Endian.little);
   }
 
   static void _setInt32AtTail(ByteData _buf, int tail, int x) {
-    _buf.setInt32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+    _buf.setInt32(_buf.lengthInBytes - tail, x, Endian.little);
   }
 
   static void _setUint32AtTail(ByteData _buf, int tail, int x) {
-    _buf.setUint32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+    _buf.setUint32(_buf.lengthInBytes - tail, x, Endian.little);
   }
 
   static void _setUint8AtTail(ByteData _buf, int tail, int x) {
@@ -665,7 +661,7 @@
     if (_isLatin(bytes)) {
       return new String.fromCharCodes(bytes);
     }
-    return UTF8.decode(bytes);
+    return utf8.decode(bytes);
   }
 
   static bool _isLatin(Uint8List bytes) {
@@ -941,14 +937,14 @@
    */
   void output(ByteData buf, int bufOffset) {
     // VTable size.
-    buf.setUint16(bufOffset, numOfUint16 * 2, Endianness.LITTLE_ENDIAN);
+    buf.setUint16(bufOffset, numOfUint16 * 2, Endian.little);
     bufOffset += 2;
     // Table size.
-    buf.setUint16(bufOffset, tableSize, Endianness.LITTLE_ENDIAN);
+    buf.setUint16(bufOffset, tableSize, Endian.little);
     bufOffset += 2;
     // Field offsets.
     for (int fieldOffset in fieldOffsets) {
-      buf.setUint16(bufOffset, fieldOffset, Endianness.LITTLE_ENDIAN);
+      buf.setUint16(bufOffset, fieldOffset, Endian.little);
       bufOffset += 2;
     }
   }
diff --git a/pkg/front_end/lib/src/base/libraries_specification.dart b/pkg/front_end/lib/src/base/libraries_specification.dart
index addde5e..2f9f553 100644
--- a/pkg/front_end/lib/src/base/libraries_specification.dart
+++ b/pkg/front_end/lib/src/base/libraries_specification.dart
@@ -88,7 +88,7 @@
 /// close attention to change them consistently.
 
 // TODO(sigmund): move this file to a shared package.
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
 
 import '../fasta/util/relativize.dart';
 
@@ -122,7 +122,7 @@
     if (json == null) return const LibrariesSpecification();
     var jsonData;
     try {
-      var data = JSON.decode(json);
+      var data = jsonDecode(json);
       if (data is! Map) {
         return _reportError('top-level specification is not a map');
       }
@@ -196,7 +196,7 @@
   /// Serialize this specification to json.
   ///
   /// If possible serializes paths relative to [outputUri].
-  String toJsonString(Uri outputUri) => JSON.encode(toJsonMap(outputUri));
+  String toJsonString(Uri outputUri) => jsonEncode(toJsonMap(outputUri));
 
   Map toJsonMap(Uri outputUri) {
     var result = {};
diff --git a/pkg/front_end/lib/src/byte_store/protected_file_byte_store.dart b/pkg/front_end/lib/src/byte_store/protected_file_byte_store.dart
index ccc2480..44d9156 100644
--- a/pkg/front_end/lib/src/byte_store/protected_file_byte_store.dart
+++ b/pkg/front_end/lib/src/byte_store/protected_file_byte_store.dart
@@ -133,7 +133,7 @@
   static String _keysReadText(RandomAccessFile file) {
     file.setPositionSync(0);
     List<int> bytes = file.readSync(file.lengthSync());
-    return UTF8.decode(bytes);
+    return utf8.decode(bytes);
   }
 
   static void _keysWrite(RandomAccessFile file, ProtectedKeys keys) {
diff --git a/pkg/front_end/lib/src/fasta/colors.dart b/pkg/front_end/lib/src/fasta/colors.dart
index c993caa..a59fe06 100644
--- a/pkg/front_end/lib/src/fasta/colors.dart
+++ b/pkg/front_end/lib/src/fasta/colors.dart
@@ -6,7 +6,7 @@
 // merge these two packages.
 library colors;
 
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonEncode;
 
 import 'dart:io' show Platform, Process, ProcessResult, stderr, stdout;
 
@@ -166,7 +166,7 @@
   if (lines.length != 2) {
     if (context.options.verbose) {
       print("Not enabling colors, unexpected output from tput: "
-          "${JSON.encode(result.stdout)}.");
+          "${jsonEncode(result.stdout)}.");
     }
     return false;
   }
@@ -175,7 +175,7 @@
   if (int.parse(numberOfColors, onError: (_) => -1) < 8) {
     if (context.options.verbose) {
       print("Not enabling colors, less than 8 colors supported: "
-          "${JSON.encode(numberOfColors)}.");
+          "${jsonEncode(numberOfColors)}.");
     }
     return false;
   }
@@ -184,7 +184,7 @@
   if (ALL_CODES != allCodes) {
     if (context.options.verbose) {
       print("Not enabling colors, color codes don't match: "
-          "${JSON.encode(ALL_CODES)} != ${JSON.encode(allCodes)}.");
+          "${jsonEncode(ALL_CODES)} != ${jsonEncode(allCodes)}.");
     }
     return false;
   }
diff --git a/pkg/front_end/lib/src/fasta/deprecated_problems.dart b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
index 935e73f..8ec0ce2 100644
--- a/pkg/front_end/lib/src/fasta/deprecated_problems.dart
+++ b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async' show Future;
 
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonEncode;
 
 import 'dart:io'
     show ContentType, HttpClient, HttpClientRequest, SocketException, stderr;
@@ -116,7 +116,7 @@
   if (charOffset != null) data["offset"] = charOffset;
   data["error"] = safeToString(error);
   data["trace"] = "$trace";
-  String json = JSON.encode(data);
+  String json = jsonEncode(data);
   HttpClient client = new HttpClient();
   try {
     Uri serverUri = Uri.parse(defaultServerAddress);
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 f6c436d..2b6c733 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
@@ -4,7 +4,7 @@
 
 library fasta.dill_library_builder;
 
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode;
 
 import 'package:kernel/ast.dart'
     show
@@ -87,7 +87,7 @@
     if (name == "_exports#") {
       Field field = member;
       StringLiteral string = field.initializer;
-      unserializableExports = JSON.decode(string.value);
+      unserializableExports = jsonDecode(string.value);
     } else {
       addBuilder(name, new DillMemberBuilder(member, this), member.fileOffset);
     }
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 55c6075..41f5b16 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1299,20 +1299,84 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)> templateDuplicatedName =
     const Template<Message Function(String name)>(
-        messageTemplate: r"""Duplicated name: '#name'.""",
+        messageTemplate: r"""'#name' is already declared in this scope.""",
         withArguments: _withArgumentsDuplicatedName);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Message Function(String name)> codeDuplicatedName =
     const Code<Message Function(String name)>(
-  "DuplicatedName",
-  templateDuplicatedName,
-);
+        "DuplicatedName", templateDuplicatedName,
+        severity: Severity.error);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 Message _withArgumentsDuplicatedName(String name) {
   return new Message(codeDuplicatedName,
-      message: """Duplicated name: '$name'.""", arguments: {'name': name});
+      message: """'$name' is already declared in this scope.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)> templateDuplicatedNameCause =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Previous declaration of '#name'.""",
+        withArguments: _withArgumentsDuplicatedNameCause);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeDuplicatedNameCause =
+    const Code<Message Function(String name)>(
+        "DuplicatedNameCause", templateDuplicatedNameCause,
+        severity: Severity.context);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDuplicatedNameCause(String name) {
+  return new Message(codeDuplicatedNameCause,
+      message: """Previous declaration of '$name'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String
+            name)> templateDuplicatedNamePreviouslyUsed = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""Can't declare '#name' because it was already used in this scope.""",
+    withArguments: _withArgumentsDuplicatedNamePreviouslyUsed);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeDuplicatedNamePreviouslyUsed =
+    const Code<Message Function(String name)>(
+        "DuplicatedNamePreviouslyUsed", templateDuplicatedNamePreviouslyUsed,
+        severity: Severity.error);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDuplicatedNamePreviouslyUsed(String name) {
+  return new Message(codeDuplicatedNamePreviouslyUsed,
+      message:
+          """Can't declare '$name' because it was already used in this scope.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateDuplicatedNamePreviouslyUsedCause =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Previous use of '#name'.""",
+        withArguments: _withArgumentsDuplicatedNamePreviouslyUsedCause);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+    codeDuplicatedNamePreviouslyUsedCause =
+    const Code<Message Function(String name)>(
+        "DuplicatedNamePreviouslyUsedCause",
+        templateDuplicatedNamePreviouslyUsedCause,
+        severity: Severity.context);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDuplicatedNamePreviouslyUsedCause(String name) {
+  return new Message(codeDuplicatedNamePreviouslyUsedCause,
+      message: """Previous use of '$name'.""", arguments: {'name': name});
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -4574,25 +4638,6 @@
     tip: r"""Try moving the prefix before the combinators.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)> templatePreviousUseOfName =
-    const Template<Message Function(String name)>(
-        messageTemplate: r"""Previous use of '#name'.""",
-        withArguments: _withArgumentsPreviousUseOfName);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codePreviousUseOfName =
-    const Code<Message Function(String name)>(
-  "PreviousUseOfName",
-  templatePreviousUseOfName,
-);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsPreviousUseOfName(String name) {
-  return new Message(codePreviousUseOfName,
-      message: """Previous use of '$name'.""", arguments: {'name': name});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codePrivateNamedParameter = messagePrivateNamedParameter;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 0ad547e..17a2764 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -157,21 +157,21 @@
             await userCode.buildComponent(verify: c.options.verify);
       } on KernelIncrementalTargetErroneousComponent {
         List<Library> librariesWithSdk = userCode.component.libraries;
-        List<Library> libraries = <Library>[];
+        List<Library> compiledLibraries = <Library>[];
         for (Library lib in librariesWithSdk) {
           if (lib.importUri.scheme == "dart") continue;
-          libraries.add(lib);
+          compiledLibraries.add(lib);
           break;
         }
         userCode.loader.builders.clear();
         userCode = userCodeOld;
         return new Component(
-            libraries: libraries, uriToSource: <Uri, Source>{});
+            libraries: compiledLibraries, uriToSource: <Uri, Source>{});
       }
       userCodeOld?.loader?.builders?.clear();
       userCodeOld = null;
 
-      List<Library> libraries =
+      List<Library> compiledLibraries =
           new List<Library>.from(userCode.loader.libraries);
       Map<Uri, Source> uriToSource =
           new Map<Uri, Source>.from(dillLoadedDataUriToSource);
@@ -180,28 +180,32 @@
           ? data.userLoadedUriMain
           : componentWithDill.mainMethod;
 
+      List<Library> outputLibraries;
       if (data.includeUserLoadedLibraries || fullComponent) {
-        addReusedLibraries(
-            libraries, mainMethod, entryPoint, reusedLibraries, data);
+        outputLibraries = computeTransitiveClosure(
+            compiledLibraries, mainMethod, entryPoint, reusedLibraries, data);
+      } else {
+        outputLibraries = compiledLibraries;
       }
 
       // Clean up.
       userCode.loader.releaseAncillaryResources();
 
       // This is the incremental component.
-      return new Component(libraries: libraries, uriToSource: uriToSource)
+      return new Component(libraries: outputLibraries, uriToSource: uriToSource)
         ..mainMethod = mainMethod;
     });
   }
 
-  void addReusedLibraries(
-      List<Library> libraries,
+  List<Library> computeTransitiveClosure(
+      List<Library> inputLibraries,
       Procedure mainMethod,
       Uri entry,
       List<LibraryBuilder> reusedLibraries,
       IncrementalCompilerData data) {
+    List<Library> result = new List<Library>.from(inputLibraries);
     Map<Uri, Library> libraryMap = <Uri, Library>{};
-    for (Library library in libraries) {
+    for (Library library in inputLibraries) {
       libraryMap[library.importUri] = library;
     }
     List<Uri> worklist = new List<Uri>.from(libraryMap.keys);
@@ -228,7 +232,7 @@
         libraryMap.remove(uri);
         Library library = potentiallyReferencedLibraries.remove(uri);
         if (library != null) {
-          libraries.add(library);
+          result.add(library);
         }
       }
     }
@@ -238,16 +242,7 @@
       userCode.loader.builders.remove(uri);
     }
 
-    // For now ensure original order of libraries to produce bit-perfect
-    // output.
-    libraries.sort((a, b) {
-      int aOrder = data.importUriToOrder[a.importUri];
-      int bOrder = data.importUriToOrder[b.importUri];
-      if (aOrder != null && bOrder != null) return aOrder - bOrder;
-      if (aOrder != null) return -1;
-      if (bOrder != null) return 1;
-      return 0;
-    });
+    return result;
   }
 
   int prepareSummary(List<int> summaryBytes, UriTranslator uriTranslator,
@@ -279,8 +274,6 @@
     if (await entity.exists()) {
       List<int> initializationBytes = await entity.readAsBytes();
       if (initializationBytes != null) {
-        Set<Uri> prevLibraryUris = new Set<Uri>.from(
-            data.component.libraries.map((Library lib) => lib.importUri));
         ticker.logMs("Read $initializeFromDillUri");
 
         Set<Uri> sdkUris = data.component.uriToSource.keys.toSet();
@@ -306,10 +299,6 @@
 
         initializedFromDill = true;
         bytesLength += initializationBytes.length;
-        for (Library lib in data.component.libraries) {
-          if (prevLibraryUris.contains(lib.importUri)) continue;
-          data.importUriToOrder[lib.importUri] = data.importUriToOrder.length;
-        }
         data.userLoadedUriMain = data.component.mainMethod;
         data.includeUserLoadedLibraries = true;
         for (Uri uri in data.component.uriToSource.keys) {
@@ -354,9 +343,7 @@
       return false;
     }
 
-    // Compute [builders] and [invalidatedImportUris].
-    addBuilderAndInvalidateUris(Uri uri, LibraryBuilder library,
-        [bool recursive = true]) {
+    addBuilderAndInvalidateUris(Uri uri, LibraryBuilder library) {
       builders[uri] = library;
       if (isInvalidated(uri, library.target.fileUri)) {
         invalidatedImportUris.add(uri);
@@ -448,7 +435,6 @@
 
 class IncrementalCompilerData {
   bool includeUserLoadedLibraries;
-  Map<Uri, int> importUriToOrder;
   Procedure userLoadedUriMain;
   Component component;
 
@@ -458,7 +444,6 @@
 
   reset() {
     includeUserLoadedLibraries = false;
-    importUriToOrder = <Uri, int>{};
     userLoadedUriMain = null;
     component = null;
   }
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 d446340..0170666 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -14,7 +14,7 @@
 
 import '../messages.dart' as messages show getLocationFromUri;
 
-import '../modifier.dart' show Modifier, constMask, finalMask;
+import '../modifier.dart' show Modifier, constMask, covariantMask, finalMask;
 
 import '../parser.dart'
     show
@@ -340,40 +340,53 @@
     switchScope = outerSwitchScope;
   }
 
-  void declareVariable(VariableDeclaration variable, Scope scope) {
-    // ignore: UNUSED_LOCAL_VARIABLE
-    Statement discardedStatement;
+  void wrapVariableInitializerInError(
+      VariableDeclaration variable,
+      Template<Message Function(String name)> template,
+      List<LocatedMessage> context) {
     String name = variable.name;
     int offset = variable.fileOffset;
-    if (scope.local[name] != null) {
+    Message message = template.withArguments(name);
+    if (variable.initializer == null) {
+      variable.initializer =
+          buildCompileTimeError(message, offset, name.length, context: context)
+            ..parent = variable;
+    } else {
+      variable.initializer = wrapInLocatedCompileTimeError(
+          variable.initializer, message.withLocation(uri, offset, name.length),
+          context: context)
+        ..parent = variable;
+    }
+  }
+
+  void declareVariable(VariableDeclaration variable, Scope scope) {
+    String name = variable.name;
+    Builder existing = scope.local[name];
+    if (existing != null) {
       // This reports an error for duplicated declarations in the same scope:
       // `{ var x; var x; }`
-      discardedStatement = pop(); // TODO(ahe): Issue 29717.
-      push(deprecated_buildCompileTimeErrorStatement(
-          "'$name' already declared in this scope.", offset));
+      wrapVariableInitializerInError(
+          variable, fasta.templateDuplicatedName, <LocatedMessage>[
+        fasta.templateDuplicatedNameCause
+            .withArguments(name)
+            .withLocation(uri, existing.charOffset, name.length)
+      ]);
       return;
     }
-    LocatedMessage error = scope.declare(
+    LocatedMessage context = scope.declare(
         variable.name,
         new KernelVariableBuilder(
             variable, member ?? classBuilder ?? library, uri),
-        variable.fileOffset,
         uri);
-    if (error != null) {
+    if (context != null) {
       // This case is different from the above error. In this case, the problem
       // is using `x` before it's declared: `{ var x; { print(x); var x;
       // }}`. In this case, we want two errors, the `x` in `print(x)` and the
       // second (or innermost declaration) of `x`.
-      discardedStatement = pop(); // TODO(ahe): Issue 29717.
-
-      // Reports the error on the last declaration of `x`.
-      push(deprecated_buildCompileTimeErrorStatement(
-          "Can't declare '$name' because it was already used in this scope.",
-          offset));
-
-      // Reports the error on `print(x)`.
-      library.addCompileTimeError(
-          error.messageObject, error.charOffset, error.length, error.uri);
+      wrapVariableInitializerInError(
+          variable,
+          fasta.templateDuplicatedNamePreviouslyUsed,
+          <LocatedMessage>[context]);
     }
   }
 
@@ -2065,6 +2078,13 @@
   }
 
   @override
+  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+      Token varFinalOrConst) {
+    push((covariantToken != null ? covariantMask : 0) |
+        Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme));
+  }
+
+  @override
   void endFormalParameter(Token thisKeyword, Token periodAfterThis,
       Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
     debugEvent("FormalParameter");
@@ -2077,7 +2097,7 @@
     }
     Identifier name = pop();
     DartType type = pop();
-    int modifiers = Modifier.validate(pop());
+    int modifiers = pop();
     if (inCatchClause) {
       modifiers |= finalMask;
     }
@@ -2910,29 +2930,40 @@
 
       variable.type = function.functionType;
       if (isFunctionExpression) {
+        Expression oldInitializer = variable.initializer;
         variable.initializer = new ShadowFunctionExpression(function)
           ..parent = variable
           ..fileOffset = formals.charOffset;
         exitLocalScope();
-        push(new ShadowNamedFunctionExpression(variable));
+        Expression expression = new ShadowNamedFunctionExpression(variable);
+        if (oldInitializer != null) {
+          // This must have been a compile-time error.
+          assert(isErroneousNode(oldInitializer));
+
+          push(new Let(
+              new VariableDeclaration.forValue(oldInitializer)
+                ..fileOffset = expression.fileOffset,
+              expression)
+            ..fileOffset = expression.fileOffset);
+        } else {
+          push(expression);
+        }
       } else {
         declaration.function = function;
         function.parent = declaration;
-        push(declaration);
-      }
-    } else if (declaration is ExpressionStatement) {
-      // If [declaration] isn't a [FunctionDeclaration], it must be because
-      // there was a compile-time error.
-      // TODO(askesc): Be more specific about the error code when we have
-      // errors represented as explicit invalid nodes.
-      assert(library.loader.handledErrors.isNotEmpty);
+        if (variable.initializer != null) {
+          // This must have been a compile-time error.
+          assert(isErroneousNode(variable.initializer));
 
-      // TODO(paulberry,ahe): ensure that when integrating with analyzer, type
-      // inference is still performed for the dropped declaration.
-      if (isFunctionExpression) {
-        push(declaration.expression);
-      } else {
-        push(declaration);
+          push(new Block(<Statement>[
+            new ExpressionStatement(variable.initializer),
+            declaration
+          ])
+            ..fileOffset = declaration.fileOffset);
+          variable.initializer = null;
+        } else {
+          push(declaration);
+        }
       }
     } else {
       return unhandled("${declaration.runtimeType}", "pushNamedFunction",
@@ -3216,6 +3247,8 @@
         break;
 
       case Assert.Expression:
+        // The parser has already reported an error indicating that assert
+        // cannot be used in an expression.
         push(deprecated_buildCompileTimeError(
             "`assert` can't be used as an expression."));
         break;
@@ -3518,20 +3551,6 @@
   }
 
   @override
-  void handleModifier(Token token) {
-    debugEvent("Modifier");
-    // TODO(ahe): Copied from outline_builder.dart.
-    push(new Modifier.fromString(token.stringValue));
-  }
-
-  @override
-  void handleModifiers(int count) {
-    debugEvent("Modifiers");
-    // TODO(ahe): Copied from outline_builder.dart.
-    push(popList(count) ?? NullValue.Modifiers);
-  }
-
-  @override
   void handleRecoverableError(
       Message message, Token startToken, Token endToken) {
     if (message == fasta.messageNativeClauseShouldBeAnnotation) {
@@ -3933,7 +3952,7 @@
   Expression wrapInDeferredCheck(
       Expression expression, KernelPrefixBuilder prefix, int charOffset) {
     var check = new VariableDeclaration.forValue(
-        new CheckLibraryIsLoaded(prefix.dependency))
+        forest.checkLibraryIsLoaded(prefix.dependency))
       ..fileOffset = charOffset;
     return new ShadowDeferredCheck(check, expression);
   }
@@ -3944,6 +3963,11 @@
     node.fileOffset = offset;
     return object;
   }
+
+  bool isErroneousNode(TreeNode node) {
+    return library.loader.handledErrors.isNotEmpty &&
+        forest.isErroneousNode(node);
+  }
 }
 
 class Identifier {
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 6aff6ed..566ee45 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -11,10 +11,15 @@
         Arguments,
         DartType,
         Expression,
+        ExpressionStatement,
+        InvalidExpression,
+        Let,
+        LibraryDependency,
         MapEntry,
         NamedExpression,
         Statement,
-        TreeNode;
+        TreeNode,
+        VariableDeclaration;
 
 import '../parser.dart' show offsetForToken;
 
@@ -24,13 +29,16 @@
     show
         ShadowArguments,
         ShadowBoolLiteral,
+        ShadowCheckLibraryIsLoaded,
         ShadowDoubleLiteral,
         ShadowIntLiteral,
         ShadowListLiteral,
+        ShadowLoadLibrary,
         ShadowMapLiteral,
         ShadowNullLiteral,
         ShadowStringLiteral,
         ShadowSymbolLiteral,
+        ShadowSyntheticExpression,
         ShadowTypeLiteral;
 
 import 'forest.dart' show Forest;
@@ -135,4 +143,35 @@
 
   @override
   int readOffset(TreeNode node) => node.fileOffset;
+
+  @override
+  Expression loadLibrary(LibraryDependency dependency) {
+    return new ShadowLoadLibrary(dependency);
+  }
+
+  @override
+  Expression checkLibraryIsLoaded(LibraryDependency dependency) {
+    return new ShadowCheckLibraryIsLoaded(dependency);
+  }
+
+  @override
+  bool isErroneousNode(TreeNode node) {
+    if (node is ExpressionStatement) {
+      ExpressionStatement statement = node;
+      node = statement.expression;
+    }
+    if (node is VariableDeclaration) {
+      VariableDeclaration variable = node;
+      node = variable.initializer;
+    }
+    if (node is ShadowSyntheticExpression) {
+      ShadowSyntheticExpression synth = node;
+      node = synth.desugared;
+    }
+    if (node is Let) {
+      Let let = node;
+      node = let.variable.initializer;
+    }
+    return node is InvalidExpression;
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
index 07560d3..79859e9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -922,7 +922,7 @@
       helper.addProblemErrorIfConst(
           messageLoadLibraryTakesNoArguments, offset, 'loadLibrary'.length);
     }
-    return builder.createLoadLibrary(offset);
+    return builder.createLoadLibrary(offset, forest);
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 0656e8c..c9a526c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -50,6 +50,12 @@
 
   int readOffset(covariant node);
 
+  Expression loadLibrary(covariant dependency);
+
+  Expression checkLibraryIsLoaded(covariant dependency);
+
+  bool isErroneousNode(covariant node);
+
   // 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/frontend_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
index 7bbec74..e44e72d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
@@ -707,7 +707,8 @@
       : super(helper, token);
 
   Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read = helper.makeStaticGet(builder.createTearoffMethod(), token);
+    var read =
+        helper.makeStaticGet(builder.createTearoffMethod(helper.forest), token);
     complexAssignment?.read = read;
     return read;
   }
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 2d41321..4742c42 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
@@ -4,7 +4,7 @@
 
 library fasta.kernel_library_builder;
 
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonEncode;
 
 import 'package:kernel/ast.dart';
 
@@ -840,7 +840,7 @@
 
     if (unserializableExports != null) {
       library.addMember(new Field(new Name("_exports#", library),
-          initializer: new StringLiteral(JSON.encode(unserializableExports)),
+          initializer: new StringLiteral(jsonEncode(unserializableExports)),
           isStatic: true,
           isConst: true));
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index ecd17f9..36c7523 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -2382,6 +2382,27 @@
   }
 }
 
+/// Concrete shadow object representing a deferred load library call.
+class ShadowLoadLibrary extends LoadLibrary implements ShadowExpression {
+  ShadowLoadLibrary(LibraryDependency import) : super(import);
+
+  @override
+  DartType _inferExpression(ShadowTypeInferrer inferrer, DartType typeContext) {
+    return super.getStaticType(inferrer.typeSchemaEnvironment);
+  }
+}
+
+/// Concrete shadow object representing a deferred library-is-loaded check.
+class ShadowCheckLibraryIsLoaded extends CheckLibraryIsLoaded
+    implements ShadowExpression {
+  ShadowCheckLibraryIsLoaded(LibraryDependency import) : super(import);
+
+  @override
+  DartType _inferExpression(ShadowTypeInferrer inferrer, DartType typeContext) {
+    return super.getStaticType(inferrer.typeSchemaEnvironment);
+  }
+}
+
 /// The result of inference for a RHS of an assignment.
 class _ComplexAssignmentInferenceResult {
   /// The resolved combiner [Procedure], e.g. `operator+` for `a += 2`, or
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_variable_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_variable_builder.dart
index 9dd42e2..65a3f94 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_variable_builder.dart
@@ -16,6 +16,9 @@
       : variable = variable,
         super(parent, variable.fileOffset, fileUri);
 
+  @override
+  int get charOffset => variable.fileOffset;
+
   bool get isLocal => true;
 
   bool get isConst => variable.isConst;
diff --git a/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
index 57eace4..67a9e22 100644
--- a/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
@@ -16,9 +16,9 @@
         ProcedureKind,
         ReturnStatement;
 
-import '../builder/builder.dart' show Builder;
+import 'kernel_builder.dart' show Builder, KernelLibraryBuilder;
 
-import 'kernel_library_builder.dart' show KernelLibraryBuilder;
+import 'forest.dart' show Forest;
 
 /// Builder to represent the `deferLibrary.loadLibrary` calls and tear-offs.
 class LoadLibraryBuilder extends Builder {
@@ -36,13 +36,13 @@
   LoadLibraryBuilder(this.parent, this.importDependency, this.charOffset)
       : super(parent, charOffset, parent.fileUri);
 
-  LoadLibrary createLoadLibrary(int charOffset) {
-    return new LoadLibrary(importDependency)..fileOffset = charOffset;
+  LoadLibrary createLoadLibrary(int charOffset, Forest forest) {
+    return forest.loadLibrary(importDependency)..fileOffset = charOffset;
   }
 
-  Procedure createTearoffMethod() {
+  Procedure createTearoffMethod(Forest forest) {
     if (tearoff != null) return tearoff;
-    LoadLibrary expression = createLoadLibrary(charOffset);
+    LoadLibrary expression = createLoadLibrary(charOffset, forest);
     String prefix = expression.import.name;
     tearoff = new Procedure(
         new Name('__loadLibrary_$prefix', parent.target),
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index ac10060..aaac6e7 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -179,8 +179,7 @@
       builders.forEach((Uri uri, LibraryBuilder library) {
         if (library.loader == this) libraryCount++;
       });
-      double ms =
-          elapsed.inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND;
+      double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
       Message message = template.withArguments(
           libraryCount,
           byteCount,
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 6e9fb76..4cb980b 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -172,8 +172,10 @@
   }
 
   @override
-  void beginFormalParameter(Token token, MemberKind kind) {
-    listener?.beginFormalParameter(token, kind);
+  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+      Token varFinalOrConst) {
+    listener?.beginFormalParameter(
+        token, kind, covariantToken, varFinalOrConst);
   }
 
   @override
@@ -1099,16 +1101,6 @@
   }
 
   @override
-  void handleModifier(Token token) {
-    listener?.handleModifier(token);
-  }
-
-  @override
-  void handleModifiers(int count) {
-    listener?.handleModifiers(count);
-  }
-
-  @override
   void handleNamedArgument(Token colon) {
     listener?.handleNamedArgument(colon);
   }
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 aa0a7be..b72575b 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -29,12 +29,12 @@
 
   /// Identifier is the start of a dotted name in a conditional import or
   /// export.
-  static const dottedName = const IdentifierContext('dottedName');
+  static const dottedName = const DottedNameIdentifierContext();
 
   /// Identifier is part of a dotted name in a conditional import or export, but
   /// it's not the first identifier of the dotted name.
   static const dottedNameContinuation =
-      const IdentifierContext('dottedNameContinuation', isContinuation: true);
+      const DottedNameIdentifierContext.continuation();
 
   /// Identifier is one of the shown/hidden names in an import/export
   /// combinator.
@@ -105,10 +105,8 @@
 
   /// Identifier is the name being declared by a class declaration or a named
   /// mixin application, for example, `Foo` in `class Foo = X with Y;`.
-  static const classOrNamedMixinDeclaration = const IdentifierContext(
-      'classOrNamedMixinDeclaration',
-      inDeclaration: true,
-      isBuiltInIdentifierAllowed: false);
+  static const classOrNamedMixinDeclaration =
+      const ClassOrNamedMixinIdentifierContext();
 
   /// Identifier is the name of a type variable being declared (e.g. `Foo` in
   /// `class C<Foo extends num> {}`).
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 0f22616..8922d33 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
@@ -17,6 +17,73 @@
 
 import 'util.dart' show optional;
 
+/// See [IdentifierContext].classOrNamedMixin
+class ClassOrNamedMixinIdentifierContext extends IdentifierContext {
+  const ClassOrNamedMixinIdentifierContext()
+      : super('classOrNamedMixinDeclaration',
+            inDeclaration: true, isBuiltInIdentifierAllowed: false);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.type.isPseudo) {
+      return identifier;
+    }
+
+    if (looksLikeStartOfNextDeclaration(identifier) ||
+        isOneOfOrEof(
+            identifier, const ['<', '{', 'extends', 'with', 'implements'])) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else if (identifier.type.isBuiltIn) {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateBuiltInIdentifierAsType);
+    } 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 = insertSyntheticIdentifierAfter(identifier, parser);
+      }
+    }
+    return identifier;
+  }
+}
+
+/// See [IdentifierContext].dottedName
+class DottedNameIdentifierContext extends IdentifierContext {
+  const DottedNameIdentifierContext() : super('dottedName');
+
+  const DottedNameIdentifierContext.continuation()
+      : super('dottedNameContinuation', isContinuation: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      return identifier;
+    }
+
+    if (looksLikeStartOfNextDeclaration(identifier) ||
+        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 = insertSyntheticIdentifierAfter(identifier, parser);
+      }
+    }
+    return identifier;
+  }
+}
+
 /// See [IdentifierContext].expression
 class ExpressionIdentifierContext extends IdentifierContext {
   const ExpressionIdentifierContext()
@@ -56,7 +123,7 @@
     parser.reportRecoverableErrorWithToken(
         next, fasta.templateExpectedIdentifier);
     if (next.isKeywordOrIdentifier) {
-      if (!isOneOfOrEof(next, ['as', 'is'])) {
+      if (!isOneOfOrEof(next, const ['as', 'is'])) {
         return next;
       }
     } else if (!next.isOperator &&
@@ -109,15 +176,6 @@
     }
     return identifier;
   }
-
-  bool looksLikeStartOfNextDeclaration(Token token) =>
-      token.isTopLevelKeyword ||
-      optional('const', token) ||
-      optional('get', token) ||
-      optional('final', token) ||
-      optional('set', token) ||
-      optional('var', token) ||
-      optional('void', token);
 }
 
 /// See [IdentifierContext].typeReference
@@ -201,3 +259,7 @@
   }
   return token.isEof;
 }
+
+bool looksLikeStartOfNextDeclaration(Token token) =>
+    token.isTopLevelKeyword ||
+    isOneOfOrEof(token, const ['const', 'get', 'final', 'set', 'var', 'void']);
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 19ed1b1..79786ca 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -232,7 +232,8 @@
     logEvent("FactoryMethod");
   }
 
-  void beginFormalParameter(Token token, MemberKind kind) {}
+  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+      Token varFinalOrConst) {}
 
   void endFormalParameter(Token thisKeyword, Token periodAfterThis,
       Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
@@ -1059,14 +1060,6 @@
     logEvent("LiteralNull");
   }
 
-  void handleModifier(Token token) {
-    logEvent("Modifier");
-  }
-
-  void handleModifiers(int count) {
-    logEvent("Modifiers");
-  }
-
   void handleNativeClause(Token nativeToken, bool hasName) {
     logEvent("NativeClause");
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index 4b23332..9bf2da1 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -4,8 +4,6 @@
 
 import '../../scanner/token.dart' show Token;
 import '../messages.dart' as fasta;
-import 'formal_parameter_kind.dart' show FormalParameterKind;
-import 'member_kind.dart' show MemberKind;
 import 'parser.dart' show Parser;
 import 'type_continuation.dart' show TypeContinuation;
 import 'util.dart' show optional;
@@ -33,12 +31,15 @@
 TypeContinuation typeContinuationAfterVar(TypeContinuation typeContinuation) {
   switch (typeContinuation) {
     case TypeContinuation.NormalFormalParameter:
+    case TypeContinuation.NormalFormalParameterAfterVar:
       return TypeContinuation.NormalFormalParameterAfterVar;
 
     case TypeContinuation.OptionalPositionalFormalParameter:
+    case TypeContinuation.OptionalPositionalFormalParameterAfterVar:
       return TypeContinuation.OptionalPositionalFormalParameterAfterVar;
 
     case TypeContinuation.NamedFormalParameter:
+    case TypeContinuation.NamedFormalParameterAfterVar:
       return TypeContinuation.NamedFormalParameterAfterVar;
 
     default:
@@ -47,163 +48,8 @@
 }
 
 /// This class is used to parse modifiers in most locations where modifiers
-/// can occur. However, it isn't used when parsing a class or when parsing
-/// the modifiers of a member function (non-local),
-/// but is used when parsing their formal parameters.
-class ModifierContext {
-  final Parser parser;
-  MemberKind memberKind;
-
-  /// When parsing the formal parameters of any function,
-  /// [parameterKind] is non-null.
-  final FormalParameterKind parameterKind;
-
-  final bool isVarAllowed;
-  TypeContinuation typeContinuation;
-  int modifierCount = 0;
-  Token varFinalOrConst;
-
-  ModifierContext(this.parser, this.memberKind, this.parameterKind,
-      this.isVarAllowed, this.typeContinuation);
-
-  bool get isCovariantFinalAllowed =>
-      memberKind != MemberKind.StaticField &&
-      memberKind != MemberKind.NonStaticField;
-
-  Token parseConst(Token token) {
-    Token next = token.next;
-    assert(optional('const', next));
-    if (!isVarAllowed) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateExtraneousModifier);
-      // TODO(danrubel): investigate why token must be included (fall through)
-      // so that tests will pass. I think that it should not be included
-      // because the 'const' is invalid in this situation.
-      //
-      // return token.next;
-    }
-    typeContinuation ??= TypeContinuation.Optional;
-    varFinalOrConst ??= next;
-    modifierCount++;
-    return parser.parseModifier(token);
-  }
-
-  Token parseCovariantOpt(Token token) {
-    Token next = token.next;
-    assert(optional('covariant', next));
-    // A built-in identifier can only be a modifier as long as it is
-    // followed by another modifier or an identifier.
-    // Otherwise, it is the identifier.
-    if (!next.next.isKeywordOrIdentifier) {
-      return token;
-    }
-    switch (memberKind) {
-      case MemberKind.Local:
-      case MemberKind.StaticField:
-      case MemberKind.StaticMethod:
-      case MemberKind.TopLevelField:
-      case MemberKind.TopLevelMethod:
-        parser.reportRecoverableErrorWithToken(
-            next, fasta.templateExtraneousModifier);
-        return next;
-
-      default:
-        modifierCount++;
-        return parser.parseModifier(token);
-    }
-  }
-
-  Token parseExternalOpt(Token token) {
-    Token next = token.next;
-    assert(optional('external', next));
-    // A built-in identifier can only be a modifier as long as it is
-    // followed by another modifier or an identifier.
-    // Otherwise, it is the identifier.
-    if (!next.next.isKeywordOrIdentifier) {
-      return token;
-    }
-    switch (memberKind) {
-      case MemberKind.Factory:
-      case MemberKind.NonStaticMethod:
-      case MemberKind.StaticMethod:
-      case MemberKind.TopLevelMethod:
-        modifierCount++;
-        return parser.parseModifier(token);
-
-      case MemberKind.StaticField:
-      case MemberKind.NonStaticField:
-        parser.reportRecoverableError(next, fasta.messageExternalField);
-        return next;
-
-      default:
-        parser.reportRecoverableErrorWithToken(
-            next, fasta.templateExtraneousModifier);
-        return next;
-    }
-  }
-
-  Token parseFinal(Token token) {
-    Token next = token.next;
-    assert(optional('final', next));
-    if (!isVarAllowed && parameterKind == null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateExtraneousModifier);
-      return next;
-    }
-    typeContinuation ??= TypeContinuation.Optional;
-    varFinalOrConst ??= next;
-    modifierCount++;
-    return parser.parseModifier(token);
-  }
-
-  Token parseStaticOpt(Token token) {
-    Token next = token.next;
-    assert(optional('static', next));
-    // A built-in identifier can only be a modifier as long as it is
-    // followed by another modifier or an identifier.
-    // Otherwise, it is the identifier.
-    if (!next.next.isKeywordOrIdentifier) {
-      return token;
-    }
-    if (parameterKind != null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateExtraneousModifier);
-      return next;
-    }
-    switch (memberKind) {
-      case MemberKind.NonStaticMethod:
-        memberKind = MemberKind.StaticMethod;
-        modifierCount++;
-        return parser.parseModifier(token);
-      case MemberKind.NonStaticField:
-        memberKind = MemberKind.StaticField;
-        modifierCount++;
-        return parser.parseModifier(token);
-      default:
-        parser.reportRecoverableErrorWithToken(
-            next, fasta.templateExtraneousModifier);
-        return next;
-    }
-  }
-
-  Token parseVar(Token token) {
-    Token next = token.next;
-    assert(optional('var', next));
-    if (!isVarAllowed && parameterKind == null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateExtraneousModifier);
-      return next;
-    }
-    typeContinuation = typeContinuationAfterVar(typeContinuation);
-    varFinalOrConst ??= next;
-    modifierCount++;
-    return parser.parseModifier(token);
-  }
-}
-
-/// This class parses modifiers in recovery situations,
-/// but does not call handleModifier or handleModifiers.
-class ModifierRecoveryContext2 {
+/// can occur, but does not call handleModifier or handleModifiers.
+class ModifierRecoveryContext {
   final Parser parser;
   Token abstractToken;
   Token constToken;
@@ -220,7 +66,7 @@
   // TODO(danrubel): Replace [ModifierRecoveryContext] and [ModifierContext]
   // with this class.
 
-  ModifierRecoveryContext2(this.parser);
+  ModifierRecoveryContext(this.parser);
 
   /// Parse modifiers for class methods and fields.
   Token parseClassMemberModifiers(Token token,
@@ -241,6 +87,26 @@
     return token;
   }
 
+  /// Parse modifiers for formal parameters.
+  Token parseFormalParameterModifiers(Token token, bool isStaticOrTopLevel,
+      {Token covariantToken, Token varFinalOrConst}) {
+    token = parseModifiers(token,
+        covariantToken: covariantToken, varFinalOrConst: varFinalOrConst);
+
+    if (isStaticOrTopLevel) {
+      reportExtraneousModifier(this.covariantToken);
+      this.covariantToken = null;
+    }
+    if (constToken != null) {
+      reportExtraneousModifier(constToken);
+      varFinalOrConst = null;
+    }
+    reportExtraneousModifier(abstractToken);
+    reportExtraneousModifier(externalToken);
+    reportExtraneousModifier(staticToken);
+    return token;
+  }
+
   /// Parse modifiers after the `factory` token.
   Token parseModifiersAfterFactory(Token token,
       {Token externalToken, Token staticOrCovariant, Token varFinalOrConst}) {
@@ -545,241 +411,3 @@
     }
   }
 }
-
-class ModifierRecoveryContext extends ModifierContext {
-  Token constToken;
-  Token covariantToken;
-  Token externalToken;
-  Token finalToken;
-  Token staticToken;
-  Token varToken;
-
-  ModifierRecoveryContext(
-      Parser parser,
-      MemberKind memberKind,
-      FormalParameterKind parameterKind,
-      bool isVarAllowed,
-      TypeContinuation typeContinuation)
-      : super(
-            parser, memberKind, parameterKind, isVarAllowed, typeContinuation);
-
-  Token parseRecovery(Token token,
-      {Token covariantToken, Token staticToken, Token varFinalOrConst}) {
-    if (covariantToken != null) {
-      this.covariantToken = covariantToken;
-      ++modifierCount;
-    }
-    if (staticToken != null) {
-      this.staticToken = staticToken;
-      ++modifierCount;
-    }
-    if (varFinalOrConst != null) {
-      this.varFinalOrConst = varFinalOrConst;
-      ++modifierCount;
-      if (optional('var', varFinalOrConst)) {
-        varToken = varFinalOrConst;
-      } else if (optional('final', varFinalOrConst)) {
-        finalToken = varFinalOrConst;
-      } else if (optional('const', varFinalOrConst)) {
-        constToken = varFinalOrConst;
-      } else {
-        throw "Internal error: Unexpected varFinalOrConst '$varFinalOrConst'.";
-      }
-    }
-
-    // Process invalid and out-of-order modifiers
-    Token next = token.next;
-    while (isModifier(next)) {
-      final value = next.stringValue;
-      if (identical('abstract', value)) {
-        token = parseAbstract(token);
-      } else if (identical('const', value)) {
-        token = parseConst(token);
-      } else if (identical('covariant', value)) {
-        token = parseCovariantOpt(token);
-      } else if (identical('external', value)) {
-        token = parseExternalOpt(token);
-      } else if (identical('final', value)) {
-        token = parseFinal(token);
-      } else if (identical('static', value)) {
-        token = parseStaticOpt(token);
-      } else if (identical('var', value)) {
-        token = parseVar(token);
-      } else {
-        token = parseExtraneousModifier(token);
-      }
-      next = token.next;
-    }
-
-    return token;
-  }
-
-  Token parseAbstract(Token token) {
-    assert(optional('abstract', token.next));
-    if (memberKind == MemberKind.NonStaticField ||
-        memberKind == MemberKind.NonStaticMethod ||
-        memberKind == MemberKind.StaticField ||
-        memberKind == MemberKind.StaticMethod) {
-      parser.reportRecoverableError(
-          token.next, fasta.messageAbstractClassMember);
-      return token.next;
-    }
-    return parseExtraneousModifier(token);
-  }
-
-  @override
-  Token parseConst(Token token) {
-    Token next = token.next;
-    if (constToken != null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateDuplicatedModifier);
-      return next;
-    }
-    constToken = next;
-    if (covariantToken != null) {
-      parser.reportRecoverableError(constToken, fasta.messageConstAndCovariant);
-      return constToken;
-    }
-    if (finalToken != null) {
-      parser.reportRecoverableError(constToken, fasta.messageConstAndFinal);
-      return constToken;
-    }
-    if (varToken != null) {
-      parser.reportRecoverableError(constToken, fasta.messageConstAndVar);
-      return constToken;
-    }
-    return super.parseConst(token);
-  }
-
-  @override
-  Token parseCovariantOpt(Token token) {
-    Token next = token.next;
-    if (covariantToken != null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateDuplicatedModifier);
-      return next;
-    }
-    covariantToken = next;
-    if (constToken != null) {
-      parser.reportRecoverableError(
-          covariantToken, fasta.messageConstAndCovariant);
-      return covariantToken;
-    }
-    if (staticToken != null) {
-      parser.reportRecoverableError(
-          covariantToken, fasta.messageCovariantAndStatic);
-      return covariantToken;
-    }
-    if (varToken != null) {
-      parser.reportRecoverableError(
-          covariantToken, fasta.messageCovariantAfterVar);
-      // fall through to parse modifier
-    } else if (finalToken != null) {
-      if (!isCovariantFinalAllowed) {
-        parser.reportRecoverableError(
-            covariantToken, fasta.messageFinalAndCovariant);
-        return covariantToken;
-      }
-      parser.reportRecoverableError(
-          covariantToken, fasta.messageCovariantAfterFinal);
-      // fall through to parse modifier
-    }
-    return super.parseCovariantOpt(token);
-  }
-
-  @override
-  Token parseExternalOpt(Token token) {
-    Token next = token.next;
-    if (externalToken != null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateDuplicatedModifier);
-      return next;
-    }
-    externalToken = token.next;
-    return super.parseExternalOpt(token);
-  }
-
-  @override
-  Token parseFinal(Token token) {
-    Token next = token.next;
-    if (finalToken != null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateDuplicatedModifier);
-      return next;
-    }
-    finalToken = next;
-    if (constToken != null) {
-      parser.reportRecoverableError(finalToken, fasta.messageConstAndFinal);
-      return finalToken;
-    }
-    if (covariantToken != null && !isCovariantFinalAllowed) {
-      parser.reportRecoverableError(finalToken, fasta.messageFinalAndCovariant);
-      return finalToken;
-    }
-    if (varToken != null) {
-      parser.reportRecoverableError(finalToken, fasta.messageFinalAndVar);
-      return finalToken;
-    }
-    return super.parseFinal(token);
-  }
-
-  Token parseExtraneousModifier(Token token) {
-    Token next = token.next;
-    if (next.isModifier) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateExtraneousModifier);
-    } else {
-      // TODO(danrubel): Provide more specific error messages.
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateUnexpectedToken);
-    }
-    return next;
-  }
-
-  @override
-  Token parseStaticOpt(Token token) {
-    Token next = token.next;
-    if (staticToken != null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateDuplicatedModifier);
-      return next;
-    }
-    staticToken = next;
-    if (covariantToken != null) {
-      parser.reportRecoverableError(
-          staticToken, fasta.messageCovariantAndStatic);
-      return staticToken;
-    }
-    if (constToken != null) {
-      parser.reportRecoverableError(staticToken, fasta.messageStaticAfterConst);
-      // fall through to parse modifier
-    } else if (finalToken != null) {
-      parser.reportRecoverableError(staticToken, fasta.messageStaticAfterFinal);
-      // fall through to parse modifier
-    } else if (varToken != null) {
-      parser.reportRecoverableError(staticToken, fasta.messageStaticAfterVar);
-      // fall through to parse modifier
-    }
-    return super.parseStaticOpt(token);
-  }
-
-  @override
-  Token parseVar(Token token) {
-    Token next = token.next;
-    if (varToken != null) {
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateDuplicatedModifier);
-      return next;
-    }
-    varToken = next;
-    if (constToken != null) {
-      parser.reportRecoverableError(varToken, fasta.messageConstAndVar);
-      return varToken;
-    }
-    if (finalToken != null) {
-      parser.reportRecoverableError(varToken, fasta.messageFinalAndVar);
-      return varToken;
-    }
-    return super.parseVar(token);
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 4d9aac8..394e0d5 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -78,11 +78,7 @@
 import 'member_kind.dart' show MemberKind;
 
 import 'modifier_context.dart'
-    show
-        ModifierRecoveryContext,
-        ModifierRecoveryContext2,
-        isModifier,
-        typeContinuationAfterVar;
+    show ModifierRecoveryContext, isModifier, typeContinuationAfterVar;
 
 import 'recovery_listeners.dart'
     show ClassHeaderRecoveryListener, ImportRecoveryListener;
@@ -757,17 +753,50 @@
   /// ```
   Token parseConditionalUri(Token token) {
     Token ifKeyword = token = token.next;
-    listener.beginConditionalUri(ifKeyword);
-    token = expect('if', token);
-    Token leftParen = token;
-    expect('(', token);
-    token = parseDottedName(token).next;
-    Token equalitySign;
-    if (optional('==', token)) {
-      equalitySign = token;
-      token = ensureLiteralString(token).next;
+    assert(optional('if', token));
+    listener.beginConditionalUri(token);
+    Token leftParen = token.next;
+    if (!optional('(', leftParen)) {
+      reportRecoverableError(
+          leftParen, fasta.templateExpectedButGot.withArguments('('));
+
+      int offset = leftParen.charOffset;
+      BeginToken openParen =
+          new SyntheticBeginToken(TokenType.OPEN_PAREN, offset);
+      Token next = openParen
+          .setNext(new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+      next = next.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
+      openParen.endGroup = next;
+
+      token.setNext(openParen);
+      next.setNext(leftParen);
+      leftParen = openParen;
     }
-    expect(')', token);
+    token = leftParen;
+    token = parseDottedName(token);
+    Token next = token.next;
+    Token equalitySign;
+    if (optional('==', next)) {
+      equalitySign = next;
+      token = ensureLiteralString(next);
+      next = token.next;
+    }
+    if (next != leftParen.endGroup) {
+      reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
+      Token endGroup = leftParen.endGroup;
+      if (endGroup.isSynthetic) {
+        // The scanner did not place the synthetic ')' correctly, so move it.
+
+        // TODO(danrubel): Its costly to find the token before the endGroup.
+        // Consider beforeSynthetic field that points to the previous token
+        // only for synthetic tokens such as ')', '}', ']' so that the parser
+        // can easily move these to the correct location.
+      }
+      next = endGroup;
+    }
+    token = next;
+    assert(optional(')', token));
+
     token = ensureLiteralString(token);
     listener.endConditionalUri(ifKeyword, leftParen, equalitySign);
     return token;
@@ -1192,19 +1221,16 @@
     assert(parameterKind != null);
     token = parseMetadataStar(token);
     Token next = token.next;
-    listener.beginFormalParameter(next, memberKind);
 
     TypeContinuation typeContinuation =
         typeContinuationFromFormalParameterKind(parameterKind);
+    Token covariantToken;
     Token varFinalOrConst;
     if (isModifier(next)) {
-      int modifierCount = 0;
-      Token covariantToken;
       if (optional('covariant', next)) {
         if (memberKind != MemberKind.StaticMethod &&
             memberKind != MemberKind.TopLevelMethod) {
-          covariantToken = token = parseModifier(token);
-          ++modifierCount;
+          covariantToken = token = next;
           next = token.next;
         }
       }
@@ -1212,36 +1238,33 @@
       if (isModifier(next)) {
         if (optional('var', next)) {
           typeContinuation = typeContinuationAfterVar(typeContinuation);
-          varFinalOrConst = token = parseModifier(token);
-          ++modifierCount;
+          varFinalOrConst = token = next;
           next = token.next;
         } else if (optional('final', next)) {
-          varFinalOrConst = token = parseModifier(token);
-          ++modifierCount;
+          varFinalOrConst = token = next;
           next = token.next;
         }
 
         if (isModifier(next)) {
           // Recovery
-          ModifierRecoveryContext modifierContext = new ModifierRecoveryContext(
-              this, memberKind, parameterKind, false, typeContinuation);
-          token = modifierContext.parseRecovery(token,
-              covariantToken: covariantToken, varFinalOrConst: varFinalOrConst);
-
-          modifierCount = modifierContext.modifierCount;
-          covariantToken = modifierContext.covariantToken;
-          varFinalOrConst = modifierContext.varFinalOrConst;
-
-          memberKind = modifierContext.memberKind;
-          typeContinuation = modifierContext.typeContinuation;
-          varFinalOrConst = modifierContext.varFinalOrConst;
-          modifierContext = null;
+          ModifierRecoveryContext context = new ModifierRecoveryContext(this);
+          token = context.parseFormalParameterModifiers(
+              token,
+              memberKind == MemberKind.StaticMethod ||
+                  memberKind == MemberKind.TopLevelMethod,
+              covariantToken: covariantToken,
+              varFinalOrConst: varFinalOrConst);
+          covariantToken = context.covariantToken;
+          varFinalOrConst = context.varFinalOrConst;
+          if (varFinalOrConst != null && optional('var', varFinalOrConst)) {
+            typeContinuation = typeContinuationAfterVar(typeContinuation);
+          }
+          context = null;
         }
       }
-      listener.handleModifiers(modifierCount);
-    } else {
-      listener.handleModifiers(0);
     }
+    listener.beginFormalParameter(
+        next, memberKind, covariantToken, varFinalOrConst);
 
     return parseType(
         token, typeContinuation, null, memberKind, varFinalOrConst);
@@ -1952,9 +1975,7 @@
       return true;
     }
     List<String> followingValues;
-    if (context == IdentifierContext.classOrNamedMixinDeclaration) {
-      followingValues = ['<', 'extends', 'with', 'implements', '{'];
-    } else if (context == IdentifierContext.combinator) {
+    if (context == IdentifierContext.combinator) {
       followingValues = [';'];
     } else if (context == IdentifierContext.constructorReferenceContinuation) {
       followingValues = ['.', ',', '(', ')', '[', ']', '}', ';'];
@@ -2043,9 +2064,7 @@
     // could create a method to test whether a given token matches one of the
     // patterns.
     List<String> initialKeywords;
-    if (context == IdentifierContext.classOrNamedMixinDeclaration) {
-      initialKeywords = topLevelKeywords();
-    } else if (context == IdentifierContext.fieldDeclaration) {
+    if (context == IdentifierContext.fieldDeclaration) {
       initialKeywords = classMemberKeywords();
     } else if (context == IdentifierContext.enumDeclaration) {
       initialKeywords = topLevelKeywords();
@@ -2736,7 +2755,7 @@
           next = token.next;
         }
         if (isModifier(next)) {
-          ModifierRecoveryContext2 context = new ModifierRecoveryContext2(this);
+          ModifierRecoveryContext context = new ModifierRecoveryContext(this);
           token = context.parseTopLevelModifiers(token,
               externalToken: externalToken, varFinalOrConst: varFinalOrConst);
           next = token.next;
@@ -3189,7 +3208,7 @@
     if (!identical(next.kind, STRING_TOKEN)) {
       Message message = fasta.templateExpectedString.withArguments(next);
       Token newToken =
-          new SyntheticStringToken(TokenType.STRING, '""', token.charOffset, 0);
+          new SyntheticStringToken(TokenType.STRING, '""', next.charOffset, 0);
       rewriteAndRecover(token, message, newToken);
     }
     return parseLiteralString(token);
@@ -3303,13 +3322,6 @@
     return 127;
   }
 
-  Token parseModifier(Token token) {
-    token = token.next;
-    assert(token.isModifier);
-    listener.handleModifier(token);
-    return token;
-  }
-
   Token parseNativeClause(Token token) {
     Token nativeToken = token = token.next;
     assert(optional('native', nativeToken));
@@ -3422,8 +3434,7 @@
             next = token.next;
           }
           if (isModifier(next)) {
-            ModifierRecoveryContext2 context =
-                new ModifierRecoveryContext2(this);
+            ModifierRecoveryContext context = new ModifierRecoveryContext(this);
             token = context.parseClassMemberModifiers(token,
                 externalToken: externalToken,
                 staticToken: staticToken,
@@ -3671,7 +3682,7 @@
 
     if (!isValidTypeReference(token.next)) {
       // Recovery
-      ModifierRecoveryContext2 context = new ModifierRecoveryContext2(this);
+      ModifierRecoveryContext context = new ModifierRecoveryContext(this);
       token = context.parseModifiersAfterFactory(token,
           externalToken: externalToken,
           staticOrCovariant: staticOrCovariant,
@@ -5401,8 +5412,8 @@
 
       if (isModifier(next)) {
         // Recovery
-        ModifierRecoveryContext2 modifierContext =
-            new ModifierRecoveryContext2(this);
+        ModifierRecoveryContext modifierContext =
+            new ModifierRecoveryContext(this);
         token = modifierContext.parseVariableDeclarationModifiers(token,
             varFinalOrConst: varFinalOrConst);
         next = token.next;
@@ -5582,15 +5593,30 @@
 
       BeginToken openParen =
           token.setNext(new SyntheticBeginToken(TokenType.OPEN_PAREN, offset));
-      Token semicolon =
-          openParen.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
-      semicolon =
-          semicolon.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
+
+      Token loopPart;
+      if (awaitToken != null) {
+        loopPart = openParen.setNext(
+            new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+        loopPart =
+            loopPart.setNext(new SyntheticKeywordToken(Keyword.IN, offset));
+        loopPart = loopPart.setNext(
+            new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+      } else {
+        loopPart =
+            openParen.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
+        loopPart =
+            loopPart.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
+      }
+
       Token closeParen =
-          semicolon.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
+          loopPart.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
       openParen.endGroup = closeParen;
-      closeParen.setNext(leftParenthesis);
-      insertBlock(closeParen);
+      Token identifier = closeParen
+          .setNext(new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+      Token semicolon =
+          identifier.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
+      semicolon.setNext(leftParenthesis);
 
       leftParenthesis = openParen;
     }
@@ -5619,12 +5645,18 @@
         // Recovery
         reportRecoverableError(next, fasta.messageColonInPlaceOfIn);
         // Fall through to process `for ( ... in ... )`
-      } else {
+      } else if (awaitToken == null || optional(';', next)) {
         // Process `for ( ... ; ... ; ... )`
         if (awaitToken != null) {
           reportRecoverableError(awaitToken, fasta.messageInvalidAwaitFor);
         }
         return parseForRest(token, forKeyword, leftParenthesis);
+      } else {
+        // Recovery
+        reportRecoverableError(
+            next, fasta.templateExpectedButGot.withArguments('in'));
+        next = token.setNext(
+            new SyntheticKeywordToken(Keyword.IN, next.offset)..setNext(next));
       }
     }
 
@@ -5709,8 +5741,12 @@
     assert(optional('in', inKeyword) || optional(':', inKeyword));
     listener.beginForInExpression(inKeyword.next);
     token = parseExpression(inKeyword).next;
+    if (!optional(')', token)) {
+      reportRecoverableError(
+          token, fasta.templateExpectedButGot.withArguments(')'));
+      token = leftParenthesis.endGroup;
+    }
     listener.endForInExpression(token);
-    expect(')', token);
     listener.beginForInBody(token.next);
     LoopState savedLoopState = loopState;
     loopState = LoopState.InsideLoop;
@@ -6153,13 +6189,30 @@
   /// ;
   /// ```
   Token parseAssert(Token token, Assert kind) {
-    Token assertKeyword = token.next;
-    assert(optional('assert', assertKeyword));
-    listener.beginAssert(assertKeyword, kind);
+    token = token.next;
+    assert(optional('assert', token));
+    listener.beginAssert(token, kind);
+    Token assertKeyword = token;
+    Token leftParenthesis = token.next;
+    if (!optional('(', leftParenthesis)) {
+      // Recovery
+      reportRecoverableError(
+          leftParenthesis, fasta.templateExpectedButGot.withArguments('('));
+      int offset = leftParenthesis.offset;
+
+      BeginToken openParen =
+          token.setNext(new SyntheticBeginToken(TokenType.OPEN_PAREN, offset));
+      Token identifier = openParen
+          .setNext(new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+      Token closeParen =
+          identifier.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
+      openParen.endGroup = closeParen;
+      closeParen.setNext(leftParenthesis);
+
+      leftParenthesis = openParen;
+    }
+    token = leftParenthesis;
     Token commaToken = null;
-    token = assertKeyword.next;
-    Token leftParenthesis = token;
-    expect('(', token);
     bool old = mayParseFunctionExpressions;
     mayParseFunctionExpressions = true;
     token = parseExpression(token).next;
@@ -6179,6 +6232,7 @@
         while (optional(',', token)) {
           Token begin = token.next;
           token = parseExpression(token).next;
+          // TODO(danrubel): Consider removing the message argument.
           listener.handleExtraneousExpression(
               begin, fasta.messageAssertExtraneousArgument);
         }
@@ -6186,13 +6240,15 @@
             firstExtra, fasta.messageAssertExtraneousArgument);
       }
     }
-    expect(')', token);
+    assert(optional(')', token));
     mayParseFunctionExpressions = old;
-    listener.endAssert(
-        assertKeyword, kind, leftParenthesis, commaToken, token.next);
     if (kind == Assert.Expression) {
       reportRecoverableError(assertKeyword, fasta.messageAssertAsExpression);
+    } else if (kind == Assert.Statement) {
+      ensureSemicolon(token);
     }
+    listener.endAssert(
+        assertKeyword, kind, leftParenthesis, commaToken, token.next);
     return token;
   }
 
@@ -6203,8 +6259,8 @@
   /// ```
   Token parseAssertStatement(Token token) {
     assert(optional('assert', token.next));
-    token = parseAssert(token, Assert.Statement);
-    return ensureSemicolon(token);
+    // parseAssert ensures that there is a trailing semicolon.
+    return parseAssert(token, Assert.Statement).next;
   }
 
   /// ```
diff --git a/pkg/front_end/lib/src/fasta/parser/parser_main.dart b/pkg/front_end/lib/src/fasta/parser/parser_main.dart
index 1cd1820..a282842 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser_main.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser_main.dart
@@ -4,7 +4,7 @@
 
 library fasta.parser.main;
 
-import 'dart:convert' show LineSplitter, UTF8;
+import 'dart:convert' show LineSplitter, utf8;
 
 import 'dart:io' show File;
 
@@ -36,7 +36,7 @@
       Uri uri = Uri.base.resolve(argument.substring(1));
       await for (String file in new File.fromUri(uri)
           .openRead()
-          .transform(UTF8.decoder)
+          .transform(utf8.decoder)
           .transform(const LineSplitter())) {
         outLine(uri.resolve(file));
       }
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 4b2394a..01e6edb 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -8,25 +8,17 @@
 
 import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN, KEYWORD_TOKEN;
 
-import '../util/link.dart' show Link;
-
-import 'identifier_context.dart' show IdentifierContext;
-
-import 'listener.dart' show Listener;
-
-import 'member_kind.dart' show MemberKind;
-
 import 'parser.dart' show Parser;
 
 import 'type_info_impl.dart'
     show
+        ComplexTypeInfo,
         NoTypeInfo,
         PrefixedTypeInfo,
         SimpleTypeArgumentsInfo,
         SimpleTypeInfo,
         VoidTypeInfo,
-        looksLikeName,
-        skipTypeArguments;
+        looksLikeName;
 
 import 'util.dart' show optional;
 
@@ -46,6 +38,13 @@
   /// code or during recovery.
   Token ensureTypeNotVoid(Token token, Parser parser);
 
+  /// Call this function when the token after [token] must be a type or void.
+  /// This function will call the appropriate event methods on the [Parser]'s
+  /// listener to handle the type, inserting a synthetic type reference if
+  /// necessary. This may modify the token stream when parsing `>>` in valid
+  /// code or during recovery.
+  Token ensureTypeOrVoid(Token token, Parser parser);
+
   /// Call this function to parse an optional type (not void) after [token].
   /// This function will call the appropriate event methods on the [Parser]'s
   /// listener to handle the type. This may modify the token stream
@@ -118,11 +117,12 @@
   if (!isValidTypeReference(next)) {
     if (next.type.isBuiltIn) {
       Token afterType = next.next;
-      if (optional('<', afterType) &&
-          afterType.endGroup != null &&
-          looksLikeName(afterType.endGroup.next)) {
-        // Recovery: built-in used as a type
-        return new ComplexTypeInfo(token).computeBuiltinAsType(required);
+      if (optional('<', afterType)) {
+        Token endGroup = afterType.endGroup;
+        if (endGroup != null && looksLikeName(endGroup.next)) {
+          // Recovery: built-in used as a type
+          return new ComplexTypeInfo(token).computeBuiltinAsType(required);
+        }
       } else {
         String value = next.stringValue;
         if (!identical('get', value) &&
@@ -161,12 +161,13 @@
   next = next.next;
 
   if (optional('<', next)) {
-    if (next.endGroup != null) {
+    Token endGroup = next.endGroup;
+    if (endGroup != null) {
       next = next.next;
       // identifier `<` `void` `>` is handled by ComplexTypeInfo.
       if (isValidTypeReference(next) && !identical('void', next.stringValue)) {
         next = next.next;
-        if (optional('>', next)) {
+        if (next == endGroup) {
           // We've seen identifier `<` identifier `>`
           next = next.next;
           if (!isGeneralizedFunctionType(next)) {
@@ -224,242 +225,3 @@
   }
   return noTypeInfo;
 }
-
-/// Instances of [ComplexTypeInfo] are returned by [computeType] to represent
-/// type references that cannot be represented by the constants above.
-class ComplexTypeInfo implements TypeInfo {
-  /// The first token in the type reference.
-  final Token start;
-
-  /// The last token in the type reference.
-  Token end;
-
-  /// Non-null if type arguments were seen during analysis.
-  Token typeArguments;
-
-  /// The tokens before the start of type variables of function types seen
-  /// during analysis. Notice that the tokens in this list might precede
-  /// either `'<'` or `'('` as not all function types have type parameters.
-  Link<Token> typeVariableStarters = const Link<Token>();
-
-  /// If the receiver represents a generalized function type then this indicates
-  /// whether it has a return type, otherwise this is `null`.
-  bool gftHasReturnType;
-
-  ComplexTypeInfo(Token beforeStart) : this.start = beforeStart.next;
-
-  @override
-  bool get couldBeExpression => false;
-
-  @override
-  Token ensureTypeNotVoid(Token token, Parser parser) =>
-      parseType(token, parser);
-
-  @override
-  Token parseTypeNotVoid(Token token, Parser parser) =>
-      parseType(token, parser);
-
-  @override
-  Token parseType(Token token, Parser parser) {
-    assert(identical(token.next, start));
-    Listener listener = parser.listener;
-
-    for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
-      parser.parseTypeVariablesOpt(t.head);
-      listener.beginFunctionType(start);
-    }
-
-    if (gftHasReturnType == false) {
-      // A function type without return type.
-      // Push the non-existing return type first. The loop below will
-      // generate the full type.
-      noTypeInfo.parseTypeNotVoid(token, parser);
-    } else if (optional('void', token.next)) {
-      token = voidTypeInfo.parseType(token, parser);
-    } else {
-      if (!optional('.', token.next.next)) {
-        token = parser.ensureIdentifier(token, IdentifierContext.typeReference);
-      } else {
-        token = parser.ensureIdentifier(
-            token, IdentifierContext.prefixedTypeReference);
-        token = parser.parseQualifiedRest(
-            token, IdentifierContext.typeReferenceContinuation);
-      }
-      token = parser.parseTypeArgumentsOpt(token);
-      listener.handleType(start, token.next);
-    }
-
-    for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
-      token = token.next;
-      assert(optional('Function', token));
-      Token functionToken = token;
-      if (optional("<", token.next)) {
-        // Skip type parameters, they were parsed above.
-        token = token.next.endGroup;
-      }
-      token = parser.parseFormalParametersRequiredOpt(
-          token, MemberKind.GeneralizedFunctionType);
-      listener.endFunctionType(functionToken, token.next);
-    }
-
-    // There are two situations in which the [token] != [end]:
-    // Valid code:    identifier `<` identifier `<` identifier `>>`
-    //    where `>>` is replaced by two tokens.
-    // Invalid code:  identifier `<` identifier identifier `>`
-    //    where a synthetic `>` is inserted between the identifiers.
-    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;
-  }
-
-  @override
-  Token skipType(Token token) {
-    return end;
-  }
-
-  /// Given `Function` non-identifier, compute the type
-  /// and return the receiver or one of the [TypeInfo] constants.
-  TypeInfo computeNoTypeGFT(bool required) {
-    assert(optional('Function', start));
-    computeRest(start, required);
-
-    if (gftHasReturnType == null) {
-      return required ? simpleTypeInfo : noTypeInfo;
-    }
-    assert(end != null);
-    return this;
-  }
-
-  /// Given void `Function` non-identifier, compute the type
-  /// and return the receiver or one of the [TypeInfo] constants.
-  TypeInfo computeVoidGFT(bool required) {
-    assert(optional('void', start));
-    assert(optional('Function', start.next));
-    computeRest(start.next, required);
-
-    if (gftHasReturnType == null) {
-      return voidTypeInfo;
-    }
-    assert(end != null);
-    return this;
-  }
-
-  /// Given a builtin, return the receiver so that parseType will report
-  /// an error for the builtin used as a type.
-  TypeInfo computeBuiltinAsType(bool required) {
-    assert(start.type.isBuiltIn);
-    end = start;
-    Token token = start.next;
-    if (optional('<', token)) {
-      typeArguments = token;
-      token = skipTypeArguments(typeArguments);
-      if (token == null) {
-        token = typeArguments;
-        typeArguments = null;
-      } else {
-        end = token;
-      }
-    }
-    computeRest(token, required);
-
-    assert(end != null);
-    return this;
-  }
-
-  /// Given identifier `Function` non-identifier, compute the type
-  /// and return the receiver or one of the [TypeInfo] constants.
-  TypeInfo computeIdentifierGFT(bool required) {
-    assert(isValidTypeReference(start));
-    assert(optional('Function', start.next));
-    computeRest(start.next, required);
-
-    if (gftHasReturnType == null) {
-      return simpleTypeInfo;
-    }
-    assert(end != null);
-    return this;
-  }
-
-  /// Given identifier `<` ... `>`, compute the type
-  /// and return the receiver or one of the [TypeInfo] constants.
-  TypeInfo computeSimpleWithTypeArguments(bool required) {
-    assert(isValidTypeReference(start));
-    typeArguments = start.next;
-    assert(optional('<', typeArguments));
-
-    Token token = skipTypeArguments(typeArguments);
-    if (token == null) {
-      return required ? simpleTypeInfo : noTypeInfo;
-    }
-    end = token;
-    computeRest(token.next, required);
-
-    if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
-      return noTypeInfo;
-    }
-    assert(end != null);
-    return this;
-  }
-
-  /// Given identifier `.` identifier, compute the type
-  /// and return the receiver or one of the [TypeInfo] constants.
-  TypeInfo computePrefixedType(bool required) {
-    assert(isValidTypeReference(start));
-    Token token = start.next;
-    assert(optional('.', token));
-    token = token.next;
-    assert(isValidTypeReference(token));
-
-    end = token;
-    token = token.next;
-    if (optional('<', token)) {
-      typeArguments = token;
-      token = skipTypeArguments(token);
-      if (token == null) {
-        return required ? prefixedTypeInfo : noTypeInfo;
-      }
-      end = token;
-      token = token.next;
-    }
-    computeRest(token, required);
-
-    if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
-      return noTypeInfo;
-    }
-    assert(end != null);
-    return this;
-  }
-
-  void computeRest(Token token, bool required) {
-    while (optional('Function', token)) {
-      Token typeVariableStart = token;
-      token = token.next;
-      if (optional('<', token)) {
-        token = token.endGroup;
-        if (token == null) {
-          break; // Not a function type.
-        }
-        assert(optional('>', token) || optional('>>', token));
-        token = token.next;
-      }
-      if (!optional('(', token)) {
-        break; // Not a function type.
-      }
-      token = token.endGroup;
-      if (token == null) {
-        break; // Not a function type.
-      }
-      if (!required && !token.next.isIdentifier) {
-        break; // `Function` used as the name in a function declaration.
-      }
-      assert(optional(')', token));
-      gftHasReturnType ??= typeVariableStart != start;
-      typeVariableStarters = typeVariableStarters.prepend(typeVariableStart);
-      end = token;
-      token = token.next;
-    }
-  }
-}
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 1a4c75b..08b2cce 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
@@ -8,14 +8,17 @@
 
 import '../fasta_codes.dart' as fasta;
 
+import '../util/link.dart' show Link;
+
 import 'identifier_context.dart' show IdentifierContext;
 
+import 'member_kind.dart' show MemberKind;
+
 import 'listener.dart' show Listener;
 
 import 'parser.dart' show Parser;
 
-import 'type_info.dart'
-    show insertSyntheticIdentifierAfter, simpleTypeInfo, TypeInfo;
+import 'type_info.dart';
 
 import 'util.dart' show optional;
 
@@ -31,10 +34,14 @@
     parser.reportRecoverableErrorWithToken(
         token.next, fasta.templateExpectedType);
     insertSyntheticIdentifierAfter(token, parser);
-    return simpleTypeInfo.parseTypeNotVoid(token, parser);
+    return simpleTypeInfo.parseType(token, parser);
   }
 
   @override
+  Token ensureTypeOrVoid(Token token, Parser parser) =>
+      ensureTypeNotVoid(token, parser);
+
+  @override
   Token parseTypeNotVoid(Token token, Parser parser) =>
       parseType(token, parser);
 
@@ -62,6 +69,10 @@
       parseType(token, parser);
 
   @override
+  Token ensureTypeOrVoid(Token token, Parser parser) =>
+      parseType(token, parser);
+
+  @override
   Token parseTypeNotVoid(Token token, Parser parser) =>
       parseType(token, parser);
 
@@ -104,6 +115,10 @@
       parseType(token, parser);
 
   @override
+  Token ensureTypeOrVoid(Token token, Parser parser) =>
+      parseType(token, parser);
+
+  @override
   Token parseTypeNotVoid(Token token, Parser parser) =>
       parseType(token, parser);
 
@@ -147,6 +162,10 @@
       parseType(token, parser);
 
   @override
+  Token ensureTypeOrVoid(Token token, Parser parser) =>
+      parseType(token, parser);
+
+  @override
   Token parseTypeNotVoid(Token token, Parser parser) =>
       parseType(token, parser);
 
@@ -182,6 +201,10 @@
   }
 
   @override
+  Token ensureTypeOrVoid(Token token, Parser parser) =>
+      parseType(token, parser);
+
+  @override
   Token parseTypeNotVoid(Token token, Parser parser) =>
       ensureTypeNotVoid(token, parser);
 
@@ -198,7 +221,8 @@
   }
 }
 
-bool looksLikeName(Token next) => next.isIdentifier || optional('this', next);
+bool looksLikeName(Token token) =>
+    token.isIdentifier || optional('this', token);
 
 Token skipTypeArguments(Token token) {
   assert(optional('<', token));
@@ -224,3 +248,249 @@
 
   return endGroup;
 }
+
+/// Instances of [ComplexTypeInfo] are returned by [computeType] to represent
+/// type references that cannot be represented by the constants above.
+class ComplexTypeInfo implements TypeInfo {
+  /// The first token in the type reference.
+  final Token start;
+
+  /// The last token in the type reference.
+  Token end;
+
+  /// Non-null if type arguments were seen during analysis.
+  Token typeArguments;
+
+  /// The tokens before the start of type variables of function types seen
+  /// during analysis. Notice that the tokens in this list might precede
+  /// either `'<'` or `'('` as not all function types have type parameters.
+  Link<Token> typeVariableStarters = const Link<Token>();
+
+  /// If the receiver represents a generalized function type then this indicates
+  /// whether it has a return type, otherwise this is `null`.
+  bool gftHasReturnType;
+
+  ComplexTypeInfo(Token beforeStart) : this.start = beforeStart.next;
+
+  @override
+  bool get couldBeExpression => false;
+
+  @override
+  Token ensureTypeNotVoid(Token token, Parser parser) =>
+      parseType(token, parser);
+
+  @override
+  Token ensureTypeOrVoid(Token token, Parser parser) =>
+      parseType(token, parser);
+
+  @override
+  Token parseTypeNotVoid(Token token, Parser parser) =>
+      parseType(token, parser);
+
+  @override
+  Token parseType(Token token, Parser parser) {
+    assert(identical(token.next, start));
+
+    for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
+      parser.parseTypeVariablesOpt(t.head);
+      parser.listener.beginFunctionType(start);
+    }
+
+    if (gftHasReturnType == false) {
+      // A function type without return type.
+      // Push the non-existing return type first. The loop below will
+      // generate the full type.
+      noTypeInfo.parseTypeNotVoid(token, parser);
+    } else {
+      Token start = token.next;
+      if (optional('void', start)) {
+        token = voidTypeInfo.parseType(token, parser);
+      } else {
+        if (!optional('.', start.next)) {
+          token =
+              parser.ensureIdentifier(token, IdentifierContext.typeReference);
+        } else {
+          token = parser.ensureIdentifier(
+              token, IdentifierContext.prefixedTypeReference);
+          token = parser.parseQualifiedRest(
+              token, IdentifierContext.typeReferenceContinuation);
+        }
+        token = parser.parseTypeArgumentsOpt(token);
+        parser.listener.handleType(start, token.next);
+      }
+    }
+
+    for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
+      token = token.next;
+      assert(optional('Function', token));
+      Token functionToken = token;
+      if (optional("<", token.next)) {
+        // Skip type parameters, they were parsed above.
+        token = token.next.endGroup;
+      }
+      token = parser.parseFormalParametersRequiredOpt(
+          token, MemberKind.GeneralizedFunctionType);
+      parser.listener.endFunctionType(functionToken, token.next);
+    }
+
+    // There are two situations in which the [token] != [end]:
+    // Valid code:    identifier `<` identifier `<` identifier `>>`
+    //    where `>>` is replaced by two tokens.
+    // Invalid code:  identifier `<` identifier identifier `>`
+    //    where a synthetic `>` is inserted between the identifiers.
+    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;
+  }
+
+  @override
+  Token skipType(Token token) {
+    return end;
+  }
+
+  /// Given `Function` non-identifier, compute the type
+  /// and return the receiver or one of the [TypeInfo] constants.
+  TypeInfo computeNoTypeGFT(bool required) {
+    assert(optional('Function', start));
+    computeRest(start, required);
+
+    if (gftHasReturnType == null) {
+      return required ? simpleTypeInfo : noTypeInfo;
+    }
+    assert(end != null);
+    return this;
+  }
+
+  /// Given void `Function` non-identifier, compute the type
+  /// and return the receiver or one of the [TypeInfo] constants.
+  TypeInfo computeVoidGFT(bool required) {
+    assert(optional('void', start));
+    assert(optional('Function', start.next));
+    computeRest(start.next, required);
+
+    if (gftHasReturnType == null) {
+      return voidTypeInfo;
+    }
+    assert(end != null);
+    return this;
+  }
+
+  /// Given a builtin, return the receiver so that parseType will report
+  /// an error for the builtin used as a type.
+  TypeInfo computeBuiltinAsType(bool required) {
+    assert(start.type.isBuiltIn);
+    end = start;
+    Token token = start.next;
+    if (optional('<', token)) {
+      typeArguments = token;
+      token = skipTypeArguments(typeArguments);
+      if (token == null) {
+        token = typeArguments;
+        typeArguments = null;
+      } else {
+        end = token;
+      }
+    }
+    computeRest(token, required);
+
+    assert(end != null);
+    return this;
+  }
+
+  /// Given identifier `Function` non-identifier, compute the type
+  /// and return the receiver or one of the [TypeInfo] constants.
+  TypeInfo computeIdentifierGFT(bool required) {
+    assert(isValidTypeReference(start));
+    assert(optional('Function', start.next));
+    computeRest(start.next, required);
+
+    if (gftHasReturnType == null) {
+      return simpleTypeInfo;
+    }
+    assert(end != null);
+    return this;
+  }
+
+  /// Given identifier `<` ... `>`, compute the type
+  /// and return the receiver or one of the [TypeInfo] constants.
+  TypeInfo computeSimpleWithTypeArguments(bool required) {
+    assert(isValidTypeReference(start));
+    typeArguments = start.next;
+    assert(optional('<', typeArguments));
+
+    Token token = skipTypeArguments(typeArguments);
+    if (token == null) {
+      return required ? simpleTypeInfo : noTypeInfo;
+    }
+    end = token;
+    computeRest(token.next, required);
+
+    if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
+      return noTypeInfo;
+    }
+    assert(end != null);
+    return this;
+  }
+
+  /// Given identifier `.` identifier, compute the type
+  /// and return the receiver or one of the [TypeInfo] constants.
+  TypeInfo computePrefixedType(bool required) {
+    assert(isValidTypeReference(start));
+    Token token = start.next;
+    assert(optional('.', token));
+    token = token.next;
+    assert(isValidTypeReference(token));
+
+    end = token;
+    token = token.next;
+    if (optional('<', token)) {
+      typeArguments = token;
+      token = skipTypeArguments(token);
+      if (token == null) {
+        return required ? prefixedTypeInfo : noTypeInfo;
+      }
+      end = token;
+      token = token.next;
+    }
+    computeRest(token, required);
+
+    if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
+      return noTypeInfo;
+    }
+    assert(end != null);
+    return this;
+  }
+
+  void computeRest(Token token, bool required) {
+    while (optional('Function', token)) {
+      Token typeVariableStart = token;
+      token = token.next;
+      if (optional('<', token)) {
+        token = token.endGroup;
+        if (token == null) {
+          break; // Not a function type.
+        }
+        assert(optional('>', token) || optional('>>', token));
+        token = token.next;
+      }
+      if (!optional('(', token)) {
+        break; // Not a function type.
+      }
+      token = token.endGroup;
+      if (token == null) {
+        break; // Not a function type.
+      }
+      if (!required && !token.next.isIdentifier) {
+        break; // `Function` used as the name in a function declaration.
+      }
+      assert(optional(')', token));
+      gftHasReturnType ??= typeVariableStart != start;
+      typeVariableStarters = typeVariableStarters.prepend(typeVariableStart);
+      end = token;
+      token = token.next;
+    }
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/scanner.dart b/pkg/front_end/lib/src/fasta/scanner.dart
index 4b83833..21de9c1 100644
--- a/pkg/front_end/lib/src/fasta/scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner.dart
@@ -4,7 +4,7 @@
 
 library fasta.scanner;
 
-import 'dart:convert' show UNICODE_REPLACEMENT_CHARACTER_RUNE, UTF8;
+import 'dart:convert' show unicodeReplacementCharacterRune, utf8;
 
 import '../scanner/token.dart' show Token;
 
@@ -34,7 +34,7 @@
 
 export '../scanner/token.dart' show Keyword, Token;
 
-const int unicodeReplacementCharacter = UNICODE_REPLACEMENT_CHARACTER_RUNE;
+const int unicodeReplacementCharacter = unicodeReplacementCharacterRune;
 
 typedef Token Recover(List<int> bytes, Token tokens, List<int> lineStarts);
 
@@ -88,7 +88,7 @@
     {List<int> bytes, String source}) {
   Token tokens = scanner.tokenize();
   if (scanner.hasErrors) {
-    if (bytes == null) bytes = UTF8.encode(source);
+    if (bytes == null) bytes = utf8.encode(source);
     recover ??= defaultRecoveryStrategy;
     tokens = recover(bytes, tokens, scanner.lineStarts);
   }
diff --git a/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
index 3947642..9442bf9 100644
--- a/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
@@ -4,7 +4,7 @@
 
 library fasta.scanner.utf8_bytes_scanner;
 
-import 'dart:convert' show UNICODE_BOM_CHARACTER_RUNE, UTF8;
+import 'dart:convert' show unicodeBomCharacterRune, utf8;
 
 import '../../scanner/token.dart' show SyntheticStringToken, TokenType;
 
@@ -133,13 +133,13 @@
     // TODO(lry): measurably slow, decode creates first a Utf8Decoder and a
     // _Utf8Decoder instance. Also the sublist is eagerly allocated.
     String codePoint =
-        UTF8.decode(bytes.sublist(startOffset, end), allowMalformed: true);
+        utf8.decode(bytes.sublist(startOffset, end), allowMalformed: true);
     if (codePoint.length == 0) {
       // The UTF-8 decoder discards leading BOM characters.
       // TODO(floitsch): don't just assume that removed characters were the
       // BOM.
       assert(containsBomAt(startOffset));
-      codePoint = new String.fromCharCode(UNICODE_BOM_CHARACTER_RUNE);
+      codePoint = new String.fromCharCode(unicodeBomCharacterRune);
     }
     if (codePoint.length == 1) {
       utf8Slack += (numBytes - 1);
@@ -176,7 +176,7 @@
     int end = byteOffset;
     // TODO(lry): this measurably slows down the scanner for files with unicode.
     String s =
-        UTF8.decode(bytes.sublist(startScanOffset, end), allowMalformed: true);
+        utf8.decode(bytes.sublist(startScanOffset, end), allowMalformed: true);
     utf8Slack += (end - startScanOffset) - s.length;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index be0d0d0..cdf9a9b 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -13,7 +13,7 @@
         messageInternalProblemExtendingUnmodifiableScope,
         templateAccessError,
         templateDuplicatedName,
-        templatePreviousUseOfName;
+        templateDuplicatedNamePreviouslyUsedCause;
 
 import 'problems.dart' show internalProblem, unsupported;
 
@@ -201,18 +201,17 @@
 
   /// Declares that the meaning of [name] in this scope is [builder].
   ///
-  /// If name was used previously in this scope, this method returns an error
-  /// that should be reported as a compile-time error. The position of this
-  /// error is given by [charOffset] and [fileUri].
-  LocatedMessage declare(
-      String name, Builder builder, int charOffset, Uri fileUri) {
+  /// If name was used previously in this scope, this method returns a message
+  /// that can be used as context for reporting a compile-time error about
+  /// [name] being used before its declared. [fileUri] is used to bind the
+  /// location of this message.
+  LocatedMessage declare(String name, Builder builder, Uri fileUri) {
     if (isModifiable) {
       if (usedNames?.containsKey(name) ?? false) {
-        return templatePreviousUseOfName
+        return templateDuplicatedNamePreviouslyUsedCause
             .withArguments(name)
             .withLocation(fileUri, usedNames[name], name.length);
       }
-      recordUse(name, charOffset, fileUri);
       local[name] = builder;
     } else {
       internalProblem(
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 445b4a5..68b1941 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -112,11 +112,6 @@
   }
 
   @override
-  void handleModifiers(int count) {
-    debugEvent("Modifiers");
-  }
-
-  @override
   void handleNoTypeArguments(Token token) {
     debugEvent("NoTypeArguments");
   }
@@ -457,11 +452,6 @@
   }
 
   @override
-  void handleModifier(Token token) {
-    debugEvent("Modifier");
-  }
-
-  @override
   void endConstructorReference(
       Token start, Token periodBeforeName, Token endToken) {
     debugEvent("ConstructorReference");
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 0bdf2dd..195f710 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -767,13 +767,20 @@
   }
 
   @override
+  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+      Token varFinalOrConst) {
+    push((covariantToken != null ? covariantMask : 0) |
+        Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme));
+  }
+
+  @override
   void endFormalParameter(Token thisKeyword, Token periodAfterThis,
       Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
     debugEvent("FormalParameter");
     int charOffset = pop();
     String name = pop();
     TypeBuilder type = pop();
-    int modifiers = Modifier.validate(pop());
+    int modifiers = pop();
     List<MetadataBuilder> metadata = pop();
     push(library.addFormalParameter(
         metadata, modifiers, type, name, thisKeyword != null, charOffset));
@@ -1170,18 +1177,6 @@
   }
 
   @override
-  void handleModifier(Token token) {
-    debugEvent("Modifier");
-    push(new Modifier.fromString(token.stringValue));
-  }
-
-  @override
-  void handleModifiers(int count) {
-    debugEvent("Modifiers");
-    push(popList(count) ?? NullValue.Modifiers);
-  }
-
-  @override
   void addCompileTimeError(Message message, int charOffset, int length,
       {List<LocatedMessage> context}) {
     library.addCompileTimeError(message, charOffset, length, uri,
diff --git a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
index 49b1793..009b3e0 100644
--- a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
+++ b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
@@ -127,9 +127,11 @@
         .firstWhere((Library library) => library.importUri.scheme != "dart");
     Uri uri = library.importUri;
     Uri base = uri.resolve(".");
+    Uri dartBase = Uri.base;
     StringBuffer buffer = new StringBuffer();
     new Printer(buffer).writeLibraryFile(library);
     String actual = "$buffer".replaceAll("$base", "org-dartlang-testcase:///");
+    actual = actual.replaceAll("$dartBase", "org-dartlang-testcase-sdk:///");
     actual = actual.replaceAll("\\n", "\n");
     File expectedFile = new File("${uri.toFilePath()}$suffix");
     if (await expectedFile.exists()) {
diff --git a/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart b/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
index e392ed6..b721d4e 100644
--- a/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
+++ b/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async' show Future;
 
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
 
 import 'dart:io' show File;
 
@@ -106,7 +106,7 @@
     var bytes = (await file.readAsBytes()).toList();
     int convertOffset(int offset) {
       if (offsetsCountCharacters) {
-        return UTF8.encode(UTF8.decode(bytes).substring(0, offset)).length;
+        return utf8.encode(utf8.decode(bytes).substring(0, offset)).length;
       } else {
         return offset;
       }
@@ -117,7 +117,7 @@
     fixes.sort((a, b) => a.offset.compareTo(b.offset));
     for (var fix in fixes.reversed) {
       bytes.replaceRange(convertOffset(fix.offset),
-          convertOffset(fix.offset + fix.length), UTF8.encode(fix.replacement));
+          convertOffset(fix.offset + fix.length), utf8.encode(fix.replacement));
     }
     await file.writeAsBytes(bytes);
   }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
index ced42ae..6fbd643 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -31,17 +31,29 @@
 
 /// Concrete class derived from [InferenceNode] to represent type inference of
 /// getters, setters, and fields based on inheritance.
-class AccessorInferenceNode extends MemberInferenceNode {
-  AccessorInferenceNode(
-      InterfaceResolver interfaceResolver,
-      Procedure declaredMethod,
-      List<Member> candidates,
-      int start,
-      int end,
-      LibraryBuilder library,
-      Uri fileUri)
-      : super(interfaceResolver, declaredMethod, candidates, start, end,
-            library, fileUri);
+class AccessorInferenceNode extends InferenceNode {
+  final InterfaceResolver _interfaceResolver;
+
+  /// The method whose return type and/or parameter types should be inferred.
+  final Procedure _declaredMethod;
+
+  /// A list containing the methods overridden by [_declaredMethod], if any.
+  final List<Member> _candidates;
+
+  /// The index of the first method in [_candidates] overridden by
+  /// [_declaredMethod].
+  final int _start;
+
+  /// The past-the-end index of the last method in [_candidates] overridden by
+  /// [_declaredMethod].
+  final int _end;
+
+  final LibraryBuilder _library;
+
+  final Uri _fileUri;
+
+  AccessorInferenceNode(this._interfaceResolver, this._declaredMethod,
+      this._candidates, this._start, this._end, this._library, this._fileUri);
 
   String get _name {
     if (_declaredMethod is! SyntheticAccessor && _declaredMethod.isSetter) {
@@ -69,7 +81,8 @@
           noLength,
           _fileUri);
     } else {
-      var inferredType = _matchTypes(overriddenTypes, _name, _offset);
+      var inferredType = _interfaceResolver.matchTypes(
+          overriddenTypes, _library, _name, _fileUri, _offset);
       if (declaredMethod is SyntheticAccessor) {
         declaredMethod._field.type = inferredType;
       } else {
@@ -482,39 +495,31 @@
       ..isGenericContravariant = target.isGenericContravariant;
   }
 
-  /// Creates a forwarding stubs for this node if necessary, and propagates
+  /// Creates a forwarding stub for this node if necessary, and propagates
   /// covariance information.
   Procedure _finalize() {
-    var inheritedMember = resolve();
-    var inheritedMemberSubstitution =
-        _interfaceResolver._substitutionFor(inheritedMember, enclosingClass);
+    var member = resolve();
+    var substitution =
+        _interfaceResolver._substitutionFor(member, enclosingClass);
     bool isDeclaredInThisClass =
-        identical(inheritedMember.enclosingClass, enclosingClass);
+        identical(member.enclosingClass, enclosingClass);
 
     // Now decide whether we need a forwarding stub or not, and propagate
     // covariance.
     var covarianceFixes = <_CovarianceFix>[];
     if (_interfaceResolver.strongMode) {
-      _computeCovarianceFixes(
-          inheritedMemberSubstitution, inheritedMember, covarianceFixes);
+      _computeCovarianceFixes(substitution, member, covarianceFixes);
     }
     if (!isDeclaredInThisClass &&
-        (!identical(inheritedMember, _resolvedCandidate(_start)) ||
+        (!identical(member, _resolvedCandidate(_start)) ||
             covarianceFixes.isNotEmpty)) {
-      var stub =
-          _createForwardingStub(inheritedMemberSubstitution, inheritedMember);
-      var function = stub.function;
-      for (var fix in covarianceFixes) {
-        fix(function);
-      }
-      return stub;
-    } else {
-      var function = inheritedMember.function;
-      for (var fix in covarianceFixes) {
-        fix(function);
-      }
-      return inheritedMember;
+      member = _createForwardingStub(substitution, member);
     }
+    var function = member.function;
+    for (var fix in covarianceFixes) {
+      fix(function);
+    }
+    return member;
   }
 
   /// Returns the [i]th element of [_candidates], finalizing it if necessary.
@@ -680,6 +685,129 @@
   bool get isTypeInferencePrepared =>
       _typeInferenceEngine.isTypeInferencePrepared;
 
+  /// Report an error if all types in [types] are not equal using `==`.
+  ///
+  /// Returns the type if there is at least one and they are all equal,
+  /// otherwise the type `dynamic`.  [library], [name], [fileUri], and
+  /// [charOffset] are used to report the error.
+  DartType matchTypes(Iterable<DartType> types, LibraryBuilder library,
+      String name, Uri fileUri, int charOffset) {
+    DartType first;
+    for (var type in types) {
+      if (first == null) {
+        first = type;
+      } else if (first != type) {
+        // Types don't match.  Report an error.
+        library.addCompileTimeError(
+            templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
+            charOffset,
+            noLength,
+            fileUri);
+        return const DynamicType();
+      }
+    }
+    // If there are no overridden types, infer `dynamic`.
+    return first ?? const DynamicType();
+  }
+
+  /// Computes the types of the methods overridden by [method] in [class_].
+  ///
+  /// The types have the type parameters of [class_] substituted appropriately.
+  ///
+  /// [candidates] has the list of inherited interface methods with the same
+  /// name as [method] as a sublist from [start] inclusive to [end] exclusive.
+  List<FunctionType> _computeMethodOverriddenTypes(Class class_,
+      Procedure method, List<Member> candidates, int start, int end) {
+    var overriddenTypes = <FunctionType>[];
+    var declaredTypeParameters = method.function.typeParameters;
+    for (int i = start; i < end; ++i) {
+      var candidate = candidates[i];
+      if (candidate is SyntheticAccessor) {
+        // This can happen if there are errors.  Just skip this override.
+        continue;
+      }
+      var candidateFunction = candidate.function;
+      if (candidateFunction == null) {
+        // This can happen if there are errors.  Just skip this override.
+        continue;
+      }
+      var substitution = _substitutionFor(candidate, class_);
+      FunctionType overriddenType =
+          substitution.substituteType(candidateFunction.functionType);
+      var overriddenTypeParameters = overriddenType.typeParameters;
+      if (overriddenTypeParameters.length != declaredTypeParameters.length) {
+        // Generic arity mismatch.  Don't do any inference for this method.
+        // TODO(paulberry): report an error.
+        overriddenTypes.clear();
+        break;
+      } else if (overriddenTypeParameters.isNotEmpty) {
+        var substitutionMap = <TypeParameter, DartType>{};
+        for (int i = 0; i < declaredTypeParameters.length; ++i) {
+          substitutionMap[overriddenTypeParameters[i]] =
+              new TypeParameterType(declaredTypeParameters[i]);
+        }
+        overriddenType = substituteTypeParams(
+            overriddenType, substitutionMap, declaredTypeParameters);
+      }
+      overriddenTypes.add(overriddenType);
+    }
+    return overriddenTypes;
+  }
+
+  void inferMethodType(LibraryBuilder library, Class class_, Procedure method,
+      List<Member> candidates, int start, int end) {
+    var overriddenTypes =
+        _computeMethodOverriddenTypes(class_, method, candidates, start, end);
+    if (ShadowProcedure.hasImplicitReturnType(method) &&
+        method.name != indexSetName) {
+      method.function.returnType = matchTypes(
+          overriddenTypes.map((type) => type.returnType),
+          library,
+          method.name.name,
+          class_.fileUri,
+          method.fileOffset);
+    }
+    var positionalParameters = method.function.positionalParameters;
+    for (int i = 0; i < positionalParameters.length; ++i) {
+      if (ShadowVariableDeclaration
+          .isImplicitlyTyped(positionalParameters[i])) {
+        // Note that if the parameter is not present in the overridden method,
+        // getPositionalParameterType treats it as dynamic.  This is consistent
+        // with the behavior called for in the informal top level type inference
+        // spec, which says:
+        //
+        //     If there is no corresponding parameter position in the overridden
+        //     method to infer from and the signatures are compatible, it is
+        //     treated as dynamic (e.g. overriding a one parameter method with a
+        //     method that takes a second optional parameter).  Note: if there
+        //     is no corresponding parameter position in the overriden method to
+        //     infer from and the signatures are incompatible (e.g. overriding a
+        //     one parameter method with a method that takes a second
+        //     non-optional parameter), the inference result is not defined and
+        //     tools are free to either emit an error, or to defer the error to
+        //     override checking.
+        positionalParameters[i].type = matchTypes(
+            overriddenTypes.map((type) => getPositionalParameterType(type, i)),
+            library,
+            positionalParameters[i].name,
+            class_.fileUri,
+            positionalParameters[i].fileOffset);
+      }
+    }
+    var namedParameters = method.function.namedParameters;
+    for (int i = 0; i < namedParameters.length; i++) {
+      if (ShadowVariableDeclaration.isImplicitlyTyped(namedParameters[i])) {
+        var name = namedParameters[i].name;
+        namedParameters[i].type = matchTypes(
+            overriddenTypes.map((type) => getNamedParameterType(type, name)),
+            library,
+            namedParameters[i].name,
+            class_.fileUri,
+            namedParameters[i].fileOffset);
+      }
+    }
+  }
+
   /// Populates [apiMembers] with a list of the implemented and inherited
   /// members of the given [class_]'s interface.
   ///
@@ -729,34 +857,50 @@
 
       InferenceNode getterInferenceNode;
       if (getterStart < getterEnd) {
-        if (declaredGetter != null) {
-          getterInferenceNode = _createInferenceNode(
-              class_,
-              declaredGetter,
-              candidates,
-              inheritedGetterStart,
-              getterEnd,
-              inheritedSetterStart,
-              setterEnd,
-              library,
-              class_.fileUri);
-        }
-        var forwardingNode = new ForwardingNode(
-            this,
-            getterInferenceNode,
-            class_,
-            name,
-            _kindOf(candidates[getterStart]),
-            candidates,
-            getterStart,
-            getterEnd);
-        if (!forwardingNode.isGetter) {
-          // Methods and operators can be finalized immediately.
-          getters[getterIndex++] = forwardingNode.finalize();
-        } else {
+        if (_kindOf(candidates[getterStart]) == ProcedureKind.Getter) {
+          // Member is a getter.
+          if (declaredGetter != null) {
+            getterInferenceNode = _createInferenceNode(
+                class_,
+                declaredGetter,
+                candidates,
+                inheritedGetterStart,
+                getterEnd,
+                inheritedSetterStart,
+                setterEnd,
+                library,
+                class_.fileUri);
+          }
           // Getters need to be resolved later, as part of type
           // inference, so just save the forwarding node for now.
-          getters[getterIndex++] = forwardingNode;
+          getters[getterIndex++] = new ForwardingNode(
+              this,
+              getterInferenceNode,
+              class_,
+              name,
+              _kindOf(candidates[getterStart]),
+              candidates,
+              getterStart,
+              getterEnd);
+        } else {
+          // Member is a method.
+          if (strongMode &&
+              declaredGetter != null &&
+              _requiresTypeInference(declaredGetter)) {
+            inferMethodType(library, class_, declaredGetter, candidates,
+                inheritedGetterStart, getterEnd);
+          }
+          var forwardingNode = new ForwardingNode(
+              this,
+              null,
+              class_,
+              name,
+              _kindOf(candidates[getterStart]),
+              candidates,
+              getterStart,
+              getterEnd);
+          // Methods and operators can be finalized immediately.
+          getters[getterIndex++] = forwardingNode.finalize();
         }
       }
       if (getterEnd < setterEnd) {
@@ -866,31 +1010,22 @@
       int crossEnd,
       LibraryBuilder library,
       Uri fileUri) {
-    if (!_requiresTypeInference(procedure)) return null;
-    switch (procedure.kind) {
-      case ProcedureKind.Getter:
-      case ProcedureKind.Setter:
-        if (strongMode && start < end) {
-          return new AccessorInferenceNode(
-              this, procedure, candidates, start, end, library, fileUri);
-        } else if (strongMode && crossStart < crossEnd) {
-          return new AccessorInferenceNode(this, procedure, candidates,
-              crossStart, crossEnd, library, fileUri);
-        } else if (procedure is SyntheticAccessor &&
-            procedure._field.initializer != null) {
-          var node = new FieldInitializerInferenceNode(
-              _typeInferenceEngine, procedure._field, library);
-          ShadowField.setInferenceNode(procedure._field, node);
-          return node;
-        }
-        return null;
-      default: // Method || Operator
-        if (strongMode) {
-          return new MethodInferenceNode(
-              this, procedure, candidates, start, end, library, fileUri);
-        }
-        return null;
+    InferenceNode node;
+    if (procedure.isAccessor && _requiresTypeInference(procedure)) {
+      if (strongMode && start < end) {
+        node = new AccessorInferenceNode(
+            this, procedure, candidates, start, end, library, fileUri);
+      } else if (strongMode && crossStart < crossEnd) {
+        node = new AccessorInferenceNode(this, procedure, candidates,
+            crossStart, crossEnd, library, fileUri);
+      } else if (procedure is SyntheticAccessor &&
+          procedure._field.initializer != null) {
+        node = new FieldInitializerInferenceNode(
+            _typeInferenceEngine, procedure._field, library);
+        ShadowField.setInferenceNode(procedure._field, node);
+      }
     }
+    return node;
   }
 
   /// Retrieves a list of the interface members of the given [class_].
@@ -1095,160 +1230,6 @@
   }
 }
 
-/// Abstract class derived from [InferenceNode] to represent type inference of
-/// methods, getters, and setters based on inheritance.
-abstract class MemberInferenceNode extends InferenceNode {
-  final InterfaceResolver _interfaceResolver;
-
-  /// The method whose return type and/or parameter types should be inferred.
-  final Procedure _declaredMethod;
-
-  /// A list containing the methods overridden by [_declaredMethod], if any.
-  final List<Member> _candidates;
-
-  /// The index of the first method in [_candidates] overridden by
-  /// [_declaredMethod].
-  final int _start;
-
-  /// The past-the-end index of the last method in [_candidates] overridden by
-  /// [_declaredMethod].
-  final int _end;
-
-  final LibraryBuilder _library;
-
-  final Uri _fileUri;
-
-  MemberInferenceNode(this._interfaceResolver, this._declaredMethod,
-      this._candidates, this._start, this._end, this._library, this._fileUri);
-
-  DartType _matchTypes(Iterable<DartType> types, String name, int charOffset) {
-    var iterator = types.iterator;
-    if (!iterator.moveNext()) {
-      // No overridden types.  Infer `dynamic`.
-      return const DynamicType();
-    }
-    var inferredType = iterator.current;
-    while (iterator.moveNext()) {
-      if (inferredType != iterator.current) {
-        // Types don't match.  Report an error.
-        _library.addCompileTimeError(
-            templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
-            charOffset,
-            noLength,
-            _fileUri);
-        return const DynamicType();
-      }
-    }
-    return inferredType;
-  }
-}
-
-/// Concrete class derived from [InferenceNode] to represent type inference of
-/// methods.
-class MethodInferenceNode extends MemberInferenceNode {
-  MethodInferenceNode(
-      InterfaceResolver interfaceResolver,
-      Procedure declaredMethod,
-      List<Member> candidates,
-      int start,
-      int end,
-      LibraryBuilder library,
-      Uri fileUri)
-      : super(interfaceResolver, declaredMethod, candidates, start, end,
-            library, fileUri);
-
-  @override
-  void resolveInternal() {
-    var declaredMethod = _declaredMethod;
-    var overriddenTypes = _computeMethodOverriddenTypes();
-    if (ShadowProcedure.hasImplicitReturnType(declaredMethod) &&
-        _declaredMethod.name != indexSetName) {
-      declaredMethod.function.returnType = _matchTypes(
-          overriddenTypes.map((type) => type.returnType),
-          declaredMethod.name.name,
-          declaredMethod.fileOffset);
-    }
-    var positionalParameters = declaredMethod.function.positionalParameters;
-    for (int i = 0; i < positionalParameters.length; i++) {
-      if (ShadowVariableDeclaration
-          .isImplicitlyTyped(positionalParameters[i])) {
-        // Note that if the parameter is not present in the overridden method,
-        // getPositionalParameterType treats it as dynamic.  This is consistent
-        // with the behavior called for in the informal top level type inference
-        // spec, which says:
-        //
-        //     If there is no corresponding parameter position in the overridden
-        //     method to infer from and the signatures are compatible, it is
-        //     treated as dynamic (e.g. overriding a one parameter method with a
-        //     method that takes a second optional parameter).  Note: if there
-        //     is no corresponding parameter position in the overriden method to
-        //     infer from and the signatures are incompatible (e.g. overriding a
-        //     one parameter method with a method that takes a second
-        //     non-optional parameter), the inference result is not defined and
-        //     tools are free to either emit an error, or to defer the error to
-        //     override checking.
-        positionalParameters[i].type = _matchTypes(
-            overriddenTypes.map((type) => getPositionalParameterType(type, i)),
-            positionalParameters[i].name,
-            positionalParameters[i].fileOffset);
-      }
-    }
-    var namedParameters = declaredMethod.function.namedParameters;
-    for (int i = 0; i < namedParameters.length; i++) {
-      if (ShadowVariableDeclaration.isImplicitlyTyped(namedParameters[i])) {
-        var name = namedParameters[i].name;
-        namedParameters[i].type = _matchTypes(
-            overriddenTypes.map((type) => getNamedParameterType(type, name)),
-            namedParameters[i].name,
-            namedParameters[i].fileOffset);
-      }
-    }
-    // Circularities should never occur with method inference, since the
-    // inference of a method can only depend on the methods above it in the
-    // class hierarchy.
-    assert(!isCircular);
-  }
-
-  /// Computes the types of the methods overridden by [_declaredMethod], with
-  /// appropriate type parameter substitutions.
-  List<FunctionType> _computeMethodOverriddenTypes() {
-    var overriddenTypes = <FunctionType>[];
-    var declaredTypeParameters = _declaredMethod.function.typeParameters;
-    for (int i = _start; i < _end; i++) {
-      var candidate = _candidates[i];
-      if (candidate is SyntheticAccessor) {
-        // This can happen if there are errors.  Just skip this override.
-        continue;
-      }
-      var candidateFunction = candidate.function;
-      if (candidateFunction == null) {
-        // This can happen if there are errors.  Just skip this override.
-        continue;
-      }
-      var substitution = _interfaceResolver._substitutionFor(
-          candidate, _declaredMethod.enclosingClass);
-      FunctionType overriddenType =
-          substitution.substituteType(candidateFunction.functionType);
-      var overriddenTypeParameters = overriddenType.typeParameters;
-      if (overriddenTypeParameters.length != declaredTypeParameters.length) {
-        // Generic arity mismatch.  Don't do any inference for this method.
-        // TODO(paulberry): report an error.
-        return <FunctionType>[];
-      } else if (overriddenTypeParameters.isNotEmpty) {
-        var substitutionMap = <TypeParameter, DartType>{};
-        for (int i = 0; i < declaredTypeParameters.length; i++) {
-          substitutionMap[overriddenTypeParameters[i]] =
-              new TypeParameterType(declaredTypeParameters[i]);
-        }
-        overriddenType = substituteTypeParams(
-            overriddenType, substitutionMap, declaredTypeParameters);
-      }
-      overriddenTypes.add(overriddenType);
-    }
-    return overriddenTypes;
-  }
-}
-
 /// A [SyntheticAccessor] represents the getter or setter implied by a field.
 class SyntheticAccessor extends Procedure {
   /// The field associated with the synthetic accessor.
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 87723e6..e1cb6ea 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -2,13 +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.md file.
 
-import 'package:front_end/src/base/instrumentation.dart';
-import 'package:front_end/src/fasta/builder/library_builder.dart';
-import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
-import 'package:front_end/src/fasta/messages.dart';
-import 'package:front_end/src/fasta/source/source_library_builder.dart';
-import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
 import 'package:kernel/ast.dart'
     show
         Class,
@@ -24,9 +17,22 @@
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
 
+import '../../base/instrumentation.dart';
+
+import '../builder/library_builder.dart';
+
 import '../deprecated_problems.dart' show Crash;
 
-import '../messages.dart' show getLocationFromNode, noLength;
+import '../kernel/kernel_shadow_ast.dart';
+
+import '../messages.dart'
+    show getLocationFromNode, noLength, templateCantInferTypeDueToCircularity;
+
+import '../source/source_library_builder.dart';
+
+import 'type_inferrer.dart';
+
+import 'type_schema_environment.dart';
 
 /// Concrete class derived from [InferenceNode] to represent type inference of a
 /// field based on its initializer.
diff --git a/pkg/front_end/lib/src/incremental/file_state.dart b/pkg/front_end/lib/src/incremental/file_state.dart
index 88a24b0..f8ab1a3 100644
--- a/pkg/front_end/lib/src/incremental/file_state.dart
+++ b/pkg/front_end/lib/src/incremental/file_state.dart
@@ -65,7 +65,7 @@
   bool _gcMarked = false;
 
   FileState._(this._fsState, this.uri, this.fileUri)
-      : uriBytes = UTF8.encode(uri.toString());
+      : uriBytes = utf8.encode(uri.toString());
 
   /// The MD5 signature of the file API as a byte array.
   /// It depends on all non-comment tokens outside the block bodies.
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index f1273f6..25bcdaa 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1647,7 +1647,24 @@
   template: "Duplicated definition of '#name'."
 
 DuplicatedName:
-  template: "Duplicated name: '#name'."
+  template: "'#name' is already declared in this scope."
+  severity: ERROR
+
+DuplicatedNameCause:
+  template: "Previous declaration of '#name'."
+  severity: CONTEXT
+
+DuplicatedNamePreviouslyUsed:
+  template: "Can't declare '#name' because it was already used in this scope."
+  severity: ERROR
+  analyzerCode: REFERENCED_BEFORE_DECLARATION
+  dart2jsCode: "*ignored*"
+  script:
+    - "main(arguments) { arguments; var arguments; }"
+
+DuplicatedNamePreviouslyUsedCause:
+  template: "Previous use of '#name'."
+  severity: CONTEXT
 
 DuplicatedParameterName:
   template: "Duplicated parameter name '#name'."
@@ -1810,9 +1827,6 @@
 AccessError:
   template: "Access error: '#name'."
 
-PreviousUseOfName:
-  template: "Previous use of '#name'."
-
 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."
 
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 6d4b93b..b02c547 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -5,6 +5,7 @@
 import 'package:front_end/src/fasta/messages.dart';
 import 'package:front_end/src/fasta/parser.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';
 import 'package:front_end/src/scanner/token.dart';
 import 'package:test/test.dart';
@@ -19,14 +20,17 @@
 @reflectiveTest
 class TokenInfoTest {
   void test_noType() {
-    TypeInfo typeInfo = noTypeInfo;
-    Token start = scanString('before ;').tokens;
-    Token expectedEnd = start;
-    expect(typeInfo.couldBeExpression, isFalse);
-    expect(typeInfo.skipType(start), expectedEnd);
+    final Token start = scanString('before ;').tokens;
 
-    TypeInfoListener listener = new TypeInfoListener();
-    expect(typeInfo.ensureTypeNotVoid(start, new Parser(listener)),
+    expect(noTypeInfo.couldBeExpression, isFalse);
+    expect(noTypeInfo.skipType(start), start);
+  }
+
+  void test_noType_ensureTypeNotVoid() {
+    final Token start = scanString('before ;').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(noTypeInfo.ensureTypeNotVoid(start, new Parser(listener)),
         new isInstanceOf<SyntheticStringToken>());
     expect(listener.calls, [
       'handleIdentifier  typeReference',
@@ -34,56 +38,99 @@
       'handleType  ;',
     ]);
     expect(listener.errors, [new ExpectedError(codeExpectedType, 7, 1)]);
+  }
 
-    listener = new TypeInfoListener();
-    expect(typeInfo.parseTypeNotVoid(start, new Parser(listener)), expectedEnd);
+  void test_noType_ensureTypeOrVoid() {
+    final Token start = scanString('before ;').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(noTypeInfo.ensureTypeOrVoid(start, new Parser(listener)),
+        new isInstanceOf<SyntheticStringToken>());
+    expect(listener.calls, [
+      'handleIdentifier  typeReference',
+      'handleNoTypeArguments ;',
+      'handleType  ;',
+    ]);
+    expect(listener.errors, [new ExpectedError(codeExpectedType, 7, 1)]);
+  }
+
+  void test_noType_parseType() {
+    final Token start = scanString('before ;').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(noTypeInfo.parseType(start, new Parser(listener)), start);
     expect(listener.calls, ['handleNoType before']);
     expect(listener.errors, isNull);
+  }
 
-    listener = new TypeInfoListener();
-    expect(typeInfo.parseType(start, new Parser(listener)), expectedEnd);
+  void test_noType_parseTypeNotVoid() {
+    final Token start = scanString('before ;').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(noTypeInfo.parseTypeNotVoid(start, new Parser(listener)), start);
     expect(listener.calls, ['handleNoType before']);
     expect(listener.errors, isNull);
   }
 
   void test_voidType() {
-    TypeInfo typeInfo = voidTypeInfo;
-    Token start = scanString('before void ;').tokens;
-    Token expectedEnd = start.next;
-    expect(typeInfo.skipType(start), expectedEnd);
-    expect(typeInfo.couldBeExpression, isFalse);
+    final Token start = scanString('before void ;').tokens;
 
-    TypeInfoListener listener = new TypeInfoListener();
-    expect(
-        typeInfo.ensureTypeNotVoid(start, new Parser(listener)), expectedEnd);
+    expect(voidTypeInfo.skipType(start), start.next);
+    expect(voidTypeInfo.couldBeExpression, isFalse);
+  }
+
+  void test_voidType_ensureTypeNotVoid() {
+    final Token start = scanString('before void ;').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(voidTypeInfo.ensureTypeNotVoid(start, new Parser(listener)),
+        start.next);
     expect(listener.calls, [
       'handleIdentifier void typeReference',
       'handleNoTypeArguments ;',
       'handleType void ;',
     ]);
     expect(listener.errors, [new ExpectedError(codeInvalidVoid, 7, 4)]);
+  }
 
-    listener = new TypeInfoListener();
-    expect(typeInfo.parseTypeNotVoid(start, new Parser(listener)), expectedEnd);
-    expect(listener.calls, [
-      'handleIdentifier void typeReference',
-      'handleNoTypeArguments ;',
-      'handleType void ;',
-    ]);
-    expect(listener.errors, [new ExpectedError(codeInvalidVoid, 7, 4)]);
+  void test_voidType_ensureTypeOrVoid() {
+    final Token start = scanString('before void ;').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
 
-    listener = new TypeInfoListener();
-    expect(typeInfo.parseType(start, new Parser(listener)), expectedEnd);
+    expect(voidTypeInfo.parseType(start, new Parser(listener)), start.next);
     expect(listener.calls, ['handleVoidKeyword void']);
     expect(listener.errors, isNull);
   }
 
+  void test_voidType_parseType() {
+    final Token start = scanString('before void ;').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(voidTypeInfo.parseType(start, new Parser(listener)), start.next);
+    expect(listener.calls, ['handleVoidKeyword void']);
+    expect(listener.errors, isNull);
+  }
+
+  void test_voidType_parseTypeNotVoid() {
+    final Token start = scanString('before void ;').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(
+        voidTypeInfo.parseTypeNotVoid(start, new Parser(listener)), start.next);
+    expect(listener.calls, [
+      'handleIdentifier void typeReference',
+      'handleNoTypeArguments ;',
+      'handleType void ;',
+    ]);
+    expect(listener.errors, [new ExpectedError(codeInvalidVoid, 7, 4)]);
+  }
+
   void test_prefixedTypeInfo() {
-    TypeInfo typeInfo = prefixedTypeInfo;
-    Token start = scanString('before C.a ;').tokens;
-    Token expectedEnd = start.next.next.next;
-    expect(typeInfo.skipType(start), expectedEnd);
-    expect(typeInfo.couldBeExpression, isTrue);
+    final Token start = scanString('before C.a ;').tokens;
+    final Token expectedEnd = start.next.next.next;
+
+    expect(prefixedTypeInfo.skipType(start), expectedEnd);
+    expect(prefixedTypeInfo.couldBeExpression, isTrue);
 
     TypeInfoListener listener;
     assertResult(Token actualEnd) {
@@ -99,21 +146,27 @@
     }
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.ensureTypeNotVoid(start, new Parser(listener)));
+    assertResult(
+        prefixedTypeInfo.ensureTypeNotVoid(start, new Parser(listener)));
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.parseTypeNotVoid(start, new Parser(listener)));
+    assertResult(
+        prefixedTypeInfo.ensureTypeOrVoid(start, new Parser(listener)));
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.parseType(start, new Parser(listener)));
+    assertResult(
+        prefixedTypeInfo.parseTypeNotVoid(start, new Parser(listener)));
+
+    listener = new TypeInfoListener();
+    assertResult(prefixedTypeInfo.parseType(start, new Parser(listener)));
   }
 
   void test_simpleTypeInfo() {
-    TypeInfo typeInfo = simpleTypeInfo;
-    Token start = scanString('before C ;').tokens;
-    Token expectedEnd = start.next;
-    expect(typeInfo.skipType(start), expectedEnd);
-    expect(typeInfo.couldBeExpression, isTrue);
+    final Token start = scanString('before C ;').tokens;
+    final Token expectedEnd = start.next;
+
+    expect(simpleTypeInfo.skipType(start), expectedEnd);
+    expect(simpleTypeInfo.couldBeExpression, isTrue);
 
     TypeInfoListener listener;
     assertResult(Token actualEnd) {
@@ -127,21 +180,24 @@
     }
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.ensureTypeNotVoid(start, new Parser(listener)));
+    assertResult(simpleTypeInfo.ensureTypeNotVoid(start, new Parser(listener)));
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.parseTypeNotVoid(start, new Parser(listener)));
+    assertResult(simpleTypeInfo.ensureTypeOrVoid(start, new Parser(listener)));
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.parseType(start, new Parser(listener)));
+    assertResult(simpleTypeInfo.parseTypeNotVoid(start, new Parser(listener)));
+
+    listener = new TypeInfoListener();
+    assertResult(simpleTypeInfo.parseType(start, new Parser(listener)));
   }
 
   void test_simpleTypeArgumentsInfo() {
-    TypeInfo typeInfo = simpleTypeArgumentsInfo;
-    Token start = scanString('before C<T> ;').tokens;
-    Token expectedEnd = start.next.next.next.next;
-    expect(typeInfo.skipType(start), expectedEnd);
-    expect(typeInfo.couldBeExpression, isFalse);
+    final Token start = scanString('before C<T> ;').tokens;
+    final Token expectedEnd = start.next.next.next.next;
+
+    expect(simpleTypeArgumentsInfo.skipType(start), expectedEnd);
+    expect(simpleTypeArgumentsInfo.couldBeExpression, isFalse);
 
     TypeInfoListener listener;
     assertResult(Token actualEnd) {
@@ -159,13 +215,20 @@
     }
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.ensureTypeNotVoid(start, new Parser(listener)));
+    assertResult(
+        simpleTypeArgumentsInfo.ensureTypeNotVoid(start, new Parser(listener)));
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.parseTypeNotVoid(start, new Parser(listener)));
+    assertResult(
+        simpleTypeArgumentsInfo.ensureTypeOrVoid(start, new Parser(listener)));
 
     listener = new TypeInfoListener();
-    assertResult(typeInfo.parseType(start, new Parser(listener)));
+    assertResult(
+        simpleTypeArgumentsInfo.parseTypeNotVoid(start, new Parser(listener)));
+
+    listener = new TypeInfoListener();
+    assertResult(
+        simpleTypeArgumentsInfo.parseType(start, new Parser(listener)));
   }
 
   void test_computeType_basic() {
@@ -232,7 +295,6 @@
       'beginMetadataStar int',
       'endMetadataStar 0',
       'beginFormalParameter int MemberKind.GeneralizedFunctionType',
-      'handleModifiers 0',
       'handleIdentifier int typeReference',
       'handleNoTypeArguments )',
       'handleType int )',
@@ -258,7 +320,6 @@
       'beginMetadataStar int',
       'endMetadataStar 0',
       'beginFormalParameter int MemberKind.GeneralizedFunctionType',
-      'handleModifiers 0',
       'handleIdentifier int typeReference',
       'handleNoTypeArguments )',
       'handleType int )',
@@ -604,7 +665,6 @@
           'beginMetadataStar int',
           'endMetadataStar 0',
           'beginFormalParameter int MemberKind.GeneralizedFunctionType',
-          'handleModifiers 0',
           'handleIdentifier int typeReference',
           'handleNoTypeArguments x',
           'handleType int x',
@@ -618,7 +678,6 @@
           'beginMetadataStar int',
           'endMetadataStar 0',
           'beginFormalParameter int MemberKind.GeneralizedFunctionType',
-          'handleModifiers 0',
           'handleIdentifier int typeReference',
           'handleNoTypeArguments x',
           'handleType int x',
@@ -696,6 +755,7 @@
   if (required == null) {
     compute(expectedInfo, source, start, true, expectedAfter, expectedCalls,
         expectedErrors);
+    start = scan(source);
     compute(expectedInfo, source, start, false, expectedAfter, expectedCalls,
         expectedErrors);
   } else {
@@ -777,7 +837,8 @@
   List<ExpectedError> errors;
 
   @override
-  void beginFormalParameter(Token token, MemberKind kind) {
+  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+      Token varFinalOrConst) {
     calls.add('beginFormalParameter $token $kind');
   }
 
@@ -860,11 +921,6 @@
   }
 
   @override
-  void handleModifiers(int count) {
-    calls.add('handleModifiers $count');
-  }
-
-  @override
   void handleNoName(Token token) {
     calls.add('handleNoName $token');
   }
diff --git a/pkg/front_end/test/fasta/shaker_test.dart b/pkg/front_end/test/fasta/shaker_test.dart
index d86e4d9..1952495 100644
--- a/pkg/front_end/test/fasta/shaker_test.dart
+++ b/pkg/front_end/test/fasta/shaker_test.dart
@@ -16,7 +16,7 @@
 library fasta.test.shaker_test;
 
 import 'dart:async' show Future;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode;
 import 'dart:io' show File;
 
 export 'package:testing/testing.dart' show Chain, runMe;
@@ -60,7 +60,7 @@
   final List<int> outlineBytes;
 
   final ExpectationSet expectationSet =
-      new ExpectationSet.fromJsonList(JSON.decode(EXPECTATIONS));
+      new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
 
   TreeShakerContext(
       this.outlineUri, this.options, this.outlineBytes, bool updateExpectations)
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 014f3a6..ee0b49b 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -8,7 +8,7 @@
 
 import 'dart:io' show File, Platform;
 
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode;
 
 import 'package:front_end/src/api_prototype/standard_file_system.dart'
     show StandardFileSystem;
@@ -115,7 +115,7 @@
   Component platform;
 
   final ExpectationSet expectationSet =
-      new ExpectationSet.fromJsonList(JSON.decode(EXPECTATIONS));
+      new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
   Expectation verificationError;
 
   FastaContext(
diff --git a/pkg/front_end/test/incremental_bulk_compiler_full.dart b/pkg/front_end/test/incremental_bulk_compiler_full.dart
index ead6b7b..c0f5a87 100644
--- a/pkg/front_end/test/incremental_bulk_compiler_full.dart
+++ b/pkg/front_end/test/incremental_bulk_compiler_full.dart
@@ -20,11 +20,9 @@
 import 'package:front_end/src/fasta/incremental_compiler.dart'
     show IncrementalCompiler;
 
-import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
-
 import 'package:front_end/src/fasta/severity.dart' show Severity;
 
-import 'package:kernel/kernel.dart' show Component, Library, Reference;
+import 'package:kernel/kernel.dart' show Component;
 
 import 'package:kernel/text/ast_to_text.dart'
     show globalDebuggingNames, NameSystem;
@@ -32,6 +30,8 @@
 import 'package:testing/testing.dart'
     show Chain, ChainContext, Result, Step, TestDescription, runMe;
 
+import 'incremental_utils.dart' as util;
+
 main([List<String> arguments = const []]) =>
     runMe(arguments, createContext, "../testing.json");
 
@@ -90,7 +90,7 @@
     try {
       IncrementalCompiler compiler =
           new IncrementalKernelGenerator(getOptions(true), uri);
-      oneShotSerialized = postProcess(await compiler.computeDelta());
+      oneShotSerialized = util.postProcess(await compiler.computeDelta());
     } catch (e) {
       oneShotFailed = true;
     }
@@ -106,7 +106,7 @@
       }
       Component bulkCompiledComponent = await context.compiler
           .computeDelta(entryPoint: uri, fullComponent: true);
-      bulkSerialized = postProcess(bulkCompiledComponent);
+      bulkSerialized = util.postProcess(bulkCompiledComponent);
     } catch (e) {
       bulkFailed = true;
     }
@@ -122,7 +122,7 @@
       }
       Component bulkCompiledComponent = await context.compiler
           .computeDelta(entryPoint: uri, fullComponent: true);
-      bulkSerialized2 = postProcess(bulkCompiledComponent);
+      bulkSerialized2 = util.postProcess(bulkCompiledComponent);
     } catch (e) {
       bulk2Failed = true;
     }
@@ -148,23 +148,6 @@
     return pass(description);
   }
 
-  List<int> postProcess(Component c) {
-    c.libraries.sort((l1, l2) {
-      return l1.fileUri.toString().compareTo(l2.fileUri.toString());
-    });
-
-    c.computeCanonicalNames();
-    for (Library library in c.libraries) {
-      library.additionalExports.sort((Reference r1, Reference r2) {
-        return r1.canonicalName
-            .toString()
-            .compareTo(r2.canonicalName.toString());
-      });
-    }
-
-    return serializeComponent(c);
-  }
-
   void checkIsEqual(List<int> a, List<int> b) {
     int length = a.length;
     if (b.length < length) {
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 147487c..0bb2e82 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -27,19 +27,19 @@
 import 'package:front_end/src/fasta/incremental_compiler.dart'
     show IncrementalCompiler;
 
-import 'package:front_end/src/fasta/kernel/utils.dart'
-    show writeComponentToFile, serializeComponent;
+import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
 
 import 'package:front_end/src/fasta/severity.dart' show Severity;
 
-import 'package:kernel/kernel.dart'
-    show Class, EmptyStatement, Library, Procedure, Component;
+import 'package:kernel/kernel.dart' show Component;
 
 import "package:testing/testing.dart"
     show Chain, ChainContext, Result, Step, TestDescription, runMe;
 
 import "package:yaml/yaml.dart" show YamlMap, loadYamlNode;
 
+import "incremental_utils.dart" as util;
+
 main([List<String> arguments = const []]) =>
     runMe(arguments, createContext, "../testing.json");
 
@@ -191,7 +191,7 @@
   Map<String, String> sourceFiles;
   CompilerOptions options;
   TestIncrementalCompiler compiler;
-  for (var world in worlds) {
+  for (Map<String, dynamic> world in worlds) {
     bool brandNewWorld = true;
     if (world["worldType"] == "updated") {
       brandNewWorld = false;
@@ -256,7 +256,7 @@
     }
 
     if (world["invalidate"] != null) {
-      for (var filename in world["invalidate"]) {
+      for (String filename in world["invalidate"]) {
         compiler.invalidate(base.resolve(filename));
       }
     }
@@ -274,7 +274,7 @@
     } else if (world["warnings"] != true && gotWarning) {
       throw "Got unexpected warnings(s): $formattedWarnings.";
     }
-    throwOnEmptyMixinBodies(component);
+    util.throwOnEmptyMixinBodies(component);
     print("Compile took ${stopwatch.elapsedMilliseconds} ms");
     newestWholeComponent = serializeComponent(component);
     if (component.libraries.length != world["expectedLibraryCount"]) {
@@ -329,7 +329,7 @@
 
 CompilerOptions getOptions(bool strong) {
   final Uri sdkRoot = computePlatformBinariesLocation();
-  var options = new CompilerOptions()
+  CompilerOptions options = new CompilerOptions()
     ..sdkRoot = sdkRoot
     ..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
     ..onProblem = (FormattedMessage problem, Severity severity,
@@ -353,8 +353,8 @@
   TestIncrementalCompiler compiler =
       new TestIncrementalCompiler(options, input);
   Component component = await compiler.computeDelta();
-  throwOnEmptyMixinBodies(component);
-  await writeComponentToFile(component, output);
+  util.throwOnEmptyMixinBodies(component);
+  new File.fromUri(output).writeAsBytesSync(util.postProcess(component));
   return compiler.initializedFromDill;
 }
 
@@ -367,10 +367,11 @@
   for (Uri invalidateUri in invalidateUris) {
     compiler.invalidate(invalidateUri);
   }
-  var initializedComponent = await compiler.computeDelta();
-  throwOnEmptyMixinBodies(initializedComponent);
+  Component initializedComponent = await compiler.computeDelta();
+  util.throwOnEmptyMixinBodies(initializedComponent);
   bool result = compiler.initializedFromDill;
-  await writeComponentToFile(initializedComponent, output);
+  new File.fromUri(output)
+      .writeAsBytesSync(util.postProcess(initializedComponent));
   int actuallyInvalidatedCount =
       compiler.invalidatedImportUrisForTesting?.length ?? 0;
   if (result && actuallyInvalidatedCount < invalidateUris.length) {
@@ -378,19 +379,20 @@
         "got $actuallyInvalidatedCount");
   }
 
-  var initializedComponent2 = await compiler.computeDelta(fullComponent: true);
-  throwOnEmptyMixinBodies(initializedComponent2);
+  Component initializedFullComponent =
+      await compiler.computeDelta(fullComponent: true);
+  util.throwOnEmptyMixinBodies(initializedFullComponent);
   Expect.equals(initializedComponent.libraries.length,
-      initializedComponent2.libraries.length);
+      initializedFullComponent.libraries.length);
   Expect.equals(initializedComponent.uriToSource.length,
-      initializedComponent2.uriToSource.length);
+      initializedFullComponent.uriToSource.length);
 
   for (Uri invalidateUri in invalidateUris) {
     compiler.invalidate(invalidateUri);
   }
 
-  var partialComponent = await compiler.computeDelta();
-  throwOnEmptyMixinBodies(partialComponent);
+  Component partialComponent = await compiler.computeDelta();
+  util.throwOnEmptyMixinBodies(partialComponent);
   actuallyInvalidatedCount =
       (compiler.invalidatedImportUrisForTesting?.length ?? 0);
   if (actuallyInvalidatedCount < invalidateUris.length) {
@@ -398,14 +400,14 @@
         "got $actuallyInvalidatedCount");
   }
 
-  var emptyComponent = await compiler.computeDelta();
-  throwOnEmptyMixinBodies(emptyComponent);
+  Component emptyComponent = await compiler.computeDelta();
+  util.throwOnEmptyMixinBodies(emptyComponent);
 
-  var fullLibUris =
+  List<Uri> fullLibUris =
       initializedComponent.libraries.map((lib) => lib.importUri).toList();
-  var partialLibUris =
+  List<Uri> partialLibUris =
       partialComponent.libraries.map((lib) => lib.importUri).toList();
-  var emptyLibUris =
+  List<Uri> emptyLibUris =
       emptyComponent.libraries.map((lib) => lib.importUri).toList();
 
   Expect.isTrue(fullLibUris.length > partialLibUris.length ||
@@ -417,29 +419,6 @@
   return result;
 }
 
-void throwOnEmptyMixinBodies(Component component) {
-  int empty = countEmptyMixinBodies(component);
-  if (empty != 0) {
-    throw "Expected 0 empty bodies in mixins, but found $empty";
-  }
-}
-
-int countEmptyMixinBodies(Component component) {
-  int empty = 0;
-  for (Library lib in component.libraries) {
-    for (Class c in lib.classes) {
-      if (c.isSyntheticMixinImplementation) {
-        for (Procedure p in c.procedures) {
-          if (p.function.body is EmptyStatement) {
-            empty++;
-          }
-        }
-      }
-    }
-  }
-  return empty;
-}
-
 String substituteVariables(String source, Uri base) {
   return source.replaceAll(r"${outDirUri}", "${base}");
 }
diff --git a/pkg/front_end/test/incremental_utils.dart b/pkg/front_end/test/incremental_utils.dart
new file mode 100644
index 0000000..c8480bf
--- /dev/null
+++ b/pkg/front_end/test/incremental_utils.dart
@@ -0,0 +1,46 @@
+// 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/kernel/utils.dart' show serializeComponent;
+
+import 'package:kernel/kernel.dart'
+    show Class, Component, EmptyStatement, Library, Procedure, Reference;
+
+List<int> postProcess(Component c) {
+  c.libraries.sort((l1, l2) {
+    return "${l1.fileUri}".compareTo("${l2.fileUri}");
+  });
+
+  c.computeCanonicalNames();
+  for (Library library in c.libraries) {
+    library.additionalExports.sort((Reference r1, Reference r2) {
+      return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
+    });
+  }
+
+  return serializeComponent(c);
+}
+
+void throwOnEmptyMixinBodies(Component component) {
+  int empty = countEmptyMixinBodies(component);
+  if (empty != 0) {
+    throw "Expected 0 empty bodies in mixins, but found $empty";
+  }
+}
+
+int countEmptyMixinBodies(Component component) {
+  int empty = 0;
+  for (Library lib in component.libraries) {
+    for (Class c in lib.classes) {
+      if (c.isSyntheticMixinImplementation) {
+        for (Procedure p in c.procedures) {
+          if (p.function.body is EmptyStatement) {
+            empty++;
+          }
+        }
+      }
+    }
+  }
+  return empty;
+}
diff --git a/pkg/front_end/test/memory_file_system_test.dart b/pkg/front_end/test/memory_file_system_test.dart
index f679d0b..89f7335 100644
--- a/pkg/front_end/test/memory_file_system_test.dart
+++ b/pkg/front_end/test/memory_file_system_test.dart
@@ -98,7 +98,7 @@
   test_readAsBytes_exists() async {
     var s = 'contents';
     file.writeAsStringSync(s);
-    expect(await file.readAsBytes(), UTF8.encode(s));
+    expect(await file.readAsBytes(), utf8.encode(s));
   }
 
   test_readAsString_badUtf8() {
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index c21bdc9..0000f0c 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -40,7 +40,7 @@
     expect(result.tokens?.type, same(Keyword.CLASS));
 
     // UTF8 encode source with trailing zero
-    List<int> bytes = UTF8.encode(source).toList();
+    List<int> bytes = utf8.encode(source).toList();
     bytes.add(0);
 
     result = usedForFuzzTesting.scan(bytes);
@@ -53,7 +53,7 @@
 class ScannerTest_Fasta_UTF8 extends ScannerTest_Fasta {
   @override
   createScanner(String source, {bool genericMethodComments: false}) {
-    List<int> encoded = UTF8.encode(source).toList(growable: true);
+    List<int> encoded = utf8.encode(source).toList(growable: true);
     encoded.add(0); // Ensure 0 terminted bytes for UTF8 scanner
     return new fasta.Utf8BytesScanner(encoded,
         includeComments: true,
@@ -65,7 +65,7 @@
       var hex = bytes.map((b) => '0x${b.toRadixString(16).toUpperCase()}');
       print('$bytes\n[${hex.join(', ')}]');
       try {
-        UTF8.decode(bytes);
+        utf8.decode(bytes);
       } catch (e) {
         // Bad UTF-8 encoding
         print('  This is invalid UTF-8, but scanner should not crash.');
@@ -712,7 +712,7 @@
 @reflectiveTest
 class ScannerTest_Fasta_Direct_UTF8 extends ScannerTest_Fasta_Direct {
   createScanner(String source, {bool includeComments}) {
-    List<int> encoded = UTF8.encode(source).toList(growable: true);
+    List<int> encoded = utf8.encode(source).toList(growable: true);
     encoded.add(0); // Ensure 0 terminted bytes for UTF8 scanner
     return new fasta.Utf8BytesScanner(encoded,
         includeComments: includeComments);
diff --git a/pkg/front_end/test/scanner_replacement_test.dart b/pkg/front_end/test/scanner_replacement_test.dart
index 9cfcb94..984c877 100644
--- a/pkg/front_end/test/scanner_replacement_test.dart
+++ b/pkg/front_end/test/scanner_replacement_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
 
 import 'package:front_end/src/fasta/scanner/recover.dart'
     show defaultRecoveryStrategy;
@@ -57,7 +57,7 @@
     assertValidTokenStream(tokens);
     assertValidBeginTokens(tokens);
     if (result.hasErrors) {
-      List<int> bytes = UTF8.encode(source);
+      List<int> bytes = utf8.encode(source);
       tokens = defaultRecoveryStrategy(bytes, tokens, result.lineStarts);
       assertValidTokenStream(tokens, errorsFirst: true);
     }
diff --git a/pkg/front_end/test/src/base/flat_buffers_test.dart b/pkg/front_end/test/src/base/flat_buffers_test.dart
index f94c7ed..facd4ae 100644
--- a/pkg/front_end/test/src/base/flat_buffers_test.dart
+++ b/pkg/front_end/test/src/base/flat_buffers_test.dart
@@ -64,21 +64,21 @@
     // Convert byteList to a ByteData so that we can read data from it.
     ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
     // First 4 bytes are an offset to the table data.
-    int tableDataLoc = byteData.getUint32(0, Endianness.LITTLE_ENDIAN);
+    int tableDataLoc = byteData.getUint32(0, Endian.little);
     // Next 4 bytes are the file identifier.
     expect(byteData.getUint8(4), 65); // 'a'
     expect(byteData.getUint8(5), 122); // 'z'
     expect(byteData.getUint8(6), 126); // '~'
     expect(byteData.getUint8(7), 255); // 'ÿ'
     // First 4 bytes of the table data are a backwards offset to the vtable.
-    int vTableLoc = tableDataLoc -
-        byteData.getInt32(tableDataLoc, Endianness.LITTLE_ENDIAN);
+    int vTableLoc =
+        tableDataLoc - byteData.getInt32(tableDataLoc, Endian.little);
     // First 2 bytes of the vtable are the size of the vtable in bytes, which
     // should be 4.
-    expect(byteData.getUint16(vTableLoc, Endianness.LITTLE_ENDIAN), 4);
+    expect(byteData.getUint16(vTableLoc, Endian.little), 4);
     // Next 2 bytes are the size of the object in bytes (including the vtable
     // pointer), which should be 4.
-    expect(byteData.getUint16(vTableLoc + 2, Endianness.LITTLE_ENDIAN), 4);
+    expect(byteData.getUint16(vTableLoc + 2, Endian.little), 4);
   }
 
   void test_low() {
@@ -128,23 +128,22 @@
     // Convert byteList to a ByteData so that we can read data from it.
     ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
     // First 4 bytes are an offset to the table data.
-    int tableDataLoc = byteData.getUint32(0, Endianness.LITTLE_ENDIAN);
+    int tableDataLoc = byteData.getUint32(0, Endian.little);
     // First 4 bytes of the table data are a backwards offset to the vtable.
-    int vTableLoc = tableDataLoc -
-        byteData.getInt32(tableDataLoc, Endianness.LITTLE_ENDIAN);
+    int vTableLoc =
+        tableDataLoc - byteData.getInt32(tableDataLoc, Endian.little);
     // First 2 bytes of the vtable are the size of the vtable in bytes, which
     // should be 10.
-    expect(byteData.getUint16(vTableLoc, Endianness.LITTLE_ENDIAN), 10);
+    expect(byteData.getUint16(vTableLoc, Endian.little), 10);
     // Next 2 bytes are the size of the object in bytes (including the vtable
     // pointer), which should be 16.
-    expect(byteData.getUint16(vTableLoc + 2, Endianness.LITTLE_ENDIAN), 16);
+    expect(byteData.getUint16(vTableLoc + 2, Endian.little), 16);
     // Remaining 6 bytes are the offsets within the object where the ints are
     // located.
     for (int i = 0; i < 3; i++) {
-      int offset =
-          byteData.getUint16(vTableLoc + 4 + 2 * i, Endianness.LITTLE_ENDIAN);
-      expect(byteData.getInt32(tableDataLoc + offset, Endianness.LITTLE_ENDIAN),
-          10 + 10 * i);
+      int offset = byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little);
+      expect(
+          byteData.getInt32(tableDataLoc + offset, Endian.little), 10 + 10 * i);
     }
   }
 
diff --git a/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart b/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
index 56728d6..9ad0d40 100644
--- a/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
@@ -9,7 +9,7 @@
 
 import 'dart:async' show Completer, Future;
 
-import 'dart:convert' show LineSplitter, UTF8;
+import 'dart:convert' show LineSplitter, utf8;
 
 import 'dart:io' show Directory, File, Platform, Process;
 
@@ -118,14 +118,14 @@
     var completers =
         new List.generate(expectedLines, (_) => new Completer<String>());
     lines = completers.map((c) => c.future).toList();
-    vm.stdout.transform(UTF8.decoder).transform(splitter).listen((line) {
+    vm.stdout.transform(utf8.decoder).transform(splitter).listen((line) {
       Expect.isTrue(i < expectedLines);
       completers[i++].complete(line);
     }, onDone: () {
       Expect.equals(expectedLines, i);
     });
 
-    vm.stderr.transform(UTF8.decoder).transform(splitter).toList().then((err) {
+    vm.stderr.transform(utf8.decoder).transform(splitter).toList().then((err) {
       Expect.isTrue(err.isEmpty, err.join('\n'));
     });
 
diff --git a/pkg/front_end/test/standard_file_system_test.dart b/pkg/front_end/test/standard_file_system_test.dart
index e78a3c7..bd67f3b 100644
--- a/pkg/front_end/test/standard_file_system_test.dart
+++ b/pkg/front_end/test/standard_file_system_test.dart
@@ -112,7 +112,7 @@
   test_readAsBytes_exists() async {
     var s = 'contents';
     new io.File(path).writeAsStringSync(s);
-    expect(await file.readAsBytes(), UTF8.encode(s));
+    expect(await file.readAsBytes(), utf8.encode(s));
   }
 
   test_readAsString_badUtf8() {
diff --git a/pkg/front_end/testcases/expression.status b/pkg/front_end/testcases/expression.status
new file mode 100644
index 0000000..de541b8
--- /dev/null
+++ b/pkg/front_end/testcases/expression.status
@@ -0,0 +1,52 @@
+// 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.
+
+class_capture.expression: Crash
+class_getter.expression: Crash
+class_invalid_static.expression: Crash
+class_invalid_static_capture.expression: Crash
+class_invalid_static_getter.expression: Crash
+class_invalid_static_setter.expression: Crash
+class_method.expression: Crash
+class_setter.expression: Crash
+class_static.expression: Crash
+class_static2.expression: Crash
+class_static3.expression: Crash
+class_type_param_bound.expression: Crash
+class_type_param_bound_illegal.expression: Crash
+class_type_param_reference.expression: Crash
+class_type_param_reference_arg.expression: Crash
+class_type_param_reference_arg_inferred.expression: Crash
+class_type_param_reference_ctor.expression: Crash
+class_type_param_reference_ctor_inferred.expression: Crash
+class_type_param_reference_var.expression: Crash
+core_lib_imported.expression: Crash
+core_lib_internal.expression: Crash
+eval.dart: Crash
+invalid.expression: Crash
+invalid_type_variable.expression: Crash
+invalid_variable.expression: Crash
+lib_ctor.expression: Crash
+lib_external_ctor.expression: Crash
+lib_nonctor.expression: Crash
+lib_nonreference.expression: Crash
+lib_nonshown_ctor.expression: Crash
+lib_reference.expression: Crash
+lib_simple.expression: Crash
+missing_variable_types.expression: Crash
+noclass.expression: Crash
+nolib.expression: Crash
+param_assign.expression: Crash
+param_capture.expression: Crash
+param_conflict.expression: Crash
+param_conflict_class.expression: Crash
+param_method.expression: Crash
+type_param_bound.expression: Crash
+type_param_shadow.expression: Crash
+type_param_shadow_arg.expression: Crash
+type_param_shadow_arg_ctor_inferred.expression: Crash
+type_param_shadow_arg_inferred.expression: Crash
+type_param_shadow_ctor.expression: Crash
+type_param_shadow_var.expression: Crash
+
diff --git a/pkg/front_end/testcases/expression/class_capture.expression.yaml b/pkg/front_end/testcases/expression/class_capture.expression.yaml
new file mode 100644
index 0000000..8d7121f
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_capture.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+expression: |
+  () { return x + y; }
diff --git a/pkg/front_end/testcases/expression/class_capture.expression.yaml.expect b/pkg/front_end/testcases/expression/class_capture.expression.yaml.expect
new file mode 100644
index 0000000..e937d8c
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_capture.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return () → dart.core::int {
+    return this.{main::B::x}.{dart.core::num::+}(this.{main::B::y});
+  };
diff --git a/pkg/front_end/testcases/expression/class_getter.expression.yaml b/pkg/front_end/testcases/expression/class_getter.expression.yaml
new file mode 100644
index 0000000..b633a11
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_getter.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+expression: |
+  z
diff --git a/pkg/front_end/testcases/expression/class_getter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_getter.expression.yaml.expect
new file mode 100644
index 0000000..e8e5846
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_getter.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return this.{main::B::z};
diff --git a/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml
new file mode 100644
index 0000000..d607088
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+static: true
+expression: |
+  doit_with_this(3)
diff --git a/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
new file mode 100644
index 0000000..1c3d9f3
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+  Method not found: 'doit_with_this'. (@0)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], <dynamic>[3].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml b/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml
new file mode 100644
index 0000000..9e410c8
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+static: true
+expression: |
+  () { return x + y; }
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml.expect
new file mode 100644
index 0000000..6208070
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml.expect
@@ -0,0 +1,8 @@
+Errors: {
+  Getter not found: 'y'. (@16)
+  Getter not found: 'x'. (@12)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return () → dynamic {
+    return (throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#x, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))).+(throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#y, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{}))));
+  };
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml b/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml
new file mode 100644
index 0000000..e9fa6d2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+static: true
+expression: |
+  z
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml.expect
new file mode 100644
index 0000000..1a79f8a
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+  Getter not found: 'z'. (@0)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml
new file mode 100644
index 0000000..17539fb
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+static: true
+expression: |
+  z = 2
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
new file mode 100644
index 0000000..ff2d316
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+  Setter not found: 'z'. (@0)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 34, const <dart.core::Type>[], <dynamic>[2].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_method.expression.yaml b/pkg/front_end/testcases/expression/class_method.expression.yaml
new file mode 100644
index 0000000..5a08e80
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_method.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+expression: |
+  doit_with_this(2)
diff --git a/pkg/front_end/testcases/expression/class_method.expression.yaml.expect b/pkg/front_end/testcases/expression/class_method.expression.yaml.expect
new file mode 100644
index 0000000..5c85dec
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_method.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return this.{main::A::doit_with_this}(2);
diff --git a/pkg/front_end/testcases/expression/class_setter.expression.yaml b/pkg/front_end/testcases/expression/class_setter.expression.yaml
new file mode 100644
index 0000000..44d76b6
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_setter.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+expression: |
+  z = 3
diff --git a/pkg/front_end/testcases/expression/class_setter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_setter.expression.yaml.expect
new file mode 100644
index 0000000..8c53fc2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_setter.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return this.{main::B::z} = 3;
diff --git a/pkg/front_end/testcases/expression/class_static.expression.yaml b/pkg/front_end/testcases/expression/class_static.expression.yaml
new file mode 100644
index 0000000..51be2c2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+static: true
+expression: |
+  doit(3)
diff --git a/pkg/front_end/testcases/expression/class_static.expression.yaml.expect b/pkg/front_end/testcases/expression/class_static.expression.yaml.expect
new file mode 100644
index 0000000..8fc9b60
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return main::A::doit(3);
diff --git a/pkg/front_end/testcases/expression/class_static2.expression.yaml b/pkg/front_end/testcases/expression/class_static2.expression.yaml
new file mode 100644
index 0000000..2c8e2b0
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static2.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+static: true
+expression: |
+  doit_with_this(2)
diff --git a/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect b/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
new file mode 100644
index 0000000..2a1fd01
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+  Method not found: 'doit_with_this'. (@0)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], <dynamic>[2].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_static3.expression.yaml b/pkg/front_end/testcases/expression/class_static3.expression.yaml
new file mode 100644
index 0000000..935b013
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static3.expression.yaml
@@ -0,0 +1,16 @@
+// 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.
+
+- entry_point: "eval.dart"
+  definitions: []
+  position: "eval.dart"
+  expression: |
+    globalVar + staticVar + 5
+
+- entry_point: "eval.dart"
+  definitions: []
+  position: "eval.dart#MyClass"
+  static: true
+  expression: |
+    globalVar + staticVar + 5
diff --git a/pkg/front_end/testcases/expression/class_static3.expression.yaml.expect b/pkg/front_end/testcases/expression/class_static3.expression.yaml.expect
new file mode 100644
index 0000000..7bc3bc9
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static3.expression.yaml.expect
@@ -0,0 +1,9 @@
+Errors: {
+  Getter not found: 'staticVar'. (@12)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return #lib1::globalVar.{dart.core::num::+}((throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#staticVar, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))) as{TypeError} dart.core::num).{dart.core::num::+}(5);
+Errors: {
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return #lib1::globalVar.{dart.core::num::+}(#lib1::MyClass::staticVar).{dart.core::num::+}(5);
diff --git a/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml
new file mode 100644
index 0000000..be7df51
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#C"
+expression: |
+  hasBound<T>()
diff --git a/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml.expect
new file mode 100644
index 0000000..2fef29d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+  return main::hasBound<main::C::T>();
diff --git a/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml
new file mode 100644
index 0000000..d2b970d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+  hasBound<T>()
diff --git a/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml.expect
new file mode 100644
index 0000000..99f4ec9
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+  return main::hasBound<main::A::T>();
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml
new file mode 100644
index 0000000..d5afdd7
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+  x is T
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml.expect
new file mode 100644
index 0000000..4dc0e4e
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+  return x is main::A::T;
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml
new file mode 100644
index 0000000..fa1365b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+  id<T>(x)
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml.expect
new file mode 100644
index 0000000..9e1d05d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+  return main::id<main::A::T>(x as{TypeError} main::A::T);
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml
new file mode 100644
index 0000000..900cff7
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml
@@ -0,0 +1,11 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+  () {
+    x = id(x);
+  }
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect
new file mode 100644
index 0000000..f830c60
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+  return () → dart.core::Null {
+    x = main::id<dynamic>(x);
+  };
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml
new file mode 100644
index 0000000..7312962
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+  new A<T>()
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml.expect
new file mode 100644
index 0000000..979c5be
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+  return new main::A::•<main::A::T>();
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml
new file mode 100644
index 0000000..5ae73cf
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml
@@ -0,0 +1,11 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+  () {
+    x = new A();
+  }
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect
new file mode 100644
index 0000000..5c172f4
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+  return () → dart.core::Null {
+    x = new main::A::•<dynamic>();
+  };
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml
new file mode 100644
index 0000000..1426f35
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml
@@ -0,0 +1,12 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+expression: |
+  () {
+    T k = null;
+    return k;
+  }
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml.expect
new file mode 100644
index 0000000..1404a49
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return () → main::A::T {
+    main::A::T k = null;
+    return k;
+  };
diff --git a/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml
new file mode 100644
index 0000000..328df34
--- /dev/null
+++ b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+- entry_point: "main.dart"
+  definitions: []
+  position: "dart:collection"
+  expression: |
+    identical(1, 1)
diff --git a/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect
new file mode 100644
index 0000000..dd6add4
--- /dev/null
+++ b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return dart.core::identical(1, 1);
diff --git a/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml
new file mode 100644
index 0000000..f3a1533
--- /dev/null
+++ b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+- entry_point: "main.dart"
+  definitions: []
+  position: "dart:collection"
+  expression: |
+    null is Queue
diff --git a/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect
new file mode 100644
index 0000000..e5db5df
--- /dev/null
+++ b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return null is dart.collection::Queue<dynamic>;
diff --git a/pkg/front_end/testcases/expression/eval.dart b/pkg/front_end/testcases/expression/eval.dart
new file mode 100644
index 0000000..b905801
--- /dev/null
+++ b/pkg/front_end/testcases/expression/eval.dart
@@ -0,0 +1,20 @@
+// 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.
+
+int globalVar = 100;
+
+class MyClass {
+  static int staticVar = 1000;
+
+  static void method(int value) {}
+}
+
+void testFunction() {
+  int i = 0;
+  while (true) {
+    if (++i % 100000000 == 0) {
+      MyClass.method(10000);
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/expression/invalid.expression.yaml b/pkg/front_end/testcases/expression/invalid.expression.yaml
new file mode 100644
index 0000000..410e7a9
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+  *foo(3,
diff --git a/pkg/front_end/testcases/expression/invalid.expression.yaml.expect b/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
new file mode 100644
index 0000000..1ce824d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+  Expected an identifier, but got '*'. (@0)
+  Method not found: 'foo'. (@1)
+  Getter not found: ''. (@0)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return (throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))).*(throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#foo, 32, const <dart.core::Type>[], <dynamic>[3].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{}))));
diff --git a/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml b/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml
new file mode 100644
index 0000000..79ff7ae
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+type_definitions: ["a#b"]
+position: "main.dart"
+expression: |
+  3
diff --git a/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml.expect b/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml.expect
new file mode 100644
index 0000000..ba1f145
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml.expect
@@ -0,0 +1,3 @@
+Errors: {
+}
+<no procedure>
diff --git a/pkg/front_end/testcases/expression/invalid_variable.expression.yaml b/pkg/front_end/testcases/expression/invalid_variable.expression.yaml
new file mode 100644
index 0000000..3409817
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid_variable.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["a#b"]
+position: "main.dart"
+expression: |
+  3
diff --git a/pkg/front_end/testcases/expression/invalid_variable.expression.yaml.expect b/pkg/front_end/testcases/expression/invalid_variable.expression.yaml.expect
new file mode 100644
index 0000000..ba1f145
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid_variable.expression.yaml.expect
@@ -0,0 +1,3 @@
+Errors: {
+}
+<no procedure>
diff --git a/pkg/front_end/testcases/expression/lib_ctor.expression.yaml b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml
new file mode 100644
index 0000000..9bfc310
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+  () { new A(); const A(); }
diff --git a/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect
new file mode 100644
index 0000000..b4269a7
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return () → dart.core::Null {
+    new main::A::•<dynamic>();
+    const main::A::•<dynamic>();
+  };
diff --git a/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml
new file mode 100644
index 0000000..aac6c87
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+  () { new Process(); new File.fromUri(Uri.parse("file://test.dart")); }
diff --git a/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect
new file mode 100644
index 0000000..a9ca37b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect
@@ -0,0 +1,8 @@
+Errors: {
+  The class 'Process' is abstract and can't be instantiated. (@9)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return () → dart.core::Null {
+    throw new dart.core::AbstractClassInstantiationError::•("Process");
+    dart.io::File::fromUri(dart.core::Uri::parse("file://test.dart"));
+  };
diff --git a/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml b/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml
new file mode 100644
index 0000000..4cf924a
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+  new Random();
diff --git a/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml.expect
new file mode 100644
index 0000000..b82b038
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+  Method not found: 'Random'. (@4)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#Random, 32, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml
new file mode 100644
index 0000000..67849fd
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+  acos(1.0)
diff --git a/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
new file mode 100644
index 0000000..d7a9a32
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+  Method not found: 'acos'. (@0)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#acos, 32, const <dart.core::Type>[], <dynamic>[1.0].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml
new file mode 100644
index 0000000..dbc9544
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+  new Directory("test")
diff --git a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
new file mode 100644
index 0000000..699e4fa
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+  Method not found: 'Directory'. (@4)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#Directory, 32, const <dart.core::Type>[], <dynamic>["test"].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/lib_reference.expression.yaml b/pkg/front_end/testcases/expression/lib_reference.expression.yaml
new file mode 100644
index 0000000..e4f0254
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_reference.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+  exit(2)
diff --git a/pkg/front_end/testcases/expression/lib_reference.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_reference.expression.yaml.expect
new file mode 100644
index 0000000..5f9d49f
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_reference.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return dart.io::exit(2);
diff --git a/pkg/front_end/testcases/expression/lib_simple.expression.yaml b/pkg/front_end/testcases/expression/lib_simple.expression.yaml
new file mode 100644
index 0000000..0e7ca4c
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_simple.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+  doitstat(2)
diff --git a/pkg/front_end/testcases/expression/lib_simple.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_simple.expression.yaml.expect
new file mode 100644
index 0000000..c54d90c
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_simple.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return main::doitstat(2);
diff --git a/pkg/front_end/testcases/expression/main.dart b/pkg/front_end/testcases/expression/main.dart
new file mode 100644
index 0000000..ba2d61d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/main.dart
@@ -0,0 +1,57 @@
+// 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.
+
+// 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.
+
+library main;
+
+import 'dart:io' show File, Process, exit;
+
+int doitstat(int x) => x + 1;
+
+int globalVar = 6;
+
+class A<T> {
+  const A();
+  static int doit(int x) => x + 1;
+  static int staticVar = 3;
+  int doit_with_this(int x) => x + 1;
+}
+
+T id<T>(T x) => x;
+
+class B {
+  int x;
+  final int y;
+  String get z {
+    return "";
+  }
+
+  void set z(int _) {}
+}
+
+class Bound {}
+
+class C<T extends Bound> {}
+
+void hasBound<T extends Bound>() {}
+
+Object k;
+
+class D<T> {
+  Y id<Y>(Y x) => x;
+  m(List<T> l) {
+    assert(l is List<T>);
+  }
+
+  foo() {
+    List<T> s;
+  }
+}
+
+main() {
+  exit(0);
+}
diff --git a/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml b/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml
new file mode 100644
index 0000000..9411454
--- /dev/null
+++ b/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["s"]
+position: "main.dart#D"
+expression: |
+  m(id(s = []))
diff --git a/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml.expect b/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml.expect
new file mode 100644
index 0000000..6b64c73
--- /dev/null
+++ b/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic s) → dynamic
+  return this.{main::D::m}(this.{main::D::id}<dart.core::List<main::D::T>>((s = <dynamic>[]) as{TypeError} dart.core::List<main::D::T>));
diff --git a/pkg/front_end/testcases/expression/noclass.expression.yaml b/pkg/front_end/testcases/expression/noclass.expression.yaml
new file mode 100644
index 0000000..ef09ec8
--- /dev/null
+++ b/pkg/front_end/testcases/expression/noclass.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#NoClass"
+expression: |
+  0
diff --git a/pkg/front_end/testcases/expression/noclass.expression.yaml.expect b/pkg/front_end/testcases/expression/noclass.expression.yaml.expect
new file mode 100644
index 0000000..ba1f145
--- /dev/null
+++ b/pkg/front_end/testcases/expression/noclass.expression.yaml.expect
@@ -0,0 +1,3 @@
+Errors: {
+}
+<no procedure>
diff --git a/pkg/front_end/testcases/expression/nolib.expression.yaml b/pkg/front_end/testcases/expression/nolib.expression.yaml
new file mode 100644
index 0000000..1502f41
--- /dev/null
+++ b/pkg/front_end/testcases/expression/nolib.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+position: "nono.dart"
+expression: |
+  0
diff --git a/pkg/front_end/testcases/expression/nolib.expression.yaml.expect b/pkg/front_end/testcases/expression/nolib.expression.yaml.expect
new file mode 100644
index 0000000..ba1f145
--- /dev/null
+++ b/pkg/front_end/testcases/expression/nolib.expression.yaml.expect
@@ -0,0 +1,3 @@
+Errors: {
+}
+<no procedure>
diff --git a/pkg/front_end/testcases/expression/param_assign.expression.yaml b/pkg/front_end/testcases/expression/param_assign.expression.yaml
new file mode 100644
index 0000000..a0262f1
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_assign.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x", "y"]
+position: "main.dart"
+expression: |
+  x = 3
diff --git a/pkg/front_end/testcases/expression/param_assign.expression.yaml.expect b/pkg/front_end/testcases/expression/param_assign.expression.yaml.expect
new file mode 100644
index 0000000..7f05f7a
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_assign.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x, dynamic y) → dynamic
+  return x = 3;
diff --git a/pkg/front_end/testcases/expression/param_capture.expression.yaml b/pkg/front_end/testcases/expression/param_capture.expression.yaml
new file mode 100644
index 0000000..72b991d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_capture.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x", "y"]
+position: "main.dart"
+expression: |
+  () { x = x + y; }
diff --git a/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect b/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect
new file mode 100644
index 0000000..b8ea8d2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x, dynamic y) → dynamic
+  return () → dart.core::Null {
+    x = x.+(y);
+  };
diff --git a/pkg/front_end/testcases/expression/param_conflict.expression.yaml b/pkg/front_end/testcases/expression/param_conflict.expression.yaml
new file mode 100644
index 0000000..8304043
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_conflict.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["dostat", "y"]
+position: "main.dart"
+expression: |
+  dostat.foo()
diff --git a/pkg/front_end/testcases/expression/param_conflict.expression.yaml.expect b/pkg/front_end/testcases/expression/param_conflict.expression.yaml.expect
new file mode 100644
index 0000000..5c4a28c
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_conflict.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic dostat, dynamic y) → dynamic
+  return dostat.foo();
diff --git a/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml b/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml
new file mode 100644
index 0000000..48969a2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["A", "y"]
+position: "main.dart"
+expression: |
+  A.foo(y)
diff --git a/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml.expect b/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml.expect
new file mode 100644
index 0000000..c66e526
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic A, dynamic y) → dynamic
+  return A.foo(y);
diff --git a/pkg/front_end/testcases/expression/param_method.expression.yaml b/pkg/front_end/testcases/expression/param_method.expression.yaml
new file mode 100644
index 0000000..da82702
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_method.expression.yaml
@@ -0,0 +1,9 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x", "y"]
+position: "main.dart"
+expression: |
+  x.foo(y)
diff --git a/pkg/front_end/testcases/expression/param_method.expression.yaml.expect b/pkg/front_end/testcases/expression/param_method.expression.yaml.expect
new file mode 100644
index 0000000..4f6b188
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_method.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x, dynamic y) → dynamic
+  return x.foo(y);
diff --git a/pkg/front_end/testcases/expression/type_param_bound.expression.yaml b/pkg/front_end/testcases/expression/type_param_bound.expression.yaml
new file mode 100644
index 0000000..9c3a1ce
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_bound.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+type_definitions: ["T"]
+position: "main.dart"
+expression: |
+  hasBound<T>()
diff --git a/pkg/front_end/testcases/expression/type_param_bound.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_bound.expression.yaml.expect
new file mode 100644
index 0000000..285eca0
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_bound.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
+  return main::hasBound<main::debugExpr::T>();
diff --git a/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml
new file mode 100644
index 0000000..4a291a5
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+  x is T
diff --git a/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml.expect
new file mode 100644
index 0000000..dfc583e
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>(dynamic x) → dynamic
+  return x is main::A::debugExpr::T;
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml
new file mode 100644
index 0000000..412fea8
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+  id<T>(x)
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml.expect
new file mode 100644
index 0000000..1a951e3
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>(dynamic x) → dynamic
+  return main::id<main::A::debugExpr::T>(x as{TypeError} main::A::debugExpr::T);
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml
new file mode 100644
index 0000000..94e653b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml
@@ -0,0 +1,12 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+  () {
+    T k = new A();
+  }
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
new file mode 100644
index 0000000..6368c6b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+  A value of type 'main::A<dynamic>' can't be assigned to a variable of type 'main::A::debugExpr::T'. (@17)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
+  return () → dart.core::Null {
+    main::A::debugExpr::T k = let final dynamic #t1 = new main::A::•<dynamic>() in let dynamic _ = null in invalid-expression "Error: A value of type 'main::A<dynamic>' can't be assigned to a variable of type 'main::A::debugExpr::T'.\nTry changing the type of the left hand side, or casting the right hand side to 'main::A::debugExpr::T'.";
+  };
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml
new file mode 100644
index 0000000..fa853f1
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml
@@ -0,0 +1,13 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+  () {
+    T k = null;
+    k = id(k);
+  }
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect
new file mode 100644
index 0000000..77370b6
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
+  return () → dart.core::Null {
+    main::A::debugExpr::T k = null;
+    k = main::id<main::A::debugExpr::T>(k);
+  };
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml
new file mode 100644
index 0000000..6dacbfb
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml
@@ -0,0 +1,10 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: []
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+  new A<T>()
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml.expect
new file mode 100644
index 0000000..87f7a81
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
+  return new main::A::•<main::A::debugExpr::T>();
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml
new file mode 100644
index 0000000..bf266c6
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml
@@ -0,0 +1,12 @@
+// 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+  () {
+    T x = null;
+  }
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect
new file mode 100644
index 0000000..0fb5c63
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>(dynamic x) → dynamic
+  return () → dart.core::Null {
+    main::A::debugExpr::T x = null;
+  };
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
index c9e0195..d336e98 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE.md file.
 
-# Invalidate nothing when the entrypoint  just exports another file
+# Invalidate nothing when the entrypoint just exports another file
 # (which has main).
 
 type: basic
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
index b71b402..544bc96 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
@@ -2,15 +2,16 @@
 import self as self;
 import "dart:core" as core;
 
-static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
-  /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
-                                                                         ^"]/* from null */;
 static method test() → dynamic {
   function f() → dynamic
     return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-  invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+  {
+    let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
   g() => 0;
   ^";
+    function g() → dynamic
+      return 0;
+  }
   dynamic v = f;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
index b71b402..544bc96 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
@@ -2,15 +2,16 @@
 import self as self;
 import "dart:core" as core;
 
-static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
-  /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
-                                                                         ^"]/* from null */;
 static method test() → dynamic {
   function f() → dynamic
     return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-  invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+  {
+    let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
   g() => 0;
   ^";
+    function g() → dynamic
+      return 0;
+  }
   dynamic v = f;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
index 6343ea9..1b564d8 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
@@ -4,15 +4,17 @@
 
 static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Method not found: 'g'.
   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
-                                                                         ^", "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
-  /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
                                                                          ^"]/* from null */;
 static method test() → dynamic {
   function f() → dynamic
     return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-  invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+  {
+    let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
   g() => 0;
   ^";
+    function g() → dynamic
+      return 0;
+  }
   () → dynamic v = f;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
index 6343ea9..fa37ad4 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
@@ -4,15 +4,17 @@
 
 static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Method not found: 'g'.
   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
-                                                                         ^", "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
-  /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
                                                                          ^"]/* from null */;
 static method test() → dynamic {
   function f() → dynamic
     return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-  invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+  {
+    let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
   g() => 0;
   ^";
+    function g() → dynamic
+      return 0;
+  }
   () → dynamic v = f;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart b/pkg/front_end/testcases/named_function_scope.dart
new file mode 100644
index 0000000..bb6e8aa
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart
@@ -0,0 +1,89 @@
+// 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.
+
+/*@testedFeatures=error,warning,context*/
+
+class T {}
+
+class V {}
+
+test() {
+  T t;
+  V v;
+  {
+    // This doesn't cause an error as the previous use of T is in an enclosing
+    // scope.
+    T() {}
+  }
+  {
+    // This doesn't cause an error as the previous use of V is in an enclosing
+    // scope.
+    var v;
+  }
+  {
+    T t;
+    // This doesn't cause a scope error as the named function expression has
+    // its own scope.
+    var x = /*@error=NamedFunctionExpression*/ T() {};
+  }
+  {
+    /*@context=DuplicatedNamePreviouslyUsedCause*/ V  v;
+    // This causes an error, V is already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+  }
+  {
+    /*@context=DuplicatedNamePreviouslyUsedCause*/ V  v;
+    // This causes an error, V is already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+  }
+  {
+    // This causes a scope error as T is already used in the function-type
+    // scope (the return type).
+    var x =
+        /*@error=ReturnTypeFunctionExpression*/
+        /*@context=DuplicatedNamePreviouslyUsedCause*/
+        T
+        /*@error=NamedFunctionExpression*/
+        /*@error=DuplicatedNamePreviouslyUsed*/
+        T() {};
+  }
+  {
+    // This causes a scope error: using the outer definition of `V` as a type
+    // when defining `V`.
+    /*@context=DuplicatedNamePreviouslyUsedCause*/
+    V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+  }
+  {
+    // This causes a scope error as T is already defined as a type variable in
+    // the function-type scope.
+    var x =
+        /*@error=NamedFunctionExpression*/
+        /*@error=DuplicatedName*/
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+  }
+  {
+    /*@context=DuplicatedNamePreviouslyUsedCause*/
+    T t;
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+  }
+  {
+    /*@context=DuplicatedNamePreviouslyUsedCause*/
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+  }
+  {
+    /*@context=DuplicatedNamePreviouslyUsedCause*/
+    T t;
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+  }
+  {
+    /*@context=DuplicatedNamePreviouslyUsedCause*/
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+  }
+  {
+    void T(/*@error=NotAType*/ T t) {}
+  }
+}
+
+void main() {
+}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
new file mode 100644
index 0000000..a6a572a
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
@@ -0,0 +1,102 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class V extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
+    var x = /*@error=NamedFunctionExpression*/ T() {};
+                                               ^", "pkg/front_end/testcases/named_function_scope.dart:46:9: Error: A function expression can't have a return type.
+        T
+        ^", "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: A function expression can't have a name.
+        T() {};
+        ^", "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: A function expression can't have a name.
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+        ^"]/* from null */;
+static method test() → dynamic {
+  self::T t;
+  self::V v;
+  {
+    function T() → dynamic {}
+  }
+  {
+    dynamic v;
+  }
+  {
+    self::T t;
+    dynamic x = let final () → dynamic T = () → dynamic {} in T;
+  }
+  {
+    self::V v;
+    dynamic V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+                                                ^";
+  }
+  {
+    self::V v;
+    dynamic V = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+                                                ^" in let final dynamic #t2 = null in null;
+  }
+  {
+    dynamic x = let final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: Can't declare 'T' because it was already used in this scope.
+        T() {};
+        ^" in let final () → self::T T = () → self::T {} in T;
+  }
+  {
+    self::V V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:55:47: Error: Can't declare 'V' because it was already used in this scope.
+    V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+                                              ^";
+  }
+  {
+    dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: 'T' is already declared in this scope.
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+        ^" in let final <T extends core::Object>() → dynamic T = <T extends core::Object>() → dynamic {} in T;
+  }
+  {
+    self::T t;
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+                                              ^";
+      function T() → self::T {}
+    }
+  }
+  {
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+                                              ^";
+      function T() → self::T {}
+    }
+  }
+  {
+    self::T t;
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+                                              ^";
+      function T(self::T t) → self::T {}
+    }
+  }
+  {
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+                                              ^";
+      function T(self::T t) → self::T {}
+    }
+  }
+  {
+    function T(invalid-type t) → void {}
+  }
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
new file mode 100644
index 0000000..a6a572a
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
@@ -0,0 +1,102 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class V extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
+    var x = /*@error=NamedFunctionExpression*/ T() {};
+                                               ^", "pkg/front_end/testcases/named_function_scope.dart:46:9: Error: A function expression can't have a return type.
+        T
+        ^", "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: A function expression can't have a name.
+        T() {};
+        ^", "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: A function expression can't have a name.
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+        ^"]/* from null */;
+static method test() → dynamic {
+  self::T t;
+  self::V v;
+  {
+    function T() → dynamic {}
+  }
+  {
+    dynamic v;
+  }
+  {
+    self::T t;
+    dynamic x = let final () → dynamic T = () → dynamic {} in T;
+  }
+  {
+    self::V v;
+    dynamic V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+                                                ^";
+  }
+  {
+    self::V v;
+    dynamic V = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+                                                ^" in let final dynamic #t2 = null in null;
+  }
+  {
+    dynamic x = let final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: Can't declare 'T' because it was already used in this scope.
+        T() {};
+        ^" in let final () → self::T T = () → self::T {} in T;
+  }
+  {
+    self::V V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:55:47: Error: Can't declare 'V' because it was already used in this scope.
+    V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+                                              ^";
+  }
+  {
+    dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: 'T' is already declared in this scope.
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+        ^" in let final <T extends core::Object>() → dynamic T = <T extends core::Object>() → dynamic {} in T;
+  }
+  {
+    self::T t;
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+                                              ^";
+      function T() → self::T {}
+    }
+  }
+  {
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+                                              ^";
+      function T() → self::T {}
+    }
+  }
+  {
+    self::T t;
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+                                              ^";
+      function T(self::T t) → self::T {}
+    }
+  }
+  {
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+                                              ^";
+      function T(self::T t) → self::T {}
+    }
+  }
+  {
+    function T(invalid-type t) → void {}
+  }
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.outline.expect b/pkg/front_end/testcases/named_function_scope.dart.outline.expect
new file mode 100644
index 0000000..95be2cd
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.outline.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+  synthetic constructor •() → void
+    ;
+}
+class V extends core::Object {
+  synthetic constructor •() → void
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
new file mode 100644
index 0000000..c207784
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
@@ -0,0 +1,104 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class V extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
+    var x = /*@error=NamedFunctionExpression*/ T() {};
+                                               ^", "pkg/front_end/testcases/named_function_scope.dart:46:9: Error: A function expression can't have a return type.
+        T
+        ^", "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: A function expression can't have a name.
+        T() {};
+        ^", "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: A function expression can't have a name.
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+        ^", "pkg/front_end/testcases/named_function_scope.dart:84:32: Error: 'T' isn't a type.
+    void T(/*@error=NotAType*/ T t) {}
+                               ^"]/* from null */;
+static method test() → dynamic {
+  self::T t;
+  self::V v;
+  {
+    function T() → core::Null {}
+  }
+  {
+    dynamic v;
+  }
+  {
+    self::T t;
+    () → core::Null x = let final () → core::Null T = () → core::Null {} in T;
+  }
+  {
+    self::V v;
+    dynamic V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+                                                ^";
+  }
+  {
+    self::V v;
+    dynamic V = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+                                                ^" in let final dynamic #t2 = null in null;
+  }
+  {
+    dynamic x = let final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: Can't declare 'T' because it was already used in this scope.
+        T() {};
+        ^" in let final () → self::T T = () → self::T {} in T;
+  }
+  {
+    self::V V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:55:47: Error: Can't declare 'V' because it was already used in this scope.
+    V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+                                              ^" as{TypeError} self::V;
+  }
+  {
+    dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: 'T' is already declared in this scope.
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+        ^" in let final <T extends core::Object>() → dynamic T = <T extends core::Object>() → dynamic {} in T;
+  }
+  {
+    self::T t;
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+                                              ^";
+      function T() → self::T {}
+    }
+  }
+  {
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+                                              ^";
+      function T() → self::T {}
+    }
+  }
+  {
+    self::T t;
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+                                              ^";
+      function T(self::T t) → self::T {}
+    }
+  }
+  {
+    {
+      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+                                              ^";
+      function T(self::T t) → self::T {}
+    }
+  }
+  {
+    function T(invalid-type t) → void {}
+  }
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
new file mode 100644
index 0000000..4fcb933
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
@@ -0,0 +1,104 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class V extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
+    var x = /*@error=NamedFunctionExpression*/ T() {};
+                                               ^", "pkg/front_end/testcases/named_function_scope.dart:46:9: Error: A function expression can't have a return type.
+        T
+        ^", "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: A function expression can't have a name.
+        T() {};
+        ^", "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: A function expression can't have a name.
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+        ^", "pkg/front_end/testcases/named_function_scope.dart:84:32: Error: 'T' isn't a type.
+    void T(/*@error=NotAType*/ T t) {}
+                               ^"]/* from null */;
+static method test() → dynamic {
+  self::T t;
+  self::V v;
+  {
+    function T() → core::Null {}
+  }
+  {
+    dynamic v;
+  }
+  {
+    self::T t;
+    () → core::Null x = let final () → core::Null T = () → core::Null {} in T;
+  }
+  {
+    self::V v;
+    dynamic V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+                                                ^";
+  }
+  {
+    self::V v;
+    dynamic V = let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+    var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+                                                ^" in let final<BottomType> #t2 = null in null;
+  }
+  {
+    dynamic x = let final dynamic #t3 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: Can't declare 'T' because it was already used in this scope.
+        T() {};
+        ^" in let final () → self::T T = () → self::T {} in T;
+  }
+  {
+    self::V V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:55:47: Error: Can't declare 'V' because it was already used in this scope.
+    V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+                                              ^" as{TypeError} self::V;
+  }
+  {
+    dynamic x = let final dynamic #t4 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: 'T' is already declared in this scope.
+        T< /*@context=DuplicatedNameCause*/ T>() {};
+        ^" in let final <T extends core::Object>() → dynamic T = <T extends core::Object>() → dynamic {} in T;
+  }
+  {
+    self::T t;
+    {
+      let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+                                              ^";
+      function T() → self::T {}
+    }
+  }
+  {
+    {
+      let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+                                              ^";
+      function T() → self::T {}
+    }
+  }
+  {
+    self::T t;
+    {
+      let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+                                              ^";
+      function T(self::T t) → self::T {}
+    }
+  }
+  {
+    {
+      let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+    T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+                                              ^";
+      function T(self::T t) → self::T {}
+    }
+  }
+  {
+    function T(invalid-type t) → void {}
+  }
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect b/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
index f52c009..01ccbc1 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
@@ -1,13 +1,11 @@
 library;
 import self as self;
+import "dart:core" as core;
 
-static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
-  for (int i = i;; false) {}
-               ^"]/* from null */;
 static method bad() → dynamic {
-  for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+  for (core::int i = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
   for (int i = i;; false) {}
-           ^"; ; false) {
+           ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null; ; false) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
index f52c009..01ccbc1 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
@@ -1,13 +1,11 @@
 library;
 import self as self;
+import "dart:core" as core;
 
-static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
-  for (int i = i;; false) {}
-               ^"]/* from null */;
 static method bad() → dynamic {
-  for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+  for (core::int i = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
   for (int i = i;; false) {}
-           ^"; ; false) {
+           ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null; ; false) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
index 95a6e96..2f59826 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
@@ -1,15 +1,14 @@
 library;
 import self as self;
+import "dart:core" as core;
 
 static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Getter not found: 'i'.
   for (int i = i;; false) {}
-               ^", "pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
-  for (int i = i;; false) {}
                ^"]/* from null */;
 static method bad() → dynamic {
-  for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+  for (core::int i = (let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
   for (int i = i;; false) {}
-           ^"; ; false) {
+           ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null) as{TypeError} core::int; ; false) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
index 95a6e96..609e28a 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
@@ -1,15 +1,14 @@
 library;
 import self as self;
+import "dart:core" as core;
 
 static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Getter not found: 'i'.
   for (int i = i;; false) {}
-               ^", "pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
-  for (int i = i;; false) {}
                ^"]/* from null */;
 static method bad() → dynamic {
-  for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+  for (core::int i = (let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
   for (int i = i;; false) {}
-           ^"; ; false) {
+           ^" in let final<BottomType> #t2 = let<BottomType> _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null) as{TypeError} core::int; ; false) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31184.dart.direct.expect
index f7b5642..4796ca3 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.direct.expect
@@ -8,7 +8,7 @@
   for (int i = 0, i > 10; i++) {}
                     ^"]/* from null */;
 static method bad() → dynamic {
-  for (core::int i = 0, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' already declared in this scope.
+  for (core::int i = 0, core::int i = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
   for (int i = 0, i > 10; i++) {}
                   ^"; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10); i = i.+(1)) {
   }
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect
index f7b5642..4796ca3 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect
@@ -8,7 +8,7 @@
   for (int i = 0, i > 10; i++) {}
                     ^"]/* from null */;
 static method bad() → dynamic {
-  for (core::int i = 0, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' already declared in this scope.
+  for (core::int i = 0, core::int i = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
   for (int i = 0, i > 10; i++) {}
                   ^"; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10); i = i.+(1)) {
   }
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
index 6f23240..63579fd 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
@@ -10,9 +10,9 @@
   for (int i = 0, i > 10; i++) {}
                     ^"]/* from null */;
 static method bad() → dynamic {
-  for (core::int i = 0, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' already declared in this scope.
+  for (core::int i = 0, core::int i = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
   for (int i = 0, i > 10; i++) {}
-                  ^"; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10) as{TypeError} core::bool; i = i.{core::num::+}(1)) {
+                  ^" as{TypeError} core::int; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10) as{TypeError} core::bool; i = i.{core::num::+}(1)) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 0d7449a..231aa5e 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -63,7 +63,8 @@
         "/testcases/.*_part[0-9]*\\.dart$",
         "/testcases/.*_lib[0-9]*\\.dart$",
         "/testcases/dartino/",
-        "/testcases/shaker/"
+        "/testcases/shaker/",
+        "/testcases/expression/"
       ]
     },
 
@@ -80,7 +81,8 @@
         "/testcases/.*_part[0-9]*\\.dart$",
         "/testcases/.*_lib[0-9]*\\.dart$",
         "/testcases/dartino/",
-        "/testcases/shaker/"
+        "/testcases/shaker/",
+        "/testcases/expression/"
       ]
     },
 
@@ -97,7 +99,8 @@
         "/testcases/.*_part[0-9]*\\.dart$",
         "/testcases/.*_lib[0-9]*\\.dart$",
         "/testcases/dartino/",
-        "/testcases/shaker/"
+        "/testcases/shaker/",
+        "/testcases/expression/"
       ]
     },
 
diff --git a/pkg/front_end/tool/_fasta/abcompile.dart b/pkg/front_end/tool/_fasta/abcompile.dart
index b419d29..fcaf2bd 100644
--- a/pkg/front_end/tool/_fasta/abcompile.dart
+++ b/pkg/front_end/tool/_fasta/abcompile.dart
@@ -156,7 +156,7 @@
     }
     if (line.startsWith(_summaryTag)) {
       String json = line.substring(_summaryTag.length - 2);
-      Map<String, dynamic> results = JSON.decode(json);
+      Map<String, dynamic> results = jsonDecode(json);
       List<double> elapsedTimes = results['elapsedTimes'];
       print('\nElapse times: $elapsedTimes');
       if (elapsedTimes.length > 0) {
@@ -183,7 +183,7 @@
   stderr.addStream(process.stderr);
   StreamSubscription<String> stdOutSubscription;
   stdOutSubscription = process.stdout
-      .transform(UTF8.decoder)
+      .transform(utf8.decoder)
       .transform(new LineSplitter())
       .listen(processLine, onDone: () {
     stdOutSubscription.cancel();
diff --git a/pkg/front_end/tool/_fasta/bulk_compile.dart b/pkg/front_end/tool/_fasta/bulk_compile.dart
index 7101a1a..fd4e09b 100644
--- a/pkg/front_end/tool/_fasta/bulk_compile.dart
+++ b/pkg/front_end/tool/_fasta/bulk_compile.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async' show Future;
 
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
 
 import 'package:front_end/src/api_prototype/compiler_options.dart'
     show CompilerOptions;
@@ -63,7 +63,7 @@
     }
     Uri uri = new Uri(scheme: customScheme, host: "", path: path);
     MemoryFileSystemEntity entity = options.fileSystem.entityForUri(uri);
-    entity.bytes = UTF8.encode(source);
+    entity.bytes = utf8.encode(source);
   }
 }
 
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index c69bb9b..1586b35 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async' show Future, Stream;
 
-import 'dart:convert' show JSON, LineSplitter, UTF8;
+import 'dart:convert' show jsonDecode, jsonEncode, LineSplitter, utf8;
 
 import 'dart:io' show File, exitCode, stderr, stdin, stdout;
 
@@ -69,7 +69,7 @@
   }
 
   if (summary) {
-    var json = JSON.encode(<String, dynamic>{'elapsedTimes': elapsedTimes});
+    var json = jsonEncode(<String, dynamic>{'elapsedTimes': elapsedTimes});
     print('\nSummary: $json');
   }
 }
@@ -85,7 +85,7 @@
 
 batchEntryPoint(List<String> arguments) {
   return new BatchCompiler(
-          stdin.transform(UTF8.decoder).transform(new LineSplitter()))
+          stdin.transform(utf8.decoder).transform(new LineSplitter()))
       .run();
 }
 
@@ -101,7 +101,7 @@
   run() async {
     await for (String line in lines) {
       try {
-        if (await batchCompileArguments(JSON.decode(line))) {
+        if (await batchCompileArguments(jsonDecode(line))) {
           stdout.writeln(">>> TEST OK");
         } else {
           stdout.writeln(">>> TEST FAIL");
diff --git a/pkg/front_end/tool/_fasta/log_analyzer.dart b/pkg/front_end/tool/_fasta/log_analyzer.dart
index 029b6d2..c93e916 100644
--- a/pkg/front_end/tool/_fasta/log_analyzer.dart
+++ b/pkg/front_end/tool/_fasta/log_analyzer.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
 
 import 'dart:io';
 
@@ -16,7 +16,7 @@
   }
   for (String filename in cl.arguments) {
     String json = await new File(filename).readAsString();
-    Map<String, dynamic> data = JSON.decode(json) as Map<String, dynamic>;
+    Map<String, dynamic> data = jsonDecode(json) as Map<String, dynamic>;
     StringBuffer sb = new StringBuffer();
     bool isFirst = true;
     for (String field in fields) {
@@ -25,7 +25,7 @@
       }
       if (field.startsWith("json:")) {
         field = field.substring(5);
-        sb.write(JSON.encode(data[field]));
+        sb.write(jsonEncode(data[field]));
       } else {
         sb.write(data[field]);
       }
diff --git a/pkg/front_end/tool/_fasta/log_collector.dart b/pkg/front_end/tool/_fasta/log_collector.dart
index b9fa0f6..971cbfe 100644
--- a/pkg/front_end/tool/_fasta/log_collector.dart
+++ b/pkg/front_end/tool/_fasta/log_collector.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:convert' show JSON, UTF8;
+import 'dart:convert' show jsonDecode, utf8;
 
 import 'dart:isolate' show RawReceivePort;
 
@@ -32,10 +32,10 @@
 }
 
 collectLog(DateTime time, HttpRequest request) async {
-  String json = await request.transform(UTF8.decoder).join();
+  String json = await request.transform(utf8.decoder).join();
   var data;
   try {
-    data = JSON.decode(json);
+    data = jsonDecode(json);
   } on FormatException catch (e) {
     print(e);
     return badRequest(
diff --git a/pkg/front_end/tool/incremental_perf.dart b/pkg/front_end/tool/incremental_perf.dart
index 1d68942..02a4bb7 100644
--- a/pkg/front_end/tool/incremental_perf.dart
+++ b/pkg/front_end/tool/incremental_perf.dart
@@ -71,7 +71,7 @@
   var entryUri = _resolveOverlayUri(options.rest[0]);
   var editsUri = Uri.base.resolve(options.rest[1]);
   var changeSets =
-      parse(JSON.decode(new File.fromUri(editsUri).readAsStringSync()));
+      parse(jsonDecode(new File.fromUri(editsUri).readAsStringSync()));
   bool verbose = options["verbose"];
   bool verboseCompilation = options["verbose-compilation"];
   bool strongMode = options["mode"] == "strong";
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index de480d6..6d4c937 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -642,7 +642,7 @@
     }
     writeOffset(node.fileOffset);
     writeByte(node.flags);
-    writeNodeList(node.annotations);
+    writeAnnotationList(node.annotations);
     writeLibraryReference(node.targetLibrary);
     writeStringReference(node.name ?? '');
     writeNodeList(node.combinators);
@@ -665,7 +665,7 @@
     if (_metadataSubsections != null) {
       _recordNodeOffsetForMetadataMapping(node);
     }
-    writeNodeList(node.annotations);
+    writeAnnotationList(node.annotations);
     writeStringReference(node.partUri);
   }
 
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 05f7f6f..c781398 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -37,7 +37,7 @@
     ]
   };
 
-  final LibraryIndex _index;
+  final LibraryIndex index;
 
   Library _coreLibrary;
   Class _objectClass;
@@ -98,309 +98,308 @@
   Library _mirrorsLibrary;
 
   CoreTypes(Component component)
-      : _index = new LibraryIndex.coreLibraries(component);
+      : index = new LibraryIndex.coreLibraries(component);
 
   Procedure get asyncErrorWrapperHelperProcedure {
     return _asyncErrorWrapperHelperProcedure ??=
-        _index.getTopLevelMember('dart:async', '_asyncErrorWrapperHelper');
+        index.getTopLevelMember('dart:async', '_asyncErrorWrapperHelper');
   }
 
   Library get asyncLibrary {
-    return _asyncLibrary ??= _index.getLibrary('dart:async');
+    return _asyncLibrary ??= index.getLibrary('dart:async');
   }
 
   Member get asyncStarStreamControllerAdd {
-    return _index.getMember('dart:async', '_AsyncStarStreamController', 'add');
+    return index.getMember('dart:async', '_AsyncStarStreamController', 'add');
   }
 
   Member get asyncStarStreamControllerAddError {
-    return _index.getMember(
+    return index.getMember(
         'dart:async', '_AsyncStarStreamController', 'addError');
   }
 
   Member get asyncStarStreamControllerAddStream {
-    return _index.getMember(
+    return index.getMember(
         'dart:async', '_AsyncStarStreamController', 'addStream');
   }
 
   Class get asyncStarStreamControllerClass {
-    return _index.getClass('dart:async', '_AsyncStarStreamController');
+    return index.getClass('dart:async', '_AsyncStarStreamController');
   }
 
   Member get asyncStarStreamControllerClose {
-    return _index.getMember(
-        'dart:async', '_AsyncStarStreamController', 'close');
+    return index.getMember('dart:async', '_AsyncStarStreamController', 'close');
   }
 
   Constructor get asyncStarStreamControllerDefaultConstructor {
     return _asyncStarStreamControllerDefaultConstructor ??=
-        _index.getMember('dart:async', '_AsyncStarStreamController', '');
+        index.getMember('dart:async', '_AsyncStarStreamController', '');
   }
 
   Member get asyncStarStreamControllerStream {
-    return _index.getMember(
+    return index.getMember(
         'dart:async', '_AsyncStarStreamController', 'get:stream');
   }
 
   Procedure get asyncStackTraceHelperProcedure {
     return _asyncStackTraceHelperProcedure ??=
-        _index.getTopLevelMember('dart:async', '_asyncStackTraceHelper');
+        index.getTopLevelMember('dart:async', '_asyncStackTraceHelper');
   }
 
   Procedure get asyncThenWrapperHelperProcedure {
     return _asyncThenWrapperHelperProcedure ??=
-        _index.getTopLevelMember('dart:async', '_asyncThenWrapperHelper');
+        index.getTopLevelMember('dart:async', '_asyncThenWrapperHelper');
   }
 
   Procedure get awaitHelperProcedure {
     return _awaitHelperProcedure ??=
-        _index.getTopLevelMember('dart:async', '_awaitHelper');
+        index.getTopLevelMember('dart:async', '_awaitHelper');
   }
 
   Class get boolClass {
-    return _boolClass ??= _index.getClass('dart:core', 'bool');
+    return _boolClass ??= index.getClass('dart:core', 'bool');
   }
 
   Class get completerClass {
-    return _completerClass ??= _index.getClass('dart:async', 'Completer');
+    return _completerClass ??= index.getClass('dart:async', 'Completer');
   }
 
   Class get asyncAwaitCompleterClass {
     return _asyncAwaitCompleterClass ??=
-        _index.getClass('dart:async', '_AsyncAwaitCompleter');
+        index.getClass('dart:async', '_AsyncAwaitCompleter');
   }
 
   Procedure get completerSyncConstructor {
     return _completerSyncConstructor ??=
-        _index.getMember('dart:async', 'Completer', 'sync');
+        index.getMember('dart:async', 'Completer', 'sync');
   }
 
   Constructor get asyncAwaitCompleterConstructor {
     return _asyncAwaitCompleterConstructor ??=
-        _index.getMember('dart:async', '_AsyncAwaitCompleter', '');
+        index.getMember('dart:async', '_AsyncAwaitCompleter', '');
   }
 
   Procedure get completerComplete {
     return _completerComplete ??=
-        _index.getMember('dart:async', 'Completer', 'complete');
+        index.getMember('dart:async', 'Completer', 'complete');
   }
 
   Procedure get completerCompleteError {
     return _completerCompleteError ??=
-        _index.getMember('dart:async', 'Completer', 'completeError');
+        index.getMember('dart:async', 'Completer', 'completeError');
   }
 
   Member get completerFuture {
-    return _index.getMember('dart:async', 'Completer', 'get:future');
+    return index.getMember('dart:async', 'Completer', 'get:future');
   }
 
   Library get coreLibrary {
-    return _coreLibrary ??= _index.getLibrary('dart:core');
+    return _coreLibrary ??= index.getLibrary('dart:core');
   }
 
   Class get doubleClass {
-    return _doubleClass ??= _index.getClass('dart:core', 'double');
+    return _doubleClass ??= index.getClass('dart:core', 'double');
   }
 
   Constructor get externalNameDefaultConstructor {
     return _externalNameDefaultConstructor ??=
-        _index.getMember('dart:_internal', 'ExternalName', '');
+        index.getMember('dart:_internal', 'ExternalName', '');
   }
 
   Class get functionClass {
-    return _functionClass ??= _index.getClass('dart:core', 'Function');
+    return _functionClass ??= index.getClass('dart:core', 'Function');
   }
 
   Class get futureClass {
-    return _futureClass ??= _index.getClass('dart:async', 'Future');
+    return _futureClass ??= index.getClass('dart:async', 'Future');
   }
 
   Procedure get futureMicrotaskConstructor {
     return _futureMicrotaskConstructor ??=
-        _index.getMember('dart:async', 'Future', 'microtask');
+        index.getMember('dart:async', 'Future', 'microtask');
   }
 
   Class get futureOrClass {
-    return _futureOrClass ??= _index.getClass('dart:async', 'FutureOr');
+    return _futureOrClass ??= index.getClass('dart:async', 'FutureOr');
   }
 
   Procedure get identicalProcedure {
     return _identicalProcedure ??=
-        _index.getTopLevelMember('dart:core', 'identical');
+        index.getTopLevelMember('dart:core', 'identical');
   }
 
   Class get intClass {
-    return _intClass ??= _index.getClass('dart:core', 'int');
+    return _intClass ??= index.getClass('dart:core', 'int');
   }
 
   Class get internalSymbolClass {
-    return _internalSymbolClass ??= _index.getClass('dart:_internal', 'Symbol');
+    return _internalSymbolClass ??= index.getClass('dart:_internal', 'Symbol');
   }
 
   Class get invocationClass {
-    return _invocationClass ??= _index.getClass('dart:core', 'Invocation');
+    return _invocationClass ??= index.getClass('dart:core', 'Invocation');
   }
 
   Class get invocationMirrorClass {
     return _invocationMirrorClass ??=
-        _index.getClass('dart:core', '_InvocationMirror');
+        index.getClass('dart:core', '_InvocationMirror');
   }
 
   Constructor get invocationMirrorWithTypeConstructor {
     return _invocationMirrorWithTypeConstructor ??=
-        _index.getMember('dart:core', '_InvocationMirror', '_withType');
+        index.getMember('dart:core', '_InvocationMirror', '_withType');
   }
 
   Constructor get invocationMirrorWithoutTypeConstructor {
     return _invocationMirrorWithoutTypeConstructor ??=
-        _index.getMember('dart:core', '_InvocationMirror', '_withoutType');
+        index.getMember('dart:core', '_InvocationMirror', '_withoutType');
   }
 
   Class get iterableClass {
-    return _iterableClass ??= _index.getClass('dart:core', 'Iterable');
+    return _iterableClass ??= index.getClass('dart:core', 'Iterable');
   }
 
   Class get iteratorClass {
-    return _iteratorClass ??= _index.getClass('dart:core', 'Iterator');
+    return _iteratorClass ??= index.getClass('dart:core', 'Iterator');
   }
 
   Class get listClass {
-    return _listClass ??= _index.getClass('dart:core', 'List');
+    return _listClass ??= index.getClass('dart:core', 'List');
   }
 
   Procedure get listFromConstructor {
     return _listFromConstructor ??=
-        _index.getMember('dart:core', 'List', 'from');
+        index.getMember('dart:core', 'List', 'from');
   }
 
   Class get mapClass {
-    return _mapClass ??= _index.getClass('dart:core', 'Map');
+    return _mapClass ??= index.getClass('dart:core', 'Map');
   }
 
   Procedure get mapUnmodifiable {
     return _mapUnmodifiable ??=
-        _index.getMember('dart:core', 'Map', 'unmodifiable');
+        index.getMember('dart:core', 'Map', 'unmodifiable');
   }
 
   Library get mirrorsLibrary {
-    return _mirrorsLibrary ??= _index.tryGetLibrary('dart:mirrors');
+    return _mirrorsLibrary ??= index.tryGetLibrary('dart:mirrors');
   }
 
   Class get noSuchMethodErrorClass {
     return _noSuchMethodErrorClass ??=
-        _index.getClass('dart:core', 'NoSuchMethodError');
+        index.getClass('dart:core', 'NoSuchMethodError');
   }
 
   Constructor get noSuchMethodErrorDefaultConstructor {
     return _noSuchMethodErrorDefaultConstructor ??=
         // TODO(regis): Replace 'withInvocation' with '' after dart2js is fixed.
-        _index.getMember('dart:core', 'NoSuchMethodError', 'withInvocation');
+        index.getMember('dart:core', 'NoSuchMethodError', 'withInvocation');
   }
 
   Class get nullClass {
-    return _nullClass ??= _index.getClass('dart:core', 'Null');
+    return _nullClass ??= index.getClass('dart:core', 'Null');
   }
 
   Class get numClass {
-    return _numClass ??= _index.getClass('dart:core', 'num');
+    return _numClass ??= index.getClass('dart:core', 'num');
   }
 
   Class get objectClass {
-    return _objectClass ??= _index.getClass('dart:core', 'Object');
+    return _objectClass ??= index.getClass('dart:core', 'Object');
   }
 
   Procedure get objectEquals {
-    return _objectEquals ??= _index.getMember('dart:core', 'Object', '==');
+    return _objectEquals ??= index.getMember('dart:core', 'Object', '==');
   }
 
   Procedure get printProcedure {
-    return _printProcedure ??= _index.getTopLevelMember('dart:core', 'print');
+    return _printProcedure ??= index.getTopLevelMember('dart:core', 'print');
   }
 
   Class get stackTraceClass {
-    return _stackTraceClass ??= _index.getClass('dart:core', 'StackTrace');
+    return _stackTraceClass ??= index.getClass('dart:core', 'StackTrace');
   }
 
   Class get streamClass {
-    return _streamClass ??= _index.getClass('dart:async', 'Stream');
+    return _streamClass ??= index.getClass('dart:async', 'Stream');
   }
 
   Member get streamIteratorSubscription {
-    return _index.getMember('dart:async', '_StreamIterator', '_subscription');
+    return index.getMember('dart:async', '_StreamIterator', '_subscription');
   }
 
   Member get streamIteratorCancel {
-    return _index.getMember('dart:async', '_StreamIterator', 'cancel');
+    return index.getMember('dart:async', '_StreamIterator', 'cancel');
   }
 
   Class get streamIteratorClass {
-    return _index.getClass('dart:async', '_StreamIterator');
+    return index.getClass('dart:async', '_StreamIterator');
   }
 
   Constructor get streamIteratorDefaultConstructor {
     return _streamIteratorDefaultConstructor ??=
-        _index.getMember('dart:async', '_StreamIterator', '');
+        index.getMember('dart:async', '_StreamIterator', '');
   }
 
   Member get streamIteratorMoveNext {
-    return _index.getMember('dart:async', '_StreamIterator', 'moveNext');
+    return index.getMember('dart:async', '_StreamIterator', 'moveNext');
   }
 
   Member get streamIteratorCurrent {
-    return _index.getMember('dart:async', '_StreamIterator', 'get:current');
+    return index.getMember('dart:async', '_StreamIterator', 'get:current');
   }
 
   Class get stringClass {
-    return _stringClass ??= _index.getClass('dart:core', 'String');
+    return _stringClass ??= index.getClass('dart:core', 'String');
   }
 
   Class get symbolClass {
-    return _symbolClass ??= _index.getClass('dart:core', 'Symbol');
+    return _symbolClass ??= index.getClass('dart:core', 'Symbol');
   }
 
   Constructor get syncIterableDefaultConstructor {
     return _syncIterableDefaultConstructor ??=
-        _index.getMember('dart:core', '_SyncIterable', '');
+        index.getMember('dart:core', '_SyncIterable', '');
   }
 
   Class get syncIteratorClass {
-    return _index.getClass('dart:core', '_SyncIterator');
+    return index.getClass('dart:core', '_SyncIterator');
   }
 
   Member get syncIteratorCurrent {
-    return _index.getMember('dart:core', '_SyncIterator', '_current');
+    return index.getMember('dart:core', '_SyncIterator', '_current');
   }
 
   Member get syncIteratorYieldEachIterable {
-    return _index.getMember('dart:core', '_SyncIterator', '_yieldEachIterable');
+    return index.getMember('dart:core', '_SyncIterator', '_yieldEachIterable');
   }
 
   Class get typeClass {
-    return _typeClass ??= _index.getClass('dart:core', 'Type');
+    return _typeClass ??= index.getClass('dart:core', 'Type');
   }
 
   Constructor get constantExpressionErrorDefaultConstructor {
     return _constantExpressionErrorDefaultConstructor ??=
-        _index.getMember('dart:core', '_ConstantExpressionError', '');
+        index.getMember('dart:core', '_ConstantExpressionError', '');
   }
 
   Member get constantExpressionErrorThrow {
     return _constantExpressionErrorThrow ??=
-        _index.getMember('dart:core', '_ConstantExpressionError', '_throw');
+        index.getMember('dart:core', '_ConstantExpressionError', '_throw');
   }
 
   Constructor get duplicatedFieldInitializerErrorDefaultConstructor {
     return _duplicatedFieldInitializerErrorDefaultConstructor ??=
-        _index.getMember('dart:core', '_DuplicatedFieldInitializerError', '');
+        index.getMember('dart:core', '_DuplicatedFieldInitializerError', '');
   }
 
   Constructor get fallThroughErrorUrlAndLineConstructor {
     return _fallThroughErrorUrlAndLineConstructor ??=
-        _index.getMember('dart:core', 'FallThroughError', '_create');
+        index.getMember('dart:core', 'FallThroughError', '_create');
   }
 
   Constructor get compileTimeErrorDefaultConstructor {
     return _compileTimeErrorDefaultConstructor ??=
-        _index.getMember('dart:core', '_CompileTimeError', '');
+        index.getMember('dart:core', '_CompileTimeError', '');
   }
 }
diff --git a/pkg/status_file/test/data/co19-dart2js.status b/pkg/status_file/test/data/co19-dart2js.status
index 438316b..26e58ff 100644
--- a/pkg/status_file/test/data/co19-dart2js.status
+++ b/pkg/status_file/test/data/co19-dart2js.status
@@ -1367,6 +1367,7 @@
 LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/table/nested-tables-with-div-offset_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/resize-table-cell_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # Please triage this failure
diff --git a/pkg/telemetry/test/crash_reporting_test.dart b/pkg/telemetry/test/crash_reporting_test.dart
index c4e812d..a61e1b4 100644
--- a/pkg/telemetry/test/crash_reporting_test.dart
+++ b/pkg/telemetry/test/crash_reporting_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
 
 import 'package:http/http.dart';
 import 'package:http/testing.dart';
@@ -31,7 +31,7 @@
 
       await sender.sendReport('test-error', stackTrace: StackTrace.current);
 
-      String body = UTF8.decode(request.bodyBytes);
+      String body = utf8.decode(request.bodyBytes);
       expect(body, contains('String')); // error.runtimeType
       expect(body, contains(analytics.trackingId));
       expect(body, contains('1.0.0'));
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 84a8c4f..026a99e 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -14,7 +14,7 @@
 import 'package:front_end/src/api_prototype/compilation_message.dart'
     show CompilationMessage, Severity;
 import 'package:front_end/src/fasta/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show Component;
+import 'package:kernel/ast.dart' show Component, StaticGet, Field;
 import 'package:kernel/core_types.dart' show CoreTypes;
 
 import 'transformations/devirtualization.dart' as devirtualization
@@ -59,6 +59,8 @@
   if (strongMode) {
     final coreTypes = new CoreTypes(component);
 
+    _patchVmConstants(coreTypes);
+
     // TODO(alexmarkov, dmitryas): Consider doing canonicalization of identical
     // mixin applications when creating mixin applications in frontend,
     // so all backends (and all transformation passes from the very beginning)
@@ -77,6 +79,21 @@
   }
 }
 
+void _patchVmConstants(CoreTypes coreTypes) {
+  // Fix Endian.host to be a const field equal to Endial.little instead of
+  // a final field. VM does not support big-endian architectures at the
+  // moment.
+  // Can't use normal patching process for this because CFE does not
+  // support patching fields.
+  // See http://dartbug.com/32836 for the background.
+  final Field host =
+      coreTypes.index.getMember('dart:typed_data', 'Endian', 'host');
+  host.isConst = true;
+  host.initializer = new StaticGet(
+      coreTypes.index.getMember('dart:typed_data', 'Endian', 'little'))
+    ..parent = host;
+}
+
 class ErrorDetector {
   final ErrorHandler previousErrorHandler;
   bool hasCompilationErrors = false;
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index de52abf..4d0804b 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, 0);
+  zx_status_t status = zx_port_queue(port_handle_, &pkt, 1);
   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, 0);
+                                      &pkt, 1);
     if (status == ZX_ERR_TIMED_OUT) {
       handler_impl->HandleTimeout();
     } else if (status != ZX_OK) {
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 145e48b..0d475e9 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1345,8 +1345,8 @@
   ASSERT(Dart_IsServiceIsolate(isolate));
   // Load embedder specific bits and return. Will not start http server.
   if (!VmService::Setup("127.0.0.1", -1, false /* running_precompiled */,
-                        false /* server dev mode */,
-                        false /* trace_loading */)) {
+                        false /* server dev mode */, false /* trace_loading */,
+                        true /* deterministic */)) {
     *error = strdup(VmService::GetErrorMessage());
     return NULL;
   }
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 4e330cf..d8bbc6f 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -473,7 +473,7 @@
   if (!VmService::Setup(Options::vm_service_server_ip(),
                         Options::vm_service_server_port(), skip_library_load,
                         Options::vm_service_dev_mode(),
-                        Options::trace_loading())) {
+                        Options::trace_loading(), Options::deterministic())) {
     *error = strdup(VmService::GetErrorMessage());
     return NULL;
   }
@@ -801,6 +801,7 @@
     {"dart:_builtin", "::", "_loadPort"},
     {"dart:_internal", "::", "_printClosure"},
     {"dart:vmservice_io", "::", "_autoStart"},
+    {"dart:vmservice_io", "::", "_deterministic"},
     {"dart:vmservice_io", "::", "_ip"},
     {"dart:vmservice_io", "::", "_isFuchsia"},
     {"dart:vmservice_io", "::", "_isWindows"},
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index a002959..df3ec97 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -396,6 +396,11 @@
     }
   }
 
+  if (Options::deterministic()) {
+    // Both an embedder and VM flag.
+    vm_options->AddArgument("--deterministic");
+  }
+
   Socket::set_short_socket_read(Options::short_socket_read());
   Socket::set_short_socket_write(Options::short_socket_write());
 #if !defined(DART_IO_SECURE_SOCKET_DISABLED)
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 793d3d8..80a4579 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -35,6 +35,7 @@
   V(compile_all, compile_all)                                                  \
   V(parse_all, parse_all)                                                      \
   V(disable_service_origin_check, vm_service_dev_mode)                         \
+  V(deterministic, deterministic)                                              \
   V(use_blobs, use_blobs)                                                      \
   V(obfuscate, obfuscate)                                                      \
   V(trace_loading, trace_loading)                                              \
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
index 30fb896..43f01ca 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, 0);
+    zx_status_t status = zx_port_queue(port_, &pkt, 1);
     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, 0);
+      zx_status_t status = zx_port_wait(port_, ZX_TIME_INFINITE, &pkt, 1);
       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, 0);
+    status = zx_port_wait(port, ZX_TIME_INFINITE, &pkt, 1);
     if (status != ZX_OK) {
       Log::PrintErr("Process::Wait: zx_port_wait failed: %s\n",
                     zx_status_get_string(status));
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index 20bd3fd..81d9529 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -63,6 +63,7 @@
 }
 
 bool _traceLoading = false;
+bool _deterministic = false;
 
 // State associated with the isolate that is used for loading.
 class IsolateLoaderState extends IsolateEmbedderData {
@@ -137,7 +138,7 @@
   // We issue only 16 concurrent calls to File.readAsBytes() to stay within
   // platform-specific resource limits (e.g. max open files). The rest go on
   // _fileRequestQueue and are processed when we can safely issue them.
-  static const int _maxFileRequests = 16;
+  static final int _maxFileRequests = _deterministic ? 1 : 16;
   int currentFileRequests = 0;
   final List<FileRequest> _fileRequestQueue = new List<FileRequest>();
 
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 82cf820..621b3f5 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -174,7 +174,8 @@
                       intptr_t server_port,
                       bool running_precompiled,
                       bool dev_mode_server,
-                      bool trace_loading) {
+                      bool trace_loading,
+                      bool deterministic) {
   Dart_Isolate isolate = Dart_CurrentIsolate();
   ASSERT(isolate != NULL);
   SetServerAddress("");
@@ -267,6 +268,12 @@
     SHUTDOWN_ON_ERROR(result);
   }
 
+  if (deterministic) {
+    result = Dart_SetField(library, DartUtils::NewString("_deterministic"),
+                           Dart_True());
+    SHUTDOWN_ON_ERROR(result);
+  }
+
   // Get _getWatchSignalInternal from dart:io.
   Dart_Handle dart_io_str = Dart_NewStringFromCString(DartUtils::kIOLibURL);
   SHUTDOWN_ON_ERROR(dart_io_str);
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h
index e9baab4..2dc00d0 100644
--- a/runtime/bin/vmservice_impl.h
+++ b/runtime/bin/vmservice_impl.h
@@ -20,7 +20,8 @@
                     intptr_t server_port,
                     bool running_precompiled,
                     bool dev_mode_server,
-                    bool trace_loading);
+                    bool trace_loading,
+                    bool deterministic);
 
   // Error message if startup failed.
   static const char* GetErrorMessage();
diff --git a/runtime/lib/bigint_patch.dart b/runtime/lib/bigint_patch.dart
index 5fc7a32..7516712 100644
--- a/runtime/lib/bigint_patch.dart
+++ b/runtime/lib/bigint_patch.dart
@@ -2307,7 +2307,7 @@
     var resultBits = new Uint8List(8);
 
     var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
-    if (length - 53 > maxDoubleExponent) return double.INFINITY;
+    if (length - 53 > maxDoubleExponent) return double.infinity;
 
     // The most significant bit is for the sign.
     if (_isNegative) resultBits[7] = 0x80;
diff --git a/runtime/lib/typed_data_patch.dart b/runtime/lib/typed_data_patch.dart
index 7e4e9cf..83a4f54 100644
--- a/runtime/lib/typed_data_patch.dart
+++ b/runtime/lib/typed_data_patch.dart
@@ -4216,7 +4216,7 @@
     _typedData._setUint8(_offset + byteOffset, value);
   }
 
-  int getInt16(int byteOffset, [Endianness endian = Endian.big]) {
+  int getInt16(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 1 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
     }
@@ -4227,7 +4227,7 @@
     return _byteSwap16(result).toSigned(16);
   }
 
-  void setInt16(int byteOffset, int value, [Endianness endian = Endian.big]) {
+  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 1 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
     }
@@ -4235,7 +4235,7 @@
         identical(endian, Endian.host) ? value : _byteSwap16(value));
   }
 
-  int getUint16(int byteOffset, [Endianness endian = Endian.big]) {
+  int getUint16(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 1 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
     }
@@ -4246,7 +4246,7 @@
     return _byteSwap16(result);
   }
 
-  void setUint16(int byteOffset, int value, [Endianness endian = Endian.big]) {
+  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 1 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
     }
@@ -4254,7 +4254,7 @@
         identical(endian, Endian.host) ? value : _byteSwap16(value));
   }
 
-  int getInt32(int byteOffset, [Endianness endian = Endian.big]) {
+  int getInt32(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 3 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
     }
@@ -4265,7 +4265,7 @@
     return _byteSwap32(result).toSigned(32);
   }
 
-  void setInt32(int byteOffset, int value, [Endianness endian = Endian.big]) {
+  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 3 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
     }
@@ -4273,7 +4273,7 @@
         identical(endian, Endian.host) ? value : _byteSwap32(value));
   }
 
-  int getUint32(int byteOffset, [Endianness endian = Endian.big]) {
+  int getUint32(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 3 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
     }
@@ -4284,7 +4284,7 @@
     return _byteSwap32(result);
   }
 
-  void setUint32(int byteOffset, int value, [Endianness endian = Endian.big]) {
+  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 3 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
     }
@@ -4292,7 +4292,7 @@
         identical(endian, Endian.host) ? value : _byteSwap32(value));
   }
 
-  int getInt64(int byteOffset, [Endianness endian = Endian.big]) {
+  int getInt64(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 7 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
     }
@@ -4303,7 +4303,7 @@
     return _byteSwap64(result).toSigned(64);
   }
 
-  void setInt64(int byteOffset, int value, [Endianness endian = Endian.big]) {
+  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 7 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
     }
@@ -4311,7 +4311,7 @@
         identical(endian, Endian.host) ? value : _byteSwap64(value));
   }
 
-  int getUint64(int byteOffset, [Endianness endian = Endian.big]) {
+  int getUint64(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 7 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
     }
@@ -4322,7 +4322,7 @@
     return _byteSwap64(result);
   }
 
-  void setUint64(int byteOffset, int value, [Endianness endian = Endian.big]) {
+  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 7 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
     }
@@ -4330,7 +4330,7 @@
         identical(endian, Endian.host) ? value : _byteSwap64(value));
   }
 
-  double getFloat32(int byteOffset, [Endianness endian = Endian.big]) {
+  double getFloat32(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 3 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
     }
@@ -4341,8 +4341,7 @@
     return _convF32[0];
   }
 
-  void setFloat32(int byteOffset, double value,
-      [Endianness endian = Endian.big]) {
+  void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 3 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
     }
@@ -4354,7 +4353,7 @@
     _typedData._setUint32(_offset + byteOffset, _byteSwap32(_convU32[0]));
   }
 
-  double getFloat64(int byteOffset, [Endianness endian = Endian.big]) {
+  double getFloat64(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 7 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
     }
@@ -4365,8 +4364,7 @@
     return _convF64[0];
   }
 
-  void setFloat64(int byteOffset, double value,
-      [Endianness endian = Endian.big]) {
+  void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 7 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
     }
@@ -4378,7 +4376,7 @@
     _typedData._setUint64(_offset + byteOffset, _byteSwap64(_convU64[0]));
   }
 
-  Float32x4 getFloat32x4(int byteOffset, [Endianness endian = Endian.big]) {
+  Float32x4 getFloat32x4(int byteOffset, [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 3 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
     }
@@ -4387,7 +4385,7 @@
   }
 
   void setFloat32x4(int byteOffset, Float32x4 value,
-      [Endianness endian = Endian.big]) {
+      [Endian endian = Endian.big]) {
     if (byteOffset < 0 || byteOffset + 3 >= length) {
       throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
     }
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index 892ebee..d023f6e 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -183,7 +183,7 @@
   Map _parseJSON(String message) {
     var map;
     try {
-      map = JSON.decode(message);
+      map = json.decode(message);
     } catch (e, st) {
       Logger.root.severe('Disconnecting: Error decoding message: $e\n$st');
       disconnect(reason: 'Connection saw corrupt JSON message: $e');
@@ -202,8 +202,8 @@
       // See format spec. in VMs Service::SendEvent.
       int offset = 0;
       // Dart2JS workaround (no getUint64). Limit to 4 GB metadata.
-      assert(bytes.getUint32(offset, Endianness.BIG_ENDIAN) == 0);
-      int metaSize = bytes.getUint32(offset + 4, Endianness.BIG_ENDIAN);
+      assert(bytes.getUint32(offset, Endian.big) == 0);
+      int metaSize = bytes.getUint32(offset + 4, Endian.big);
       offset += 8;
       var meta = _utf8Decoder.convert(new Uint8List.view(
           bytes.buffer, bytes.offsetInBytes + offset, metaSize));
@@ -315,13 +315,13 @@
     var message;
     // Encode message.
     if (target.chrome) {
-      message = JSON.encode({
+      message = json.encode({
         'id': int.parse(serial),
         'method': 'Dart.observatoryQuery',
         'params': {'id': serial, 'query': request.method}
       });
     } else {
-      message = JSON.encode(
+      message = json.encode(
           {'id': serial, 'method': request.method, 'params': request.params});
     }
     if (request.method != 'getTagProfile' &&
diff --git a/runtime/observatory/lib/src/app/settings.dart b/runtime/observatory/lib/src/app/settings.dart
index 32339d0..da6d8a8 100644
--- a/runtime/observatory/lib/src/app/settings.dart
+++ b/runtime/observatory/lib/src/app/settings.dart
@@ -10,7 +10,7 @@
 
   /// Associated [value] with [key]. [value] must be JSON encodable.
   static void set(String key, dynamic value) {
-    _storage[key] = JSON.encode(value);
+    _storage[key] = json.encode(value);
   }
 
   /// Get value associated with [key]. Return value will be a JSON encodable
@@ -20,7 +20,7 @@
     if (value == null) {
       return null;
     }
-    return JSON.decode(value);
+    return json.decode(value);
   }
 }
 
diff --git a/runtime/observatory/lib/src/elements/timeline/dashboard.dart b/runtime/observatory/lib/src/elements/timeline/dashboard.dart
index 3217f0e..bfa7f57 100644
--- a/runtime/observatory/lib/src/elements/timeline/dashboard.dart
+++ b/runtime/observatory/lib/src/elements/timeline/dashboard.dart
@@ -223,7 +223,7 @@
       [Map<String, dynamic> params = const <String, dynamic>{}]) async {
     var message = {'method': method, 'params': params};
     _frame.contentWindow
-        .postMessage(JSON.encode(message), window.location.href);
+        .postMessage(json.encode(message), window.location.href);
     return null;
   }
 }
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
index 8e63126..a751329 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.dart
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -204,7 +204,7 @@
       [Map<String, dynamic> params = const <String, dynamic>{}]) async {
     var message = {'method': method, 'params': params};
     _frame.contentWindow
-        .postMessage(JSON.encode(message), window.location.href);
+        .postMessage(json.encode(message), window.location.href);
     return null;
   }
 
diff --git a/runtime/observatory/lib/src/elements/vm_connect.dart b/runtime/observatory/lib/src/elements/vm_connect.dart
index cdf5fd7..30dd852 100644
--- a/runtime/observatory/lib/src/elements/vm_connect.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect.dart
@@ -165,7 +165,7 @@
       var reader = new FileReader();
       reader.readAsText(e.files[0]);
       reader.onLoad.listen((_) {
-        var crashDump = JSON.decode(reader.result);
+        var crashDump = json.decode(reader.result);
         _loadDump(crashDump);
       });
     });
diff --git a/runtime/observatory/lib/src/repositories/settings.dart b/runtime/observatory/lib/src/repositories/settings.dart
index 4121d93..5cfffc0 100644
--- a/runtime/observatory/lib/src/repositories/settings.dart
+++ b/runtime/observatory/lib/src/repositories/settings.dart
@@ -10,7 +10,7 @@
 
   /// Associated [value] with [key]. [value] must be JSON encodable.
   static void set(String key, dynamic value) {
-    _storage[key] = JSON.encode(value);
+    _storage[key] = json.encode(value);
   }
 
   /// Get value associated with [key]. Return value will be a JSON encodable
@@ -20,7 +20,7 @@
     if (value == null) {
       return null;
     }
-    return JSON.decode(value);
+    return json.decode(value);
   }
 }
 
diff --git a/runtime/observatory/lib/src/sample_profile/sample_profile.dart b/runtime/observatory/lib/src/sample_profile/sample_profile.dart
index a116563..569d4e3 100644
--- a/runtime/observatory/lib/src/sample_profile/sample_profile.dart
+++ b/runtime/observatory/lib/src/sample_profile/sample_profile.dart
@@ -862,7 +862,7 @@
 
         sampleCount = profile['sampleCount'];
         samplePeriod = profile['samplePeriod'];
-        sampleRate = (Duration.MICROSECONDS_PER_SECOND / samplePeriod);
+        sampleRate = (Duration.microsecondsPerSecond / samplePeriod);
         stackDepth = profile['stackDepth'];
         timeSpan = profile['timeSpan'];
 
@@ -1084,10 +1084,10 @@
   }
 
   int approximateMillisecondsForCount(count) {
-    return (count * samplePeriod) ~/ Duration.MICROSECONDS_PER_MILLISECOND;
+    return (count * samplePeriod) ~/ Duration.microsecondsPerMillisecond;
   }
 
   double approximateSecondsForCount(count) {
-    return (count * samplePeriod) / Duration.MICROSECONDS_PER_SECOND;
+    return (count * samplePeriod) / Duration.microsecondsPerSecond;
   }
 }
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 76e3487..a10cfaa 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1261,19 +1261,19 @@
 
   Duration get avgCollectionTime {
     final mcs = totalCollectionTimeInSeconds *
-        Duration.MICROSECONDS_PER_SECOND /
+        Duration.microsecondsPerSecond /
         math.max(collections, 1);
     return new Duration(microseconds: mcs.ceil());
   }
 
   Duration get totalCollectionTime {
-    final mcs = totalCollectionTimeInSeconds * Duration.MICROSECONDS_PER_SECOND;
+    final mcs = totalCollectionTimeInSeconds * Duration.microsecondsPerSecond;
     return new Duration(microseconds: mcs.ceil());
   }
 
   Duration get avgCollectionPeriod {
     final mcs =
-        averageCollectionPeriodInMillis * Duration.MICROSECONDS_PER_MILLISECOND;
+        averageCollectionPeriodInMillis * Duration.microsecondsPerMillisecond;
     return new Duration(microseconds: mcs.ceil());
   }
 
@@ -2256,8 +2256,8 @@
       exceptions = map['_debuggerSettings']['_exceptions'];
     }
     if (map['bytes'] != null) {
-      var bytes = BASE64.decode(map['bytes']);
-      bytesAsString = UTF8.decode(bytes);
+      var bytes = base64Decode(map['bytes']);
+      bytesAsString = utf8.decode(bytes);
     }
     if (map['logRecord'] != null) {
       logRecord = map['logRecord'];
@@ -2922,7 +2922,7 @@
     }
     ;
     if (map['bytes'] != null) {
-      Uint8List bytes = BASE64.decode(map['bytes']);
+      Uint8List bytes = base64Decode(map['bytes']);
       switch (map['kind']) {
         case "Uint8ClampedList":
           typedElements = bytes.buffer.asUint8ClampedList();
diff --git a/runtime/observatory/lib/utils.dart b/runtime/observatory/lib/utils.dart
index f65c1a1..4957014 100644
--- a/runtime/observatory/lib/utils.dart
+++ b/runtime/observatory/lib/utils.dart
@@ -157,19 +157,19 @@
     var value = duration.inMicroseconds.abs();
     switch (precision) {
       case DurationComponent.Days:
-        value = (value / Duration.MICROSECONDS_PER_DAY).round();
+        value = (value / Duration.microsecondsPerDay).round();
         break;
       case DurationComponent.Hours:
-        value = (value / Duration.MICROSECONDS_PER_HOUR).round();
+        value = (value / Duration.microsecondsPerHour).round();
         break;
       case DurationComponent.Minutes:
-        value = (value / Duration.MICROSECONDS_PER_MINUTE).round();
+        value = (value / Duration.microsecondsPerMinute).round();
         break;
       case DurationComponent.Seconds:
-        value = (value / Duration.MICROSECONDS_PER_SECOND).round();
+        value = (value / Duration.microsecondsPerSecond).round();
         break;
       case DurationComponent.Milliseconds:
-        value = (value / Duration.MICROSECONDS_PER_MILLISECOND).round();
+        value = (value / Duration.microsecondsPerMillisecond).round();
         break;
       case DurationComponent.Microseconds:
         break;
@@ -186,24 +186,24 @@
     }
     switch (precision) {
       case DurationComponent.Microseconds:
-        components.add('${value % Duration.MICROSECONDS_PER_MILLISECOND}μs');
-        value = (value / Duration.MICROSECONDS_PER_MILLISECOND).floor();
+        components.add('${value % Duration.microsecondsPerMillisecond}μs');
+        value = (value / Duration.microsecondsPerMillisecond).floor();
         if (value != 0) {
           continue Milliseconds;
         }
         break;
       Milliseconds:
       case DurationComponent.Milliseconds:
-        components.add('${value % Duration.MILLISECONDS_PER_SECOND}ms');
-        value = (value / Duration.MILLISECONDS_PER_SECOND).floor();
+        components.add('${value % Duration.millisecondsPerSecond}ms');
+        value = (value / Duration.millisecondsPerSecond).floor();
         if (value != 0) {
           continue Seconds;
         }
         break;
       Seconds:
       case DurationComponent.Seconds:
-        components.add('${value % Duration.SECONDS_PER_MINUTE}s');
-        value = (value / Duration.SECONDS_PER_MINUTE).floor();
+        components.add('${value % Duration.secondsPerMinute}s');
+        value = (value / Duration.secondsPerMinute).floor();
         ;
         if (value != 0) {
           continue Minutes;
@@ -211,16 +211,16 @@
         break;
       Minutes:
       case DurationComponent.Minutes:
-        components.add('${value % Duration.MINUTES_PER_HOUR}m');
-        value = (value / Duration.MINUTES_PER_HOUR).floor();
+        components.add('${value % Duration.minutesPerHour}m');
+        value = (value / Duration.minutesPerHour).floor();
         if (value != 0) {
           continue Hours;
         }
         break;
       Hours:
       case DurationComponent.Hours:
-        components.add('${value % Duration.HOURS_PER_DAY}h');
-        value = (value / Duration.HOURS_PER_DAY).floor();
+        components.add('${value % Duration.hoursPerDay}h');
+        value = (value / Duration.hoursPerDay).floor();
         if (value != 0) {
           continue Days;
         }
@@ -241,10 +241,10 @@
   }
 
   static String formatDurationInSeconds(Duration x) =>
-      formatSeconds(x.inMicroseconds / Duration.MICROSECONDS_PER_SECOND);
+      formatSeconds(x.inMicroseconds / Duration.microsecondsPerSecond);
 
   static String formatDurationInMilliseconds(Duration x) =>
-      formatMillis(x.inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND);
+      formatMillis(x.inMicroseconds / Duration.microsecondsPerMillisecond);
 
   static bool runningInJavaScript() => identical(1.0, 1);
 
@@ -299,7 +299,7 @@
       // Already scheduled.
       return;
     }
-    _timer = new Timer(Duration.ZERO, () {
+    _timer = new Timer(Duration.zero, () {
       _timer = null;
       callback();
     });
diff --git a/runtime/observatory/tests/service/crash_dump_test.dart b/runtime/observatory/tests/service/crash_dump_test.dart
index 4d56ccc..2309c94 100644
--- a/runtime/observatory/tests/service/crash_dump_test.dart
+++ b/runtime/observatory/tests/service/crash_dump_test.dart
@@ -25,11 +25,11 @@
     print('Received response');
     Completer completer = new Completer<String>();
     StringBuffer sb = new StringBuffer();
-    response.transform(UTF8.decoder).listen((chunk) {
+    response.transform(utf8.decoder).listen((chunk) {
       sb.write(chunk);
     }, onDone: () => completer.complete(sb.toString()));
     var responseString = await completer.future;
-    JSON.decode(responseString);
+    json.decode(responseString);
   }
 ];
 
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
index 9d7a45b..4ed4172 100644
--- a/runtime/observatory/tests/service/dev_fs_http_put_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
@@ -13,7 +13,7 @@
 Future<String> readResponse(HttpClientResponse response) {
   var completer = new Completer<String>();
   var contents = new StringBuffer();
-  response.transform(UTF8.decoder).listen((String data) {
+  response.transform(utf8.decoder).listen((String data) {
     contents.write(data);
   }, onDone: () => completer.complete(contents.toString()));
   return completer.future;
@@ -25,7 +25,7 @@
     var fsId = 'test';
     var filePath = '/foo/bar.dat';
     var fileContents = [0, 1, 2, 3, 4, 5, 6, 255];
-    var fileContentsBase64 = BASE64.encode(fileContents);
+    var fileContentsBase64 = base64Encode(fileContents);
 
     var result;
     // Create DevFS.
@@ -43,7 +43,7 @@
     request.add(GZIP.encode([9]));
     HttpClientResponse response = await request.close();
     String responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     expect(result['result']['type'], equals('Success'));
 
     // Trigger an error by issuing an HTTP PUT.
@@ -53,7 +53,7 @@
     request.write(GZIP.encode(fileContents));
     response = await request.close();
     responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     Map error = result['error']['data'];
     expect(error, isNotNull);
     expect(error['details'].contains("expects the 'path' parameter"), isTrue);
@@ -66,7 +66,7 @@
     request.add(GZIP.encode(fileContents));
     response = await request.close();
     responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     expect(result['result']['type'], equals('Success'));
 
     // Close the HTTP client.
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
index ea8c92f..ed4c886 100644
--- a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
@@ -13,7 +13,7 @@
 Future<String> readResponse(HttpClientResponse response) {
   var completer = new Completer<String>();
   var contents = new StringBuffer();
-  response.transform(UTF8.decoder).listen((String data) {
+  response.transform(utf8.decoder).listen((String data) {
     contents.write(data);
   }, onDone: () => completer.complete(contents.toString()));
   return completer.future;
@@ -24,9 +24,9 @@
   (VM vm) async {
     var fsId = 'test';
     var filePath = '/foo/b\rar.dart';
-    var filePathBase64 = BASE64.encode(UTF8.encode(filePath));
+    var filePathBase64 = base64Encode(utf8.encode(filePath));
     var fileContents = [0, 1, 2, 3, 4, 5, 6, 255];
-    var fileContentsBase64 = BASE64.encode(fileContents);
+    var fileContentsBase64 = base64Encode(fileContents);
 
     var result;
     // Create DevFS.
@@ -44,7 +44,7 @@
     request.add(GZIP.encode([9]));
     HttpClientResponse response = await request.close();
     String responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     expect(result['result']['type'], equals('Success'));
 
     // Trigger an error by issuing an HTTP PUT.
@@ -54,7 +54,7 @@
     request.write(GZIP.encode(fileContents));
     response = await request.close();
     responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     Map error = result['error']['data'];
     expect(error, isNotNull);
     expect(error['details'].contains("expects the 'path' parameter"), isTrue);
@@ -67,7 +67,7 @@
     request.add(GZIP.encode(fileContents));
     response = await request.close();
     responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     expect(result['result']['type'], equals('Success'));
 
     // Close the HTTP client.
diff --git a/runtime/observatory/tests/service/dev_fs_spawn_test.dart b/runtime/observatory/tests/service/dev_fs_spawn_test.dart
index 1ed42cf..9a741fc 100644
--- a/runtime/observatory/tests/service/dev_fs_spawn_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_spawn_test.dart
@@ -102,7 +102,7 @@
 
     // Write three scripts to the fs.
     for (int i = 0; i < 3; i++) {
-      var fileContents = BASE64.encode(UTF8.encode(scripts[i]));
+      var fileContents = base64Encode(utf8.encode(scripts[i]));
       result = await vm.invokeRpcNoUpgrade('_writeDevFSFile', {
         'fsName': fsName,
         'path': filePaths[i],
diff --git a/runtime/observatory/tests/service/dev_fs_test.dart b/runtime/observatory/tests/service/dev_fs_test.dart
index 2349977..abe80cc 100644
--- a/runtime/observatory/tests/service/dev_fs_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_test.dart
@@ -56,7 +56,7 @@
   (VM vm) async {
     var fsId = 'banana';
     var filePath = '/foo/bar.dat';
-    var fileContents = BASE64.encode(UTF8.encode('fileContents'));
+    var fileContents = base64Encode(utf8.encode('fileContents'));
 
     var result;
     // Create DevFS.
@@ -119,8 +119,8 @@
     result = await vm.invokeRpcNoUpgrade('_writeDevFSFiles', {
       'fsName': fsId,
       'files': [
-        ['/a', BASE64.encode(UTF8.encode('a_contents'))],
-        ['/b', BASE64.encode(UTF8.encode('b_contents'))]
+        ['/a', base64Encode(utf8.encode('a_contents'))],
+        ['/b', base64Encode(utf8.encode('b_contents'))]
       ]
     });
     expect(result['type'], equals('Success'));
@@ -132,7 +132,7 @@
     });
     expect(result['type'], equals('FSFile'));
     expect(result['fileContents'],
-        equals(BASE64.encode(UTF8.encode('b_contents'))));
+        equals(base64Encode(utf8.encode('b_contents'))));
 
     // List all the files in the file system.
     result = await vm.invokeRpcNoUpgrade('_listDevFSFiles', {
diff --git a/runtime/observatory/tests/service/dev_fs_uri_test.dart b/runtime/observatory/tests/service/dev_fs_uri_test.dart
index 201ea14..0b6643a 100644
--- a/runtime/observatory/tests/service/dev_fs_uri_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_uri_test.dart
@@ -13,7 +13,7 @@
 Future<String> readResponse(HttpClientResponse response) {
   var completer = new Completer<String>();
   var contents = new StringBuffer();
-  response.transform(UTF8.decoder).listen((String data) {
+  response.transform(utf8.decoder).listen((String data) {
     contents.write(data);
   }, onDone: () => completer.complete(contents.toString()));
   return completer.future;
@@ -26,9 +26,9 @@
     // NOTE: When using the URI encoding scheme, paths cannot be absolute.
     var filePath = 'foo/bar.dat';
     var fileUri = Uri.parse(filePath);
-    var fileUriBase64 = BASE64.encode(UTF8.encode(fileUri.toString()));
+    var fileUriBase64 = base64Encode(utf8.encode(fileUri.toString()));
     var fileContents = [0, 1, 2, 3, 4, 5, 6, 255];
-    var fileContentsBase64 = BASE64.encode(fileContents);
+    var fileContentsBase64 = base64Encode(fileContents);
 
     var filePath2 = 'baz/boo.dat';
     var fileUri2 = Uri.parse(filePath2);
@@ -49,7 +49,7 @@
     request.add(GZIP.encode([9]));
     HttpClientResponse response = await request.close();
     String responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     print(result);
     expect(result['result']['type'], equals('Success'));
 
@@ -60,7 +60,7 @@
     request.write(GZIP.encode(fileContents));
     response = await request.close();
     responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     Map error = result['error']['data'];
     expect(error, isNotNull);
     expect(error['details'].contains("expects the 'path' parameter"), isTrue);
@@ -73,7 +73,7 @@
     request.add(GZIP.encode(fileContents));
     response = await request.close();
     responseBody = await readResponse(response);
-    result = JSON.decode(responseBody);
+    result = jsonDecode(responseBody);
     expect(result['result']['type'], equals('Success'));
 
     // Close the HTTP client.
diff --git a/runtime/observatory/tests/service/dev_fs_weird_char_test.dart b/runtime/observatory/tests/service/dev_fs_weird_char_test.dart
index 48c15c3..ce99969 100644
--- a/runtime/observatory/tests/service/dev_fs_weird_char_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_weird_char_test.dart
@@ -13,7 +13,7 @@
   (VM vm) async {
     var fsId = 'test';
     var filePath = '/foo/bar?dat';
-    var fileContents = BASE64.encode(UTF8.encode('fileContents'));
+    var fileContents = base64Encode(utf8.encode('fileContents'));
 
     var result;
     // Create DevFS.
diff --git a/runtime/observatory/tests/service/developer_extension_test.dart b/runtime/observatory/tests/service/developer_extension_test.dart
index 072378e..f128f93 100644
--- a/runtime/observatory/tests/service/developer_extension_test.dart
+++ b/runtime/observatory/tests/service/developer_extension_test.dart
@@ -19,7 +19,7 @@
     case 'ext..delay':
       Completer c = new Completer();
       new Timer(new Duration(seconds: 1), () {
-        c.complete(new ServiceExtensionResponse.result(JSON.encode({
+        c.complete(new ServiceExtensionResponse.result(jsonEncode({
             'type': '_delayedType',
             'method': method,
             'parameters': paremeters,
@@ -35,7 +35,7 @@
       throw "I always throw!";
     case 'ext..success':
       return new Future.value(
-          new ServiceExtensionResponse.result(JSON.encode({
+          new ServiceExtensionResponse.result(jsonEncode({
               'type': '_extensionType',
               'method': method,
               'parameters': paremeters,
diff --git a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
index a6860b9..c467159 100644
--- a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
@@ -7,7 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
 import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:async' show Future, Stream, StreamController;
 
 var tests = <IsolateTest>[
@@ -23,10 +23,10 @@
     final socket = new StreamController();
 
     // Avoid to manually encode and decode messages from the stream
-    Stream<String> stream = socket.stream.map(JSON.encode);
+    Stream<String> stream = socket.stream.map(jsonEncode);
     stream.retype<Object>().pipe(_socket);
     dynamic _decoder(dynamic obj) {
-      return JSON.decode(obj);
+      return jsonDecode(obj);
     }
 
     final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_disappear_test.dart b/runtime/observatory/tests/service/external_service_disappear_test.dart
index 8199de2..9e9931e 100644
--- a/runtime/observatory/tests/service/external_service_disappear_test.dart
+++ b/runtime/observatory/tests/service/external_service_disappear_test.dart
@@ -7,7 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
 import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:async' show Future, Stream, StreamController;
 
 var tests = <IsolateTest>[
@@ -23,10 +23,10 @@
     final socket = new StreamController();
 
     // Avoid to manually encode and decode messages from the stream
-    Stream<String> stream = socket.stream.map(JSON.encode);
+    Stream<String> stream = socket.stream.map(jsonEncode);
     stream.retype<Object>().pipe(_socket);
     dynamic _decoder(dynamic obj) {
-      return JSON.decode(obj);
+      return jsonDecode(obj);
     }
 
     final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_notification_invocation_test.dart b/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
index bba191a..2c064af 100644
--- a/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
@@ -7,7 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
 import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:async' show Future, Stream, StreamController;
 
 var tests = <IsolateTest>[
@@ -26,13 +26,13 @@
     final socket_invoker = new StreamController<Map>();
 
     // Avoid to manually encode and decode messages from the stream
-    Stream<String> socket_stream = socket.stream.map(JSON.encode);
+    Stream<String> socket_stream = socket.stream.map(jsonEncode);
     socket_stream.retype<Object>().pipe(_socket);
     Stream<String> socket_invoker_stream =
-        socket_invoker.stream.map(JSON.encode);
+        socket_invoker.stream.map(jsonEncode);
     socket_invoker_stream.retype<Object>().pipe(_socket_invoker);
     dynamic _decoder(dynamic obj) {
-      return JSON.decode(obj);
+      return jsonDecode(obj);
     }
 
     final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_registration_test.dart b/runtime/observatory/tests/service/external_service_registration_test.dart
index c0dab2f..083c6d6 100644
--- a/runtime/observatory/tests/service/external_service_registration_test.dart
+++ b/runtime/observatory/tests/service/external_service_registration_test.dart
@@ -7,7 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
 import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:async' show Future, Stream, StreamController;
 
 var tests = <IsolateTest>[
@@ -26,10 +26,10 @@
     final socket = new StreamController();
 
     // Avoid to manually encode and decode messages from the stream
-    Stream<String> socket_stream = socket.stream.map(JSON.encode);
+    Stream<String> socket_stream = socket.stream.map(jsonEncode);
     socket_stream.retype<Object>().pipe(_socket);
     dynamic _decoder(dynamic obj) {
-      return JSON.decode(obj);
+      return jsonDecode(obj);
     }
 
     final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart b/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
index 74e258c..11d478e 100644
--- a/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
+++ b/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
@@ -7,7 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
 import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:async' show Future, Stream, StreamController;
 
 var tests = <IsolateTest>[
@@ -26,10 +26,10 @@
     final socket = new StreamController();
 
     // Avoid to manually encode and decode messages from the stream
-    Stream<String> stream = socket.stream.map(JSON.encode);
+    Stream<String> stream = socket.stream.map(jsonEncode);
     stream.retype<Object>().pipe(_socket);
     dynamic _decoder(dynamic obj) {
-      return JSON.decode(obj);
+      return jsonDecode(obj);
     }
 
     final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
index 78091e1..43405ad 100644
--- a/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
@@ -7,7 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
 import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:async' show Future, Stream, StreamController;
 
 var tests = <IsolateTest>[
@@ -23,10 +23,10 @@
     final socket = new StreamController();
 
     // Avoid to manually encode and decode messages from the stream
-    Stream<String> stream = socket.stream.map(JSON.encode);
+    Stream<String> stream = socket.stream.map(jsonEncode);
     stream.retype<Object>().pipe(_socket);
     dynamic _decoder(dynamic obj) {
-      return JSON.decode(obj);
+      return jsonDecode(obj);
     }
 
     final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/file_service_test.dart b/runtime/observatory/tests/service/file_service_test.dart
index 7f372c0..fe9dd6f 100644
--- a/runtime/observatory/tests/service/file_service_test.dart
+++ b/runtime/observatory/tests/service/file_service_test.dart
@@ -27,7 +27,7 @@
 
   Future<ServiceExtensionResponse> cleanup(ignored_a, ignored_b) {
     closeDown();
-    var result = JSON.encode({'type': 'foobar'});
+    var result = jsonEncode({'type': 'foobar'});
     return new Future.value(new ServiceExtensionResponse.result(result));
   }
 
@@ -60,7 +60,7 @@
       closeDown();
       throw e;
     }
-    var result = JSON.encode({'type': 'foobar'});
+    var result = jsonEncode({'type': 'foobar'});
     return new Future.value(new ServiceExtensionResponse.result(result));
   }
 
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index 8ac90d2..6e1cb43 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -6,7 +6,7 @@
 library get_object_rpc_test;
 
 import 'dart:typed_data';
-import 'dart:convert' show BASE64;
+import 'dart:convert' show base64Decode;
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
 import 'service_test_common.dart';
@@ -447,7 +447,7 @@
     expect(result['offset'], isNull);
     expect(result['count'], isNull);
     expect(result['bytes'], equals('AwIB'));
-    Uint8List bytes = BASE64.decode(result['bytes']);
+    Uint8List bytes = base64Decode(result['bytes']);
     expect(bytes.buffer.asUint8List().toString(), equals('[3, 2, 1]'));
   },
 
@@ -473,7 +473,7 @@
     expect(result['offset'], isNull);
     expect(result['count'], equals(2));
     expect(result['bytes'], equals('AwI='));
-    Uint8List bytes = BASE64.decode(result['bytes']);
+    Uint8List bytes = base64Decode(result['bytes']);
     expect(bytes.buffer.asUint8List().toString(), equals('[3, 2]'));
   },
 
@@ -500,7 +500,7 @@
     expect(result['offset'], equals(2));
     expect(result['count'], equals(1));
     expect(result['bytes'], equals('AQ=='));
-    Uint8List bytes = BASE64.decode(result['bytes']);
+    Uint8List bytes = base64Decode(result['bytes']);
     expect(bytes.buffer.asUint8List().toString(), equals('[1]'));
   },
 
@@ -550,7 +550,7 @@
     expect(result['offset'], isNull);
     expect(result['count'], isNull);
     expect(result['bytes'], equals('AwAAAAAAAAACAAAAAAAAAAEAAAAAAAAA'));
-    Uint8List bytes = BASE64.decode(result['bytes']);
+    Uint8List bytes = base64Decode(result['bytes']);
     expect(bytes.buffer.asUint64List().toString(), equals('[3, 2, 1]'));
   },
 
@@ -576,7 +576,7 @@
     expect(result['offset'], isNull);
     expect(result['count'], equals(2));
     expect(result['bytes'], equals('AwAAAAAAAAACAAAAAAAAAA=='));
-    Uint8List bytes = BASE64.decode(result['bytes']);
+    Uint8List bytes = base64Decode(result['bytes']);
     expect(bytes.buffer.asUint64List().toString(), equals('[3, 2]'));
   },
 
@@ -603,7 +603,7 @@
     expect(result['offset'], equals(2));
     expect(result['count'], equals(1));
     expect(result['bytes'], equals('AQAAAAAAAAA='));
-    Uint8List bytes = BASE64.decode(result['bytes']);
+    Uint8List bytes = base64Decode(result['bytes']);
     expect(bytes.buffer.asUint64List().toString(), equals('[1]'));
   },
 
diff --git a/runtime/observatory/tests/service/process_service_test.dart b/runtime/observatory/tests/service/process_service_test.dart
index 8a22291..df8556a 100644
--- a/runtime/observatory/tests/service/process_service_test.dart
+++ b/runtime/observatory/tests/service/process_service_test.dart
@@ -33,7 +33,7 @@
 
   Future<ServiceExtensionResponse> cleanup(ignored_a, ignored_b) {
     closeDown();
-    var result = JSON.encode({'type': 'foobar'});
+    var result = jsonEncode({'type': 'foobar'});
     return new Future.value(new ServiceExtensionResponse.result(result));
   }
 
@@ -57,7 +57,7 @@
       throw e;
     }
 
-    var result = JSON.encode({
+    var result = jsonEncode({
       'type': 'foobar',
       'pids': [process1.pid, process2.pid, process3.pid]
     });
@@ -67,7 +67,7 @@
   Future<ServiceExtensionResponse> closeStdin(ignored_a, ignored_b) {
     process3.stdin.close();
     return process3.exitCode.then<ServiceExtensionResponse>((int exit) {
-      var result = JSON.encode({'type': 'foobar'});
+      var result = jsonEncode({'type': 'foobar'});
       return new ServiceExtensionResponse.result(result);
     });
   }
diff --git a/runtime/observatory/tests/service/tcp_socket_closing_service_test.dart b/runtime/observatory/tests/service/tcp_socket_closing_service_test.dart
index c22794e..a995125 100644
--- a/runtime/observatory/tests/service/tcp_socket_closing_service_test.dart
+++ b/runtime/observatory/tests/service/tcp_socket_closing_service_test.dart
@@ -42,7 +42,7 @@
     }
   });
   var client = await io.RawDatagramSocket.bind('127.0.0.1', 0);
-  client.send(UTF8.encoder.convert('foobar'),
+  client.send(utf8.encoder.convert('foobar'),
       new io.InternetAddress('127.0.0.1'), server.port);
   client.close();
 
diff --git a/runtime/observatory/tests/service/tcp_socket_service_test.dart b/runtime/observatory/tests/service/tcp_socket_service_test.dart
index aef552a..ef80a75 100644
--- a/runtime/observatory/tests/service/tcp_socket_service_test.dart
+++ b/runtime/observatory/tests/service/tcp_socket_service_test.dart
@@ -14,7 +14,7 @@
   // to allow us to query them from the other isolate.
   var serverSocket = await io.ServerSocket.bind('127.0.0.1', 0);
   serverSocket.listen((s) {
-    s.transform(UTF8.decoder).listen(print);
+    s.transform(utf8.decoder).listen(print);
     s.close();
   });
   var socket = await io.Socket.connect("127.0.0.1", serverSocket.port);
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 13da4d1..c8a4111 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -223,7 +223,7 @@
       var blank;
       var first = true;
       process.stdout
-          .transform(UTF8.decoder)
+          .transform(utf8.decoder)
           .transform(new LineSplitter())
           .listen((line) {
         const kObservatoryListening = 'Observatory listening on ';
@@ -243,7 +243,7 @@
         print('>testee>out> $line');
       });
       process.stderr
-          .transform(UTF8.decoder)
+          .transform(utf8.decoder)
           .transform(new LineSplitter())
           .listen((line) {
         print('>testee>err> $line');
diff --git a/runtime/observatory/tests/service/udp_socket_service_test.dart b/runtime/observatory/tests/service/udp_socket_service_test.dart
index d51ca6a..3d40eda 100644
--- a/runtime/observatory/tests/service/udp_socket_service_test.dart
+++ b/runtime/observatory/tests/service/udp_socket_service_test.dart
@@ -18,7 +18,7 @@
     }
   });
   var client = await io.RawDatagramSocket.bind('127.0.0.1', 0);
-  client.send(UTF8.encoder.convert('foobar'),
+  client.send(utf8.encoder.convert('foobar'),
       new io.InternetAddress('127.0.0.1'), server.port);
 }
 
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index e31ec60..a3b0e33 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -18,6 +18,7 @@
 #include "vm/symbols.h"
 #include "vm/timeline.h"
 #include "vm/type_table.h"
+#include "vm/type_testing_stubs.h"
 
 namespace dart {
 
@@ -589,6 +590,10 @@
       }
     }
   }
+
+  // After resolving, we re-initialize the type testing stub.
+  type.SetTypeTestingStub(
+      Instructions::Handle(TypeTestingStubGenerator::DefaultCodeForType(type)));
 }
 
 void ClassFinalizer::FinalizeTypeParameters(const Class& cls,
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index c41dede..03dbd3b 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -97,7 +97,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kClassCid);
     intptr_t count = predefined_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawClass* cls = predefined_[i];
       intptr_t class_id = cls->ptr()->id_;
@@ -105,7 +105,7 @@
       s->AssignRef(cls);
     }
     count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawClass* cls = objects_[i];
       s->AssignRef(cls);
@@ -162,7 +162,7 @@
   void ReadAlloc(Deserializer* d) {
     predefined_start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     ClassTable* table = d->isolate()->class_table();
     for (intptr_t i = 0; i < count; i++) {
       intptr_t class_id = d->ReadCid();
@@ -174,7 +174,7 @@
     predefined_stop_index_ = d->next_index();
 
     start_index_ = d->next_index();
-    count = d->Read<int32_t>();
+    count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Class::InstanceSize()));
     }
@@ -298,7 +298,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kUnresolvedClassCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawUnresolvedClass* cls = objects_[i];
       s->AssignRef(cls);
@@ -307,7 +307,6 @@
 
   void WriteFill(Serializer* s) {
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawUnresolvedClass* cls = objects_[i];
       RawObject** from = cls->from();
@@ -332,7 +331,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, UnresolvedClass::InstanceSize()));
@@ -379,11 +378,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeArgumentsCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTypeArguments* type_args = objects_[i];
       intptr_t length = Smi::Value(type_args->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(type_args);
     }
   }
@@ -393,7 +392,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawTypeArguments* type_args = objects_[i];
       intptr_t length = Smi::Value(type_args->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->Write<bool>(type_args->IsCanonical());
       intptr_t hash = Smi::Value(type_args->ptr()->hash_);
       s->Write<int32_t>(hash);
@@ -417,9 +416,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(AllocateUninitialized(old_space,
                                          TypeArguments::InstanceSize(length)));
     }
@@ -432,7 +431,7 @@
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawTypeArguments* type_args =
           reinterpret_cast<RawTypeArguments*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
                                      TypeArguments::InstanceSize(length),
@@ -469,7 +468,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kPatchClassCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawPatchClass* cls = objects_[i];
       s->AssignRef(cls);
@@ -505,7 +504,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, PatchClass::InstanceSize()));
@@ -565,7 +564,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kFunctionCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawFunction* func = objects_[i];
       s->AssignRef(func);
@@ -615,7 +614,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Function::InstanceSize()));
     }
@@ -734,7 +733,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kClosureDataCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawClosureData* data = objects_[i];
       s->AssignRef(data);
@@ -767,7 +766,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, ClosureData::InstanceSize()));
@@ -815,7 +814,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kSignatureDataCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawSignatureData* data = objects_[i];
       s->AssignRef(data);
@@ -847,7 +846,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, SignatureData::InstanceSize()));
@@ -892,7 +891,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kRedirectionDataCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawRedirectionData* data = objects_[i];
       s->AssignRef(data);
@@ -924,7 +923,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, RedirectionData::InstanceSize()));
@@ -999,7 +998,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kFieldCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawField* field = objects_[i];
       s->AssignRef(field);
@@ -1071,7 +1070,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Field::InstanceSize()));
     }
@@ -1152,7 +1151,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLiteralTokenCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLiteralToken* token = objects_[i];
       s->AssignRef(token);
@@ -1185,7 +1184,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, LiteralToken::InstanceSize()));
@@ -1230,7 +1229,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTokenStreamCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTokenStream* stream = objects_[i];
       s->AssignRef(stream);
@@ -1262,7 +1261,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, TokenStream::InstanceSize()));
@@ -1306,7 +1305,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kScriptCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawScript* script = objects_[i];
       s->AssignRef(script);
@@ -1344,7 +1343,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Script::InstanceSize()));
     }
@@ -1398,7 +1397,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLibraryCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLibrary* lib = objects_[i];
       s->AssignRef(lib);
@@ -1440,7 +1439,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Library::InstanceSize()));
     }
@@ -1502,7 +1501,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kNamespaceCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawNamespace* ns = objects_[i];
       s->AssignRef(ns);
@@ -1534,7 +1533,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Namespace::InstanceSize()));
     }
@@ -1566,10 +1565,6 @@
   virtual ~KernelProgramInfoSerializationCluster() {}
 
   void Trace(Serializer* s, RawObject* object) {
-    if (s->kind() == Snapshot::kFullAOT) {
-      return;
-    }
-
     RawKernelProgramInfo* info = KernelProgramInfo::RawCast(object);
     objects_.Add(info);
 
@@ -1581,13 +1576,9 @@
   }
 
   void WriteAlloc(Serializer* s) {
-    if (s->kind() == Snapshot::kFullAOT) {
-      return;
-    }
-
     s->WriteCid(kKernelProgramInfoCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawKernelProgramInfo* info = objects_[i];
       s->AssignRef(info);
@@ -1595,10 +1586,6 @@
   }
 
   void WriteFill(Serializer* s) {
-    if (s->kind() == Snapshot::kFullAOT) {
-      return;
-    }
-
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawKernelProgramInfo* info = objects_[i];
@@ -1622,11 +1609,9 @@
   virtual ~KernelProgramInfoDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
-    ASSERT(d->kind() != Snapshot::kFullAOT);
-
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, KernelProgramInfo::InstanceSize()));
@@ -1635,8 +1620,6 @@
   }
 
   void ReadFill(Deserializer* d) {
-    ASSERT(d->kind() != Snapshot::kFullAOT);
-
     bool is_vm_object = d->isolate() == Dart::vm_isolate();
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
@@ -1691,7 +1674,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kCodeCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawCode* code = objects_[i];
       s->AssignRef(code);
@@ -1773,7 +1756,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Code::InstanceSize(0)));
     }
@@ -1883,11 +1866,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kObjectPoolCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawObjectPool* pool = objects_[i];
       intptr_t length = pool->ptr()->length_;
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(pool);
     }
   }
@@ -1897,7 +1880,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawObjectPool* pool = objects_[i];
       intptr_t length = pool->ptr()->length_;
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       uint8_t* entry_types = pool->ptr()->entry_types();
       for (intptr_t j = 0; j < length; j++) {
         ObjectPool::EntryType entry_type =
@@ -1950,9 +1933,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(
           AllocateUninitialized(old_space, ObjectPool::InstanceSize(length)));
     }
@@ -1962,7 +1945,7 @@
   void ReadFill(Deserializer* d) {
     bool is_vm_object = d->isolate() == Dart::vm_isolate();
     for (intptr_t id = start_index_; id < stop_index_; id += 1) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       RawObjectPool* pool = reinterpret_cast<RawObjectPool*>(d->Ref(id + 0));
       Deserializer::InitializeHeader(
           pool, kObjectPoolCid, ObjectPool::InstanceSize(length), is_vm_object);
@@ -2013,34 +1996,28 @@
     objects_.Add(object);
 
     // A string's hash must already be computed when we write it because it
-    // will be loaded into read-only memory.
-    if (cid_ == kOneByteStringCid) {
-      RawOneByteString* str = static_cast<RawOneByteString*>(object);
-      if (String::GetCachedHash(str) == 0) {
-        intptr_t hash =
-            String::Hash(str->ptr()->data(), Smi::Value(str->ptr()->length_));
-        String::SetCachedHash(str, hash);
-      }
-      ASSERT(String::GetCachedHash(str) != 0);
-    } else if (cid_ == kTwoByteStringCid) {
-      RawTwoByteString* str = static_cast<RawTwoByteString*>(object);
-      if (String::GetCachedHash(str) == 0) {
-        intptr_t hash = String::Hash(str->ptr()->data(),
-                                     Smi::Value(str->ptr()->length_) * 2);
-        String::SetCachedHash(str, hash);
-      }
-      ASSERT(String::GetCachedHash(str) != 0);
+    // will be loaded into read-only memory. Extra bytes due to allocation
+    // rounding need to be deterministically set for reliable deduplication in
+    // shared images.
+    if (object->IsVMHeapObject()) {
+      // This object is already read-only.
+    } else {
+      Object::FinalizeReadOnlyObject(object);
     }
   }
 
   void WriteAlloc(Serializer* s) {
     s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
+    uint32_t running_offset = 0;
     for (intptr_t i = 0; i < count; i++) {
       RawObject* object = objects_[i];
-      int32_t rodata_offset = s->GetDataOffset(object);
-      s->Write<int32_t>(rodata_offset);
+      uint32_t offset = s->GetDataOffset(object);
+      ASSERT(Utils::IsAligned(offset, kObjectAlignment));
+      ASSERT(offset > running_offset);
+      s->WriteUnsigned((offset - running_offset) >> kObjectAlignmentLog2);
+      running_offset = offset;
       s->AssignRef(object);
     }
   }
@@ -2061,10 +2038,11 @@
   virtual ~RODataDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
+    uint32_t running_offset = 0;
     for (intptr_t i = 0; i < count; i++) {
-      int32_t rodata_offset = d->Read<int32_t>();
-      d->AssignRef(d->GetObjectAt(rodata_offset));
+      running_offset += d->ReadUnsigned() << kObjectAlignmentLog2;
+      d->AssignRef(d->GetObjectAt(running_offset));
     }
   }
 
@@ -2090,11 +2068,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kExceptionHandlersCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawExceptionHandlers* handlers = objects_[i];
       intptr_t length = handlers->ptr()->num_entries_;
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(handlers);
     }
   }
@@ -2104,7 +2082,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawExceptionHandlers* handlers = objects_[i];
       intptr_t length = handlers->ptr()->num_entries_;
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->WriteRef(handlers->ptr()->handled_types_data_);
 
       uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
@@ -2126,9 +2104,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(AllocateUninitialized(
           old_space, ExceptionHandlers::InstanceSize(length)));
     }
@@ -2141,7 +2119,7 @@
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawExceptionHandlers* handlers =
           reinterpret_cast<RawExceptionHandlers*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       Deserializer::InitializeHeader(handlers, kExceptionHandlersCid,
                                      ExceptionHandlers::InstanceSize(length),
                                      is_vm_object);
@@ -2176,11 +2154,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kContextCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawContext* context = objects_[i];
       intptr_t length = context->ptr()->num_variables_;
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(context);
     }
   }
@@ -2190,7 +2168,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawContext* context = objects_[i];
       intptr_t length = context->ptr()->num_variables_;
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->WriteRef(context->ptr()->parent_);
       for (intptr_t j = 0; j < length; j++) {
         s->WriteRef(context->ptr()->data()[j]);
@@ -2211,9 +2189,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(
           AllocateUninitialized(old_space, Context::InstanceSize(length)));
     }
@@ -2225,7 +2203,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawContext* context = reinterpret_cast<RawContext*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       Deserializer::InitializeHeader(
           context, kContextCid, Context::InstanceSize(length), is_vm_object);
       context->ptr()->num_variables_ = length;
@@ -2258,11 +2236,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kContextScopeCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawContextScope* scope = objects_[i];
       intptr_t length = scope->ptr()->num_variables_;
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(scope);
     }
   }
@@ -2272,7 +2250,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawContextScope* scope = objects_[i];
       intptr_t length = scope->ptr()->num_variables_;
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->Write<bool>(scope->ptr()->is_implicit_);
       RawObject** from = scope->from();
       RawObject** to = scope->to(length);
@@ -2295,9 +2273,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(
           AllocateUninitialized(old_space, ContextScope::InstanceSize(length)));
     }
@@ -2309,7 +2287,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawContextScope* scope = reinterpret_cast<RawContextScope*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       Deserializer::InitializeHeader(scope, kContextScopeCid,
                                      ContextScope::InstanceSize(length),
                                      is_vm_object);
@@ -2344,7 +2322,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kUnlinkedCallCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawUnlinkedCall* unlinked = objects_[i];
       s->AssignRef(unlinked);
@@ -2376,7 +2354,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, UnlinkedCall::InstanceSize()));
@@ -2422,7 +2400,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kICDataCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawICData* ic = objects_[i];
       s->AssignRef(ic);
@@ -2462,7 +2440,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, ICData::InstanceSize()));
     }
@@ -2516,7 +2494,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kMegamorphicCacheCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawMegamorphicCache* cache = objects_[i];
       s->AssignRef(cache);
@@ -2549,7 +2527,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, MegamorphicCache::InstanceSize()));
@@ -2592,7 +2570,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kSubtypeTestCacheCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawSubtypeTestCache* cache = objects_[i];
       s->AssignRef(cache);
@@ -2620,7 +2598,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, SubtypeTestCache::InstanceSize()));
@@ -2662,7 +2640,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLanguageErrorCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLanguageError* error = objects_[i];
       s->AssignRef(error);
@@ -2697,7 +2675,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, LanguageError::InstanceSize()));
@@ -2746,7 +2724,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kUnhandledExceptionCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawUnhandledException* exception = objects_[i];
       s->AssignRef(exception);
@@ -2778,7 +2756,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, UnhandledException::InstanceSize()));
@@ -2834,7 +2812,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
 
     s->Write<int32_t>(next_field_offset_in_words_);
     s->Write<int32_t>(instance_size_in_words_);
@@ -2877,7 +2855,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     next_field_offset_in_words_ = d->Read<int32_t>();
     instance_size_in_words_ = d->Read<int32_t>();
     intptr_t instance_size =
@@ -2942,7 +2920,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLibraryPrefixCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLibraryPrefix* prefix = objects_[i];
       s->AssignRef(prefix);
@@ -2977,7 +2955,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, LibraryPrefix::InstanceSize()));
@@ -3015,7 +2993,8 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeSerializationCluster : public SerializationCluster {
  public:
-  TypeSerializationCluster() : SerializationCluster("Type") {}
+  explicit TypeSerializationCluster(const TypeTestingStubFinder& ttsf)
+      : SerializationCluster("Type"), type_testing_stubs_(ttsf) {}
   virtual ~TypeSerializationCluster() {}
 
   void Trace(Serializer* s, RawObject* object) {
@@ -3046,13 +3025,13 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeCid);
     intptr_t count = canonical_objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawType* type = canonical_objects_[i];
       s->AssignRef(type);
     }
     count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawType* type = objects_[i];
       s->AssignRef(type);
@@ -3060,6 +3039,8 @@
   }
 
   void WriteFill(Serializer* s) {
+    const bool is_vm_isolate = s->isolate() == Dart::vm_isolate();
+
     intptr_t count = canonical_objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawType* type = canonical_objects_[i];
@@ -3070,6 +3051,12 @@
       }
       s->WriteTokenPosition(type->ptr()->token_pos_);
       s->Write<int8_t>(type->ptr()->type_state_);
+      if (s->kind() == Snapshot::kFullAOT) {
+        RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
+            type->ptr()->type_test_stub_entry_point_);
+        const int32_t text_offset = s->GetTextOffset(instr, Code::null());
+        s->Write<int32_t>(text_offset);
+      }
     }
     count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
@@ -3081,31 +3068,51 @@
       }
       s->WriteTokenPosition(type->ptr()->token_pos_);
       s->Write<int8_t>(type->ptr()->type_state_);
+      if (s->kind() == Snapshot::kFullAOT) {
+        RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
+            type->ptr()->type_test_stub_entry_point_);
+        const int32_t text_offset = s->GetTextOffset(instr, Code::null());
+        s->Write<int32_t>(text_offset);
+      }
+    }
+
+    // The dynamic/void objects are not serialized, so we manually send
+    // the type testing stub for it.
+    if (s->kind() == Snapshot::kFullAOT && is_vm_isolate) {
+      RawInstructions* dynamic_instr = type_testing_stubs_.LookupByAddresss(
+          Type::dynamic_type().type_test_stub_entry_point());
+      s->Write<int32_t>(s->GetTextOffset(dynamic_instr, Code::null()));
+
+      RawInstructions* void_instr = type_testing_stubs_.LookupByAddresss(
+          Type::void_type().type_test_stub_entry_point());
+      s->Write<int32_t>(s->GetTextOffset(void_instr, Code::null()));
     }
   }
 
  private:
   GrowableArray<RawType*> canonical_objects_;
   GrowableArray<RawType*> objects_;
+  const TypeTestingStubFinder& type_testing_stubs_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
 class TypeDeserializationCluster : public DeserializationCluster {
  public:
-  TypeDeserializationCluster() {}
+  TypeDeserializationCluster()
+      : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
   virtual ~TypeDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
     canonical_start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Type::InstanceSize()));
     }
     canonical_stop_index_ = d->next_index();
 
     start_index_ = d->next_index();
-    count = d->Read<int32_t>();
+    count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Type::InstanceSize()));
     }
@@ -3113,13 +3120,13 @@
   }
 
   void ReadFill(Deserializer* d) {
-    bool is_vm_object = d->isolate() == Dart::vm_isolate();
+    const bool is_vm_isolate = d->isolate() == Dart::vm_isolate();
 
     for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
          id++) {
       RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
       Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
-                                     is_vm_object, true);
+                                     is_vm_isolate, true);
       RawObject** from = type->from();
       RawObject** to = type->to();
       for (RawObject** p = from; p <= to; p++) {
@@ -3127,12 +3134,18 @@
       }
       type->ptr()->token_pos_ = d->ReadTokenPosition();
       type->ptr()->type_state_ = d->Read<int8_t>();
+      if (d->kind() == Snapshot::kFullAOT) {
+        const int32_t text_offset = d->Read<int32_t>();
+        instr_ = d->GetInstructionsAt(text_offset);
+        type_ = type;
+        type_.SetTypeTestingStub(instr_);
+      }
     }
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
       Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
-                                     is_vm_object);
+                                     is_vm_isolate);
       RawObject** from = type->from();
       RawObject** to = type->to();
       for (RawObject** p = from; p <= to; p++) {
@@ -3140,18 +3153,52 @@
       }
       type->ptr()->token_pos_ = d->ReadTokenPosition();
       type->ptr()->type_state_ = d->Read<int8_t>();
+      if (d->kind() == Snapshot::kFullAOT) {
+        const int32_t text_offset = d->Read<int32_t>();
+        instr_ = d->GetInstructionsAt(text_offset);
+        type_ = type;
+        type_.SetTypeTestingStub(instr_);
+      }
+    }
+
+    // The dynamic/void objects are not serialized, so we manually send
+    // the type testing stub for it.
+    if (d->kind() == Snapshot::kFullAOT && is_vm_isolate) {
+      instr_ = d->GetInstructionsAt(d->Read<int32_t>());
+      Type::dynamic_type().SetTypeTestingStub(instr_);
+      instr_ = d->GetInstructionsAt(d->Read<int32_t>());
+      Type::void_type().SetTypeTestingStub(instr_);
+    }
+  }
+
+  void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+    if (kind != Snapshot::kFullAOT) {
+      for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
+           id++) {
+        type_ ^= refs.At(id);
+        instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
+        type_.SetTypeTestingStub(instr_);
+      }
+      for (intptr_t id = start_index_; id < stop_index_; id++) {
+        type_ ^= refs.At(id);
+        instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
+        type_.SetTypeTestingStub(instr_);
+      }
     }
   }
 
  private:
   intptr_t canonical_start_index_;
   intptr_t canonical_stop_index_;
+  AbstractType& type_;
+  Instructions& instr_;
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeRefSerializationCluster : public SerializationCluster {
  public:
-  TypeRefSerializationCluster() : SerializationCluster("TypeRef") {}
+  explicit TypeRefSerializationCluster(const TypeTestingStubFinder& ttsf)
+      : SerializationCluster("TypeRef"), type_testing_stubs_(ttsf) {}
   virtual ~TypeRefSerializationCluster() {}
 
   void Trace(Serializer* s, RawObject* object) {
@@ -3168,7 +3215,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeRefCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTypeRef* type = objects_[i];
       s->AssignRef(type);
@@ -3184,23 +3231,31 @@
       for (RawObject** p = from; p <= to; p++) {
         s->WriteRef(*p);
       }
+      if (s->kind() == Snapshot::kFullAOT) {
+        RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
+            type->ptr()->type_test_stub_entry_point_);
+        const int32_t text_offset = s->GetTextOffset(instr, Code::null());
+        s->Write<int32_t>(text_offset);
+      }
     }
   }
 
  private:
   GrowableArray<RawTypeRef*> objects_;
+  const TypeTestingStubFinder& type_testing_stubs_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
 class TypeRefDeserializationCluster : public DeserializationCluster {
  public:
-  TypeRefDeserializationCluster() {}
+  TypeRefDeserializationCluster()
+      : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
   virtual ~TypeRefDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, TypeRef::InstanceSize()));
     }
@@ -3219,14 +3274,26 @@
       for (RawObject** p = from; p <= to; p++) {
         *p = d->ReadRef();
       }
+      if (d->kind() == Snapshot::kFullAOT) {
+        const int32_t text_offset = d->Read<int32_t>();
+        instr_ = d->GetInstructionsAt(text_offset);
+        type_ = type;
+        type_.SetTypeTestingStub(instr_);
+      }
     }
   }
+
+ private:
+  AbstractType& type_;
+  Instructions& instr_;
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeParameterSerializationCluster : public SerializationCluster {
  public:
-  TypeParameterSerializationCluster() : SerializationCluster("TypeParameter") {}
+  explicit TypeParameterSerializationCluster(const TypeTestingStubFinder& ttsf)
+      : SerializationCluster("TypeParameter"), type_testing_stubs_(ttsf) {}
+
   virtual ~TypeParameterSerializationCluster() {}
 
   void Trace(Serializer* s, RawObject* object) {
@@ -3244,7 +3311,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeParameterCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTypeParameter* type = objects_[i];
       s->AssignRef(type);
@@ -3264,23 +3331,31 @@
       s->WriteTokenPosition(type->ptr()->token_pos_);
       s->Write<int16_t>(type->ptr()->index_);
       s->Write<int8_t>(type->ptr()->type_state_);
+      if (s->kind() == Snapshot::kFullAOT) {
+        RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
+            type->ptr()->type_test_stub_entry_point_);
+        const int32_t text_offset = s->GetTextOffset(instr, Code::null());
+        s->Write<int32_t>(text_offset);
+      }
     }
   }
 
  private:
   GrowableArray<RawTypeParameter*> objects_;
+  const TypeTestingStubFinder& type_testing_stubs_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
 class TypeParameterDeserializationCluster : public DeserializationCluster {
  public:
-  TypeParameterDeserializationCluster() {}
+  TypeParameterDeserializationCluster()
+      : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
   virtual ~TypeParameterDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, TypeParameter::InstanceSize()));
@@ -3304,8 +3379,28 @@
       type->ptr()->token_pos_ = d->ReadTokenPosition();
       type->ptr()->index_ = d->Read<int16_t>();
       type->ptr()->type_state_ = d->Read<int8_t>();
+      if (d->kind() == Snapshot::kFullAOT) {
+        const int32_t text_offset = d->Read<int32_t>();
+        instr_ = d->GetInstructionsAt(text_offset);
+        type_ = type;
+        type_.SetTypeTestingStub(instr_);
+      }
     }
   }
+
+  void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+    if (kind != Snapshot::kFullAOT) {
+      for (intptr_t id = start_index_; id < stop_index_; id++) {
+        type_ ^= refs.At(id);
+        instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
+        type_.SetTypeTestingStub(instr_);
+      }
+    }
+  }
+
+ private:
+  AbstractType& type_;
+  Instructions& instr_;
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -3328,7 +3423,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kBoundedTypeCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawBoundedType* type = objects_[i];
       s->AssignRef(type);
@@ -3360,7 +3455,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, BoundedType::InstanceSize()));
@@ -3404,7 +3499,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kClosureCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawClosure* closure = objects_[i];
       s->AssignRef(closure);
@@ -3437,7 +3532,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Closure::InstanceSize()));
     }
@@ -3481,7 +3576,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kMintCid);
 
-    s->Write<int32_t>(smis_.length() + mints_.length());
+    s->WriteUnsigned(smis_.length() + mints_.length());
     for (intptr_t i = 0; i < smis_.length(); i++) {
       RawSmi* smi = smis_[i];
       s->Write<bool>(true);
@@ -3514,7 +3609,7 @@
     bool is_vm_object = d->isolate() == Dart::vm_isolate();
 
     start_index_ = d->next_index();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       bool is_canonical = d->Read<bool>();
       int64_t value = d->Read<int64_t>();
@@ -3571,7 +3666,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kBigintCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawBigint* bigint = objects_[i];
       s->AssignRef(bigint);
@@ -3604,7 +3699,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Bigint::InstanceSize()));
     }
@@ -3642,7 +3737,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kDoubleCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawDouble* dbl = objects_[i];
       s->AssignRef(dbl);
@@ -3671,7 +3766,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Double::InstanceSize()));
     }
@@ -3712,7 +3807,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kGrowableObjectArrayCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawGrowableObjectArray* array = objects_[i];
       s->AssignRef(array);
@@ -3746,7 +3841,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          GrowableObjectArray::InstanceSize()));
@@ -3788,11 +3883,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTypedData* data = objects_[i];
       intptr_t length = Smi::Value(data->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(data);
     }
   }
@@ -3803,7 +3898,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawTypedData* data = objects_[i];
       intptr_t length = Smi::Value(data->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->Write<bool>(data->IsCanonical());
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
       s->WriteBytes(cdata, length * element_size);
@@ -3824,10 +3919,10 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(AllocateUninitialized(
           old_space, TypedData::InstanceSize(length * element_size)));
     }
@@ -3840,7 +3935,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawTypedData* data = reinterpret_cast<RawTypedData*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       intptr_t length_in_bytes = length * element_size;
       Deserializer::InitializeHeader(data, cid_,
@@ -3872,7 +3967,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawExternalTypedData* data = objects_[i];
       s->AssignRef(data);
@@ -3885,7 +3980,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawExternalTypedData* data = objects_[i];
       intptr_t length = Smi::Value(data->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data_);
       s->WriteBytes(cdata, length * element_size);
     }
@@ -3905,7 +4000,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, ExternalTypedData::InstanceSize()));
@@ -3920,7 +4015,7 @@
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawExternalTypedData* data =
           reinterpret_cast<RawExternalTypedData*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       Deserializer::InitializeHeader(
           data, cid_, ExternalTypedData::InstanceSize(), is_vm_object);
       data->ptr()->length_ = Smi::New(length);
@@ -3954,7 +4049,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kStackTraceCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawStackTrace* trace = objects_[i];
       s->AssignRef(trace);
@@ -3986,7 +4081,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, StackTrace::InstanceSize()));
@@ -4030,7 +4125,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kRegExpCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawRegExp* regexp = objects_[i];
       s->AssignRef(regexp);
@@ -4065,7 +4160,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, RegExp::InstanceSize()));
     }
@@ -4111,7 +4206,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kWeakPropertyCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawWeakProperty* property = objects_[i];
       s->AssignRef(property);
@@ -4143,7 +4238,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, WeakProperty::InstanceSize()));
@@ -4197,7 +4292,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLinkedHashMapCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLinkedHashMap* map = objects_[i];
       s->AssignRef(map);
@@ -4245,7 +4340,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, LinkedHashMap::InstanceSize()));
@@ -4316,11 +4411,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawArray* array = objects_[i];
       intptr_t length = Smi::Value(array->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(array);
     }
   }
@@ -4330,7 +4425,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawArray* array = objects_[i];
       intptr_t length = Smi::Value(array->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->Write<bool>(array->IsCanonical());
       s->WriteRef(array->ptr()->type_arguments_);
       for (intptr_t j = 0; j < length; j++) {
@@ -4353,9 +4448,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(
           AllocateUninitialized(old_space, Array::InstanceSize(length)));
     }
@@ -4367,7 +4462,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawArray* array = reinterpret_cast<RawArray*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(array, cid_, Array::InstanceSize(length),
                                      is_vm_object, is_canonical);
@@ -4398,11 +4493,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kOneByteStringCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawOneByteString* str = objects_[i];
       intptr_t length = Smi::Value(str->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(str);
     }
   }
@@ -4412,7 +4507,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawOneByteString* str = objects_[i];
       intptr_t length = Smi::Value(str->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->Write<bool>(str->IsCanonical());
       intptr_t hash = String::GetCachedHash(str);
       s->Write<int32_t>(hash);
@@ -4433,9 +4528,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(AllocateUninitialized(old_space,
                                          OneByteString::InstanceSize(length)));
     }
@@ -4447,7 +4542,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(str, kOneByteStringCid,
                                      OneByteString::InstanceSize(length),
@@ -4475,11 +4570,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTwoByteStringCid);
     intptr_t count = objects_.length();
-    s->Write<int32_t>(count);
+    s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTwoByteString* str = objects_[i];
       intptr_t length = Smi::Value(str->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->AssignRef(str);
     }
   }
@@ -4489,7 +4584,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawTwoByteString* str = objects_[i];
       intptr_t length = Smi::Value(str->ptr()->length_);
-      s->Write<int32_t>(length);
+      s->WriteUnsigned(length);
       s->Write<bool>(str->IsCanonical());
       intptr_t hash = String::GetCachedHash(str);
       s->Write<int32_t>(hash);
@@ -4510,9 +4605,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<int32_t>();
+    intptr_t count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       d->AssignRef(AllocateUninitialized(old_space,
                                          TwoByteString::InstanceSize(length)));
     }
@@ -4524,7 +4619,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(d->Ref(id));
-      intptr_t length = d->Read<int32_t>();
+      intptr_t length = d->ReadUnsigned();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(str, kTwoByteStringCid,
                                      TwoByteString::InstanceSize(length),
@@ -4669,11 +4764,11 @@
     case kLibraryPrefixCid:
       return new (Z) LibraryPrefixSerializationCluster();
     case kTypeCid:
-      return new (Z) TypeSerializationCluster();
+      return new (Z) TypeSerializationCluster(type_testing_stubs_);
     case kTypeRefCid:
-      return new (Z) TypeRefSerializationCluster();
+      return new (Z) TypeRefSerializationCluster(type_testing_stubs_);
     case kTypeParameterCid:
-      return new (Z) TypeParameterSerializationCluster();
+      return new (Z) TypeParameterSerializationCluster(type_testing_stubs_);
     case kBoundedTypeCid:
       return new (Z) BoundedTypeSerializationCluster();
     case kClosureCid:
@@ -4734,7 +4829,7 @@
   return offset;
 }
 
-int32_t Serializer::GetDataOffset(RawObject* object) const {
+uint32_t Serializer::GetDataOffset(RawObject* object) const {
   return image_writer_->GetDataOffsetFor(object);
 }
 
@@ -4899,9 +4994,9 @@
   }
 #endif
 
-  Write<int32_t>(num_base_objects_);
-  Write<int32_t>(num_objects);
-  Write<int32_t>(num_clusters);
+  WriteUnsigned(num_base_objects_);
+  WriteUnsigned(num_objects);
+  WriteUnsigned(num_clusters);
 
   for (intptr_t cid = 1; cid < num_cids_; cid++) {
     SerializationCluster* cluster = clusters_by_cid_[cid];
@@ -5063,7 +5158,7 @@
   void VisitObject(RawObject* obj) {
     if (obj->IsInstructions()) {
       uword addr = RawObject::ToAddr(obj);
-      int32_t offset = addr - text_base_;
+      uint32_t offset = addr - text_base_;
       heap_->SetObjectId(obj, -offset);
     }
   }
@@ -5340,14 +5435,14 @@
   return image_reader_->GetInstructionsAt(offset);
 }
 
-RawObject* Deserializer::GetObjectAt(int32_t offset) const {
+RawObject* Deserializer::GetObjectAt(uint32_t offset) const {
   return image_reader_->GetObjectAt(offset);
 }
 
 void Deserializer::Prepare() {
-  num_base_objects_ = Read<int32_t>();
-  num_objects_ = Read<int32_t>();
-  num_clusters_ = Read<int32_t>();
+  num_base_objects_ = ReadUnsigned();
+  num_objects_ = ReadUnsigned();
+  num_clusters_ = ReadUnsigned();
 
   clusters_ = new DeserializationCluster*[num_clusters_];
   refs_ = Array::New(num_objects_ + 1, Heap::kOld);
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index dd0eb7c..c9e4970 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -15,6 +15,7 @@
 #include "vm/heap.h"
 #include "vm/object.h"
 #include "vm/snapshot.h"
+#include "vm/type_testing_stubs.h"
 #include "vm/version.h"
 
 #if defined(DEBUG)
@@ -208,7 +209,7 @@
   void Write(T value) {
     WriteStream::Raw<sizeof(T), T>::Write(&stream_, value);
   }
-
+  void WriteUnsigned(intptr_t value) { stream_.WriteUnsigned(value); }
   void WriteBytes(const uint8_t* addr, intptr_t len) {
     stream_.WriteBytes(addr, len);
   }
@@ -220,7 +221,7 @@
       if (id == 0) {
         FATAL("Missing ref");
       }
-      Write<int32_t>(id);
+      WriteUnsigned(id);
       return;
     }
 
@@ -241,7 +242,7 @@
       }
       FATAL("Missing ref");
     }
-    Write<int32_t>(id);
+    WriteUnsigned(id);
   }
 
   void WriteTokenPosition(TokenPosition pos) {
@@ -254,7 +255,7 @@
   }
 
   int32_t GetTextOffset(RawInstructions* instr, RawCode* code) const;
-  int32_t GetDataOffset(RawObject* object) const;
+  uint32_t GetDataOffset(RawObject* object) const;
   intptr_t GetDataSize() const;
   intptr_t GetTextSize() const;
 
@@ -264,6 +265,7 @@
   void DumpCombinedCodeStatistics();
 
  private:
+  TypeTestingStubFinder type_testing_stubs_;
   Heap* heap_;
   Zone* zone_;
   Snapshot::Kind kind_;
@@ -312,7 +314,7 @@
   T Read() {
     return ReadStream::Raw<sizeof(T), T>::Read(&stream_);
   }
-
+  intptr_t ReadUnsigned() { return stream_.ReadUnsigned(); }
   void ReadBytes(uint8_t* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
 
   const uint8_t* CurrentBufferAddress() const {
@@ -337,10 +339,7 @@
     return refs_->ptr()->data()[index];
   }
 
-  RawObject* ReadRef() {
-    int32_t index = Read<int32_t>();
-    return Ref(index);
-  }
+  RawObject* ReadRef() { return Ref(ReadUnsigned()); }
 
   TokenPosition ReadTokenPosition() {
     return TokenPosition::SnapshotDecode(Read<int32_t>());
@@ -352,7 +351,7 @@
   }
 
   RawInstructions* GetInstructionsAt(int32_t offset) const;
-  RawObject* GetObjectAt(int32_t offset) const;
+  RawObject* GetObjectAt(uint32_t offset) const;
 
   RawApiError* VerifyVersionAndFeatures(Isolate* isolate);
 
diff --git a/runtime/vm/code_patcher.cc b/runtime/vm/code_patcher.cc
index 784c9af..ca7cd0e 100644
--- a/runtime/vm/code_patcher.cc
+++ b/runtime/vm/code_patcher.cc
@@ -28,4 +28,15 @@
   }
 }
 
+bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size) {
+  uint8_t* bytes = reinterpret_cast<uint8_t*>(addr);
+  for (intptr_t i = 0; i < size; i++) {
+    int16_t val = pattern[i];
+    if ((val >= 0) && (val != bytes[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index 8518a74..17ff119 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -102,8 +102,16 @@
                                 NativeFunction target,
                                 const Code& trampoline);
 #endif
+
+  static intptr_t GetSubtypeTestCachePoolIndex(uword return_address);
 };
 
+// Beginning from [addr] we compare [size] bytes with [pattern].  All [0..255]
+// values in [pattern] have to match, negative values are skipped.
+//
+// Example pattern: `[0x3d, 0x8b, -1, -1]`.
+bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size);
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CODE_PATCHER_H_
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 8cebf38..4c99d91 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -16,17 +16,6 @@
 
 namespace dart {
 
-static bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size) {
-  uint8_t* bytes = reinterpret_cast<uint8_t*>(addr);
-  for (intptr_t i = 0; i < size; i++) {
-    int16_t val = pattern[i];
-    if ((val >= 0) && (val != bytes[i])) {
-      return false;
-    }
-  }
-  return true;
-}
-
 intptr_t IndexFromPPLoad(uword start) {
   int32_t offset = *reinterpret_cast<int32_t*>(start);
   return ObjectPool::IndexFromOffset(offset);
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index f84ed2e..37eea57 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -46,6 +46,7 @@
 #include "vm/timeline.h"
 #include "vm/timer.h"
 #include "vm/type_table.h"
+#include "vm/type_testing_stubs.h"
 #include "vm/unicode.h"
 #include "vm/version.h"
 
@@ -273,6 +274,10 @@
 
       ClassFinalizer::SortClasses();
 
+      // Collects type usage information which allows us to decide when/how to
+      // optimize runtime type tests.
+      TypeUsageInfo type_usage_info(T);
+
       // The cid-ranges of subclasses of a class are e.g. used for is/as checks
       // as well as other type checks.
       HierarchyInfo hierarchy_info(T);
@@ -312,6 +317,10 @@
         // Compile newly found targets and add their callees until we reach a
         // fixed point.
         Iterate();
+
+        // Replace the default type testing stubs installed on [Type]s with new
+        // [Type]-specialized stubs.
+        AttachOptimizedTypeTestingStub();
       }
 
       I->set_compilation_allowed(false);
@@ -1858,6 +1867,80 @@
   }
 }
 
+void Precompiler::AttachOptimizedTypeTestingStub() {
+  Isolate::Current()->heap()->CollectAllGarbage();
+  GrowableHandlePtrArray<const AbstractType> types(Z, 200);
+  {
+    class TypesCollector : public ObjectVisitor {
+     public:
+      explicit TypesCollector(Zone* zone,
+                              GrowableHandlePtrArray<const AbstractType>* types)
+          : type_(AbstractType::Handle(zone)), types_(types) {}
+
+      void VisitObject(RawObject* obj) {
+        if (obj->GetClassId() == kTypeCid || obj->GetClassId() == kTypeRefCid) {
+          type_ ^= obj;
+          types_->Add(type_);
+        }
+      }
+
+     private:
+      AbstractType& type_;
+      GrowableHandlePtrArray<const AbstractType>* types_;
+    };
+
+    HeapIterationScope his(T);
+    TypesCollector visitor(Z, &types);
+
+    // Find all type objects in this isolate.
+    I->heap()->VisitObjects(&visitor);
+
+    // Find all type objects in the vm-isolate.
+    Dart::vm_isolate()->heap()->VisitObjects(&visitor);
+  }
+
+  TypeUsageInfo* type_usage_info = Thread::Current()->type_usage_info();
+
+  // At this point we're not generating any new code, so we build a picture of
+  // which types we might type-test against.
+  type_usage_info->BuildTypeUsageInformation();
+
+  TypeTestingStubGenerator type_testing_stubs;
+  Instructions& instr = Instructions::Handle();
+  for (intptr_t i = 0; i < types.length(); i++) {
+    const AbstractType& type = types.At(i);
+
+    if (!type.IsResolved()) {
+      continue;
+    }
+
+    // [kVectorCid] is excluded because it doesn't have a real class,
+    // corresponding to the class id, in Dart source code.
+    if (type.IsType() && type.type_class_id() == kVectorCid) {
+      continue;
+    }
+
+    if (type.InVMHeap()) {
+      // The only important types in the vm isolate are "dynamic"/"void", which
+      // will get their optimized top-type testing stub installed at creation.
+      continue;
+    }
+
+    if (type.IsResolved() && !type.IsMalformedOrMalbounded()) {
+      if (type_usage_info->IsUsedInTypeTest(type)) {
+        instr = type_testing_stubs.OptimizedCodeForType(type);
+        type.SetTypeTestingStub(instr);
+
+        // Ensure we retain the type.
+        AddType(type);
+      }
+    }
+  }
+
+  ASSERT(Object::dynamic_type().type_test_stub_entry_point() !=
+         StubCode::DefaultTypeTest_entry()->EntryPoint());
+}
+
 void Precompiler::DropTypes() {
   ObjectStore* object_store = I->object_store();
   GrowableObjectArray& retained_types =
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index c54fc75..93e8326 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -373,6 +373,8 @@
   void TraceConstFunctions();
   void CollectCallbackFields();
 
+  void AttachOptimizedTypeTestingStub();
+
   void TraceForRetainedFunctions();
   void DropFunctions();
   void DropFields();
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index b4f890a..ab6f811 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -353,6 +353,13 @@
   void Bind(Label* label);
   void Jump(Label* label) { b(label); }
 
+  void LoadField(Register dst, FieldAddress address) { ldr(dst, address); }
+
+  void CompareWithFieldValue(Register value, FieldAddress address) {
+    ldr(TMP, address);
+    cmp(value, Operand(TMP));
+  }
+
   // Misc. functionality
   intptr_t CodeSize() const { return buffer_.Size(); }
   intptr_t prologue_offset() const { return prologue_offset_; }
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index cfe69b9..373f848 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -438,6 +438,13 @@
   void Bind(Label* label);
   void Jump(Label* label) { b(label); }
 
+  void LoadField(Register dst, FieldAddress address) { ldr(dst, address); }
+
+  void CompareWithFieldValue(Register value, FieldAddress address) {
+    ldr(TMP, address);
+    cmp(value, Operand(TMP));
+  }
+
   // Misc. functionality
   intptr_t CodeSize() const { return buffer_.Size(); }
   intptr_t prologue_offset() const { return prologue_offset_; }
@@ -1506,6 +1513,7 @@
 
   void EnterFrame(intptr_t frame_size);
   void LeaveFrame();
+  void Ret() { ret(LR); }
 
   void CheckCodePointer();
   void RestoreCodePointer();
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 704550e..24783cb 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -566,6 +566,7 @@
 
   void CompareRegisters(Register a, Register b);
   void BranchIf(Condition condition, Label* label) { j(condition, label); }
+  void LoadField(Register dst, FieldAddress address) { movw(dst, address); }
 
   // Issues a move instruction if 'to' is not the same as 'from'.
   void MoveRegister(Register to, Register from);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 83a80ff..5b85011 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -651,6 +651,7 @@
   }
 
   // Methods for High-level operations and implemented on all architectures.
+  void Ret() { ret(); }
   void CompareRegisters(Register a, Register b);
   void BranchIf(Condition condition, Label* label) { j(condition, label); }
 
@@ -799,6 +800,12 @@
   void Bind(Label* label);
   void Jump(Label* label) { jmp(label); }
 
+  void LoadField(Register dst, FieldAddress address) { movq(dst, address); }
+
+  void CompareWithFieldValue(Register value, FieldAddress address) {
+    cmpq(value, address);
+  }
+
   void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
   static bool EmittingComments();
 
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index a18453c..202a3e1 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -3226,7 +3226,7 @@
   EXPECT_FLOAT_EQ(-1.0, res, 0.000001f);
   EXPECT_DISASSEMBLY_NOT_WINDOWS_ENDS_WITH(
       "movups xmm10,[rax]\n"
-      "movq r11,[thr+0xf8]\n"
+      "movq r11,[thr+0x...]\n"
       "xorpd xmm10,[r11]\n"
       "movaps xmm0,xmm10\n"
       "pop thr\n"
diff --git a/runtime/vm/compiler/backend/code_statistics.cc b/runtime/vm/compiler/backend/code_statistics.cc
index 7e5cdc5..22df62c 100644
--- a/runtime/vm/compiler/backend/code_statistics.cc
+++ b/runtime/vm/compiler/backend/code_statistics.cc
@@ -108,8 +108,8 @@
 }
 
 int CombinedCodeStatistics::CompareEntries(const void* a, const void* b) {
-  const intptr_t a_size = static_cast<const Entry*>(a)->bytes;
-  const intptr_t b_size = static_cast<const Entry*>(b)->bytes;
+  const intptr_t a_size = (*static_cast<const Entry* const*>(a))->bytes;
+  const intptr_t b_size = (*static_cast<const Entry* const*>(b))->bytes;
   if (a_size < b_size) {
     return -1;
   } else if (a_size > b_size) {
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 0de93d5..5d30eda 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -26,7 +26,6 @@
 // Quick access to the current zone and isolate.
 #define I (isolate())
 #define Z (graph_->zone())
-#define T (graph_->thread())
 
 ConstantPropagator::ConstantPropagator(
     FlowGraph* graph,
@@ -1111,8 +1110,7 @@
       default:
         UNREACHABLE();
     }
-    const Double& result =
-        Double::ZoneHandle(Double::New(result_val, Heap::kOld));
+    const Double& result = Double::ZoneHandle(Double::NewCanonical(result_val));
     SetValue(instr, result);
   }
 }
@@ -1323,7 +1321,6 @@
   // instructions, previous pointers, predecessors, etc. after eliminating
   // unreachable code.  We do not maintain those properties during the
   // transformation.
-  auto& value = Object::Handle(Z);
   for (BlockIterator b = graph_->reverse_postorder_iterator(); !b.Done();
        b.Advance()) {
     BlockEntryInstr* block = b.Current();
@@ -1401,14 +1398,7 @@
           THR_Print("Constant v%" Pd " = %s\n", defn->ssa_temp_index(),
                     defn->constant_value().ToCString());
         }
-        value = defn->constant_value().raw();
-        if ((value.IsString() || value.IsMint() || value.IsDouble()) &&
-            !value.IsCanonical()) {
-          const char* error_str = nullptr;
-          value = Instance::Cast(value).CheckAndCanonicalize(T, &error_str);
-          ASSERT(!value.IsNull() && (error_str == nullptr));
-        }
-        ConstantInstr* constant = graph_->GetConstant(value);
+        ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
         defn->ReplaceUsesWith(constant);
         i.RemoveCurrentFromGraph();
       }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 793a26f..e7b1a69 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -32,6 +32,7 @@
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 #include "vm/timeline.h"
+#include "vm/type_testing_stubs.h"
 
 namespace dart {
 
@@ -1232,7 +1233,7 @@
            (block == flow_graph().graph_entry()->normal_entry())));
 }
 
-// Allocate a register that is not explicitly blocked.
+// Allocate a register that is not explictly blocked.
 static Register AllocateFreeRegister(bool* blocked_registers) {
   for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) {
     if (!blocked_registers[regno]) {
@@ -1873,29 +1874,14 @@
   }
 }
 
-bool FlowGraphCompiler::GenerateSubclassTypeCheck(Register class_id_reg,
+bool FlowGraphCompiler::GenerateSubtypeRangeCheck(Register class_id_reg,
                                                   const Class& type_class,
                                                   Label* is_subtype) {
   HierarchyInfo* hi = Thread::Current()->hierarchy_info();
   if (hi != NULL) {
-    // We test up to 4 different cid ranges, if we would need to test more in
-    // order to get a definite answer we fall back to the old mechanism (namely
-    // of going into the subtyping cache)
-    static const intptr_t kMaxNumberOfCidRangesToTest = 4;
-
     const CidRangeVector& ranges = hi->SubtypeRangesForClass(type_class);
     if (ranges.length() <= kMaxNumberOfCidRangesToTest) {
-      Label fail;
-      int bias = 0;
-      for (intptr_t i = 0; i < ranges.length(); ++i) {
-        const CidRange& range = ranges[i];
-        if (!range.IsIllegalRange()) {
-          bias = EmitTestAndCallCheckCid(assembler(), is_subtype, class_id_reg,
-                                         range, bias,
-                                         /*jump_on_miss=*/false);
-        }
-      }
-      __ Bind(&fail);
+      GenerateCidRangesCheck(assembler(), class_id_reg, ranges, is_subtype);
       return true;
     }
   }
@@ -1909,6 +1895,117 @@
   return false;
 }
 
+void FlowGraphCompiler::GenerateCidRangesCheck(Assembler* assembler,
+                                               Register class_id_reg,
+                                               const CidRangeVector& cid_ranges,
+                                               Label* inside_range_lbl,
+                                               Label* outside_range_lbl,
+                                               bool fall_through_if_inside) {
+  // If there are no valid class ranges, the check will fail.  If we are
+  // supposed to fall-through in the positive case, we'll explicitly jump to
+  // the [outside_range_lbl].
+  if (cid_ranges.length() == 1 && cid_ranges[0].IsIllegalRange()) {
+    if (fall_through_if_inside) {
+      assembler->Jump(outside_range_lbl);
+    }
+    return;
+  }
+
+  int bias = 0;
+  for (intptr_t i = 0; i < cid_ranges.length(); ++i) {
+    const CidRange& range = cid_ranges[i];
+    RELEASE_ASSERT(!range.IsIllegalRange());
+    const bool last_round = i == (cid_ranges.length() - 1);
+
+    Label* jump_label = last_round && fall_through_if_inside ? outside_range_lbl
+                                                             : inside_range_lbl;
+    const bool jump_on_miss = last_round && fall_through_if_inside;
+
+    bias = EmitTestAndCallCheckCid(assembler, jump_label, class_id_reg, range,
+                                   bias, jump_on_miss);
+  }
+}
+
+void FlowGraphCompiler::GenerateAssertAssignableAOT(
+    const AbstractType& dst_type,
+    const String& dst_name,
+    const Register instance_reg,
+    const Register instantiator_type_args_reg,
+    const Register function_type_args_reg,
+    const Register subtype_cache_reg,
+    const Register dst_type_reg,
+    const Register scratch_reg,
+    Label* done) {
+  TypeUsageInfo* type_usage_info = thread()->type_usage_info();
+
+  // If the int type is assignable to [dst_type] we special case it on the
+  // caller side!
+  const Type& int_type = Type::Handle(zone(), Type::IntType());
+  bool is_non_smi = false;
+  if (int_type.IsSubtypeOf(dst_type, NULL, NULL, Heap::kOld)) {
+    __ BranchIfSmi(instance_reg, done);
+    is_non_smi = true;
+  }
+
+  // We can handle certain types very efficiently on the call site (with a
+  // bailout to the normal stub, which will do a runtime call).
+  if (dst_type.IsTypeParameter()) {
+    const TypeParameter& type_param = TypeParameter::Cast(dst_type);
+    const Register kTypeArgumentsReg = type_param.IsClassTypeParameter()
+                                           ? instantiator_type_args_reg
+                                           : function_type_args_reg;
+
+    // Check if type arguments are null, i.e. equivalent to vector of dynamic.
+    __ CompareObject(kTypeArgumentsReg, Object::null_object());
+    __ BranchIf(EQUAL, done);
+    __ LoadField(dst_type_reg,
+                 FieldAddress(kTypeArgumentsReg, TypeArguments::type_at_offset(
+                                                     type_param.index())));
+    if (type_usage_info != NULL) {
+      type_usage_info->UseTypeInAssertAssignable(dst_type);
+    }
+  } else {
+    HierarchyInfo* hi = Thread::Current()->hierarchy_info();
+    if (hi != NULL) {
+      const Class& type_class = Class::Handle(zone(), dst_type.type_class());
+
+      bool check_handled_at_callsite = false;
+      bool used_cid_range_check = false;
+      const bool can_use_simple_cid_range_test =
+          hi->CanUseSubtypeRangeCheckFor(dst_type);
+      if (can_use_simple_cid_range_test) {
+        const CidRangeVector& ranges = hi->SubtypeRangesForClass(type_class);
+        if (ranges.length() <= kMaxNumberOfCidRangesToTest) {
+          if (is_non_smi) {
+            __ LoadClassId(scratch_reg, instance_reg);
+          } else {
+            __ LoadClassIdMayBeSmi(scratch_reg, instance_reg);
+          }
+          GenerateCidRangesCheck(assembler(), scratch_reg, ranges, done);
+          used_cid_range_check = true;
+          check_handled_at_callsite = true;
+        }
+      }
+
+      if (!used_cid_range_check && can_use_simple_cid_range_test &&
+          IsListClass(type_class)) {
+        __ LoadClassIdMayBeSmi(scratch_reg, instance_reg);
+        GenerateListTypeCheck(scratch_reg, done);
+        used_cid_range_check = true;
+      }
+
+      // If we haven't handled the positive case of the type check on the
+      // call-site, we want an optimized type testing stub and therefore record
+      // it in the [TypeUsageInfo].
+      if (!check_handled_at_callsite) {
+        ASSERT(type_usage_info != NULL);
+        type_usage_info->UseTypeInAssertAssignable(dst_type);
+      }
+    }
+    __ LoadObject(dst_type_reg, dst_type);
+  }
+}
+
 #undef __
 #endif
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 9a7948f..f61ef7b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -302,6 +302,7 @@
   // Accessors.
   Assembler* assembler() const { return assembler_; }
   const ParsedFunction& parsed_function() const { return parsed_function_; }
+  const Function& function() const { return parsed_function_.function(); }
   const GrowableArray<BlockEntryInstr*>& block_order() const {
     return block_order_;
   }
@@ -363,6 +364,21 @@
                                 const AbstractType& dst_type,
                                 const String& dst_name,
                                 LocationSummary* locs);
+  void GenerateAssertAssignableAOT(TokenPosition token_pos,
+                                   intptr_t deopt_id,
+                                   const AbstractType& dst_type,
+                                   const String& dst_name,
+                                   LocationSummary* locs);
+
+  void GenerateAssertAssignableAOT(const AbstractType& dst_type,
+                                   const String& dst_name,
+                                   const Register instance_reg,
+                                   const Register instantiator_type_args_reg,
+                                   const Register function_type_args_reg,
+                                   const Register subtype_cache_reg,
+                                   const Register dst_type_reg,
+                                   const Register scratch_reg,
+                                   Label* done);
 
 // DBC emits calls very differently from all other architectures due to its
 // interpreted nature.
@@ -431,10 +447,25 @@
   // Returns true if no further checks are necessary but the code coming after
   // the emitted code here is still required do a runtime call (for the negative
   // case of throwing an exception).
-  bool GenerateSubclassTypeCheck(Register class_id_reg,
+  bool GenerateSubtypeRangeCheck(Register class_id_reg,
                                  const Class& type_class,
                                  Label* is_subtype_lbl);
 
+  // We test up to 4 different cid ranges, if we would need to test more in
+  // order to get a definite answer we fall back to the old mechanism (namely
+  // of going into the subtyping cache)
+  static const intptr_t kMaxNumberOfCidRangesToTest = 4;
+
+  // If [fall_through_if_inside] is `true`, then [outside_range_lbl] must be
+  // supplied, since it will be jumped to in the last case if the cid is outside
+  // the range.
+  static void GenerateCidRangesCheck(Assembler* assembler,
+                                     Register class_id_reg,
+                                     const CidRangeVector& cid_ranges,
+                                     Label* inside_range_lbl,
+                                     Label* outside_range_lbl = NULL,
+                                     bool fall_through_if_inside = false);
+
   void EmitOptimizedInstanceCall(const StubEntry& stub_entry,
                                  const ICData& ic_data,
                                  intptr_t deopt_id,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 1917cf9..a27e76c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -381,7 +381,7 @@
 
   // Fast case for cid-range based checks.
   // Warning: This code destroys the contents of [kClassIdReg].
-  if (GenerateSubclassTypeCheck(kClassIdReg, type_class, is_instance_lbl)) {
+  if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
     return false;
   }
 
@@ -641,15 +641,14 @@
           !dst_type.IsVoidType()));
   const Register kInstantiatorTypeArgumentsReg = R2;
   const Register kFunctionTypeArgumentsReg = R1;
-  __ PushList((1 << kInstantiatorTypeArgumentsReg) |
-              (1 << kFunctionTypeArgumentsReg));
-  // A null object is always assignable and is returned as result.
-  Label is_assignable, runtime_call;
-  __ CompareObject(R0, Object::null_object());
-  __ b(&is_assignable, EQ);
 
   // Generate throw new TypeError() if the type is malformed or malbounded.
   if (dst_type.IsMalformedOrMalbounded()) {
+    // A null object is always assignable and is returned as result.
+    Label is_assignable;
+    __ CompareObject(R0, Object::null_object());
+    __ b(&is_assignable, EQ);
+
     __ PushObject(Object::null_object());  // Make room for the result.
     __ Push(R0);                           // Push the source object.
     __ PushObject(dst_name);               // Push the name of the destination.
@@ -660,37 +659,92 @@
     __ bkpt(0);
 
     __ Bind(&is_assignable);  // For a null object.
-    __ PopList((1 << kFunctionTypeArgumentsReg) |
-               (1 << kInstantiatorTypeArgumentsReg));
     return;
   }
 
-  // Generate inline type check, linking to runtime call if not assignable.
-  SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
-  test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
-                                        &runtime_call);
+  if (FLAG_precompiled_mode) {
+    GenerateAssertAssignableAOT(token_pos, deopt_id, dst_type, dst_name, locs);
+  } else {
+    Label is_assignable_fast, is_assignable, runtime_call;
 
-  __ Bind(&runtime_call);
-  __ ldm(
-      IA, SP,
-      (1 << kFunctionTypeArgumentsReg) | (1 << kInstantiatorTypeArgumentsReg));
-  __ PushObject(Object::null_object());  // Make room for the result.
-  __ Push(R0);                           // Push the source object.
-  __ PushObject(dst_type);               // Push the type of the destination.
-  __ PushList((1 << kInstantiatorTypeArgumentsReg) |
-              (1 << kFunctionTypeArgumentsReg));
-  __ PushObject(dst_name);  // Push the name of the destination.
-  __ LoadUniqueObject(R0, test_cache);
-  __ Push(R0);
-  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
-  // Pop the parameters supplied to the runtime entry. The result of the
-  // type check runtime call is the checked value.
-  __ Drop(6);
-  __ Pop(R0);
+    // A null object is always assignable and is returned as result.
+    __ CompareObject(R0, Object::null_object());
+    __ b(&is_assignable_fast, EQ);
 
-  __ Bind(&is_assignable);
-  __ PopList((1 << kFunctionTypeArgumentsReg) |
-             (1 << kInstantiatorTypeArgumentsReg));
+    __ PushList((1 << kInstantiatorTypeArgumentsReg) |
+                (1 << kFunctionTypeArgumentsReg));
+
+    // Generate inline type check, linking to runtime call if not assignable.
+    SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
+    test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
+                                          &runtime_call);
+
+    __ Bind(&runtime_call);
+    __ ldm(IA, SP,
+           (1 << kFunctionTypeArgumentsReg) |
+               (1 << kInstantiatorTypeArgumentsReg));
+    __ PushObject(Object::null_object());  // Make room for the result.
+    __ Push(R0);                           // Push the source object.
+    __ PushObject(dst_type);               // Push the type of the destination.
+    __ PushList((1 << kInstantiatorTypeArgumentsReg) |
+                (1 << kFunctionTypeArgumentsReg));
+    __ PushObject(dst_name);  // Push the name of the destination.
+    __ LoadUniqueObject(R0, test_cache);
+    __ Push(R0);
+    GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+    // Pop the parameters supplied to the runtime entry. The result of the
+    // type check runtime call is the checked value.
+    __ Drop(6);
+    __ Pop(R0);
+    __ Bind(&is_assignable);
+    __ PopList((1 << kFunctionTypeArgumentsReg) |
+               (1 << kInstantiatorTypeArgumentsReg));
+    __ Bind(&is_assignable_fast);
+  }
+}
+
+void FlowGraphCompiler::GenerateAssertAssignableAOT(
+    TokenPosition token_pos,
+    intptr_t deopt_id,
+    const AbstractType& dst_type,
+    const String& dst_name,
+    LocationSummary* locs) {
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R2;
+  const Register kFunctionTypeArgumentsReg = R1;
+
+  const Register kSubtypeTestCacheReg = R3;
+  const Register kDstTypeReg = R8;
+  const Register kScratchReg = R4;
+
+  Label done;
+
+  GenerateAssertAssignableAOT(dst_type, dst_name, kInstanceReg,
+                              kInstantiatorTypeArgumentsReg,
+                              kFunctionTypeArgumentsReg, kSubtypeTestCacheReg,
+                              kDstTypeReg, kScratchReg, &done);
+  // We use 2 consecutive entries in the pool for the subtype cache and the
+  // destination name.  The second entry, namely [dst_name] seems to be unused,
+  // but it will be used by the code throwing a TypeError if the type test fails
+  // (see runtime/vm/runtime_entry.cc:TypeCheck).  It will use pattern matching
+  // on the call site to find out at which pool index the destination name is
+  // located.
+  const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
+      Object::null_object(), Patchability::kPatchable);
+  const intptr_t sub_type_cache_offset =
+      ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
+  const intptr_t dst_name_index =
+      __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+  ASSERT((sub_type_cache_index + 1) == dst_name_index);
+  ASSERT(__ constant_pool_allowed());
+
+  __ LoadField(R9,
+               FieldAddress(kDstTypeReg,
+                            AbstractType::type_test_stub_entry_point_offset()));
+  __ ldr(kSubtypeTestCacheReg, Address(PP, sub_type_cache_offset));
+  __ blx(R9);
+  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  __ Bind(&done);
 }
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
@@ -1195,13 +1249,14 @@
                                                bool jump_on_miss) {
   intptr_t cid_start = range.cid_start;
   if (range.IsSingleCid()) {
-    __ CompareImmediate(class_id_reg, cid_start - bias);
-    __ b(label, jump_on_miss ? NE : EQ);
+    __ AddImmediateSetFlags(class_id_reg, class_id_reg, bias - cid_start);
+    __ BranchIf(jump_on_miss ? NOT_ZERO : ZERO, label);
+    bias = cid_start;
   } else {
     __ AddImmediate(class_id_reg, class_id_reg, bias - cid_start);
-    bias = cid_start;
     __ CompareImmediate(class_id_reg, range.Extent());
-    __ b(label, jump_on_miss ? HI : LS);  // Unsigned higher.
+    __ BranchIf(jump_on_miss ? UNSIGNED_GREATER : UNSIGNED_LESS_EQUAL, label);
+    bias = cid_start;
   }
   return bias;
 }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index dd22a37..c76e56d 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -367,7 +367,7 @@
 
   // Fast case for cid-range based checks.
   // Warning: This code destroys the contents of [kClassIdReg].
-  if (GenerateSubclassTypeCheck(kClassIdReg, type_class, is_instance_lbl)) {
+  if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
     return false;
   }
 
@@ -622,14 +622,14 @@
           !dst_type.IsVoidType()));
   const Register kInstantiatorTypeArgumentsReg = R1;
   const Register kFunctionTypeArgumentsReg = R2;
-  __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
-  // A null object is always assignable and is returned as result.
-  Label is_assignable, runtime_call;
-  __ CompareObject(R0, Object::null_object());
-  __ b(&is_assignable, EQ);
 
   // Generate throw new TypeError() if the type is malformed or malbounded.
   if (dst_type.IsMalformedOrMalbounded()) {
+    // A null object is always assignable and is returned as result.
+    Label is_assignable, runtime_call;
+    __ CompareObject(R0, Object::null_object());
+    __ b(&is_assignable, EQ);
+
     __ PushObject(Object::null_object());  // Make room for the result.
     __ Push(R0);                           // Push the source object.
     __ PushObject(dst_name);               // Push the name of the destination.
@@ -640,33 +640,89 @@
     __ brk(0);
 
     __ Bind(&is_assignable);  // For a null object.
-    __ PopPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
     return;
   }
 
-  // Generate inline type check, linking to runtime call if not assignable.
-  SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
-  test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
-                                        &runtime_call);
+  if (FLAG_precompiled_mode) {
+    GenerateAssertAssignableAOT(token_pos, deopt_id, dst_type, dst_name, locs);
+  } else {
+    Label is_assignable_fast, is_assignable, runtime_call;
 
-  __ Bind(&runtime_call);
-  __ ldp(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg,
-         Address(SP, 0 * kWordSize, Address::PairOffset));
-  __ PushObject(Object::null_object());  // Make room for the result.
-  __ Push(R0);                           // Push the source object.
-  __ PushObject(dst_type);               // Push the type of the destination.
-  __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
-  __ PushObject(dst_name);  // Push the name of the destination.
-  __ LoadUniqueObject(R0, test_cache);
-  __ Push(R0);
-  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
-  // Pop the parameters supplied to the runtime entry. The result of the
-  // type check runtime call is the checked value.
-  __ Drop(6);
-  __ Pop(R0);
+    // A null object is always assignable and is returned as result.
+    __ CompareObject(R0, Object::null_object());
+    __ b(&is_assignable_fast, EQ);
 
-  __ Bind(&is_assignable);
-  __ PopPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+    __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+
+    // Generate inline type check, linking to runtime call if not assignable.
+    SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
+    test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
+                                          &runtime_call);
+
+    __ Bind(&runtime_call);
+    __ ldp(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg,
+           Address(SP, 0 * kWordSize, Address::PairOffset));
+    __ PushObject(Object::null_object());  // Make room for the result.
+    __ Push(R0);                           // Push the source object.
+    __ PushObject(dst_type);               // Push the type of the destination.
+    __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+    __ PushObject(dst_name);  // Push the name of the destination.
+    __ LoadUniqueObject(R0, test_cache);
+    __ Push(R0);
+    GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+    // Pop the parameters supplied to the runtime entry. The result of the
+    // type check runtime call is the checked value.
+    __ Drop(6);
+    __ Pop(R0);
+    __ Bind(&is_assignable);
+    __ PopPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+    __ Bind(&is_assignable_fast);
+  }
+}
+
+void FlowGraphCompiler::GenerateAssertAssignableAOT(
+    TokenPosition token_pos,
+    intptr_t deopt_id,
+    const AbstractType& dst_type,
+    const String& dst_name,
+    LocationSummary* locs) {
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R1;
+  const Register kFunctionTypeArgumentsReg = R2;
+
+  const Register kSubtypeTestCacheReg = R3;
+  const Register kDstTypeReg = R8;
+  const Register kScratchReg = R4;
+
+  Label done;
+
+  GenerateAssertAssignableAOT(dst_type, dst_name, kInstanceReg,
+                              kInstantiatorTypeArgumentsReg,
+                              kFunctionTypeArgumentsReg, kSubtypeTestCacheReg,
+                              kDstTypeReg, kScratchReg, &done);
+
+  // We use 2 consecutive entries in the pool for the subtype cache and the
+  // destination name.  The second entry, namely [dst_name] seems to be unused,
+  // but it will be used by the code throwing a TypeError if the type test fails
+  // (see runtime/vm/runtime_entry.cc:TypeCheck).  It will use pattern matching
+  // on the call site to find out at which pool index the destination name is
+  // located.
+  const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
+      Object::null_object(), Patchability::kPatchable);
+  const intptr_t sub_type_cache_offset =
+      ObjectPool::element_offset(sub_type_cache_index);
+  const intptr_t dst_name_index =
+      __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+  ASSERT((sub_type_cache_index + 1) == dst_name_index);
+  ASSERT(__ constant_pool_allowed());
+
+  __ LoadField(R9,
+               FieldAddress(kDstTypeReg,
+                            AbstractType::type_test_stub_entry_point_offset()));
+  __ ldr(kSubtypeTestCacheReg, Address(PP, sub_type_cache_offset));
+  __ blr(R9);
+  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  __ Bind(&done);
 }
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
@@ -1146,15 +1202,16 @@
                                                const CidRange& range,
                                                int bias,
                                                bool jump_on_miss) {
-  intptr_t cid_start = range.cid_start;
+  const intptr_t cid_start = range.cid_start;
   if (range.IsSingleCid()) {
-    __ CompareImmediate(class_id_reg, cid_start - bias);
-    __ b(label, jump_on_miss ? NE : EQ);
+    __ AddImmediateSetFlags(class_id_reg, class_id_reg, bias - cid_start);
+    __ BranchIf(jump_on_miss ? NOT_EQUAL : EQUAL, label);
+    bias = cid_start;
   } else {
     __ AddImmediate(class_id_reg, bias - cid_start);
     bias = cid_start;
     __ CompareImmediate(class_id_reg, range.Extent());
-    __ b(label, jump_on_miss ? HI : LS);  // Unsigned higher / less-or-equal.
+    __ BranchIf(jump_on_miss ? UNSIGNED_GREATER : UNSIGNED_LESS_EQUAL, label);
   }
   return bias;
 }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 712ab2e..0580e5c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -384,7 +384,7 @@
 
   // Fast case for cid-range based checks.
   // Warning: This code destroys the contents of [kClassIdReg].
-  if (GenerateSubclassTypeCheck(kClassIdReg, type_class, is_instance_lbl)) {
+  if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
     return false;
   }
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index d710b8c..4a2c58b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -382,7 +382,7 @@
 
   // Fast case for cid-range based checks.
   // Warning: This code destroys the contents of [kClassIdReg].
-  if (GenerateSubclassTypeCheck(kClassIdReg, type_class, is_instance_lbl)) {
+  if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
     return false;
   }
 
@@ -630,13 +630,17 @@
   ASSERT(dst_type.IsMalformedOrMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType() &&
           !dst_type.IsVoidType()));
-  // A null object is always assignable and is returned as result.
-  Label is_assignable, runtime_call;
-  __ CompareObject(RAX, Object::null_object());
-  __ j(EQUAL, &is_assignable);
 
+  const Register kInstantiatorTypeArgumentsReg = RDX;
+  const Register kFunctionTypeArgumentsReg = RCX;
+
+  // A null object is always assignable and is returned as result.
   // Generate throw new TypeError() if the type is malformed or malbounded.
   if (dst_type.IsMalformedOrMalbounded()) {
+    Label is_assignable;
+    __ CompareObject(RAX, Object::null_object());
+    __ j(EQUAL, &is_assignable);
+
     __ PushObject(Object::null_object());  // Make room for the result.
     __ pushq(RAX);                         // Push the source object.
     __ PushObject(dst_name);               // Push the name of the destination.
@@ -650,28 +654,79 @@
     return;
   }
 
-  // Generate inline type check, linking to runtime call if not assignable.
-  SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
-  // The registers RAX, RCX, RDX are preserved across the call.
-  test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
-                                        &runtime_call);
+  if (FLAG_precompiled_mode) {
+    GenerateAssertAssignableAOT(token_pos, deopt_id, dst_type, dst_name, locs);
+  } else {
+    Label is_assignable, runtime_call;
 
-  __ Bind(&runtime_call);
-  __ PushObject(Object::null_object());  // Make room for the result.
-  __ pushq(RAX);                         // Push the source object.
-  __ PushObject(dst_type);               // Push the type of the destination.
-  __ pushq(RDX);                         // Instantiator type arguments.
-  __ pushq(RCX);                         // Function type arguments.
-  __ PushObject(dst_name);               // Push the name of the destination.
-  __ LoadUniqueObject(RAX, test_cache);
-  __ pushq(RAX);
-  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
-  // Pop the parameters supplied to the runtime entry. The result of the
-  // type check runtime call is the checked value.
-  __ Drop(6);
-  __ popq(RAX);
+    // A null object is always assignable and is returned as result.
+    __ CompareObject(RAX, Object::null_object());
+    __ j(EQUAL, &is_assignable);
 
-  __ Bind(&is_assignable);
+    // Generate inline type check, linking to runtime call if not assignable.
+    SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
+    // The registers RAX, RCX, RDX are preserved across the call.
+    test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
+                                          &runtime_call);
+
+    __ Bind(&runtime_call);
+    __ PushObject(Object::null_object());  // Make room for the result.
+    __ pushq(RAX);                         // Push the source object.
+    __ PushObject(dst_type);               // Push the type of the destination.
+    __ pushq(kInstantiatorTypeArgumentsReg);
+    __ pushq(kFunctionTypeArgumentsReg);
+    __ PushObject(dst_name);  // Push the name of the destination.
+    __ LoadUniqueObject(RAX, test_cache);
+    __ pushq(RAX);
+    GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+    // Pop the parameters supplied to the runtime entry. The result of the
+    // type check runtime call is the checked value.
+    __ Drop(6);
+    __ popq(RAX);
+    __ Bind(&is_assignable);
+  }
+}
+
+void FlowGraphCompiler::GenerateAssertAssignableAOT(
+    TokenPosition token_pos,
+    intptr_t deopt_id,
+    const AbstractType& dst_type,
+    const String& dst_name,
+    LocationSummary* locs) {
+  const Register kInstanceReg = RAX;
+  const Register kInstantiatorTypeArgumentsReg = RDX;
+  const Register kFunctionTypeArgumentsReg = RCX;
+
+  Label done;
+
+  const Register subtype_cache_reg = R9;
+  const Register kScratchReg = RBX;
+
+  GenerateAssertAssignableAOT(dst_type, dst_name, kInstanceReg,
+                              kInstantiatorTypeArgumentsReg,
+                              kFunctionTypeArgumentsReg, subtype_cache_reg,
+                              kScratchReg, kScratchReg, &done);
+
+  // We use 2 consecutive entries in the pool for the subtype cache and the
+  // destination name.  The second entry, namely [dst_name] seems to be unused,
+  // but it will be used by the code throwing a TypeError if the type test fails
+  // (see runtime/vm/runtime_entry.cc:TypeCheck).  It will use pattern matching
+  // on the call site to find out at which pool index the destination name is
+  // located.
+  const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
+      Object::null_object(), Patchability::kPatchable);
+  const intptr_t sub_type_cache_offset =
+      ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
+  const intptr_t dst_name_index =
+      __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+  ASSERT((sub_type_cache_index + 1) == dst_name_index);
+  ASSERT(__ constant_pool_allowed());
+
+  __ movq(subtype_cache_reg,
+          Address::AddressBaseImm32(PP, sub_type_cache_offset));
+  __ call(FieldAddress(RBX, AbstractType::type_test_stub_entry_point_offset()));
+  EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+  __ Bind(&done);
 }
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
@@ -1108,16 +1163,18 @@
                                                const CidRange& range,
                                                int bias,
                                                bool jump_on_miss) {
+  // Note of WARNING: Due to smaller instruction encoding we use the 32-bit
+  // instructions on x64, which means the compare instruction has to be
+  // 32-bit (since the subtraction instruction is as well).
   intptr_t cid_start = range.cid_start;
   if (range.IsSingleCid()) {
     __ cmpl(class_id_reg, Immediate(cid_start - bias));
-    __ j(jump_on_miss ? NOT_EQUAL : EQUAL, label);
+    __ BranchIf(jump_on_miss ? NOT_EQUAL : EQUAL, label);
   } else {
     __ addl(class_id_reg, Immediate(bias - cid_start));
     bias = cid_start;
     __ cmpl(class_id_reg, Immediate(range.Extent()));
-    __ j(jump_on_miss ? ABOVE : BELOW_EQUAL,
-         label);  // Unsigned higher / lower-or-equal.
+    __ BranchIf(jump_on_miss ? UNSIGNED_GREATER : UNSIGNED_LESS_EQUAL, label);
   }
   return bias;
 }
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 4967657..4f2db6a 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -27,6 +27,7 @@
 #include "vm/scopes.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
 
 #include "vm/compiler/backend/il_printer.h"
 
@@ -46,23 +47,28 @@
             "Support unboxed double and float32x4 fields.");
 DECLARE_FLAG(bool, eliminate_type_checks);
 
-const CidRangeVector& HierarchyInfo::SubtypeRangesForClass(const Class& klass) {
-  ClassTable* table = thread_->isolate()->class_table();
+const CidRangeVector& HierarchyInfo::SubtypeRangesForClass(
+    const Class& klass,
+    bool include_abstract) {
+  ClassTable* table = thread()->isolate()->class_table();
   const intptr_t cid_count = table->NumCids();
-  if (cid_subtype_ranges_ == NULL) {
-    cid_subtype_ranges_ = new CidRangeVector[cid_count];
+  CidRangeVector** cid_ranges =
+      include_abstract ? &cid_subtype_ranges_abstract_ : &cid_subtype_ranges_;
+  if (*cid_ranges == NULL) {
+    *cid_ranges = new CidRangeVector[cid_count];
   }
 
-  CidRangeVector& ranges = cid_subtype_ranges_[klass.id()];
+  CidRangeVector& ranges = (*cid_ranges)[klass.id()];
   if (ranges.length() == 0) {
-    BuildRangesFor(table, &ranges, klass, /*use_subtype_test=*/true);
+    BuildRangesFor(table, &ranges, klass, /*use_subtype_test=*/true,
+                   include_abstract);
   }
   return ranges;
 }
 
 const CidRangeVector& HierarchyInfo::SubclassRangesForClass(
     const Class& klass) {
-  ClassTable* table = thread_->isolate()->class_table();
+  ClassTable* table = thread()->isolate()->class_table();
   const intptr_t cid_count = table->NumCids();
   if (cid_subclass_ranges_ == NULL) {
     cid_subclass_ranges_ = new CidRangeVector[cid_count];
@@ -78,8 +84,9 @@
 void HierarchyInfo::BuildRangesFor(ClassTable* table,
                                    CidRangeVector* ranges,
                                    const Class& klass,
-                                   bool use_subtype_test) {
-  Zone* zone = thread_->zone();
+                                   bool use_subtype_test,
+                                   bool include_abstract) {
+  Zone* zone = thread()->zone();
   Class& cls = Class::Handle(zone);
 
   // Only really used if `use_subtype_test == true`.
@@ -92,8 +99,8 @@
   for (intptr_t cid = kInstanceCid; cid < cid_count; ++cid) {
     // Create local zone because deep hierarchies may allocate lots of handles
     // within one iteration of this loop.
-    StackZone stack_zone(thread_);
-    HANDLESCOPE(thread_);
+    StackZone stack_zone(thread());
+    HANDLESCOPE(thread());
 
     if (!table->HasValidClassAt(cid)) continue;
     if (cid == kTypeArgumentsCid) continue;
@@ -101,7 +108,7 @@
     if (cid == kDynamicCid) continue;
     if (cid == kNullCid) continue;
     cls = table->At(cid);
-    if (cls.is_abstract()) continue;
+    if (!include_abstract && cls.is_abstract()) continue;
     if (cls.is_patch()) continue;
     if (cls.IsTopLevel()) continue;
 
@@ -144,14 +151,26 @@
 bool HierarchyInfo::CanUseSubtypeRangeCheckFor(const AbstractType& type) {
   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
 
-  if (!type.IsInstantiated() || type.IsFunctionType() ||
+  if (!type.IsInstantiated() || !type.IsType() || type.IsFunctionType() ||
       type.IsDartFunctionType()) {
     return false;
   }
 
-  Zone* zone = thread_->zone();
+  Zone* zone = thread()->zone();
   const Class& type_class = Class::Handle(zone, type.type_class());
 
+  // The FutureOr<T> type cannot be handled by checking whether the instance is
+  // a subtype of FutureOr and then checking whether the type argument `T`
+  // matches.
+  //
+  // Instead we would need to perform multiple checks:
+  //
+  //    instance is Null || instance is T || instance is Future<T>
+  //
+  if (type_class.IsFutureOrClass()) {
+    return false;
+  }
+
   // We can use class id range checks only if we don't have to test type
   // arguments.
   //
@@ -175,7 +194,7 @@
     const AbstractType& type) {
   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
 
-  if (type.IsFunctionType() || type.IsDartFunctionType()) {
+  if (!type.IsType() || type.IsFunctionType() || type.IsDartFunctionType()) {
     return false;
   }
 
@@ -183,11 +202,23 @@
   // [CanUseSubtypeRangeCheckFor], since we handle type parameters in the type
   // expression in some cases (see below).
 
-  Zone* zone = thread_->zone();
+  Zone* zone = thread()->zone();
   const Class& type_class = Class::Handle(zone, type.type_class());
   const intptr_t num_type_parameters = type_class.NumTypeParameters();
   const intptr_t num_type_arguments = type_class.NumTypeArguments();
 
+  // The FutureOr<T> type cannot be handled by checking whether the instance is
+  // a subtype of FutureOr and then checking whether the type argument `T`
+  // matches.
+  //
+  // Instead we would need to perform multiple checks:
+  //
+  //    instance is Null || instance is T || instance is Future<T>
+  //
+  if (type_class.IsFutureOrClass()) {
+    return false;
+  }
+
   // This function should only be called for generic classes.
   ASSERT(type_class.NumTypeParameters() > 0 &&
          type.arguments() != TypeArguments::null());
@@ -225,7 +256,8 @@
                                             intptr_t* lower_limit,
                                             intptr_t* upper_limit) {
   if (CanUseSubtypeRangeCheckFor(type)) {
-    const Class& type_class = Class::Handle(thread_->zone(), type.type_class());
+    const Class& type_class =
+        Class::Handle(thread()->zone(), type.type_class());
     const CidRangeVector& ranges = SubtypeRangesForClass(type_class);
     if (ranges.length() == 1) {
       const CidRange& range = ranges[0];
@@ -3766,6 +3798,14 @@
   ArgumentsInfo args_info(type_args_len(), ArgumentCount(), argument_names());
   compiler->GenerateStaticCall(deopt_id(), token_pos(), function(), args_info,
                                locs(), *call_ic_data, rebind_rule_);
+  if (function().IsFactory()) {
+    TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+    if (type_usage_info != nullptr) {
+      const Class& klass = Class::Handle(function().Owner());
+      RegisterTypeArgumentsUse(compiler->function(), type_usage_info, klass,
+                               ArgumentAt(0));
+    }
+  }
 #else
   const Array& arguments_descriptor = Array::Handle(
       zone, (ic_data() == NULL) ? GetArgumentsDescriptor()
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index aaed3e0..829a16e 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -37,6 +37,7 @@
 class RangeAnalysis;
 class RangeBoundary;
 class UnboxIntegerInstr;
+class TypeUsageInfo;
 
 // CompileType describes type of the value produced by the definition.
 //
@@ -351,23 +352,27 @@
  public:
   explicit HierarchyInfo(Thread* thread)
       : StackResource(thread),
-        thread_(thread),
         cid_subtype_ranges_(NULL),
+        cid_subtype_ranges_abstract_(NULL),
         cid_subclass_ranges_(NULL) {
     thread->set_hierarchy_info(this);
   }
 
   ~HierarchyInfo() {
-    thread_->set_hierarchy_info(NULL);
+    thread()->set_hierarchy_info(NULL);
 
     delete[] cid_subtype_ranges_;
     cid_subtype_ranges_ = NULL;
 
+    delete[] cid_subtype_ranges_abstract_;
+    cid_subtype_ranges_abstract_ = NULL;
+
     delete[] cid_subclass_ranges_;
     cid_subclass_ranges_ = NULL;
   }
 
-  const CidRangeVector& SubtypeRangesForClass(const Class& klass);
+  const CidRangeVector& SubtypeRangesForClass(const Class& klass,
+                                              bool include_abstract = false);
   const CidRangeVector& SubclassRangesForClass(const Class& klass);
 
   bool InstanceOfHasClassRange(const AbstractType& type,
@@ -396,10 +401,11 @@
   void BuildRangesFor(ClassTable* table,
                       CidRangeVector* ranges,
                       const Class& klass,
-                      bool use_subtype_test);
+                      bool use_subtype_test,
+                      bool include_abstract = false);
 
-  Thread* thread_;
   CidRangeVector* cid_subtype_ranges_;
+  CidRangeVector* cid_subtype_ranges_abstract_;
   CidRangeVector* cid_subclass_ranges_;
 };
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 01bf389..cd4d8f0 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -22,6 +22,7 @@
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
 
 #define __ compiler->assembler()->
 #define Z (compiler->zone())
@@ -395,14 +396,55 @@
 
 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
+  // In AOT mode, we want to prevent spilling of the function/instantiator type
+  // argument vectors, since we preserve them.  So we make this a `kNoCall`
+  // summary.  Though most other registers can be modified by the type testing
+  // stubs we are calling.  To tell the register allocator about it, we reserve
+  // all the other registers as temporary registers.
+  // TODO(http://dartbug.com/32788): Simplify this.
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R2;
+  const Register kFunctionTypeArgumentsReg = R1;
+
+  const intptr_t kNonChangeableInputRegs =
+      (1 << kInstanceReg) | (1 << kInstantiatorTypeArgumentsReg) |
+      (1 << kFunctionTypeArgumentsReg);
+
   const intptr_t kNumInputs = 3;
-  const intptr_t kNumTemps = 0;
+
+  const intptr_t kNumTemps =
+      FLAG_precompiled_mode ? (Utils::CountOneBits64(kDartAvailableCpuRegs) -
+                               Utils::CountOneBits64(kNonChangeableInputRegs))
+                            : 0;
+
   LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(R0));  // Value.
-  summary->set_in(1, Location::RegisterLocation(R2));  // Instant. type args.
-  summary->set_in(2, Location::RegisterLocation(R1));  // Function type args.
-  summary->set_out(0, Location::RegisterLocation(R0));
+      LocationSummary(zone, kNumInputs, kNumTemps,
+                      FLAG_precompiled_mode ? LocationSummary::kCallCalleeSafe
+                                            : LocationSummary::kCall);
+  summary->set_in(0, Location::RegisterLocation(kInstanceReg));  // Value.
+  summary->set_in(1,
+                  Location::RegisterLocation(
+                      kInstantiatorTypeArgumentsReg));  // Instant. type args.
+  summary->set_in(2, Location::RegisterLocation(
+                         kFunctionTypeArgumentsReg));  // Function type args.
+
+  // TODO(http://dartbug.com/32787): Use Location::SameAsFirstInput() instead,
+  // once register allocator no longer hits assertion.
+  summary->set_out(0, Location::RegisterLocation(kInstanceReg));
+
+  if (FLAG_precompiled_mode) {
+    // Let's reserve all registers except for the input ones.
+    intptr_t next_temp = 0;
+    for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+      const bool is_allocatable = ((1 << i) & kDartAvailableCpuRegs) != 0;
+      const bool is_input = ((1 << i) & kNonChangeableInputRegs) != 0;
+      if (is_allocatable && !is_input) {
+        summary->set_temp(next_temp++,
+                          Location::RegisterLocation(static_cast<Register>(i)));
+      }
+    }
+  }
+
   return summary;
 }
 
@@ -2391,6 +2433,14 @@
 }
 
 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+  if (type_usage_info != nullptr) {
+    const Class& list_class = Class::Handle(
+        compiler->thread()->isolate()->class_table()->At(kArrayCid));
+    RegisterTypeArgumentsUse(compiler->function(), type_usage_info, list_class,
+                             element_type()->definition());
+  }
+
   const Register kLengthReg = R2;
   const Register kElemTypeReg = R1;
   const Register kResultReg = R0;
@@ -6344,6 +6394,13 @@
 }
 
 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (ArgumentCount() == 1) {
+    TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+    if (type_usage_info != nullptr) {
+      RegisterTypeArgumentsUse(compiler->function(), type_usage_info, cls_,
+                               ArgumentAt(0));
+    }
+  }
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
   const StubEntry stub_entry(stub);
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index b2e0a9d..595c61a 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -21,6 +21,7 @@
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
 
 #define __ compiler->assembler()->
 #define Z (compiler->zone())
@@ -393,14 +394,55 @@
 
 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
+  // In AOT mode, we want to prevent spilling of the function/instantiator type
+  // argument vectors, since we preserve them.  So we make this a `kNoCall`
+  // summary.  Though most other registers can be modified by the type testing
+  // stubs we are calling.  To tell the register allocator about it, we reserve
+  // all the other registers as temporary registers.
+  // TODO(http://dartbug.com/32788): Simplify this.
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R1;
+  const Register kFunctionTypeArgumentsReg = R2;
+
+  const intptr_t kNonChangeableInputRegs =
+      (1 << kInstanceReg) | (1 << kInstantiatorTypeArgumentsReg) |
+      (1 << kFunctionTypeArgumentsReg);
+
   const intptr_t kNumInputs = 3;
-  const intptr_t kNumTemps = 0;
+
+  const intptr_t kNumTemps =
+      FLAG_precompiled_mode ? (Utils::CountOneBits64(kDartAvailableCpuRegs) -
+                               Utils::CountOneBits64(kNonChangeableInputRegs))
+                            : 0;
+
   LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(R0));  // Value.
-  summary->set_in(1, Location::RegisterLocation(R1));  // Instant. type args.
-  summary->set_in(2, Location::RegisterLocation(R2));  // Function type args.
-  summary->set_out(0, Location::RegisterLocation(R0));
+      LocationSummary(zone, kNumInputs, kNumTemps,
+                      FLAG_precompiled_mode ? LocationSummary::kCallCalleeSafe
+                                            : LocationSummary::kCall);
+  summary->set_in(0, Location::RegisterLocation(kInstanceReg));  // Value.
+  summary->set_in(1,
+                  Location::RegisterLocation(
+                      kInstantiatorTypeArgumentsReg));  // Instant. type args.
+  summary->set_in(2, Location::RegisterLocation(
+                         kFunctionTypeArgumentsReg));  // Function type args.
+
+  // TODO(http://dartbug.com/32787): Use Location::SameAsFirstInput() instead,
+  // once register allocator no longer hits assertion.
+  summary->set_out(0, Location::RegisterLocation(kInstanceReg));
+
+  if (FLAG_precompiled_mode) {
+    // Let's reserve all registers except for the input ones.
+    intptr_t next_temp = 0;
+    for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+      const bool is_allocatable = ((1 << i) & kDartAvailableCpuRegs) != 0;
+      const bool is_input = ((1 << i) & kNonChangeableInputRegs) != 0;
+      if (is_allocatable && !is_input) {
+        summary->set_temp(next_temp++,
+                          Location::RegisterLocation(static_cast<Register>(i)));
+      }
+    }
+  }
+
   return summary;
 }
 
@@ -2148,6 +2190,14 @@
 }
 
 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+  if (type_usage_info != nullptr) {
+    const Class& list_class = Class::Handle(
+        compiler->thread()->isolate()->class_table()->At(kArrayCid));
+    RegisterTypeArgumentsUse(compiler->function(), type_usage_info, list_class,
+                             element_type()->definition());
+  }
+
   const Register kLengthReg = R2;
   const Register kElemTypeReg = R1;
   const Register kResultReg = R0;
@@ -5552,6 +5602,13 @@
 }
 
 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (ArgumentCount() == 1) {
+    TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+    if (type_usage_info != nullptr) {
+      RegisterTypeArgumentsUse(compiler->function(), type_usage_info, cls_,
+                               ArgumentAt(0));
+    }
+  }
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
   const StubEntry stub_entry(stub);
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index f3109b6..20495f3 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -20,6 +20,7 @@
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
 
 #define __ compiler->assembler()->
 #define Z (compiler->zone())
@@ -361,14 +362,55 @@
 
 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
+  // In AOT mode, we want to prevent spilling of the function/instantiator type
+  // argument vectors, since we preserve them.  So we make this a `kNoCall`
+  // summary.  Though most other registers can be modified by the type testing
+  // stubs we are calling.  To tell the register allocator about it, we reserve
+  // all the other registers as temporary registers.
+  // TODO(http://dartbug.com/32788): Simplify this.
+  const Register kInstanceReg = RAX;
+  const Register kInstantiatorTypeArgumentsReg = RDX;
+  const Register kFunctionTypeArgumentsReg = RCX;
+
+  const intptr_t kNonChangeableInputRegs =
+      (1 << kInstanceReg) | (1 << kInstantiatorTypeArgumentsReg) |
+      (1 << kFunctionTypeArgumentsReg);
+
   const intptr_t kNumInputs = 3;
-  const intptr_t kNumTemps = 0;
+
+  const intptr_t kNumTemps =
+      FLAG_precompiled_mode ? (Utils::CountOneBits64(kDartAvailableCpuRegs) -
+                               Utils::CountOneBits64(kNonChangeableInputRegs))
+                            : 0;
+
   LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(RAX));  // Value.
-  summary->set_in(1, Location::RegisterLocation(RDX));  // Instant. type args.
-  summary->set_in(2, Location::RegisterLocation(RCX));  // Function type args.
-  summary->set_out(0, Location::RegisterLocation(RAX));
+      LocationSummary(zone, kNumInputs, kNumTemps,
+                      FLAG_precompiled_mode ? LocationSummary::kCallCalleeSafe
+                                            : LocationSummary::kCall);
+  summary->set_in(0, Location::RegisterLocation(kInstanceReg));  // Value.
+  summary->set_in(1,
+                  Location::RegisterLocation(
+                      kInstantiatorTypeArgumentsReg));  // Instant. type args.
+  summary->set_in(2, Location::RegisterLocation(
+                         kFunctionTypeArgumentsReg));  // Function type args.
+
+  // TODO(http://dartbug.com/32787): Use Location::SameAsFirstInput() instead,
+  // once register allocator no longer hits assertion.
+  summary->set_out(0, Location::RegisterLocation(kInstanceReg));
+
+  if (FLAG_precompiled_mode) {
+    // Let's reserve all registers except for the input ones.
+    intptr_t next_temp = 0;
+    for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+      const bool is_allocatable = ((1 << i) & kDartAvailableCpuRegs) != 0;
+      const bool is_input = ((1 << i) & kNonChangeableInputRegs) != 0;
+      if (is_allocatable && !is_input) {
+        summary->set_temp(next_temp++,
+                          Location::RegisterLocation(static_cast<Register>(i)));
+      }
+    }
+  }
+
   return summary;
 }
 
@@ -2077,6 +2119,14 @@
 }
 
 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+  if (type_usage_info != nullptr) {
+    const Class& list_class = Class::Handle(
+        compiler->thread()->isolate()->class_table()->At(kArrayCid));
+    RegisterTypeArgumentsUse(compiler->function(), type_usage_info, list_class,
+                             element_type()->definition());
+  }
+
   // Allocate the array.  R10 = length, RBX = element type.
   const Register kLengthReg = R10;
   const Register kElemTypeReg = RBX;
@@ -5738,6 +5788,13 @@
 }
 
 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (ArgumentCount() == 1) {
+    TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+    if (type_usage_info != nullptr) {
+      RegisterTypeArgumentsUse(compiler->function(), type_usage_info, cls_,
+                               ArgumentAt(0));
+    }
+  }
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
   const StubEntry stub_entry(stub);
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 9abd019..10d2c09 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -1373,7 +1373,7 @@
 // Note that on DBC registers are always essentially spilled so
 // we don't need to block anything.
 #if !defined(TARGET_ARCH_DBC)
-  if (locs->always_calls()) {
+  if (locs->always_calls() && !locs->callee_safe_call()) {
     // Expected shape of live range:
     //
     //              i  i'
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index 2cf9a45..f6ffbab 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -570,7 +570,8 @@
   enum ContainsCall {
     kNoCall,  // Used registers must be reserved as tmp.
     kCall,    // Registers have been saved and can be used without reservation.
-    kCallOnSlowPath  // Used registers must be reserved as tmp.
+    kCallCalleeSafe,  // Registers will be saved by the callee.
+    kCallOnSlowPath   // Used registers must be reserved as tmp.
   };
 
   LocationSummary(Zone* zone,
@@ -651,7 +652,11 @@
   }
   void SetStackBit(intptr_t index) { stack_bitmap()->Set(index, true); }
 
-  bool always_calls() const { return contains_call_ == kCall; }
+  bool always_calls() const {
+    return contains_call_ == kCall || contains_call_ == kCallCalleeSafe;
+  }
+
+  bool callee_safe_call() const { return contains_call_ == kCallCalleeSafe; }
 
   bool can_call() { return contains_call_ != kNoCall; }
 
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 684a6c3..a0cb2ef 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4202,7 +4202,8 @@
 
   if (!target.IsNull() && (target.raw() != parent.raw())) {
     DEBUG_ASSERT(Isolate::Current()->HasAttemptedReload());
-    if ((target.is_static() != parent.is_static()) || (target.kind() != parent.kind())) {
+    if ((target.is_static() != parent.is_static()) ||
+        (target.kind() != parent.kind())) {
       target = Function::null();
     }
   }
@@ -8327,9 +8328,9 @@
     TokenPosition* position) {
   if (position != NULL) *position = TokenPosition::kNoSource;
 
-  Double& constant = Double::ZoneHandle(
-      Z, Double::NewCanonical(
-             H.DartString(ReadStringReference())));  // read string reference.
+  Double& constant =
+      Double::ZoneHandle(Z, Double::New(H.DartString(ReadStringReference()),
+                                        Heap::kOld));  // read string reference.
   return Constant(constant);
 }
 
diff --git a/runtime/vm/compiler/method_recognizer.h b/runtime/vm/compiler/method_recognizer.h
index 1203498..afffc77 100644
--- a/runtime/vm/compiler/method_recognizer.h
+++ b/runtime/vm/compiler/method_recognizer.h
@@ -409,24 +409,24 @@
   V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 0x62f615e4)                  \
   V(_ByteDataView, setInt8, ByteDataViewSetInt8, 0x6395293e)                   \
   V(_ByteDataView, setUint8, ByteDataViewSetUint8, 0x79979d1f)                 \
-  V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x57499d9c)                 \
-  V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x4dd87acb)               \
-  V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x57213f62)                 \
-  V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x5f315c42)               \
-  V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x476e7eb8)                 \
-  V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x6d64f0fa)               \
-  V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x12197195)             \
-  V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x14d20ad7)             \
+  V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x525ec534)                 \
+  V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x48eda263)               \
+  V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x523666fa)                 \
+  V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x5a4683da)               \
+  V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x4283a650)                 \
+  V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x687a1892)               \
+  V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x7d5784fd)             \
+  V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x00101e3f)             \
   V(_ByteDataView, getInt8, ByteDataViewGetInt8, 0x68448b4d)                   \
   V(_ByteDataView, getUint8, ByteDataViewGetUint8, 0x5d68cbf2)                 \
-  V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x2f4f6115)                 \
-  V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x10556170)               \
-  V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x00435162)                 \
-  V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x6fd07e56)               \
-  V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x3e124984)                 \
-  V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x2798f8e3)               \
-  V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x77404fe1)             \
-  V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x771585bf)             \
+  V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x691b5ead)                 \
+  V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x78b744d8)               \
+  V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x3a0f4efa)                 \
+  V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x583261be)               \
+  V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x77de471c)                 \
+  V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x0ffadc4b)               \
+  V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x6a205749)             \
+  V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x69f58d27)             \
   V(::, exp, MathExp, 0x32ab9efa)                                              \
   V(::, log, MathLog, 0x1ee8f9fc)                                              \
   V(::, max, MathMax, 0x377e8889)                                              \
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 8ca2c59..48cc6c3 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -347,7 +347,9 @@
 
   // Platform-independent variants declared for all platforms
   EQUAL = EQ,
+  ZERO = EQUAL,
   NOT_EQUAL = NE,
+  NOT_ZERO = NOT_EQUAL,
   LESS = LT,
   LESS_EQUAL = LE,
   GREATER_EQUAL = GE,
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 829e3d9..594baf4 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -195,7 +195,9 @@
 
   // Platform-independent variants declared for all platforms
   EQUAL = EQ,
+  ZERO = EQUAL,
   NOT_EQUAL = NE,
+  NOT_ZERO = NOT_EQUAL,
   LESS = LT,
   LESS_EQUAL = LE,
   GREATER_EQUAL = GE,
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index c003966..fb393bd 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -217,6 +217,7 @@
         return strdup("Precompiled runtime requires a precompiled snapshot");
 #else
         StubCode::InitOnce();
+        Object::FinishInitOnce(vm_isolate_);
         // MallocHooks can't be initialized until StubCode has been since stack
         // trace generation relies on stub methods that are generated in
         // StubCode::InitOnce().
@@ -234,6 +235,7 @@
         // Must copy before leaving the zone.
         return strdup(error.ToErrorCString());
       }
+      Object::FinishInitOnce(vm_isolate_);
 #if !defined(PRODUCT)
       if (tds.enabled()) {
         tds.SetNumArguments(2);
@@ -262,6 +264,7 @@
 #else
       vm_snapshot_kind_ = Snapshot::kNone;
       StubCode::InitOnce();
+      Object::FinishInitOnce(vm_isolate_);
       // MallocHooks can't be initialized until StubCode has been since stack
       // trace generation relies on stub methods that are generated in
       // StubCode::InitOnce().
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index e5b731c..9e2d9f9 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -96,7 +96,7 @@
     AllocateZoneHandle(Zone* zone) {
 #if defined(DEBUG)
   Thread* thread = Thread::Current();
-  ASSERT(thread->zone() == zone);
+  ASSERT(zone->ContainsNestedZone(thread->zone()));
   ASSERT(thread->no_handle_scope_depth() == 0);
 #endif  // DEBUG
   Handles* handles = zone->handles();
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 95a7da0..89186a4 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -12,6 +12,7 @@
 #include "vm/object.h"
 #include "vm/stub_code.h"
 #include "vm/timeline.h"
+#include "vm/type_testing_stubs.h"
 
 namespace dart {
 
@@ -36,7 +37,7 @@
   return offset;
 }
 
-int32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) {
+uint32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) {
   intptr_t heap_size = raw_object->Size();
   intptr_t offset = next_data_offset_;
   next_data_offset_ += heap_size;
@@ -239,6 +240,7 @@
   Object& owner = Object::Handle(zone);
   String& str = String::Handle(zone);
 
+  TypeTestingStubFinder tts;
   for (intptr_t i = 0; i < instructions_.length(); i++) {
     const Instructions& insns = *instructions_[i].insns_;
     const Code& code = *instructions_[i].code_;
@@ -270,28 +272,41 @@
 
     // 2. Write a label at the entry point.
     // Linux's perf uses these labels.
-    owner = code.owner();
-    if (owner.IsNull()) {
-      const char* name = StubCode::NameOfStub(insns.UncheckedEntryPoint());
-      assembly_stream_.Print("Precompiled_Stub_%s:\n", name);
-    } else if (owner.IsClass()) {
-      str = Class::Cast(owner).Name();
-      const char* name = str.ToCString();
-      EnsureIdentifier(const_cast<char*>(name));
-      assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name,
-                             i);
-    } else if (owner.IsFunction()) {
-      const char* name = Function::Cast(owner).ToQualifiedCString();
-      EnsureIdentifier(const_cast<char*>(name));
-      assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
+    if (code.IsNull()) {
+      const char* name = tts.StubNameFromAddresss(insns.UncheckedEntryPoint());
+      assembly_stream_.Print("Precompiled_%s:\n", name);
     } else {
-      UNREACHABLE();
+      owner = code.owner();
+      if (owner.IsNull()) {
+        const char* name = StubCode::NameOfStub(insns.UncheckedEntryPoint());
+        if (name != NULL) {
+          assembly_stream_.Print("Precompiled_Stub_%s:\n", name);
+        } else {
+          const char* name =
+              tts.StubNameFromAddresss(insns.UncheckedEntryPoint());
+          assembly_stream_.Print("Precompiled__%s:\n", name);
+        }
+      } else if (owner.IsClass()) {
+        str = Class::Cast(owner).Name();
+        const char* name = str.ToCString();
+        EnsureIdentifier(const_cast<char*>(name));
+        assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name,
+                               i);
+      } else if (owner.IsFunction()) {
+        const char* name = Function::Cast(owner).ToQualifiedCString();
+        EnsureIdentifier(const_cast<char*>(name));
+        assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
+      } else {
+        UNREACHABLE();
+      }
     }
 
 #ifdef DART_PRECOMPILER
     // Create a label for use by DWARF.
-    intptr_t dwarf_index = dwarf_->AddCode(code);
-    assembly_stream_.Print(".Lcode%" Pd ":\n", dwarf_index);
+    if (!code.IsNull()) {
+      const intptr_t dwarf_index = dwarf_->AddCode(code);
+      assembly_stream_.Print(".Lcode%" Pd ":\n", dwarf_index);
+    }
 #endif
 
     {
@@ -489,7 +504,7 @@
   return result;
 }
 
-RawObject* ImageReader::GetObjectAt(int32_t offset) const {
+RawObject* ImageReader::GetObjectAt(uint32_t offset) const {
   ASSERT(Utils::IsAligned(offset, kWordSize));
 
   RawObject* result = reinterpret_cast<RawObject*>(
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index ece57a3..5e9fe3d 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -51,7 +51,7 @@
   ImageReader(const uint8_t* instructions_buffer, const uint8_t* data_buffer);
 
   RawInstructions* GetInstructionsAt(int32_t offset) const;
-  RawObject* GetObjectAt(int32_t offset) const;
+  RawObject* GetObjectAt(uint32_t offset) const;
 
  private:
   const uint8_t* instructions_buffer_;
@@ -79,7 +79,7 @@
     objects_.Clear();
   }
   int32_t GetTextOffsetFor(RawInstructions* instructions, RawCode* code);
-  int32_t GetDataOffsetFor(RawObject* raw_object);
+  uint32_t GetDataOffsetFor(RawObject* raw_object);
 
   void Write(WriteStream* clustered_stream, bool vm);
   intptr_t text_size() const { return next_text_offset_; }
diff --git a/runtime/vm/instructions.h b/runtime/vm/instructions.h
index 0a2e817..e0ec51f 100644
--- a/runtime/vm/instructions.h
+++ b/runtime/vm/instructions.h
@@ -28,6 +28,20 @@
 
 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj);
 
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
+class TypeTestingStubCallPattern : public ValueObject {
+ public:
+  explicit TypeTestingStubCallPattern(uword pc) : pc_(pc) {}
+
+  intptr_t GetSubtypeTestCachePoolIndex();
+
+ private:
+  const uword pc_;
+};
+
+#endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_INSTRUCTIONS_H_
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index a605542..f62215f 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -285,6 +285,27 @@
   return false;
 }
 
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
+intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
+  // Calls to the type testing stubs look like:
+  //   ldr R3, [PP+idx]
+  //   blx R9
+
+  // Ensure the caller of the type testing stub (whose return address is [pc_])
+  // branched via the `blx R9` instruction.
+  ASSERT(*reinterpret_cast<uint32_t*>(pc_ - Instr::kInstrSize) == 0xe12fff39);
+  const uword load_instr_end = pc_ - Instr::kInstrSize;
+
+  Register reg;
+  intptr_t pool_index = -1;
+  InstructionPattern::DecodeLoadWordFromPool(load_instr_end, &reg, &pool_index);
+  ASSERT(reg == R3);
+  return pool_index;
+}
+
+#endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index bfa0a76..f728ffd 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -351,6 +351,27 @@
   return bx_lr->InstructionBits() == instruction;
 }
 
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
+intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
+  // Calls to the type testing stubs look like:
+  //   ldr R3, [PP+idx]
+  //   blr R9
+
+  // Ensure the caller of the type testing stub (whose return address is [pc_])
+  // branched via the `blr R9` instruction.
+  ASSERT(*reinterpret_cast<uint32_t*>(pc_ - Instr::kInstrSize) == 0xd63f0120);
+  const uword load_instr_end = pc_ - Instr::kInstrSize;
+
+  Register reg;
+  intptr_t pool_index = -1;
+  InstructionPattern::DecodeLoadWordFromPool(load_instr_end, &reg, &pool_index);
+  ASSERT(reg == R3);
+  return pool_index;
+}
+
+#endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM64
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index da8a4cb..3c63a75 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -5,6 +5,7 @@
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_X64.
 #if defined(TARGET_ARCH_X64)
 
+#include "vm/code_patcher.h"
 #include "vm/instructions.h"
 #include "vm/instructions_x64.h"
 
@@ -63,6 +64,22 @@
   return false;
 }
 
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
+intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
+  const intptr_t kCallPatternSize = 10;
+  static int16_t pattern[kCallPatternSize] = {
+      0x4d, 0x8b, 0x8f, -1, -1, -1, -1,  // movq R9, [PP + offs]
+      0xff, 0x53, 0x07                   // callq [RBX+ 0x7]
+  };
+  const uword start = pc_ - kCallPatternSize;
+  ASSERT(MatchesPattern(start, pattern, kCallPatternSize));
+
+  return IndexFromPPLoad(start + 3);
+}
+
+#endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 10a99dc..a297180 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -42,12 +42,14 @@
 #include "vm/runtime_entry.h"
 #include "vm/scopes.h"
 #include "vm/stack_frame.h"
+#include "vm/stub_code.h"
 #include "vm/symbols.h"
 #include "vm/tags.h"
 #include "vm/thread_registry.h"
 #include "vm/timeline.h"
 #include "vm/timer.h"
 #include "vm/type_table.h"
+#include "vm/type_testing_stubs.h"
 #include "vm/unicode.h"
 #include "vm/weak_code.h"
 #include "vm/zone_text_buffer.h"
@@ -999,6 +1001,22 @@
   ASSERT(extractor_parameter_names_->IsArray());
 }
 
+void Object::FinishInitOnce(Isolate* isolate) {
+  // The type testing stubs we initialize in AbstractType objects for the
+  // canonical type of kDynamicCid/kVoidCid/kVectorCid need to be set in this
+  // method, which is called after StubCode::InitOnce().
+  Instructions& instr = Instructions::Handle();
+
+  instr = TypeTestingStubGenerator::DefaultCodeForType(*dynamic_type_);
+  dynamic_type_->SetTypeTestingStub(instr);
+
+  instr = TypeTestingStubGenerator::DefaultCodeForType(*void_type_);
+  void_type_->SetTypeTestingStub(instr);
+
+  instr = TypeTestingStubGenerator::DefaultCodeForType(*vector_type_);
+  vector_type_->SetTypeTestingStub(instr);
+}
+
 // An object visitor which will mark all visited objects. This is used to
 // premark all objects in the vm_isolate_ heap.  Also precalculates hash
 // codes so that we can get the identity hash code of objects in the read-
@@ -1020,11 +1038,7 @@
     if (!obj->IsFreeListElement()) {
       ASSERT(obj->IsVMHeapObject());
       obj->SetMarkBitUnsynchronized();
-      if (obj->IsStringInstance()) {
-        RawString* str = reinterpret_cast<RawString*>(obj);
-        intptr_t hash = String::Hash(str);
-        String::SetCachedHash(str, hash);
-      }
+      Object::FinalizeReadOnlyObject(obj);
 #if defined(HASH_IN_OBJECT_HEADER)
       // These objects end up in the read-only VM isolate which is shared
       // between isolates, so we have to prepopulate them with identity hash
@@ -1130,6 +1144,65 @@
   }
 }
 
+void Object::FinalizeReadOnlyObject(RawObject* object) {
+  NoSafepointScope no_safepoint;
+  intptr_t cid = object->GetClassId();
+  if (cid == kOneByteStringCid) {
+    RawOneByteString* str = static_cast<RawOneByteString*>(object);
+    if (String::GetCachedHash(str) == 0) {
+      intptr_t hash = String::Hash(str);
+      String::SetCachedHash(str, hash);
+    }
+    intptr_t size = OneByteString::UnroundedSize(str);
+    ASSERT(size <= str->Size());
+    memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
+           str->Size() - size);
+  } else if (cid == kTwoByteStringCid) {
+    RawTwoByteString* str = static_cast<RawTwoByteString*>(object);
+    if (String::GetCachedHash(str) == 0) {
+      intptr_t hash = String::Hash(str);
+      String::SetCachedHash(str, hash);
+    }
+    ASSERT(String::GetCachedHash(str) != 0);
+    intptr_t size = TwoByteString::UnroundedSize(str);
+    ASSERT(size <= str->Size());
+    memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
+           str->Size() - size);
+  } else if (cid == kExternalOneByteStringCid) {
+    RawExternalOneByteString* str =
+        static_cast<RawExternalOneByteString*>(object);
+    if (String::GetCachedHash(str) == 0) {
+      intptr_t hash = String::Hash(str);
+      String::SetCachedHash(str, hash);
+    }
+  } else if (cid == kExternalTwoByteStringCid) {
+    RawExternalTwoByteString* str =
+        static_cast<RawExternalTwoByteString*>(object);
+    if (String::GetCachedHash(str) == 0) {
+      intptr_t hash = String::Hash(str);
+      String::SetCachedHash(str, hash);
+    }
+  } else if (cid == kCodeSourceMapCid) {
+    RawCodeSourceMap* map = CodeSourceMap::RawCast(object);
+    intptr_t size = CodeSourceMap::UnroundedSize(map);
+    ASSERT(size <= map->Size());
+    memset(reinterpret_cast<void*>(RawObject::ToAddr(map) + size), 0,
+           map->Size() - size);
+  } else if (cid == kStackMapCid) {
+    RawStackMap* map = StackMap::RawCast(object);
+    intptr_t size = StackMap::UnroundedSize(map);
+    ASSERT(size <= map->Size());
+    memset(reinterpret_cast<void*>(RawObject::ToAddr(map) + size), 0,
+           map->Size() - size);
+  } else if (cid == kPcDescriptorsCid) {
+    RawPcDescriptors* desc = PcDescriptors::RawCast(object);
+    intptr_t size = PcDescriptors::UnroundedSize(desc);
+    ASSERT(size <= desc->Size());
+    memset(reinterpret_cast<void*>(RawObject::ToAddr(desc) + size), 0,
+           desc->Size() - size);
+  }
+}
+
 void Object::set_vm_isolate_snapshot_object_table(const Array& table) {
   ASSERT(Isolate::Current() == Dart::vm_isolate());
   *vm_isolate_snapshot_object_table_ = table.raw();
@@ -16944,6 +17017,19 @@
   return "AbstractType";
 }
 
+void AbstractType::SetTypeTestingStub(const Instructions& instr) const {
+  if (instr.IsNull()) {
+    // This only happens during bootstrapping when creating Type objects before
+    // we have the instructions.
+    ASSERT(type_class_id() == kDynamicCid || type_class_id() == kVoidCid ||
+           type_class_id() == kVectorCid);
+    StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, 0);
+  } else {
+    StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_,
+                    instr.UncheckedEntryPoint());
+  }
+}
+
 RawType* Type::NullType() {
   return Isolate::Current()->object_store()->null_type();
 }
@@ -17852,7 +17938,8 @@
                    const TypeArguments& arguments,
                    TokenPosition token_pos,
                    Heap::Space space) {
-  const Type& result = Type::Handle(Type::New(space));
+  Zone* Z = Thread::Current()->zone();
+  const Type& result = Type::Handle(Z, Type::New(space));
   if (clazz.IsClass()) {
     result.set_type_class(Class::Cast(clazz));
   } else {
@@ -17862,6 +17949,9 @@
   result.SetHash(0);
   result.set_token_pos(token_pos);
   result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated);
+
+  result.SetTypeTestingStub(Instructions::Handle(
+      Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.raw();
 }
 
@@ -17888,7 +17978,8 @@
   const char* class_name;
   if (HasResolvedTypeClass()) {
     cls = type_class();
-    class_name = String::Handle(zone, cls.Name()).ToCString();
+    const String& name = String::Handle(zone, cls.Name());
+    class_name = name.IsNull() ? "<null>" : name.ToCString();
   } else {
     class_name = UnresolvedClass::Handle(zone, unresolved_class()).ToCString();
   }
@@ -17971,6 +18062,9 @@
       space);
   ASSERT(!instantiated_ref_type.IsTypeRef());
   instantiated_type_ref.set_type(instantiated_ref_type);
+
+  instantiated_type_ref.SetTypeTestingStub(Instructions::Handle(
+      TypeTestingStubGenerator::DefaultCodeForType(instantiated_type_ref)));
   return instantiated_type_ref.raw();
 }
 
@@ -18056,8 +18150,12 @@
 }
 
 RawTypeRef* TypeRef::New(const AbstractType& type) {
-  const TypeRef& result = TypeRef::Handle(TypeRef::New());
+  Zone* Z = Thread::Current()->zone();
+  const TypeRef& result = TypeRef::Handle(Z, TypeRef::New());
   result.set_type(type);
+
+  result.SetTypeTestingStub(Instructions::Handle(
+      Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.raw();
 }
 
@@ -18359,7 +18457,8 @@
                                      const AbstractType& bound,
                                      TokenPosition token_pos) {
   ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull());
-  const TypeParameter& result = TypeParameter::Handle(TypeParameter::New());
+  Zone* Z = Thread::Current()->zone();
+  const TypeParameter& result = TypeParameter::Handle(Z, TypeParameter::New());
   result.set_parameterized_class(parameterized_class);
   result.set_parameterized_function(parameterized_function);
   result.set_index(index);
@@ -18369,6 +18468,9 @@
   result.set_token_pos(token_pos);
   result.StoreNonPointer(&result.raw_ptr()->type_state_,
                          RawTypeParameter::kAllocated);
+
+  result.SetTypeTestingStub(Instructions::Handle(
+      Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.raw();
 }
 
@@ -18626,11 +18728,15 @@
 RawBoundedType* BoundedType::New(const AbstractType& type,
                                  const AbstractType& bound,
                                  const TypeParameter& type_parameter) {
-  const BoundedType& result = BoundedType::Handle(BoundedType::New());
+  Zone* Z = Thread::Current()->zone();
+  const BoundedType& result = BoundedType::Handle(Z, BoundedType::New());
   result.set_type(type);
   result.set_bound(bound);
   result.SetHash(0);
   result.set_type_parameter(type_parameter);
+
+  result.SetTypeTestingStub(Instructions::Handle(
+      Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.raw();
 }
 
@@ -18701,9 +18807,13 @@
 
 RawMixinAppType* MixinAppType::New(const AbstractType& super_type,
                                    const Array& mixin_types) {
-  const MixinAppType& result = MixinAppType::Handle(MixinAppType::New());
+  Zone* Z = Thread::Current()->zone();
+  const MixinAppType& result = MixinAppType::Handle(Z, MixinAppType::New());
   result.set_super_type(super_type);
   result.set_mixin_types(mixin_types);
+
+  result.SetTypeTestingStub(Instructions::Handle(
+      Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.raw();
 }
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 0323ff6..de0a01a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -42,9 +42,10 @@
 class Assembler;
 class Closure;
 class Code;
-class DisassemblyFormatter;
 class DeoptInstr;
+class DisassemblyFormatter;
 class FinalizablePersistentHandle;
+class HierarchyInfo;
 class LocalScope;
 class CodeStatistics;
 
@@ -556,7 +557,9 @@
   // Initialize the VM isolate.
   static void InitNull(Isolate* isolate);
   static void InitOnce(Isolate* isolate);
+  static void FinishInitOnce(Isolate* isolate);
   static void FinalizeVMIsolate(Isolate* isolate);
+  static void FinalizeReadOnlyObject(RawObject* object);
 
   // Initialize a new isolate either from a Kernel IR, from source, or from a
   // snapshot.
@@ -4354,6 +4357,12 @@
   static const intptr_t kBytesPerElement = 1;
   static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
 
+  static intptr_t UnroundedSize(RawPcDescriptors* desc) {
+    return UnroundedSize(desc->ptr()->length_);
+  }
+  static intptr_t UnroundedSize(intptr_t len) {
+    return sizeof(RawPcDescriptors) + len;
+  }
   static intptr_t InstanceSize() {
     ASSERT(sizeof(RawPcDescriptors) ==
            OFFSET_OF_RETURNED_VALUE(RawPcDescriptors, data));
@@ -4361,7 +4370,7 @@
   }
   static intptr_t InstanceSize(intptr_t len) {
     ASSERT(0 <= len && len <= kMaxElements);
-    return RoundedAllocationSize(sizeof(RawPcDescriptors) + len);
+    return RoundedAllocationSize(UnroundedSize(len));
   }
 
   static RawPcDescriptors* New(GrowableArray<uint8_t>* delta_encoded_data);
@@ -4476,6 +4485,12 @@
   static const intptr_t kBytesPerElement = 1;
   static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
 
+  static intptr_t UnroundedSize(RawCodeSourceMap* map) {
+    return UnroundedSize(map->ptr()->length_);
+  }
+  static intptr_t UnroundedSize(intptr_t len) {
+    return sizeof(RawCodeSourceMap) + len;
+  }
   static intptr_t InstanceSize() {
     ASSERT(sizeof(RawCodeSourceMap) ==
            OFFSET_OF_RETURNED_VALUE(RawCodeSourceMap, data));
@@ -4483,7 +4498,7 @@
   }
   static intptr_t InstanceSize(intptr_t len) {
     ASSERT(0 <= len && len <= kMaxElements);
-    return RoundedAllocationSize(sizeof(RawCodeSourceMap) + len);
+    return RoundedAllocationSize(UnroundedSize(len));
   }
 
   static RawCodeSourceMap* New(intptr_t length);
@@ -4542,15 +4557,20 @@
 
   static const intptr_t kMaxLengthInBytes = kSmiMax;
 
+  static intptr_t UnroundedSize(RawStackMap* map) {
+    return UnroundedSize(map->ptr()->length_);
+  }
+  static intptr_t UnroundedSize(intptr_t len) {
+    // The stackmap payload is in an array of bytes.
+    intptr_t payload_size = Utils::RoundUp(len, kBitsPerByte) / kBitsPerByte;
+    return sizeof(RawStackMap) + payload_size;
+  }
   static intptr_t InstanceSize() {
     ASSERT(sizeof(RawStackMap) == OFFSET_OF_RETURNED_VALUE(RawStackMap, data));
     return 0;
   }
   static intptr_t InstanceSize(intptr_t length) {
-    ASSERT(length >= 0);
-    // The stackmap payload is in an array of bytes.
-    intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte;
-    return RoundedAllocationSize(sizeof(RawStackMap) + payload_size);
+    return RoundedAllocationSize(UnroundedSize(length));
   }
   static RawStackMap* New(intptr_t pc_offset,
                           BitmapBuilder* bmap,
@@ -4642,6 +4662,9 @@
   }
 
   RawInstructions* instructions() const { return raw_ptr()->instructions_; }
+  static RawInstructions* InstructionsOf(const RawCode* code) {
+    return code->ptr()->instructions_;
+  }
 
   static intptr_t saved_instructions_offset() {
     return OFFSET_OF(RawCode, instructions_);
@@ -6115,6 +6138,16 @@
       const TypeArguments& instantiator_type_args,
       const TypeArguments& function_type_args);
 
+  static intptr_t type_test_stub_entry_point_offset() {
+    return OFFSET_OF(RawAbstractType, type_test_stub_entry_point_);
+  }
+
+  uword type_test_stub_entry_point() const {
+    return raw_ptr()->type_test_stub_entry_point_;
+  }
+
+  void SetTypeTestingStub(const Instructions& instr) const;
+
  private:
   // Check the 'is subtype of' or 'is more specific than' relationship.
   bool TypeTest(TypeTestKind test_kind,
@@ -6154,6 +6187,12 @@
   static intptr_t type_class_id_offset() {
     return OFFSET_OF(RawType, type_class_id_);
   }
+  static intptr_t arguments_offset() {
+    return OFFSET_OF(RawType, type_class_id_);
+  }
+  static intptr_t type_state_offset() {
+    return OFFSET_OF(RawType, type_state_);
+  }
   static intptr_t hash_offset() { return OFFSET_OF(RawType, hash_); }
   virtual bool IsFinalized() const {
     return (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
@@ -6305,6 +6344,8 @@
 // Note that the cycle always involves type arguments.
 class TypeRef : public AbstractType {
  public:
+  static intptr_t type_offset() { return OFFSET_OF(RawTypeRef, type_); }
+
   virtual bool IsFinalized() const {
     const AbstractType& ref_type = AbstractType::Handle(type());
     return !ref_type.IsNull() && ref_type.IsFinalized();
@@ -7354,12 +7395,17 @@
     return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data);
   }
 
+  static intptr_t UnroundedSize(RawOneByteString* str) {
+    return UnroundedSize(Smi::Value(str->ptr()->length_));
+  }
+  static intptr_t UnroundedSize(intptr_t len) {
+    return sizeof(RawOneByteString) + (len * kBytesPerElement);
+  }
   static intptr_t InstanceSize() {
     ASSERT(sizeof(RawOneByteString) ==
            OFFSET_OF_RETURNED_VALUE(RawOneByteString, data));
     return 0;
   }
-
   static intptr_t InstanceSize(intptr_t len) {
     ASSERT(sizeof(RawOneByteString) == String::kSizeofRawString);
     ASSERT(0 <= len && len <= kMaxElements);
@@ -7369,8 +7415,7 @@
     // memory allocated for the raw string.
     if (len == 0) return InstanceSize(1);
 #endif
-    return String::RoundedAllocationSize(sizeof(RawOneByteString) +
-                                         (len * kBytesPerElement));
+    return String::RoundedAllocationSize(UnroundedSize(len));
   }
 
   static RawOneByteString* New(intptr_t len, Heap::Space space);
@@ -7498,12 +7543,17 @@
     return OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data);
   }
 
+  static intptr_t UnroundedSize(RawTwoByteString* str) {
+    return UnroundedSize(Smi::Value(str->ptr()->length_));
+  }
+  static intptr_t UnroundedSize(intptr_t len) {
+    return sizeof(RawTwoByteString) + (len * kBytesPerElement);
+  }
   static intptr_t InstanceSize() {
     ASSERT(sizeof(RawTwoByteString) ==
            OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data));
     return 0;
   }
-
   static intptr_t InstanceSize(intptr_t len) {
     ASSERT(sizeof(RawTwoByteString) == String::kSizeofRawString);
     ASSERT(0 <= len && len <= kMaxElements);
@@ -7511,8 +7561,7 @@
     // If we don't pad, then the external string object does not fit in the
     // memory allocated for the raw string.
     if (len == 0) return InstanceSize(1);
-    return String::RoundedAllocationSize(sizeof(RawTwoByteString) +
-                                         (len * kBytesPerElement));
+    return String::RoundedAllocationSize(UnroundedSize(len));
   }
 
   static RawTwoByteString* New(intptr_t len, Heap::Space space);
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 53b8716..891760f 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -125,6 +125,7 @@
   R_(Code, megamorphic_miss_code)                                              \
   R_(Function, megamorphic_miss_function)                                      \
   RW(Array, obfuscation_map)                                                   \
+  RW(GrowableObjectArray, type_testing_stubs)                                  \
   RW(GrowableObjectArray, changed_in_last_reload)                              \
 // Please remember the last entry must be referred in the 'to' function below.
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index c82c8cd..de84a19 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1797,11 +1797,13 @@
     kFinalizedInstantiated,    // Instantiated type ready for use.
     kFinalizedUninstantiated,  // Uninstantiated type ready for use.
   };
+  uword type_test_stub_entry_point_;  // Accessed from generated code.
 
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(AbstractType);
 
   friend class ObjectStore;
+  friend class StubCode;
 };
 
 class RawType : public RawAbstractType {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index e738756..dd41cf1 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -218,6 +218,9 @@
   type.set_token_pos(TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
   type.set_type_state(reader->Read<int8_t>());
 
+  // Read the code object for the type testing stub and set its entrypoint.
+  reader->EnqueueTypePostprocessing(type);
+
   // Set all the object fields.
   READ_OBJECT_FIELDS(type, type.raw()->from(), type.raw()->to(), kAsReference);
 
@@ -294,6 +297,9 @@
   TypeRef& type_ref = TypeRef::ZoneHandle(reader->zone(), TypeRef::New());
   reader->AddBackRef(object_id, &type_ref, kIsDeserialized);
 
+  // Read the code object for the type testing stub and set its entrypoint.
+  reader->EnqueueTypePostprocessing(type_ref);
+
   // Set all the object fields.
   READ_OBJECT_FIELDS(type_ref, type_ref.raw()->from(), type_ref.raw()->to(),
                      kAsReference);
@@ -337,6 +343,9 @@
   type_parameter.set_index(reader->Read<int16_t>());
   type_parameter.set_type_state(reader->Read<int8_t>());
 
+  // Read the code object for the type testing stub and set its entrypoint.
+  reader->EnqueueTypePostprocessing(type_parameter);
+
   // Set all the object fields.
   READ_OBJECT_FIELDS(type_parameter, type_parameter.raw()->from(),
                      type_parameter.raw()->to(), kAsReference);
@@ -392,6 +401,9 @@
       BoundedType::ZoneHandle(reader->zone(), BoundedType::New());
   reader->AddBackRef(object_id, &bounded_type, kIsDeserialized);
 
+  // Read the code object for the type testing stub and set its entrypoint.
+  reader->EnqueueTypePostprocessing(bounded_type);
+
   // Set all the object fields.
   READ_OBJECT_FIELDS(bounded_type, bounded_type.raw()->from(),
                      bounded_type.raw()->to(), kAsReference);
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 9b99bed..4838da1 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -14,6 +14,7 @@
 #include "vm/deopt_instructions.h"
 #include "vm/exceptions.h"
 #include "vm/flags.h"
+#include "vm/instructions.h"
 #include "vm/kernel_isolate.h"
 #include "vm/message.h"
 #include "vm/message_handler.h"
@@ -665,9 +666,14 @@
       TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
   const TypeArguments& function_type_arguments =
       TypeArguments::CheckedHandle(zone, arguments.ArgAt(3));
-  const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(4));
-  const SubtypeTestCache& cache =
-      SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(5));
+  String& dst_name = String::Handle(zone);
+  dst_name ^= arguments.ArgAt(4);
+  ASSERT(dst_name.IsNull() || dst_name.IsString());
+
+  SubtypeTestCache& cache = SubtypeTestCache::Handle(zone);
+  cache ^= arguments.ArgAt(5);
+  ASSERT(cache.IsNull() || cache.IsSubtypeTestCache());
+
   ASSERT(!dst_type.IsMalformed());    // Already checked in code generator.
   ASSERT(!dst_type.IsMalbounded());   // Already checked in code generator.
   ASSERT(!dst_type.IsDynamicType());  // No need to check assignment.
@@ -700,10 +706,85 @@
       ASSERT(isolate->type_checks());
       bound_error_message = String::New(bound_error.ToErrorCString());
     }
+    if (dst_name.IsNull()) {
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32) &&                 \
+    (defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME))
+      // Grab the [dst_name] from the pool.  It's stored at one pool slot after
+      // the subtype-test-cache.
+      DartFrameIterator iterator(thread,
+                                 StackFrameIterator::kNoCrossThreadIteration);
+      StackFrame* caller_frame = iterator.NextFrame();
+      const Code& caller_code =
+          Code::Handle(zone, caller_frame->LookupDartCode());
+      const ObjectPool& pool =
+          ObjectPool::Handle(zone, caller_code.object_pool());
+      TypeTestingStubCallPattern tts_pattern(caller_frame->pc());
+      const intptr_t stc_pool_idx = tts_pattern.GetSubtypeTestCachePoolIndex();
+      const intptr_t dst_name_idx = stc_pool_idx + 1;
+      dst_name ^= pool.ObjectAt(dst_name_idx);
+#else
+      UNREACHABLE();
+#endif
+    }
+
     Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name,
                                         bound_error_message);
     UNREACHABLE();
   }
+
+  if (cache.IsNull()) {
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32) &&                 \
+    (defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME))
+
+#if defined(DART_PRECOMPILER)
+    if (FLAG_precompiled_mode) {
+#endif  // defined(DART_PRECOMPILER)
+
+      // We lazily create [SubtypeTestCache] for those call sites which actually
+      // need one and will patch the pool entry.
+      DartFrameIterator iterator(thread,
+                                 StackFrameIterator::kNoCrossThreadIteration);
+      StackFrame* caller_frame = iterator.NextFrame();
+      const Code& caller_code =
+          Code::Handle(zone, caller_frame->LookupDartCode());
+      const ObjectPool& pool =
+          ObjectPool::Handle(zone, caller_code.object_pool());
+      TypeTestingStubCallPattern tts_pattern(caller_frame->pc());
+      const intptr_t stc_pool_idx = tts_pattern.GetSubtypeTestCachePoolIndex();
+
+      // The pool entry must be initialized to `null` when we patch it.
+      ASSERT(pool.ObjectAt(stc_pool_idx) == Object::null());
+      cache = SubtypeTestCache::New();
+      pool.SetObjectAt(stc_pool_idx, cache);
+
+#if defined(DART_PRECOMPILER)
+    }
+#endif  // defined(DART_PRECOMPILER)
+
+#else
+    // WARNING: If we ever come here, it's a really bad sign, because it means
+    // that there was a type test, which generated code could not handle but we
+    // have no subtype cache.  Which means that this successfully-passing type
+    // check will always go to runtime.
+    //
+    // Currently there is one known case when this happens:
+    //
+    // The [FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest] is
+    // handling type checks against int/num specially: It generates a number of
+    // class-id checks.  Unfortunately it handles only normal implementations of
+    // 'int', such as kSmiCid, kMintCid, kBigintCid.  It will signal that there
+    // is no subtype-cache necessary on that call site, because all integer
+    // types have been handled.
+    //
+    // -> Though this is not true, due to (from runtime/lib/array_patch.dart):
+    //
+    //    class _GrowableArrayMarker implements int { }
+    //
+    // Because of this, we cannot have an `UNREACHABLE()` here, but rather just
+    // have a NOP and return `true`, to signal the type check passed.
+#endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+  }
+
   UpdateTypeTestCache(src_instance, dst_type, instantiator_type_arguments,
                       function_type_arguments, Bool::True(), cache);
   arguments.SetReturn(src_instance);
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 1b91df8..447fbf4 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -15,8 +15,10 @@
 #include "vm/object.h"
 #include "vm/object_store.h"
 #include "vm/snapshot_ids.h"
+#include "vm/stub_code.h"
 #include "vm/symbols.h"
 #include "vm/timeline.h"
+#include "vm/type_testing_stubs.h"
 #include "vm/version.h"
 
 // We currently only expect the Dart mutator to read snapshots.
@@ -189,6 +191,7 @@
       heap_(isolate()->heap()),
       old_space_(thread_->isolate()->heap()->old_space()),
       cls_(Class::Handle(zone_)),
+      code_(Code::Handle(zone_)),
       obj_(Object::Handle(zone_)),
       pobj_(PassiveObject::Handle(zone_)),
       array_(Array::Handle(zone_)),
@@ -208,6 +211,7 @@
               ? Object::vm_isolate_snapshot_object_table().Length()
               : 0),
       backward_references_(backward_refs),
+      types_to_postprocess_(GrowableObjectArray::Handle(zone_)),
       objects_to_rehash_(GrowableObjectArray::Handle(zone_)) {}
 
 RawObject* SnapshotReader::ReadObject() {
@@ -215,6 +219,7 @@
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     objects_to_rehash_ = GrowableObjectArray::New(HEAP_SPACE(kind_));
+    types_to_postprocess_ = GrowableObjectArray::New(HEAP_SPACE(kind_));
 
     PassiveObject& obj =
         PassiveObject::Handle(zone(), ReadObjectImpl(kAsInlinedObject));
@@ -234,6 +239,7 @@
     } else {
       result = obj.raw();
     }
+    RunDelayedTypePostprocessing();
     const Object& ok = Object::Handle(zone_, RunDelayedRehashingOfMaps());
     objects_to_rehash_ = GrowableObjectArray::null();
     if (!ok.IsNull()) {
@@ -248,6 +254,22 @@
   }
 }
 
+void SnapshotReader::EnqueueTypePostprocessing(const AbstractType& type) {
+  types_to_postprocess_.Add(type, HEAP_SPACE(kind_));
+}
+
+void SnapshotReader::RunDelayedTypePostprocessing() {
+  if (types_to_postprocess_.Length() > 0) {
+    AbstractType& type = AbstractType::Handle();
+    Instructions& instr = Instructions::Handle();
+    for (intptr_t i = 0; i < types_to_postprocess_.Length(); ++i) {
+      type ^= types_to_postprocess_.At(i);
+      instr = TypeTestingStubGenerator::DefaultCodeForType(type);
+      type.SetTypeTestingStub(instr);
+    }
+  }
+}
+
 void SnapshotReader::EnqueueRehashingOfMap(const LinkedHashMap& map) {
   objects_to_rehash_.Add(map, HEAP_SPACE(kind_));
 }
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 44cb6db..6dd74d4 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -326,6 +326,7 @@
   PassiveObject* PassiveObjectHandle() { return &pobj_; }
   Array* ArrayHandle() { return &array_; }
   Class* ClassHandle() { return &cls_; }
+  Code* CodeHandle() { return &code_; }
   String* StringHandle() { return &str_; }
   AbstractType* TypeHandle() { return &type_; }
   TypeArguments* TypeArgumentsHandle() { return &type_arguments_; }
@@ -371,6 +372,9 @@
   PageSpace* old_space() const { return old_space_; }
 
  private:
+  void EnqueueTypePostprocessing(const AbstractType& type);
+  void RunDelayedTypePostprocessing();
+
   void EnqueueRehashingOfMap(const LinkedHashMap& map);
   RawObject* RunDelayedRehashingOfMaps();
 
@@ -434,6 +438,7 @@
   Heap* heap_;            // Heap of the current isolate.
   PageSpace* old_space_;  // Old space of the current isolate.
   Class& cls_;            // Temporary Class handle.
+  Code& code_;            // Temporary Code handle.
   Object& obj_;           // Temporary Object handle.
   PassiveObject& pobj_;   // Temporary PassiveObject handle.
   Array& array_;          // Temporary Array handle.
@@ -450,6 +455,7 @@
   UnhandledException& error_;      // Error handle.
   intptr_t max_vm_isolate_object_id_;
   ZoneGrowableArray<BackRefNode>* backward_references_;
+  GrowableObjectArray& types_to_postprocess_;
   GrowableObjectArray& objects_to_rehash_;
 
   friend class ApiError;
@@ -770,6 +776,8 @@
   friend class RawSubtypeTestCache;
   friend class RawTokenStream;
   friend class RawType;
+  friend class RawTypeRef;
+  friend class RawBoundedType;
   friend class RawTypeArguments;
   friend class RawTypeParameter;
   friend class RawUserTag;
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 9bd84f1..a664808 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -82,14 +82,8 @@
 void StubCode::VisitObjectPointers(ObjectPointerVisitor* visitor) {}
 
 bool StubCode::HasBeenInitialized() {
-#if !defined(TARGET_ARCH_DBC)
-  // Use JumpToHandler and InvokeDart as canaries.
-  const StubEntry* entry_1 = StubCode::JumpToFrame_entry();
-  const StubEntry* entry_2 = StubCode::InvokeDartCode_entry();
-  return (entry_1 != NULL) && (entry_2 != NULL);
-#else
-  return true;
-#endif
+  // Use AsynchronousGapMarker as canary.
+  return StubCode::AsynchronousGapMarker_entry() != NULL;
 }
 
 bool StubCode::InInvocationStub(uword pc) {
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 0ef2edc..4fd3d6a 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -67,6 +67,11 @@
   V(Subtype1TestCache)                                                         \
   V(Subtype2TestCache)                                                         \
   V(Subtype4TestCache)                                                         \
+  V(DefaultTypeTest)                                                           \
+  V(TopTypeTypeTest)                                                           \
+  V(TypeRefTypeTest)                                                           \
+  V(UnreachableTypeTest)                                                       \
+  V(SlowTypeTest)                                                              \
   V(CallClosureNoSuchMethod)                                                   \
   V(FrameAwaitingMaterialization)                                              \
   V(AsynchronousGapMarker)
@@ -82,6 +87,11 @@
   V(Deoptimize)                                                                \
   V(DeoptimizeLazyFromReturn)                                                  \
   V(DeoptimizeLazyFromThrow)                                                   \
+  V(DefaultTypeTest)                                                           \
+  V(TopTypeTypeTest)                                                           \
+  V(TypeRefTypeTest)                                                           \
+  V(UnreachableTypeTest)                                                       \
+  V(SlowTypeTest)                                                              \
   V(FrameAwaitingMaterialization)                                              \
   V(AsynchronousGapMarker)
 
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 9b9ca0b..8f51b9f 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
+
 #if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/assembler/assembler.h"
@@ -12,11 +13,12 @@
 #include "vm/dart_entry.h"
 #include "vm/heap.h"
 #include "vm/instructions.h"
+#include "vm/isolate.h"
 #include "vm/object_store.h"
 #include "vm/runtime_entry.h"
 #include "vm/stack_frame.h"
-#include "vm/stub_code.h"
 #include "vm/tags.h"
+#include "vm/type_testing_stubs.h"
 
 #define __ assembler->
 
@@ -1726,6 +1728,9 @@
 // R2: instantiator type arguments (only if n == 4, can be raw_null).
 // R1: function type arguments (only if n == 4, can be raw_null).
 // R3: SubtypeTestCache.
+//
+// Preserves R0/R2
+//
 // Result in R1: null -> not found, otherwise result (true or false).
 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
   ASSERT((n == 1) || (n == 2) || (n == 4));
@@ -1838,6 +1843,206 @@
   GenerateSubtypeNTestCacheStub(assembler, 4);
 }
 
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+//   - R0 : instance to test against.
+//   - R2 : instantiator type arguments (if needed).
+//   - R1 : function type arguments (if needed).
+//
+//   - R3 : subtype test cache.
+//
+//   - R8 : type to test against.
+//   - R4 : name of destination variable.
+//
+// Preserves R0/R2.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  Label done;
+
+  const Register kInstanceReg = R0;
+  // Fast case for 'null'.
+  __ CompareObject(kInstanceReg, Object::null_object());
+  __ BranchIf(EQUAL, &done);
+
+  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  __ bx(R9);
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Ret();
+}
+
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  const Register kTypeRefReg = R8;
+
+  // We dereference the TypeRef and tail-call to it's type testing stub.
+  __ ldr(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
+  __ ldr(R9, FieldAddress(kTypeRefReg,
+                          AbstractType::type_test_stub_entry_point_offset()));
+  __ bx(R9);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  const Register kInstanceReg = R0;
+  const Register kClassIdReg = R9;
+
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+                                      kInstanceReg, kClassIdReg);
+
+  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  __ bx(TMP);
+}
+
+void TypeTestingStubGenerator::
+    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+                                                      HierarchyInfo* hi,
+                                                      const Class& type_class,
+                                                      const TypeArguments& tp,
+                                                      const TypeArguments& ta) {
+  const Register kInstanceReg = R0;
+  const Register kInstanceTypeArguments = NOTFP;
+  const Register kClassIdReg = R9;
+
+  BuildOptimizedSubclassRangeCheckWithTypeArguments(
+      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+      kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const AbstractType& type_arg,
+    intptr_t type_param_value_offset_i,
+    Label* check_failed) {
+  const Register kInstantiatorTypeArgumentsReg = R2;
+  const Register kFunctionTypeArgumentsReg = R1;
+  const Register kInstanceTypeArguments = NOTFP;
+
+  const Register kClassIdReg = R9;
+  const Register kOwnTypeArgumentValue = TMP;
+
+  BuildOptimizedTypeArgumentValueCheck(
+      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Breakpoint();
+}
+
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+  Label done, call_runtime;
+
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R2;
+  const Register kFunctionTypeArgumentsReg = R1;
+  const Register kDstTypeReg = R8;
+  const Register kSubtypeTestCacheReg = R3;
+
+  __ EnterStubFrame();
+
+#ifdef DEBUG
+  // Guaranteed by caller.
+  Label no_error;
+  __ CompareObject(kInstanceReg, Object::null_object());
+  __ BranchIf(NOT_EQUAL, &no_error);
+  __ Breakpoint();
+  __ Bind(&no_error);
+#endif
+
+  // Need to handle slow cases of [Smi]s here because the
+  // [SubtypeTestCache]-based stubs do not handle [Smi]s.
+  Label non_smi_value;
+  __ BranchIfSmi(kInstanceReg, &call_runtime);
+
+  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+  __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
+  __ BranchIf(EQUAL, &call_runtime);
+
+  const Register kTmp = NOTFP;
+
+  // If this is not a [Type] object, we'll go to the runtime.
+  Label is_simple, is_instantiated, is_uninstantiated;
+  __ LoadClassId(kTmp, kDstTypeReg);
+  __ cmp(kTmp, Operand(kTypeCid));
+  __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+
+  // Check whether this [Type] is instantiated/uninstantiated.
+  __ ldrb(kTmp, FieldAddress(kDstTypeReg, Type::type_state_offset()));
+  __ cmp(kTmp, Operand(RawType::kFinalizedInstantiated));
+  __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+  // Fall through to &is_instantiated
+
+  const intptr_t kRegsToSave = (1 << kSubtypeTestCacheReg) |
+                               (1 << kDstTypeReg) |
+                               (1 << kFunctionTypeArgumentsReg);
+
+  __ Bind(&is_instantiated);
+  {
+    __ PushList(kRegsToSave);
+    __ BranchLink(*StubCode::Subtype2TestCache_entry());
+    __ CompareObject(R1, Bool::True());
+    __ PopList(kRegsToSave);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    __ Jump(&call_runtime);
+  }
+
+  __ Bind(&is_uninstantiated);
+  {
+    __ PushList(kRegsToSave);
+    __ BranchLink(*StubCode::Subtype4TestCache_entry());
+    __ CompareObject(R1, Bool::True());
+    __ PopList(kRegsToSave);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    // Fall through to runtime_call
+  }
+
+  __ Bind(&call_runtime);
+
+  // We cannot really ensure here that dynamic/Object never occur here (though
+  // it is guaranteed at dart_precompiled_runtime time).  This is because we do
+  // constant evaluation with default stubs and only install optimized versions
+  // before writing out the AOT snapshot.  So dynamic/Object will run with
+  // default stub in constant evaluation.
+  __ CompareObject(kDstTypeReg, Type::dynamic_type());
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
+  __ BranchIf(EQUAL, &done);
+
+  __ PushObject(Object::null_object());  // Make room for result.
+  __ Push(kInstanceReg);
+  __ Push(kDstTypeReg);
+  __ Push(kInstantiatorTypeArgumentsReg);
+  __ Push(kFunctionTypeArgumentsReg);
+  __ PushObject(Object::null_object());
+  __ Push(kSubtypeTestCacheReg);
+  __ CallRuntime(kTypeCheckRuntimeEntry, 6);
+  __ Pop(kSubtypeTestCacheReg);
+  __ Drop(1);  // dst_name
+  __ Pop(kFunctionTypeArgumentsReg);
+  __ Pop(kInstantiatorTypeArgumentsReg);
+  __ Pop(kDstTypeReg);
+  __ Pop(kInstanceReg);
+  __ Drop(1);  // Discard return value.
+  __ Bind(&done);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
 // Return the current stack pointer address, used to do stack alignment checks.
 void StubCode::GenerateGetCStackPointerStub(Assembler* assembler) {
   __ mov(R0, Operand(SP));
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index e23bb90..f0354a8 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -16,6 +16,7 @@
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/tags.h"
+#include "vm/type_testing_stubs.h"
 
 #define __ assembler->
 
@@ -1772,6 +1773,9 @@
 // R1: instantiator type arguments (only if n == 4, can be raw_null).
 // R2: function type arguments (only if n == 4, can be raw_null).
 // R3: SubtypeTestCache.
+//
+// Preserves R0/R2/R8.
+//
 // Result in R1: null -> not found, otherwise result (true or false).
 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
   ASSERT((n == 1) || (n == 2) || (n == 4));
@@ -1884,6 +1888,213 @@
   GenerateSubtypeNTestCacheStub(assembler, 4);
 }
 
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+//   - R0 : instance to test against.
+//   - R2 : instantiator type arguments (if needed).
+//   - R1 : function type arguments (if needed).
+//
+//   - R3 : subtype test cache.
+//
+//   - R8 : type to test against.
+//   - R4 : name of destination variable.
+//
+// Preserves R0/R2.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  Label done;
+
+  const Register kInstanceReg = R0;
+  const Register kDstTypeReg = R8;
+
+  // Fast case for 'null'.
+  __ CompareObject(kInstanceReg, Object::null_object());
+  __ BranchIf(EQUAL, &done);
+
+  // Fast case for 'int'.
+  Label not_smi;
+  __ BranchIfNotSmi(kInstanceReg, &not_smi);
+  __ CompareObject(kDstTypeReg, Object::ZoneHandle(Type::IntType()));
+  __ BranchIf(EQUAL, &done);
+  __ Bind(&not_smi);
+
+  // Tail call the [SubtypeTestCache]-based implementation.
+  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  __ br(R9);
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Ret();
+}
+
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  const Register kTypeRefReg = R8;
+
+  // We dereference the TypeRef and tail-call to it's type testing stub.
+  __ ldr(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
+  __ ldr(R9, FieldAddress(kTypeRefReg,
+                          AbstractType::type_test_stub_entry_point_offset()));
+  __ br(R9);
+}
+
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Breakpoint();
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  const Register kInstanceReg = R0;
+  const Register kClassIdReg = R9;
+
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+                                      kInstanceReg, kClassIdReg);
+
+  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  __ br(R9);
+}
+
+void TypeTestingStubGenerator::
+    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+                                                      HierarchyInfo* hi,
+                                                      const Class& type_class,
+                                                      const TypeArguments& tp,
+                                                      const TypeArguments& ta) {
+  const Register kInstanceReg = R0;
+  const Register kInstanceTypeArguments = R7;
+  const Register kClassIdReg = R9;
+
+  BuildOptimizedSubclassRangeCheckWithTypeArguments(
+      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+      kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const AbstractType& type_arg,
+    intptr_t type_param_value_offset_i,
+    Label* check_failed) {
+  const Register kInstantiatorTypeArgumentsReg = R1;
+  const Register kFunctionTypeArgumentsReg = R2;
+  const Register kInstanceTypeArguments = R7;
+
+  const Register kClassIdReg = R9;
+  const Register kOwnTypeArgumentValue = TMP;
+
+  BuildOptimizedTypeArgumentValueCheck(
+      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+  Label done, call_runtime;
+
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R1;
+  const Register kFunctionTypeArgumentsReg = R2;
+
+  const Register kSubtypeTestCacheReg = R3;
+  const Register kDstTypeReg = R8;
+
+  __ EnterStubFrame();
+
+#ifdef DEBUG
+  // Guaranteed by caller.
+  Label no_error;
+  __ CompareObject(kInstanceReg, Object::null_object());
+  __ BranchIf(NOT_EQUAL, &no_error);
+  __ Breakpoint();
+  __ Bind(&no_error);
+#endif
+
+  // Need to handle slow cases of [Smi]s here because the
+  // [SubtypeTestCache]-based stubs do not handle [Smi]s.
+  Label non_smi_value;
+  __ BranchIfSmi(kInstanceReg, &call_runtime);
+
+  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+  __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
+  __ BranchIf(EQUAL, &call_runtime);
+
+  const Register kTmp = R9;
+
+  // If this is not a [Type] object, we'll go to the runtime.
+  Label is_simple, is_instantiated, is_uninstantiated;
+  __ LoadClassId(kTmp, kDstTypeReg);
+  __ cmp(kTmp, Operand(kTypeCid));
+  __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+
+  // Check whether this [Type] is instantiated/uninstantiated.
+  __ ldr(kTmp, FieldAddress(kDstTypeReg, Type::type_state_offset()), kByte);
+  __ cmp(kTmp, Operand(RawType::kFinalizedInstantiated));
+  __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+  // Fall through to &is_instantiated
+
+  __ Bind(&is_instantiated);
+  {
+    __ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ BranchLink(*StubCode::Subtype2TestCache_entry());
+    __ CompareObject(R1, Bool::True());
+    __ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    __ Jump(&call_runtime);
+  }
+
+  __ Bind(&is_uninstantiated);
+  {
+    __ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ BranchLink(*StubCode::Subtype4TestCache_entry());
+    __ CompareObject(R1, Bool::True());
+    __ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    // Fall through to runtime_call
+  }
+
+  __ Bind(&call_runtime);
+
+  // We cannot really ensure here that dynamic/Object never occur here (though
+  // it is guaranteed at dart_precompiled_runtime time).  This is because we do
+  // constant evaluation with default stubs and only install optimized versions
+  // before writing out the AOT snapshot.  So dynamic/Object will run with
+  // default stub in constant evaluation.
+  __ CompareObject(kDstTypeReg, Type::dynamic_type());
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
+  __ BranchIf(EQUAL, &done);
+
+  __ PushObject(Object::null_object());  // Make room for result.
+  __ Push(kInstanceReg);
+  __ Push(kDstTypeReg);
+  __ Push(kInstantiatorTypeArgumentsReg);
+  __ Push(kFunctionTypeArgumentsReg);
+  __ PushObject(Object::null_object());
+  __ Push(kSubtypeTestCacheReg);
+  __ CallRuntime(kTypeCheckRuntimeEntry, 6);
+  __ Pop(kSubtypeTestCacheReg);
+  __ Drop(1);  // dst_name
+  __ Pop(kFunctionTypeArgumentsReg);
+  __ Pop(kInstantiatorTypeArgumentsReg);
+  __ Pop(kDstTypeReg);
+  __ Pop(kInstanceReg);
+  __ Drop(1);  // Discard return value.
+  __ Bind(&done);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
 void StubCode::GenerateGetCStackPointerStub(Assembler* assembler) {
   __ mov(R0, CSP);
   __ ret();
diff --git a/runtime/vm/stub_code_dbc.cc b/runtime/vm/stub_code_dbc.cc
index 4b7157c..f78a5d1 100644
--- a/runtime/vm/stub_code_dbc.cc
+++ b/runtime/vm/stub_code_dbc.cc
@@ -83,6 +83,31 @@
   __ Trap();
 }
 
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
   __ Trap();
 }
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 9ef1116..a632adf 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1779,6 +1779,31 @@
   GenerateSubtypeNTestCacheStub(assembler, 4);
 }
 
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  // Only used in AOT and therefore not on ia32.
+  __ Breakpoint();
+}
+
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  // Only used in AOT and therefore not on ia32.
+  __ Breakpoint();
+}
+
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  // Only used in AOT and therefore not on ia32.
+  __ Breakpoint();
+}
+
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  // Only used in AOT and therefore not on ia32.
+  __ Breakpoint();
+}
+
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+  // Only used in AOT and therefore not on ia32.
+  __ Breakpoint();
+}
+
 // Return the current stack pointer address, used to do stack alignment checks.
 // TOS + 0: return address
 // Result in EAX.
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 5183d28..fc8e781 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -3,9 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
+
+#include "vm/stub_code.h"
+
 #if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/assembler/disassembler.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_entry.h"
@@ -15,8 +19,8 @@
 #include "vm/resolver.h"
 #include "vm/scavenger.h"
 #include "vm/stack_frame.h"
-#include "vm/stub_code.h"
 #include "vm/tags.h"
+#include "vm/type_testing_stubs.h"
 
 #define __ assembler->
 
@@ -1717,7 +1721,7 @@
 //
 //   - TOS + 0: return address.
 //
-// Preserves R9/RAX/RCX/RDX.
+// Preserves R9/RAX/RCX/RDX, RBX.
 //
 // Result in R8: null -> not found, otherwise result (true or false).
 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
@@ -1841,6 +1845,194 @@
   GenerateSubtypeNTestCacheStub(assembler, 4);
 }
 
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+//   - R9  : RawSubtypeTestCache
+//   - RAX : instance to test against.
+//   - RDX : instantiator type arguments (if needed).
+//   - RCX : function type arguments (if needed).
+//
+//   - RBX : type to test against.
+//   - R10 : name of destination variable.
+//
+// Preserves R9/RAX/RCX/RDX, RBX, R10.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  Label done;
+
+  const Register kInstanceReg = RAX;
+
+  // Fast case for 'null'.
+  __ CompareObject(kInstanceReg, Object::null_object());
+  __ BranchIf(EQUAL, &done);
+
+  __ movq(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ jmp(FieldAddress(CODE_REG, Code::entry_point_offset()));
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Ret();
+}
+
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  const Register kTypeRefReg = RBX;
+
+  // We dereference the TypeRef and tail-call to it's type testing stub.
+  __ movq(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
+  __ jmp(FieldAddress(kTypeRefReg,
+                      AbstractType::type_test_stub_entry_point_offset()));
+}
+
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Breakpoint();
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  const Register kInstanceReg = RAX;
+  const Register kClassIdReg = TMP;
+
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+                                      kInstanceReg, kClassIdReg);
+
+  __ movq(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ jmp(FieldAddress(CODE_REG, Code::entry_point_offset()));
+}
+
+void TypeTestingStubGenerator::
+    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+                                                      HierarchyInfo* hi,
+                                                      const Class& type_class,
+                                                      const TypeArguments& tp,
+                                                      const TypeArguments& ta) {
+  const Register kInstanceReg = RAX;
+  const Register kInstanceTypeArguments = RSI;
+  const Register kClassIdReg = TMP;
+
+  BuildOptimizedSubclassRangeCheckWithTypeArguments(
+      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+      kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const AbstractType& type_arg,
+    intptr_t type_param_value_offset_i,
+    Label* check_failed) {
+  const Register kInstanceTypeArguments = RSI;
+  const Register kInstantiatorTypeArgumentsReg = RDX;
+  const Register kFunctionTypeArgumentsReg = RCX;
+
+  const Register kClassIdReg = TMP;
+  const Register kOwnTypeArgumentValue = RDI;
+
+  BuildOptimizedTypeArgumentValueCheck(
+      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+  Label done, call_runtime;
+
+  const Register kInstanceReg = RAX;
+  const Register kInstantiatorTypeArgumentsReg = RDX;
+  const Register kFunctionTypeArgumentsReg = RCX;
+  const Register kDstTypeReg = RBX;
+  const Register kSubtypeTestCacheReg = R9;
+
+  __ EnterStubFrame();
+
+#ifdef DEBUG
+  // Guaranteed by caller.
+  Label no_error;
+  __ CompareObject(kInstanceReg, Object::null_object());
+  __ BranchIf(NOT_EQUAL, &no_error);
+  __ Breakpoint();
+  __ Bind(&no_error);
+#endif
+
+  // Need to handle slow cases of [Smi]s here because the
+  // [SubtypeTestCache]-based stubs do not handle [Smi]s.
+  __ BranchIfSmi(kInstanceReg, &call_runtime);
+
+  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+  __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
+  __ BranchIf(EQUAL, &call_runtime);
+
+  const Register kTmp = RDI;
+
+  // If this is not a [Type] object, we'll go to the runtime.
+  Label is_simple, is_instantiated, is_uninstantiated;
+  __ LoadClassId(kTmp, kDstTypeReg);
+  __ cmpq(kTmp, Immediate(kTypeCid));
+  __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+
+  // Check whether this [Type] is instantiated/uninstantiated.
+  __ cmpb(FieldAddress(kDstTypeReg, Type::type_state_offset()),
+          Immediate(RawType::kFinalizedInstantiated));
+  __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+  // Fall through to &is_instantiated
+
+  __ Bind(&is_instantiated);
+  {
+    __ Call(*StubCode::Subtype2TestCache_entry());
+    __ CompareObject(R8, Bool::True());
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    __ Jump(&call_runtime);
+  }
+
+  __ Bind(&is_uninstantiated);
+  {
+    __ Call(*StubCode::Subtype4TestCache_entry());
+    __ CompareObject(R8, Bool::True());
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    // Fall through to runtime_call
+  }
+
+  __ Bind(&call_runtime);
+
+  // We cannot really ensure here that dynamic/Object never occur here (though
+  // it is guaranteed at dart_precompiled_runtime time).  This is because we do
+  // constant evaluation with default stubs and only install optimized versions
+  // before writing out the AOT snapshot.  So dynamic/Object will run with
+  // default stub in constant evaluation.
+  __ CompareObject(kDstTypeReg, Type::dynamic_type());
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
+  __ BranchIf(EQUAL, &done);
+
+  __ PushObject(Object::null_object());  // Make room for result.
+  __ pushq(kInstanceReg);
+  __ pushq(kDstTypeReg);
+  __ pushq(kInstantiatorTypeArgumentsReg);
+  __ pushq(kFunctionTypeArgumentsReg);
+  __ PushObject(Object::null_object());
+  __ pushq(kSubtypeTestCacheReg);
+  __ CallRuntime(kTypeCheckRuntimeEntry, 6);
+  __ popq(kSubtypeTestCacheReg);
+  __ Drop(1);
+  __ popq(kFunctionTypeArgumentsReg);
+  __ popq(kInstantiatorTypeArgumentsReg);
+  __ popq(kDstTypeReg);
+  __ popq(kInstanceReg);
+  __ Drop(1);  // Discard return value.
+  __ Bind(&done);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
 // Return the current stack pointer address, used to stack alignment
 // checks.
 // TOS + 0: return address
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index af6c31a..68b4a05 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -93,6 +93,7 @@
       stack_overflow_count_(0),
       cha_(NULL),
       hierarchy_info_(NULL),
+      type_usage_info_(NULL),
       deopt_id_(0),
       pending_functions_(GrowableObjectArray::null()),
       active_exception_(Object::null()),
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 3f98f69..06655b0 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -55,6 +55,7 @@
 class TimelineStream;
 class TypeArguments;
 class TypeParameter;
+class TypeUsageInfo;
 class Zone;
 
 #define REUSABLE_HANDLE_LIST(V)                                                \
@@ -97,7 +98,9 @@
   V(RawCode*, lazy_deopt_from_return_stub_,                                    \
     StubCode::DeoptimizeLazyFromReturn_entry()->code(), NULL)                  \
   V(RawCode*, lazy_deopt_from_throw_stub_,                                     \
-    StubCode::DeoptimizeLazyFromThrow_entry()->code(), NULL)
+    StubCode::DeoptimizeLazyFromThrow_entry()->code(), NULL)                   \
+  V(RawCode*, slow_type_test_stub_, StubCode::SlowTypeTest_entry()->code(),    \
+    NULL)
 
 #endif
 
@@ -353,6 +356,18 @@
     hierarchy_info_ = value;
   }
 
+  TypeUsageInfo* type_usage_info() const {
+    ASSERT(isolate_ != NULL);
+    return type_usage_info_;
+  }
+
+  void set_type_usage_info(TypeUsageInfo* value) {
+    ASSERT(isolate_ != NULL);
+    ASSERT((type_usage_info_ == NULL && value != NULL) ||
+           (type_usage_info_ != NULL && value == NULL));
+    type_usage_info_ = value;
+  }
+
   int32_t no_callback_scope_depth() const { return no_callback_scope_depth_; }
 
   void IncrementNoCallbackScopeDepth() {
@@ -793,6 +808,7 @@
   // Compiler state:
   CHA* cha_;
   HierarchyInfo* hierarchy_info_;
+  TypeUsageInfo* type_usage_info_;
   intptr_t deopt_id_;  // Compilation specific counter.
   RawGrowableObjectArray* pending_functions_;
 
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
new file mode 100644
index 0000000..82f55a7
--- /dev/null
+++ b/runtime/vm/type_testing_stubs.cc
@@ -0,0 +1,974 @@
+// 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 "vm/type_testing_stubs.h"
+#include "vm/compiler/assembler/disassembler.h"
+#include "vm/compiler/backend/flow_graph_compiler.h"
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/object_store.h"
+
+#define __ assembler->
+
+namespace dart {
+
+DECLARE_FLAG(bool, disassemble_stubs);
+
+TypeTestingStubNamer::TypeTestingStubNamer()
+    : lib_(Library::Handle()),
+      klass_(Class::Handle()),
+      type_(AbstractType::Handle()),
+      type_arguments_(TypeArguments::Handle()),
+      string_(String::Handle()) {}
+
+const char* TypeTestingStubNamer::StubNameForType(
+    const AbstractType& type) const {
+  const uintptr_t address =
+      reinterpret_cast<uintptr_t>(type.raw()) & 0x7fffffff;
+  Zone* Z = Thread::Current()->zone();
+  return OS::SCreate(Z, "TypeTestingStub_%s__%" Pd "", StringifyType(type),
+                     address);
+}
+
+const char* TypeTestingStubNamer::StringifyType(
+    const AbstractType& type) const {
+  Zone* Z = Thread::Current()->zone();
+  if (type.IsType() && !type.IsFunctionType()) {
+    const intptr_t cid = Type::Cast(type).type_class_id();
+    ClassTable* class_table = Isolate::Current()->class_table();
+    klass_ = class_table->At(cid);
+    ASSERT(!klass_.IsNull());
+
+    const char* curl = "";
+    lib_ = klass_.library();
+    if (!lib_.IsNull()) {
+      string_ = lib_.url();
+      curl = OS::SCreate(Z, "%s_", string_.ToCString());
+    } else {
+      static intptr_t counter = 0;
+      curl = OS::SCreate(Z, "nolib%" Pd "_", counter++);
+    }
+
+    string_ = klass_.ScrubbedName();
+    ASSERT(!string_.IsNull());
+    const char* concatenated =
+        AssemblerSafeName(OS::SCreate(Z, "%s_%s", curl, string_.ToCString()));
+
+    const intptr_t type_parameters = klass_.NumTypeParameters();
+    if (type.arguments() != TypeArguments::null() && type_parameters > 0) {
+      type_arguments_ = type.arguments();
+      ASSERT(type_arguments_.Length() >= type_parameters);
+      const intptr_t length = type_arguments_.Length();
+      for (intptr_t i = 0; i < type_parameters; ++i) {
+        type_ = type_arguments_.TypeAt(length - type_parameters + i);
+        concatenated =
+            OS::SCreate(Z, "%s__%s", concatenated, StringifyType(type_));
+      }
+    }
+    return concatenated;
+  } else if (type.IsTypeParameter()) {
+    string_ = TypeParameter::Cast(type).name();
+    return AssemblerSafeName(OS::SCreate(Z, "%s", string_.ToCString()));
+  } else if (type.IsTypeRef()) {
+    const Type& dereferenced_type =
+        Type::Handle(Type::RawCast(TypeRef::Cast(type).type()));
+    return OS::SCreate(Z, "TypeRef_%s", StringifyType(dereferenced_type));
+  } else {
+    return AssemblerSafeName(OS::SCreate(Z, "%s", type.ToCString()));
+  }
+}
+
+const char* TypeTestingStubNamer::AssemblerSafeName(char* cname) {
+  char* cursor = cname;
+  while (*cursor != '\0') {
+    char c = *cursor;
+    if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+          (c >= '0' && c <= '9') || (c == '_'))) {
+      *cursor = '_';
+    }
+    cursor++;
+  }
+  return cname;
+}
+
+RawInstructions* TypeTestingStubGenerator::DefaultCodeForType(
+    const AbstractType& type) {
+  // During bootstrapping we have no access to stubs yet, so we'll just return
+  // `null` and patch these later in `Object::FinishInitOnce()`.
+  if (!StubCode::HasBeenInitialized()) {
+    ASSERT(type.IsType());
+    const intptr_t cid = Type::Cast(type).type_class_id();
+    ASSERT(cid == kDynamicCid || cid == kVoidCid || cid == kVectorCid);
+    return Instructions::null();
+  }
+
+  if (type.raw() == Type::ObjectType() || type.raw() == Type::DynamicType() ||
+      type.raw() == Type::VoidType()) {
+    return Code::InstructionsOf(StubCode::TopTypeTypeTest_entry()->code());
+  }
+
+  if (type.IsTypeRef()) {
+    return Code::InstructionsOf(StubCode::TypeRefTypeTest_entry()->code());
+  }
+
+  if (type.IsType() || type.IsTypeParameter()) {
+    return Code::InstructionsOf(StubCode::DefaultTypeTest_entry()->code());
+  } else {
+    ASSERT(type.IsBoundedType() || type.IsMixinAppType());
+    return Code::InstructionsOf(StubCode::UnreachableTypeTest_entry()->code());
+  }
+}
+
+TypeTestingStubGenerator::TypeTestingStubGenerator()
+    : object_store_(Isolate::Current()->object_store()),
+      array_(GrowableObjectArray::Handle()),
+      instr_(Instructions::Handle()) {}
+
+RawInstructions* TypeTestingStubGenerator::OptimizedCodeForType(
+    const AbstractType& type) {
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+  ASSERT(StubCode::HasBeenInitialized());
+
+  if (type.IsTypeRef()) {
+    return Code::InstructionsOf(StubCode::TypeRefTypeTest_entry()->code());
+  }
+
+  if (type.raw() == Type::ObjectType() || type.raw() == Type::DynamicType()) {
+    return Code::InstructionsOf(StubCode::TopTypeTypeTest_entry()->code());
+  }
+
+  if (type.IsCanonical()) {
+    ASSERT(type.IsResolved());
+    if (type.IsType()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      // Lazily create the type testing stubs array.
+      array_ = object_store_->type_testing_stubs();
+      if (array_.IsNull()) {
+        array_ = GrowableObjectArray::New(Heap::kOld);
+        object_store_->set_type_testing_stubs(array_);
+      }
+
+      instr_ = TypeTestingStubGenerator::BuildCodeForType(Type::Cast(type));
+      if (!instr_.IsNull()) {
+        array_.Add(type);
+        array_.Add(instr_);
+      } else {
+        // Fall back to default.
+        instr_ =
+            Code::InstructionsOf(StubCode::DefaultTypeTest_entry()->code());
+      }
+#else
+      // In the precompiled runtime we cannot lazily create new optimized type
+      // testing stubs, so if we cannot find one, we'll just return the default
+      // one.
+      instr_ = Code::InstructionsOf(StubCode::DefaultTypeTest_entry()->code());
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+      return instr_.raw();
+    }
+  }
+#endif  // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+  return TypeTestingStubGenerator::DefaultCodeForType(type);
+}
+
+TypeTestingStubFinder::TypeTestingStubFinder()
+    : array_(GrowableObjectArray::Handle()),
+      type_(Type::Handle()),
+      code_(Code::Handle()),
+      instr_(Instructions::Handle()) {
+  array_ = Isolate::Current()->object_store()->type_testing_stubs();
+  if (!array_.IsNull()) {
+    SortTableForFastLookup();
+  }
+}
+
+// TODO(kustermann): Use sorting/hashtables to speed this up.
+RawInstructions* TypeTestingStubFinder::LookupByAddresss(
+    uword entry_point) const {
+  // First test the 2 common ones:
+  code_ = StubCode::DefaultTypeTest_entry()->code();
+  if (entry_point == code_.UncheckedEntryPoint()) {
+    return code_.instructions();
+  }
+  code_ = StubCode::TopTypeTypeTest_entry()->code();
+  if (entry_point == code_.UncheckedEntryPoint()) {
+    return code_.instructions();
+  }
+  code_ = StubCode::TypeRefTypeTest_entry()->code();
+  if (entry_point == code_.UncheckedEntryPoint()) {
+    return code_.instructions();
+  }
+  code_ = StubCode::UnreachableTypeTest_entry()->code();
+  if (entry_point == code_.UncheckedEntryPoint()) {
+    return code_.instructions();
+  }
+
+  const intptr_t tuple_idx = LookupInSortedArray(entry_point);
+  return Instructions::RawCast(array_.At(2 * tuple_idx + 1));
+}
+
+const char* TypeTestingStubFinder::StubNameFromAddresss(
+    uword entry_point) const {
+  // First test the 2 common ones:
+  code_ = StubCode::DefaultTypeTest_entry()->code();
+  if (entry_point == code_.UncheckedEntryPoint()) {
+    return "TypeTestingStub_Default";
+  }
+  code_ = StubCode::UnreachableTypeTest_entry()->code();
+  if (entry_point == code_.UncheckedEntryPoint()) {
+    return "TypeTestingStub_Unreachable";
+  }
+
+  const intptr_t tuple_idx = LookupInSortedArray(entry_point);
+  type_ = AbstractType::RawCast(array_.At(2 * tuple_idx));
+  return namer_.StubNameForType(type_);
+}
+
+void TypeTestingStubFinder::SortTableForFastLookup() {
+  struct Sorter {
+    explicit Sorter(const GrowableObjectArray& array)
+        : array_(array),
+          object_(AbstractType::Handle()),
+          object2_(AbstractType::Handle()) {}
+
+    void Sort() {
+      const intptr_t tuples = array_.Length() / 2;
+      InsertionSort(0, tuples - 1);
+    }
+
+    void InsertionSort(intptr_t start, intptr_t end) {
+      for (intptr_t i = start + 1; i <= end; ++i) {
+        intptr_t j = i;
+        while (j > start && Value(j - 1) > Value(j)) {
+          Swap(j - 1, j);
+          j--;
+        }
+      }
+    }
+
+    void Swap(intptr_t i, intptr_t j) {
+      // Swap type.
+      object_ = array_.At(2 * i);
+      object2_ = array_.At(2 * j);
+      array_.SetAt(2 * i, object2_);
+      array_.SetAt(2 * j, object_);
+
+      // Swap instructions.
+      object_ = array_.At(2 * i + 1);
+      object2_ = array_.At(2 * j + 1);
+      array_.SetAt(2 * i + 1, object2_);
+      array_.SetAt(2 * j + 1, object_);
+    }
+
+    uword Value(intptr_t i) {
+      return Instructions::UncheckedEntryPoint(
+          Instructions::RawCast(array_.At(2 * i + 1)));
+    }
+
+    const GrowableObjectArray& array_;
+    Object& object_;
+    Object& object2_;
+  };
+
+  Sorter sorter(array_);
+  sorter.Sort();
+}
+
+intptr_t TypeTestingStubFinder::LookupInSortedArray(uword entry_point) const {
+  intptr_t left = 0;
+  intptr_t right = array_.Length() / 2 - 1;
+
+  while (left <= right) {
+    const intptr_t mid = left + (right - left) / 2;
+    RawInstructions* instr = Instructions::RawCast(array_.At(2 * mid + 1));
+    const uword mid_value = Instructions::UncheckedEntryPoint(instr);
+
+    if (entry_point < mid_value) {
+      right = mid - 1;
+    } else if (mid_value == entry_point) {
+      return mid;
+    } else {
+      left = mid + 1;
+    }
+  }
+
+  // The caller should only call this function if [entry_point] is a real type
+  // testing entrypoint, in which case it must be guaranteed to find it.
+  UNREACHABLE();
+  return NULL;
+}
+
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+RawInstructions* TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
+  HierarchyInfo* hi = Thread::Current()->hierarchy_info();
+  ASSERT(hi != NULL);
+
+  if (!hi->CanUseSubtypeRangeCheckFor(type)) {
+    if (!hi->CanUseGenericSubtypeRangeCheckFor(type)) {
+      return Instructions::null();
+    }
+  }
+
+  const Class& type_class = Class::Handle(type.type_class());
+  ASSERT(!type_class.IsNull());
+
+  // To use the already-defined __ Macro !
+  Assembler assembler;
+  BuildOptimizedTypeTestStub(&assembler, hi, type, type_class);
+
+  const char* name = namer_.StubNameForType(type);
+  const Code& code =
+      Code::Handle(Code::FinalizeCode(name, &assembler, false /* optimized */));
+#ifndef PRODUCT
+  if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
+    LogBlock lb;
+    THR_Print("Code for stub '%s': {\n", name);
+    DisassembleToStdout formatter;
+    code.Disassemble(&formatter);
+    THR_Print("}\n");
+    const ObjectPool& object_pool = ObjectPool::Handle(code.object_pool());
+    object_pool.DebugPrint();
+  }
+#endif  // !PRODUCT
+
+  return code.instructions();
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStubFastCases(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class,
+    Register instance_reg,
+    Register class_id_reg) {
+  // These are handled via the TopTypeTypeTestStub!
+  ASSERT(
+      !(type.raw() == Type::ObjectType() || type.raw() == Type::DynamicType()));
+
+  // Fast case for 'int'.
+  if (type.raw() == Type::IntType()) {
+    Label non_smi_value;
+    __ BranchIfNotSmi(instance_reg, &non_smi_value);
+    __ Ret();
+    __ Bind(&non_smi_value);
+  } else if (type.IsDartFunctionType()) {
+    Label continue_checking;
+    __ CompareImmediate(class_id_reg, kClosureCid);
+    __ BranchIf(NOT_EQUAL, &continue_checking);
+    __ Ret();
+    __ Bind(&continue_checking);
+
+  } else {
+    // TODO(kustermann): Make more fast cases, e.g. Type::Number()
+    // is implemented by Smi.
+  }
+
+  // Check the cid ranges which are a subtype of [type].
+  if (hi->CanUseSubtypeRangeCheckFor(type)) {
+    const CidRangeVector& ranges = hi->SubtypeRangesForClass(type_class);
+
+    const Type& int_type = Type::Handle(Type::IntType());
+    const bool smi_is_ok = int_type.IsSubtypeOf(type, NULL, NULL, Heap::kNew);
+
+    BuildOptimizedSubtypeRangeCheck(assembler, ranges, class_id_reg,
+                                    instance_reg, smi_is_ok);
+  } else {
+    ASSERT(hi->CanUseGenericSubtypeRangeCheckFor(type));
+
+    const intptr_t num_type_parameters = type_class.NumTypeParameters();
+    const intptr_t num_type_arguments = type_class.NumTypeArguments();
+
+    const TypeArguments& tp =
+        TypeArguments::Handle(type_class.type_parameters());
+    ASSERT(tp.Length() == num_type_parameters);
+
+    const TypeArguments& ta = TypeArguments::Handle(type.arguments());
+    ASSERT(ta.Length() == num_type_arguments);
+
+    BuildOptimizedSubclassRangeCheckWithTypeArguments(assembler, hi, type_class,
+                                                      tp, ta);
+  }
+
+  // Fast case for 'null'.
+  Label non_null;
+  __ CompareObject(instance_reg, Object::null_object());
+  __ BranchIf(NOT_EQUAL, &non_null);
+  __ Ret();
+  __ Bind(&non_null);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedSubtypeRangeCheck(
+    Assembler* assembler,
+    const CidRangeVector& ranges,
+    Register class_id_reg,
+    Register instance_reg,
+    bool smi_is_ok) {
+  Label cid_range_failed, is_subtype;
+
+  if (smi_is_ok) {
+    __ LoadClassIdMayBeSmi(class_id_reg, instance_reg);
+  } else {
+    __ BranchIfSmi(instance_reg, &cid_range_failed);
+    __ LoadClassId(class_id_reg, instance_reg);
+  }
+
+  FlowGraphCompiler::GenerateCidRangesCheck(
+      assembler, class_id_reg, ranges, &is_subtype, &cid_range_failed, true);
+  __ Bind(&is_subtype);
+  __ Ret();
+  __ Bind(&cid_range_failed);
+}
+
+void TypeTestingStubGenerator::
+    BuildOptimizedSubclassRangeCheckWithTypeArguments(
+        Assembler* assembler,
+        HierarchyInfo* hi,
+        const Class& type_class,
+        const TypeArguments& tp,
+        const TypeArguments& ta,
+        const Register class_id_reg,
+        const Register instance_reg,
+        const Register instance_type_args_reg) {
+  // a) First we make a quick sub*class* cid-range check.
+  Label check_failed;
+  ASSERT(!type_class.is_implemented());
+  const CidRangeVector& ranges = hi->SubclassRangesForClass(type_class);
+  BuildOptimizedSubclassRangeCheck(assembler, ranges, class_id_reg,
+                                   instance_reg, &check_failed);
+  // fall through to continue
+
+  // b) Then we'll load the values for the type parameters.
+  __ LoadField(
+      instance_type_args_reg,
+      FieldAddress(instance_reg, type_class.type_arguments_field_offset()));
+
+  // The kernel frontend should fill in any non-assigned type parameters on
+  // construction with dynamic/Object, so we should never get the null type
+  // argument vector in created instances.
+  //
+  // TODO(kustermann): We could consider not using "null" as type argument
+  // vector representing all-dynamic to avoid this extra check (which will be
+  // uncommon because most Dart code in 2.0 will be strongly typed)!
+  Label process_done;
+  __ CompareObject(instance_type_args_reg, Object::null_object());
+  __ BranchIf(NOT_EQUAL, &process_done);
+  __ Ret();
+  __ Bind(&process_done);
+
+  // c) Then we'll check each value of the type argument.
+  AbstractType& type_arg = AbstractType::Handle();
+
+  const intptr_t num_type_parameters = type_class.NumTypeParameters();
+  const intptr_t num_type_arguments = type_class.NumTypeArguments();
+  for (intptr_t i = 0; i < num_type_parameters; ++i) {
+    const intptr_t type_param_value_offset_i =
+        num_type_arguments - num_type_parameters + i;
+
+    type_arg = ta.TypeAt(type_param_value_offset_i);
+    ASSERT(type_arg.IsTypeParameter() ||
+           hi->CanUseSubtypeRangeCheckFor(type_arg));
+
+    BuildOptimizedTypeArgumentValueCheck(
+        assembler, hi, type_arg, type_param_value_offset_i, &check_failed);
+  }
+  __ Ret();
+
+  // If anything fails.
+  __ Bind(&check_failed);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedSubclassRangeCheck(
+    Assembler* assembler,
+    const CidRangeVector& ranges,
+    Register class_id_reg,
+    Register instance_reg,
+    Label* check_failed) {
+  __ LoadClassIdMayBeSmi(class_id_reg, instance_reg);
+
+  Label is_subtype;
+  FlowGraphCompiler::GenerateCidRangesCheck(assembler, class_id_reg, ranges,
+                                            &is_subtype, check_failed, true);
+  __ Bind(&is_subtype);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const AbstractType& type_arg,
+    intptr_t type_param_value_offset_i,
+    const Register class_id_reg,
+    const Register instance_type_args_reg,
+    const Register instantiator_type_args_reg,
+    const Register function_type_args_reg,
+    const Register own_type_arg_reg,
+    Label* check_failed) {
+  if (type_arg.raw() != Type::ObjectType() &&
+      type_arg.raw() != Type::DynamicType()) {
+    // TODO(kustermann): Even though it should be safe to use TMP here, we
+    // should avoid using TMP outside the assembler.  Try to find a free
+    // register to use here!
+    __ LoadField(
+        TMP,
+        FieldAddress(instance_type_args_reg,
+                     TypeArguments::type_at_offset(type_param_value_offset_i)));
+    __ LoadField(class_id_reg, FieldAddress(TMP, Type::type_class_id_offset()));
+
+    if (type_arg.IsTypeParameter()) {
+      const TypeParameter& type_param = TypeParameter::Cast(type_arg);
+      const Register kTypeArgumentsReg = type_param.IsClassTypeParameter()
+                                             ? instantiator_type_args_reg
+                                             : function_type_args_reg;
+      __ LoadField(
+          own_type_arg_reg,
+          FieldAddress(kTypeArgumentsReg,
+                       TypeArguments::type_at_offset(type_param.index())));
+      __ CompareWithFieldValue(
+          class_id_reg,
+          FieldAddress(own_type_arg_reg, Type::type_class_id_offset()));
+      __ BranchIf(NOT_EQUAL, check_failed);
+    } else {
+      const Class& type_class = Class::Handle(type_arg.type_class());
+      const CidRangeVector& ranges =
+          hi->SubtypeRangesForClass(type_class, /*include_abstract=*/true);
+
+      Label is_subtype;
+      __ SmiUntag(class_id_reg);
+      FlowGraphCompiler::GenerateCidRangesCheck(
+          assembler, class_id_reg, ranges, &is_subtype, check_failed, true);
+      __ Bind(&is_subtype);
+    }
+  }
+}
+
+void RegisterTypeArgumentsUse(const Function& function,
+                              TypeUsageInfo* type_usage_info,
+                              const Class& klass,
+                              Definition* type_arguments) {
+  // The [type_arguments] can, in the general case, be any kind of [Definition]
+  // but generally (in order of expected frequency)
+  //
+  //   Case a)
+  //      type_arguments <- Constant(#null)
+  //      type_arguments <- Constant(#TypeArguments: [ ... ])
+  //
+  //   Case b)
+  //      type_arguments <- InstantiateTypeArguments(
+  //          <type-expr-with-parameters>, ita, fta)
+  //
+  //   Case c)
+  //      type_arguments <- LoadField(vx)
+  //      type_arguments <- LoadField(vx T{_ABC})
+  //      type_arguments <- LoadField(vx T{Type: class: '_ABC'})
+  //
+  //   Case d, e)
+  //      type_arguments <- LoadIndexedUnsafe(rbp[vx + 16]))
+  //      type_arguments <- Parameter(0)
+
+  if (ConstantInstr* constant = type_arguments->AsConstant()) {
+    const Object& object = constant->value();
+    ASSERT(object.IsNull() || object.IsTypeArguments());
+    const TypeArguments& type_arguments =
+        TypeArguments::Handle(TypeArguments::RawCast(object.raw()));
+    type_usage_info->UseTypeArgumentsInInstanceCreation(klass, type_arguments);
+  } else if (InstantiateTypeArgumentsInstr* instantiate =
+                 type_arguments->AsInstantiateTypeArguments()) {
+    const TypeArguments& ta = instantiate->type_arguments();
+    ASSERT(!ta.IsNull());
+    type_usage_info->UseTypeArgumentsInInstanceCreation(klass, ta);
+  } else if (LoadFieldInstr* load_field = type_arguments->AsLoadField()) {
+    Definition* instance = load_field->instance()->definition();
+    intptr_t cid = instance->Type()->ToNullableCid();
+    if (cid == kDynamicCid) {
+      // This is an approximation: If we only know the type, but not the cid, we
+      // might have a this-dispatch where we know it's either this class or any
+      // subclass.
+      // We try to strengthen this assumption furher down by checking the offset
+      // of the type argument vector, but generally speaking this could be a
+      // false-postive, which is still ok!
+      const AbstractType& type = *instance->Type()->ToAbstractType();
+      if (type.IsType()) {
+        const Class& type_class = Class::Handle(type.type_class());
+        if (type_class.NumTypeArguments() >= klass.NumTypeArguments()) {
+          cid = type_class.id();
+        }
+      }
+    }
+    if (cid != kDynamicCid) {
+      const Class& instance_klass =
+          Class::Handle(Isolate::Current()->class_table()->At(cid));
+      if (instance_klass.IsGeneric() &&
+          instance_klass.type_arguments_field_offset() ==
+              load_field->offset_in_bytes()) {
+        // This is a subset of Case c) above, namely forwarding the type
+        // argument vector.
+        //
+        // We use the declaration type arguments for the instance creation,
+        // which is a non-instantiated, expanded, type arguments vector.
+        const AbstractType& declaration_type =
+            AbstractType::Handle(instance_klass.DeclarationType());
+        TypeArguments& declaration_type_args =
+            TypeArguments::Handle(declaration_type.arguments());
+        type_usage_info->UseTypeArgumentsInInstanceCreation(
+            klass, declaration_type_args);
+      }
+    }
+  } else if (type_arguments->IsParameter() ||
+             type_arguments->IsLoadIndexedUnsafe()) {
+    // This happens in constructors with non-optional/optional parameters
+    // where we forward the type argument vector to object allocation.
+    //
+    // Theoretically this could be a false-positive, which is still ok, but
+    // practically it's guranteed that this is a forward of a type argument
+    // vector passed in by the caller.
+    if (function.IsFactory()) {
+      const Class& enclosing_class = Class::Handle(function.Owner());
+      const AbstractType& declaration_type =
+          AbstractType::Handle(enclosing_class.DeclarationType());
+      TypeArguments& declaration_type_args =
+          TypeArguments::Handle(declaration_type.arguments());
+      type_usage_info->UseTypeArgumentsInInstanceCreation(
+          klass, declaration_type_args);
+    }
+  } else {
+    // It can also be a phi node where the inputs are any of the above.
+    ASSERT(type_arguments->IsPhi());
+  }
+}
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+#else  // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+
+void RegisterTypeArgumentsUse(const Function& function,
+                              TypeUsageInfo* type_usage_info,
+                              const Class& klass,
+                              Definition* type_arguments) {
+  // We only have a [TypeUsageInfo] object available durin AOT compilation.
+  UNREACHABLE();
+}
+
+#endif  // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+
+#undef __
+
+const TypeArguments& TypeArgumentInstantiator::InstantiateTypeArguments(
+    const Class& klass,
+    const TypeArguments& type_arguments) {
+  const intptr_t len = klass.NumTypeArguments();
+  TypeArguments* instantiated_type_arguments = type_arguments_handles_.Obtain();
+  *instantiated_type_arguments = TypeArguments::New(len);
+  for (intptr_t i = 0; i < len; ++i) {
+    type_ = type_arguments.TypeAt(i);
+    type_ = InstantiateType(type_);
+    instantiated_type_arguments->SetTypeAt(i, type_);
+    ASSERT(type_.IsCanonical() ||
+           (type_.IsTypeRef() &&
+            AbstractType::Handle(TypeRef::Cast(type_).type()).IsCanonical()));
+  }
+  *instantiated_type_arguments =
+      instantiated_type_arguments->Canonicalize(NULL);
+  type_arguments_handles_.Release(instantiated_type_arguments);
+  return *instantiated_type_arguments;
+}
+
+RawAbstractType* TypeArgumentInstantiator::InstantiateType(
+    const AbstractType& type) {
+  if (type.IsTypeParameter()) {
+    const TypeParameter& parameter = TypeParameter::Cast(type);
+    ASSERT(parameter.IsClassTypeParameter());
+    ASSERT(parameter.IsFinalized());
+    if (instantiator_type_arguments_.IsNull()) {
+      return Type::DynamicType();
+    }
+    return instantiator_type_arguments_.TypeAt(parameter.index());
+  } else if (type.IsFunctionType()) {
+    // No support for function types yet.
+    UNREACHABLE();
+    return nullptr;
+  } else if (type.IsTypeRef()) {
+    // No support for recursive types.
+    UNREACHABLE();
+    return nullptr;
+  } else if (type.IsType()) {
+    if (type.IsInstantiated() || type.arguments() == TypeArguments::null()) {
+      return type.raw();
+    }
+
+    const Type& from = Type::Cast(type);
+    klass_ = from.type_class();
+
+    Type* to = type_handles_.Obtain();
+    TypeArguments* to_type_arguments = type_arguments_handles_.Obtain();
+
+    *to_type_arguments = TypeArguments::null();
+    *to = Type::New(klass_, *to_type_arguments, type.token_pos());
+
+    *to_type_arguments = from.arguments();
+    to->set_arguments(InstantiateTypeArguments(klass_, *to_type_arguments));
+    to->SetIsFinalized();
+    *to ^= to->Canonicalize(NULL);
+
+    type_arguments_handles_.Release(to_type_arguments);
+    type_handles_.Release(to);
+
+    return to->raw();
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+TypeUsageInfo::TypeUsageInfo(Thread* thread)
+    : StackResource(thread),
+      zone_(thread->zone()),
+      finder_(zone_),
+      assert_assignable_types_(),
+      instance_creation_arguments_(
+          new TypeArgumentsSet[thread->isolate()->class_table()->NumCids()]),
+      klass_(Class::Handle(zone_)) {
+  thread->set_type_usage_info(this);
+}
+
+TypeUsageInfo::~TypeUsageInfo() {
+  thread()->set_type_usage_info(NULL);
+  delete[] instance_creation_arguments_;
+}
+
+void TypeUsageInfo::UseTypeInAssertAssignable(const AbstractType& type) {
+  if (!assert_assignable_types_.HasKey(&type)) {
+    AddTypeToSet(&assert_assignable_types_, &type);
+  }
+}
+
+void TypeUsageInfo::UseTypeArgumentsInInstanceCreation(
+    const Class& klass,
+    const TypeArguments& ta) {
+  if (ta.IsNull() || ta.IsCanonical()) {
+    // The Dart VM performs an optimization where it re-uses type argument
+    // vectors if the use-site needs a prefix of an already-existent type
+    // arguments vector.
+    //
+    // For example:
+    //
+    //    class Foo<K, V> {
+    //      foo() => new Bar<K>();
+    //    }
+    //
+    // So the length of the type arguments vector can be longer than the number
+    // of type arguments the class expects.
+    ASSERT(ta.IsNull() || klass.NumTypeArguments() <= ta.Length());
+
+    // If this is a non-instantiated [TypeArguments] object, then it referes to
+    // type parameters.  We need to ensure the type parameters in [ta] only
+    // refer to type parameters in the class.
+    if (!ta.IsNull() && !ta.IsInstantiated() &&
+        finder_.FindClass(ta).IsNull()) {
+      return;
+    }
+
+    klass_ = klass.raw();
+    while (klass_.NumTypeArguments() > 0) {
+      const intptr_t cid = klass_.id();
+      TypeArgumentsSet& set = instance_creation_arguments_[cid];
+      if (!set.HasKey(&ta)) {
+        set.Insert(&TypeArguments::ZoneHandle(zone_, ta.raw()));
+      }
+      klass_ = klass_.SuperClass();
+    }
+  }
+}
+
+void TypeUsageInfo::BuildTypeUsageInformation() {
+  ClassTable* class_table = thread()->isolate()->class_table();
+  const intptr_t cid_count = class_table->NumCids();
+
+  // Step 1) Propagate instantiated type argument vectors.
+  PropagateTypeArguments(class_table, cid_count);
+
+  // Step 2) Collect the type parameters we're interested in.
+  TypeParameterSet parameters_tested_against;
+  CollectTypeParametersUsedInAssertAssignable(&parameters_tested_against);
+
+  // Step 2) Add all types which flow into a type parameter we test against to
+  // the set of types tested against.
+  UpdateAssertAssignableTypes(class_table, cid_count,
+                              &parameters_tested_against);
+}
+
+void TypeUsageInfo::PropagateTypeArguments(ClassTable* class_table,
+                                           intptr_t cid_count) {
+  // See comment in .h file for what this method does.
+
+  Class& klass = Class::Handle(zone_);
+  TypeArguments& temp_type_arguments = TypeArguments::Handle(zone_);
+
+  // We cannot modify a set while we are iterating over it, so we delay the
+  // addition to the set to the point when iteration has finished and use this
+  // list as temporary storage.
+  GrowableObjectArray& delayed_type_argument_set =
+      GrowableObjectArray::Handle(zone_, GrowableObjectArray::New());
+
+  TypeArgumentInstantiator instantiator(zone_);
+
+  const intptr_t kPropgationRounds = 2;
+  for (intptr_t round = 0; round < kPropgationRounds; ++round) {
+    for (intptr_t cid = 0; cid < cid_count; ++cid) {
+      if (!class_table->IsValidIndex(cid) ||
+          !class_table->HasValidClassAt(cid)) {
+        continue;
+      }
+
+      klass = class_table->At(cid);
+      bool null_in_delayed_type_argument_set = false;
+      delayed_type_argument_set.SetLength(0);
+
+      auto it = instance_creation_arguments_[cid].GetIterator();
+      for (const TypeArguments** type_arguments = it.Next();
+           type_arguments != nullptr; type_arguments = it.Next()) {
+        // We have a "type allocation" with "klass<type_arguments[0:N]>".
+        if (!(*type_arguments)->IsNull() &&
+            !(*type_arguments)->IsInstantiated()) {
+          const Class& enclosing_class = finder_.FindClass(**type_arguments);
+          if (!klass.IsNull()) {
+            // We know that "klass<type_arguments[0:N]>" happens inside
+            // [enclosing_class].
+            if (enclosing_class.raw() != klass.raw()) {
+              // Now we try to instantiate [type_arguments] with all the known
+              // instantiator type argument vectors of the [enclosing_class].
+              const intptr_t enclosing_class_cid = enclosing_class.id();
+              TypeArgumentsSet& instantiator_set =
+                  instance_creation_arguments_[enclosing_class_cid];
+              auto it2 = instantiator_set.GetIterator();
+              for (const TypeArguments** instantiator_type_arguments =
+                       it2.Next();
+                   instantiator_type_arguments != nullptr;
+                   instantiator_type_arguments = it2.Next()) {
+                // We have also a "type allocation" with
+                // "enclosing_class<instantiator_type_arguments[0:M]>".
+                if ((*instantiator_type_arguments)->IsNull() ||
+                    (*instantiator_type_arguments)->IsInstantiated()) {
+                  temp_type_arguments = instantiator.Instantiate(
+                      klass, **type_arguments, **instantiator_type_arguments);
+                  if (temp_type_arguments.IsNull() &&
+                      !null_in_delayed_type_argument_set) {
+                    null_in_delayed_type_argument_set = true;
+                    delayed_type_argument_set.Add(temp_type_arguments);
+                  } else {
+                    delayed_type_argument_set.Add(temp_type_arguments);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      // Now we add the [delayed_type_argument_set] elements to the set of
+      // instantiator type arguments of [klass] (and its superclasses).
+      if (delayed_type_argument_set.Length() > 0) {
+        while (klass.NumTypeArguments() > 0) {
+          TypeArgumentsSet& type_argument_set =
+              instance_creation_arguments_[klass.id()];
+          const intptr_t len = delayed_type_argument_set.Length();
+          for (intptr_t i = 0; i < len; ++i) {
+            temp_type_arguments =
+                TypeArguments::RawCast(delayed_type_argument_set.At(i));
+            if (!type_argument_set.HasKey(&temp_type_arguments)) {
+              type_argument_set.Insert(
+                  &TypeArguments::ZoneHandle(zone_, temp_type_arguments.raw()));
+            }
+          }
+          klass = klass.SuperClass();
+        }
+      }
+    }
+  }
+}
+
+void TypeUsageInfo::CollectTypeParametersUsedInAssertAssignable(
+    TypeParameterSet* set) {
+  TypeParameter& param = TypeParameter::Handle(zone_);
+  auto it = assert_assignable_types_.GetIterator();
+  for (const AbstractType** type = it.Next(); type != nullptr;
+       type = it.Next()) {
+    AddToSetIfParameter(set, *type, &param);
+  }
+}
+
+void TypeUsageInfo::UpdateAssertAssignableTypes(
+    ClassTable* class_table,
+    intptr_t cid_count,
+    TypeParameterSet* parameters_tested_against) {
+  Class& klass = Class::Handle(zone_);
+  TypeParameter& param = TypeParameter::Handle(zone_);
+  TypeArguments& params = TypeArguments::Handle(zone_);
+  AbstractType& type = AbstractType::Handle(zone_);
+
+  // Because Object/dynamic are common values for type parameters, we add them
+  // eagerly and avoid doing it down inside the loop.
+  type = Type::DynamicType();
+  UseTypeInAssertAssignable(type);
+  type = Type::ObjectType();
+  UseTypeInAssertAssignable(type);
+
+  for (intptr_t cid = 0; cid < cid_count; ++cid) {
+    if (!class_table->IsValidIndex(cid) || !class_table->HasValidClassAt(cid)) {
+      continue;
+    }
+    klass = class_table->At(cid);
+    if (klass.NumTypeArguments() <= 0) {
+      continue;
+    }
+
+    const intptr_t num_parameters = klass.NumTypeParameters();
+    params = klass.type_parameters();
+    for (intptr_t i = 0; i < num_parameters; ++i) {
+      param ^= params.TypeAt(i);
+      if (parameters_tested_against->HasKey(&param)) {
+        TypeArgumentsSet& ta_set = instance_creation_arguments_[cid];
+        auto it = ta_set.GetIterator();
+        for (const TypeArguments** ta = it.Next(); ta != nullptr;
+             ta = it.Next()) {
+          // We only add instantiated types to the set (and dynamic/Object were
+          // already handled above).
+          if (!(*ta)->IsNull()) {
+            type ^= (*ta)->TypeAt(i);
+            if (type.IsInstantiated()) {
+              UseTypeInAssertAssignable(type);
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+void TypeUsageInfo::AddToSetIfParameter(TypeParameterSet* set,
+                                        const AbstractType* type,
+                                        TypeParameter* param) {
+  if (type->IsTypeParameter()) {
+    *param ^= type->raw();
+    if (!param->IsNull() && !set->HasKey(param)) {
+      set->Insert(&TypeParameter::Handle(zone_, param->raw()));
+    }
+  }
+}
+
+void TypeUsageInfo::AddTypeToSet(TypeSet* set, const AbstractType* type) {
+  if (!set->HasKey(type)) {
+    set->Insert(&AbstractType::ZoneHandle(zone_, type->raw()));
+  }
+}
+
+bool TypeUsageInfo::IsUsedInTypeTest(const AbstractType& type) {
+  const AbstractType* dereferenced_type = &type;
+  if (type.IsTypeRef()) {
+    dereferenced_type = &AbstractType::Handle(TypeRef::Cast(type).type());
+  }
+  if (dereferenced_type->IsResolved() && dereferenced_type->IsFinalized()) {
+    return assert_assignable_types_.HasKey(dereferenced_type);
+  }
+  return false;
+}
+
+}  // namespace dart
diff --git a/runtime/vm/type_testing_stubs.h b/runtime/vm/type_testing_stubs.h
new file mode 100644
index 0000000..d03b48a
--- /dev/null
+++ b/runtime/vm/type_testing_stubs.h
@@ -0,0 +1,412 @@
+// 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_VM_TYPE_TESTING_STUBS_H_
+#define RUNTIME_VM_TYPE_TESTING_STUBS_H_
+
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/backend/il.h"
+
+namespace dart {
+
+class TypeTestingStubNamer {
+ public:
+  TypeTestingStubNamer();
+
+  // Simple helper for stringinfying a [type] and prefix it with the type
+  // testing
+  //
+  // (only during dart_boostrap).
+  const char* StubNameForType(const AbstractType& type) const;
+
+ private:
+  const char* StringifyType(const AbstractType& type) const;
+  static const char* AssemblerSafeName(char* cname);
+
+  Library& lib_;
+  Class& klass_;
+  AbstractType& type_;
+  TypeArguments& type_arguments_;
+  String& string_;
+};
+
+class TypeTestingStubGenerator {
+ public:
+  // During bootstrapping it will return `null` for a whitelisted set of types,
+  // otherwise it will return a default stub which tail-calls
+  // subtypingtest/runtime code.
+  static RawInstructions* DefaultCodeForType(const AbstractType& type);
+
+  TypeTestingStubGenerator();
+
+  // Creates new stub for [type] (and registers the tuple in object store
+  // array) or returns default stub.
+  RawInstructions* OptimizedCodeForType(const AbstractType& type);
+
+ private:
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  RawInstructions* BuildCodeForType(const Type& type);
+  static void BuildOptimizedTypeTestStub(Assembler* assembler,
+                                         HierarchyInfo* hi,
+                                         const Type& type,
+                                         const Class& type_class);
+
+  static void BuildOptimizedTypeTestStubFastCases(Assembler* assembler,
+                                                  HierarchyInfo* hi,
+                                                  const Type& type,
+                                                  const Class& type_class,
+                                                  Register instance_reg,
+                                                  Register class_id_reg);
+
+  static void BuildOptimizedSubtypeRangeCheck(Assembler* assembler,
+                                              const CidRangeVector& ranges,
+                                              Register class_id_reg,
+                                              Register instance_reg,
+                                              bool smi_is_ok);
+
+  static void BuildOptimizedSubclassRangeCheckWithTypeArguments(
+      Assembler* assembler,
+      HierarchyInfo* hi,
+      const Class& type_class,
+      const TypeArguments& type_parameters,
+      const TypeArguments& type_arguments);
+
+  static void BuildOptimizedSubclassRangeCheckWithTypeArguments(
+      Assembler* assembler,
+      HierarchyInfo* hi,
+      const Class& type_class,
+      const TypeArguments& type_parameters,
+      const TypeArguments& type_arguments,
+      const Register class_id_reg,
+      const Register instance_reg,
+      const Register instance_type_args_reg);
+
+  static void BuildOptimizedSubclassRangeCheck(Assembler* assembler,
+                                               const CidRangeVector& ranges,
+                                               Register class_id_reg,
+                                               Register instance_reg,
+                                               Label* check_failed);
+
+  static void BuildOptimizedTypeArgumentValueCheck(
+      Assembler* assembler,
+      HierarchyInfo* hi,
+      const AbstractType& type_arg,
+      intptr_t type_param_value_offset_i,
+      Label* check_failed);
+
+  static void BuildOptimizedTypeArgumentValueCheck(
+      Assembler* assembler,
+      HierarchyInfo* hi,
+      const AbstractType& type_arg,
+      intptr_t type_param_value_offset_i,
+      const Register class_id_reg,
+      const Register instance_type_args_reg,
+      const Register instantiator_type_args_reg,
+      const Register function_type_args_reg,
+      const Register type_arg_reg,
+      Label* check_failed);
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+
+  TypeTestingStubNamer namer_;
+  ObjectStore* object_store_;
+  GrowableObjectArray& array_;
+  Instructions& instr_;
+};
+
+// It is assumed that the caller ensures, while this object lives there is no
+// other access to [Isolate::Current()->object_store()->type_testing_stubs()].
+class TypeTestingStubFinder {
+ public:
+  TypeTestingStubFinder();
+
+  // When serializing an AOT snapshot via our clustered snapshot writer, we
+  // write out references to the [Instructions] object for all the
+  // [AbstractType] objects we encounter.
+  //
+  // This method is used for this mapping of stub entrypoint addresses to the
+  // corresponding [Instructions] object.
+  RawInstructions* LookupByAddresss(uword entry_point) const;
+
+  // When generating an AOT snapshot as an assembly file (i.e. ".S" file) we
+  // need to generate labels for the type testing stubs.
+  //
+  // This method maps stub entrypoint addresses to meaningful names.
+  const char* StubNameFromAddresss(uword entry_point) const;
+
+ private:
+  // Sorts the tuples in [array_] according to entrypoint.
+  void SortTableForFastLookup();
+
+  // Returns the tuple index where [entry_point] was found.
+  intptr_t LookupInSortedArray(uword entry_point) const;
+
+  TypeTestingStubNamer namer_;
+  GrowableObjectArray& array_;
+  AbstractType& type_;
+  Code& code_;
+  Instructions& instr_;
+};
+
+template <typename T>
+class ReusableHandleStack {
+ public:
+  explicit ReusableHandleStack(Zone* zone) : zone_(zone), handles_count_(0) {}
+
+  T* Obtain() {
+    T* handle;
+    if (handles_count_ < handles_.length()) {
+      handle = handles_[handles_count_];
+    } else {
+      handle = &T::ZoneHandle(zone_);
+      handles_.Add(handle);
+    }
+    handles_count_++;
+    return handle;
+  }
+
+  // The released [handle] can be used even after releasing until the next
+  // call to [Obtain].
+  void Release(T* handle) {
+    handles_count_--;
+    ASSERT(handles_count_ >= 0);
+    ASSERT(handles_[handles_count_] == handle);
+  }
+
+  Zone* zone_;
+
+  intptr_t handles_count_;
+  MallocGrowableArray<T*> handles_;
+};
+
+// Attempts to find a [Class] from un-instantiated [TypeArgument] vector to
+// which it's type parameters are referring to.
+//
+// If the given type argument vector contains references to type parameters,
+// this finder will either return a valid class if all of the type parameters
+// come from the same class and returns `null` otherwise.
+//
+// It is safe to use this class inside loops since the implementation uses a
+// [ReusableHandleStack] (which in pratice will only use a handful of handles).
+class TypeArgumentClassFinder {
+ public:
+  explicit TypeArgumentClassFinder(Zone* zone)
+      : klass_(Class::Handle(zone)),
+        type_(AbstractType::Handle(zone)),
+        type_arguments_handles_(zone) {}
+
+  const Class& FindClass(const TypeArguments& ta) {
+    klass_ = Class::null();
+
+    const intptr_t len = ta.Length();
+    for (intptr_t i = 0; i < len; ++i) {
+      type_ = ta.TypeAt(i);
+      if (!FindClassFromType(type_)) {
+        klass_ = Class::null();
+        break;
+      }
+    }
+    return klass_;
+  }
+
+ private:
+  bool FindClassFromType(const AbstractType& type) {
+    if (type.IsTypeParameter()) {
+      const TypeParameter& parameter = TypeParameter::Cast(type);
+      if (!parameter.IsClassTypeParameter()) {
+        return false;
+      }
+      if (klass_.IsNull()) {
+        klass_ = parameter.parameterized_class();
+      } else {
+        // Dart has no support for nested classes.
+        ASSERT(klass_.raw() == parameter.parameterized_class());
+      }
+      return true;
+    } else if (type.IsFunctionType()) {
+      // No support for function types yet.
+      return false;
+    } else if (type.IsTypeRef()) {
+      // No support for recursive types.
+      return false;
+    } else if (type.IsType()) {
+      TypeArguments* type_arguments = type_arguments_handles_.Obtain();
+      *type_arguments = Type::Cast(type).arguments();
+      const intptr_t len = type_arguments->Length();
+      for (intptr_t i = 0; i < len; ++i) {
+        type_ = type_arguments->TypeAt(i);
+        if (!FindClassFromType(type_)) {
+          type_arguments_handles_.Release(type_arguments);
+          return false;
+        }
+      }
+      type_arguments_handles_.Release(type_arguments);
+      return true;
+    } else if (type.IsBoundedType()) {
+      // No support for bounded types.
+      return false;
+    }
+    UNREACHABLE();
+    return false;
+  }
+
+  Class& klass_;
+  AbstractType& type_;
+
+  ReusableHandleStack<TypeArguments> type_arguments_handles_;
+};
+
+// Used for instantiating a [TypeArguments] which contains references to type
+// parameters based on an instantiator [TypeArguments] vector.
+//
+// It is safe to use this class inside loops since the implementation uses a
+// [ReusableHandleStack] (which in pratice will only use a handful of handles).
+class TypeArgumentInstantiator {
+ public:
+  explicit TypeArgumentInstantiator(Zone* zone)
+      : klass_(Class::Handle(zone)),
+        type_(AbstractType::Handle(zone)),
+        instantiator_type_arguments_(TypeArguments::Handle(zone)),
+        type_arguments_handles_(zone),
+        type_handles_(zone) {}
+
+  RawTypeArguments* Instantiate(
+      const Class& klass,
+      const TypeArguments& type_arguments,
+      const TypeArguments& instantiator_type_arguments) {
+    instantiator_type_arguments_ = instantiator_type_arguments.raw();
+    return InstantiateTypeArguments(klass, type_arguments).raw();
+  }
+
+ private:
+  const TypeArguments& InstantiateTypeArguments(
+      const Class& klass,
+      const TypeArguments& type_arguments);
+
+  RawAbstractType* InstantiateType(const AbstractType& type);
+
+  Class& klass_;
+  AbstractType& type_;
+  TypeArguments& instantiator_type_arguments_;
+
+  ReusableHandleStack<TypeArguments> type_arguments_handles_;
+  ReusableHandleStack<Type> type_handles_;
+};
+
+// Collects data on how [Type] objects are used in generated code.
+class TypeUsageInfo : public StackResource {
+ public:
+  explicit TypeUsageInfo(Thread* thread);
+  ~TypeUsageInfo();
+
+  void UseTypeInAssertAssignable(const AbstractType& type);
+  void UseTypeArgumentsInInstanceCreation(const Class& klass,
+                                          const TypeArguments& ta);
+
+  // Finalize the collected type usage information.
+  void BuildTypeUsageInformation();
+
+  // Query if [type] is very likely used in a type test (can give
+  // false-positives and false-negatives, but tries to make a very good guess)
+  bool IsUsedInTypeTest(const AbstractType& type);
+
+ private:
+  template <typename T>
+  class ObjectSetTrait {
+   public:
+    // Typedefs needed for the DirectChainedHashMap template.
+    typedef const T* Key;
+    typedef const T* Value;
+    typedef const T* Pair;
+
+    static Key KeyOf(Pair kv) { return kv; }
+    static Value ValueOf(Pair kv) { return kv; }
+    static inline intptr_t Hashcode(Key key) { return key->Hash(); }
+  };
+
+  class TypeSetTrait : public ObjectSetTrait<const AbstractType> {
+   public:
+    static inline bool IsKeyEqual(const AbstractType* pair,
+                                  const AbstractType* key) {
+      return pair->Equals(*key);
+    }
+  };
+
+  class TypeArgumentsSetTrait : public ObjectSetTrait<const TypeArguments> {
+   public:
+    static inline bool IsKeyEqual(const TypeArguments* pair,
+                                  const TypeArguments* key) {
+      return pair->raw() == key->raw();
+    }
+  };
+
+  class TypeParameterSetTrait : public ObjectSetTrait<const TypeParameter> {
+   public:
+    static inline bool IsKeyEqual(const TypeParameter* pair,
+                                  const TypeParameter* key) {
+      return pair->raw() == key->raw();
+    }
+  };
+
+  typedef DirectChainedHashMap<TypeSetTrait> TypeSet;
+  typedef DirectChainedHashMap<TypeArgumentsSetTrait> TypeArgumentsSet;
+  typedef DirectChainedHashMap<TypeParameterSetTrait> TypeParameterSet;
+
+  // Runs an (early terminated) fix-point algorithm which propagates type
+  // arguments.  For example:
+  //
+  //   class Base<X> {}
+  //
+  //   class Foo<A, B> extends Base<B> {
+  //     foo() => new Map<List<B>, A>();
+  //   }
+  //
+  //   main() {
+  //     new Foo<String, int>();
+  //     new Map<double, bool>();
+  //   }
+  //
+  // will end up adding new type argument vectors to the per-class instantiator
+  // type argument vector set:
+  //
+  //   Foo:
+  //     <int, String, int>
+  //   Map:
+  //     <List<int>, String>
+  //     <double, bool>
+  //
+  void PropagateTypeArguments(ClassTable* class_table, intptr_t cid_count);
+
+  // Collects all type parameters we are doing assert assignable checks against.
+  void CollectTypeParametersUsedInAssertAssignable(TypeParameterSet* set);
+
+  // All types which flow into any of the type parameters in [set] will be added
+  // to the set of types we test against.
+  void UpdateAssertAssignableTypes(ClassTable* class_table,
+                                   intptr_t cid_count,
+                                   TypeParameterSet* set);
+
+  void AddToSetIfParameter(TypeParameterSet* set,
+                           const AbstractType* type,
+                           TypeParameter* param);
+  void AddTypeToSet(TypeSet* set, const AbstractType* type);
+
+  Zone* zone_;
+  TypeArgumentClassFinder finder_;
+  TypeSet assert_assignable_types_;
+  TypeArgumentsSet* instance_creation_arguments_;
+
+  Class& klass_;
+};
+
+void RegisterTypeArgumentsUse(const Function& function,
+                              TypeUsageInfo* type_usage_info,
+                              const Class& klass,
+                              Definition* type_arguments);
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_TYPE_TESTING_STUBS_H_
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index a4ee4fa..65be0c4 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -341,6 +341,8 @@
   "token_position.cc",
   "token_position.h",
   "type_table.h",
+  "type_testing_stubs.cc",
+  "type_testing_stubs.h",
   "unibrow-inl.h",
   "unibrow.cc",
   "unibrow.h",
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index b65d2df..b892cdc 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -75,6 +75,14 @@
 
   Zone* previous() const { return previous_; }
 
+  bool ContainsNestedZone(Zone* other) const {
+    while (other != NULL) {
+      if (this == other) return true;
+      other = other->previous_;
+    }
+    return false;
+  }
+
  private:
   Zone();
   ~Zone();  // Delete all memory associated with the zone.
diff --git a/samples-dev/swarm/UIState.dart b/samples-dev/swarm/UIState.dart
index 461c844..f2e0a9e 100644
--- a/samples-dev/swarm/UIState.dart
+++ b/samples-dev/swarm/UIState.dart
@@ -35,7 +35,7 @@
         // the views for this.
         window.history.replaceState(null, document.title, '#');
       } else if (state != '') {
-        loadFromHistory(JSON.decode(state));
+        loadFromHistory(jsonDecode(state));
       }
       firstEvent = false;
     });
@@ -55,7 +55,7 @@
       throw 'history tracking not started';
     }
 
-    String state = JSON.encode(toHistory());
+    String state = jsonEncode(toHistory());
 
     // TODO(jmesserly): [state] should be an Object, and we should pass it to
     // the state parameter instead of as a #hash URL. Right now we're working
diff --git a/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart b/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart
index 5a11333..76857782 100644
--- a/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart
+++ b/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart
@@ -21,8 +21,7 @@
 
   static const YESTERDAY = 'Yesterday';
 
-  static const MS_IN_WEEK =
-      DateTime.DAYS_PER_WEEK * Duration.MILLISECONDS_PER_DAY;
+  static const MS_IN_WEEK = DateTime.daysPerWeek * Duration.millisecondsPerDay;
 
   // TODO(jmesserly): workaround for missing DateTime.fromDate in Dartium
   // Remove this once that is implemented. See b/5055106
@@ -153,7 +152,7 @@
 
     final today = new DateTime(now.year, now.month, now.day, 0, 0, 0, 0);
     Duration delta = today.difference(then);
-    if (delta.inMilliseconds < Duration.MILLISECONDS_PER_DAY) {
+    if (delta.inMilliseconds < Duration.millisecondsPerDay) {
       return YESTERDAY;
     } else if (delta.inMilliseconds < MS_IN_WEEK) {
       return WEEKDAYS[getWeekday(then)];
@@ -175,9 +174,9 @@
   static int getWeekday(DateTime dateTime) {
     final unixTimeStart = new DateTime(1970, 1, 1, 0, 0, 0, 0);
     int msSince1970 = dateTime.difference(unixTimeStart).inMilliseconds;
-    int daysSince1970 = msSince1970 ~/ Duration.MILLISECONDS_PER_DAY;
+    int daysSince1970 = msSince1970 ~/ Duration.millisecondsPerDay;
     // 1970-1-1 was Thursday
-    return ((daysSince1970 + DateTime.THURSDAY) % DateTime.DAYS_PER_WEEK);
+    return ((daysSince1970 + DateTime.thursday) % DateTime.daysPerWeek);
   }
 
   /** Formats a time in H:MM A format */
@@ -203,7 +202,7 @@
     }
 
     String mm =
-        twoDigits(duration.inMinutes.remainder(Duration.MINUTES_PER_HOUR));
+        twoDigits(duration.inMinutes.remainder(Duration.minutesPerHour));
     return "${hours}:${mm} ${a}";
   }
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 1e306bc..1b0f1aa 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -166,19 +166,20 @@
   }
 }
 
-Null _kNull(_) => null;
-
 @patch
 class int {
   @patch
   static int parse(String source,
       {int radix, @deprecated int onError(String source)}) {
-    return Primitives.parseInt(source, radix, onError);
+    int value = tryParse(source, radix: radix);
+    if (value != null) return value;
+    if (onError != null) return onError(source);
+    throw new FormatException(source);
   }
 
   @patch
   static int tryParse(String source, {int radix}) {
-    return Primitives.parseInt(source, radix, _kNull);
+    return Primitives.parseInt(source, radix);
   }
 }
 
@@ -187,12 +188,15 @@
   @patch
   static double parse(String source,
       [@deprecated double onError(String source)]) {
-    return Primitives.parseDouble(source, onError);
+    double value = tryParse(source);
+    if (value != null) return value;
+    if (onError != null) return onError(source);
+    throw new FormatException('Invalid double', source);
   }
 
   @patch
   static double tryParse(String source) {
-    return Primitives.parseDouble(source, _kNull);
+    return Primitives.parseDouble(source);
   }
 }
 
@@ -2684,7 +2688,7 @@
     var resultBits = new Uint8List(8);
 
     var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
-    if (length - 53 > maxDoubleExponent) return double.INFINITY;
+    if (length - 53 > maxDoubleExponent) return double.infinity;
 
     // The most significant bit is for the sign.
     if (_isNegative) resultBits[7] = 0x80;
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index d1eae5a..28307ad 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -758,14 +758,7 @@
     return JS('int', '#', hash);
   }
 
-  @NoInline()
-  static int _parseIntError(String source, int handleError(String source)) {
-    if (handleError == null) throw new FormatException(source);
-    return handleError(source);
-  }
-
-  static int parseInt(
-      String source, int radix, int handleError(String source)) {
+  static int parseInt(String source, int radix) {
     checkString(source);
     var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
     var match = JS('JSExtendableArray|Null', '#.exec(#)', re, source);
@@ -777,7 +770,7 @@
       // TODO(sra): It might be that the match failed due to unrecognized U+0085
       // spaces.  We could replace them with U+0020 spaces and try matching
       // again.
-      return _parseIntError(source, handleError);
+      return null;
     }
     String decimalMatch = match[decimalIndex];
     if (radix == null) {
@@ -789,7 +782,7 @@
         // Cannot fail because we know that the digits are all hex.
         return JS('int', r'parseInt(#, 16)', source);
       }
-      return _parseIntError(source, handleError);
+      return null;
     }
 
     if (radix is! int) {
@@ -828,7 +821,7 @@
       for (int i = 0; i < digitsPart.length; i++) {
         int characterCode = digitsPart.codeUnitAt(i) | 0x20;
         if (characterCode > maxCharCode) {
-          return _parseIntError(source, handleError);
+          return null;
         }
       }
     }
@@ -837,16 +830,7 @@
     return JS('int', r'parseInt(#, #)', source, radix);
   }
 
-  @NoInline()
-  static double _parseDoubleError(
-      String source, double handleError(String source)) {
-    if (handleError == null) {
-      throw new FormatException('Invalid double', source);
-    }
-    return handleError(source);
-  }
-
-  static double parseDouble(String source, double handleError(String source)) {
+  static double parseDouble(String source) {
     checkString(source);
     // Notice that JS parseFloat accepts garbage at the end of the string.
     // Accept only:
@@ -859,7 +843,7 @@
         r'/^\s*[+-]?(?:Infinity|NaN|'
         r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
         source)) {
-      return _parseDoubleError(source, handleError);
+      return null;
     }
     var result = JS('num', r'parseFloat(#)', source);
     if (result.isNaN) {
@@ -867,7 +851,7 @@
       if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
         return result;
       }
-      return _parseDoubleError(source, handleError);
+      return null;
     }
     return result;
   }
diff --git a/sdk/lib/convert/html_escape.dart b/sdk/lib/convert/html_escape.dart
index befde38..9d6804c 100644
--- a/sdk/lib/convert/html_escape.dart
+++ b/sdk/lib/convert/html_escape.dart
@@ -168,8 +168,8 @@
   /**
    * Create converter that escapes HTML characters.
    *
-   * If [mode] is provided as either [HtmlEscapeMode.ATTRIBUTE] or
-   * [HtmlEscapeMode.ELEMENT], only the corresponding subset of HTML
+   * If [mode] is provided as either [HtmlEscapeMode.attribute] or
+   * [HtmlEscapeMode.element], only the corresponding subset of HTML
    * characters are escaped.
    * The default is to escape all HTML characters.
    */
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index 5f57649..f1ceda4 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -328,7 +328,7 @@
 
 String _argumentsAsJson(Map arguments) {
   if ((arguments == null) || (arguments.length == 0)) {
-    // Fast path no arguments. Avoid calling JSON.encode.
+    // Fast path no arguments. Avoid calling jsonEncode.
     return '{}';
   }
   return json.encode(arguments);
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 012e9ed..971f9a5 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -1254,7 +1254,7 @@
 LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError, Pass # Please triage this flake
 LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError, Pass # Please triage this flake
 LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # Please triage this flake
-LayoutTests/fast/css/font-face-unicode-range-load_t01: Pass, Slow
+LayoutTests/fast/css/font-face-unicode-range-load_t01: Pass, Timeout # It is not slow, but flaky when it times out.
 LayoutTests/fast/multicol/newmulticol/balance_t04: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
diff --git a/tests/compiler/dart2js/codegen/type_inference3_test.dart b/tests/compiler/dart2js/codegen/type_inference3_test.dart
index 1173171..8cb9a1b 100644
--- a/tests/compiler/dart2js/codegen/type_inference3_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference3_test.dart
@@ -19,7 +19,8 @@
     await compile(TEST_ONE, entry: 'sum', useKernel: useKernel,
         check: (String generated) {
       RegExp regexp = new RegExp(getNumberTypeCheck('(param1|b)'));
-      Expect.isTrue(regexp.hasMatch(generated));
+      Expect.isTrue(
+          regexp.hasMatch(generated), '$regexp not found in:\n$generated');
     });
   }
 
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index d090da2..d15d999 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -41,26 +41,6 @@
 quarantined/http_test: RuntimeError # not supported with CFE, consider deleting.
 rti/rti_emission_test: Pass, Slow
 rti/rti_need_test: Pass, Slow
-serialization/analysis1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/analysis3_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/analysis4_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/analysis5_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation0_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation3_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation4_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation5_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation_1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/impact_test: Slow, RuntimeError # Issue 32149
-serialization/library_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model0_test: Slow, RuntimeError # Issue 32149
-serialization/model1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model3_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model4_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model5_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model_1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/native_data_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/reserialization_test: Slow, RuntimeError # Issue 32149
 show_package_warnings_test: RuntimeError # missing errors from the FE
 sourcemaps/pub_build_validity_test: Pass, RuntimeError # Investigate: passes locally, but only fails in bots.
 sourcemaps/source_mapping_invokes_test: Pass, Slow
@@ -103,7 +83,6 @@
 old_frontend/analyze_dart2js_helpers_test: Pass, Slow
 old_frontend/duplicate_library_test: Pass, Slow
 output_type_test: Pass, Slow
-serialization*: Slow, Pass
 sourcemaps/source_map_pub_build_validity_test: Pass, Slow
 sourcemaps/stacktrace_test: Pass, Slow
 uri_retention_test: Pass, Slow
@@ -111,7 +90,6 @@
 [ !$checked ]
 end_to_end/exit_code_test: Skip # This tests requires checked mode.
 jsinterop/declaration_test: Slow, Pass
-serialization*: Slow, Pass
 
 [ $runtime == chrome || $runtime == ff || $runtime == firefox || $runtime == safari || $jscl ]
 *: Skip # dart2js uses #import('dart:io'); and it is not self-hosted (yet).
diff --git a/tests/compiler/dart2js/end_to_end/library_env_test.dart b/tests/compiler/dart2js/end_to_end/library_env_test.dart
index 8c3ae8b..85a4498 100644
--- a/tests/compiler/dart2js/end_to_end/library_env_test.dart
+++ b/tests/compiler/dart2js/end_to_end/library_env_test.dart
@@ -55,7 +55,7 @@
   const DummyCompilerInput();
 
   Future<Input> readFromUri(Uri uri,
-      {InputKind inputKind: InputKind.utf8}) async {
+      {InputKind inputKind: InputKind.UTF8}) async {
     if (uri.toString().endsWith("dart_client.platform")) {
       return new Binary(uri, clientPlatform.codeUnits);
     } else if (uri.toString().endsWith("dart_server.platform")) {
diff --git a/tests/compiler/dart2js/equivalence/check_functions.dart b/tests/compiler/dart2js/equivalence/check_functions.dart
index 945803a..b06c4ed 100644
--- a/tests/compiler/dart2js/equivalence/check_functions.dart
+++ b/tests/compiler/dart2js/equivalence/check_functions.dart
@@ -23,11 +23,11 @@
 import 'package:compiler/src/js_backend/interceptor_data.dart';
 import 'package:compiler/src/js_emitter/code_emitter_task.dart';
 import 'package:compiler/src/js_emitter/model.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/universe/class_set.dart';
 import 'package:compiler/src/universe/world_builder.dart';
 import 'package:compiler/src/world.dart';
 import 'package:js_ast/js_ast.dart' as js;
+import 'equivalence_helper.dart';
 import 'check_helpers.dart';
 
 void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2,
@@ -365,33 +365,6 @@
       strategy: const CheckStrategy());
 }
 
-void checkAllResolvedAsts(Compiler compiler1, Compiler compiler2,
-    {bool verbose: false}) {
-  checkLoadedLibraryMembers(compiler1, compiler2, (Element member1) {
-    return member1 is ExecutableElement &&
-        compiler1.resolution.hasResolvedAst(member1);
-  }, checkResolvedAsts, verbose: verbose);
-}
-
-/// Check equivalence of [impact1] and [impact2].
-void checkResolvedAsts(
-    Compiler compiler1, Element member1, Compiler compiler2, Element member2,
-    {bool verbose: false}) {
-  if (!compiler2.serialization.isDeserialized(member2)) {
-    return;
-  }
-  ResolvedAst resolvedAst1 = compiler1.resolution.getResolvedAst(member1);
-  ResolvedAst resolvedAst2 = compiler2.serialization.getResolvedAst(member2);
-
-  if (resolvedAst1 == null || resolvedAst2 == null) return;
-
-  if (verbose) {
-    print('Checking resolved asts for $member1 vs $member2');
-  }
-
-  testResolvedAstEquivalence(resolvedAst1, resolvedAst2, const CheckStrategy());
-}
-
 void checkNativeClasses(
     Compiler compiler1, Compiler compiler2, TestStrategy strategy) {
   Iterable<ClassEntity> nativeClasses1 = compiler1
diff --git a/tests/compiler/dart2js/equivalence/check_helpers.dart b/tests/compiler/dart2js/equivalence/check_helpers.dart
index 9191c01..4a52acc 100644
--- a/tests/compiler/dart2js/equivalence/check_helpers.dart
+++ b/tests/compiler/dart2js/equivalence/check_helpers.dart
@@ -11,9 +11,10 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/resolution_types.dart';
 import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:expect/expect.dart';
 
+import 'equivalence_helper.dart';
+
 Check currentCheck;
 
 class Check {
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/tests/compiler/dart2js/equivalence/equivalence_helper.dart
similarity index 94%
rename from pkg/compiler/lib/src/serialization/equivalence.dart
rename to tests/compiler/dart2js/equivalence/equivalence_helper.dart
index 486c774..75d497d 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/tests/compiler/dart2js/equivalence/equivalence_helper.dart
@@ -2,35 +2,35 @@
 // 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.
 
-/// Functions for asserting equivalence across serialization.
+/// Functions for asserting equivalence across different compiler
+/// implementations.
 
-library dart2js.serialization.equivalence;
+library dart2js.test.equivalence;
 
-import '../closure.dart';
-import '../common/resolution.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/modelx.dart';
-import '../elements/jumps.dart';
-import '../elements/names.dart';
-import '../elements/types.dart';
-import '../elements/visitor.dart';
-import '../js_backend/backend_serialization.dart'
-    show NativeBehaviorSerialization;
-import '../native/native.dart' show NativeBehavior;
-import '../resolution/access_semantics.dart';
-import '../resolution/send_structure.dart';
-import '../resolution/tree_elements.dart';
+import 'package:compiler/src/closure.dart';
+import 'package:compiler/src/common/resolution.dart';
+import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/constants/values.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/jumps.dart';
+import 'package:compiler/src/elements/modelx.dart';
+import 'package:compiler/src/elements/names.dart';
+import 'package:compiler/src/elements/resolution_types.dart';
+import 'package:compiler/src/elements/types.dart';
+import 'package:compiler/src/elements/visitor.dart';
+import 'package:compiler/src/native/native.dart'
+    show NativeBehavior, SpecialType;
+import 'package:compiler/src/resolution/access_semantics.dart';
+import 'package:compiler/src/resolution/send_structure.dart';
+import 'package:compiler/src/resolution/tree_elements.dart';
+import 'package:compiler/src/tree/nodes.dart';
+import 'package:compiler/src/universe/feature.dart';
+import 'package:compiler/src/universe/selector.dart';
+import 'package:compiler/src/universe/use.dart';
+import 'package:compiler/src/util/util.dart';
+
 import 'package:front_end/src/fasta/scanner.dart';
-import '../tree/nodes.dart';
-import '../universe/selector.dart';
-import '../universe/feature.dart';
-import '../universe/use.dart';
-import '../util/util.dart';
-import 'resolved_ast_serialization.dart';
 
 typedef bool Equivalence<E>(E a, E b, {TestStrategy strategy});
 
@@ -1237,27 +1237,26 @@
           a,
           b,
           'dartTypesReturned',
-          NativeBehaviorSerialization.filterDartTypes(a.typesReturned),
-          NativeBehaviorSerialization.filterDartTypes(b.typesReturned)) &&
+          NativeBehaviorFilters.filterDartTypes(a.typesReturned),
+          NativeBehaviorFilters.filterDartTypes(b.typesReturned)) &&
       strategy.testLists(
           a,
           b,
           'specialTypesReturned',
-          NativeBehaviorSerialization.filterSpecialTypes(a.typesReturned),
-          NativeBehaviorSerialization.filterSpecialTypes(b.typesReturned)) &&
+          NativeBehaviorFilters.filterSpecialTypes(a.typesReturned),
+          NativeBehaviorFilters.filterSpecialTypes(b.typesReturned)) &&
       strategy.testTypeLists(
           a,
           b,
           'dartTypesInstantiated',
-          NativeBehaviorSerialization.filterDartTypes(a.typesInstantiated),
-          NativeBehaviorSerialization.filterDartTypes(b.typesInstantiated)) &&
+          NativeBehaviorFilters.filterDartTypes(a.typesInstantiated),
+          NativeBehaviorFilters.filterDartTypes(b.typesInstantiated)) &&
       strategy.testLists(
           a,
           b,
           'specialTypesInstantiated',
-          NativeBehaviorSerialization.filterSpecialTypes(a.typesInstantiated),
-          NativeBehaviorSerialization
-              .filterSpecialTypes(b.typesInstantiated)) &&
+          NativeBehaviorFilters.filterSpecialTypes(a.typesInstantiated),
+          NativeBehaviorFilters.filterSpecialTypes(b.typesInstantiated)) &&
       strategy.test(a, b, 'useGvn', a.useGvn, b.useGvn);
 }
 
@@ -2232,3 +2231,62 @@
           metadata1.annotatedElement, metadata2.annotatedElement) &&
       areConstantsEquivalent(metadata1.constant, metadata2.constant);
 }
+
+class NativeBehaviorFilters {
+  static const int NORMAL_TYPE = 0;
+  static const int THIS_TYPE = 1;
+  static const int SPECIAL_TYPE = 2;
+
+  static int getTypeKind(var type) {
+    if (type is DartType) {
+      // TODO(johnniwinther): Remove this when annotation are no longer resolved
+      // to this-types.
+      if (type is InterfaceType &&
+          type.typeArguments.isNotEmpty &&
+          type.typeArguments.first is TypeVariableType) {
+        return THIS_TYPE;
+      }
+      return NORMAL_TYPE;
+    }
+    return SPECIAL_TYPE;
+  }
+
+  /// Returns a list of the non-this-type [ResolutionDartType]s in [types].
+  static List<ResolutionDartType> filterDartTypes(List types) {
+    return types.where((type) => getTypeKind(type) == NORMAL_TYPE).toList();
+  }
+
+  // TODO(johnniwinther): Remove this when annotation are no longer resolved
+  // to this-types.
+  /// Returns a list of the classes of this-types in [types].
+  static List<Element> filterThisTypes(List types) {
+    return types
+        .where((type) => getTypeKind(type) == THIS_TYPE)
+        .map((type) => type.element)
+        .toList();
+  }
+
+  /// Returns a list of the names of the [SpecialType]s in [types].
+  static List<String> filterSpecialTypes(List types) {
+    return types.where((type) => getTypeKind(type) == SPECIAL_TYPE).map((t) {
+      SpecialType type = t;
+      return type.name;
+    }).toList();
+  }
+}
+
+/// Visitor that computes a node-index mapping.
+class AstIndexComputer extends Visitor {
+  final Map<Node, int> nodeIndices = <Node, int>{};
+  final List<Node> nodeList = <Node>[];
+
+  @override
+  visitNode(Node node) {
+    nodeIndices.putIfAbsent(node, () {
+      // Some nodes (like Modifier and empty NodeList) can be reused.
+      nodeList.add(node);
+      return nodeIndices.length;
+    });
+    node.visitChildren(this);
+  }
+}
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index fad8d47..1ab3749 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -587,6 +587,9 @@
       } else {
         print('--from kernel (strong mode)-----------------------------------');
         List<String> options = [Flags.strongMode]..addAll(testOptions);
+        if (trustTypeAnnotations) {
+          options.add(Flags.omitImplicitChecks);
+        }
         MemberAnnotations<IdValue> annotations = expectedMaps[strongMarker];
         CompiledData compiledData2 = await computeData(
             entryPoint, memorySourceFiles, computeFromKernel,
diff --git a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
index 6fa2be5..5c22fee 100644
--- a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
+++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -10,7 +10,6 @@
 import '../type_test_helper.dart';
 
 const List<FunctionTypeData> existentialTypeData = const <FunctionTypeData>[
-  // TODO(johnniwinther): Test generic bounds when #31531 is fixed.
   const FunctionTypeData('void', 'F1', '<T>(T t)'),
   const FunctionTypeData('void', 'F2', '<S>(S s)'),
   const FunctionTypeData('void', 'F3', '<U, V>(U u, V v)'),
@@ -31,10 +30,13 @@
       factory C3.fact() => C3.gen();
       C3.gen();
     }
+    class C4 implements C3<C4> {}
     void F9<U extends V, V>(U u, V v) {}
     F10() {
       void local<A extends B, B>(A a, B b) {}
     }
+    void F11<Q extends C3<Q>>(Q q) {}
+    void F12<P extends C3<P>>(P p) {}
   """), compileMode: CompileMode.kernel, options: [Flags.strongMode]);
 
     testToString(FunctionType type, String expectedToString) {
@@ -79,6 +81,8 @@
     InterfaceType int_ = env['int'];
     InterfaceType C1 = instantiate(env.getClass('C1'), []);
     InterfaceType C2 = instantiate(env.getClass('C2'), []);
+    ClassEntity C3 = env.getClass('C3');
+    InterfaceType C4 = instantiate(env.getClass('C4'), []);
     FunctionType F1 = env.getFieldType('F1');
     FunctionType F2 = env.getFieldType('F2');
     FunctionType F3 = env.getFieldType('F3');
@@ -89,6 +93,8 @@
     FunctionType F8 = env.getFieldType('F8');
     FunctionType F9 = env.getMemberType('F9');
     FunctionType F10 = env.getClosureType('F10');
+    FunctionType F11 = env.getMemberType('F11');
+    FunctionType F12 = env.getMemberType('F12');
 
     List<FunctionType> all = <FunctionType>[
       F1,
@@ -101,6 +107,8 @@
       F8,
       F9,
       F10,
+      F11,
+      F12,
     ];
 
     testToString(F1, 'void Function<#A>(#A)');
@@ -113,6 +121,8 @@
     testToString(F8, '#A Function<#A extends num>(#A)');
     testToString(F9, 'void Function<#A extends #B,#B>(#A,#B)');
     testToString(F10, 'void Function<#A extends #B,#B>(#A,#B)');
+    testToString(F11, 'void Function<#A extends C3<#A>>(#A)');
+    testToString(F12, 'void Function<#A extends C3<#A>>(#A)');
 
     testBounds(F1, [Object_]);
     testBounds(F2, [Object_]);
@@ -124,6 +134,12 @@
     testBounds(F8, [num_]);
     testBounds(F9, [F9.typeVariables.last, Object_]);
     testBounds(F10, [F10.typeVariables.last, Object_]);
+    testBounds(F11, [
+      instantiate(C3, [F11.typeVariables.last])
+    ]);
+    testBounds(F12, [
+      instantiate(C3, [F12.typeVariables.last])
+    ]);
 
     testInstantiate(F1, [C1], 'void Function(C1)');
     testInstantiate(F2, [C2], 'void Function(C2)');
@@ -135,6 +151,8 @@
     testInstantiate(F8, [int_], 'int Function(int)');
     testInstantiate(F9, [int_, num_], 'void Function(int,num)');
     testInstantiate(F10, [int_, num_], 'void Function(int,num)');
+    testInstantiate(F11, [C4], 'void Function(C4)');
+    testInstantiate(F12, [C4], 'void Function(C4)');
 
     Map<FunctionType, List<FunctionType>> expectedEquals =
         <FunctionType, List<FunctionType>>{
@@ -142,6 +160,8 @@
       F2: [F1],
       F9: [F10],
       F10: [F9],
+      F11: [F12],
+      F12: [F11],
     };
 
     Map<FunctionType, List<FunctionType>> expectedSubtype =
@@ -163,8 +183,7 @@
         areEqual: true);
     testRelations(F1.typeVariables.first, F2.typeVariables.first);
 
-    ClassEntity cls = env.getClass('C3');
-    env.elementEnvironment.forEachConstructor(cls,
+    env.elementEnvironment.forEachConstructor(C3,
         (ConstructorEntity constructor) {
       Expect.equals(
           0,
diff --git a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
new file mode 100644
index 0000000..e938ddb
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Test based on language_2/call_method_function_typed_value_test/04
+
+import "package:expect/expect.dart";
+
+/*ast.element: f:[subclass=JSNumber]*/
+/*kernel.element: f:[subclass=JSNumber]*/
+/*strong.element: f:[subclass=JSInt]*/
+int f(int /*[null|subclass=Object]*/ i) => 2 /*invoke: [exact=JSUInt31]*/ * i;
+
+typedef int IntToInt(int x);
+
+/*element: test:[null]*/
+test(/*[null|subclass=Object]*/ a, /*[subclass=Closure]*/ b) =>
+    Expect.identical(a, b);
+
+/*element: main:[null]*/
+main() {
+  // It is possible to use `.call` on a function-typed value (even though it is
+  // redundant).  Similarly, it is possible to tear off `.call` on a
+  // function-typed value (but it is a no-op).
+  IntToInt f2 = f;
+
+  test(f2. /*[subclass=Closure]*/ call, f);
+}
diff --git a/tests/compiler/dart2js/inference/data/closurization_instance.dart b/tests/compiler/dart2js/inference/data/closurization_instance.dart
index 13f52ca..a4b1c5f 100644
--- a/tests/compiler/dart2js/inference/data/closurization_instance.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_instance.dart
@@ -17,19 +17,17 @@
   method() => 42;
 }
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var c = new Class();
   var local = c. /*[exact=Class]*/ method;
   local. /*invoke: [subclass=Closure]*/ toString();
   local();
   local
-      . /*invoke: [empty]*/
+      . /*invoke: [subclass=Closure]*/
       toString();
   local.call();
   return local
-      . /*invoke: [empty]*/
+      . /*invoke: [subclass=Closure]*/
       toString();
 }
diff --git a/tests/compiler/dart2js/inference/data/closurization_instance_call.dart b/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
index 5a074cd..0c98bcc 100644
--- a/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
@@ -21,11 +21,7 @@
   method() => 42;
 }
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [exact=Class].
-/*ast.element: closurizedCallToString:[exact=JSString]*/
-/*kernel.element: closurizedCallToString:[exact=JSString]*/
-/*strong.element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var c = new Class();
   c.call(); // Make `Class.call` live.
@@ -39,15 +35,15 @@
   local();
   local
       .
-      /*ast.invoke: [exact=Class]*/
-      /*kernel.invoke: [exact=Class]*/
-      /*strong.invoke: [empty]*/
+      /*ast.invoke: [subtype=Function]*/
+      /*kernel.invoke: [subtype=Function]*/
+      /*strong.invoke: [subclass=Closure]*/
       toString();
   local.call();
   return local
       .
-      /*ast.invoke: [exact=Class]*/
-      /*kernel.invoke: [exact=Class]*/
-      /*strong.invoke: [empty]*/
+      /*ast.invoke: [subtype=Function]*/
+      /*kernel.invoke: [subtype=Function]*/
+      /*strong.invoke: [subclass=Closure]*/
       toString();
 }
diff --git a/tests/compiler/dart2js/inference/data/closurization_local_call.dart b/tests/compiler/dart2js/inference/data/closurization_local_call.dart
index 2e2cf0e..25e3bcd 100644
--- a/tests/compiler/dart2js/inference/data/closurization_local_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_local_call.dart
@@ -18,11 +18,7 @@
   call() => true;
 }
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [exact=Class].
-/*ast.element: closurizedCallToString:[exact=JSString]*/
-/*kernel.element: closurizedCallToString:[exact=JSString]*/
-/*strong.element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var c = new Class();
   c.call(); // Make `Class.call` live.
@@ -36,15 +32,15 @@
   local();
   local
       .
-      /*ast.invoke: [exact=Class]*/
-      /*kernel.invoke: [exact=Class]*/
-      /*strong.invoke: [empty]*/
+      /*ast.invoke: [subtype=Function]*/
+      /*kernel.invoke: [subtype=Function]*/
+      /*strong.invoke: [subclass=Closure]*/
       toString();
   local.call();
   return local
       .
-      /*ast.invoke: [exact=Class]*/
-      /*kernel.invoke: [exact=Class]*/
-      /*strong.invoke: [empty]*/
+      /*ast.invoke: [subtype=Function]*/
+      /*kernel.invoke: [subtype=Function]*/
+      /*strong.invoke: [subclass=Closure]*/
       toString();
 }
diff --git a/tests/compiler/dart2js/inference/data/closurization_static.dart b/tests/compiler/dart2js/inference/data/closurization_static.dart
index e93e641..5ddf338 100644
--- a/tests/compiler/dart2js/inference/data/closurization_static.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_static.dart
@@ -14,18 +14,16 @@
 /*element: method:[exact=JSUInt31]*/
 method() => 42;
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var local = method;
   local. /*invoke: [subclass=Closure]*/ toString();
   local();
   local
-      . /*invoke: [empty]*/
+      . /*invoke: [subclass=Closure]*/
       toString();
   local.call();
   return local
-      . /*invoke: [empty]*/
+      . /*invoke: [subclass=Closure]*/
       toString();
 }
diff --git a/tests/compiler/dart2js/inference/data/closurization_static_call.dart b/tests/compiler/dart2js/inference/data/closurization_static_call.dart
index e4efff1..6a28213 100644
--- a/tests/compiler/dart2js/inference/data/closurization_static_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_static_call.dart
@@ -21,11 +21,7 @@
   call() => true;
 }
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [exact=Class].
-/*ast.element: closurizedCallToString:[exact=JSString]*/
-/*kernel.element: closurizedCallToString:[exact=JSString]*/
-/*strong.element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var c = new Class();
   c.call(); // Make `Class.call` live.
@@ -39,15 +35,15 @@
   local();
   local
       .
-      /*ast.invoke: [exact=Class]*/
-      /*kernel.invoke: [exact=Class]*/
-      /*strong.invoke: [empty]*/
+      /*ast.invoke: [subtype=Function]*/
+      /*kernel.invoke: [subtype=Function]*/
+      /*strong.invoke: [subclass=Closure]*/
       toString();
   local.call();
   return local
       .
-      /*ast.invoke: [exact=Class]*/
-      /*kernel.invoke: [exact=Class]*/
-      /*strong.invoke: [empty]*/
+      /*ast.invoke: [subtype=Function]*/
+      /*kernel.invoke: [subtype=Function]*/
+      /*strong.invoke: [subclass=Closure]*/
       toString();
 }
diff --git a/tests/compiler/dart2js/inference/data/local_functions.dart b/tests/compiler/dart2js/inference/data/local_functions.dart
index f6b03f1..478faf2 100644
--- a/tests/compiler/dart2js/inference/data/local_functions.dart
+++ b/tests/compiler/dart2js/inference/data/local_functions.dart
@@ -94,35 +94,29 @@
 // Implicit .call on a local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closureToString:[empty]*/
+/*element: closureToString:[exact=JSString]*/
 closureToString() {
   var local = /*[null]*/ () {};
   local();
-  return local. /*invoke: [empty]*/ toString();
+  return local. /*invoke: [subclass=Closure]*/ toString();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Explicit .call on a local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closureCallToString:[empty]*/
+/*element: closureCallToString:[exact=JSString]*/
 closureCallToString() {
   var local = /*[null]*/ () {};
   local.call();
-  return local. /*invoke: [empty]*/ toString();
+  return local. /*invoke: [subclass=Closure]*/ toString();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Operator == on the result of a parameter invocation.
 ////////////////////////////////////////////////////////////////////////////////
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: _callCompare:[empty]*/
+/*element: _callCompare:[subclass=Closure]*/
 _callCompare(int /*[subclass=Closure]*/ compare({a, b})) {
   compare(a: 0, b: 1) == 0;
   return compare;
@@ -145,7 +139,7 @@
   method1() {}
 }
 
-/*element: _callClosure:[empty]*/
+/*element: _callClosure:[subclass=Closure]*/
 _callClosure(/*[subclass=Closure]*/ f({c})) {
   f(c: new Class1()).method1();
   return f;
diff --git a/tests/compiler/dart2js/inference/data/local_functions_call.dart b/tests/compiler/dart2js/inference/data/local_functions_call.dart
index 308de0f..586bf73 100644
--- a/tests/compiler/dart2js/inference/data/local_functions_call.dart
+++ b/tests/compiler/dart2js/inference/data/local_functions_call.dart
@@ -15,14 +15,12 @@
 // Explicit .call on a local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closureCallToString:[empty]*/
+/*element: closureCallToString:[exact=JSString]*/
 closureCallToString() {
   var local = /*[null]*/ () {};
   local.call();
   return local
       .
-      /*invoke: [empty]*/
+      /*invoke: [subclass=Closure]*/
       toString();
 }
diff --git a/tests/compiler/dart2js/inference/data/locals_notrust.dart b/tests/compiler/dart2js/inference/data/locals_notrust.dart
index bf14080..35f518a 100644
--- a/tests/compiler/dart2js/inference/data/locals_notrust.dart
+++ b/tests/compiler/dart2js/inference/data/locals_notrust.dart
@@ -31,6 +31,7 @@
 // function.
 ////////////////////////////////////////////////////////////////////////////////
 
+// TODO(johnniwinther): Trust the function type in strong mode.
 /*element: _dontTrustFunctions:[exact=JSBool]*/
 _dontTrustFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
   dynamic c = f(0);
diff --git a/tests/compiler/dart2js/inference/data/locals_trust.dart b/tests/compiler/dart2js/inference/data/locals_trust.dart
index f3dc89b..c179e96 100644
--- a/tests/compiler/dart2js/inference/data/locals_trust.dart
+++ b/tests/compiler/dart2js/inference/data/locals_trust.dart
@@ -10,7 +10,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Test that we trust the explicit type of a local with
-// --trust-type-annotations.
+// --trust-type-annotations or --omit-implicit-checks.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*element: _trustLocals:[exact=JSBool]*/ _trustLocals(
@@ -27,9 +27,10 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Test that we don't trust the type of a function even with
-// --trust-type-annotations.
+// --trust-type-annotations or --omit-implicit-checks.
 ////////////////////////////////////////////////////////////////////////////////
 
+// TODO(johnniwinther): Trust the function type in strong mode.
 /*element: _dontTrustFunctions:[exact=JSBool]*/
 _dontTrustFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
   dynamic c = f(0);
diff --git a/tests/compiler/dart2js/inference/data/parameters_notrust.dart b/tests/compiler/dart2js/inference/data/parameters_notrust.dart
new file mode 100644
index 0000000..41503d2
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/parameters_notrust.dart
@@ -0,0 +1,35 @@
+// 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:expect/expect.dart';
+
+/*element: main:[null]*/
+main() {
+  dontTrustParameters();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test that we don't trust the explicit type of a parameter, but do trust
+// the local type of parameters in Dart 2.
+//
+// This means that in both Dart 1 and Dart 2 we infer the parameter type to be
+// either an int or a String. In Dart 1 we don't trust the static type of the
+// parameter within the method, so the return type is inferred to be either an
+// int or a String. In Dart 2 we _do_ trust the static type of the parameter
+// within the method and therefore infer the return type to be an int.
+////////////////////////////////////////////////////////////////////////////////
+
+/*ast.element: _dontTrustParameters:Union([exact=JSString], [exact=JSUInt31])*/
+/*kernel.element: _dontTrustParameters:Union([exact=JSString], [exact=JSUInt31])*/
+/*strong.element: _dontTrustParameters:[exact=JSUInt31]*/
+_dontTrustParameters(int /*Union([exact=JSString], [exact=JSUInt31])*/ i) {
+  return i;
+}
+
+/*element: dontTrustParameters:[null]*/
+dontTrustParameters() {
+  dynamic f = _dontTrustParameters;
+  Expect.equals(0, f(0));
+  Expect.throws(/*[null|subclass=Object]*/ () => f('foo'));
+}
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
index a36baa9..3b7ff13 100644
--- a/tests/compiler/dart2js/inference/data/parameters_trust.dart
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -11,16 +11,11 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Test that we trust the explicit type of a parameter with
-// --trust-type-annotations.
+// --trust-type-annotations or --omit-implicit-checks.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*element: _trustParameters:[exact=JSUInt31]*/
-_trustParameters(
-    int
-        /*ast.[exact=JSUInt31]*/
-        /*kernel.[exact=JSUInt31]*/
-        /*strong.Union([exact=JSString], [exact=JSUInt31])*/
-        i) {
+_trustParameters(int /*[exact=JSUInt31]*/ i) {
   return i;
 }
 
diff --git a/tests/compiler/dart2js/inference/data/refine_locals.dart b/tests/compiler/dart2js/inference/data/refine_locals.dart
index c7c328c..54a4013 100644
--- a/tests/compiler/dart2js/inference/data/refine_locals.dart
+++ b/tests/compiler/dart2js/inference/data/refine_locals.dart
@@ -178,16 +178,14 @@
 // Refine the type of a local variable through a sequence of invocations.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _refineToClosureLocal:[empty]*/
+/*element: _refineToClosureLocal:[subclass=Closure]*/
 _refineToClosureLocal() {
   var f = /*[null]*/ ({/*[exact=JSUInt31]*/ a}) {};
   f(a: 0);
   return f;
 }
 
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: _refineToClosureLocalCall:[empty]*/
+/*element: _refineToClosureLocalCall:[subclass=Closure]*/
 _refineToClosureLocalCall() {
   var f = /*[null]*/ ({/*[exact=JSUInt31]*/ b}) {};
   f.call(b: 0);
diff --git a/tests/compiler/dart2js/kernel/arguments.dart b/tests/compiler/dart2js/kernel/arguments.dart
new file mode 100644
index 0000000..11374c0
--- /dev/null
+++ b/tests/compiler/dart2js/kernel/arguments.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.kernel.arguments;
+
+import 'package:compiler/src/filenames.dart';
+
+class Arguments {
+  final String filename;
+  final int start;
+  final int end;
+  final bool verbose;
+
+  const Arguments({this.filename, this.start, this.end, this.verbose: false});
+
+  factory Arguments.from(List<String> arguments) {
+    String filename;
+    int start;
+    int end;
+    for (String arg in arguments) {
+      if (!arg.startsWith('-')) {
+        int index = int.parse(arg, onError: (_) => null);
+        if (index == null) {
+          filename = arg;
+        } else if (start == null) {
+          start = index;
+        } else {
+          end = index;
+        }
+      }
+    }
+    bool verbose = arguments.contains('-v');
+    return new Arguments(
+        filename: filename, start: start, end: end, verbose: verbose);
+  }
+
+  Uri get uri {
+    if (filename != null) {
+      return Uri.base.resolve(nativeToUriPath(filename));
+    }
+    return null;
+  }
+}
diff --git a/tests/compiler/dart2js/kernel/closed_world2_test.dart b/tests/compiler/dart2js/kernel/closed_world2_test.dart
index fe9b70d..d21a95d 100644
--- a/tests/compiler/dart2js/kernel/closed_world2_test.dart
+++ b/tests/compiler/dart2js/kernel/closed_world2_test.dart
@@ -18,14 +18,14 @@
 import 'package:compiler/src/js_backend/backend_usage.dart';
 import 'package:compiler/src/kernel/element_map.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/universe/world_builder.dart';
 import 'package:compiler/src/util/util.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../memory_compiler.dart';
-import '../serialization/helper.dart';
 import '../equivalence/check_functions.dart';
+import '../equivalence/equivalence_helper.dart';
+import 'arguments.dart';
 import 'compiler_helper.dart';
 import 'test_helpers.dart';
 
diff --git a/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart b/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart
index 5dc6689..21dd30e 100644
--- a/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart
+++ b/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart
@@ -22,10 +22,9 @@
 import 'package:expect/expect.dart';
 import '../memory_compiler.dart';
 import '../equivalence/check_functions.dart';
-import '../serialization/helper.dart';
-import 'test_helpers.dart';
-
+import 'arguments.dart';
 import 'compiler_helper.dart';
+import 'test_helpers.dart';
 
 const SOURCE = const {
   'main.dart': '''
diff --git a/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart b/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart
index e6e987e..0de692d 100644
--- a/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart
+++ b/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart
@@ -17,17 +17,17 @@
 import 'package:compiler/src/kernel/element_map.dart';
 import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/universe/world_builder.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../memory_compiler.dart';
 import '../equivalence/check_functions.dart';
 import '../equivalence/check_helpers.dart';
-import '../serialization/helper.dart';
-import 'test_helpers.dart';
+import '../equivalence/equivalence_helper.dart';
 
+import 'arguments.dart';
 import 'compiler_helper.dart';
+import 'test_helpers.dart';
 
 class Test {
   final Uri uri;
diff --git a/tests/compiler/dart2js/kernel/impact_test.dart b/tests/compiler/dart2js/kernel/impact_test.dart
index 42e37e7..1e21b09 100644
--- a/tests/compiler/dart2js/kernel/impact_test.dart
+++ b/tests/compiler/dart2js/kernel/impact_test.dart
@@ -17,13 +17,13 @@
 import 'package:compiler/src/kernel/element_map_impl.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:compiler/src/resolution/registry.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/universe/call_structure.dart';
 import 'package:compiler/src/universe/feature.dart';
 import 'package:compiler/src/universe/use.dart';
 import 'package:compiler/src/util/util.dart';
 import 'package:expect/expect.dart';
 import '../equivalence/check_helpers.dart';
+import '../equivalence/equivalence_helper.dart';
 import 'compiler_helper.dart';
 import 'test_helpers.dart';
 
diff --git a/tests/compiler/dart2js/kernel/run_from_dill_test.dart b/tests/compiler/dart2js/kernel/run_from_dill_test.dart
index da6d490..29e526e 100644
--- a/tests/compiler/dart2js/kernel/run_from_dill_test.dart
+++ b/tests/compiler/dart2js/kernel/run_from_dill_test.dart
@@ -10,8 +10,8 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/commandline_options.dart';
 
+import 'arguments.dart';
 import 'compiler_helper.dart';
-import '../serialization/helper.dart';
 
 const SOURCE = const {
   'main.dart': r'''
diff --git a/tests/compiler/dart2js/kernel/test_helpers.dart b/tests/compiler/dart2js/kernel/test_helpers.dart
index cf49121..3f24c19 100644
--- a/tests/compiler/dart2js/kernel/test_helpers.dart
+++ b/tests/compiler/dart2js/kernel/test_helpers.dart
@@ -15,9 +15,10 @@
 import 'package:compiler/src/kernel/element_map_impl.dart';
 import 'package:compiler/src/kernel/indexed.dart';
 import 'package:compiler/src/kernel/kelements.dart' show KLocalFunction;
-import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/util/util.dart';
 
+import '../equivalence/equivalence_helper.dart';
+
 class KernelEquivalence {
   final WorldDeconstructionForTesting testing;
 
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index a5f6d2e..88dc06c 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -85,7 +85,6 @@
     {Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
     Uri entryPoint,
     List<Uri> entryPoints,
-    List<Uri> resolutionInputs,
     CompilerDiagnostics diagnosticHandler,
     CompilerOutput outputProvider,
     List<String> options: const <String>[],
@@ -100,7 +99,6 @@
   }
   CompilerImpl compiler = compilerFor(
       entryPoint: entryPoint,
-      resolutionInputs: resolutionInputs,
       memorySourceFiles: memorySourceFiles,
       diagnosticHandler: diagnosticHandler,
       outputProvider: outputProvider,
@@ -132,7 +130,6 @@
 
 CompilerImpl compilerFor(
     {Uri entryPoint,
-    List<Uri> resolutionInputs,
     Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
     CompilerDiagnostics diagnosticHandler,
     CompilerOutput outputProvider,
@@ -185,7 +182,6 @@
   CompilerOptions compilerOptions = CompilerOptions.parse(options,
       libraryRoot: libraryRoot, platformBinaries: platformBinaries)
     ..entryPoint = entryPoint
-    ..resolutionInputs = resolutionInputs
     ..packageRoot = packageRoot
     ..environment = {}
     ..packageConfig = packageConfig
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 9340024..24a93e7 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -43,7 +43,7 @@
     }
     Input input;
     switch (inputKind) {
-      case InputKind.utf8:
+      case InputKind.UTF8:
         if (source is String) {
           input = new StringSourceFile.fromUri(resourceUri, source);
         } else {
@@ -66,6 +66,6 @@
 
   @override
   Future<Input> readFromUri(Uri resourceUri,
-          {InputKind inputKind: InputKind.utf8}) =>
+          {InputKind inputKind: InputKind.UTF8}) =>
       readBytesFromUri(resourceUri, inputKind);
 }
diff --git a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
index 4cbd4b9..532dd9e 100644
--- a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
@@ -101,12 +101,14 @@
   InterfaceType get enclosingConstructedType =>
       _environment.enclosingConstructedType;
 
+  @override
   void reportWarning(
       ConstantExpression expression, MessageKind kind, Map arguments) {
     errors.add(new EvaluationError(kind, arguments));
     _environment.reportWarning(expression, kind, arguments);
   }
 
+  @override
   void reportError(
       ConstantExpression expression, MessageKind kind, Map arguments) {
     errors.add(new EvaluationError(kind, arguments));
@@ -119,6 +121,7 @@
     return _environment.evaluateConstructor(constructor, type, evaluate);
   }
 
+  @override
   ConstantValue evaluateField(FieldEntity field, ConstantValue evaluate()) {
     return _environment.evaluateField(field, evaluate);
   }
diff --git a/tests/compiler/dart2js/old_frontend/library_resolution_test.dart b/tests/compiler/dart2js/old_frontend/library_resolution_test.dart
index 190bea2..86250d2 100644
--- a/tests/compiler/dart2js/old_frontend/library_resolution_test.dart
+++ b/tests/compiler/dart2js/old_frontend/library_resolution_test.dart
@@ -56,7 +56,7 @@
     if (uri == mock2LibraryUri) {
       uri = Uri.parse('memory:mock2.dart');
     }
-    Input input = await provider.readBytesFromUri(uri, InputKind.utf8);
+    Input input = await provider.readBytesFromUri(uri, InputKind.UTF8);
     return input.data;
   }
 
diff --git a/tests/compiler/dart2js/old_frontend/message_span_test.dart b/tests/compiler/dart2js/old_frontend/message_span_test.dart
index 35009d7..6d774bc 100644
--- a/tests/compiler/dart2js/old_frontend/message_span_test.dart
+++ b/tests/compiler/dart2js/old_frontend/message_span_test.dart
@@ -162,7 +162,7 @@
           // Remove `filename:line:column:` and message.
           String strippedLocationMessage = locationMessage
               .substring(locationMessage.indexOf(MARKER) + MARKER.length + 1);
-          // Using JSON.encode to add string quotes and backslashes.
+          // Using jsonEncode to add string quotes and backslashes.
           String expected = json.encode(
               utf8.decode(expectedSpanText.codeUnits, allowMalformed: true));
           String actual = json.encode(utf8
diff --git a/tests/compiler/dart2js/serialization/analysis1_test.dart b/tests/compiler/dart2js/serialization/analysis1_test.dart
deleted file mode 100644
index e78f634..0000000
--- a/tests/compiler/dart2js/serialization/analysis1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis1_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis2_test.dart b/tests/compiler/dart2js/serialization/analysis2_test.dart
deleted file mode 100644
index 05c3339..0000000
--- a/tests/compiler/dart2js/serialization/analysis2_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis2_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis3_test.dart b/tests/compiler/dart2js/serialization/analysis3_test.dart
deleted file mode 100644
index 84da9d9..0000000
--- a/tests/compiler/dart2js/serialization/analysis3_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis3_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis4_test.dart b/tests/compiler/dart2js/serialization/analysis4_test.dart
deleted file mode 100644
index ff5c1ac..0000000
--- a/tests/compiler/dart2js/serialization/analysis4_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis4_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis5_test.dart b/tests/compiler/dart2js/serialization/analysis5_test.dart
deleted file mode 100644
index 4e44643..0000000
--- a/tests/compiler/dart2js/serialization/analysis5_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis5_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis_test_helper.dart b/tests/compiler/dart2js/serialization/analysis_test_helper.dart
deleted file mode 100644
index 8c48c7c..0000000
--- a/tests/compiler/dart2js/serialization/analysis_test_helper.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_analysis_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/filenames.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-import 'test_data.dart';
-
-/// Number of tests that are not part of the automatic test grouping.
-int SKIP_COUNT = 0;
-
-/// Number of groups that the [TESTS] are split into.
-int SPLIT_COUNT = 5;
-
-main(List<String> args) {
-  asyncTest(() async {
-    Arguments arguments = new Arguments.from(args);
-    SerializedData serializedData =
-        await serializeDartCore(arguments: arguments);
-    if (arguments.filename != null) {
-      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
-      await analyze(entryPoint,
-          resolutionInputs: serializedData.toUris(),
-          sourceFiles: serializedData.toMemorySourceFiles());
-    } else {
-      await arguments.forEachTest(serializedData, TESTS, analyze);
-    }
-    printMeasurementResults();
-  });
-}
-
-Future analyze(Uri entryPoint,
-    {Map<String, String> sourceFiles: const <String, String>{},
-    List<Uri> resolutionInputs,
-    int index,
-    Test test,
-    bool verbose: false}) async {
-  String testDescription = test != null ? test.name : '${entryPoint}';
-  String id = index != null ? '$index: ' : '';
-  String title = '${id}${testDescription}';
-  await measure(title, 'analyze', () async {
-    DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
-    await runCompiler(
-        entryPoint: entryPoint,
-        resolutionInputs: resolutionInputs,
-        memorySourceFiles: sourceFiles,
-        options: [Flags.analyzeOnly, Flags.useOldFrontend],
-        diagnosticHandler: diagnosticCollector);
-    if (test != null) {
-      Expect.equals(test.expectedErrorCount, diagnosticCollector.errors.length,
-          "Unexpected error count.");
-      Expect.equals(test.expectedWarningCount,
-          diagnosticCollector.warnings.length, "Unexpected warning count.");
-      Expect.equals(test.expectedHintCount, diagnosticCollector.hints.length,
-          "Unexpected hint count.");
-      Expect.equals(test.expectedInfoCount, diagnosticCollector.infos.length,
-          "Unexpected info count.");
-    }
-  });
-}
diff --git a/tests/compiler/dart2js/serialization/compilation0_test.dart b/tests/compiler/dart2js/serialization/compilation0_test.dart
deleted file mode 100644
index 3e68dd2..0000000
--- a/tests/compiler/dart2js/serialization/compilation0_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation0_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSkipped(0, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation1_test.dart b/tests/compiler/dart2js/serialization/compilation1_test.dart
deleted file mode 100644
index f59e0a0..0000000
--- a/tests/compiler/dart2js/serialization/compilation1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation1_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation2_test.dart b/tests/compiler/dart2js/serialization/compilation2_test.dart
deleted file mode 100644
index 1947010..0000000
--- a/tests/compiler/dart2js/serialization/compilation2_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation2_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation3_test.dart b/tests/compiler/dart2js/serialization/compilation3_test.dart
deleted file mode 100644
index 90bc6ff..0000000
--- a/tests/compiler/dart2js/serialization/compilation3_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation3_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation4_test.dart b/tests/compiler/dart2js/serialization/compilation4_test.dart
deleted file mode 100644
index 809f62b..0000000
--- a/tests/compiler/dart2js/serialization/compilation4_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation4_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation5_test.dart b/tests/compiler/dart2js/serialization/compilation5_test.dart
deleted file mode 100644
index 10ce5eb..0000000
--- a/tests/compiler/dart2js/serialization/compilation5_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation5_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation_1_test.dart b/tests/compiler/dart2js/serialization/compilation_1_test.dart
deleted file mode 100644
index 355cddc..0000000
--- a/tests/compiler/dart2js/serialization/compilation_1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation_1_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSkipped(1, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation_test_helper.dart b/tests/compiler/dart2js/serialization/compilation_test_helper.dart
deleted file mode 100644
index f1d22dd..0000000
--- a/tests/compiler/dart2js/serialization/compilation_test_helper.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_compilation_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/compiler_new.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/filenames.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-import 'test_data.dart';
-import '../output_collector.dart';
-
-/// Number of tests that are not part of the automatic test grouping.
-int SKIP_COUNT = 2;
-
-/// Number of groups that the [TESTS] are split into.
-int SPLIT_COUNT = 5;
-
-main(List<String> args) {
-  asyncTest(() async {
-    Arguments arguments = new Arguments.from(args);
-    SerializedData serializedData =
-        await serializeDartCore(arguments: arguments);
-    if (arguments.filename != null) {
-      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
-      SerializationResult result = await serialize(entryPoint,
-          memorySourceFiles: serializedData.toMemorySourceFiles(),
-          resolutionInputs: serializedData.toUris());
-      await compile(entryPoint,
-          resolutionInputs: result.serializedData.toUris(),
-          sourceFiles: result.serializedData.toMemorySourceFiles());
-    } else {
-      await arguments.forEachTest(serializedData, TESTS, compile);
-    }
-    printMeasurementResults();
-  });
-}
-
-Future compile(Uri entryPoint,
-    {Map<String, String> sourceFiles: const <String, String>{},
-    List<Uri> resolutionInputs,
-    int index,
-    Test test,
-    bool verbose: false}) async {
-  String testDescription = test != null ? test.name : '${entryPoint}';
-  String id = index != null ? '$index: ' : '';
-  String title = '${id}${testDescription}';
-  OutputCollector outputCollector = new OutputCollector();
-  await measure(title, 'compile', () async {
-    List<String> options = [Flags.useOldFrontend];
-    if (test != null && test.checkedMode) {
-      options.add(Flags.enableCheckedMode);
-    }
-    await runCompiler(
-        entryPoint: entryPoint,
-        memorySourceFiles: sourceFiles,
-        resolutionInputs: resolutionInputs,
-        options: options,
-        outputProvider: outputCollector);
-  });
-  if (verbose) {
-    print(outputCollector.getOutput('', OutputType.js));
-  }
-}
diff --git a/tests/compiler/dart2js/serialization/duplicate_library_test.dart b/tests/compiler/dart2js/serialization/duplicate_library_test.dart
deleted file mode 100644
index 7f8eceb..0000000
--- a/tests/compiler/dart2js/serialization/duplicate_library_test.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.duplicate_libraryc_test;
-
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common/names.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-
-void main(List<String> args) {
-  asyncTest(() async {
-    SerializedData data =
-        await serializeDartCore(arguments: new Arguments.from(args));
-    Map<String, String> sourceFiles = data.toMemorySourceFiles();
-    List<Uri> resolutionInputs = data.toUris();
-    Uri extraUri = Uri.parse('memory:extraUri');
-    sourceFiles[extraUri.path] = data.data;
-    resolutionInputs.add(extraUri);
-
-    DiagnosticCollector collector = new DiagnosticCollector();
-    await runCompiler(
-        entryPoint: Uris.dart_core,
-        memorySourceFiles: sourceFiles,
-        resolutionInputs: resolutionInputs,
-        diagnosticHandler: collector,
-        options: [Flags.analyzeAll, Flags.useOldFrontend]);
-    Expect.isTrue(collector.errors.isNotEmpty,
-        "Expected duplicate serialized library errors.");
-  });
-}
diff --git a/tests/compiler/dart2js/serialization/equivalence_test.dart b/tests/compiler/dart2js/serialization/equivalence_test.dart
deleted file mode 100644
index 027df4e..0000000
--- a/tests/compiler/dart2js/serialization/equivalence_test.dart
+++ /dev/null
@@ -1,855 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.serialization_test;
-
-import 'dart:io';
-import '../memory_compiler.dart';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common.dart';
-import 'package:compiler/src/common/resolution.dart';
-import 'package:compiler/src/constants/constructors.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/invariant.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
-import 'package:compiler/src/elements/visitor.dart';
-import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/library_loader.dart';
-import 'package:compiler/src/ordered_typeset.dart';
-import 'package:compiler/src/serialization/element_serialization.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
-import 'package:compiler/src/serialization/json_serializer.dart';
-import 'package:compiler/src/serialization/serialization.dart';
-import 'package:expect/expect.dart';
-import '../equivalence/check_helpers.dart';
-
-const TEST_SOURCES = const <String, String>{
-  'main.dart': '''
-import 'library.dart';
-import 'deferred_library.dart' deferred as prefix;
-
-asyncMethod() async {}
-asyncStarMethod() async* {}
-syncStarMethod() sync* {}
-get asyncGetter async {}
-get asyncStarGetter async* {}
-get syncStarGetter sync* {}
-
-genericMethod<T>() {}
-
-class Class1 {
-  factory Class1.deferred() = prefix.DeferredClass;
-  factory Class1.unresolved() = Unresolved;
-}
-''',
-  'deferred_library.dart': '''
-class DeferredClass {
-}
-
-get getter => 0;
-set setter(_) {}
-get property => 0;
-set property(_) {}
-''',
-  'library.dart': '''
-class Type {}
-''',
-};
-
-main(List<String> arguments) {
-  // Ensure that we can print out constant expressions.
-  DEBUG_MODE = true;
-
-  Uri entryPoint;
-  String outPath;
-  bool prettyPrint = false;
-  for (String arg in arguments) {
-    if (arg.startsWith('--')) {
-      if (arg.startsWith('--out=')) {
-        outPath = arg.substring('--out='.length);
-      } else if (arg == '--pretty-print') {
-        prettyPrint = true;
-      } else {
-        print("Unknown option $arg");
-      }
-    } else {
-      if (entryPoint != null) {
-        print("Multiple entrypoints is not supported.");
-      }
-      entryPoint = Uri.base.resolve(nativeToUriPath(arg));
-    }
-  }
-  Map<String, String> sourceFiles = const <String, String>{};
-  if (entryPoint == null) {
-    entryPoint = Uri.parse('memory:main.dart');
-    sourceFiles = TEST_SOURCES;
-  }
-  asyncTest(() async {
-    CompilationResult result = await runCompiler(
-        memorySourceFiles: sourceFiles,
-        entryPoint: entryPoint,
-        options: [
-          Flags.analyzeAll,
-          Flags.genericMethodSyntax,
-          Flags.useOldFrontend
-        ]);
-    Compiler compiler = result.compiler;
-    testSerialization(compiler.libraryLoader.libraries, compiler.reporter,
-        compiler.resolution, compiler.libraryLoader,
-        outPath: outPath, prettyPrint: prettyPrint);
-    Expect.isFalse(
-        compiler.reporter.hasReportedError, "Unexpected errors occured.");
-  });
-}
-
-void testSerialization(
-    Iterable<LibraryElement> libraries1,
-    DiagnosticReporter reporter,
-    Resolution resolution,
-    LibraryProvider libraryProvider,
-    {String outPath,
-    bool prettyPrint}) {
-  Serializer serializer = new Serializer();
-  for (LibraryElement library1 in libraries1) {
-    serializer.serialize(library1);
-  }
-  String text = serializer.toText(const JsonSerializationEncoder());
-  String outText = text;
-  if (prettyPrint) {
-    outText = serializer.prettyPrint();
-  }
-  if (outPath != null) {
-    new File(outPath).writeAsStringSync(outText);
-  } else if (prettyPrint) {
-    print(outText);
-  }
-
-  Deserializer deserializer = new Deserializer.fromText(
-      new DeserializationContext(reporter, resolution, libraryProvider),
-      Uri.parse('out1.data'),
-      text,
-      const JsonSerializationDecoder());
-  List<LibraryElement> libraries2 = <LibraryElement>[];
-  for (LibraryElement library1 in libraries1) {
-    LibraryElement library2 = deserializer.lookupLibrary(library1.canonicalUri);
-    if (library2 == null) {
-      throw new ArgumentError('No library ${library1.canonicalUri} found.');
-    }
-    checkLibraryContent('library1', 'library2', 'library', library1, library2);
-    libraries2.add(library2);
-  }
-
-  Serializer serializer2 = new Serializer();
-  for (LibraryElement library2 in libraries2) {
-    serializer2.serialize(library2);
-  }
-  String text2 = serializer2.toText(const JsonSerializationEncoder());
-
-  Deserializer deserializer3 = new Deserializer.fromText(
-      new DeserializationContext(reporter, resolution, libraryProvider),
-      Uri.parse('out2.data'),
-      text2,
-      const JsonSerializationDecoder());
-  for (LibraryElement library1 in libraries1) {
-    LibraryElement library2 = deserializer.lookupLibrary(library1.canonicalUri);
-    if (library2 == null) {
-      throw new ArgumentError('No library ${library1.canonicalUri} found.');
-    }
-    LibraryElement library3 =
-        deserializer3.lookupLibrary(library1.canonicalUri);
-    if (library3 == null) {
-      throw new ArgumentError('No library ${library1.canonicalUri} found.');
-    }
-    checkLibraryContent('library1', 'library3', 'library', library1, library3);
-    checkLibraryContent('library2', 'library3', 'library', library2, library3);
-  }
-}
-
-/// Check the equivalence of [library1] and [library2] and their content.
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-checkLibraryContent(Object object1, object2, String property,
-    LibraryElement library1, LibraryElement library2) {
-  checkElementProperties(object1, object2, property, library1, library2);
-}
-
-/// Check the equivalence of [element1] and [element2] and their properties.
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-checkElementProperties(Object object1, object2, String property,
-    Element element1, Element element2) {
-  currentCheck =
-      new Check(currentCheck, object1, object2, property, element1, element2);
-  const ElementPropertyEquivalence().visit(element1, element2);
-  currentCheck = currentCheck.parent;
-}
-
-/// Checks the equivalence of [constructor1] and [constructor2].
-void constantConstructorEquivalence(
-    ConstantConstructor constructor1, ConstantConstructor constructor2) {
-  const ConstantConstructorEquivalence().visit(constructor1, constructor2);
-}
-
-/// Visitor that checks the equivalence of [ConstantConstructor]s.
-class ConstantConstructorEquivalence
-    extends ConstantConstructorVisitor<dynamic, ConstantConstructor> {
-  const ConstantConstructorEquivalence();
-
-  @override
-  void visit(
-      ConstantConstructor constructor1, ConstantConstructor constructor2) {
-    if (identical(constructor1, constructor2)) return;
-    check(constructor1, constructor2, 'kind', constructor1.kind,
-        constructor2.kind);
-    constructor1.accept(this, constructor2);
-  }
-
-  @override
-  visitGenerative(GenerativeConstantConstructor constructor1,
-      GenerativeConstantConstructor constructor2) {
-    ResolutionInterfaceType type1 = constructor1.type;
-    ResolutionInterfaceType type2 = constructor2.type;
-    checkTypes(constructor1, constructor2, 'type', type1, type2);
-    check(constructor1, constructor2, 'defaultValues.length',
-        constructor1.defaultValues.length, constructor2.defaultValues.length);
-    constructor1.defaultValues.forEach((k, v) {
-      checkConstants(constructor1, constructor2, 'defaultValue[$k]', v,
-          constructor2.defaultValues[k]);
-    });
-    check(constructor1, constructor2, 'fieldMap.length',
-        constructor1.fieldMap.length, constructor2.fieldMap.length);
-    constructor1.fieldMap.forEach((k1, v1) {
-      bool matched = false;
-      constructor2.fieldMap.forEach((k2, v2) {
-        if (k1.name == k2.name &&
-            k1.library.canonicalUri == k2.library.canonicalUri) {
-          checkElementIdentities(
-              constructor1, constructor2, 'fieldMap[${k1.name}].key', k1, k2);
-          checkConstants(
-              constructor1, constructor2, 'fieldMap[${k1.name}].value', v1, v2);
-          matched = true;
-        }
-      });
-      if (!matched) {
-        throw 'Unmatched field $k1 = $v1';
-      }
-    });
-    checkConstants(
-        constructor1,
-        constructor2,
-        'superConstructorInvocation',
-        constructor1.superConstructorInvocation,
-        constructor2.superConstructorInvocation);
-  }
-
-  @override
-  visitRedirectingFactory(RedirectingFactoryConstantConstructor constructor1,
-      RedirectingFactoryConstantConstructor constructor2) {
-    checkConstants(
-        constructor1,
-        constructor2,
-        'targetConstructorInvocation',
-        constructor1.targetConstructorInvocation,
-        constructor2.targetConstructorInvocation);
-  }
-
-  @override
-  visitRedirectingGenerative(
-      RedirectingGenerativeConstantConstructor constructor1,
-      RedirectingGenerativeConstantConstructor constructor2) {
-    check(constructor1, constructor2, 'defaultValues.length',
-        constructor1.defaultValues.length, constructor2.defaultValues.length);
-    constructor1.defaultValues.forEach((k, v) {
-      checkConstants(constructor1, constructor2, 'defaultValue[$k]', v,
-          constructor2.defaultValues[k]);
-    });
-    checkConstants(
-        constructor1,
-        constructor2,
-        'thisConstructorInvocation',
-        constructor1.thisConstructorInvocation,
-        constructor2.thisConstructorInvocation);
-  }
-
-  @override
-  visitErroneous(ErroneousConstantConstructor constructor1,
-      ErroneousConstantConstructor constructor2) {
-    throw new UnsupportedError("ConstantConstructorEquivalence.visitErroneous");
-  }
-}
-
-/// Check the equivalence of the two lists of elements, [list1] and [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-checkElementLists(Object object1, Object object2, String property,
-    Iterable<Element> list1, Iterable<Element> list2) {
-  checkListEquivalence(
-      object1, object2, property, list1, list2, checkElementProperties);
-}
-
-/// Check the equivalence of the two metadata annotations, [metadata1] and
-/// [metadata2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-checkMetadata(Object object1, Object object2, String property,
-    MetadataAnnotation metadata1, MetadataAnnotation metadata2) {
-  check(object1, object2, property, metadata1, metadata2,
-      areMetadataAnnotationsEquivalent);
-}
-
-/// Visitor that checks for equivalence of [Element] properties.
-class ElementPropertyEquivalence extends BaseElementVisitor<dynamic, Element> {
-  const ElementPropertyEquivalence();
-
-  void visit(Element element1, Element element2) {
-    if (element1 == null && element2 == null) return;
-    if (element1 == null || element2 == null) {
-      throw currentCheck;
-    }
-    element1 = element1.declaration;
-    element2 = element2.declaration;
-    if (element1 == element2) return;
-    check(element1, element2, 'kind', element1.kind, element2.kind);
-    element1.accept(this, element2);
-    check(element1, element2, 'isSynthesized', element1.isSynthesized,
-        element2.isSynthesized);
-    check(element1, element2, 'isLocal', element1.isLocal, element2.isLocal);
-    check(element1, element2, 'isFinal', element1.isFinal, element2.isFinal);
-    check(element1, element2, 'isConst', element1.isConst, element2.isConst);
-    check(element1, element2, 'isAbstract', element1.isAbstract,
-        element2.isAbstract);
-    check(element1, element2, 'isStatic', element1.isStatic, element2.isStatic);
-    check(element1, element2, 'isTopLevel', element1.isTopLevel,
-        element2.isTopLevel);
-    check(element1, element2, 'isClassMember', element1.isClassMember,
-        element2.isClassMember);
-    check(element1, element2, 'isInstanceMember', element1.isInstanceMember,
-        element2.isInstanceMember);
-    List<MetadataAnnotation> metadata1 = <MetadataAnnotation>[];
-    metadata1.addAll(element1.metadata);
-    if (element1.isPatched) {
-      metadata1.addAll(element1.implementation.metadata);
-    }
-    List<MetadataAnnotation> metadata2 = <MetadataAnnotation>[];
-    metadata2.addAll(element2.metadata);
-    if (element2.isPatched) {
-      metadata2.addAll(element2.implementation.metadata);
-    }
-    checkListEquivalence(
-        element1, element2, 'metadata', metadata1, metadata2, checkMetadata);
-  }
-
-  @override
-  void visitElement(Element e, Element arg) {
-    throw new UnsupportedError("Unsupported element $e");
-  }
-
-  @override
-  void visitLibraryElement(LibraryElement element1, LibraryElement element2) {
-    checkElementIdentities(null, null, null, element1, element2);
-    check(element1, element2, 'name', element1.name, element2.name);
-    check(element1, element2, 'libraryName', element1.libraryName,
-        element2.libraryName);
-    visitMembers(element1, element2);
-    visit(element1.entryCompilationUnit, element2.entryCompilationUnit);
-
-    checkElementLists(
-        element1,
-        element2,
-        'compilationUnits',
-        LibrarySerializer.getCompilationUnits(element1),
-        LibrarySerializer.getCompilationUnits(element2));
-
-    checkElementLists(
-        element1,
-        element2,
-        'imports',
-        LibrarySerializer.getImports(element1),
-        LibrarySerializer.getImports(element2));
-    checkElementLists(
-        element1, element2, 'exports', element1.exports, element2.exports);
-
-    List<Element> imported1 = LibrarySerializer.getImportedElements(element1);
-    List<Element> imported2 = LibrarySerializer.getImportedElements(element2);
-    checkElementListIdentities(
-        element1, element2, 'importScope', imported1, imported2);
-
-    checkElementListIdentities(
-        element1,
-        element2,
-        'exportScope',
-        LibrarySerializer.getExportedElements(element1),
-        LibrarySerializer.getExportedElements(element2));
-
-    for (int index = 0; index < imported1.length; index++) {
-      checkImportsFor(element1, element2, imported1[index], imported2[index]);
-    }
-  }
-
-  void checkImportsFor(
-      Element element1, Element element2, Element import1, Element import2) {
-    List<ImportElement> imports1 = element1.library.getImportsFor(import1);
-    List<ImportElement> imports2 = element2.library.getImportsFor(import2);
-    checkElementListIdentities(element1, element2,
-        'importsFor($import1/$import2)', imports1, imports2);
-  }
-
-  @override
-  void visitCompilationUnitElement(
-      CompilationUnitElement element1, CompilationUnitElement element2) {
-    checkElementIdentities(
-        element1, element2, 'library', element1.library, element2.library);
-    check(element1, element2, 'script.resourceUri', element1.script.resourceUri,
-        element2.script.resourceUri);
-    List<Element> members1 = <Element>[];
-    List<Element> members2 = <Element>[];
-    element1.forEachLocalMember((Element member) {
-      members1.add(member);
-    });
-    element2.forEachLocalMember((Element member) {
-      members2.add(member);
-    });
-    checkElementListIdentities(
-        element1, element2, 'localMembers', members1, members2);
-  }
-
-  void visitMembers(
-      ScopeContainerElement element1, ScopeContainerElement element2) {
-    Set<String> names = new Set<String>();
-    Iterable<Element> members1 = element1.isLibrary
-        ? LibrarySerializer.getMembers(element1)
-        : ClassSerializer.getMembers(element1);
-    Iterable<Element> members2 = element2.isLibrary
-        ? LibrarySerializer.getMembers(element2)
-        : ClassSerializer.getMembers(element2);
-    for (Element member in members1) {
-      names.add(member.name);
-    }
-    for (Element member in members2) {
-      names.add(member.name);
-    }
-    element1 = element1.implementation;
-    element2 = element2.implementation;
-    for (String name in names) {
-      Element member1 = element1.localLookup(name);
-      Element member2 = element2.localLookup(name);
-      if (member1 == null) {
-        String message =
-            'Missing member for $member2 in\n ${members1.join('\n ')}';
-        if (member2.isAbstractField) {
-          // TODO(johnniwinther): Ensure abstract fields are handled correctly.
-          //print(message);
-          continue;
-        } else {
-          throw message;
-        }
-      }
-      if (member2 == null) {
-        String message =
-            'Missing member for $member1 in\n ${members2.join('\n ')}';
-        if (member1.isAbstractField) {
-          // TODO(johnniwinther): Ensure abstract fields are handled correctly.
-          //print(message);
-          continue;
-        } else {
-          throw message;
-        }
-      }
-      currentCheck = new Check(
-          currentCheck, element1, element2, 'member:$name', member1, member2);
-      visit(member1, member2);
-      currentCheck = currentCheck.parent;
-    }
-  }
-
-  @override
-  void visitClassElement(ClassElement element1, ClassElement element2) {
-    checkElementIdentities(null, null, null, element1, element2);
-    check(element1, element2, 'name', element1.name, element2.name);
-    if (!element1.isUnnamedMixinApplication) {
-      check(element1, element2, 'sourcePosition', element1.sourcePosition,
-          element2.sourcePosition);
-    } else {
-      check(element1, element2, 'sourcePosition.uri',
-          element1.sourcePosition.uri, element2.sourcePosition.uri);
-      MixinApplicationElement mixin1 = element1;
-      MixinApplicationElement mixin2 = element2;
-      checkElementIdentities(
-          mixin1, mixin2, 'subclass', mixin1.subclass, mixin2.subclass);
-      checkTypes(
-          mixin1, mixin2, 'mixinType', mixin1.mixinType, mixin2.mixinType);
-    }
-    checkElementIdentities(
-        element1, element2, 'library', element1.library, element2.library);
-    checkElementIdentities(element1, element2, 'compilationUnit',
-        element1.compilationUnit, element2.compilationUnit);
-    checkTypeLists(element1, element2, 'typeVariables', element1.typeVariables,
-        element2.typeVariables);
-    checkTypes(
-        element1, element2, 'thisType', element1.thisType, element2.thisType);
-    checkTypes(
-        element1, element2, 'rawType', element1.rawType, element2.rawType);
-    check(element1, element2, 'isObject', element1.isObject, element2.isObject);
-    checkTypeLists(element1, element2, 'typeVariables', element1.typeVariables,
-        element2.typeVariables);
-    check(element1, element2, 'isAbstract', element1.isAbstract,
-        element2.isAbstract);
-    check(element1, element2, 'isUnnamedMixinApplication',
-        element1.isUnnamedMixinApplication, element2.isUnnamedMixinApplication);
-    check(element1, element2, 'isProxy', element1.isProxy, element2.isProxy);
-    check(element1, element2, 'isInjected', element1.isInjected,
-        element2.isInjected);
-    check(element1, element2, 'isEnumClass', element1.isEnumClass,
-        element2.isEnumClass);
-    if (element1.isEnumClass) {
-      EnumClassElement enum1 = element1;
-      EnumClassElement enum2 = element2;
-      checkElementLists(
-          enum1, enum2, 'enumValues', enum1.enumValues, enum2.enumValues);
-    }
-    if (!element1.isObject) {
-      checkTypes(element1, element2, 'supertype', element1.supertype,
-          element2.supertype);
-    }
-    check(element1, element2, 'hierarchyDepth', element1.hierarchyDepth,
-        element2.hierarchyDepth);
-    checkTypeLists(element1, element2, 'allSupertypes',
-        element1.allSupertypes.toList(), element2.allSupertypes.toList());
-    OrderedTypeSet typeSet1 = element1.allSupertypesAndSelf;
-    OrderedTypeSet typeSet2 = element2.allSupertypesAndSelf;
-    checkListEquivalence(element1, element2, 'allSupertypes',
-        typeSet1.levelOffsets, typeSet2.levelOffsets, check);
-    check(element1, element2, 'allSupertypesAndSelf.levels', typeSet1.levels,
-        typeSet2.levels);
-    checkTypeLists(element1, element2, 'supertypes',
-        typeSet1.supertypes.toList(), typeSet2.supertypes.toList());
-    checkTypeLists(element1, element2, 'types', typeSet1.types.toList(),
-        typeSet2.types.toList());
-
-    checkTypeLists(element1, element2, 'interfaces',
-        element1.interfaces.toList(), element2.interfaces.toList());
-
-    List<ConstructorElement> getConstructors(ClassElement cls) {
-      return cls.implementation.constructors.map((c) => c.declaration).toList();
-    }
-
-    checkElementLists(element1, element2, 'constructors',
-        getConstructors(element1), getConstructors(element2));
-
-    checkElementIdentities(
-        element1,
-        element2,
-        'defaultConstructor',
-        element1.lookupDefaultConstructor(),
-        element2.lookupDefaultConstructor());
-
-    visitMembers(element1, element2);
-
-    ClassElement superclass1 = element1.superclass;
-    ClassElement superclass2 = element2.superclass;
-    while (superclass1 != null && superclass1.isMixinApplication) {
-      checkElementProperties(
-          element1, element2, 'supermixin', superclass1, superclass2);
-      superclass1 = superclass1.superclass;
-      superclass2 = superclass2.superclass;
-    }
-  }
-
-  @override
-  void visitFieldElement(FieldElement element1, FieldElement element2) {
-    checkElementIdentities(null, null, null, element1, element2);
-    check(element1, element2, 'name', element1.name, element2.name);
-    check(element1, element2, 'sourcePosition', element1.sourcePosition,
-        element2.sourcePosition);
-    checkTypes(element1, element2, 'type', element1.type, element2.type);
-    checkConstants(
-        element1, element2, 'constant', element1.constant, element2.constant);
-    check(element1, element2, 'isTopLevel', element1.isTopLevel,
-        element2.isTopLevel);
-    check(element1, element2, 'isStatic', element1.isStatic, element2.isStatic);
-    check(element1, element2, 'isInstanceMember', element1.isInstanceMember,
-        element2.isInstanceMember);
-    check(element1, element2, 'isInjected', element1.isInjected,
-        element2.isInjected);
-
-    checkElementIdentities(
-        element1, element2, 'library', element1.library, element2.library);
-    checkElementIdentities(element1, element2, 'compilationUnit',
-        element1.compilationUnit, element2.compilationUnit);
-    checkElementIdentities(element1, element2, 'enclosingClass',
-        element1.enclosingClass, element2.enclosingClass);
-  }
-
-  @override
-  void visitFunctionElement(
-      FunctionElement element1, FunctionElement element2) {
-    checkElementIdentities(null, null, null, element1, element2);
-    check(element1, element2, 'name', element1.name, element2.name);
-    check(element1, element2, 'sourcePosition', element1.sourcePosition,
-        element2.sourcePosition);
-    checkTypes(element1, element2, 'type', element1.type, element2.type);
-    checkListEquivalence(element1, element2, 'parameters', element1.parameters,
-        element2.parameters, checkElementProperties);
-    check(element1, element2, 'isOperator', element1.isOperator,
-        element2.isOperator);
-    check(element1, element2, 'asyncMarker', element1.asyncMarker,
-        element2.asyncMarker);
-    check(element1, element2, 'isInjected', element1.isInjected,
-        element2.isInjected);
-
-    checkElementIdentities(
-        element1, element2, 'library', element1.library, element2.library);
-    checkElementIdentities(element1, element2, 'compilationUnit',
-        element1.compilationUnit, element2.compilationUnit);
-    checkElementIdentities(element1, element2, 'enclosingClass',
-        element1.enclosingClass, element2.enclosingClass);
-
-    check(
-        element1,
-        element2,
-        'functionSignature.type',
-        element1.functionSignature.type,
-        element2.functionSignature.type,
-        areTypesEquivalent);
-    checkElementLists(
-        element1,
-        element2,
-        'functionSignature.requiredParameters',
-        element1.functionSignature.requiredParameters,
-        element2.functionSignature.requiredParameters);
-    checkElementLists(
-        element1,
-        element2,
-        'functionSignature.optionalParameters',
-        element1.functionSignature.optionalParameters,
-        element2.functionSignature.optionalParameters);
-    check(
-        element1,
-        element2,
-        'functionSignature.requiredParameterCount',
-        element1.functionSignature.requiredParameterCount,
-        element2.functionSignature.requiredParameterCount);
-    check(
-        element1,
-        element2,
-        'functionSignature.optionalParameterCount',
-        element1.functionSignature.optionalParameterCount,
-        element2.functionSignature.optionalParameterCount);
-    check(
-        element1,
-        element2,
-        'functionSignature.optionalParametersAreNamed',
-        element1.functionSignature.optionalParametersAreNamed,
-        element2.functionSignature.optionalParametersAreNamed);
-    check(
-        element1,
-        element2,
-        'functionSignature.hasOptionalParameters',
-        element1.functionSignature.hasOptionalParameters,
-        element2.functionSignature.hasOptionalParameters);
-    check(
-        element1,
-        element2,
-        'functionSignature.parameterCount',
-        element1.functionSignature.parameterCount,
-        element2.functionSignature.parameterCount);
-    checkElementLists(
-        element1,
-        element2,
-        'functionSignature.orderedOptionalParameters',
-        element1.functionSignature.orderedOptionalParameters,
-        element2.functionSignature.orderedOptionalParameters);
-    checkTypeLists(element1, element2, 'typeVariables', element1.typeVariables,
-        element2.typeVariables);
-  }
-
-  @override
-  void visitConstructorElement(
-      ConstructorElement element1, ConstructorElement element2) {
-    checkElementIdentities(null, null, null, element1, element2);
-    checkElementIdentities(element1, element2, 'enclosingClass',
-        element1.enclosingClass, element2.enclosingClass);
-    check(element1, element2, 'name', element1.name, element2.name);
-    if (!element1.isSynthesized) {
-      check(element1, element2, 'sourcePosition', element1.sourcePosition,
-          element2.sourcePosition);
-    } else {
-      check(element1, element2, 'sourcePosition.uri',
-          element1.sourcePosition.uri, element2.sourcePosition.uri);
-    }
-    checkListEquivalence(element1, element2, 'parameters', element1.parameters,
-        element2.parameters, checkElementProperties);
-    checkTypes(element1, element2, 'type', element1.type, element2.type);
-    check(element1, element2, 'isExternal', element1.isExternal,
-        element2.isExternal);
-    if (element1.isConst && !element1.isExternal) {
-      constantConstructorEquivalence(
-          element1.constantConstructor, element2.constantConstructor);
-    }
-    check(element1, element2, 'isRedirectingGenerative',
-        element1.isRedirectingGenerative, element2.isRedirectingGenerative);
-    check(element1, element2, 'isRedirectingFactory',
-        element1.isRedirectingFactory, element2.isRedirectingFactory);
-    checkElementIdentities(element1, element2, 'effectiveTarget',
-        element1.effectiveTarget, element2.effectiveTarget);
-    if (element1.isRedirectingFactory) {
-      checkElementIdentities(
-          element1,
-          element2,
-          'immediateRedirectionTarget',
-          element1.immediateRedirectionTarget,
-          element2.immediateRedirectionTarget);
-      checkElementIdentities(
-          element1,
-          element2,
-          'redirectionDeferredPrefix',
-          element1.redirectionDeferredPrefix,
-          element2.redirectionDeferredPrefix);
-      check(
-          element1,
-          element2,
-          'isEffectiveTargetMalformed',
-          element1.isEffectiveTargetMalformed,
-          element2.isEffectiveTargetMalformed);
-    }
-    checkElementIdentities(element1, element2, 'definingConstructor',
-        element1.definingConstructor, element2.definingConstructor);
-    check(
-        element1,
-        element2,
-        'effectiveTargetType',
-        element1.computeEffectiveTargetType(element1.enclosingClass.thisType),
-        element2.computeEffectiveTargetType(element2.enclosingClass.thisType),
-        areTypesEquivalent);
-    check(
-        element1,
-        element2,
-        'effectiveTargetType.raw',
-        element1.computeEffectiveTargetType(element1.enclosingClass.rawType),
-        element2.computeEffectiveTargetType(element2.enclosingClass.rawType),
-        areTypesEquivalent);
-    checkElementIdentities(
-        element1,
-        element2,
-        'immediateRedirectionTarget',
-        element1.immediateRedirectionTarget,
-        element2.immediateRedirectionTarget);
-    checkElementIdentities(element1, element2, 'redirectionDeferredPrefix',
-        element1.redirectionDeferredPrefix, element2.redirectionDeferredPrefix);
-    check(element1, element2, 'isInjected', element1.isInjected,
-        element2.isInjected);
-  }
-
-  @override
-  void visitAbstractFieldElement(
-      AbstractFieldElement element1, AbstractFieldElement element2) {
-    visit(element1.getter, element2.getter);
-    visit(element1.setter, element2.setter);
-  }
-
-  @override
-  void visitTypeVariableElement(
-      TypeVariableElement element1, TypeVariableElement element2) {
-    checkElementIdentities(null, null, null, element1, element2);
-    check(element1, element2, 'name', element1.name, element2.name);
-    check(element1, element2, 'sourcePosition', element1.sourcePosition,
-        element2.sourcePosition);
-    check(element1, element2, 'index', element1.index, element2.index);
-    checkTypes(element1, element2, 'type', element1.type, element2.type);
-    checkTypes(element1, element2, 'bound', element1.bound, element2.bound);
-  }
-
-  @override
-  void visitTypedefElement(TypedefElement element1, TypedefElement element2) {
-    checkElementIdentities(null, null, null, element1, element2);
-    check(element1, element2, 'name', element1.name, element2.name);
-    check(element1, element2, 'sourcePosition', element1.sourcePosition,
-        element2.sourcePosition);
-    checkTypes(element1, element2, 'alias', element1.alias, element2.alias);
-    checkTypeLists(element1, element2, 'typeVariables', element1.typeVariables,
-        element2.typeVariables);
-    checkElementIdentities(
-        element1, element2, 'library', element1.library, element2.library);
-    checkElementIdentities(element1, element2, 'compilationUnit',
-        element1.compilationUnit, element2.compilationUnit);
-    // TODO(johnniwinther): Check the equivalence of typedef parameters.
-  }
-
-  @override
-  void visitParameterElement(
-      ParameterElement element1, ParameterElement element2) {
-    checkElementIdentities(null, null, null, element1, element2);
-    checkElementIdentities(element1, element2, 'functionDeclaration',
-        element1.functionDeclaration, element2.functionDeclaration);
-    check(element1, element2, 'name', element1.name, element2.name);
-    check(element1, element2, 'sourcePosition', element1.sourcePosition,
-        element2.sourcePosition);
-    checkTypes(element1, element2, 'type', element1.type, element2.type);
-    check(element1, element2, 'isOptional', element1.isOptional,
-        element2.isOptional);
-    check(element1, element2, 'isNamed', element1.isNamed, element2.isNamed);
-    check(element1, element2, 'name', element1.name, element2.name);
-    if (element1.isOptional) {
-      checkConstants(
-          element1, element2, 'constant', element1.constant, element2.constant);
-    }
-    checkElementIdentities(element1, element2, 'compilationUnit',
-        element1.compilationUnit, element2.compilationUnit);
-  }
-
-  @override
-  void visitFieldParameterElement(
-      InitializingFormalElement element1, InitializingFormalElement element2) {
-    visitParameterElement(element1, element2);
-    checkElementIdentities(element1, element2, 'fieldElement',
-        element1.fieldElement, element2.fieldElement);
-  }
-
-  @override
-  void visitImportElement(ImportElement element1, ImportElement element2) {
-    check(element1, element2, 'uri', element1.uri, element2.uri);
-    check(element1, element2, 'isDeferred', element1.isDeferred,
-        element2.isDeferred);
-    checkElementProperties(
-        element1, element2, 'prefix', element1.prefix, element2.prefix);
-    checkElementIdentities(element1, element2, 'importedLibrary',
-        element1.importedLibrary, element2.importedLibrary);
-  }
-
-  @override
-  void visitExportElement(ExportElement element1, ExportElement element2) {
-    check(element1, element2, 'uri', element1.uri, element2.uri);
-    checkElementIdentities(element1, element2, 'importedLibrary',
-        element1.exportedLibrary, element2.exportedLibrary);
-  }
-
-  @override
-  void visitPrefixElement(PrefixElement element1, PrefixElement element2) {
-    check(element1, element2, 'isDeferred', element1.isDeferred,
-        element2.isDeferred);
-    checkElementIdentities(element1, element2, 'deferredImport',
-        element1.deferredImport, element2.deferredImport);
-    if (element1.isDeferred) {
-      checkElementProperties(element1, element2, 'loadLibrary',
-          element1.loadLibrary, element2.loadLibrary);
-    }
-    element1.forEachLocalMember((Element member1) {
-      String name = member1.name;
-      Element member2 = element2.lookupLocalMember(name);
-      checkElementIdentities(
-          element1, element2, 'lookupLocalMember:$name', member1, member2);
-      checkImportsFor(element1, element2, member1, member2);
-    });
-  }
-
-  @override
-  void visitErroneousElement(
-      ErroneousElement element1, ErroneousElement element2) {
-    check(element1, element2, 'messageKind', element1.messageKind,
-        element2.messageKind);
-  }
-}
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
deleted file mode 100644
index 4770141..0000000
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_helper;
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:compiler/compiler_new.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/filenames.dart';
-
-import '../memory_compiler.dart';
-import 'test_data.dart';
-
-const String DEFAULT_DATA_FILE_NAME = 'out.data';
-
-class Arguments {
-  final String filename;
-  final int start;
-  final int end;
-  final bool loadSerializedData;
-  final bool saveSerializedData;
-  final String serializedDataFileName;
-  final bool verbose;
-
-  const Arguments(
-      {this.filename,
-      this.start,
-      this.end,
-      this.loadSerializedData: false,
-      this.saveSerializedData: false,
-      this.serializedDataFileName: DEFAULT_DATA_FILE_NAME,
-      this.verbose: false});
-
-  factory Arguments.from(List<String> arguments) {
-    String filename;
-    int start;
-    int end;
-    for (String arg in arguments) {
-      if (!arg.startsWith('-')) {
-        int index = int.parse(arg, onError: (_) => null);
-        if (index == null) {
-          filename = arg;
-        } else if (start == null) {
-          start = index;
-        } else {
-          end = index;
-        }
-      }
-    }
-    bool verbose = arguments.contains('-v');
-    bool loadSerializedData = arguments.contains('-l');
-    bool saveSerializedData = arguments.contains('-s');
-    if (arguments.contains('--auto')) {
-      File file = new File(DEFAULT_DATA_FILE_NAME);
-      if (file.existsSync()) {
-        loadSerializedData = true;
-      } else {
-        saveSerializedData = true;
-      }
-    }
-    return new Arguments(
-        filename: filename,
-        start: start,
-        end: end,
-        verbose: verbose,
-        loadSerializedData: loadSerializedData,
-        saveSerializedData: saveSerializedData);
-  }
-
-  Uri get uri {
-    if (filename != null) {
-      return Uri.base.resolve(nativeToUriPath(filename));
-    }
-    return null;
-  }
-
-  Future forEachTest(SerializedData serializedData, List<Test> tests,
-      TestFunction testFunction) async {
-    Uri entryPoint = Uri.parse('memory:main.dart');
-    int first = start ?? 0;
-    int last = end ?? tests.length;
-
-    for (int index = first; index < last; index++) {
-      Test test = TESTS[index];
-      List<SerializedData> dataList =
-          await preserializeData(serializedData, test);
-      Map<String, String> sourceFiles = <String, String>{};
-      sourceFiles.addAll(test.sourceFiles);
-      if (test.preserializedSourceFiles != null) {
-        sourceFiles.addAll(test.preserializedSourceFiles);
-      }
-      if (test.unserializedSourceFiles != null) {
-        sourceFiles.addAll(test.unserializedSourceFiles);
-      }
-      List<Uri> resolutionInputs = <Uri>[];
-      for (SerializedData data in dataList) {
-        data.expandMemorySourceFiles(sourceFiles);
-        data.expandUris(resolutionInputs);
-      }
-      await testFunction(entryPoint,
-          sourceFiles: sourceFiles,
-          resolutionInputs: resolutionInputs,
-          index: index,
-          test: test,
-          verbose: verbose);
-    }
-  }
-}
-
-typedef Future TestFunction(Uri entryPoint,
-    {Map<String, String> sourceFiles,
-    List<Uri> resolutionInputs,
-    int index,
-    Test test,
-    bool verbose});
-
-Future<SerializedData> serializeDartCore(
-    {Arguments arguments: const Arguments()}) {
-  return measure('dart:core', 'serialize', () async {
-    Uri uri = Uri.parse('memory:${arguments.serializedDataFileName}');
-    SerializedData serializedData;
-    if (arguments.loadSerializedData) {
-      File file = new File(arguments.serializedDataFileName);
-      if (file.existsSync()) {
-        print('Loading data from $file');
-        serializedData = new SerializedData(uri, file.readAsStringSync());
-      }
-    } else {
-      SerializationResult result =
-          await serialize(Uris.dart_core, dataUri: uri);
-      serializedData = result.serializedData;
-    }
-    if (arguments.saveSerializedData) {
-      File file = new File(arguments.serializedDataFileName);
-      print('Saving data to $file');
-      file.writeAsStringSync(serializedData.data);
-    }
-    return serializedData;
-  });
-}
-
-class SerializationResult {
-  final Compiler compiler;
-  final SerializedData serializedData;
-
-  SerializationResult(this.compiler, this.serializedData);
-}
-
-Future<SerializationResult> serialize(Uri entryPoint,
-    {Map<String, String> memorySourceFiles: const <String, String>{},
-    List<Uri> resolutionInputs: const <Uri>[],
-    Uri dataUri,
-    bool deserializeCompilationDataForTesting: false}) async {
-  if (dataUri == null) {
-    dataUri = Uri.parse('memory:${DEFAULT_DATA_FILE_NAME}');
-  }
-  OutputCollector outputCollector = new OutputCollector();
-  Compiler compiler = compilerFor(
-      options: [Flags.resolveOnly, Flags.useOldFrontend],
-      memorySourceFiles: memorySourceFiles,
-      resolutionInputs: resolutionInputs,
-      outputProvider: outputCollector);
-  compiler.serialization.deserializeCompilationDataForTesting =
-      deserializeCompilationDataForTesting;
-  await compiler.run(entryPoint);
-  SerializedData serializedData = new SerializedData(
-      dataUri, outputCollector.getOutput('', OutputType.serializationData));
-  return new SerializationResult(compiler, serializedData);
-}
-
-class SerializedData {
-  final Uri uri;
-  final String data;
-
-  SerializedData(this.uri, this.data) {
-    assert(uri != null);
-    assert(data != null);
-  }
-
-  Map<String, String> toMemorySourceFiles([Map<String, String> input]) {
-    Map<String, String> sourceFiles = <String, String>{};
-    if (input != null) {
-      sourceFiles.addAll(input);
-    }
-    expandMemorySourceFiles(sourceFiles);
-    return sourceFiles;
-  }
-
-  void expandMemorySourceFiles(Map<String, String> sourceFiles) {
-    if (uri.scheme == 'memory') {
-      sourceFiles[uri.path] = data;
-    }
-  }
-
-  List<Uri> toUris([List<Uri> input]) {
-    List<Uri> uris = <Uri>[];
-    if (input != null) {
-      uris.addAll(input);
-    }
-    expandUris(uris);
-    return uris;
-  }
-
-  void expandUris(List<Uri> uris) {
-    uris.add(uri);
-  }
-}
-
-Future<List<SerializedData>> preserializeData(
-    SerializedData serializedData, Test test) async {
-  if (test == null ||
-      test.preserializedSourceFiles == null ||
-      test.preserializedSourceFiles.isEmpty) {
-    return <SerializedData>[serializedData];
-  }
-
-  List<Uri> uriList = <Uri>[];
-  for (String key in test.preserializedSourceFiles.keys) {
-    uriList.add(Uri.parse('memory:$key'));
-  }
-  Map<String, String> sourceFiles = serializedData.toMemorySourceFiles();
-  sourceFiles.addAll(test.preserializedSourceFiles);
-  if (test.unserializedSourceFiles != null) {
-    sourceFiles.addAll(test.unserializedSourceFiles);
-  }
-  Uri additionalDataUri = Uri.parse('memory:additional.data');
-  SerializedData additionalSerializedData;
-  if (test.sourceFiles.isEmpty) {
-    SerializationResult result = await serialize(uriList.first,
-        memorySourceFiles: sourceFiles,
-        resolutionInputs: serializedData.toUris(),
-        dataUri: additionalDataUri);
-    additionalSerializedData = result.serializedData;
-  } else {
-    OutputCollector outputCollector = new OutputCollector();
-    Compiler compiler = compilerFor(
-        entryPoint: test.sourceFiles.isEmpty ? uriList.first : null,
-        memorySourceFiles: sourceFiles,
-        resolutionInputs: serializedData.toUris(),
-        options: [Flags.resolveOnly, Flags.useOldFrontend],
-        outputProvider: outputCollector);
-    compiler.librariesToAnalyzeWhenRun = uriList;
-    await compiler.run(null);
-    List<LibraryElement> libraries = <LibraryElement>[];
-    for (Uri uri in uriList) {
-      libraries.add(compiler.libraryLoader.lookupLibrary(uri));
-    }
-    additionalSerializedData = new SerializedData(additionalDataUri,
-        outputCollector.getOutput('', OutputType.serializationData));
-  }
-  return <SerializedData>[serializedData, additionalSerializedData];
-}
-
-class MeasurementResult {
-  final String title;
-  final String taskTitle;
-  final int elapsedMilliseconds;
-
-  MeasurementResult(this.title, this.taskTitle, this.elapsedMilliseconds);
-}
-
-final List<MeasurementResult> measurementResults = <MeasurementResult>[];
-
-/// Print all store [measurementResults] grouped by title and sorted by
-/// decreasing execution time.
-void printMeasurementResults() {
-  Map<String, int> totals = <String, int>{};
-
-  for (MeasurementResult result in measurementResults) {
-    totals.putIfAbsent(result.title, () => 0);
-    totals[result.title] += result.elapsedMilliseconds;
-  }
-
-  List<String> sorted = totals.keys.toList();
-  sorted.sort((a, b) => -totals[a].compareTo(totals[b]));
-
-  int paddingLength = '${totals[sorted.first]}'.length;
-
-  String pad(int value) {
-    String text = '$value';
-    return '${' ' * (paddingLength - text.length)}$text';
-  }
-
-  print('================================================================');
-  print('Summary:');
-  for (String task in sorted) {
-    int time = totals[task];
-    print('${pad(time)}ms $task');
-  }
-
-  measurementResults.clear();
-}
-
-/// Measure execution of [task], print the result and store it in
-/// [measurementResults] for a summary.
-Future measure(String title, String taskTitle, Future task()) async {
-  Stopwatch stopwatch = new Stopwatch()..start();
-  print('================================================================');
-  print('$taskTitle: $title');
-  print('----------------------------------------------------------------');
-  var result = await task();
-  stopwatch.stop();
-  int elapsedMilliseconds = stopwatch.elapsedMilliseconds;
-  print('$taskTitle: $title: ${elapsedMilliseconds}ms');
-  measurementResults
-      .add(new MeasurementResult(title, taskTitle, elapsedMilliseconds));
-  return result;
-}
diff --git a/tests/compiler/dart2js/serialization/impact_test.dart b/tests/compiler/dart2js/serialization/impact_test.dart
deleted file mode 100644
index 1e5ce1e..0000000
--- a/tests/compiler/dart2js/serialization/impact_test.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.serialization_impact_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/filenames.dart';
-import '../memory_compiler.dart';
-import '../equivalence/check_functions.dart';
-import 'helper.dart';
-
-main(List<String> args) {
-  Arguments arguments = new Arguments.from(args);
-  asyncTest(() async {
-    SerializedData serializedData =
-        await serializeDartCore(arguments: arguments);
-    if (arguments.filename != null) {
-      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
-      await check(serializedData, entryPoint);
-    } else {
-      Uri entryPoint = Uri.parse('memory:main.dart');
-      await check(serializedData, entryPoint,
-          sourceFiles: {'main.dart': 'main() {}'}, verbose: arguments.verbose);
-    }
-  });
-}
-
-Future check(SerializedData serializedData, Uri entryPoint,
-    {Map<String, String> sourceFiles: const <String, String>{},
-    bool verbose: false}) async {
-  Compiler compilerNormal =
-      compilerFor(memorySourceFiles: sourceFiles, options: [Flags.analyzeAll]);
-  compilerNormal.impactCacheDeleter.retainCachesForTesting = true;
-  await compilerNormal.run(entryPoint);
-
-  Compiler compilerDeserialized = compilerFor(
-      memorySourceFiles: serializedData.toMemorySourceFiles(sourceFiles),
-      resolutionInputs: serializedData.toUris(),
-      options: [Flags.analyzeAll]);
-  compilerDeserialized.impactCacheDeleter.retainCachesForTesting = true;
-  await compilerDeserialized.run(entryPoint);
-
-  checkAllImpacts(compilerNormal, compilerDeserialized, verbose: verbose);
-}
diff --git a/tests/compiler/dart2js/serialization/library_test.dart b/tests/compiler/dart2js/serialization/library_test.dart
deleted file mode 100644
index 9788562..0000000
--- a/tests/compiler/dart2js/serialization/library_test.dart
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_library_test;
-
-import 'dart:async';
-import 'dart:io';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/invariant.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/serialization/json_serializer.dart';
-import 'package:compiler/src/serialization/serialization.dart';
-import 'package:expect/expect.dart';
-import '../equivalence/check_functions.dart';
-import '../memory_compiler.dart';
-import 'equivalence_test.dart';
-import 'helper.dart';
-
-main(List<String> arguments) {
-  // Ensure that we can print out constant expressions.
-  DEBUG_MODE = true;
-
-  Uri entryPoint;
-  String outPath;
-  int shardCount = 3;
-  bool prettyPrint = false;
-  for (String arg in arguments) {
-    if (arg.startsWith('--')) {
-      if (arg.startsWith('--out=')) {
-        outPath = arg.substring('--out='.length);
-      } else if (arg == '--pretty-print') {
-        prettyPrint = true;
-      } else if (arg.startsWith('--shards=')) {
-        shardCount = int.parse(arg.substring('--shards='.length));
-      } else {
-        print("Unknown option $arg");
-      }
-    } else {
-      if (entryPoint != null) {
-        print("Multiple entrypoints are not supported.");
-      }
-      entryPoint = Uri.parse(arg);
-    }
-  }
-  if (entryPoint == null) {
-    entryPoint = Uris.dart_core;
-  }
-  asyncTest(() async {
-    Compiler compiler =
-        await compilerFor(entryPoint: entryPoint, options: [Flags.analyzeAll]);
-    compiler.serialization.supportSerialization = true;
-    await compiler.run(entryPoint);
-    List<SerializedData> data = createData(compiler,
-        outPath: outPath, prettyPrint: prettyPrint, shardCount: shardCount);
-    await testAnalysis(compiler, data, entryPoint);
-  });
-}
-
-List<SerializedData> createData(Compiler compiler,
-    {String outPath, bool prettyPrint, int shardCount: 3}) {
-  Iterable<LibraryElement> libraries1 = compiler.libraryLoader.libraries;
-  if (shardCount < 1 || shardCount > libraries1.length) {
-    shardCount = libraries1.length;
-  }
-  List<List<LibraryElement>> librarySplits = <List<LibraryElement>>[];
-  int offset = 0;
-  int shardSize = (libraries1.length / shardCount).ceil();
-  for (int shard = 0; shard < shardCount; shard++) {
-    List<LibraryElement> libraries = <LibraryElement>[];
-    for (int index = 0; index < shardSize; index++) {
-      if (offset + index < libraries1.length) {
-        libraries.add(libraries1.elementAt(offset + index));
-      }
-    }
-    librarySplits.add(libraries);
-    offset += shardSize;
-  }
-  print(librarySplits.join('\n'));
-  List<SerializedData> data = <SerializedData>[];
-  for (int shard = 0; shard < shardCount; shard++) {
-    List<LibraryElement> libraries = librarySplits[shard];
-    Serializer serializer = compiler.serialization.createSerializer(libraries);
-    String text = serializer.toText(const JsonSerializationEncoder());
-    String outText = text;
-    if (prettyPrint) {
-      outText = serializer.prettyPrint();
-    }
-    if (outPath != null) {
-      String name = outPath;
-      String ext = '';
-      int dotPos = outPath.lastIndexOf('.');
-      if (dotPos != -1) {
-        name = outPath.substring(0, dotPos);
-        ext = outPath.substring(dotPos);
-      }
-      new File('$name$shard$ext').writeAsStringSync(outText);
-    } else if (prettyPrint) {
-      print(outText);
-    }
-    data.add(new SerializedData(Uri.parse('memory:out$shard.data'), text));
-  }
-  return data;
-}
-
-Future testAnalysis(
-    Compiler compiler1, List<SerializedData> data, Uri entryPoint) async {
-  Map<String, String> memorySourceFiles = <String, String>{};
-  List<Uri> resolutionInputs = <Uri>[];
-  for (int index = 0; index < data.length; index++) {
-    SerializedData serializedData = data[index];
-    serializedData.expandMemorySourceFiles(memorySourceFiles);
-    serializedData.expandUris(resolutionInputs);
-  }
-  CompilationResult result = await runCompiler(
-      entryPoint: entryPoint,
-      memorySourceFiles: memorySourceFiles,
-      resolutionInputs: resolutionInputs,
-      options: [Flags.analyzeAll]);
-  Compiler compiler2 = result.compiler;
-  for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
-    LibraryElement library2 =
-        compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
-    if (library2 == null) {
-      throw new ArgumentError('No library ${library1.canonicalUri} found.');
-    }
-    checkLibraryContent('library1', 'library2', 'library', library1, library2);
-    checkAllResolvedAsts(compiler1, compiler2);
-    checkAllImpacts(compiler1, compiler2);
-  }
-  Expect.isFalse(compiler2.reporter.hasReportedError, "Unexpected errors");
-}
diff --git a/tests/compiler/dart2js/serialization/members_test.dart b/tests/compiler/dart2js/serialization/members_test.dart
deleted file mode 100644
index 0ef66a6..0000000
--- a/tests/compiler/dart2js/serialization/members_test.dart
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.class_members_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/names.dart';
-import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/resolution/class_members.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
-import '../equivalence/check_helpers.dart';
-import '../equivalence/check_functions.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-
-main(List<String> args) {
-  Arguments arguments = new Arguments.from(args);
-  asyncTest(() async {
-    SerializedData serializedData =
-        await serializeDartCore(arguments: arguments);
-    if (arguments.filename != null) {
-      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
-      await checkClassMembers(serializedData, entryPoint,
-          verbose: arguments.verbose);
-    } else {
-      await checkClassMembers(serializedData, Uris.dart_core,
-          verbose: arguments.verbose);
-    }
-  });
-}
-
-Future checkClassMembers(SerializedData serializedData, Uri entryPoint,
-    {bool verbose: false}) async {
-  Compiler compilerNormal = compilerFor(options: [Flags.analyzeAll]);
-  await compilerNormal.run(entryPoint);
-
-  Compiler compilerDeserialized = compilerFor(
-      memorySourceFiles: serializedData.toMemorySourceFiles(),
-      resolutionInputs: serializedData.toUris(),
-      options: [Flags.analyzeAll]);
-  await compilerDeserialized.run(entryPoint);
-
-  checkAllMembers(compilerNormal, compilerDeserialized, verbose: true);
-}
-
-void checkAllMembers(Compiler compiler1, Compiler compiler2,
-    {bool verbose: false}) {
-  checkLoadedLibraryMembers(compiler1, compiler2,
-      (Element member1) => member1 is ClassElement, checkMembers,
-      verbose: verbose);
-}
-
-/// Check equivalence of members of [class1] and [class2].
-void checkMembers(
-    Compiler compiler1, Element _class1, Compiler compiler2, Element _class2,
-    {bool verbose: false}) {
-  ClassMemberMixin class1 = _class1;
-  ClassMemberMixin class2 = _class2;
-  if (verbose) {
-    print('Checking $class1 vs $class2');
-  }
-  MembersCreator.computeAllClassMembers(compiler1.resolution, class1);
-  MembersCreator.computeAllClassMembers(compiler2.resolution, class2);
-
-  check(
-      class1,
-      class2,
-      'interfaceMemberAreClassMembers',
-      class1.interfaceMembersAreClassMembers,
-      class2.interfaceMembersAreClassMembers);
-  class1.forEachClassMember((Member member1) {
-    Name name1 = member1.name;
-    Name name2 = convertName(name1, compiler2);
-    checkMember(class1, class2, 'classMember:$name1', member1,
-        class2.lookupClassMember(name2));
-  });
-
-  class1.forEachInterfaceMember((MemberSignature member1) {
-    Name name1 = member1.name;
-    Name name2 = convertName(name1, compiler2);
-    checkMemberSignature(class1, class2, 'interfaceMember:$name1', member1,
-        class2.lookupInterfaceMember(name2));
-  });
-}
-
-Name convertName(Name name, Compiler compiler) {
-  if (name.isPrivate) {
-    LibraryElement library1 = name.library;
-    LibraryElement library2 =
-        compiler.libraryLoader.lookupLibrary(library1.canonicalUri);
-    if (!areElementsEquivalent(library1, library2)) {
-      throw 'Libraries ${library1} and ${library2} are not equivalent';
-    }
-    name = new Name(name.text, library2, isSetter: name.isSetter);
-  }
-  return name;
-}
-
-void checkMember(ClassElement class1, ClassElement class2, String property,
-    Member member1, Member member2) {
-  if (member2 == null) {
-    print('$class1 class members:');
-    class1.forEachClassMember((m) => print(' ${m.name} $m'));
-    print('$class2 class members:');
-    class2.forEachClassMember((m) => print(' ${m.name} $m'));
-    throw "No member ${member1.name} in $class2 for $property";
-  }
-  checkMemberSignature(class1, class2, property, member1, member2);
-  checkElementIdentities(
-      class1, class2, '$property.element', member1.element, member2.element);
-  check(class1, class2, '$property.declarer', member1.declarer,
-      member2.declarer, areTypesEquivalent);
-  check(
-      class1, class2, '$property.isStatic', member1.isStatic, member2.isStatic);
-  check(class1, class2, '$property.isDeclaredByField',
-      member1.isDeclaredByField, member2.isDeclaredByField);
-  check(class1, class2, '$property.isAbstract', member1.isAbstract,
-      member2.isAbstract);
-  if (member1.isAbstract && member1.implementation != null) {
-    checkMember(class1, class2, '$property.implementation',
-        member1.implementation, member2.implementation);
-  }
-}
-
-void checkMemberSignature(ClassElement class1, ClassElement class2,
-    String property, MemberSignature member1, MemberSignature member2) {
-  if (member2 == null) {
-    print('$class1 interface members:');
-    class1.forEachInterfaceMember((m) => print(' ${m.name} $m'));
-    print('$class2 interface members:');
-    class2.forEachInterfaceMember((m) => print(' ${m.name} $m'));
-    throw "No member ${member1.name} in $class2 for $property";
-  }
-  check(class1, class2, '$property.name', member1.name, member2.name,
-      areNamesEquivalent);
-  check(class1, class2, '$property.type', member1.type, member2.type,
-      areTypesEquivalent);
-  check(class1, class2, '$property.functionType', member1.functionType,
-      member2.functionType, areTypesEquivalent);
-  check(
-      class1, class2, '$property.isGetter', member1.isGetter, member2.isGetter);
-  check(
-      class1, class2, '$property.isSetter', member1.isSetter, member2.isSetter);
-  check(
-      class1, class2, '$property.isMethod', member1.isMethod, member2.isMethod);
-}
diff --git a/tests/compiler/dart2js/serialization/model0_test.dart b/tests/compiler/dart2js/serialization/model0_test.dart
deleted file mode 100644
index 3731bd1..0000000
--- a/tests/compiler/dart2js/serialization/model0_test.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.serialization.model0_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSkipped(0, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model1_test.dart b/tests/compiler/dart2js/serialization/model1_test.dart
deleted file mode 100644
index aec8489..0000000
--- a/tests/compiler/dart2js/serialization/model1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model1_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model2_test.dart b/tests/compiler/dart2js/serialization/model2_test.dart
deleted file mode 100644
index 8f02334..0000000
--- a/tests/compiler/dart2js/serialization/model2_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model2_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model3_test.dart b/tests/compiler/dart2js/serialization/model3_test.dart
deleted file mode 100644
index d3a2ff1..0000000
--- a/tests/compiler/dart2js/serialization/model3_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model3_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model4_test.dart b/tests/compiler/dart2js/serialization/model4_test.dart
deleted file mode 100644
index 5871fc2..0000000
--- a/tests/compiler/dart2js/serialization/model4_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model4_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model5_test.dart b/tests/compiler/dart2js/serialization/model5_test.dart
deleted file mode 100644
index 9cf0596..0000000
--- a/tests/compiler/dart2js/serialization/model5_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model5_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model_1_test.dart b/tests/compiler/dart2js/serialization/model_1_test.dart
deleted file mode 100644
index e74bd17..0000000
--- a/tests/compiler/dart2js/serialization/model_1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model_1_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
-  test.main(testSkipped(1, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model_test_helper.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart
deleted file mode 100644
index 976b565..0000000
--- a/tests/compiler/dart2js/serialization/model_test_helper.dart
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_model_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/closure.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common_elements.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/deferred_load.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/js_backend/js_backend.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
-import 'package:compiler/src/tree/nodes.dart';
-import 'package:compiler/src/world.dart';
-import '../memory_compiler.dart';
-import '../equivalence/check_helpers.dart';
-import '../equivalence/check_functions.dart';
-import 'helper.dart';
-import 'test_data.dart';
-
-/// Number of tests that are not part of the automatic test grouping.
-int SKIP_COUNT = 2;
-
-/// Number of groups that the [TESTS] are split into.
-int SPLIT_COUNT = 5;
-
-main(List<String> args) {
-  asyncTest(() async {
-    Arguments arguments = new Arguments.from(args);
-    SerializedData serializedData =
-        await serializeDartCore(arguments: arguments);
-    if (arguments.uri != null) {
-      Uri entryPoint = arguments.uri;
-      SerializationResult result =
-          await measure('${entryPoint}', 'serialize', () {
-        return serialize(entryPoint,
-            memorySourceFiles: serializedData.toMemorySourceFiles(),
-            resolutionInputs: serializedData.toUris(),
-            dataUri: Uri.parse('memory:test.data'));
-      });
-      await checkModels(entryPoint,
-          sourceFiles: serializedData
-              .toMemorySourceFiles(result.serializedData.toMemorySourceFiles()),
-          resolutionInputs:
-              serializedData.toUris(result.serializedData.toUris()));
-    } else {
-      await arguments.forEachTest(serializedData, TESTS, checkModels);
-    }
-    printMeasurementResults();
-  });
-}
-
-Future checkModels(Uri entryPoint,
-    {Map<String, String> sourceFiles: const <String, String>{},
-    List<Uri> resolutionInputs,
-    int index,
-    Test test,
-    bool verbose: false}) async {
-  String testDescription = test != null ? test.name : '${entryPoint}';
-  String id = index != null ? '$index: ' : '';
-  String title = '${id}${testDescription}';
-  Compiler compilerNormal = await measure(title, 'compile normal', () async {
-    Compiler compilerNormal = compilerFor(
-        memorySourceFiles: sourceFiles,
-        options: [Flags.analyzeOnly, Flags.useOldFrontend]);
-    compilerNormal.impactCacheDeleter.retainCachesForTesting = true;
-    await compilerNormal.run(entryPoint);
-    ElementEnvironment elementEnvironment =
-        compilerNormal.frontendStrategy.elementEnvironment;
-    compilerNormal.closeResolution(elementEnvironment.mainFunction);
-    return compilerNormal;
-  });
-
-  Compiler compilerDeserialized =
-      await measure(title, 'compile deserialized', () async {
-    Compiler compilerDeserialized = compilerFor(
-        memorySourceFiles: sourceFiles,
-        resolutionInputs: resolutionInputs,
-        options: [Flags.analyzeOnly, Flags.useOldFrontend]);
-    compilerDeserialized.impactCacheDeleter.retainCachesForTesting = true;
-    await compilerDeserialized.run(entryPoint);
-    ElementEnvironment elementEnvironment =
-        compilerDeserialized.frontendStrategy.elementEnvironment;
-    compilerDeserialized.closeResolution(elementEnvironment.mainFunction);
-    return compilerDeserialized;
-  });
-
-  return measure(title, 'check models', () async {
-    checkAllImpacts(compilerNormal, compilerDeserialized, verbose: verbose);
-    ClosedWorld closedWorld1 =
-        compilerNormal.resolutionWorldBuilder.closedWorldForTesting;
-    ClosedWorld closedWorld2 =
-        compilerNormal.resolutionWorldBuilder.closedWorldForTesting;
-    checkResolutionEnqueuers(
-        closedWorld1.backendUsage,
-        closedWorld2.backendUsage,
-        compilerNormal.enqueuer.resolution,
-        compilerDeserialized.enqueuer.resolution,
-        verbose: verbose);
-    checkClosedWorlds(closedWorld1, closedWorld2,
-        // Serialized native data include non-live members.
-        allowExtra: true,
-        verbose: verbose);
-    checkBackendInfo(compilerNormal, compilerDeserialized, verbose: verbose);
-  });
-}
-
-void checkBackendInfo(Compiler compilerNormal, Compiler compilerDeserialized,
-    {bool verbose: false}) {
-  checkSets(
-      compilerNormal.enqueuer.resolution.processedEntities,
-      compilerDeserialized.enqueuer.resolution.processedEntities,
-      "Processed element mismatch",
-      areEntitiesEquivalent, onSameElement: (a, b) {
-    checkElements(compilerNormal, compilerDeserialized, a, b, verbose: verbose);
-  }, verbose: verbose);
-  Expect.equals(
-      compilerNormal.deferredLoadTask.isProgramSplit,
-      compilerDeserialized.deferredLoadTask.isProgramSplit,
-      "isProgramSplit mismatch");
-
-  Iterable<ConstantValue> constants1 =
-      compilerNormal.backend.outputUnitData.constantsForTesting;
-  Iterable<ConstantValue> constants2 =
-      compilerDeserialized.backend.outputUnitData.constantsForTesting;
-  checkSets(
-      constants1,
-      constants2,
-      'deferredLoadTask._outputUnitForConstants.keys',
-      areConstantValuesEquivalent,
-      failOnUnfound: false,
-      failOnExtra: false,
-      onSameElement: (ConstantValue value1, ConstantValue value2) {
-    checkOutputUnits(
-        compilerNormal,
-        compilerDeserialized,
-        compilerNormal.backend.outputUnitData.outputUnitForConstant(value1),
-        compilerDeserialized.backend.outputUnitData
-            .outputUnitForConstant(value2),
-        'for ${value1.toStructuredText()} '
-        'vs ${value2.toStructuredText()}');
-  }, onUnfoundElement: (ConstantValue value1) {
-    OutputUnit outputUnit1 =
-        compilerNormal.backend.outputUnitData.outputUnitForConstant(value1);
-    Expect.isTrue(outputUnit1.isMainOutput,
-        "Missing deferred constant: ${value1.toStructuredText()}");
-  }, onExtraElement: (ConstantValue value2) {
-    OutputUnit outputUnit2 = compilerDeserialized.backend.outputUnitData
-        .outputUnitForConstant(value2);
-    Expect.isTrue(outputUnit2.isMainOutput,
-        "Extra deferred constant: ${value2.toStructuredText()}");
-  }, elementToString: (a) {
-    OutputUnit o1 =
-        compilerNormal.backend.outputUnitData.outputUnitForConstant(a);
-    OutputUnit o2 =
-        compilerDeserialized.backend.outputUnitData.outputUnitForConstant(a);
-    return '${a.toStructuredText()} -> ${o1}/${o2}';
-  });
-}
-
-void checkElements(
-    Compiler compiler1, Compiler compiler2, Element element1, Element element2,
-    {bool verbose: false}) {
-  if (element1.isAbstract) return;
-  if (element1.isFunction ||
-      element1.isConstructor ||
-      (element1.isField && element1.isInstanceMember)) {
-    ClosureTask closureTask1 = compiler1.backendStrategy.closureDataLookup;
-    ClosureRepresentationInfo closureData1 =
-        closureTask1.getClosureInfoForMember(element1 as MemberElement);
-    ClosureTask closureTask2 = compiler2.backendStrategy.closureDataLookup;
-    ClosureRepresentationInfo closureData2 =
-        closureTask2.getClosureInfoForMember(element2 as MemberElement);
-
-    checkElementIdentities(
-        closureData1,
-        closureData2,
-        '$element1.closureEntity',
-        closureData1.closureEntity,
-        closureData2.closureEntity);
-    checkElementIdentities(
-        closureData1,
-        closureData2,
-        '$element1.closureClassEntity',
-        closureData1.closureClassEntity,
-        closureData2.closureClassEntity);
-    checkElementIdentities(closureData1, closureData2, '$element1.callMethod',
-        closureData1.callMethod, closureData2.callMethod);
-    check(closureData1, closureData2, '$element1.thisLocal',
-        closureData1.thisLocal, closureData2.thisLocal, areLocalsEquivalent);
-
-    checkElementListIdentities(
-        closureData1,
-        closureData2,
-        "$element1.createdFieldEntities",
-        closureData1.createdFieldEntities,
-        closureData2.createdFieldEntities);
-    check(
-        closureData1,
-        closureData2,
-        '$element1.thisFieldEntity',
-        closureData1.thisFieldEntity,
-        closureData2.thisFieldEntity,
-        areCapturedVariablesEquivalent);
-    if (element1 is MemberElement && element2 is MemberElement) {
-      MemberElement member1 = element1.implementation;
-      MemberElement member2 = element2.implementation;
-      checkSets(member1.nestedClosures, member2.nestedClosures,
-          "$member1.nestedClosures", areElementsEquivalent, verbose: verbose,
-          onSameElement: (a, b) {
-        LocalFunctionElement localFunction1 = a.expression;
-        LocalFunctionElement localFunction2 = b.expression;
-        checkElementIdentities(localFunction1, localFunction2, 'enclosingClass',
-            localFunction1.enclosingClass, localFunction2.enclosingClass);
-        testResolvedAstEquivalence(localFunction1.resolvedAst,
-            localFunction2.resolvedAst, const CheckStrategy());
-      });
-    }
-  }
-  JavaScriptBackend backend1 = compiler1.backend;
-  JavaScriptBackend backend2 = compiler2.backend;
-  if (element1 is MethodElement && element2 is MethodElement) {
-    Expect.equals(
-        backend1.inlineCache.getCurrentCacheDecisionForTesting(element1),
-        backend2.inlineCache.getCurrentCacheDecisionForTesting(element2),
-        "Inline cache decision mismatch for $element1 vs $element2");
-  }
-
-  checkElementOutputUnits(compiler1, compiler2, element1, element2);
-}
-
-bool areLocalsEquivalent(Local a, Local b) => areLocalVariablesEquivalent(a, b);
-
-bool areLocalVariablesEquivalent(LocalVariable a, LocalVariable b) {
-  if (a == b) return true;
-  if (a == null || b == null) return false;
-
-  if (a is Element) {
-    return b is Element && areElementsEquivalent(a as Element, b as Element);
-  } else {
-    return a.runtimeType == b.runtimeType &&
-        areElementsEquivalent(a.executableContext, b.executableContext);
-  }
-}
-
-bool areCapturedVariablesEquivalent(FieldEntity a, FieldEntity b) {
-  if (a == b) return true;
-  if (a == null || b == null) return false;
-  if (a is ClosureFieldElement && b is ClosureFieldElement) {
-    return areElementsEquivalent(a.closureClass, b.closureClass) &&
-        areLocalVariablesEquivalent(a.local, b.local);
-  } else if (a is BoxFieldElement && b is BoxFieldElement) {
-    return areElementsEquivalent(a.variableElement, b.variableElement) &&
-        areLocalVariablesEquivalent(a.box, b.box);
-  }
-  return false;
-}
-
-bool areCapturedScopesEquivalent(CapturedScope a, CapturedScope b) {
-  if (a == b) return true;
-  if (a == null || b == null) return false;
-  if (!areLocalVariablesEquivalent(a.context, b.context)) {
-    return false;
-  }
-  if (!areLocalVariablesEquivalent(a.thisLocal, b.thisLocal)) {
-    return false;
-  }
-  var aBoxed = <LocalVariable, Entity>{};
-  a.forEachBoxedVariable((k, v) => aBoxed[k] = v);
-  var bBoxed = <LocalVariable, Entity>{};
-  b.forEachBoxedVariable((k, v) => bBoxed[k] = v);
-  checkMaps(aBoxed, bBoxed, 'CapturedScope.boxedVariables',
-      areLocalVariablesEquivalent, areEntitiesEquivalent);
-  return true;
-}
-
-String nodeToString(Node node) {
-  String text = '$node';
-  if (text.length > 40) {
-    return '(${node.runtimeType}) ${text.substring(0, 37)}...';
-  }
-  return '(${node.runtimeType}) $text';
-}
-
-void checkElementOutputUnits(Compiler compiler1, Compiler compiler2,
-    Element element1, Element element2) {
-  OutputUnit outputUnit1 =
-      compiler1.backend.outputUnitData.outputUnitForEntityForTesting(element1);
-  OutputUnit outputUnit2 =
-      compiler2.backend.outputUnitData.outputUnitForEntityForTesting(element2);
-  checkOutputUnits(compiler1, compiler2, outputUnit1, outputUnit2,
-      'for $element1 vs $element2');
-}
-
-void checkOutputUnits(Compiler compiler1, Compiler compiler2,
-    OutputUnit outputUnit1, OutputUnit outputUnit2, String message) {
-  if (outputUnit1 == null && outputUnit2 == null) return;
-  check(outputUnit1, outputUnit2, 'OutputUnit.isMainOutput $message',
-      outputUnit1.isMainOutput, outputUnit2.isMainOutput);
-  checkSetEquivalence(
-      outputUnit1,
-      outputUnit2,
-      'OutputUnit.imports $message',
-      compiler1.deferredLoadTask.getImportNames(outputUnit1),
-      compiler2.deferredLoadTask.getImportNames(outputUnit2),
-      (a, b) => areElementsEquivalent(a.declaration, b.declaration));
-}
diff --git a/tests/compiler/dart2js/serialization/native_data_test.dart b/tests/compiler/dart2js/serialization/native_data_test.dart
deleted file mode 100644
index 4d0fbb0..0000000
--- a/tests/compiler/dart2js/serialization/native_data_test.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.native_data_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/js_backend/native_data.dart';
-import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
-import 'package:compiler/src/world.dart';
-import '../equivalence/check_helpers.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-
-main(List<String> args) {
-  asyncTest(() async {
-    Arguments arguments = new Arguments.from(args);
-    Uri uri = Uris.dart_html;
-    if (arguments.filename != null) {
-      uri = Uri.base.resolve(nativeToUriPath(arguments.filename));
-    }
-    await checkNativeData(uri, verbose: arguments.verbose);
-  });
-}
-
-Future checkNativeData(Uri uri, {bool verbose: false}) async {
-  print('------------------------------------------------------------------');
-  print('analyze normal: $uri');
-  print('------------------------------------------------------------------');
-  SerializationResult result = await serialize(uri);
-  Compiler compiler1 = result.compiler;
-  SerializedData serializedData = result.serializedData;
-  var elementEnvironment1 = compiler1.frontendStrategy.elementEnvironment;
-  ClosedWorld closedWorld1 =
-      compiler1.closeResolution(elementEnvironment1.mainFunction).closedWorld;
-
-  print('------------------------------------------------------------------');
-  print('analyze deserialized: $uri');
-  print('------------------------------------------------------------------');
-  Compiler compiler2 = compilerFor(
-      memorySourceFiles: serializedData.toMemorySourceFiles(),
-      resolutionInputs: serializedData.toUris(),
-      options: [Flags.analyzeAll]);
-  await compiler2.run(uri);
-  var elementEnvironment2 = compiler2.frontendStrategy.elementEnvironment;
-  ClosedWorld closedWorld2 =
-      compiler2.closeResolution(elementEnvironment2.mainFunction).closedWorld;
-
-  NativeBasicDataImpl nativeBasicData1 =
-      compiler1.frontendStrategy.nativeBasicData;
-  NativeBasicDataImpl nativeBasicData2 =
-      compiler2.frontendStrategy.nativeBasicData;
-  NativeDataImpl nativeData1 = closedWorld1.nativeData;
-  NativeDataImpl nativeData2 = closedWorld2.nativeData;
-
-  checkMaps(nativeData1.jsInteropLibraries, nativeData2.jsInteropLibraries,
-      "NativeData.jsInteropLibraryNames", areEntitiesEquivalent, equality,
-      verbose: verbose);
-
-  checkMaps(nativeData1.jsInteropClasses, nativeData2.jsInteropClasses,
-      "NativeData.jsInteropClassNames", areEntitiesEquivalent, equality,
-      verbose: verbose);
-
-  checkMaps(nativeData1.jsInteropMembers, nativeData2.jsInteropMembers,
-      "NativeData.jsInteropMemberNames", areEntitiesEquivalent, equality,
-      verbose: verbose);
-
-  checkMaps(nativeData1.nativeMemberName, nativeData2.nativeMemberName,
-      "NativeData.nativeMemberName", areEntitiesEquivalent, equality,
-      verbose: verbose);
-
-  checkMaps(
-      nativeBasicData1.nativeClassTagInfo,
-      nativeBasicData2.nativeClassTagInfo,
-      "NativeData.nativeClassTagInfo",
-      areEntitiesEquivalent,
-      equality,
-      verbose: verbose);
-
-  checkMaps(
-      nativeData1.nativeMethodBehavior,
-      nativeData2.nativeMethodBehavior,
-      "NativeData.nativeMethodBehavior",
-      areEntitiesEquivalent,
-      testNativeBehavior,
-      verbose: verbose);
-
-  checkMaps(
-      nativeData1.nativeFieldLoadBehavior,
-      nativeData2.nativeFieldLoadBehavior,
-      "NativeData.nativeFieldLoadBehavior",
-      areEntitiesEquivalent,
-      testNativeBehavior,
-      verbose: verbose);
-
-  checkMaps(
-      nativeData1.nativeFieldStoreBehavior,
-      nativeData2.nativeFieldStoreBehavior,
-      "NativeData.nativeFieldStoreBehavior",
-      areEntitiesEquivalent,
-      testNativeBehavior,
-      verbose: verbose);
-}
diff --git a/tests/compiler/dart2js/serialization/reserialization_test.dart b/tests/compiler/dart2js/serialization/reserialization_test.dart
deleted file mode 100644
index 8814e54..0000000
--- a/tests/compiler/dart2js/serialization/reserialization_test.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.reserialization_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/invariant.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:expect/expect.dart';
-import '../equivalence/check_functions.dart';
-import 'helper.dart';
-import 'equivalence_test.dart';
-
-main(List<String> args) {
-  // Ensure that we can print out constant expressions.
-  DEBUG_MODE = true;
-
-  Arguments arguments = new Arguments.from(args);
-  Uri entryPoint;
-  if (arguments.filename != null) {
-    entryPoint = Uri.parse(arguments.filename);
-  } else {
-    entryPoint = Uri.parse('dart:core');
-  }
-  asyncTest(() async {
-    await testReserialization(entryPoint);
-  });
-}
-
-Future testReserialization(Uri entryPoint) async {
-  SerializationResult result1 = await serialize(entryPoint);
-  Compiler compiler1 = result1.compiler;
-  SerializedData serializedData1 = result1.serializedData;
-  Iterable<LibraryElement> libraries1 = compiler1.libraryLoader.libraries;
-
-  SerializationResult result2 = await serialize(entryPoint,
-      memorySourceFiles: serializedData1.toMemorySourceFiles(),
-      resolutionInputs: serializedData1.toUris(),
-      deserializeCompilationDataForTesting: true);
-  Compiler compiler2 = result2.compiler;
-  SerializedData serializedData2 = result2.serializedData;
-  Iterable<LibraryElement> libraries2 = compiler2.libraryLoader.libraries;
-
-  SerializationResult result3 = await serialize(entryPoint,
-      memorySourceFiles: serializedData2.toMemorySourceFiles(),
-      resolutionInputs: serializedData2.toUris(),
-      deserializeCompilationDataForTesting: true);
-  Compiler compiler3 = result3.compiler;
-  Iterable<LibraryElement> libraries3 = compiler3.libraryLoader.libraries;
-
-  for (LibraryElement library1 in libraries1) {
-    LibraryElement library2 = libraries2.firstWhere((LibraryElement library2) {
-      return library2.canonicalUri == library1.canonicalUri;
-    });
-    Expect.isNotNull(
-        library2, "No library found for ${library1.canonicalUri}.");
-    checkLibraryContent('library1', 'library2', 'library', library1, library2);
-
-    LibraryElement library3 = libraries3.firstWhere((LibraryElement library3) {
-      return library3.canonicalUri == library1.canonicalUri;
-    });
-    Expect.isNotNull(
-        library3, "No library found for ${library1.canonicalUri}.");
-    checkLibraryContent('library1', 'library3', 'library', library1, library3);
-  }
-
-  checkAllResolvedAsts(compiler1, compiler2);
-  checkAllResolvedAsts(compiler1, compiler3);
-
-  checkAllImpacts(compiler1, compiler2);
-  checkAllImpacts(compiler1, compiler3);
-}
diff --git a/tests/compiler/dart2js/serialization/resolved_ast_test.dart b/tests/compiler/dart2js/serialization/resolved_ast_test.dart
deleted file mode 100644
index 7561f73..0000000
--- a/tests/compiler/dart2js/serialization/resolved_ast_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.serialization_resolved_ast_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/filenames.dart';
-import '../equivalence/check_functions.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-import 'test_data.dart';
-
-main(List<String> args) {
-  Arguments arguments = new Arguments.from(args);
-  asyncTest(() async {
-    SerializedData serializedData =
-        await serializeDartCore(arguments: arguments);
-    if (arguments.filename != null) {
-      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
-      await check(serializedData, entryPoint);
-    } else {
-      Uri entryPoint = Uri.parse('memory:main.dart');
-      // TODO(johnniwinther): Change to test all serialized resolved ast instead
-      // only those used in the test.
-      Test test = TESTS.first;
-      await check(serializedData, entryPoint, test.sourceFiles);
-    }
-  });
-}
-
-Future check(SerializedData serializedData, Uri entryPoint,
-    [Map<String, String> sourceFiles = const <String, String>{}]) async {
-  Compiler compilerNormal = compilerFor(
-      memorySourceFiles: sourceFiles,
-      options: [Flags.analyzeAll, Flags.useOldFrontend]);
-  compilerNormal.impactCacheDeleter.retainCachesForTesting = true;
-  await compilerNormal.run(entryPoint);
-
-  Compiler compilerDeserialized = compilerFor(
-      memorySourceFiles: serializedData.toMemorySourceFiles(sourceFiles),
-      resolutionInputs: serializedData.toUris(),
-      options: [Flags.analyzeAll, Flags.useOldFrontend]);
-  compilerDeserialized.impactCacheDeleter.retainCachesForTesting = true;
-  await compilerDeserialized.run(entryPoint);
-
-  checkAllResolvedAsts(compilerNormal, compilerDeserialized, verbose: true);
-}
diff --git a/tests/compiler/dart2js/serialization/test_data.dart b/tests/compiler/dart2js/serialization/test_data.dart
deleted file mode 100644
index 667ff90..0000000
--- a/tests/compiler/dart2js/serialization/test_data.dart
+++ /dev/null
@@ -1,829 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_test_data;
-
-const List<Test> TESTS = const <Test>[
-  // These tests are very long-running and put here first to compile them on
-  // their own tests.
-  const Test(
-      'Disable tree shaking through reflection',
-      const {
-        'main.dart': '''
-import 'dart:mirrors';
-
-main() {
-  reflect(null).invoke(#toString, []).reflectee;
-}
-''',
-      },
-      expectedWarningCount: 1),
-
-  const Test('Use of dart:indexed_db', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-import 'dart:indexed_db';
-''',
-  }),
-
-  // These tests
-  const Test('Empty program', const {'main.dart': 'main() {}'}),
-
-  const Test(
-      'Hello World', const {'main.dart': 'main() => print("Hello World");'}),
-
-  const Test('Too many arguments to print',
-      const {'main.dart': 'main() => print("Hello World", 0);'},
-      expectedWarningCount: 1, expectedInfoCount: 1),
-
-  const Test('Hello World with string interpolation', const {
-    'main.dart': r'''
-main() {
-  String text = "Hello World";
-  print('$text');
-}'''
-  }),
-
-  const Test(
-      'Too many arguments to print with string interpolation',
-      const {
-        'main.dart': r'''
-main() {
-  String text = "Hello World";
-  print('$text', text);
-}'''
-      },
-      expectedWarningCount: 1,
-      expectedInfoCount: 1),
-
-  const Test('Print main arguments', const {
-    'main.dart': r'''
-main(List<String> arguments) {
-  print(arguments);
-}'''
-  }),
-
-  const Test('For loop on main arguments', const {
-    'main.dart': r'''
-main(List<String> arguments) {
-  for (int i = 0; i < arguments.length; i++) {
-    print(arguments[i]);
-  }
-}'''
-  }),
-
-  const Test('For-in loop on main arguments', const {
-    'main.dart': r'''
-main(List<String> arguments) {
-  for (String argument in arguments) {
-    print(argument);
-  }
-}'''
-  }),
-
-  const Test('Simple class', const {
-    'main.dart': r'''
-class Class {}
-main() {
-  print(new Class());
-}'''
-  }),
-
-  const Test(
-      'Simple class implements Function without call method',
-      const {
-        'main.dart': r'''
-class Class implements Function {}
-main() {
-  print(new Class());
-}'''
-      },
-      expectedWarningCount: 1),
-
-  const Test('Simple class implements Function with call method', const {
-    'main.dart': r'''
-class Class implements Function {
-  call() {}
-}
-main() {
-  print(new Class()());
-}'''
-  }),
-
-  const Test('Implement Comparable', const {
-    'main.dart': r'''
-class Class implements Comparable<Class> {
-  int compareTo(Class other) => 0;
-}
-main() {
-  print(new Class());
-}'''
-  }),
-
-  const Test(
-      'Implement Comparable with two many type arguments',
-      const {
-        'main.dart': r'''
-class Class implements Comparable<Class, Class> {
-  int compareTo(other) => 0;
-}
-main() {
-  print(new Class());
-}'''
-      },
-      expectedWarningCount: 1),
-
-  const Test(
-      'Implement Comparable with incompatible parameter types',
-      const {
-        'main.dart': r'''
-class Class implements Comparable<Class> {
-  int compareTo(String other) => 0;
-}
-main() {
-  print(new Class().compareTo(null));
-}'''
-      },
-      expectedWarningCount: 1,
-      expectedInfoCount: 1),
-
-  const Test(
-      'Implement Comparable with incompatible parameter count',
-      const {
-        'main.dart': r'''
-class Class implements Comparable {
-  bool compareTo(a, b) => true;
-}
-main() {
-  print(new Class().compareTo(null, null));
-}'''
-      },
-      expectedWarningCount: 1,
-      expectedInfoCount: 1),
-
-  const Test(
-      'Implement Random and call nextInt directly',
-      const {
-        'main.dart': r'''
-import 'dart:math';
-
-class MyRandom implements Random {
-  int nextInt(int max) {
-    return max.length;
-  }
-  bool nextBool() => true;
-  double nextDouble() => 0.0;
-}
-main() {
-  new MyRandom().nextInt(0);
-}'''
-      },
-      expectedWarningCount: 1,
-      expectedInfoCount: 0),
-
-  const Test('Implement Random and do not call nextInt', const {
-    'main.dart': r'''
-import 'dart:math';
-
-class MyRandom implements Random {
-  int nextInt(int max) {
-    return max.length;
-  }
-  bool nextBool() => true;
-  double nextDouble() => 0.0;
-}
-main() {
-  new MyRandom();
-}'''
-  }),
-
-  const Test(
-      'Implement Random and call nextInt through native code',
-      const {
-        'main.dart': r'''
-import 'dart:math';
-
-class MyRandom implements Random {
-  int nextInt(int max) {
-    return max.length;
-  }
-  bool nextBool() => true;
-  double nextDouble() => 0.0;
-}
-main() {
-  // Invocation of `MyRandom.nextInt` is only detected knowing the actual
-  // implementation class for `List` and the world impact of its `shuffle`
-  // method.
-  [].shuffle(new MyRandom());
-}'''
-      },
-      expectedWarningCount: 1,
-      expectedInfoCount: 0),
-
-  const Test('Handle break and continue', const {
-    'main.dart': '''
-main() {
-  loop: for (var a in []) {
-    for (var b in []) {
-      continue loop;
-    }
-    break;
-  }
-}'''
-  }),
-
-  const Test('Explicit default constructor', const {
-    'main.dart': '''
-class A {
-  A();
-}
-main() => new A();
-    ''',
-  }),
-
-  const Test('Explicit default constructor, preserialized', const {
-    'main.dart': '''
-import 'lib.dart';
-main() => new A();
-    ''',
-  }, preserializedSourceFiles: const {
-    'lib.dart': '''
-class A {
-  A();
-}
-''',
-  }),
-
-  const Test('Const constructor', const {
-    'main.dart': '''
-class C {
-  const C();
-}
-main() => const C();'''
-  }),
-
-  const Test('Redirecting factory', const {
-    'main.dart': '''
-class C {
-  factory C() = Object;
-}
-main() => new C();'''
-  }),
-
-  const Test('Redirecting factory with optional arguments', const {
-    'main.dart': '''
-abstract class C implements List {
-  factory C([_]) = List;
-}
-main() => new C();'''
-  }),
-
-  const Test('Constructed constant using its default values.', const {
-    'main.dart': '''
-main() => const Duration();
-''',
-  }),
-
-  const Test('Call forwarding constructor on named mixin application', const {
-    'main.dart': '''
-import 'dart:collection';
-main() => new UnmodifiableListView(null);
-''',
-  }),
-
-  const Test('Function reference constant', const {
-    'main.dart': '''
-var myIdentical = identical;
-main() => myIdentical;
-''',
-  }),
-
-  const Test('Super method call', const {
-    'main.dart': '''
-class Foo {
-  String toString() => super.toString();
-}
-main() {
-  print(new Foo());
-}
-''',
-  }),
-
-  const Test(
-      'Call forwarding constructor on named mixin application, no args.',
-      const {
-        'main.dart': '''
-import 'lib.dart';
-main() => new C();
-''',
-      },
-      preserializedSourceFiles: const {
-        'lib.dart': '''
-class M {}
-class S {}
-class C = S with M;
-''',
-      }),
-
-  const Test(
-      'Call forwarding constructor on named mixin application, one arg.',
-      const {
-        'main.dart': '''
-import 'lib.dart';
-main() => new C(0);
-''',
-      },
-      preserializedSourceFiles: const {
-        'lib.dart': '''
-class M {}
-class S {
-  S(a);
-}
-class C = S with M;
-''',
-      }),
-
-  const Test(
-      'Import mirrors, thus checking import paths',
-      const {
-        'main.dart': '''
-import 'dart:mirrors';
-main() {}
-''',
-      },
-      expectedWarningCount: 1),
-
-  const Test('Serialized symbol literal', const {
-    'main.dart': '''
-import 'lib.dart';
-main() => m();
-''',
-  }, preserializedSourceFiles: const {
-    'lib.dart': '''
-m() => print(#main);
-''',
-  }),
-
-  const Test('Indirect unserialized library', const {
-    'main.dart': '''
-import 'a.dart';
-main() => foo();
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-import 'memory:b.dart';
-foo() => bar();
-''',
-  }, unserializedSourceFiles: const {
-    'b.dart': '''
-import 'memory:a.dart';
-bar() => foo();
-''',
-  }),
-
-  const Test('Multiple structurally identical mixins', const {
-    'main.dart': '''
-class S {}
-class M {}
-class C1 extends S with M {}
-class C2 extends S with M {}
-main() {
-  new C1();
-  new C2();
-}
-''',
-  }),
-
-  const Test('Deferred loading', const {
-    'main.dart': '''
-import 'a.dart' deferred as lib;
-main() {
-  lib.foo();
-}
-''',
-    'a.dart': '''
-void foo() {}
-''',
-  }),
-
-  const Test('fromEnvironment constants', const {
-    'main.dart': '''
-main() => const String.fromEnvironment("foo");
-''',
-  }),
-
-  const Test('Unused noSuchMethod', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {
-  new A().m();
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-class A {
-  noSuchMethod(_) => null;
-  m();
-}
-''',
-  }),
-
-  const Test('Malformed types', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {
-  m();
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-Unresolved m() {}
-''',
-  }),
-
-  const Test('Function types for closures', const {
-    'main.dart': '''
-import 'a.dart';
-
-typedef Func();
-
-main(args) {
-  (args.isEmpty ? new B() : new C()) is Func;
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-class B {
-  call(a) {}
-}
-class C {
-  call() {}
-}
-''',
-  }),
-
-  const Test('Double literal in constant constructor', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {
-  const A(1.0);
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-class A {
-  final field1;
-  const A(a) : this.field1 = a + 1.0;
-}
-''',
-  }),
-
-  const Test('Index set if null', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() => m(null, null, null);
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-m(a, b, c) => a[b] ??= c;
-''',
-  }),
-
-  const Test('If-null expression in constant constructor', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {
-  const A(1.0);
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-class A {
-  final field1;
-  const A(a) : this.field1 = a ?? 1.0;
-}
-''',
-  }),
-
-  const Test('Forwarding constructor defined by forwarding constructor', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() => new C();
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-class A {}
-class B {}
-class C {}
-class D = A with B, C;
-''',
-    'b.dart': '''
-''',
-  }),
-
-  const Test('Deferred prefix loadLibrary', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {
-  test();
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-import 'b.dart' deferred as pre;
-test() {
-  pre.loadLibrary();
-}
-''',
-    'b.dart': '''
-''',
-  }),
-
-  const Test(
-      'Deferred without prefix',
-      const {
-        'main.dart': '''
-import 'a.dart';
-
-main() {
-  test();
-}
-''',
-      },
-      preserializedSourceFiles: const {
-        'a.dart': '''
-import 'b.dart' deferred;
-test() {}
-''',
-        'b.dart': '''
-''',
-      },
-      expectedErrorCount: 1),
-
-  const Test(
-      'Deferred with duplicate prefix',
-      const {
-        'main.dart': '''
-import 'a.dart';
-
-main() {
-  test();
-}
-''',
-      },
-      preserializedSourceFiles: const {
-        'a.dart': '''
-import 'b.dart' deferred as pre;
-import 'c.dart' deferred as pre;
-test() {}
-''',
-        'b.dart': '''
-''',
-        'c.dart': '''
-''',
-      },
-      expectedErrorCount: 1),
-
-  const Test('Closure in operator function', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {
-  test();
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-class C {
-  operator ==(other) => () {};
-}
-
-test() => new C() == null;
-''',
-  }),
-
-  const Test(
-      'Checked setter',
-      const {
-        'main.dart': '''
-import 'a.dart';
-
-main() {
-  test();
-}
-''',
-      },
-      preserializedSourceFiles: const {
-        'a.dart': '''
-class C {
-  set foo(int i) {}
-}
-
-test() => new C().foo = 0;
-''',
-      },
-      checkedMode: true),
-
-  const Test('Deferred access', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {
-  test();
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-import 'b.dart' deferred as b;
-
-test() => b.loadLibrary().then((_) => b.test2());
-''',
-    'b.dart': '''
-test2() {}
-''',
-  }),
-
-  const Test('Deferred access of dart:core', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {
-  test();
-}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-import "dart:core" deferred as core;
-
-test() {
-  core.loadLibrary().then((_) => null);
-}
-''',
-  }),
-
-  const Test('Use of dart:indexed_db', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() {}
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-import 'dart:indexed_db';
-''',
-  }),
-
-  const Test('Deferred static access', const {},
-      preserializedSourceFiles: const {
-        'main.dart': '''
-import 'b.dart' deferred as prefix;
-
-main() => prefix.loadLibrary().then((_) => prefix.test2());
-''',
-        'b.dart': '''
-test2() => x;
-var x = const ConstClass(const ConstClass(1));
-class ConstClass {
-  final x;
-  const ConstClass(this.x);
-}
-''',
-      }),
-
-  const Test('Multi variable declaration', const {
-    'main.dart': '''
-import 'a.dart';
-
-main() => y;
-''',
-  }, preserializedSourceFiles: const {
-    'a.dart': '''
-var x, y = 2;
-''',
-  }),
-
-  const Test('Double values', const {}, preserializedSourceFiles: const {
-    'main.dart': '''
-const a = 1e+400;
-main() => a;
-''',
-  }),
-
-  const Test('Erroneous constructor', const {},
-      preserializedSourceFiles: const {
-        'main.dart': '''
-main() => new Null();
-'''
-      }),
-
-  const Test('Metadata on imports', const {}, preserializedSourceFiles: const {
-    'main.dart': '''
-@deprecated
-import 'main.dart';
-
-main() {}
-'''
-  }),
-
-  const Test('Metadata on exports', const {}, preserializedSourceFiles: const {
-    'main.dart': '''
-@deprecated
-export 'main.dart';
-
-main() {}
-'''
-  }),
-
-  const Test('Metadata on part tags', const {},
-      preserializedSourceFiles: const {
-        'main.dart': '''
-library main;
-
-@deprecated
-part 'a.dart';
-
-main() {}
-'''
-      },
-      unserializedSourceFiles: const {
-        'a.dart': '''
-part of main;
-'''
-      }),
-
-  const Test('Metadata on part-of tags', const {},
-      preserializedSourceFiles: const {
-        'main.dart': '''
-library main;
-
-part 'a.dart';
-
-main() {}
-'''
-      },
-      unserializedSourceFiles: const {
-        'a.dart': '''
-@deprecated
-part of main;
-'''
-      }),
-
-  const Test('Ambiguous elements', const {}, preserializedSourceFiles: const {
-    'main.dart': '''
-import 'a.dart';
-import 'b.dart';
-
-main() => new foo();
-''',
-    'a.dart': '''
-var foo;
-''',
-    'b.dart': '''
-var foo;
-''',
-  }),
-
-  const Test('html and mirrors', const {},
-      preserializedSourceFiles: const {
-        'main.dart': '''
-import 'dart:html';
-import 'dart:mirrors';
-main() {}
-'''
-      },
-      expectedWarningCount: 1),
-];
-
-class Test {
-  final String name;
-  final Map sourceFiles;
-  final Map preserializedSourceFiles;
-  final Map unserializedSourceFiles;
-  final int expectedErrorCount;
-  final int expectedWarningCount;
-  final int expectedHintCount;
-  final int expectedInfoCount;
-  final bool checkedMode;
-
-  const Test(this.name, this.sourceFiles,
-      {this.preserializedSourceFiles,
-      this.unserializedSourceFiles,
-      this.expectedErrorCount: 0,
-      this.expectedWarningCount: 0,
-      this.expectedHintCount: 0,
-      this.expectedInfoCount: 0,
-      this.checkedMode: false});
-}
diff --git a/tests/compiler/dart2js/serialization/test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
deleted file mode 100644
index 3b64fa0..0000000
--- a/tests/compiler/dart2js/serialization/test_helper.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_test_helper;
-
-import 'test_data.dart';
-
-/// Returns the test arguments for testing the [index]th skipped test. The
-/// [skip] count is used to check that [index] is a valid index.
-List<String> testSkipped(int index, int skip) {
-  if (index < 0 || index >= skip) {
-    throw new ArgumentError('Invalid skip index $index');
-  }
-  return ['${index}', '${index + 1}'];
-}
-
-/// Return the test arguments for testing the [index]th segment (1-based) of
-/// the [TESTS] split into [count] groups. The first [skip] tests are excluded
-/// from the automatic grouping.
-List<String> testSegment(int index, int count, int skip) {
-  if (index < 0 || index > count) {
-    throw new ArgumentError('Invalid segment index $index');
-  }
-
-  String segmentNumber(int i) {
-    return '${skip + i * (TESTS.length - skip) ~/ count}';
-  }
-
-  if (index == 1 && skip != 0) {
-    return ['${skip}', segmentNumber(index)];
-  } else if (index == count) {
-    return [segmentNumber(index - 1)];
-  } else {
-    return [segmentNumber(index - 1), segmentNumber(index)];
-  }
-}
diff --git a/tests/compiler/dart2js_extra/32853_test.dart b/tests/compiler/dart2js_extra/32853_test.dart
new file mode 100644
index 0000000..ccf8dab
--- /dev/null
+++ b/tests/compiler/dart2js_extra/32853_test.dart
@@ -0,0 +1,15 @@
+// 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
+
+// Regression test for issue 32853.
+
+
+int foo<T extends Comparable<T>>(T a, T b) => a.compareTo(b);
+
+main() {
+  int Function<T extends Comparable<T>>(T, T) f = foo;
+  print(f<num>(1, 2));
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index bb4d673..02e2263 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -6,7 +6,6 @@
 class_test: Fail
 constant_javascript_semantics4_test: Fail, OK
 generic_class_is_test: Fail # Issue 32004
-local_function_call_test: RuntimeError # Issue 31879
 mirror_printer_test: Pass, Slow # Issue 25940, 16473
 mirrors_used_closure_test: Fail # Issue 17939
 no_such_method_test: Fail # Wrong Invocation.memberName.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index fe9e13b..80b93c7 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -11,7 +11,6 @@
 full_stacktrace2_test: Pass, RuntimeError # Issue 12698
 full_stacktrace3_test: Pass, RuntimeError # Issue 12698
 library_env_test/has_no_html_support: RuntimeError, OK
-local_function_test: RuntimeError # Issue 31879
 vm/*: Skip # Issue 12699
 
 [ $arch == ia32 && $compiler == dart2js && $runtime == d8 ]
diff --git a/tests/language_2/const_cast4_test.dart b/tests/language_2/const_cast4_test.dart
new file mode 100644
index 0000000..cb7a250
--- /dev/null
+++ b/tests/language_2/const_cast4_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+/// Casts in constants correctly substitute type variables.
+
+class A {
+  const A();
+}
+
+class B implements A {
+  const B();
+}
+
+class M<T extends A> {
+  final T a;
+  const M(dynamic t) : a = t; // adds implicit cast `as T`
+}
+
+class N<S extends A> extends M<S> {
+  const N(dynamic t) : super(t);
+}
+
+main() {
+  print(const N<B>(const B()));
+}
diff --git a/tests/language_2/double_identical_test.dart b/tests/language_2/double_identical_test.dart
index 2004e63..16b99fe 100644
--- a/tests/language_2/double_identical_test.dart
+++ b/tests/language_2/double_identical_test.dart
@@ -10,5 +10,5 @@
   Expect.isTrue(identical(0.0, 0.0));
   Expect.isTrue(identical(1.234E9, 1.234E9));
   Expect.isFalse(identical(0.0, -0.0));
-  Expect.isTrue(identical(double.NAN, double.NAN));
+  Expect.isTrue(identical(double.nan, double.nan));
 }
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index aaf47f0..0ed2de8 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -31,7 +31,6 @@
 final_syntax_test/04: Fail # Issue 11124
 function_type_parameter2_negative_test: CompileTimeError
 function_type_parameter_negative_test: CompileTimeError
-fuzzy_arrows_test/01: MissingCompileTimeError
 generic_function_type_as_type_argument_test/01: MissingCompileTimeError # Issue 30929
 generic_function_type_as_type_argument_test/02: MissingCompileTimeError # Issue 30929
 generic_local_functions_test: CompileTimeError # Issue 28515
@@ -1184,7 +1183,6 @@
 mixin_super_2_test/03: MissingCompileTimeError
 mixin_supertype_subclass_test/02: MissingCompileTimeError
 mixin_supertype_subclass_test/05: MissingCompileTimeError
-mixin_type_parameter_inference_test/11: MissingCompileTimeError # Fuzzy arrow, 32114
 multiline_newline_test/01: CompileTimeError
 multiline_newline_test/01r: CompileTimeError
 multiline_newline_test/02: CompileTimeError
@@ -1411,6 +1409,7 @@
 constructor_call_as_function_test: StaticWarning
 constructor_duplicate_final_test/03: MissingCompileTimeError
 create_unresolved_type_test/01: MissingCompileTimeError
+fuzzy_arrows_test/01: MissingCompileTimeError
 generic_constructor_mixin2_test/01: MissingCompileTimeError
 generic_constructor_mixin3_test/01: MissingCompileTimeError
 generic_constructor_mixin_test/01: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index b53060d..742853a 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -994,10 +994,6 @@
 
 [ $compiler == dart2js && $fasta ]
 call_method_as_cast_test/06: RuntimeError
-call_method_function_typed_value_test/02: RuntimeError
-call_method_function_typed_value_test/04: RuntimeError
-call_method_function_typed_value_test/06: RuntimeError
-call_method_function_typed_value_test/08: RuntimeError
 call_method_implicit_tear_off_implements_function_test/05: RuntimeError
 call_method_implicit_tear_off_implements_function_test/06: RuntimeError
 call_method_is_check_test/06: RuntimeError
@@ -1177,7 +1173,7 @@
 deferred_regression_22995_test: RuntimeError
 deferred_regression_28678_test: RuntimeError
 deferred_shadow_load_library_test: RuntimeError
-deferred_shared_and_unshared_classes_test: CompileTimeError
+deferred_shared_and_unshared_classes_test: RuntimeError
 deferred_static_seperate_test: RuntimeError
 deferred_type_dependency_test/as: RuntimeError
 deferred_type_dependency_test/is: RuntimeError
@@ -1254,7 +1250,6 @@
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
 generic_methods_overriding_test/01: MissingCompileTimeError
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_recursive_bound_test/03: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/metadata_collector.dart': Failed assertion: line 100 pos 12: 'isBound': is not true.
 generic_methods_simple_as_expression_test/02: MissingRuntimeError
 generic_methods_type_expression_test: RuntimeError
 generic_methods_unused_parameter_test: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
@@ -1847,7 +1842,7 @@
 deferred_regression_22995_test: RuntimeError
 deferred_regression_28678_test: RuntimeError
 deferred_shadow_load_library_test: RuntimeError
-deferred_shared_and_unshared_classes_test: CompileTimeError
+deferred_shared_and_unshared_classes_test: RuntimeError
 deferred_static_seperate_test: RuntimeError
 deferred_type_dependency_test/as: RuntimeError
 deferred_type_dependency_test/is: RuntimeError
@@ -1922,7 +1917,6 @@
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
 generic_methods_overriding_test/01: MissingCompileTimeError
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_recursive_bound_test/03: Crash # NoSuchMethodError: The method 'markSeen' was called on null.
 generic_methods_simple_as_expression_test/02: MissingRuntimeError
 generic_methods_type_expression_test: RuntimeError
 generic_methods_unused_parameter_test: RuntimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 97c9e8d..b259467 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -30,7 +30,6 @@
 conflicting_type_variable_and_setter_test: CompileTimeError
 const_cast2_test/01: CompileTimeError
 const_cast2_test/none: CompileTimeError
-const_evaluation_test/01: RuntimeError # Issue 29920
 const_for_in_variable_test/01: MissingCompileTimeError
 const_types_test/07: MissingCompileTimeError
 const_types_test/08: MissingCompileTimeError
@@ -57,7 +56,6 @@
 forwarding_stub_tearoff_generic_test: RuntimeError
 forwarding_stub_tearoff_test: CompileTimeError
 function_propagation_test: RuntimeError
-fuzzy_arrows_test/01: MissingCompileTimeError
 generic_local_functions_test: CompileTimeError
 generic_methods_generic_function_parameter_test: CompileTimeError
 generic_methods_generic_function_result_test/none: CompileTimeError # Issue #30208
@@ -113,20 +111,16 @@
 mixin_supertype_subclass_test/02: MissingCompileTimeError
 mixin_supertype_subclass_test/05: MissingCompileTimeError
 mixin_type_parameter_inference_previous_mixin_test/01: CompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/02: RuntimeError
-mixin_type_parameter_inference_previous_mixin_test/03: MissingCompileTimeError
+mixin_type_parameter_inference_previous_mixin_test/02: CompileTimeError
 mixin_type_parameter_inference_previous_mixin_test/04: MissingCompileTimeError
 mixin_type_parameter_inference_previous_mixin_test/05: RuntimeError
 mixin_type_parameter_inference_test/01: CompileTimeError
-mixin_type_parameter_inference_test/02: RuntimeError
-mixin_type_parameter_inference_test/03: RuntimeError
-mixin_type_parameter_inference_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_test/05: MissingCompileTimeError
+mixin_type_parameter_inference_test/02: CompileTimeError
+mixin_type_parameter_inference_test/03: CompileTimeError
 mixin_type_parameter_inference_test/06: MissingCompileTimeError
 mixin_type_parameter_inference_test/07: MissingCompileTimeError
 mixin_type_parameter_inference_test/08: RuntimeError
 mixin_type_parameter_inference_test/09: RuntimeError
-mixin_type_parameter_inference_test/11: MissingCompileTimeError
 mock_writable_final_private_field_test: CompileTimeError # Issue 30848
 multiline_newline_test/01: CompileTimeError
 multiline_newline_test/01r: CompileTimeError
@@ -137,7 +131,6 @@
 multiline_newline_test/none: RuntimeError
 multiple_interface_inheritance_test: CompileTimeError # Issue 30552
 nested_generic_closure_test: CompileTimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError # Issue 31425
 override_inheritance_field_test/04: CompileTimeError
 override_inheritance_field_test/06: CompileTimeError
 override_inheritance_field_test/26: CompileTimeError
@@ -375,7 +368,6 @@
 deferred_inheritance_constraints_test/mixin: MissingCompileTimeError
 deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError
 deferred_load_library_wrong_args_test/01: CompileTimeError
-deferred_shared_and_unshared_classes_test: CompileTimeError # Issue 31402 Error: A value of type 'dart.core::List<dynamic>' can't be assigned to a variable of type 'dart.core::Iterable<dart.async::Future<dynamic>>'.
 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddk
 duplicate_export_negative_test: Fail
 duplicate_implements_test/01: MissingCompileTimeError
@@ -399,7 +391,6 @@
 field_override4_test/02: MissingCompileTimeError
 field_override_test/00: MissingCompileTimeError
 field_override_test/01: MissingCompileTimeError
-function_call_generic_test: RuntimeError # Issue 32756. Crashes on dsend
 function_propagation_test: RuntimeError
 function_type_parameter2_negative_test: Fail
 function_type_parameter_negative_test: Fail
@@ -555,13 +546,11 @@
 mixin_type_parameters_errors_test/03: MissingCompileTimeError
 mixin_type_parameters_errors_test/04: MissingCompileTimeError
 mixin_type_parameters_errors_test/05: MissingCompileTimeError
-mock_writable_final_field_test: RuntimeError # Expect.listEquals(list length, expected: <1>, actual: <0>) fails: Next element <123>
 mock_writable_final_private_field_test: RuntimeError
 multiline_newline_test/06: MissingCompileTimeError
 multiline_newline_test/06r: MissingCompileTimeError
 named_constructor_test/01: MissingCompileTimeError
 named_parameters_default_eq_test/02: MissingCompileTimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError # Issue 31425
 nsm5_test: MissingCompileTimeError
 null2_test: RuntimeError # Issue 32194
 null_method_test: RuntimeError # Issue 32194
@@ -712,6 +701,7 @@
 compile_time_constant_e_test: RuntimeError # Issue 30876; Expect.identical(expected: <A 3 499 99 100>, actual: <A 3 499 99 100>) fails.
 config_import_corelib_test: CompileTimeError
 config_import_test: RuntimeError # Expect.equals(expected: <b>, actual: <a>) fails.
+const_evaluation_test/01: RuntimeError # dart:mirrors not supported in DDC
 const_list_test: RuntimeError # Expect.equals(expected: <false>, actual: <true>) fails.
 const_map4_test: RuntimeError # Expect.equals(expected: <true>, actual: <false>) fails.
 const_switch_test/02: RuntimeError # Issue 29920; Expect.equals(expected: <0>, actual: <0.0>) fails.
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 3c1f1a3..ea83e68 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -636,7 +636,6 @@
 deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
 deferred_not_loaded_check_test: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
 deferred_redirecting_factory_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
-deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
 deferred_static_seperate_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
 disassemble_test: Pass, Slow
 dynamic_prefix_core_test/none: CompileTimeError
@@ -958,7 +957,6 @@
 deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
 deferred_not_loaded_check_test: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
 deferred_redirecting_factory_test: CompileTimeError, Fail, Crash # Issue 23408, KernelVM bug: Deferred loading kernel issue 30273.
-deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
 deferred_static_seperate_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
 deopt_inlined_function_lazy_test: Skip # Incompatible flag: --deoptimize-alot
 dynamic_prefix_core_test/none: CompileTimeError
@@ -1209,7 +1207,6 @@
 cyclic_typedef_test/10: Crash
 cyclic_typedef_test/11: Crash
 deferred_load_library_wrong_args_test/01: CompileTimeError
-deferred_shared_and_unshared_classes_test: CompileTimeError
 duplicate_implements_test/01: MissingCompileTimeError
 duplicate_implements_test/02: MissingCompileTimeError
 dynamic_prefix_core_test/none: CompileTimeError
diff --git a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
index ab35197..126c2c0 100644
--- a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
+++ b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
@@ -80,7 +80,7 @@
   a.test5<int>(1);
   (a.test5 as dynamic)<int>(1);
   Expect.throwsTypeError(() => (a.test5 as dynamic)<String>("foo"));
-  Expect.throwsTypeError(() => (a.test5 as dynamic)<int>(3.0));
+  Expect.throwsTypeError(() => (a.test5 as dynamic)<int>(3.1));
 
   Expect.throwsTypeError(() => a.test6());
   Expect.throwsTypeError(() => (a.test6 as dynamic)());
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 220eb6c..45b680a 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -116,7 +116,6 @@
 typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 10275
 
 [ $compiler == fasta ]
-mirrors/library_imports_bad_metadata_test/01: Crash
 mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
 mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
 mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
diff --git a/tests/lib_2/convert/json_test.dart b/tests/lib_2/convert/json_test.dart
index edd89e9..d7be8a0 100644
--- a/tests/lib_2/convert/json_test.dart
+++ b/tests/lib_2/convert/json_test.dart
@@ -170,7 +170,7 @@
   testError(integers: "");
 
   // Test for "Initial zero only allowed for zero integer part" moved to
-  // json_strict_test.dart because IE's JSON.decode accepts additional initial
+  // json_strict_test.dart because IE's jsonDecode accepts additional initial
   // zeros.
 
   // Only minus allowed as sign.
diff --git a/tests/lib_2/convert/utf84_test.dart b/tests/lib_2/convert/utf84_test.dart
index b1a9950..bc1db59 100755
--- a/tests/lib_2/convert/utf84_test.dart
+++ b/tests/lib_2/convert/utf84_test.dart
@@ -626,7 +626,7 @@
 
   String decodeUtf8List(List<int> codeUnits) => utf8.decode(codeUnits);
   String decodeUtf8Uint8List(List<int> codeUnits) =>
-      UTF8.decode(new Uint8List.fromList(codeUnits));
+      utf8.decode(new Uint8List.fromList(codeUnits));
 
   testUtf8BytesToString(decodeUtf8List);
   testUtf8BytesToString(decodeUtf8Uint8List);
@@ -647,7 +647,7 @@
 }
 
 void testEncodeToUtf8() {
-  List<int> encodeUtf8(String str) => UTF8.encode(str);
+  List<int> encodeUtf8(String str) => utf8.encode(str);
 
   Expect.listEquals(
       testEnglishUtf8, encodeUtf8(testEnglishPhrase), "english to utf8");
@@ -681,19 +681,19 @@
   Expect.listEquals([0x800], utf8ToRunes([0xe0, 0xa0, 0x80]), "800");
   Expect.listEquals([0x10000], utf8ToRunes([0xf0, 0x90, 0x80, 0x80]), "10000");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xf8, 0x88, 0x80, 0x80, 0x80]), "200000");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfc, 0x84, 0x80, 0x80, 0x80, 0x80]), "4000000");
 
   // boundary conditions: Last possible sequence of a certain length
@@ -701,48 +701,48 @@
   Expect.listEquals([0x7ff], utf8ToRunes([0xdf, 0xbf]), "7ff");
   Expect.listEquals([0xffff], utf8ToRunes([0xef, 0xbf, 0xbf]), "ffff");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xf7, 0xbf, 0xbf, 0xbf]), "1fffff");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfb, 0xbf, 0xbf, 0xbf, 0xbf]), "3ffffff");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfd, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf]), "4000000");
 
   // other boundary conditions
   Expect.listEquals([0xd7ff], utf8ToRunes([0xed, 0x9f, 0xbf]), "d7ff");
   Expect.listEquals([0xe000], utf8ToRunes([0xee, 0x80, 0x80]), "e000");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xef, 0xbf, 0xbd]), "fffd");
   Expect
       .listEquals([0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
 
   // unexpected continuation bytes
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0x80]),
+  Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0x80]),
       "80 => replacement character");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xbf]),
+  Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xbf]),
       "bf => replacement character");
 
   List<int> allContinuationBytes = <int>[];
   List<int> matchingReplacementChars = <int>[];
   for (int i = 0x80; i < 0xc0; i++) {
     allContinuationBytes.add(i);
-    matchingReplacementChars.add(UNICODE_REPLACEMENT_CHARACTER_RUNE);
+    matchingReplacementChars.add(unicodeReplacementCharacterRune);
   }
   Expect.listEquals(matchingReplacementChars, utf8ToRunes(allContinuationBytes),
       "80 - bf => replacement character x 64");
@@ -751,7 +751,7 @@
   matchingReplacementChars = <int>[];
   for (int i = 0xc0; i < 0xe0; i++) {
     allFirstTwoByteSeq.addAll([i, 0x20]);
-    matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+    matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
   }
   Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstTwoByteSeq),
       "c0 - df + space => replacement character + space x 32");
@@ -760,7 +760,7 @@
   matchingReplacementChars = <int>[];
   for (int i = 0xe0; i < 0xf0; i++) {
     allFirstThreeByteSeq.addAll([i, 0x20]);
-    matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+    matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
   }
   Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstThreeByteSeq),
       "e0 - ef + space => replacement character x 16");
@@ -769,7 +769,7 @@
   matchingReplacementChars = <int>[];
   for (int i = 0xf0; i < 0xf8; i++) {
     allFirstFourByteSeq.addAll([i, 0x20]);
-    matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+    matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
   }
   Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstFourByteSeq),
       "f0 - f7 + space => replacement character x 8");
@@ -778,7 +778,7 @@
   matchingReplacementChars = <int>[];
   for (int i = 0xf8; i < 0xfc; i++) {
     allFirstFiveByteSeq.addAll([i, 0x20]);
-    matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+    matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
   }
   Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstFiveByteSeq),
       "f8 - fb + space => replacement character x 4");
@@ -787,91 +787,91 @@
   matchingReplacementChars = <int>[];
   for (int i = 0xfc; i < 0xfe; i++) {
     allFirstSixByteSeq.addAll([i, 0x20]);
-    matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+    matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
   }
   Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstSixByteSeq),
       "fc - fd + space => replacement character x 2");
 
   // Sequences with last continuation byte missing
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xc2]),
+  Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xc2]),
       "2-byte sequence with last byte missing");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xe0, 0x80]), "3-byte sequence with last byte missing");
   Expect.listEquals(
-      [UNICODE_REPLACEMENT_CHARACTER_RUNE],
+      [unicodeReplacementCharacterRune],
       utf8ToRunes([0xf0, 0x80, 0x80]),
       "4-byte sequence with last byte missing");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xf8, 0x88, 0x80, 0x80]),
       "5-byte sequence with last byte missing");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80]),
       "6-byte sequence with last byte missing");
 
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xdf]),
+  Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xdf]),
       "2-byte sequence with last byte missing (hi)");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xef, 0xbf]), "3-byte sequence with last byte missing (hi)");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xf7, 0xbf, 0xbf]),
       "4-byte sequence with last byte missing (hi)");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfb, 0xbf, 0xbf, 0xbf]),
       "5-byte sequence with last byte missing (hi)");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfd, 0xbf, 0xbf, 0xbf, 0xbf]),
       "6-byte sequence with last byte missing (hi)");
 
   // Concatenation of incomplete sequences
   Expect.listEquals(
       [
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE,
-        UNICODE_REPLACEMENT_CHARACTER_RUNE
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune
       ],
       utf8ToRunes([
         0xc2,
@@ -908,82 +908,82 @@
       "Concatenation of incomplete sequences");
 
   // Impossible bytes
-  Expect.listEquals(
-      [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xfe]), "fe");
-  Expect.listEquals(
-      [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xff]), "ff");
+  Expect
+      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
+  Expect
+      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfe, 0xfe, 0xff, 0xff]), "fe fe ff ff");
 
   // Overlong sequences
   Expect.listEquals(
-      [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xc0, 0xaf]), "c0 af");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0xaf]), "c0 af");
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xf8, 0x80, 0x80, 0x80, 0xaf]), "f8 80 80 80 af");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0xaf]), "fc 80 80 80 80 af");
 
   Expect.listEquals(
-      [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xc1, 0xbf]), "c1 bf");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xc1, 0xbf]), "c1 bf");
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xf8, 0x87, 0xbf, 0xbf, 0xbf]), "f8 87 bf bf bf");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfc, 0x83, 0xbf, 0xbf, 0xbf, 0xbf]), "fc 83 bf bf bf bf");
 
   Expect.listEquals(
-      [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xc0, 0x80]), "c0 80");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0x80]), "c0 80");
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
-  Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+  Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xf8, 0x80, 0x80, 0x80, 0x80]), "f8 80 80 80 80");
   Expect.listEquals([
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE,
-    UNICODE_REPLACEMENT_CHARACTER_RUNE
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
   ], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0x80]), "fc 80 80 80 80 80");
 
   // Other illegal code positions (???)
diff --git a/tests/lib_2/convert/utf85_test.dart b/tests/lib_2/convert/utf85_test.dart
index ecec964..3f287e9 100644
--- a/tests/lib_2/convert/utf85_test.dart
+++ b/tests/lib_2/convert/utf85_test.dart
@@ -9,7 +9,7 @@
 
 main() {
   for (int i = 0; i <= 0x10FFFF; i++) {
-    if (i == UNICODE_BOM_CHARACTER_RUNE) continue;
+    if (i == unicodeBomCharacterRune) continue;
     Expect.equals(
         i, utf8.decode(utf8.encode(new String.fromCharCode(i))).runes.first);
   }
diff --git a/tests/lib_2/convert/utf8_test.dart b/tests/lib_2/convert/utf8_test.dart
index fc1856b..858c982 100644
--- a/tests/lib_2/convert/utf8_test.dart
+++ b/tests/lib_2/convert/utf8_test.dart
@@ -67,7 +67,7 @@
 
     var typed = new Uint8List.fromList(input);
     Expect.throws(() {
-      UTF8.decoder.convert(typed);
+      utf8.decoder.convert(typed);
     }, (e) => e is FormatException && typed == e.source && offset == e.offset);
   }
 
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index b8926562..1d2d4a3 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -8,7 +8,6 @@
 
 [ $compiler == dartdevk ]
 async/slow_consumer_test: CompileTimeError
-collection/list_test: RuntimeError
 convert/chunked_conversion1_test: RuntimeError
 convert/chunked_conversion_utf82_test: RuntimeError
 convert/chunked_conversion_utf86_test: RuntimeError
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index d51d869..cd95ea9 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -136,7 +136,6 @@
 mirrors/library_exports_hidden_test: RuntimeError, Crash, CompileTimeError # Issue 31402 (Invocation arguments)
 mirrors/library_exports_shown_test: RuntimeError, CompileTimeError # Issue 31402 (Invocation arguments)
 mirrors/library_import_deferred_loading_test: RuntimeError # Deferred loading kernel issue 28335.
-mirrors/library_imports_bad_metadata_test/none: Crash
 mirrors/library_imports_deferred_test: RuntimeError, CompileTimeError # Issue 31402 (Invocation arguments)
 mirrors/library_imports_hidden_test: RuntimeError # Issue 31402 (Invocation arguments)
 mirrors/library_imports_metadata_test: RuntimeError # Issue 31402 (Invocation arguments)
@@ -253,7 +252,7 @@
 mirrors/instantiate_abstract_class_test: RuntimeError
 mirrors/invoke_closurization2_test: RuntimeError
 mirrors/invoke_throws_test: RuntimeError
-mirrors/library_imports_bad_metadata_test/none: RuntimeError
+mirrors/library_imports_bad_metadata_test/none: RuntimeError, Crash # Issue 32879
 mirrors/metadata_const_map_test: Crash
 mirrors/mixin_members_test: RuntimeError
 mirrors/null_test: RuntimeError
@@ -332,7 +331,6 @@
 [ $compiler == fasta && $strong ]
 isolate/isolate_stress_test: CompileTimeError
 mirrors/deferred_type_test: CompileTimeError
-mirrors/library_imports_bad_metadata_test/01: Crash
 mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
 mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
 mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
@@ -350,7 +348,6 @@
 [ $fasta && !$strong ]
 isolate/isolate_import_test/01: MissingCompileTimeError
 isolate/isolate_stress_test: CompileTimeError
-mirrors/library_imports_bad_metadata_test/01: Crash
 mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
 mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
 mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
diff --git a/tests/standalone/verbose_gc_to_bmu_test.dart b/tests/standalone/verbose_gc_to_bmu_test.dart
index 5213d4c..884e139 100644
--- a/tests/standalone/verbose_gc_to_bmu_test.dart
+++ b/tests/standalone/verbose_gc_to_bmu_test.dart
@@ -43,9 +43,9 @@
     process.stdin.write(gcLog);
     process.stdin.close();
     var stdoutStringStream =
-        process.stdout.transform(UTF8.decoder).transform(new LineSplitter());
+        process.stdout.transform(utf8.decoder).transform(new LineSplitter());
     var stderrStringStream =
-        process.stderr.transform(UTF8.decoder).transform(new LineSplitter());
+        process.stderr.transform(utf8.decoder).transform(new LineSplitter());
     // Wait for 3 future events: stdout and stderr streams closed, and
     // process terminated.
     var futures = [];
diff --git a/tests/standalone_2/io/file_test.dart b/tests/standalone_2/io/file_test.dart
index c5229cf..da550d8 100644
--- a/tests/standalone_2/io/file_test.dart
+++ b/tests/standalone_2/io/file_test.dart
@@ -1201,8 +1201,8 @@
     text = new File(name).readAsStringSync(encoding: lenientAscii);
     // Default replacement character is the Unicode replacement character.
     expected = [
-      UNICODE_REPLACEMENT_CHARACTER_RUNE,
-      UNICODE_REPLACEMENT_CHARACTER_RUNE,
+      unicodeReplacementCharacterRune,
+      unicodeReplacementCharacterRune,
       120,
       46,
       32,
diff --git a/tests/standalone_2/io/file_typed_data_test.dart b/tests/standalone_2/io/file_typed_data_test.dart
index b6efa40..4ef1612 100644
--- a/tests/standalone_2/io/file_typed_data_test.dart
+++ b/tests/standalone_2/io/file_typed_data_test.dart
@@ -14,7 +14,7 @@
 void testWriteInt8ListAndView() {
   asyncStart();
   const int LIST_LENGTH = 8;
-  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int8List.BYTES_PER_ELEMENT;
+  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int8List.bytesPerElement;
   const int VIEW_LENGTH = 4;
   Int8List list = new Int8List(LIST_LENGTH);
   for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
@@ -44,7 +44,7 @@
 void testWriteUint8ListAndView() {
   asyncStart();
   const int LIST_LENGTH = 8;
-  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint8List.BYTES_PER_ELEMENT;
+  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint8List.bytesPerElement;
   const int VIEW_LENGTH = 4;
   Uint8List list = new Uint8List(LIST_LENGTH);
   for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
@@ -104,10 +104,10 @@
 void testWriteInt16ListAndView() {
   asyncStart();
   const int LIST_LENGTH = 8;
-  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int16List.BYTES_PER_ELEMENT;
-  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int16List.BYTES_PER_ELEMENT;
+  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int16List.bytesPerElement;
+  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int16List.bytesPerElement;
   const int VIEW_LENGTH = 4;
-  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int16List.BYTES_PER_ELEMENT;
+  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int16List.bytesPerElement;
   var list = new Int16List(LIST_LENGTH);
   for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
   var view =
@@ -146,10 +146,10 @@
 void testWriteUint16ListAndView() {
   asyncStart();
   const int LIST_LENGTH = 8;
-  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Uint16List.BYTES_PER_ELEMENT;
-  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint16List.BYTES_PER_ELEMENT;
+  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Uint16List.bytesPerElement;
+  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint16List.bytesPerElement;
   const int VIEW_LENGTH = 4;
-  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint16List.BYTES_PER_ELEMENT;
+  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint16List.bytesPerElement;
   var list = new Uint16List(LIST_LENGTH);
   for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
   var view =
@@ -188,10 +188,10 @@
 void testWriteInt32ListAndView() {
   asyncStart();
   const int LIST_LENGTH = 8;
-  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int32List.BYTES_PER_ELEMENT;
-  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int32List.BYTES_PER_ELEMENT;
+  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int32List.bytesPerElement;
+  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int32List.bytesPerElement;
   const int VIEW_LENGTH = 4;
-  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.BYTES_PER_ELEMENT;
+  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.bytesPerElement;
   var list = new Int32List(LIST_LENGTH);
   for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
   var view =
@@ -230,10 +230,10 @@
 void testWriteUint32ListAndView() {
   asyncStart();
   const int LIST_LENGTH = 8;
-  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int32List.BYTES_PER_ELEMENT;
-  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int32List.BYTES_PER_ELEMENT;
+  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int32List.bytesPerElement;
+  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int32List.bytesPerElement;
   const int VIEW_LENGTH = 4;
-  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.BYTES_PER_ELEMENT;
+  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.bytesPerElement;
   var list = new Uint32List(LIST_LENGTH);
   for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
   var view =
@@ -272,10 +272,10 @@
 void testWriteInt64ListAndView() {
   asyncStart();
   const int LIST_LENGTH = 8;
-  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int64List.BYTES_PER_ELEMENT;
-  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int64List.BYTES_PER_ELEMENT;
+  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int64List.bytesPerElement;
+  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int64List.bytesPerElement;
   const int VIEW_LENGTH = 4;
-  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int64List.BYTES_PER_ELEMENT;
+  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int64List.bytesPerElement;
   var list = new Int64List(LIST_LENGTH);
   for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
   var view =
@@ -314,10 +314,10 @@
 void testWriteUint64ListAndView() {
   asyncStart();
   const int LIST_LENGTH = 8;
-  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Uint64List.BYTES_PER_ELEMENT;
-  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint64List.BYTES_PER_ELEMENT;
+  const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Uint64List.bytesPerElement;
+  const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint64List.bytesPerElement;
   const int VIEW_LENGTH = 4;
-  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint64List.BYTES_PER_ELEMENT;
+  const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint64List.bytesPerElement;
   var list = new Uint64List(LIST_LENGTH);
   for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
   var view =
diff --git a/tests/standalone_2/io/process_inherit_stdio_test.dart b/tests/standalone_2/io/process_inherit_stdio_test.dart
index 9ca1bf6..375f87e 100644
--- a/tests/standalone_2/io/process_inherit_stdio_test.dart
+++ b/tests/standalone_2/io/process_inherit_stdio_test.dart
@@ -26,7 +26,7 @@
   Completer<String> s = new Completer();
   future.then((process) {
     StringBuffer buf = new StringBuffer();
-    process.stdout.transform(UTF8.decoder).listen((data) {
+    process.stdout.transform(utf8.decoder).listen((data) {
       buf.write(data);
     }, onDone: () {
       s.complete(buf.toString());
diff --git a/tests/standalone_2/map_insert_remove_oom_test.dart b/tests/standalone_2/map_insert_remove_oom_test.dart
index 25c1a33..f20126a 100644
--- a/tests/standalone_2/map_insert_remove_oom_test.dart
+++ b/tests/standalone_2/map_insert_remove_oom_test.dart
@@ -2,7 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 //
-// VMOptions=--old_gen_heap_size=10
+// VMOptions=--old_gen_heap_size=11
+//
+// Notice we set the old gen heap size to 11 MB, which seems to be the minimum
+// (in debug mode) to not cause us run OOM during isolate initialization.  The
+// problem here is that we pre-allocate certain exceptions, e.g. NullThrownError
+// during isolate initialization, but if we have an allocation failure before
+// that, we end up running into a recursive allocate/throw loop.
+//
 // Test that compaction does occur on repeated add/remove.
 
 main() {
diff --git a/tools/VERSION b/tools/VERSION
index 7f55251..4229ed2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 0
 PATCH 0
-PRERELEASE 48
+PRERELEASE 49
 PRERELEASE_PATCH 0
diff --git a/tools/apps/update_homebrew/lib/update_homebrew.dart b/tools/apps/update_homebrew/lib/update_homebrew.dart
index 5628c41..477ddb0 100644
--- a/tools/apps/update_homebrew/lib/update_homebrew.dart
+++ b/tools/apps/update_homebrew/lib/update_homebrew.dart
@@ -33,7 +33,7 @@
         'channels/$channel/release/$revision/$download.sha256sum',
         downloadOptions: DownloadOptions.FullMedia);
 
-    var hashLine = await ASCII.decodeStream(media.stream);
+    var hashLine = await ascii.decodeStream(media.stream);
     return new RegExp('[0-9a-fA-F]*').stringMatch(hashLine);
   } finally {
     client.close();
@@ -49,7 +49,7 @@
         'dart-archive', 'channels/$channel/release/$revision/VERSION',
         downloadOptions: DownloadOptions.FullMedia);
 
-    var versionObject = await JSON.fuse(ASCII).decoder.bind(media.stream).first;
+    var versionObject = await json.fuse(ascii).decoder.bind(media.stream).first;
     return versionObject['version'];
   } finally {
     client.close();
diff --git a/tools/build.py b/tools/build.py
index df5c045..f22d32d 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -1,14 +1,317 @@
 #!/usr/bin/env python
 #
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-# This script simply forwards to tools/ninja.py. It is retained simply to avoid
-# breaking various workflows.
-
-import ninja
+import multiprocessing
+import optparse
+import os
+import subprocess
 import sys
+import time
+import utils
+
+HOST_OS = utils.GuessOS()
+HOST_CPUS = utils.GuessCpus()
+SCRIPT_DIR = os.path.dirname(sys.argv[0])
+DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
+
+usage = """\
+usage: %%prog [options] [targets]
+
+This script invokes ninja to build Dart.
+"""
+
+
+def BuildOptions():
+  result = optparse.OptionParser(usage=usage)
+  result.add_option("-m", "--mode",
+      help='Build variants (comma-separated).',
+      metavar='[all,debug,release,product]',
+      default='debug')
+  result.add_option("-v", "--verbose",
+      help='Verbose output.',
+      default=False, action="store_true")
+  result.add_option("-a", "--arch",
+      help='Target architectures (comma-separated).',
+      metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
+              'simarm64,arm64,simdbc,armsimdbc]',
+      default=utils.GuessArchitecture())
+  result.add_option("--os",
+      help='Target OSs (comma-separated).',
+      metavar='[all,host,android]',
+      default='host')
+  result.add_option("-j",
+      type=int,
+      help='Ninja -j option for Goma builds.',
+      metavar=1000,
+      default=1000)
+  result.add_option("--no-start-goma",
+      help="Don't try to start goma",
+      default=False,
+      action='store_true')
+  return result
+
+
+def ProcessOsOption(os_name):
+  if os_name == 'host':
+    return HOST_OS
+  return os_name
+
+
+def ProcessOptions(options, args):
+  if options.arch == 'all':
+    options.arch = 'ia32,x64,simarm,simarm64,simdbc64'
+  if options.mode == 'all':
+    options.mode = 'debug,release,product'
+  if options.os == 'all':
+    options.os = 'host,android'
+  options.mode = options.mode.split(',')
+  options.arch = options.arch.split(',')
+  options.os = options.os.split(',')
+  for mode in options.mode:
+    if not mode in ['debug', 'release', 'product']:
+      print "Unknown mode %s" % mode
+      return False
+  for arch in options.arch:
+    archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
+             'simarmv5te', 'armv5te', 'simarm64', 'arm64',
+             'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
+    if not arch in archs:
+      print "Unknown arch %s" % arch
+      return False
+  options.os = [ProcessOsOption(os_name) for os_name in options.os]
+  for os_name in options.os:
+    if not os_name in ['android', 'freebsd', 'linux', 'macos', 'win32']:
+      print "Unknown os %s" % os_name
+      return False
+    if os_name != HOST_OS:
+      if os_name != 'android':
+        print "Unsupported target os %s" % os_name
+        return False
+      if not HOST_OS in ['linux', 'macos']:
+        print ("Cross-compilation to %s is not supported on host os %s."
+               % (os_name, HOST_OS))
+        return False
+      if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64',
+                      'simdbc', 'simdbc64']:
+        print ("Cross-compilation to %s is not supported for architecture %s."
+               % (os_name, arch))
+        return False
+      # We have not yet tweaked the v8 dart build to work with the Android
+      # NDK/SDK, so don't try to build it.
+      if not args:
+        print "For android builds you must specify a target, such as 'runtime'."
+        return False
+  return True
+
+
+def NotifyBuildDone(build_config, success, start):
+  if not success:
+    print "BUILD FAILED"
+
+  sys.stdout.flush()
+
+  # Display a notification if build time exceeded DART_BUILD_NOTIFICATION_DELAY.
+  notification_delay = float(
+    os.getenv('DART_BUILD_NOTIFICATION_DELAY', sys.float_info.max))
+  if (time.time() - start) < notification_delay:
+    return
+
+  if success:
+    message = 'Build succeeded.'
+  else:
+    message = 'Build failed.'
+  title = build_config
+
+  command = None
+  if HOST_OS == 'macos':
+    # Use AppleScript to display a UI non-modal notification.
+    script = 'display notification  "%s" with title "%s" sound name "Glass"' % (
+      message, title)
+    command = "osascript -e '%s' &" % script
+  elif HOST_OS == 'linux':
+    if success:
+      icon = 'dialog-information'
+    else:
+      icon = 'dialog-error'
+    command = "notify-send -i '%s' '%s' '%s' &" % (icon, message, title)
+  elif HOST_OS == 'win32':
+    if success:
+      icon = 'info'
+    else:
+      icon = 'error'
+    command = ("powershell -command \""
+      "[reflection.assembly]::loadwithpartialname('System.Windows.Forms')"
+        "| Out-Null;"
+      "[reflection.assembly]::loadwithpartialname('System.Drawing')"
+        "| Out-Null;"
+      "$n = new-object system.windows.forms.notifyicon;"
+      "$n.icon = [system.drawing.systemicons]::information;"
+      "$n.visible = $true;"
+      "$n.showballoontip(%d, '%s', '%s', "
+      "[system.windows.forms.tooltipicon]::%s);\"") % (
+        5000, # Notification stays on for this many milliseconds
+        message, title, icon)
+
+  if command:
+    # Ignore return code, if this command fails, it doesn't matter.
+    os.system(command)
+
+
+def RunGN(target_os, mode, arch):
+  gn_os = 'host' if target_os == HOST_OS else target_os
+  gn_command = [
+    'python',
+    os.path.join(DART_ROOT, 'tools', 'gn.py'),
+    '-m', mode,
+    '-a', arch,
+    '--os', gn_os,
+    '-v',
+  ]
+  process = subprocess.Popen(gn_command)
+  process.wait()
+  if process.returncode != 0:
+    print ("Tried to run GN, but it failed. Try running it manually: \n\t$ " +
+           ' '.join(gn_command))
+
+
+def ShouldRunGN(out_dir):
+  return (not os.path.exists(out_dir) or
+          not os.path.isfile(os.path.join(out_dir, 'args.gn')))
+
+
+def UseGoma(out_dir):
+  args_gn = os.path.join(out_dir, 'args.gn')
+  return 'use_goma = true' in open(args_gn, 'r').read()
+
+
+# Try to start goma, but don't bail out if we can't. Instead print an error
+# message, and let the build fail with its own error messages as well.
+goma_started = False
+def EnsureGomaStarted(out_dir):
+  global goma_started
+  if goma_started:
+    return True
+  args_gn_path = os.path.join(out_dir, 'args.gn')
+  goma_dir = None
+  with open(args_gn_path, 'r') as fp:
+    for line in fp:
+      if 'goma_dir' in line:
+        words = line.split()
+        goma_dir = words[2][1:-1]  # goma_dir = "/path/to/goma"
+  if not goma_dir:
+    print 'Could not find goma for ' + out_dir
+    return False
+  if not os.path.exists(goma_dir) or not os.path.isdir(goma_dir):
+    print 'Could not find goma at ' + goma_dir
+    return False
+  goma_ctl = os.path.join(goma_dir, 'goma_ctl.py')
+  goma_ctl_command = [
+    'python',
+    goma_ctl,
+    'ensure_start',
+  ]
+  process = subprocess.Popen(goma_ctl_command)
+  process.wait()
+  if process.returncode != 0:
+    print ("Tried to run goma_ctl.py, but it failed. Try running it manually: "
+           + "\n\t" + ' '.join(goma_ctl_command))
+    return False
+  goma_started = True
+  return True
+
+
+# Returns a tuple (build_config, command to run, whether goma is used)
+def BuildOneConfig(options, targets, target_os, mode, arch):
+  build_config = utils.GetBuildConf(mode, arch, target_os)
+  out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
+  using_goma = False
+  if ShouldRunGN(out_dir):
+    RunGN(target_os, mode, arch)
+  command = ['ninja', '-C', out_dir]
+  if options.verbose:
+    command += ['-v']
+  if UseGoma(out_dir):
+    if options.no_start_goma or EnsureGomaStarted(out_dir):
+      using_goma = True
+      command += [('-j%s' % str(options.j))]
+    else:
+      # If we couldn't ensure that goma is started, let the build start, but
+      # slowly so we can see any helpful error messages that pop out.
+      command += ['-j1']
+  command += targets
+  return (build_config, command, using_goma)
+
+
+def RunOneBuildCommand(build_config, args):
+  start_time = time.time()
+  print ' '.join(args)
+  process = subprocess.Popen(args, stdin=None)
+  process.wait()
+  if process.returncode != 0:
+    NotifyBuildDone(build_config, success=False, start=start_time)
+    return 1
+  else:
+    NotifyBuildDone(build_config, success=True, start=start_time)
+
+  return 0
+
+
+def RunOneGomaBuildCommand(args):
+  try:
+    print ' '.join(args)
+    process = subprocess.Popen(args, stdin=None)
+    process.wait()
+    print (' '.join(args) + " done.")
+    return process.returncode
+  except KeyboardInterrupt:
+    return 1
+
+
+def Main():
+  starttime = time.time()
+  # Parse the options.
+  parser = BuildOptions()
+  (options, args) = parser.parse_args()
+  if not ProcessOptions(options, args):
+    parser.print_help()
+    return 1
+  # Determine which targets to build. By default we build the "all" target.
+  if len(args) == 0:
+    targets = ['all']
+  else:
+    targets = args
+
+  # Build all targets for each requested configuration.
+  configs = []
+  for target_os in options.os:
+    for mode in options.mode:
+      for arch in options.arch:
+        configs.append(BuildOneConfig(options, targets, target_os, mode, arch))
+
+  # Build regular configs.
+  goma_builds = []
+  for (build_config, args, goma) in configs:
+    if args is None:
+      return 1
+    if goma:
+      goma_builds.append(args)
+    elif RunOneBuildCommand(build_config, args) != 0:
+      return 1
+
+  # Run goma builds in parallel.
+  pool = multiprocessing.Pool(multiprocessing.cpu_count())
+  results = pool.map(RunOneGomaBuildCommand, goma_builds, chunksize=1)
+  for r in results:
+    if r != 0:
+      return 1
+
+  endtime = time.time()
+  print ("The build took %.3f seconds" % (endtime - starttime))
+  return 0
+
 
 if __name__ == '__main__':
-  sys.exit(ninja.Main())
+  sys.exit(Main())
diff --git a/tools/gardening/lib/src/buildbucket.dart b/tools/gardening/lib/src/buildbucket.dart
index d2fcc73..ff4db96 100644
--- a/tools/gardening/lib/src/buildbucket.dart
+++ b/tools/gardening/lib/src/buildbucket.dart
@@ -12,14 +12,14 @@
   var api = new BuildBucketApi();
   var result = api.search("buildset:patch/gerrit/dart-review.googlesource.com/"
       "${changeNumber}/${patchset}");
-  return result.then(JSON.decode).then(_buildsFromJson);
+  return result.then(jsonDecode).then(_buildsFromJson);
 }
 
 /// Get builds from a swarming task with [swarmingTaskId].
 Future<List<BuildBucketBuild>> buildsFromSwarmingTaskId(String swarmingTaskId) {
   var api = new BuildBucketApi();
   var result = api.search("swarming_task_id:$swarmingTaskId");
-  return result.then(JSON.decode).then(_buildsFromJson);
+  return result.then(jsonDecode).then(_buildsFromJson);
 }
 
 /// Gets builds from a [builder] in descending order.
@@ -32,14 +32,14 @@
       fields: "builds(id,tags)",
       status: "COMPLETED",
       result: "SUCCESS");
-  return result.then(JSON.decode).then(_buildsFromJson);
+  return result.then(jsonDecode).then(_buildsFromJson);
 }
 
 /// Fetches all builders from a specific [clientBucket].
 Future<Iterable<Builder>> fetchBuilders(String clientBucket) async {
   BuildBucketApi api = new BuildBucketApi();
   String result = await api.builders();
-  var json = JSON.decode(result);
+  var json = jsonDecode(result);
   var buckets = json["buckets"].where((bucket) {
     return bucket["name"] == clientBucket;
   });
diff --git a/tools/gardening/lib/src/logdog_rpc.dart b/tools/gardening/lib/src/logdog_rpc.dart
index 06e7766..32f1499 100644
--- a/tools/gardening/lib/src/logdog_rpc.dart
+++ b/tools/gardening/lib/src/logdog_rpc.dart
@@ -17,12 +17,12 @@
         scheme: "https", host: LOGDOG_HOST, path: "prpc/logdog.Logs/Get");
     var body = {"project": project, "path": path};
     return withCache(
-            () => _makePostRequest(uri, JSON.encode(body), {
+            () => _makePostRequest(uri, jsonEncode(body), {
                   HttpHeaders.CONTENT_TYPE: "application/json",
                   HttpHeaders.ACCEPT: "application/json"
                 }),
             "logdog-get-$path")
-        .then(JSON.decode)
+        .then(jsonDecode)
         .then((json) {
       StringBuffer buffer = new StringBuffer();
       json["logs"].forEach((log) {
@@ -41,12 +41,12 @@
         scheme: "https", host: LOGDOG_HOST, path: "prpc/logdog.Logs/Query");
     var body = {"project": project, "path": path, "maxResults": maxResults};
     return withCache(
-            () => _makePostRequest(uri, JSON.encode(body), {
+            () => _makePostRequest(uri, jsonEncode(body), {
                   HttpHeaders.CONTENT_TYPE: "application/json",
                   HttpHeaders.ACCEPT: "application/json"
                 }),
             "logdog-query-$path")
-        .then(JSON.decode)
+        .then(jsonDecode)
         .then((json) {
       if (json["streams"] == null) {
         return <LogdogStream>[];
diff --git a/tools/gardening/lib/src/luci_api.dart b/tools/gardening/lib/src/luci_api.dart
index 2a44833..bf808f0 100644
--- a/tools/gardening/lib/src/luci_api.dart
+++ b/tools/gardening/lib/src/luci_api.dart
@@ -34,7 +34,7 @@
                 host: CBE_HOST,
                 path: "/get_master/${client}")),
             "cbe")
-        .then(JSON.decode);
+        .then(jsonDecode);
   }
 
   /// Calling the Milo Api to get latest builds for this bot,
@@ -53,15 +53,15 @@
       "includeCurrent": true
     };
     return withCache(
-            () => _makePostRequest(uri, JSON.encode(body), {
+            () => _makePostRequest(uri, jsonEncode(body), {
                   HttpHeaders.CONTENT_TYPE: "application/json",
                   HttpHeaders.ACCEPT: "application/json"
                 }),
             '${uri.path}_${botName}_$amount')
-        .then(JSON.decode)
+        .then(jsonDecode)
         .then((json) {
       return json["builds"].map((b) {
-        var build = JSON.decode(UTF8.decode(BASE64.decode(b["data"])));
+        var build = jsonDecode(utf8.decode(base64Decode(b["data"])));
         return getBuildDetailFromJson(client, botName, build);
       }).toList();
     });
@@ -77,14 +77,14 @@
         path: "prpc/milo.Buildbot/GetBuildbotBuildJSON");
     var body = {"master": client, "builder": botName, "buildNum": buildNumber};
     return withCache(
-            () => _makePostRequest(uri, JSON.encode(body), {
+            () => _makePostRequest(uri, jsonEncode(body), {
                   HttpHeaders.CONTENT_TYPE: "application/json",
                   HttpHeaders.ACCEPT: "application/json"
                 }),
             '${uri.path}_${botName}_$buildNumber')
-        .then(JSON.decode)
+        .then(jsonDecode)
         .then((json) {
-      var build = JSON.decode(UTF8.decode(BASE64.decode(json["data"])));
+      var build = jsonDecode(utf8.decode(base64Decode(json["data"])));
       return getBuildDetailFromJson(client, botName, build);
     });
   }
@@ -97,7 +97,7 @@
       response.drain();
       throw new HttpException(response.reasonPhrase, uri: uri);
     }
-    return response.transform(UTF8.decoder).join();
+    return response.transform(utf8.decoder).join();
   }
 
   /// [_makePostRequest] performs a post request to [uri], where the posted
diff --git a/tools/gardening/lib/src/results/test_result_service.dart b/tools/gardening/lib/src/results/test_result_service.dart
index f6a56d7..9d9326a 100644
--- a/tools/gardening/lib/src/results/test_result_service.dart
+++ b/tools/gardening/lib/src/results/test_result_service.dart
@@ -89,7 +89,7 @@
     var cache = createCache ?? standardCache;
     return logdog
         .get(BUILDER_PROJECT, logName, cache(duration: new Duration(days: 365)))
-        .then((json) => new TestResult.fromJson(JSON.decode(json)));
+        .then((json) => new TestResult.fromJson(jsonDecode(json)));
   }
 
   /// Gets result logs from logdog streams.
@@ -99,7 +99,7 @@
     return Future.wait(streams.map((stream) {
       logger.debug('Getting the log ${stream.path}...');
       return logdog.get(project, stream.path, cache).then((log) {
-        return new TestResult.fromJson(JSON.decode(log));
+        return new TestResult.fromJson(jsonDecode(log));
       }).catchError(
           errorLogger(logger, "Could not get a log.", new TestResult()));
     }));
@@ -221,7 +221,7 @@
   Future<TestResult> getFromFile(File file) {
     return file
         .readAsString()
-        .then(JSON.decode)
+        .then(jsonDecode)
         .then((json) => new TestResult.fromJson(json));
   }
 }
diff --git a/tools/gardening/lib/src/util.dart b/tools/gardening/lib/src/util.dart
index d0b44cd..48c3848 100644
--- a/tools/gardening/lib/src/util.dart
+++ b/tools/gardening/lib/src/util.dart
@@ -88,9 +88,9 @@
     throw new HttpException(uri, response.statusCode);
   }
   if (timeout != null) {
-    return response.timeout(timeout).transform(UTF8.decoder).join();
+    return response.timeout(timeout).transform(utf8.decoder).join();
   } else {
-    return response.transform(UTF8.decoder).join();
+    return response.transform(utf8.decoder).join();
   }
 }
 
diff --git a/tools/ninja.py b/tools/ninja.py
deleted file mode 100755
index f22d32d..0000000
--- a/tools/ninja.py
+++ /dev/null
@@ -1,317 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import multiprocessing
-import optparse
-import os
-import subprocess
-import sys
-import time
-import utils
-
-HOST_OS = utils.GuessOS()
-HOST_CPUS = utils.GuessCpus()
-SCRIPT_DIR = os.path.dirname(sys.argv[0])
-DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
-
-usage = """\
-usage: %%prog [options] [targets]
-
-This script invokes ninja to build Dart.
-"""
-
-
-def BuildOptions():
-  result = optparse.OptionParser(usage=usage)
-  result.add_option("-m", "--mode",
-      help='Build variants (comma-separated).',
-      metavar='[all,debug,release,product]',
-      default='debug')
-  result.add_option("-v", "--verbose",
-      help='Verbose output.',
-      default=False, action="store_true")
-  result.add_option("-a", "--arch",
-      help='Target architectures (comma-separated).',
-      metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
-              'simarm64,arm64,simdbc,armsimdbc]',
-      default=utils.GuessArchitecture())
-  result.add_option("--os",
-      help='Target OSs (comma-separated).',
-      metavar='[all,host,android]',
-      default='host')
-  result.add_option("-j",
-      type=int,
-      help='Ninja -j option for Goma builds.',
-      metavar=1000,
-      default=1000)
-  result.add_option("--no-start-goma",
-      help="Don't try to start goma",
-      default=False,
-      action='store_true')
-  return result
-
-
-def ProcessOsOption(os_name):
-  if os_name == 'host':
-    return HOST_OS
-  return os_name
-
-
-def ProcessOptions(options, args):
-  if options.arch == 'all':
-    options.arch = 'ia32,x64,simarm,simarm64,simdbc64'
-  if options.mode == 'all':
-    options.mode = 'debug,release,product'
-  if options.os == 'all':
-    options.os = 'host,android'
-  options.mode = options.mode.split(',')
-  options.arch = options.arch.split(',')
-  options.os = options.os.split(',')
-  for mode in options.mode:
-    if not mode in ['debug', 'release', 'product']:
-      print "Unknown mode %s" % mode
-      return False
-  for arch in options.arch:
-    archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
-             'simarmv5te', 'armv5te', 'simarm64', 'arm64',
-             'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
-    if not arch in archs:
-      print "Unknown arch %s" % arch
-      return False
-  options.os = [ProcessOsOption(os_name) for os_name in options.os]
-  for os_name in options.os:
-    if not os_name in ['android', 'freebsd', 'linux', 'macos', 'win32']:
-      print "Unknown os %s" % os_name
-      return False
-    if os_name != HOST_OS:
-      if os_name != 'android':
-        print "Unsupported target os %s" % os_name
-        return False
-      if not HOST_OS in ['linux', 'macos']:
-        print ("Cross-compilation to %s is not supported on host os %s."
-               % (os_name, HOST_OS))
-        return False
-      if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64',
-                      'simdbc', 'simdbc64']:
-        print ("Cross-compilation to %s is not supported for architecture %s."
-               % (os_name, arch))
-        return False
-      # We have not yet tweaked the v8 dart build to work with the Android
-      # NDK/SDK, so don't try to build it.
-      if not args:
-        print "For android builds you must specify a target, such as 'runtime'."
-        return False
-  return True
-
-
-def NotifyBuildDone(build_config, success, start):
-  if not success:
-    print "BUILD FAILED"
-
-  sys.stdout.flush()
-
-  # Display a notification if build time exceeded DART_BUILD_NOTIFICATION_DELAY.
-  notification_delay = float(
-    os.getenv('DART_BUILD_NOTIFICATION_DELAY', sys.float_info.max))
-  if (time.time() - start) < notification_delay:
-    return
-
-  if success:
-    message = 'Build succeeded.'
-  else:
-    message = 'Build failed.'
-  title = build_config
-
-  command = None
-  if HOST_OS == 'macos':
-    # Use AppleScript to display a UI non-modal notification.
-    script = 'display notification  "%s" with title "%s" sound name "Glass"' % (
-      message, title)
-    command = "osascript -e '%s' &" % script
-  elif HOST_OS == 'linux':
-    if success:
-      icon = 'dialog-information'
-    else:
-      icon = 'dialog-error'
-    command = "notify-send -i '%s' '%s' '%s' &" % (icon, message, title)
-  elif HOST_OS == 'win32':
-    if success:
-      icon = 'info'
-    else:
-      icon = 'error'
-    command = ("powershell -command \""
-      "[reflection.assembly]::loadwithpartialname('System.Windows.Forms')"
-        "| Out-Null;"
-      "[reflection.assembly]::loadwithpartialname('System.Drawing')"
-        "| Out-Null;"
-      "$n = new-object system.windows.forms.notifyicon;"
-      "$n.icon = [system.drawing.systemicons]::information;"
-      "$n.visible = $true;"
-      "$n.showballoontip(%d, '%s', '%s', "
-      "[system.windows.forms.tooltipicon]::%s);\"") % (
-        5000, # Notification stays on for this many milliseconds
-        message, title, icon)
-
-  if command:
-    # Ignore return code, if this command fails, it doesn't matter.
-    os.system(command)
-
-
-def RunGN(target_os, mode, arch):
-  gn_os = 'host' if target_os == HOST_OS else target_os
-  gn_command = [
-    'python',
-    os.path.join(DART_ROOT, 'tools', 'gn.py'),
-    '-m', mode,
-    '-a', arch,
-    '--os', gn_os,
-    '-v',
-  ]
-  process = subprocess.Popen(gn_command)
-  process.wait()
-  if process.returncode != 0:
-    print ("Tried to run GN, but it failed. Try running it manually: \n\t$ " +
-           ' '.join(gn_command))
-
-
-def ShouldRunGN(out_dir):
-  return (not os.path.exists(out_dir) or
-          not os.path.isfile(os.path.join(out_dir, 'args.gn')))
-
-
-def UseGoma(out_dir):
-  args_gn = os.path.join(out_dir, 'args.gn')
-  return 'use_goma = true' in open(args_gn, 'r').read()
-
-
-# Try to start goma, but don't bail out if we can't. Instead print an error
-# message, and let the build fail with its own error messages as well.
-goma_started = False
-def EnsureGomaStarted(out_dir):
-  global goma_started
-  if goma_started:
-    return True
-  args_gn_path = os.path.join(out_dir, 'args.gn')
-  goma_dir = None
-  with open(args_gn_path, 'r') as fp:
-    for line in fp:
-      if 'goma_dir' in line:
-        words = line.split()
-        goma_dir = words[2][1:-1]  # goma_dir = "/path/to/goma"
-  if not goma_dir:
-    print 'Could not find goma for ' + out_dir
-    return False
-  if not os.path.exists(goma_dir) or not os.path.isdir(goma_dir):
-    print 'Could not find goma at ' + goma_dir
-    return False
-  goma_ctl = os.path.join(goma_dir, 'goma_ctl.py')
-  goma_ctl_command = [
-    'python',
-    goma_ctl,
-    'ensure_start',
-  ]
-  process = subprocess.Popen(goma_ctl_command)
-  process.wait()
-  if process.returncode != 0:
-    print ("Tried to run goma_ctl.py, but it failed. Try running it manually: "
-           + "\n\t" + ' '.join(goma_ctl_command))
-    return False
-  goma_started = True
-  return True
-
-
-# Returns a tuple (build_config, command to run, whether goma is used)
-def BuildOneConfig(options, targets, target_os, mode, arch):
-  build_config = utils.GetBuildConf(mode, arch, target_os)
-  out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
-  using_goma = False
-  if ShouldRunGN(out_dir):
-    RunGN(target_os, mode, arch)
-  command = ['ninja', '-C', out_dir]
-  if options.verbose:
-    command += ['-v']
-  if UseGoma(out_dir):
-    if options.no_start_goma or EnsureGomaStarted(out_dir):
-      using_goma = True
-      command += [('-j%s' % str(options.j))]
-    else:
-      # If we couldn't ensure that goma is started, let the build start, but
-      # slowly so we can see any helpful error messages that pop out.
-      command += ['-j1']
-  command += targets
-  return (build_config, command, using_goma)
-
-
-def RunOneBuildCommand(build_config, args):
-  start_time = time.time()
-  print ' '.join(args)
-  process = subprocess.Popen(args, stdin=None)
-  process.wait()
-  if process.returncode != 0:
-    NotifyBuildDone(build_config, success=False, start=start_time)
-    return 1
-  else:
-    NotifyBuildDone(build_config, success=True, start=start_time)
-
-  return 0
-
-
-def RunOneGomaBuildCommand(args):
-  try:
-    print ' '.join(args)
-    process = subprocess.Popen(args, stdin=None)
-    process.wait()
-    print (' '.join(args) + " done.")
-    return process.returncode
-  except KeyboardInterrupt:
-    return 1
-
-
-def Main():
-  starttime = time.time()
-  # Parse the options.
-  parser = BuildOptions()
-  (options, args) = parser.parse_args()
-  if not ProcessOptions(options, args):
-    parser.print_help()
-    return 1
-  # Determine which targets to build. By default we build the "all" target.
-  if len(args) == 0:
-    targets = ['all']
-  else:
-    targets = args
-
-  # Build all targets for each requested configuration.
-  configs = []
-  for target_os in options.os:
-    for mode in options.mode:
-      for arch in options.arch:
-        configs.append(BuildOneConfig(options, targets, target_os, mode, arch))
-
-  # Build regular configs.
-  goma_builds = []
-  for (build_config, args, goma) in configs:
-    if args is None:
-      return 1
-    if goma:
-      goma_builds.append(args)
-    elif RunOneBuildCommand(build_config, args) != 0:
-      return 1
-
-  # Run goma builds in parallel.
-  pool = multiprocessing.Pool(multiprocessing.cpu_count())
-  results = pool.map(RunOneGomaBuildCommand, goma_builds, chunksize=1)
-  for r in results:
-    if r != 0:
-      return 1
-
-  endtime = time.time()
-  print ("The build took %.3f seconds" % (endtime - starttime))
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(Main())
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart
index f8dd6fc..53f4002 100644
--- a/tools/patch_sdk.dart
+++ b/tools/patch_sdk.dart
@@ -10,7 +10,7 @@
 import 'dart:isolate' show RawReceivePort;
 import 'dart:async';
 import 'dart:math' as math;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonEncode;
 
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -148,7 +148,7 @@
 
   await _writeSync(
       librariesJson.toFilePath(),
-      JSON.encode({
+      jsonEncode({
         mode: {"libraries": locations}
       }));
 
diff --git a/tools/status_clean.dart b/tools/status_clean.dart
index 1c47633..1606298 100644
--- a/tools/status_clean.dart
+++ b/tools/status_clean.dart
@@ -5,7 +5,7 @@
 library status_clean;
 
 import "dart:async";
-import "dart:convert" show JSON, UTF8;
+import "dart:convert" show json, utf8;
 import "dart:io";
 import "testing/dart/multitest.dart";
 import "testing/dart/status_file_parser.dart";
@@ -388,8 +388,8 @@
         .then((HttpClientRequest request) => request.close())
         .then((HttpClientResponse response) {
       return response
-          .transform(UTF8.decoder)
-          .transform(JSON.decoder)
+          .transform(utf8.decoder)
+          .transform(json.decoder)
           .first
           .then((List testResults) {
         var setOfActualOutcomes = new Set<Expectation>();
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index 17dd98b..7f9adcd 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -5,7 +5,7 @@
 library android;
 
 import "dart:async";
-import "dart:convert" show LineSplitter, UTF8;
+import "dart:convert" show LineSplitter, utf8;
 import "dart:core";
 import "dart:collection";
 import "dart:io";
@@ -46,7 +46,7 @@
     {String stdin, Duration timeout}) {
   Future<String> getOutput(Stream<List<int>> stream) {
     return stream
-        .transform(UTF8.decoder)
+        .transform(utf8.decoder)
         .toList()
         .then((data) => data.join(""));
   }
@@ -130,7 +130,7 @@
 
   AndroidEmulator._private(this._port, this._adbDevice, this._emulatorProcess) {
     Stream<String> getLines(Stream s) {
-      return s.transform(UTF8.decoder).transform(new LineSplitter());
+      return s.transform(utf8.decoder).transform(new LineSplitter());
     }
 
     getLines(_emulatorProcess.stdout).listen((line) {
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index dd66be3..2489eb3 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -206,7 +206,7 @@
       }
 
       stdoutSubscription =
-          process.stdout.transform(UTF8.decoder).listen((data) {
+          process.stdout.transform(utf8.decoder).listen((data) {
         _addStdout(data);
       }, onError: (error) {
         // This should _never_ happen, but we really want this in the log
@@ -215,7 +215,7 @@
       }, onDone: closeStdout);
 
       stderrSubscription =
-          process.stderr.transform(UTF8.decoder).listen((data) {
+          process.stderr.transform(utf8.decoder).listen((data) {
         _addStderr(data);
       }, onError: (error) {
         // This should _never_ happen, but we really want this in the log
@@ -802,7 +802,7 @@
     id = _idCounter++;
   }
 
-  String toJSON() => JSON.encode({'url': url, 'id': id, 'isHtmlTest': false});
+  String toJSON() => jsonEncode({'url': url, 'id': id, 'isHtmlTest': false});
 }
 
 /**
@@ -815,7 +815,7 @@
       this.expectedMessages)
       : super(url, doneCallback, timeout) {}
 
-  String toJSON() => JSON.encode({
+  String toJSON() => jsonEncode({
         'url': url,
         'id': id,
         'isHtmlTest': true,
@@ -1297,7 +1297,7 @@
     errorReportingServer = server;
     void errorReportingHandler(HttpRequest request) {
       StringBuffer buffer = new StringBuffer();
-      request.transform(UTF8.decoder).listen((data) {
+      request.transform(utf8.decoder).listen((data) {
         buffer.write(data);
       }, onDone: () {
         String back = buffer.toString();
@@ -1389,7 +1389,7 @@
   void handleReport(HttpRequest request, String browserId, int testId,
       {bool isStatusUpdate}) {
     StringBuffer buffer = new StringBuffer();
-    request.transform(UTF8.decoder).listen((data) {
+    request.transform(utf8.decoder).listen((data) {
       buffer.write(data);
     }, onDone: () {
       String back = buffer.toString();
@@ -1410,7 +1410,7 @@
     // If an error occurs while receiving the data from the request stream,
     // we don't handle it specially. We can safely ignore it, since the started
     // events are not crucial.
-    request.transform(UTF8.decoder).listen((data) {
+    request.transform(utf8.decoder).listen((data) {
       buffer.write(data);
     }, onDone: () {
       String back = buffer.toString();
diff --git a/tools/testing/dart/command_output.dart b/tools/testing/dart/command_output.dart
index e342522..9700e6c 100644
--- a/tools/testing/dart/command_output.dart
+++ b/tools/testing/dart/command_output.dart
@@ -330,7 +330,7 @@
     }
 
     try {
-      var events = JSON.decode(content);
+      var events = jsonDecode(content);
       if (events != null) {
         validate("Message must be a List", events is List);
 
diff --git a/tools/testing/dart/configuration.dart b/tools/testing/dart/configuration.dart
index 769e0b7..9071636 100644
--- a/tools/testing/dart/configuration.dart
+++ b/tools/testing/dart/configuration.dart
@@ -275,7 +275,7 @@
       try {
         var path = new Path("build/win_toolchain.json").toNativePath();
         var text = new File(path).readAsStringSync();
-        _windowsSdkPath = JSON.decode(text)['win_sdk'] as String;
+        _windowsSdkPath = jsonDecode(text)['win_sdk'] as String;
       } on dynamic {
         // Ignore errors here. If win_sdk is not found, stack trace dumping
         // for timeouts won't work.
diff --git a/tools/testing/dart/html_test.dart b/tools/testing/dart/html_test.dart
index 864a6d2..5c80b01 100644
--- a/tools/testing/dart/html_test.dart
+++ b/tools/testing/dart/html_test.dart
@@ -32,7 +32,7 @@
   var match = htmlAnnotation.firstMatch(contents);
   if (match == null) return null;
 
-  var annotation = JSON.decode(match[1]);
+  var annotation = jsonDecode(match[1]);
   if (annotation is! Map ||
       annotation['expectedMessages'] is! List ||
       annotation['scripts'] is! List) {
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index 0f33e17..b3d0e27 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -164,7 +164,7 @@
           var totalIndex = (result.stdout as String).indexOf('JSON:');
           var report = (result.stdout as String).substring(totalIndex + 5);
 
-          var map = JSON.decode(report) as Map<String, int>;
+          var map = jsonDecode(report) as Map<String, int>;
 
           if (keys == null) {
             keys = map.keys.toList();
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index fb56beb..b3d4c90 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -186,7 +186,7 @@
       _sink = new File(TestUtils.testOutcomeFileName)
           .openWrite(mode: FileMode.APPEND);
     }
-    _sink.write("${JSON.encode(record)}\n");
+    _sink.write("${jsonEncode(record)}\n");
   }
 }
 
@@ -252,7 +252,7 @@
   void allTestsKnown() {
     if (jsonOnly) {
       print("JSON:");
-      print(JSON.encode(summaryReport.values));
+      print(jsonEncode(summaryReport.values));
     } else {
       summaryReport.printReport();
     }
@@ -793,7 +793,7 @@
           new File(path.append(TestUtils.resultLogFileName).toNativePath());
       file.createSync(recursive: true);
       file.writeAsStringSync(
-          JSON.encode({'configurations': configurations, 'results': results}));
+          jsonEncode({'configurations': configurations, 'results': results}));
     }
   }
 }
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index b2d8477..c76168e 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -256,13 +256,13 @@
 
   void _checkUtf8(List<int> data) {
     try {
-      UTF8.decode(data, allowMalformed: false);
+      utf8.decode(data, allowMalformed: false);
     } on FormatException {
       hasNonUtf8 = true;
-      String malformed = UTF8.decode(data, allowMalformed: true);
+      String malformed = utf8.decode(data, allowMalformed: true);
       data
         ..clear()
-        ..addAll(UTF8.encode(malformed))
+        ..addAll(utf8.encode(malformed))
         ..addAll("""
 
   *****************************************************************************
@@ -674,7 +674,7 @@
 
   String _createArgumentsLine(List<String> arguments, int timeout) {
     if (_useJson) {
-      return "${JSON.encode(arguments)}\n";
+      return "${jsonEncode(arguments)}\n";
     } else {
       return arguments.join(' ') + '\n';
     }
@@ -742,7 +742,7 @@
       _process = p;
 
       Stream<String> _stdoutStream =
-          _process.stdout.transform(UTF8.decoder).transform(new LineSplitter());
+          _process.stdout.transform(utf8.decoder).transform(new LineSplitter());
       _stdoutSubscription = _stdoutStream.listen((String line) {
         if (line.startsWith('>>> TEST')) {
           _status = line;
@@ -763,7 +763,7 @@
       _stdoutSubscription.pause();
 
       Stream<String> _stderrStream =
-          _process.stderr.transform(UTF8.decoder).transform(new LineSplitter());
+          _process.stderr.transform(utf8.decoder).transform(new LineSplitter());
       _stderrSubscription = _stderrStream.listen((String line) {
         if (line.startsWith('>>> EOF STDERR')) {
           _stderrSubscription.pause();
@@ -1274,7 +1274,7 @@
       if (result.exitCode != 0) break;
     }
     return createCommandOutput(command, result.exitCode, result.timedOut,
-        UTF8.encode('$writer'), [], stopwatch.elapsed, false);
+        utf8.encode('$writer'), [], stopwatch.elapsed, false);
   }
 
   BatchRunnerProcess _getBatchRunner(String identifier) {
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index 0e458ba..e9c9175 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -181,14 +181,14 @@
 }
 
 List<int> encodeUtf8(String string) {
-  return UTF8.encode(string);
+  return utf8.encode(string);
 }
 
 // TODO(kustermann,ricow): As soon we have a debug log we should log
 // invalid utf8-encoded input to the log.
 // Currently invalid bytes will be replaced by a replacement character.
 String decodeUtf8(List<int> bytes) {
-  return UTF8.decode(bytes, allowMalformed: true);
+  return utf8.decode(bytes, allowMalformed: true);
 }
 
 /// Given a chunk of UTF-8 output, splits it into lines, normalizes carriage
@@ -217,10 +217,10 @@
     return n.toString().padLeft(count, "0");
   }
 
-  var minutes = digits(2, duration.inMinutes, Duration.MINUTES_PER_HOUR);
-  var seconds = digits(2, duration.inSeconds, Duration.SECONDS_PER_MINUTE);
+  var minutes = digits(2, duration.inMinutes, Duration.minutesPerHour);
+  var seconds = digits(2, duration.inSeconds, Duration.secondsPerMinute);
   var millis =
-      digits(6, duration.inMilliseconds, Duration.MILLISECONDS_PER_SECOND);
+      digits(6, duration.inMilliseconds, Duration.millisecondsPerSecond);
 
   if (duration.inHours >= 1) {
     return "${duration.inHours}:${minutes}:${seconds}s";
diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn
index 67415d5..9619512 100644
--- a/utils/dartanalyzer/BUILD.gn
+++ b/utils/dartanalyzer/BUILD.gn
@@ -27,25 +27,11 @@
     rebase_path("../../tests/language/first_test.dart"),
   ]
   name = "dartanalyzer"
-  cli_files = exec_script("../../tools/list_dart_files.py",
-                          [
-                            "absolute",
-                            rebase_path("../../pkg/analyzer_cli"),
-                          ],
-                          "list lines")
-  inputs = cli_files + analyzer_files
 }
 
 aot_assembly("dartanalyzer_aot_assembly") {
   main_dart = "../../pkg/analyzer_cli/bin/analyzer.dart"
   name = "dartanalyzer"
-  cli_files = exec_script("../../tools/list_dart_files.py",
-                          [
-                            "absolute",
-                            rebase_path("../../pkg/analyzer_cli"),
-                          ],
-                          "list lines")
-  inputs = cli_files + analyzer_files
 }
 
 # This target is for Goma. It should not be used in the SDK.
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 6ae3cd9..e9a6160 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -23,7 +23,6 @@
     rebase_path("../../pkg/dev_compiler"),
     "-o",
     "dartdevc.js",
-    "--unsafe-force-compile",
     rebase_path("../../pkg/dev_compiler/bin/dartdevc.dart"),
   ]
 
@@ -31,25 +30,18 @@
     ":dartdevc_sdk",
   ]
 
-  inputs = exec_script("../../tools/list_dart_files.py",
-                       [
-                         "absolute",
-                         rebase_path("../../pkg/dev_compiler/bin"),
-                       ],
-                       "list lines")
-  inputs += [ sdk_summary ]
+  inputs = [ sdk_summary ]
 }
 
 application_snapshot("dartdevk") {
   main_dart = "../../pkg/dev_compiler/bin/dartdevk.dart"
 
-  # TODO(vsm): Train this on real input.
   training_args = [
     "--dart-sdk-summary",
     rebase_path(sdk_dill),
     "-o",
     "dartdevk.js",
-    rebase_path("../../pkg/dev_compiler/test/codegen/sunflower/sunflower.dart"),
+    rebase_path("../../pkg/dev_compiler/bin/dartdevk.dart"),
   ]
 
   deps = [
@@ -57,13 +49,7 @@
     ":dartdevc_sdk_kernel_summary",
   ]
 
-  inputs = exec_script("../../tools/list_dart_files.py",
-                       [
-                         "absolute",
-                         rebase_path("../../pkg/dev_compiler/bin"),
-                       ],
-                       "list lines")
-  inputs += [ sdk_dill ]
+  inputs = [ sdk_dill ]
 }
 
 sdk_lib_files = exec_script("../../tools/list_dart_files.py",
diff --git a/utils/dartdoc/BUILD.gn b/utils/dartdoc/BUILD.gn
index ac302a8..0ba4fe2 100644
--- a/utils/dartdoc/BUILD.gn
+++ b/utils/dartdoc/BUILD.gn
@@ -7,8 +7,4 @@
 application_snapshot("dartdoc") {
   main_dart = "../../third_party/pkg/dartdoc/bin/dartdoc.dart"
   training_args = [ "--help" ]
-  inputs = exec_script("../../tools/list_dart_files.py",
-                       [ "absolute",
-                         rebase_path("../../third_party/pkg/dartdoc") ],
-                       "list lines")
 }
diff --git a/utils/dartfmt/BUILD.gn b/utils/dartfmt/BUILD.gn
index 7c688a3..566475f 100644
--- a/utils/dartfmt/BUILD.gn
+++ b/utils/dartfmt/BUILD.gn
@@ -7,9 +7,4 @@
 application_snapshot("dartfmt") {
   main_dart = "../../third_party/pkg_tested/dart_style/bin/format.dart"
   training_args = [ "--help" ]
-  inputs =
-      exec_script("../../tools/list_dart_files.py",
-                  [ "absolute",
-                    rebase_path("../../third_party/pkg_tested/dart_style") ],
-                  "list lines")
 }
diff --git a/utils/pub/BUILD.gn b/utils/pub/BUILD.gn
index 33cea34..b2f724c 100644
--- a/utils/pub/BUILD.gn
+++ b/utils/pub/BUILD.gn
@@ -7,12 +7,4 @@
 application_snapshot("pub") {
   main_dart = "../../third_party/pkg/pub/bin/pub.dart"
   training_args = [ "--help" ]
-  deps = [
-    "../compiler:dart2js_files_stamp",
-  ]
-  dart2js_gen_dir =
-      get_label_info("../compiler:dart2js_files_stamp", "target_gen_dir")
-  inputs = [
-    "$dart2js_gen_dir/dart2js_files.stamp",
-  ]
 }