[manual roll] update third party packages for latest flutter roll

Change-Id: I4df4dc3c19f0559edf4e49ac6a186dbac62aac1e
diff --git a/bazel_worker/.gitignore b/bazel_worker/.gitignore
deleted file mode 100644
index 00035d7..0000000
--- a/bazel_worker/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.buildlog
-.DS_Store
-.idea
-.pub/
-.settings/
-build/
-packages
-.packages
-pubspec.lock
-.dart_tool
diff --git a/bazel_worker/.travis.yml b/bazel_worker/.travis.yml
deleted file mode 100644
index f21e9b1..0000000
--- a/bazel_worker/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-language: dart
-
-script: ./tool/travis.sh
-
-dart:
-  - dev
-
-# Speed up builds by using containerization. Disable this if you need to use
-# sudo in your scripts.
-sudo: false
-
-branches:
-  only:
-    - master
-
-cache:
-  directories:
-  - $HOME/.pub-cache
diff --git a/bazel_worker/AUTHORS b/bazel_worker/AUTHORS
deleted file mode 100644
index e8063a8..0000000
--- a/bazel_worker/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Below is a list of people and organizations that have contributed
-# to the project. Names should be added to the list like so:
-#
-#   Name/Organization <email address>
-
-Google Inc.
diff --git a/bazel_worker/BUILD.gn b/bazel_worker/BUILD.gn
deleted file mode 100644
index f34a3f5..0000000
--- a/bazel_worker/BUILD.gn
+++ /dev/null
@@ -1,19 +0,0 @@
-# This file is generated by importer.py for bazel_worker-0.1.23+1
-
-import("//build/dart/dart_library.gni")
-
-dart_library("bazel_worker") {
-  package_name = "bazel_worker"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/async",
-    "//third_party/dart-pkg/pub/pedantic",
-    "//third_party/dart-pkg/pub/protobuf",
-  ]
-}
diff --git a/bazel_worker/CHANGELOG.md b/bazel_worker/CHANGELOG.md
deleted file mode 100644
index 6a6fed5..0000000
--- a/bazel_worker/CHANGELOG.md
+++ /dev/null
@@ -1,129 +0,0 @@
-## 0.1.23+1
-
-* Don't rely on `exitCode` to know when a worker terminates, instead wait for
-  the input stream to close.
-  * The SDK may also start throwing instead of returning a `null` here, so this
-    pre-emptively guards against that.
-
-## 0.1.23
-
-* Support protobuf `1.x`.
-* Added a tool for updating generated proto files and updated them
-  using the latest version of the protoc_plugin package.
-  * This required a lower bound bump of the `protobuf` package to `0.14.4`.
-
-## 0.1.22
-
-* Require protobuf 0.14.0.
-
-## 0.1.21
-
-* Make `TestStdinAsync` behave like a `Stream<Uint8List>`
-
-## 0.1.20
-
-* Close worker `outputStream` on `cancel`.
-
-## 0.1.19
-
-* Work around https://github.com/dart-lang/sdk/issues/35874.
-
-## 0.1.18
-
-* Add a `trackWork` optional named argument to `BazelDriver.doWork`. This allows
-  the caller to know when a work request is actually sent to a worker.
-
-## 0.1.17
-
-* Allow protobuf 0.13.0.
-
-## 0.1.16
-
-* Update the worker_protocol.pb.dart file with the latest proto generator.
-* Require protobuf 0.11.0.
-
-## 0.1.15
-
-* Update the worker_protocol.pb.dart file with the latest proto generator.
-* Require protobuf 0.10.4.
-
-## 0.1.14
-
-* Allow workers to support running in isolates. To support running in isolates,
-  workers must modify their `main` method to accept a `SendPort` then use it
-  when creating the `AsyncWorkerConnection`. See `async_worker` in `e2e_test`.
-
-## 0.1.13
-
-* Support protobuf 0.10.0.
-
-## 0.1.12
-
-* Set max SDK version to `<3.0.0`.
-
-## 0.1.11
-
-* Added support for protobuf 0.9.0.
-
-## 0.1.10
-
-* Update the SDK dependency to 2.0.0-dev.17.0.
-* Update to protobuf version 0.8.0
-* Remove usages of deprecated upper-case constants from the SDK.
-
-## 0.1.9
-
-* Update the worker_protocol.pb.dart file with the latest proto generator.
-
-## 0.1.8
-
-* Add `Future cancel()` method to `DriverConnection`, which in the case of a
-  `StdDriverConnection` closes the input stream.
-  * The `terminateWorkers` method on `BazelWorkerDriver` now calls `cancel` on
-    all worker connections to ensure the vm can exit correctly.
-
-## 0.1.7
-
-* Update the `BazelWorkerDriver` class to handle worker crashes, and retry work
-  requests. The number of retries is configurable with the new `int maxRetries`
-  optional arg to the `BazelWorkerDriver` constructor.
-
-## 0.1.6
-
-* Update the worker_protocol.pb.dart file with the latest proto generator.
-* Add support for package:async 2.x and package:protobuf 6.x.
-
-## 0.1.5
-
-* Change TestStdinAsync.controller to StreamController<List<int>> (instead of
-  using dynamic as the type argument).
-
-## 0.1.4
-
-* Added `BazelWorkerDriver` class, which can be used to implement the bazel side
-  of the protocol. This allows you to speak to any process which knows the bazel
-  protocol from your own process.
-* Changed `WorkerConnection#readRequest` to return a `FutureOr<WorkRequest>`
-  instead of dynamic.
-
-## 0.1.3
-
-* Add automatic intercepting of print calls and append them to
-  `response.output`. This makes more libraries work out of the box, as printing
-  would previously cause an error due to communication over stdin/stdout.
-  * Note that using stdin/stdout directly will still cause an error, but that is
-    less common.
-
-## 0.1.2
-
-* Add better handling for the case where stdin gives an error instead of an EOF.
-
-## 0.1.1
-
-* Export `AsyncMessageGrouper` and `SyncMessageGrouper` as part of the testing
-  library. These can assist when writing e2e tests and communicating with a
-  worker process.
-
-## 0.1.0
-
-* Initial version.
diff --git a/bazel_worker/CONTRIBUTING.md b/bazel_worker/CONTRIBUTING.md
deleted file mode 100644
index 6f5e0ea..0000000
--- a/bazel_worker/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-### Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-All submissions, including submissions by project members, require review.
-
-### File headers
-All files in the project must start with the following header.
-
-    // 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.
-
-### The small print
-Contributions made by corporations are covered by a different agreement than the
-one above, the
-[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
diff --git a/bazel_worker/LICENSE b/bazel_worker/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/bazel_worker/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/bazel_worker/README.md b/bazel_worker/README.md
deleted file mode 100644
index 41a6784..0000000
--- a/bazel_worker/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-Tools for creating a persistent worker loop for [bazel](http://bazel.io/).
-
-## Usage
-
-There are two abstract classes provided by this package, `AsyncWorkerLoop` and
-`SyncWorkerLoop`. These each have a `performRequest` method which you must
-implement.
-
-Lets look at a simple example of a `SyncWorkerLoop` implementation:
-
-```dart
-import 'dart:io';
-import 'package:bazel_worker/bazel_worker.dart';
-
-void main() {
-  // Blocks until it gets an EOF from stdin.
-  new SyncSimpleWorker().run();
-}
-
-class SyncSimpleWorker extends SyncWorkerLoop {
-  /// Must synchronously return a [WorkResponse], since this is a
-  /// [SyncWorkerLoop].
-  WorkResponse performRequest(WorkRequest request) {
-    new File('hello.txt').writeAsStringSync('hello world!');
-    return new WorkResponse()..exitCode = EXIT_CODE_OK;
-  }
-}
-```
-
-And now the same thing, implemented as an `AsyncWorkerLoop`:
-
-```dart
-import 'dart:io';
-import 'package:bazel_worker/bazel_worker.dart';
-
-void main() {
-  // Doesn't block, runs tasks async as they are received on stdin.
-  new AsyncSimpleWorker().run();
-}
-
-class AsyncSimpleWorker extends AsyncWorkerLoop {
-  /// Must return a [Future<WorkResponse>], since this is an
-  /// [AsyncWorkerLoop].
-  Future<WorkResponse> performRequest(WorkRequest request) async {
-    await new File('hello.txt').writeAsString('hello world!');
-    return new WorkResponse()..exitCode = EXIT_CODE_OK;
-  }
-}
-```
-
-As you can see, these are nearly identical, it mostly comes down to the
-constraints on your package and personal preference which one you choose to
-implement.
-
-## Testing
-
-A `package:bazel_worker/testing.dart` file is also provided, which can greatly
-assist with writing unit tests for your worker. See the
-`test/worker_loop_test.dart` test included in this package for an example of how
-the helpers can be used.
-
-## Features and bugs
-
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/bazel_worker/issues
diff --git a/bazel_worker/analysis_options.yaml b/bazel_worker/analysis_options.yaml
deleted file mode 100644
index 9781e73..0000000
--- a/bazel_worker/analysis_options.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-include: package:pedantic/analysis_options.yaml
-
-analyzer:
-
-linter:
-  rules:
-    - always_declare_return_types
-    # - annotate_overrides
-    - avoid_empty_else
-    - avoid_init_to_null
-    # - avoid_return_types_on_setters
-    - camel_case_types
-    # - constant_identifier_names
-    - empty_constructor_bodies
-    - hash_and_equals
-    - library_names
-    - library_prefixes
-    # - non_constant_identifier_names
-    - package_api_docs
-    - package_names
-    - package_prefixed_library_names
-    - prefer_is_not_empty
-    - slash_for_doc_comments
-    # - type_annotate_public_apis
-    - type_init_formals
-    - unnecessary_brace_in_string_interps
-    - unnecessary_getters_setters
diff --git a/bazel_worker/e2e_test/bin/async_worker.dart b/bazel_worker/e2e_test/bin/async_worker.dart
deleted file mode 100644
index ddd530c..0000000
--- a/bazel_worker/e2e_test/bin/async_worker.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:isolate';
-
-import 'package:e2e_test/async_worker.dart';
-
-/// This worker can run in one of two ways: normally, using stdin/stdout, or
-/// in an isolate, communicating over a [SendPort].
-Future main(List<String> args, [SendPort sendPort]) async {
-  await ExampleAsyncWorker(sendPort).run();
-}
diff --git a/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart b/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart
deleted file mode 100644
index fce1eff..0000000
--- a/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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:isolate';
-
-import 'package:e2e_test/forwards_to_isolate_async_worker.dart';
-
-/// Wraps the worker provided by `async_worker.dart`, launching it in an
-/// isolate. Requests are forwarded to the isolate and responses are returned
-/// directly from the isolate.
-///
-/// Anyone actually using the facility to wrap a worker in an isolate will want
-/// to use this code to do additional work, for example post processing one of
-/// the output files.
-Future main(List<String> args, SendPort message) async {
-  var receivePort = ReceivePort();
-  await Isolate.spawnUri(
-      Uri.file('async_worker.dart'), [], receivePort.sendPort);
-
-  var worker = await ForwardsToIsolateAsyncWorker.create(receivePort);
-  await worker.run();
-}
diff --git a/bazel_worker/e2e_test/bin/sync_worker.dart b/bazel_worker/e2e_test/bin/sync_worker.dart
deleted file mode 100644
index 9bdcc77..0000000
--- a/bazel_worker/e2e_test/bin/sync_worker.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:e2e_test/sync_worker.dart';
-
-void main() {
-  ExampleSyncWorker().run();
-}
diff --git a/bazel_worker/e2e_test/lib/async_worker.dart b/bazel_worker/e2e_test/lib/async_worker.dart
deleted file mode 100644
index 075a5e6..0000000
--- a/bazel_worker/e2e_test/lib/async_worker.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:isolate';
-
-import 'package:bazel_worker/bazel_worker.dart';
-
-/// Example worker that just returns in its response all the arguments passed
-/// separated by newlines.
-class ExampleAsyncWorker extends AsyncWorkerLoop {
-  /// Set [sendPort] to run in an isolate.
-  ExampleAsyncWorker([SendPort sendPort])
-      : super(connection: AsyncWorkerConnection(sendPort: sendPort));
-
-  @override
-  Future<WorkResponse> performRequest(WorkRequest request) async {
-    return WorkResponse()
-      ..exitCode = 0
-      ..output = request.arguments.join('\n');
-  }
-}
diff --git a/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart b/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart
deleted file mode 100644
index bb937b2..0000000
--- a/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:isolate';
-
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:bazel_worker/driver.dart';
-
-/// Example worker that just forwards requests to an isolate.
-class ForwardsToIsolateAsyncWorker extends AsyncWorkerLoop {
-  final IsolateDriverConnection _isolateDriverConnection;
-
-  static Future<ForwardsToIsolateAsyncWorker> create(
-      ReceivePort receivePort) async {
-    return ForwardsToIsolateAsyncWorker(
-        await IsolateDriverConnection.create(receivePort));
-  }
-
-  ForwardsToIsolateAsyncWorker(this._isolateDriverConnection);
-
-  @override
-  Future<WorkResponse> performRequest(WorkRequest request) {
-    _isolateDriverConnection.writeRequest(request);
-    return _isolateDriverConnection.readResponse();
-  }
-}
diff --git a/bazel_worker/e2e_test/lib/sync_worker.dart b/bazel_worker/e2e_test/lib/sync_worker.dart
deleted file mode 100644
index 789f780..0000000
--- a/bazel_worker/e2e_test/lib/sync_worker.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:bazel_worker/bazel_worker.dart';
-
-/// Example worker that just returns in its response all the arguments passed
-/// separated by newlines.
-class ExampleSyncWorker extends SyncWorkerLoop {
-  @override
-  WorkResponse performRequest(WorkRequest request) {
-    return WorkResponse()
-      ..exitCode = 0
-      ..output = request.arguments.join('\n');
-  }
-}
diff --git a/bazel_worker/e2e_test/pubspec.yaml b/bazel_worker/e2e_test/pubspec.yaml
deleted file mode 100644
index d9c3577..0000000
--- a/bazel_worker/e2e_test/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: e2e_test
-dependencies:
-  bazel_worker:
-    path: ../
-dev_dependencies:
-  cli_util: ^0.1.0
-  path: ^1.4.1
-  test: ^1.0.0
-environment:
-  sdk: '>=2.0.0 <3.0.0'
diff --git a/bazel_worker/e2e_test/test/e2e_test.dart b/bazel_worker/e2e_test/test/e2e_test.dart
deleted file mode 100644
index faae0d3..0000000
--- a/bazel_worker/e2e_test/test/e2e_test.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:bazel_worker/driver.dart';
-import 'package:cli_util/cli_util.dart';
-import 'package:path/path.dart' as p;
-import 'package:test/test.dart';
-
-void main() {
-  var sdkPath = getSdkPath();
-  var dart = p.join(sdkPath, 'bin', 'dart');
-  runE2eTestForWorker('sync worker',
-      () => Process.start(dart, [p.join('bin', 'sync_worker.dart')]));
-  runE2eTestForWorker('async worker',
-      () => Process.start(dart, [p.join('bin', 'async_worker.dart')]));
-  runE2eTestForWorker(
-      'async worker in isolate',
-      () =>
-          Process.start(dart, [p.join('bin', 'async_worker_in_isolate.dart')]));
-}
-
-void runE2eTestForWorker(String groupName, SpawnWorker spawnWorker) {
-  BazelWorkerDriver driver;
-  group(groupName, () {
-    setUp(() {
-      driver = BazelWorkerDriver(spawnWorker);
-    });
-
-    tearDown(() async {
-      await driver.terminateWorkers();
-    });
-
-    test('single work request', () async {
-      await _doRequests(driver, count: 1);
-    });
-
-    test('lots of requests', () async {
-      await _doRequests(driver, count: 1000);
-    });
-  });
-}
-
-/// Runs [count] work requests through [driver], and asserts that they all
-/// completed with the correct response.
-Future _doRequests(BazelWorkerDriver driver, {int count}) async {
-  count ??= 100;
-  var requests = List.generate(count, (requestNum) {
-    var request = WorkRequest();
-    request.arguments.addAll(List.generate(requestNum, (argNum) => '$argNum'));
-    return request;
-  });
-  var responses = await Future.wait(requests.map(driver.doWork));
-  for (var i = 0; i < responses.length; i++) {
-    var request = requests[i];
-    var response = responses[i];
-    expect(response.exitCode, EXIT_CODE_OK);
-    expect(response.output, request.arguments.join('\n'));
-  }
-}
diff --git a/bazel_worker/lib/bazel_worker.dart b/bazel_worker/lib/bazel_worker.dart
deleted file mode 100644
index 0b00408..0000000
--- a/bazel_worker/lib/bazel_worker.dart
+++ /dev/null
@@ -1,11 +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.
-
-export 'src/worker/async_worker_loop.dart';
-export 'src/constants.dart';
-export 'src/message_grouper.dart';
-export 'src/worker/sync_worker_loop.dart';
-export 'src/worker/worker_connection.dart';
-export 'src/worker/worker_loop.dart';
-export 'src/worker_protocol.pb.dart';
diff --git a/bazel_worker/lib/driver.dart b/bazel_worker/lib/driver.dart
deleted file mode 100644
index 7453491..0000000
--- a/bazel_worker/lib/driver.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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.
-
-export 'src/driver/driver.dart';
-export 'src/driver/driver_connection.dart';
-export 'src/constants.dart';
-export 'src/message_grouper.dart';
-export 'src/worker_protocol.pb.dart';
diff --git a/bazel_worker/lib/src/async_message_grouper.dart b/bazel_worker/lib/src/async_message_grouper.dart
deleted file mode 100644
index 310a7f9..0000000
--- a/bazel_worker/lib/src/async_message_grouper.dart
+++ /dev/null
@@ -1,66 +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:collection';
-
-import 'package:async/async.dart';
-import 'package:pedantic/pedantic.dart';
-
-import 'message_grouper.dart';
-import 'message_grouper_state.dart';
-
-/// Collects stream data into messages by interpreting it as
-/// base-128 encoded lengths interleaved with raw data.
-class AsyncMessageGrouper implements MessageGrouper {
-  /// Current state for reading in messages;
-  final _state = MessageGrouperState();
-
-  /// The input stream.
-  final StreamQueue<List<int>> _inputQueue;
-
-  /// The current buffer.
-  final Queue<int> _buffer = Queue<int>();
-
-  /// Completes after [cancel] is called or [inputStream] is closed.
-  Future<void> get done => _done.future;
-  final _done = Completer<void>();
-
-  AsyncMessageGrouper(Stream<List<int>> inputStream)
-      : _inputQueue = StreamQueue(inputStream);
-
-  /// Returns the next full message that is received, or null if none are left.
-  @override
-  Future<List<int>> get next async {
-    try {
-      List<int> message;
-      while (message == null &&
-          (_buffer.isNotEmpty || await _inputQueue.hasNext)) {
-        if (_buffer.isEmpty) _buffer.addAll(await _inputQueue.next);
-        var nextByte = _buffer.removeFirst();
-        if (nextByte == -1) return null;
-        message = _state.handleInput(nextByte);
-      }
-
-      // If there is nothing left in the queue then cancel the subscription.
-      if (message == null) unawaited(cancel());
-
-      return message;
-    } catch (e) {
-      // It appears we sometimes get an exception instead of -1 as expected when
-      // stdin closes, this handles that in the same way (returning a null
-      // message)
-      return null;
-    }
-  }
-
-  /// Stop listening to the stream for further updates.
-  Future cancel() {
-    if (!_done.isCompleted) {
-      _done.complete(null);
-      return _inputQueue.cancel();
-    }
-    return done;
-  }
-}
diff --git a/bazel_worker/lib/src/constants.dart b/bazel_worker/lib/src/constants.dart
deleted file mode 100644
index 30113d3..0000000
--- a/bazel_worker/lib/src/constants.dart
+++ /dev/null
@@ -1,6 +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.
-
-const int EXIT_CODE_OK = 0;
-const int EXIT_CODE_ERROR = 15;
diff --git a/bazel_worker/lib/src/driver/driver.dart b/bazel_worker/lib/src/driver/driver.dart
deleted file mode 100644
index 16cbc96..0000000
--- a/bazel_worker/lib/src/driver/driver.dart
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:io';
-
-import '../constants.dart';
-import '../worker_protocol.pb.dart';
-import 'driver_connection.dart';
-
-typedef SpawnWorker = Future<Process> Function();
-
-/// A driver for talking to a bazel worker.
-///
-/// This allows you to use any binary that supports the bazel worker protocol in
-/// the same way that bazel would, but from another dart process instead.
-class BazelWorkerDriver {
-  /// Idle worker processes.
-  final _idleWorkers = <Process>[];
-
-  /// The maximum number of idle workers at any given time.
-  final int _maxIdleWorkers;
-
-  /// The maximum number of times to retry a [WorkAttempt] if there is an error.
-  final int _maxRetries;
-
-  /// The maximum number of concurrent workers to run at any given time.
-  final int _maxWorkers;
-
-  /// The number of currently active workers.
-  int get _numWorkers => _readyWorkers.length + _spawningWorkers.length;
-
-  /// All workers that are fully spawned and ready to handle work.
-  final _readyWorkers = <Process>[];
-
-  /// All workers that are in the process of being spawned.
-  final _spawningWorkers = <Future<Process>>[];
-
-  /// Work requests that haven't been started yet.
-  final _workQueue = Queue<_WorkAttempt>();
-
-  /// Factory method that spawns a worker process.
-  final SpawnWorker _spawnWorker;
-
-  BazelWorkerDriver(this._spawnWorker,
-      {int maxIdleWorkers, int maxWorkers, int maxRetries})
-      : _maxIdleWorkers = maxIdleWorkers ?? 4,
-        _maxWorkers = maxWorkers ?? 4,
-        _maxRetries = maxRetries ?? 4;
-
-  /// Waits for an available worker, and then sends [WorkRequest] to it.
-  ///
-  /// If [trackWork] is provided it will be invoked with a [Future] once the
-  /// [request] has been actually sent to the worker. This allows the caller
-  /// to determine when actual work is being done versus just waiting for an
-  /// available worker.
-  Future<WorkResponse> doWork(WorkRequest request,
-      {Function(Future<WorkResponse>) trackWork}) {
-    var attempt = _WorkAttempt(request, trackWork: trackWork);
-    _workQueue.add(attempt);
-    _runWorkQueue();
-    return attempt.response;
-  }
-
-  /// Calls `kill` on all worker processes.
-  Future terminateWorkers() async {
-    for (var worker in _readyWorkers.toList()) {
-      _killWorker(worker);
-    }
-    await Future.wait(_spawningWorkers.map((worker) async {
-      _killWorker(await worker);
-    }));
-  }
-
-  /// Runs as many items in [_workQueue] as possible given the number of
-  /// available workers.
-  ///
-  /// Will spawn additional workers until [_maxWorkers] has been reached.
-  ///
-  /// This method synchronously drains the [_workQueue] and [_idleWorkers], but
-  /// some tasks may not actually start right away if they need to wait for a
-  /// worker to spin up.
-  void _runWorkQueue() {
-    // Bail out conditions, we will continue to call ourselves indefinitely
-    // until one of these is met.
-    if (_workQueue.isEmpty) return;
-    if (_numWorkers == _maxWorkers && _idleWorkers.isEmpty) return;
-    if (_numWorkers > _maxWorkers) {
-      throw StateError('Internal error, created to many workers. Please '
-          'file a bug at https://github.com/dart-lang/bazel_worker/issues/new');
-    }
-
-    // At this point we definitely want to run a task, we just need to decide
-    // whether or not we need to start up a new worker.
-    var attempt = _workQueue.removeFirst();
-    if (_idleWorkers.isNotEmpty) {
-      _runWorker(_idleWorkers.removeLast(), attempt);
-    } else {
-      // No need to block here, we want to continue to synchronously drain the
-      // work queue.
-      var futureWorker = _spawnWorker();
-      _spawningWorkers.add(futureWorker);
-      futureWorker.then((worker) {
-        _spawningWorkers.remove(futureWorker);
-        _readyWorkers.add(worker);
-
-        var connection = StdDriverConnection.forWorker(worker);
-        _workerConnections[worker] = connection;
-        _runWorker(worker, attempt);
-
-        // When the worker exits we should retry running the work queue in case
-        // there is more work to be done. This is primarily just a defensive
-        // thing but is cheap to do.
-        //
-        // We don't use `exitCode` because it is null for detached processes (
-        // which is common for workers).
-        connection.done.then((_) {
-          _idleWorkers.remove(worker);
-          _readyWorkers.remove(worker);
-          _runWorkQueue();
-        });
-      });
-    }
-    // Recursively calls itself until one of the bail out conditions are met.
-    _runWorkQueue();
-  }
-
-  /// Sends [request] to [worker].
-  ///
-  /// Once the worker responds then it will be added back to the pool of idle
-  /// workers.
-  void _runWorker(Process worker, _WorkAttempt attempt) {
-    var rescheduled = false;
-
-    runZoned(() async {
-      var connection = _workerConnections[worker];
-
-      connection.writeRequest(attempt.request);
-      var responseFuture = connection.readResponse();
-      if (attempt.trackWork != null) {
-        attempt.trackWork(responseFuture);
-      }
-      var response = await responseFuture;
-
-      // It is possible for us to complete with an error response due to an
-      // unhandled async error before we get here.
-      if (!attempt.responseCompleter.isCompleted) {
-        if (response == null) {
-          rescheduled = _tryReschedule(attempt);
-          if (rescheduled) return;
-          stderr.writeln('Failed to run request ${attempt.request}');
-          response = WorkResponse()
-            ..exitCode = EXIT_CODE_ERROR
-            ..output =
-                'Invalid response from worker, this probably means it wrote '
-                    'invalid output or died.';
-        }
-        attempt.responseCompleter.complete(response);
-        _cleanUp(worker);
-      }
-    }, onError: (e, s) {
-      // Note that we don't need to do additional cleanup here on failures. If
-      // the worker dies that is already handled in a generic fashion, we just
-      // need to make sure we complete with a valid response.
-      if (!attempt.responseCompleter.isCompleted) {
-        rescheduled = _tryReschedule(attempt);
-        if (rescheduled) return;
-        var response = WorkResponse()
-          ..exitCode = EXIT_CODE_ERROR
-          ..output = 'Error running worker:\n$e\n$s';
-        attempt.responseCompleter.complete(response);
-        _cleanUp(worker);
-      }
-    });
-  }
-
-  /// Performs post-work cleanup for [worker].
-  void _cleanUp(Process worker) {
-    // If the worker crashes, it won't be in `_readyWorkers` any more, and
-    // we don't want to add it to _idleWorkers.
-    if (_readyWorkers.contains(worker)) {
-      _idleWorkers.add(worker);
-    }
-
-    // Do additional work if available.
-    _runWorkQueue();
-
-    // If the worker wasn't immediately used we might have to many idle
-    // workers now, kill one if necessary.
-    if (_idleWorkers.length > _maxIdleWorkers) {
-      // Note that whenever we spawn a worker we listen for its exit code
-      // and clean it up so we don't need to do that here.
-      var worker = _idleWorkers.removeLast();
-      _killWorker(worker);
-    }
-  }
-
-  /// Attempts to reschedule a failed [attempt].
-  ///
-  /// Returns whether or not the job was successfully rescheduled.
-  bool _tryReschedule(_WorkAttempt attempt) {
-    if (attempt.timesRetried >= _maxRetries) return false;
-    stderr.writeln('Rescheduling failed request...');
-    attempt.timesRetried++;
-    _workQueue.add(attempt);
-    _runWorkQueue();
-    return true;
-  }
-
-  void _killWorker(Process worker) {
-    _workerConnections[worker].cancel();
-    _readyWorkers.remove(worker);
-    _idleWorkers.remove(worker);
-    worker.kill();
-  }
-}
-
-/// Encapsulates an attempt to fulfill a [WorkRequest], a completer for the
-/// [WorkResponse], and the number of times it has been retried.
-class _WorkAttempt {
-  final WorkRequest request;
-  final responseCompleter = Completer<WorkResponse>();
-  final Function(Future<WorkResponse>) trackWork;
-
-  Future<WorkResponse> get response => responseCompleter.future;
-
-  int timesRetried = 0;
-
-  _WorkAttempt(this.request, {this.trackWork});
-}
-
-final _workerConnections = Expando<DriverConnection>('connection');
diff --git a/bazel_worker/lib/src/driver/driver_connection.dart b/bazel_worker/lib/src/driver/driver_connection.dart
deleted file mode 100644
index b282aec..0000000
--- a/bazel_worker/lib/src/driver/driver_connection.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:isolate';
-
-import '../async_message_grouper.dart';
-import '../worker_protocol.pb.dart';
-import '../constants.dart';
-import '../utils.dart';
-
-/// A connection from a `BazelWorkerDriver` to a worker.
-///
-/// Unlike `WorkerConnection` there is no synchronous version of this class.
-/// This is because drivers talk to multiple workers, so they should never block
-/// when waiting for the response of any individual worker.
-abstract class DriverConnection {
-  Future<WorkResponse> readResponse();
-
-  void writeRequest(WorkRequest request);
-
-  Future cancel();
-}
-
-/// Default implementation of [DriverConnection] that works with [Stdin]
-/// and [Stdout].
-class StdDriverConnection implements DriverConnection {
-  final AsyncMessageGrouper _messageGrouper;
-  final StreamSink<List<int>> _outputStream;
-
-  Future<void> get done => _messageGrouper.done;
-
-  StdDriverConnection(
-      {Stream<List<int>> inputStream, StreamSink<List<int>> outputStream})
-      : _messageGrouper = AsyncMessageGrouper(inputStream ?? stdin),
-        _outputStream = outputStream ?? stdout;
-
-  factory StdDriverConnection.forWorker(Process worker) => StdDriverConnection(
-      inputStream: worker.stdout, outputStream: worker.stdin);
-
-  /// Note: This will attempts to recover from invalid proto messages by parsing
-  /// them as strings. This is a common error case for workers (they print a
-  /// message to stdout on accident). This isn't perfect however as it only
-  /// happens if the parsing throws, you can still hang indefinitely if the
-  /// [MessageGrouper] doesn't find what it thinks is the end of a proto
-  /// message.
-  @override
-  Future<WorkResponse> readResponse() async {
-    var buffer = await _messageGrouper.next;
-    if (buffer == null) return null;
-
-    WorkResponse response;
-    try {
-      response = WorkResponse.fromBuffer(buffer);
-    } catch (_) {
-      try {
-        // Try parsing the message as a string and set that as the output.
-        var output = utf8.decode(buffer);
-        var response = WorkResponse()
-          ..exitCode = EXIT_CODE_ERROR
-          ..output = 'Worker sent an invalid response:\n$output';
-        return response;
-      } catch (_) {
-        // Fall back to original exception and rethrow if we fail to parse as
-        // a string.
-      }
-      rethrow;
-    }
-    return response;
-  }
-
-  @override
-  void writeRequest(WorkRequest request) {
-    _outputStream.add(protoToDelimitedBuffer(request));
-  }
-
-  @override
-  Future cancel() async {
-    await _outputStream.close();
-    await _messageGrouper.cancel();
-  }
-}
-
-/// [DriverConnection] that works with an isolate via a [SendPort].
-class IsolateDriverConnection implements DriverConnection {
-  final StreamIterator _receivePortIterator;
-  final SendPort _sendPort;
-
-  IsolateDriverConnection._(this._receivePortIterator, this._sendPort);
-
-  /// Creates a driver connection for a worker in an isolate. Provide the
-  /// [receivePort] attached to the [SendPort] that the isolate was created
-  /// with.
-  static Future<IsolateDriverConnection> create(ReceivePort receivePort) async {
-    var receivePortIterator = StreamIterator(receivePort);
-    await receivePortIterator.moveNext();
-    var sendPort = receivePortIterator.current as SendPort;
-    return IsolateDriverConnection._(receivePortIterator, sendPort);
-  }
-
-  @override
-  Future<WorkResponse> readResponse() async {
-    await _receivePortIterator.moveNext();
-    return WorkResponse.fromBuffer(_receivePortIterator.current as List<int>);
-  }
-
-  @override
-  void writeRequest(WorkRequest request) {
-    _sendPort.send(request.writeToBuffer());
-  }
-
-  @override
-  Future cancel() async {}
-}
diff --git a/bazel_worker/lib/src/message_grouper.dart b/bazel_worker/lib/src/message_grouper.dart
deleted file mode 100644
index 635983e..0000000
--- a/bazel_worker/lib/src/message_grouper.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.
-
-/// Interface for a [MessageGrouper], which groups bytes in  delimited proto
-/// format into the bytes for each message.
-///
-/// This interface should not generally be implemented directly, instead use
-/// the [SyncMessageGrouper] or [AsyncMessageGrouper] implementations.
-abstract class MessageGrouper {
-  /// Returns either a [List<int>] or a [Future<List<int>>].
-  dynamic get next;
-}
diff --git a/bazel_worker/lib/src/message_grouper_state.dart b/bazel_worker/lib/src/message_grouper_state.dart
deleted file mode 100644
index 5cbf933..0000000
--- a/bazel_worker/lib/src/message_grouper_state.dart
+++ /dev/null
@@ -1,126 +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:typed_data';
-
-import 'package:protobuf/protobuf.dart';
-
-/// State held by the [MessageGrouper] while waiting for additional data to
-/// arrive.
-class MessageGrouperState {
-  /// Reads the initial length.
-  _LengthReader _lengthReader;
-
-  /// Reads messages from a stream of bytes.
-  _MessageReader _messageReader;
-
-  MessageGrouperState() {
-    reset();
-  }
-
-  /// Handle one byte at a time.
-  ///
-  /// Returns a [List<int>] of message bytes if [byte] was the last byte in a
-  /// message, otherwise returns [null].
-  List<int> handleInput(int byte) {
-    if (!_lengthReader.done) {
-      _lengthReader.readByte(byte);
-      if (_lengthReader.done) {
-        _messageReader = _MessageReader(_lengthReader.length);
-      }
-    } else {
-      assert(_messageReader != null);
-      _messageReader.readByte(byte);
-    }
-
-    if (_lengthReader.done && _messageReader.done) {
-      var message = _messageReader.message;
-      reset();
-      return message;
-    }
-
-    return null;
-  }
-
-  /// Reset the state so that we are ready to receive the next message.
-  void reset() {
-    _lengthReader = _LengthReader();
-    _messageReader = null;
-  }
-}
-
-/// Reads a length one byte at a time.
-///
-/// The base-128 encoding is in little-endian order, with the high bit set on
-/// all bytes but the last.  This was chosen since it's the same as the
-/// base-128 encoding used by protobufs, so it allows a modest amount of code
-/// reuse at the other end of the protocol.
-class _LengthReader {
-  /// Whether or not we are done reading the length.
-  bool get done => _done;
-  bool _done = false;
-
-  /// If [_done] is `true`, the decoded value of the length bytes received so
-  /// far (if any).  If [_done] is `false`, the decoded length that was most
-  /// recently received.
-  int _length;
-
-  /// The length read in.  You are only allowed to read this if [_done] is
-  /// `true`.
-  int get length {
-    assert(_done);
-    return _length;
-  }
-
-  final List<int> _buffer = <int>[];
-
-  /// Read a single byte into [_length].
-  void readByte(int byte) {
-    assert(!_done);
-    _buffer.add(byte);
-
-    // Check for the last byte in the length, and then read it.
-    if ((byte & 0x80) == 0) {
-      _done = true;
-      var reader = CodedBufferReader(_buffer);
-      _length = reader.readInt32();
-    }
-  }
-}
-
-/// Reads some number of bytes from a stream, one byte at a time.
-class _MessageReader {
-  /// Whether or not we are done reading bytes from the stream.
-  bool get done => _done;
-  bool _done;
-
-  /// The total length of the message to be read.
-  final int _length;
-
-  /// A [Uint8List] which holds the message data. You are only allowed to read
-  /// this if [_done] is `true`.
-  Uint8List get message {
-    assert(_done);
-    return _message;
-  }
-
-  final Uint8List _message;
-
-  /// If [_done] is `false`, the number of message bytes that have been received
-  /// so far.  Otherwise zero.
-  int _numMessageBytesReceived = 0;
-
-  _MessageReader(int length)
-      : _message = Uint8List(length),
-        _length = length,
-        _done = length == 0;
-
-  /// Reads [byte] into [_message].
-  void readByte(int byte) {
-    assert(!done);
-
-    _message[_numMessageBytesReceived++] = byte;
-    if (_numMessageBytesReceived == _length) _done = true;
-  }
-}
diff --git a/bazel_worker/lib/src/sync_message_grouper.dart b/bazel_worker/lib/src/sync_message_grouper.dart
deleted file mode 100644
index c0d11f0..0000000
--- a/bazel_worker/lib/src/sync_message_grouper.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.
-
-import 'dart:io';
-
-import 'message_grouper.dart';
-import 'message_grouper_state.dart';
-
-/// Groups bytes in delimited proto format into the bytes for each message.
-class SyncMessageGrouper implements MessageGrouper {
-  final _state = MessageGrouperState();
-  final Stdin _stdin;
-
-  SyncMessageGrouper(this._stdin);
-
-  /// Blocks until the next full message is received, and then returns it.
-  ///
-  /// Returns null at end of file.
-  @override
-  List<int> get next {
-    try {
-      List<int> message;
-      while (message == null) {
-        var nextByte = _stdin.readByteSync();
-        if (nextByte == -1) return null;
-        message = _state.handleInput(nextByte);
-      }
-      return message;
-    } catch (e) {
-      // It appears we sometimes get an exception instead of -1 as expected when
-      // stdin closes, this handles that in the same way (returning a null
-      // message)
-      return null;
-    }
-  }
-}
diff --git a/bazel_worker/lib/src/utils.dart b/bazel_worker/lib/src/utils.dart
deleted file mode 100644
index 609b435..0000000
--- a/bazel_worker/lib/src/utils.dart
+++ /dev/null
@@ -1,23 +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:typed_data';
-
-import 'package:protobuf/protobuf.dart';
-
-List<int> protoToDelimitedBuffer(GeneratedMessage message) {
-  var messageBuffer = CodedBufferWriter();
-  message.writeToCodedBufferWriter(messageBuffer);
-
-  var delimiterBuffer = CodedBufferWriter();
-  delimiterBuffer.writeInt32NoTag(messageBuffer.lengthInBytes);
-
-  var result =
-      Uint8List(messageBuffer.lengthInBytes + delimiterBuffer.lengthInBytes);
-
-  delimiterBuffer.writeTo(result);
-  messageBuffer.writeTo(result, delimiterBuffer.lengthInBytes);
-
-  return result;
-}
diff --git a/bazel_worker/lib/src/worker/async_worker_loop.dart b/bazel_worker/lib/src/worker/async_worker_loop.dart
deleted file mode 100644
index 9405c4f..0000000
--- a/bazel_worker/lib/src/worker/async_worker_loop.dart
+++ /dev/null
@@ -1,55 +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 '../constants.dart';
-import '../worker_protocol.pb.dart';
-import 'worker_connection.dart';
-import 'worker_loop.dart';
-
-/// Persistent Bazel worker loop.
-///
-/// Extend this class and implement the `performRequest` method.
-abstract class AsyncWorkerLoop implements WorkerLoop {
-  final AsyncWorkerConnection connection;
-
-  AsyncWorkerLoop({AsyncWorkerConnection connection})
-      : connection = connection ?? StdAsyncWorkerConnection();
-
-  /// Perform a single [WorkRequest], and return a [WorkResponse].
-  @override
-  Future<WorkResponse> performRequest(WorkRequest request);
-
-  /// Run the worker loop. The returned [Future] doesn't complete until
-  /// [connection#readRequest] returns `null`.
-  @override
-  Future run() async {
-    while (true) {
-      WorkResponse response;
-      try {
-        var request = await connection.readRequest();
-        if (request == null) break;
-        var printMessages = StringBuffer();
-        response = await runZoned(() => performRequest(request),
-            zoneSpecification:
-                ZoneSpecification(print: (self, parent, zone, message) {
-          printMessages.writeln();
-          printMessages.write(message);
-        }));
-        if (printMessages.isNotEmpty) {
-          response.output = '${response.output}$printMessages';
-        }
-        // In case they forget to set this.
-        response.exitCode ??= EXIT_CODE_OK;
-      } catch (e, s) {
-        response = WorkResponse()
-          ..exitCode = EXIT_CODE_ERROR
-          ..output = '$e\n$s';
-      }
-
-      connection.writeResponse(response);
-    }
-  }
-}
diff --git a/bazel_worker/lib/src/worker/sync_worker_loop.dart b/bazel_worker/lib/src/worker/sync_worker_loop.dart
deleted file mode 100644
index 2d287b0..0000000
--- a/bazel_worker/lib/src/worker/sync_worker_loop.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.
-import 'dart:async';
-
-import '../constants.dart';
-import '../worker_protocol.pb.dart';
-import 'worker_connection.dart';
-import 'worker_loop.dart';
-
-/// Persistent Bazel worker loop.
-///
-/// Extend this class and implement the `performRequest` method.
-abstract class SyncWorkerLoop implements WorkerLoop {
-  final SyncWorkerConnection connection;
-
-  SyncWorkerLoop({SyncWorkerConnection connection})
-      : connection = connection ?? StdSyncWorkerConnection();
-
-  /// Perform a single [WorkRequest], and return a [WorkResponse].
-  @override
-  WorkResponse performRequest(WorkRequest request);
-
-  /// Run the worker loop. Blocks until [connection#readRequest] returns `null`.
-  @override
-  void run() {
-    while (true) {
-      WorkResponse response;
-      try {
-        var request = connection.readRequest();
-        if (request == null) break;
-        var printMessages = StringBuffer();
-        response = runZoned(() => performRequest(request), zoneSpecification:
-            ZoneSpecification(print: (self, parent, zone, message) {
-          printMessages.writeln();
-          printMessages.write(message);
-        }));
-        if (printMessages.isNotEmpty) {
-          response.output = '${response.output}$printMessages';
-        }
-        // In case they forget to set this.
-        response.exitCode ??= EXIT_CODE_OK;
-      } catch (e, s) {
-        response = WorkResponse()
-          ..exitCode = EXIT_CODE_ERROR
-          ..output = '$e\n$s';
-      }
-
-      connection.writeResponse(response);
-    }
-  }
-}
diff --git a/bazel_worker/lib/src/worker/worker_connection.dart b/bazel_worker/lib/src/worker/worker_connection.dart
deleted file mode 100644
index a429cfe..0000000
--- a/bazel_worker/lib/src/worker/worker_connection.dart
+++ /dev/null
@@ -1,124 +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:isolate';
-import 'dart:typed_data';
-
-import '../async_message_grouper.dart';
-import '../sync_message_grouper.dart';
-import '../utils.dart';
-import '../worker_protocol.pb.dart';
-
-/// A connection from a worker to a driver (driver could be bazel, a dart
-/// program using `BazelWorkerDriver`, or any other process that speaks the
-/// protocol).
-abstract class WorkerConnection {
-  /// Reads a [WorkRequest] or returns [null] if there are none left.
-  ///
-  /// See [AsyncWorkerConnection] and [SyncWorkerConnection] for more narrow
-  /// interfaces.
-  FutureOr<WorkRequest> readRequest();
-
-  void writeResponse(WorkResponse response);
-}
-
-abstract class AsyncWorkerConnection implements WorkerConnection {
-  /// Creates a [StdAsyncWorkerConnection] with the specified [inputStream]
-  /// and [outputStream], unless [sendPort] is specified, in which case
-  /// creates a [SendPortAsyncWorkerConnection].
-  factory AsyncWorkerConnection(
-          {Stream<List<int>> inputStream,
-          StreamSink<List<int>> outputStream,
-          SendPort sendPort}) =>
-      sendPort == null
-          ? StdAsyncWorkerConnection(
-              inputStream: inputStream, outputStream: outputStream)
-          : SendPortAsyncWorkerConnection(sendPort);
-
-  @override
-  Future<WorkRequest> readRequest();
-}
-
-abstract class SyncWorkerConnection implements WorkerConnection {
-  @override
-  WorkRequest readRequest();
-}
-
-/// Default implementation of [AsyncWorkerConnection] that works with [Stdin]
-/// and [Stdout].
-class StdAsyncWorkerConnection implements AsyncWorkerConnection {
-  final AsyncMessageGrouper _messageGrouper;
-  final StreamSink<List<int>> _outputStream;
-
-  StdAsyncWorkerConnection(
-      {Stream<List<int>> inputStream, StreamSink<List<int>> outputStream})
-      : _messageGrouper = AsyncMessageGrouper(inputStream ?? stdin),
-        _outputStream = outputStream ?? stdout;
-
-  @override
-  Future<WorkRequest> readRequest() async {
-    var buffer = await _messageGrouper.next;
-    if (buffer == null) return null;
-
-    return WorkRequest.fromBuffer(buffer);
-  }
-
-  @override
-  void writeResponse(WorkResponse response) {
-    _outputStream.add(protoToDelimitedBuffer(response));
-  }
-}
-
-/// Implementation of [AsyncWorkerConnection] for running in an isolate.
-class SendPortAsyncWorkerConnection implements AsyncWorkerConnection {
-  final ReceivePort receivePort;
-  final StreamIterator<Uint8List> receivePortIterator;
-  final SendPort sendPort;
-
-  factory SendPortAsyncWorkerConnection(SendPort sendPort) {
-    var receivePort = ReceivePort();
-    sendPort.send(receivePort.sendPort);
-    return SendPortAsyncWorkerConnection._(receivePort, sendPort);
-  }
-
-  SendPortAsyncWorkerConnection._(this.receivePort, this.sendPort)
-      : receivePortIterator = StreamIterator(receivePort.cast());
-
-  @override
-  Future<WorkRequest> readRequest() async {
-    if (!await receivePortIterator.moveNext()) return null;
-    return WorkRequest.fromBuffer(receivePortIterator.current);
-  }
-
-  @override
-  void writeResponse(WorkResponse response) {
-    sendPort.send(response.writeToBuffer());
-  }
-}
-
-/// Default implementation of [SyncWorkerConnection] that works with [Stdin] and
-/// [Stdout].
-class StdSyncWorkerConnection implements SyncWorkerConnection {
-  final SyncMessageGrouper _messageGrouper;
-  final Stdout _stdoutStream;
-
-  StdSyncWorkerConnection({Stdin stdinStream, Stdout stdoutStream})
-      : _messageGrouper = SyncMessageGrouper(stdinStream ?? stdin),
-        _stdoutStream = stdoutStream ?? stdout;
-
-  @override
-  WorkRequest readRequest() {
-    var buffer = _messageGrouper.next;
-    if (buffer == null) return null;
-
-    return WorkRequest.fromBuffer(buffer);
-  }
-
-  @override
-  void writeResponse(WorkResponse response) {
-    _stdoutStream.add(protoToDelimitedBuffer(response));
-  }
-}
diff --git a/bazel_worker/lib/src/worker/worker_loop.dart b/bazel_worker/lib/src/worker/worker_loop.dart
deleted file mode 100644
index 2e4a023..0000000
--- a/bazel_worker/lib/src/worker/worker_loop.dart
+++ /dev/null
@@ -1,18 +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 '../worker_protocol.pb.dart';
-
-/// Interface for a [WorkerLoop].
-///
-/// This interface should not generally be implemented directly, instead use
-/// the [SyncWorkerLoop] or [AsyncWorkerLoop] implementations.
-abstract class WorkerLoop {
-  /// Perform a single [WorkRequest], and return either a [WorkResponse] or
-  /// a [Future<WorkResponse>].
-  dynamic performRequest(WorkRequest request);
-
-  /// Run the worker loop. Should return either a [Future] or [null].
-  dynamic run();
-}
diff --git a/bazel_worker/lib/src/worker_protocol.pb.dart b/bazel_worker/lib/src/worker_protocol.pb.dart
deleted file mode 100644
index 90e4381..0000000
--- a/bazel_worker/lib/src/worker_protocol.pb.dart
+++ /dev/null
@@ -1,182 +0,0 @@
-///
-//  Generated code. Do not modify.
-//  source: worker_protocol.proto
-//
-// @dart = 2.3
-// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type
-// ignore_for_file: annotate_overrides
-
-import 'dart:core' as $core;
-
-import 'package:protobuf/protobuf.dart' as $pb;
-
-class Input extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo('Input',
-      package: const $pb.PackageName('blaze.worker'),
-      createEmptyInstance: create)
-    ..aOS(1, 'path')
-    ..a<$core.List<$core.int>>(2, 'digest', $pb.PbFieldType.OY)
-    ..hasRequiredFields = false;
-
-  Input._() : super();
-  factory Input() => create();
-  factory Input.fromBuffer($core.List<$core.int> i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory Input.fromJson($core.String i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  Input clone() => Input()..mergeFromMessage(this);
-  Input copyWith(void Function(Input) updates) =>
-      super.copyWith((message) => updates(message as Input));
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static Input create() => Input._();
-  Input createEmptyInstance() => create();
-  static $pb.PbList<Input> createRepeated() => $pb.PbList<Input>();
-  @$core.pragma('dart2js:noInline')
-  static Input getDefault() =>
-      _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Input>(create);
-  static Input _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get path => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set path($core.String v) {
-    $_setString(0, v);
-  }
-
-  @$pb.TagNumber(1)
-  $core.bool hasPath() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearPath() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.List<$core.int> get digest => $_getN(1);
-  @$pb.TagNumber(2)
-  set digest($core.List<$core.int> v) {
-    $_setBytes(1, v);
-  }
-
-  @$pb.TagNumber(2)
-  $core.bool hasDigest() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearDigest() => clearField(2);
-}
-
-class WorkRequest extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo('WorkRequest',
-      package: const $pb.PackageName('blaze.worker'),
-      createEmptyInstance: create)
-    ..pPS(1, 'arguments')
-    ..pc<Input>(2, 'inputs', $pb.PbFieldType.PM, subBuilder: Input.create)
-    ..a<$core.int>(3, 'requestId', $pb.PbFieldType.O3)
-    ..hasRequiredFields = false;
-
-  WorkRequest._() : super();
-  factory WorkRequest() => create();
-  factory WorkRequest.fromBuffer($core.List<$core.int> i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory WorkRequest.fromJson($core.String i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  WorkRequest clone() => WorkRequest()..mergeFromMessage(this);
-  WorkRequest copyWith(void Function(WorkRequest) updates) =>
-      super.copyWith((message) => updates(message as WorkRequest));
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static WorkRequest create() => WorkRequest._();
-  WorkRequest createEmptyInstance() => create();
-  static $pb.PbList<WorkRequest> createRepeated() => $pb.PbList<WorkRequest>();
-  @$core.pragma('dart2js:noInline')
-  static WorkRequest getDefault() => _defaultInstance ??=
-      $pb.GeneratedMessage.$_defaultFor<WorkRequest>(create);
-  static WorkRequest _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.List<$core.String> get arguments => $_getList(0);
-
-  @$pb.TagNumber(2)
-  $core.List<Input> get inputs => $_getList(1);
-
-  @$pb.TagNumber(3)
-  $core.int get requestId => $_getIZ(2);
-  @$pb.TagNumber(3)
-  set requestId($core.int v) {
-    $_setSignedInt32(2, v);
-  }
-
-  @$pb.TagNumber(3)
-  $core.bool hasRequestId() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearRequestId() => clearField(3);
-}
-
-class WorkResponse extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo('WorkResponse',
-      package: const $pb.PackageName('blaze.worker'),
-      createEmptyInstance: create)
-    ..a<$core.int>(1, 'exitCode', $pb.PbFieldType.O3)
-    ..aOS(2, 'output')
-    ..a<$core.int>(3, 'requestId', $pb.PbFieldType.O3)
-    ..hasRequiredFields = false;
-
-  WorkResponse._() : super();
-  factory WorkResponse() => create();
-  factory WorkResponse.fromBuffer($core.List<$core.int> i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromBuffer(i, r);
-  factory WorkResponse.fromJson($core.String i,
-          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
-      create()..mergeFromJson(i, r);
-  WorkResponse clone() => WorkResponse()..mergeFromMessage(this);
-  WorkResponse copyWith(void Function(WorkResponse) updates) =>
-      super.copyWith((message) => updates(message as WorkResponse));
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static WorkResponse create() => WorkResponse._();
-  WorkResponse createEmptyInstance() => create();
-  static $pb.PbList<WorkResponse> createRepeated() =>
-      $pb.PbList<WorkResponse>();
-  @$core.pragma('dart2js:noInline')
-  static WorkResponse getDefault() => _defaultInstance ??=
-      $pb.GeneratedMessage.$_defaultFor<WorkResponse>(create);
-  static WorkResponse _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.int get exitCode => $_getIZ(0);
-  @$pb.TagNumber(1)
-  set exitCode($core.int v) {
-    $_setSignedInt32(0, v);
-  }
-
-  @$pb.TagNumber(1)
-  $core.bool hasExitCode() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearExitCode() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get output => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set output($core.String v) {
-    $_setString(1, v);
-  }
-
-  @$pb.TagNumber(2)
-  $core.bool hasOutput() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearOutput() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $core.int get requestId => $_getIZ(2);
-  @$pb.TagNumber(3)
-  set requestId($core.int v) {
-    $_setSignedInt32(2, v);
-  }
-
-  @$pb.TagNumber(3)
-  $core.bool hasRequestId() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearRequestId() => clearField(3);
-}
diff --git a/bazel_worker/lib/testing.dart b/bazel_worker/lib/testing.dart
deleted file mode 100644
index 037aa1e..0000000
--- a/bazel_worker/lib/testing.dart
+++ /dev/null
@@ -1,197 +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:collection';
-import 'dart:io';
-import 'dart:typed_data';
-
-import 'package:bazel_worker/bazel_worker.dart';
-
-export 'src/async_message_grouper.dart';
-export 'src/sync_message_grouper.dart';
-export 'src/utils.dart' show protoToDelimitedBuffer;
-
-/// Interface for a mock [Stdin] object that allows you to add bytes manually.
-abstract class TestStdin implements Stdin {
-  void addInputBytes(List<int> bytes);
-
-  void close();
-}
-
-/// A [Stdin] mock object which only implements `readByteSync`.
-class TestStdinSync implements TestStdin {
-  /// Pending bytes to be delivered synchronously.
-  final Queue<int> pendingBytes = Queue<int>();
-
-  /// Adds all the [bytes] to this stream.
-  @override
-  void addInputBytes(List<int> bytes) {
-    pendingBytes.addAll(bytes);
-  }
-
-  /// Add a -1 to signal EOF.
-  @override
-  void close() {
-    pendingBytes.add(-1);
-  }
-
-  @override
-  int readByteSync() {
-    return pendingBytes.removeFirst();
-  }
-
-  @override
-  void noSuchMethod(Invocation invocation) {
-    throw StateError('Unexpected invocation ${invocation.memberName}.');
-  }
-}
-
-/// A mock [Stdin] object which only implements `listen`.
-///
-/// Note: You must call [close] in order for the loop to exit properly.
-class TestStdinAsync implements TestStdin {
-  /// Controls the stream for async delivery of bytes.
-  final StreamController<Uint8List> _controller = StreamController();
-  StreamController<Uint8List> get controller => _controller;
-
-  /// Adds all the [bytes] to this stream.
-  @override
-  void addInputBytes(List<int> bytes) {
-    _controller.add(Uint8List.fromList(bytes));
-  }
-
-  /// Closes this stream. This is necessary for the [AsyncWorkerLoop] to exit.
-  @override
-  void close() {
-    _controller.close();
-  }
-
-  @override
-  StreamSubscription<Uint8List> listen(void Function(Uint8List bytes) onData,
-      {Function onError, void Function() onDone, bool cancelOnError}) {
-    return _controller.stream.listen(onData,
-        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
-  }
-
-  @override
-  void noSuchMethod(Invocation invocation) {
-    throw StateError('Unexpected invocation ${invocation.memberName}.');
-  }
-}
-
-/// A [Stdout] mock object.
-class TestStdoutStream implements Stdout {
-  final List<List<int>> writes = <List<int>>[];
-
-  @override
-  void add(List<int> bytes) {
-    writes.add(bytes);
-  }
-
-  @override
-  void noSuchMethod(Invocation invocation) {
-    throw StateError('Unexpected invocation ${invocation.memberName}.');
-  }
-}
-
-/// Interface for a [TestWorkerConnection] which records its responses
-abstract class TestWorkerConnection implements WorkerConnection {
-  List<WorkResponse> get responses;
-}
-
-/// Interface for a [TestWorkerLoop] which allows you to enqueue responses.
-abstract class TestWorkerLoop implements WorkerLoop {
-  void enqueueResponse(WorkResponse response);
-
-  /// If set, this message will be printed during the call to `performRequest`.
-  String get printMessage;
-}
-
-/// A [StdSyncWorkerConnection] which records its responses.
-class TestSyncWorkerConnection extends StdSyncWorkerConnection
-    implements TestWorkerConnection {
-  @override
-  final List<WorkResponse> responses = <WorkResponse>[];
-
-  TestSyncWorkerConnection(Stdin stdinStream, Stdout stdoutStream)
-      : super(stdinStream: stdinStream, stdoutStream: stdoutStream);
-
-  @override
-  void writeResponse(WorkResponse response) {
-    super.writeResponse(response);
-    responses.add(response);
-  }
-}
-
-/// A [SyncWorkerLoop] for testing.
-class TestSyncWorkerLoop extends SyncWorkerLoop implements TestWorkerLoop {
-  final List<WorkRequest> requests = <WorkRequest>[];
-  final Queue<WorkResponse> _responses = Queue<WorkResponse>();
-
-  @override
-  final String printMessage;
-
-  TestSyncWorkerLoop(SyncWorkerConnection connection, {this.printMessage})
-      : super(connection: connection);
-
-  @override
-  WorkResponse performRequest(WorkRequest request) {
-    requests.add(request);
-    if (printMessage != null) print(printMessage);
-    return _responses.removeFirst();
-  }
-
-  /// Adds [response] to the queue. These will be returned from
-  /// [performResponse] in the order they are added, otherwise it will throw
-  /// if the queue is empty.
-  @override
-  void enqueueResponse(WorkResponse response) {
-    _responses.addLast(response);
-  }
-}
-
-/// A [StdAsyncWorkerConnection] which records its responses.
-class TestAsyncWorkerConnection extends StdAsyncWorkerConnection
-    implements TestWorkerConnection {
-  @override
-  final List<WorkResponse> responses = <WorkResponse>[];
-
-  TestAsyncWorkerConnection(
-      Stream<List<int>> inputStream, StreamSink<List<int>> outputStream)
-      : super(inputStream: inputStream, outputStream: outputStream);
-
-  @override
-  void writeResponse(WorkResponse response) {
-    super.writeResponse(response);
-    responses.add(response);
-  }
-}
-
-/// A [AsyncWorkerLoop] for testing.
-class TestAsyncWorkerLoop extends AsyncWorkerLoop implements TestWorkerLoop {
-  final List<WorkRequest> requests = <WorkRequest>[];
-  final Queue<WorkResponse> _responses = Queue<WorkResponse>();
-
-  @override
-  final String printMessage;
-
-  TestAsyncWorkerLoop(AsyncWorkerConnection connection, {this.printMessage})
-      : super(connection: connection);
-
-  @override
-  Future<WorkResponse> performRequest(WorkRequest request) async {
-    requests.add(request);
-    if (printMessage != null) print(printMessage);
-    return _responses.removeFirst();
-  }
-
-  /// Adds [response] to the queue. These will be returned from
-  /// [performResponse] in the order they are added, otherwise it will throw
-  /// if the queue is empty.
-  @override
-  void enqueueResponse(WorkResponse response) {
-    _responses.addLast(response);
-  }
-}
diff --git a/bazel_worker/pubspec.yaml b/bazel_worker/pubspec.yaml
deleted file mode 100644
index dbae4cd..0000000
--- a/bazel_worker/pubspec.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: bazel_worker
-version: 0.1.23+1
-
-description: Tools for creating a bazel persistent worker.
-homepage: https://github.com/dart-lang/bazel_worker
-
-environment:
-  sdk: '>=2.3.0 <3.0.0'
-
-dependencies:
-  async: '>1.9.0 <3.0.0'
-  pedantic: ^1.8.0
-  protobuf: '>=0.14.4 <2.0.0'
-
-dev_dependencies:
-  test: ^1.2.0
diff --git a/bazel_worker/tool/travis.sh b/bazel_worker/tool/travis.sh
deleted file mode 100755
index bccd424..0000000
--- a/bazel_worker/tool/travis.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-# Fast fail the script on failures.
-set -e
-
-# Verify that the libraries are error free.
-dartanalyzer --fatal-infos --fatal-warnings \
-  lib/bazel_worker.dart \
-  lib/driver.dart \
-  lib/testing.dart \
-  test/test_all.dart
-
-# Run the tests.
-pub run test
-
-pushd e2e_test
-pub get
-dartanalyzer --fatal-infos --fatal-warnings test/e2e_test.dart
-pub run test
-popd
diff --git a/bazel_worker/tool/update_proto.sh b/bazel_worker/tool/update_proto.sh
deleted file mode 100755
index b224694..0000000
--- a/bazel_worker/tool/update_proto.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-set -e
-
-if [ -z "$1" ]; then
-    echo "Expected exactly one argument which is the protoc_plugin version to use"
-else
-    echo "Using protoc_plugin version $1"
-    pub global activate protoc_plugin "$1"
-fi
-
-BAZEL_REPO=.dart_tool/bazel_worker/bazel.git/
-# Bash away old versions if they exist
-rm -rf "$BAZEL_REPO"
-git clone https://github.com/bazelbuild/bazel.git "$BAZEL_REPO"
-
-protoc --proto_path="${BAZEL_REPO}/src/main/protobuf" --dart_out=lib/src worker_protocol.proto
-dartfmt -w lib/src/worker_protocol.pb.dart
-
-# We only care about the *.pb.dart file, not the extra files
-rm lib/src/worker_protocol.pbenum.dart
-rm lib/src/worker_protocol.pbjson.dart
-rm lib/src/worker_protocol.pbserver.dart
-
-rm -rf "$BAZEL_REPO"
diff --git a/build/BUILD.gn b/build/BUILD.gn
deleted file mode 100644
index 1cb5195..0000000
--- a/build/BUILD.gn
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file is generated by importer.py for build-1.2.2
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build") {
-  package_name = "build"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/convert",
-    "//third_party/dart-pkg/pub/logging",
-    "//third_party/dart-pkg/pub/glob",
-    "//third_party/dart-pkg/pub/crypto",
-    "//third_party/dart-pkg/pub/analyzer",
-    "//third_party/dart-pkg/pub/meta",
-    "//third_party/dart-pkg/pub/async",
-    "//third_party/dart-pkg/pub/path",
-  ]
-}
diff --git a/build/CHANGELOG.md b/build/CHANGELOG.md
deleted file mode 100644
index 1926bf6..0000000
--- a/build/CHANGELOG.md
+++ /dev/null
@@ -1,471 +0,0 @@
-## 1.2.2
-
-### Updated docs for some minor behavior changes in build_resolvers 1.3.0
-
-- `Resolver.libraries` will now return any library that has been resolved with
-  this resolver. This means calls to `libraryFor` or `isLibrary` on files not
-  already resolved will make subsequent `libraries` streams return more
-  libraries than previous calls did.
-- The same holds for `findLibraryByName` since it searches through the
-  `libraries` stream. You may get a different result at different points in
-  your build method if you resolve additional libraries.
-
-## 1.2.1
-
-- Allow analyzer `0.39.x`.
-
-## 1.2.0
-
-- Add the `void reportUnusedAssets(Iterable<AssetId> ids)` method to the
-  `BuildStep` class.
-  - **WARNING**: Using this introduces serious risk of non-hermetic builds.
-  - Indicates to the build system that `ids` were read but their content has
-    no impact on the outputs of the build.
-  - Build system implementations can choose to support this feature or not,
-    and it should be assumed to be a no-op by default.
-
-## 1.1.6
-
-- Allow analyzer version 0.38.0.
-
-## 1.1.5
-
-- Allow analyzer version 0.37.0.
-
-## 1.1.4
-
-- Internal cleanup: use "strict raw types".
-- Some return types for interfaces to implement changed from `Future<dynamic>`
-  to `Future<void>`.
-
-## 1.1.3
-
-- Update the minimum sdk constraint to 2.1.0.
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-
-## 1.1.2
-
-- Internal fixes: Remove default value for optional argument.
-
-## 1.1.1
-
-- Requires analyzer version `0.35.0`
-  - `Resolver` implementations in other packages are now backed by an
-    `AnalysisDriver`. There are behavior changes which may be breaking. The
-    `LibraryElement` instances returned by the resolver will now:
-    - Have non-working `context` fields.
-    - Have no source offsets for annotations or their errors.
-    - Have working `session` fields.
-    - Have `Source` instances with different URIs than before.
-
-## 1.1.0
-
-- Add `Resolver.assetIdForElement` API. This allows finding the Dart source
-  asset which contains the definition of an element found through the analyzer.
-- Include the AssetId hash code in the default digest implementation.
-  - Any custom implementations of the `AssetReader.digest` method should do the
-    same, and a comment has been added to that effect.
-
-## 1.0.2
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 1.0.1
-
-- Increased the upper bound for `package:analyzer` to `<0.34.0`.
-
-## 1.0.0
-
-### Breaking Changes
-
-- Changed the return type of `Builder.build` from `Future<dynamic>` to
-  `FutureOr<void>`. This should not be breaking for most `Builder` authors, it
-  is only breaking for build system implementations that run `Builder`s.
-
-## 0.12.8
-
-- Added the `T trackStage<T>(String label, T Function() action);` method to
-  `BuildStep`. Actions that are tracked in this way will show up in the
-  performance timeline at `/$perf`.
-
-## 0.12.7+4
-
-- `print` calls inside a Builder will now log at warning instead of info.
-
-## 0.12.7+3
-
-- Throw when attempting to use a `BuildStep` after it has been completed.
-
-## 0.12.7+2
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.12.7+1
-
-- `AssetId`s can no longer be constructed with paths that reach outside their
-  package.
-
-## 0.12.7
-
-- Added `Resolvers.reset` method.
-
-## 0.12.6
-
-- Added `List<String> get pathSegments` to `AssetId`.
-- `log` will now always return a `Logger` instance.
-- Support `package:analyzer` `0.32.0`.
-
-## 0.12.5
-
-- Add exclude support to `FileDeletingBuilder`.
-
-## 0.12.4
-
-- Add `FileDeletingBuilder`.
-- Add `PostProcesBuilderFactory` typedef.
-
-## 0.12.3
-
-- Added an `isRoot` boolean to `BuilderOptions`, which allows builders to have
-  different behavior for the root package, if desired.
-- Add `PostProcessBuilder`. This is only supported by `build_runner`.
-
-## 0.12.2
-
-- Include stack trace in log for exceptions throw by builders.
-
-## 0.12.1
-
-- Add `BuilderOptions.empty` and `BuilderOptions.overrideWith`.
-
-## 0.12.0+2
-
-- **Bug Fix** Correctly handle encoding `AssetId`s as `URI`s when they contain
-  characters which are not valid for a path segment.
-
-## 0.12.0+1
-
-- Support the latest `analyzer` package.
-
-## 0.12.0
-
-### Breaking Changes
-
-- Added the `Future<Digest> digest(AssetId id)` method to the `AssetReader`
-  interface. There is a default implementation which uses `readAsBytes` and
-  `md5`.
-
-## 0.11.2
-
-- Bug Fix: `MultiplexingBuilder` now filters inputs rather than calling _every_
-  builder on any input that matched _any_ builder.
-
-## 0.11.1
-
-- Add `BuilderOptions` and `BuilderFactory` interfaces. Along with
-  `package:build_config` this will offer a consistent way to describe and create
-  the Builder instances exposed by a package.
-
-## 0.11.0
-
-- **Breaking**: `AssetReader.findAssets` now returns a `Stream<AssetId>`
-  instead of an `Iterable<AssetId>`. This also impacts `BuildStep` since that
-  implements `AssetReader`.
-
-## 0.10.2+1
-
-- Fix an issue where multiple `ResourceManager`s would share `Resource`
-  instances if running at the same time.
-
-## 0.10.2
-
-- Added the `MultiPackageAssetReader` interface which allows globbing within
-  any package.
-  - This is not exposed to typical users, only build system implementations
-    need it. The `BuildStep` class does not implement this interface.
-- The docs for `AssetReader#findAssets` have changed such that it globs within
-  the current package instead of the root package (typically defined as
-  `buildStep.inputId.package`).
-  - Before you could run builders only on the root package, but now that you
-    can run them on any package the old functionality no longer makes sense.
-
-## 0.10.1
-
-- Remove restrictions around the root package when Builders are running. It is
-  the responsibility of the build system to ensure that builders are only run on
-  inputs that will produce outputs that can be written.
-- Added the `Resource` class, and `BuildStep#fetchResource` method.
-
-## 0.10.0+1
-
-- Bug Fix: Capture asynchronous errors during asset writing.
-
-## 0.10.0
-
-- **Breaking**: Removed deprecated method `BuildStep.hasInput` - all uses should
-  be going through `BuildStep.canRead`.
-- **Breaking**: `Resolver` has asynchronous APIs for resolution and is retrieved
-  synchronously from the `BuildStep`.
-- **Breaking**:  Replaced `Resolver.getLibrary` with `libraryFor` and
-  `getLibraryByName` with `findLibraryByName`.
-- Change `AssetReader.canRead` to always return a Future.
-
-## 0.9.3
-
-- Add support for resolving `asset:` URIs into AssetIds
-- Add `uri` property on AssetId
-
-## 0.9.1
-
-- Skip Builders which would produce no outputs.
-
-## 0.9.0
-
-- Deprecate `BuildStep.hasInput` in favor of `BuildStep.canRead`.
-- Rename `AssetReader.hasInput` as `canRead`. This is breaking for implementers
-  of `AssetReader` and for any clients passing a `BuildStep` as an `AssetReader`
-- Make `canRead` return a `FutureOr` for more flexibility
-- Drop `ManagedBuildStep` class.
-- Drop `BuildStep.logger`. All logging should go through the top level `log`.
-- `BuildStep.writeAs*` methods now take a `FutureOr` for content. Builders which
-  produce content asynchronously can now set up the write without waiting for it
-  to resolve.
-- **Breaking** `declareOutputs` is replaced with `buildExtensions`. All `Builder`
-  implementations must now have outputs that vary only based on the extensions
-  of inputs, rather than based on any part of the `AssetId`.
-
-## 0.8.0
-
-- Add `AssetReader.findAssets` to allow listing assets by glob.
-
-## 0.7.3
-
-- Add `BuildStep.inputLibrary` as a convenience.
-- Fix a bug in `AssetId.resolve` to prepend `lib/` when resolving packages.
-
-## 0.7.2
-
-- Add an `AssetId.resolve` constructor to easily construct AssetIds from import
-  uris.
-- Capture 'print' calls inside running builds and automatically turn them in to
-  `log.info`. Depending on the environment a print can be hazardous so this
-  makes all builders safe and consistent by default.
-
-## 0.7.1+1
-
-- Use comment syntax for generic method - not everyone is on an SDK version that
-  supports the real syntax.
-
-## 0.7.1
-
-- Add a top-level `log` getter which is scoped to running builds and can be used
-  anywhere within a build rather than passing around a logger. This replaces the
-  `BuildStep.logger` field.
-- Deprecate `BuildStep.logger` - it is replaced by `log`
-- Deprecate `ManagedBuildStep`, all build runs should go through `runBuilders`.
-
-## 0.7.0
-
-A number of changes to the apis, primarily to support reading/writing as bytes,
-as this is going to inevitably be a required feature. This will hopefully be the
-last breaking change before the `1.0` release, but it is a fairly large one.
-
-### New Features
-
-- The `AssetWriter` class now has a
-  `Future writeAsBytes(AssetId id, List<int> bytes)` method.
-- The `AssetReader` class now has a `Future<List<int>> readAsBytes(AssetId id)`
-  method.
-- You no longer need to call `Resolver#release` on any resolvers you get from
-  a `BuildStep` (in fact, the `Resolver` interface no longer has this method).
-- There is now a `BuildStep#resolver` getter, which resolves the primary input,
-  and returns a `Future<Resolver>`. This replaces the `BuildStep#resolve`
-  method.
-- `Resolver` has a new `isLibrary` method to check whether an asset is a Dart
-  library source file before trying to resolve it's LibraryElement
-
-### Breaking Changes
-
-- The `Asset` class has been removed entirely.
-- The `AssetWriter#writeAsString` signature has changed to
-  `Future writeAsString(AssetId id, String contents, {Encoding encoding})`.
-- The type of the `AssetWriterSpy#assetsWritten` getter has changed from an
-  `Iterable<Asset>` to an `Iterable<AssetId>`.
-- `BuildStep#input` has been changed to `BuildStep#inputId`, and its type has
-  changed from `Asset` to `AssetId`. This means you must now use
-  `BuildStep#readAsString` or `BuildStep#readAsBytes` to read the primary input,
-  instead of it already being read in for you.
-- `Resolver` no longer has a `release` method (they are released for you).
-- `BuildStep#resolve` no longer exists, and has been replaced with the
-  `BuildStep#resolver` getter.
-- `Resolver.getLibrary` will now throw a `NonLibraryAssetException` instead of
-  return null if it is asked to resolve an impossible library.
-
-**Note**: The changes to `AssetReader` and `AssetWriter` also affect `BuildStep`
-and other classes that implement those interfaces.
-
-## 0.6.3
-
-- Add hook for `build_barback` to write assets from a Future
-
-## 0.6.2
-
-- Remove unused dependencies
-
-## 0.6.1
-
-- `BuildStep` now implements `AssetReader` and `AssetWriter` so it's easier to
-  share with other code paths using a more limited interface.
-
-## 0.6.0
-
-- **BREAKING** Move some classes and methods out of this package. If you are
-  using `build`, `watch`, or `serve`, along with `PhaseGroup` and related
-  classes add a dependency on `build_runner`. If you are using
-  `BuilderTransformer` or `TansformerBuilder` add a dependency on
-  `build_barback`.
-- **BREAKING** Resolvers is now an abstract class. If you were using the
-  constructor `const Resolvers()` as a default instance import `build_barback`
-  and used `const BarbackResolvers()` instead.
-
-## 0.5.0
-
-- **BREAKING** BuilderTransformer must be constructed with a single Builder. Use
-  the MultiplexingBuilder to cover cases with a list of builders
-- When using a MultiplexingBuilder if multiple Builders have overlapping outputs
-  the entire step will not run rather than running builders up to the point
-  where there is an overlap
-
-## 0.4.1+3
-
-- With the default logger, print exceptions with a terse stack trace.
-- Provide a better error when an inputSet package cannot be found.
-- Fix `dev_dependencies` so tests run.
-
-## 0.4.1+2
-
-- Stop using removed argument `useSharedSources` when constructing Resolvers
-- Support code_transformers 0.5.x
-
-## 0.4.1+1
-
-- Support analyzer 0.29.x
-
-## 0.4.1
-
-- Support analyzer 0.28.x
-
-## 0.4.0
-
-- **BREAKING** BuilderTransformer must be constructed with a List<Builder>
-  rather than inherit and override.
-- Simplifies Resolver interface so it is possible to add implementations which
-  are less complex than the one from code_transformers.
-- Adds a Resolvers class and support for overriding the concrete Resolver that
-  is used by build steps.
-- Updates some test expectations to match the new behavior of analyzer.
-
-## 0.3.0+6
-
-- Convert `packages` paths in the file watcher to their absolute paths. This
-  fixes [#109](https://github.com/dart-lang/build/issues/109).
-
-## 0.3.0+5
-
-- Fix duplicate logs issue when running as a BuilderTransformer.
-
-- Support `crypto` 2.0.0.
-
-## 0.3.0+4
-
-- Add error and stack trace to log messages from the BuilderTransformer.
-
-## 0.3.0+3
-
-- Fixed BuilderTransformer so that logs are passed on to the TransformLogger.
-
-## 0.3.0+2
-
-- Enable serving files outside the server root by default (enables serving
-  files from other packages).
-
-## 0.3.0+1
-
-- Fix an AssetGraph bug where generated nodes might be created as non-generated
-  nodes if they are attempted to be read from previous build steps.
-
-## 0.3.0
-
-- **BREAKING** Renamed values of three enums to be lower-case:
-  `BuildType`, `BuildStatus`, and `PackageDependencyType`.
-- Updated to crypto ^1.0.0.
-- Added option to resolve additional entry points in `buildStep.resolve`.
-- Added option to pass in a custom `Resolvers` instance.
-
-## 0.2.1
-
-- Added the `deleteFilesByDefault` option to all top level methods. This will
-  skip the prompt to delete files, and instead act as if you responded `y`.
-  - Also by default in a non-console environment the prompt no longer exists and
-    it will instead just exit with an error.
-- Added support for multiple build scripts. Each script now has its own asset
-  graph based on a hash of the script uri.
-  - You need to be careful here, as you can get in an infinite loop if two
-    separate build scripts keep triggering updates for each other.
-  - There is no explicit link between multiple scripts, so they operate as if
-    all changes from other scripts were user edits. This will usually just do
-    the "right thing", but may result in undesired behavior in some
-    circumstances.
-- Improved logging for non-posix consoles.
-
-## 0.2.0
-
-- Updated the top level classes to take a `PhaseGroup` instead of a
-  `List<List<Phase>>`.
-- Added logic to handle nested package directories.
-- Basic windows support added, although it may still be unstable.
-- Significantly increased the resolving speed by using the same sources cache.
-- Added a basic README.
-- Moved the `.build` folder to `.dart_tool/build`. Other packages in the future
-  may also use this folder.
-
-## 0.1.4
-
-- Added top level `serve` function.
-  - Just like `watch`, but it provides a server which blocks on any ongoing
-    builds before responding to requests.
-- Minor bug fixes.
-
-## 0.1.3
-
-- Builds are now fully incremental, even on startup.
-  - Builds will be invalidated if the build script or any of its dependencies
-    are updated since there is no way of knowing how that would affect things.
-- Added `lastModified` to `AssetReader` (only matters if you implement it).
-
-## 0.1.2
-
-- Exposed the top level `watch` function. This can be used to watch the file
-  system and run incremental rebuilds on changes.
-  - Initial build is still non-incremental.
-
-## 0.1.1
-
-- Exposed the top level `build` function. This can be used to run builds.
-  - For this release all builds are non-incremental, and delete all previous
-    build outputs when they start up.
-  - Creates a `.build` directory which should be added to your `.gitignore`.
-- Added `resolve` method to `BuildStep` which can give you a `Resolver` for an
-  `AssetId`.
-  - This is experimental and may get moved out to a separate package.
-  - Resolves the full dart sdk so this is slow, first call will take multiple
-    seconds. Subsequent calls are much faster though.
-  - Will end up marking all transitive deps as dependencies, so your files may
-    end up being recompiled often when not entirely necessary (once we have
-    incremental builds).
-- Added `listAssetIds` to `AssetReader` (only matters if you implement it).
-- Added `delete` to `AssetWriter` (also only matters if you implement it).
-
-## 0.1.0
-
-- Initial version
diff --git a/build/LICENSE b/build/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/build/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build/README.md b/build/README.md
deleted file mode 100644
index 48c3545..0000000
--- a/build/README.md
+++ /dev/null
@@ -1,157 +0,0 @@
-# [![Build Status](https://travis-ci.org/dart-lang/build.svg?branch=master)](https://travis-ci.org/dart-lang/build)
-
-# `build`
-
-Defines the basic pieces of how a build happens and how they interact.
-
-## [`Builder`][dartdoc:Builder]
-
-The business logic for code generation. Most consumers of the `build` package
-will create custom implementations of `Builder`.
-
-## [`BuildStep`][dartdoc:BuildStep]
-
-The way a `Builder` interacts with the outside world. Defines the unit of work
-and allows reading/writing files and resolving Dart source code.
-
-## [`Resolver`][dartdoc:Resolver] class
-
-An interface into the dart [analyzer][pub:analyzer] to allow resolution of code
-that needs static analysis and/or code generation.
-
-## Implementing your own Builders
-
-A `Builder` gets invoked one by one on it's inputs, and may read other files and
-output new files based on those inputs.
-
-The basic API looks like this:
-
-```dart
-abstract class Builder {
-  /// You can only output files that are configured here by suffix substitution.
-  /// You are not required to output all of these files, but no other builder
-  /// may declare the same outputs.
-  Map<String, List<String>> get buildExtensions;
-
-  /// This is where you build and output files.
-  FutureOr<void> build(BuildStep buildStep);
-}
-```
-
-Here is an implementation of a `Builder` which just copies files to other files
-with the same name, but an additional extension:
-
-```dart
-import 'package:build/build.dart';
-
-/// A really simple [Builder], it just makes copies of .txt files!
-class CopyBuilder implements Builder {
-  @override
-  final buildExtensions = const {
-    '.txt': ['.txt.copy']
-  };
-
-  @override
-  Future<void> build(BuildStep buildStep) async {
-    // Each `buildStep` has a single input.
-    var inputId = buildStep.inputId;
-
-    // Create a new target `AssetId` based on the old one.
-    var copy = inputId.addExtension('.copy');
-    var contents = await buildStep.readAsString(inputId);
-
-    // Write out the new asset.
-    await buildStep.writeAsString(copy, contents);
-  }
-}
-```
-
-It should be noted that you should _never_ touch the file system directly. Go
-through the `buildStep#readAsString` and `buildStep#writeAsString` methods in
-order to read and write assets. This is what enables the package to track all of
-your dependencies and do incremental rebuilds. It is also what enables your
-[`Builder`][dartdoc:Builder] to run on different environments.
-
-### Using the analyzer
-
-If you need to do analyzer resolution, you can use the `BuildStep#resolver`
-object. This makes sure that all `Builder`s in the system share the same
-analysis context, which greatly speeds up the overall system when multiple
-`Builder`s are doing resolution.
-
-Here is an example of a `Builder` which uses the `resolve` method:
-
-```dart
-import 'package:build/build.dart';
-
-class ResolvingCopyBuilder implements Builder {
-  // Take a `.dart` file as input so that the Resolver has code to resolve
-  @override
-  final buildExtensions = const {
-    '.dart': ['.dart.copy']
-  };
-
-  @override
-  Future<void> build(BuildStep buildStep) async {
-    // Get the `LibraryElement` for the primary input.
-    var entryLib = await buildStep.inputLibrary;
-    // Resolves all libraries reachable from the primary input.
-    var resolver = buildStep.resolver;
-    // Get a `LibraryElement` for another asset.
-    var libFromAsset = await resolver.libraryFor(
-        AssetId.resolve('some_import.dart', from: buildStep.inputId));
-    // Or get a `LibraryElement` by name.
-    var libByName = await resolver.findLibraryByName('my.library');
-  }
-}
-```
-
-Once you have gotten a `LibraryElement` using one of the methods on `Resolver`,
-you are now just using the regular `analyzer` package to explore your app.
-
-### Sharing expensive objects across build steps
-
-The build package includes a `Resource` class, which can give you an instance
-of an expensive object that is guaranteed to be unique across builds, but may
-be re-used by multiple build steps within a single build (to the extent that
-the implementation allows). It also gives you a way of disposing of your
-resource at the end of its lifecycle.
-
-The `Resource<T>` constructor takes a single required argument which is a
-factory function that returns a `FutureOr<T>`. There is also a named argument
-`dispose` which is called at the end of life for the resource, with the
-instance that should be disposed. This returns a `FutureOr<dynamic>`.
-
-So a simple example `Resource` would look like this:
-
-```dart
-final resource = Resource(
-  () => createMyExpensiveResource(),
-  dispose: (instance) async {
-    await instance.doSomeCleanup();
-  });
-```
-
-You can get an instance of the underlying resource by using the
-`BuildStep#fetchResource` method, whose type signature looks like
-`Future<T> fetchResource<T>(Resource<T>)`.
-
-**Important Note**: It may be tempting to try and use a `Resource` instance to
-cache information from previous build steps (or even assets), but this should
-be avoided because it can break the soundness of the build, and may introduce
-subtle bugs for incremental builds (remember the whole build doesn't run every
-time!). The `build` package relies on the `BuildStep#canRead` and
-`BuildStep#readAs*` methods to track build step dependencies, so sidestepping
-those can and will break the dependency tracking, resulting in inconsistent and
-stale assets.
-
-## Features and bugs
-
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/build/issues
-
-[dartdoc:Builder]: https://pub.dev/documentation/build/latest/build/Builder-class.html
-[dartdoc:BuildStep]: https://pub.dev/documentation/build/latest/build/BuildStep-class.html
-[dartdoc:Resolver]: https://pub.dev/documentation/build/latest/build/Resolver-class.html
-[pub:analyzer]: https://pub.dev/packages/analyzer
diff --git a/build/lib/build.dart b/build/lib/build.dart
deleted file mode 100644
index b5f3574..0000000
--- a/build/lib/build.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-
-export 'src/analyzer/resolver.dart';
-export 'src/asset/exceptions.dart';
-export 'src/asset/id.dart';
-export 'src/asset/reader.dart';
-export 'src/asset/writer.dart';
-export 'src/builder/build_step.dart' hide NoOpStageTracker;
-export 'src/builder/builder.dart';
-export 'src/builder/exceptions.dart';
-export 'src/builder/file_deleting_builder.dart' show FileDeletingBuilder;
-export 'src/builder/logging.dart' show log;
-export 'src/builder/multiplexing_builder.dart';
-export 'src/builder/post_process_build_step.dart' show PostProcessBuildStep;
-export 'src/builder/post_process_builder.dart'
-    show PostProcessBuilder, PostProcessBuilderFactory;
-export 'src/generate/expected_outputs.dart';
-export 'src/generate/run_builder.dart';
-export 'src/generate/run_post_process_builder.dart' show runPostProcessBuilder;
-export 'src/resource/resource.dart';
diff --git a/build/lib/src/analyzer/resolver.dart b/build/lib/src/analyzer/resolver.dart
deleted file mode 100644
index be73cfc..0000000
--- a/build/lib/src/analyzer/resolver.dart
+++ /dev/null
@@ -1,82 +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:analyzer/dart/element/element.dart';
-
-import '../asset/id.dart';
-import '../builder/build_step.dart';
-
-/// Standard interface for resolving Dart source code as part of a build.
-abstract class Resolver {
-  /// Returns whether [assetId] represents an Dart library file.
-  ///
-  /// This will be `false` in the case where the file is not Dart source code,
-  /// or is a `part of` file (not a standalone Dart library).
-  Future<bool> isLibrary(AssetId assetId);
-
-  /// All libraries recursively accessible from the entry point or subsequent
-  /// calls to [libraryFor] and [isLibrary].
-  ///
-  /// **NOTE**: This includes all Dart SDK libraries as well.
-  Stream<LibraryElement> get libraries;
-
-  /// Returns a resolved library representing the file defined in [assetId].
-  ///
-  /// * Throws [NonLibraryAssetException] if [assetId] is not a Dart library.
-  Future<LibraryElement> libraryFor(AssetId assetId);
-
-  /// Returns the first resolved library identified by [libraryName].
-  ///
-  /// A library is resolved if it's recursively accessible from the entry point
-  /// or subsequent calls to [libraryFor] and [isLibrary]. If no library can be
-  /// found, returns `null`.
-  ///
-  /// **NOTE**: In general, its recommended to use [libraryFor] with an absolute
-  /// asset id instead of a named identifier that has the possibility of not
-  /// being unique.
-  Future<LibraryElement> findLibraryByName(String libraryName);
-
-  /// Returns the [AssetId] of the Dart library or part declaring [element].
-  ///
-  /// If [element] is defined in the SDK or in a summary throws
-  /// `UnresolvableAssetException`, although a non-throwing return here does not
-  /// guarantee that the asset is readable.
-  ///
-  /// The returned asset is not necessarily the asset that should be imported to
-  /// use the element, it may be a part file instead of the library.
-  Future<AssetId> assetIdForElement(Element element);
-}
-
-/// A resolver that should be manually released at the end of a build step.
-abstract class ReleasableResolver implements Resolver {
-  /// Release this resolver so it can be updated by following build steps.
-  void release();
-}
-
-/// A factory that returns a resolver for a given [BuildStep].
-abstract class Resolvers {
-  const Resolvers();
-
-  Future<ReleasableResolver> get(BuildStep buildStep);
-
-  /// Reset the state of any caches within [Resolver] instances produced by
-  /// this [Resolvers].
-  ///
-  /// In between calls to [reset] no Assets should change, so every call to
-  /// `BuildStep.readAsString` for a given AssetId should return identical
-  /// contents. Any time an Asset's contents may change [reset] must be called.
-  void reset() {}
-}
-
-/// Thrown when attempting to read a non-Dart library in a [Resolver].
-class NonLibraryAssetException implements Exception {
-  final AssetId assetId;
-
-  const NonLibraryAssetException(this.assetId);
-
-  @override
-  String toString() => 'Asset [$assetId] is not a Dart library. '
-      'It may be a part file or a file without Dart source code.';
-}
diff --git a/build/lib/src/asset/exceptions.dart b/build/lib/src/asset/exceptions.dart
deleted file mode 100644
index 141c071..0000000
--- a/build/lib/src/asset/exceptions.dart
+++ /dev/null
@@ -1,57 +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 'id.dart';
-
-class AssetNotFoundException implements Exception {
-  final AssetId assetId;
-
-  AssetNotFoundException(this.assetId);
-
-  @override
-  String toString() => 'AssetNotFoundException: $assetId';
-}
-
-class PackageNotFoundException implements Exception {
-  final String name;
-
-  PackageNotFoundException(this.name);
-
-  @override
-  String toString() => 'PackageNotFoundException: $name';
-}
-
-class InvalidOutputException implements Exception {
-  final AssetId assetId;
-  final String message;
-
-  InvalidOutputException(this.assetId, this.message);
-
-  @override
-  String toString() => 'InvalidOutputException: $assetId\n$message';
-}
-
-class InvalidInputException implements Exception {
-  final AssetId assetId;
-
-  InvalidInputException(this.assetId);
-
-  @override
-  String toString() => 'InvalidInputException: $assetId\n'
-      'For package dependencies, only files under `lib` may be used as inputs.';
-}
-
-class BuildStepCompletedException implements Exception {
-  @override
-  String toString() => 'BuildStepCompletedException: '
-      'Attempt to use a BuildStep after is has completed';
-}
-
-class UnresolvableAssetException implements Exception {
-  final String description;
-
-  const UnresolvableAssetException(this.description);
-
-  @override
-  String toString() => 'Unresolvable Asset from $description.';
-}
diff --git a/build/lib/src/asset/id.dart b/build/lib/src/asset/id.dart
deleted file mode 100644
index a743cf7..0000000
--- a/build/lib/src/asset/id.dart
+++ /dev/null
@@ -1,169 +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 'package:path/path.dart' as p;
-
-/// Identifies an asset within a package.
-class AssetId implements Comparable<AssetId> {
-  /// The name of the package containing this asset.
-  final String package;
-
-  /// The path to the asset relative to the root directory of [package].
-  ///
-  /// Source (i.e. read from disk) and generated (i.e. the output of a
-  /// `Builder`) assets all have paths. Even intermediate assets that are
-  /// generated and then consumed by later transformations will still have a
-  /// path used to identify it.
-  ///
-  /// Asset paths always use forward slashes as path separators, regardless of
-  /// the host platform. Asset paths will always be within their package, that
-  /// is they will never contain "../".
-  final String path;
-
-  /// Splits [path] into its components.
-  List<String> get pathSegments => p.url.split(path);
-
-  /// The file extension of the asset, if it has one, including the ".".
-  String get extension => p.extension(path);
-
-  /// Creates a new [AssetId] at [path] within [package].
-  ///
-  /// The [path] will be normalized: any backslashes will be replaced with
-  /// forward slashes (regardless of host OS) and "." and ".." will be removed
-  /// where possible.
-  AssetId(this.package, String path) : path = _normalizePath(path);
-
-  /// Creates a new [AssetId] from an [uri] String.
-  ///
-  /// This gracefully handles `package:` or `asset:` URIs.
-  ///
-  /// Resolve a `package:` URI when creating an [AssetId] from an `import` or
-  /// `export` directive pointing to a package's _lib_ directory:
-  /// ```dart
-  /// AssetId assetOfDirective(UriReferencedElement element) {
-  ///   return new AssetId.resolve(element.uri);
-  /// }
-  /// ```
-  ///
-  /// When resolving a relative URI with no scheme, specifyg the origin asset
-  /// ([from]) - otherwise an [ArgumentError] will be thrown.
-  /// ```dart
-  /// AssetId assetOfDirective(AssetId origin, UriReferencedElement element) {
-  ///   return new AssetId.resolve(element.uri, from: origin);
-  /// }
-  /// ```
-  ///
-  /// `asset:` uris have the format '$package/$path', including the top level
-  /// directory.
-  factory AssetId.resolve(String uri, {AssetId from}) {
-    final parsedUri = Uri.parse(uri);
-    if (parsedUri.hasScheme) {
-      if (parsedUri.scheme == 'package') {
-        return AssetId(parsedUri.pathSegments.first,
-            p.url.join('lib', p.url.joinAll(parsedUri.pathSegments.skip(1))));
-      } else if (parsedUri.scheme == 'asset') {
-        return AssetId(parsedUri.pathSegments.first,
-            p.url.joinAll(parsedUri.pathSegments.skip(1)));
-      }
-      throw UnsupportedError(
-          'Cannot resolve $uri; only "package" and "asset" schemes supported');
-    }
-    if (from == null) {
-      throw ArgumentError.value(from, 'from',
-          'An AssetId "from" must be specified to resolve a relative URI');
-    }
-    return AssetId(p.url.normalize(from.package),
-        p.url.join(p.url.dirname(from.path), uri));
-  }
-
-  /// Parses an [AssetId] string of the form "package|path/to/asset.txt".
-  ///
-  /// The [path] will be normalized: any backslashes will be replaced with
-  /// forward slashes (regardless of host OS) and "." and ".." will be removed
-  /// where possible.
-  factory AssetId.parse(String description) {
-    var parts = description.split('|');
-    if (parts.length != 2) {
-      throw FormatException('Could not parse "$description".');
-    }
-
-    if (parts[0].isEmpty) {
-      throw FormatException(
-          'Cannot have empty package name in "$description".');
-    }
-
-    if (parts[1].isEmpty) {
-      throw FormatException('Cannot have empty path in "$description".');
-    }
-
-    return AssetId(parts[0], parts[1]);
-  }
-
-  /// A `package:` URI suitable for use directly with other systems if this
-  /// asset is under it's package's `lib/` directory, else an `asset:` URI
-  /// suitable for use within build tools.
-  Uri get uri => _uri ??= _constructUri(this);
-  Uri _uri;
-
-  /// Deserializes an [AssetId] from [data], which must be the result of
-  /// calling [serialize] on an existing [AssetId].
-  AssetId.deserialize(List<dynamic> data)
-      : package = data[0] as String,
-        path = data[1] as String;
-
-  /// Returns `true` if [other] is an [AssetId] with the same package and path.
-  @override
-  bool operator ==(Object other) =>
-      other is AssetId && package == other.package && path == other.path;
-
-  @override
-  int get hashCode => package.hashCode ^ path.hashCode;
-
-  @override
-  int compareTo(AssetId other) {
-    var packageComp = package.compareTo(other.package);
-    if (packageComp != 0) return packageComp;
-    return path.compareTo(other.path);
-  }
-
-  /// Returns a new [AssetId] with the same [package] as this one and with the
-  /// [path] extended to include [extension].
-  AssetId addExtension(String extension) => AssetId(package, '$path$extension');
-
-  /// Returns a new [AssetId] with the same [package] and [path] as this one
-  /// but with file extension [newExtension].
-  AssetId changeExtension(String newExtension) =>
-      AssetId(package, p.withoutExtension(path) + newExtension);
-
-  @override
-  String toString() => '$package|$path';
-
-  /// Serializes this [AssetId] to an object that can be sent across isolates
-  /// and passed to [AssetId.deserialize].
-  Object serialize() => [package, path];
-}
-
-String _normalizePath(String path) {
-  if (p.isAbsolute(path)) {
-    throw ArgumentError.value(path, 'Asset paths must be relative.');
-  }
-
-  // Normalize path separators so that they are always "/" in the AssetID.
-  path = path.replaceAll(r'\', '/');
-
-  // Collapse "." and "..".
-  final collapsed = p.posix.normalize(path);
-  if (collapsed.startsWith('../')) {
-    throw ArgumentError.value(
-        path, 'Asset paths may not reach outside the package.');
-  }
-  return collapsed;
-}
-
-Uri _constructUri(AssetId id) {
-  final originalSegments = id.pathSegments;
-  final isLib = originalSegments.first == 'lib';
-  final scheme = isLib ? 'package' : 'asset';
-  final pathSegments = isLib ? originalSegments.skip(1) : originalSegments;
-  return Uri(scheme: scheme, pathSegments: [id.package]..addAll(pathSegments));
-}
diff --git a/build/lib/src/asset/reader.dart b/build/lib/src/asset/reader.dart
deleted file mode 100644
index fdee30b..0000000
--- a/build/lib/src/asset/reader.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.
-
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:crypto/crypto.dart';
-import 'package:convert/convert.dart';
-import 'package:glob/glob.dart';
-
-import 'id.dart';
-
-/// Standard interface for reading an asset within in a package.
-///
-/// An [AssetReader] is required when calling the `runBuilder` method.
-abstract class AssetReader {
-  /// Returns a [Future] that completes with the bytes of a binary asset.
-  ///
-  /// * Throws a `PackageNotFoundException` if `id.package` is not found.
-  /// * Throws a `AssetNotFoundException` if `id.path` is not found.
-  Future<List<int>> readAsBytes(AssetId id);
-
-  /// Returns a [Future] that completes with the contents of a text asset.
-  ///
-  /// When decoding as text uses [encoding], or [utf8] is not specified.
-  ///
-  /// * Throws a `PackageNotFoundException` if `id.package` is not found.
-  /// * Throws a `AssetNotFoundException` if `id.path` is not found.
-  Future<String> readAsString(AssetId id, {Encoding encoding});
-
-  /// Indicates whether asset at [id] is readable.
-  Future<bool> canRead(AssetId id);
-
-  /// Returns all readable assets matching [glob] under the current package.
-  Stream<AssetId> findAssets(Glob glob);
-
-  /// Returns a [Digest] representing a hash of the contents of [id].
-  ///
-  /// The digests should include the asset ID as well as the content of the
-  /// file, as some build systems may rely on the digests for two files being
-  /// different, even if their content is the same.
-  ///
-  /// This should be treated as a transparent [Digest] and the implementation
-  /// may differ based on the current build system being used.
-  Future<Digest> digest(AssetId id) async {
-    var digestSink = AccumulatorSink<Digest>();
-    md5.startChunkedConversion(digestSink)
-      ..add(await readAsBytes(id))
-      ..add(id.toString().codeUnits)
-      ..close();
-    return digestSink.events.first;
-  }
-}
-
-/// The same as an `AssetReader`, except that `findAssets` takes an optional
-/// argument `package` which allows you to glob any package.
-///
-/// This should not be exposed to end users generally, but can be used by
-/// different build system implementations.
-abstract class MultiPackageAssetReader extends AssetReader {
-  /// Returns all readable assets matching [glob] under [package].
-  ///
-  /// Some implementations may require the [package] argument, while others
-  /// may have a sane default.
-  @override
-  Stream<AssetId> findAssets(Glob glob, {String package});
-}
diff --git a/build/lib/src/asset/writer.dart b/build/lib/src/asset/writer.dart
deleted file mode 100644
index 68ba81f..0000000
--- a/build/lib/src/asset/writer.dart
+++ /dev/null
@@ -1,50 +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:convert';
-
-import 'id.dart';
-
-/// Standard interface for writing an asset into a package's outputs.
-abstract class AssetWriter {
-  /// Writes [bytes] to a binary file located at [id].
-  ///
-  /// Returns a [Future] that completes after writing the asset out.
-  ///
-  /// * Throws a `PackageNotFoundException` if `id.package` is not found.
-  /// * Throws an `InvalidOutputException` if the output was not valid.
-  Future<void> writeAsBytes(AssetId id, List<int> bytes);
-
-  /// Writes [contents] to a text file located at [id] with [encoding].
-  ///
-  /// Returns a [Future] that completes after writing the asset out.
-  ///
-  /// * Throws a `PackageNotFoundException` if `id.package` is not found.
-  /// * Throws an `InvalidOutputException` if the output was not valid.
-  Future<void> writeAsString(AssetId id, String contents,
-      {Encoding encoding = utf8});
-}
-
-/// An [AssetWriter] which tracks all [assetsWritten] during its lifetime.
-class AssetWriterSpy implements AssetWriter {
-  final AssetWriter _delegate;
-  final _assetsWritten = Set<AssetId>();
-
-  AssetWriterSpy(this._delegate);
-
-  Iterable<AssetId> get assetsWritten => _assetsWritten;
-
-  @override
-  Future<void> writeAsBytes(AssetId id, List<int> bytes) {
-    _assetsWritten.add(id);
-    return _delegate.writeAsBytes(id, bytes);
-  }
-
-  @override
-  Future<void> writeAsString(AssetId id, String contents,
-      {Encoding encoding = utf8}) {
-    _assetsWritten.add(id);
-    return _delegate.writeAsString(id, contents, encoding: encoding);
-  }
-}
diff --git a/build/lib/src/builder/build_step.dart b/build/lib/src/builder/build_step.dart
deleted file mode 100644
index fb7a159..0000000
--- a/build/lib/src/builder/build_step.dart
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:analyzer/dart/element/element.dart';
-
-import '../analyzer/resolver.dart';
-import '../asset/id.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../resource/resource.dart';
-
-/// A single step in a build process.
-///
-/// This represents a single [inputId], logic around resolving as a library,
-/// and the ability to read and write assets as allowed by the underlying build
-/// system.
-abstract class BuildStep implements AssetReader, AssetWriter {
-  /// The primary for this build step.
-  AssetId get inputId;
-
-  /// Resolved library defined by [inputId].
-  ///
-  /// Throws [NonLibraryAssetException] if [inputId] is not a Dart library file.
-  Future<LibraryElement> get inputLibrary;
-
-  /// Gets an instance provided by [resource] which is guaranteed to be unique
-  /// within a single build, and may be reused across build steps within a
-  /// build if the implementation allows.
-  ///
-  /// It is also guaranteed that [resource] will be disposed before the next
-  /// build starts (and the dispose callback will be invoked if provided).
-  Future<T> fetchResource<T>(Resource<T> resource);
-
-  /// Writes [bytes] to a binary file located at [id].
-  ///
-  /// Returns a [Future] that completes after writing the asset out.
-  ///
-  /// * Throws a `PackageNotFoundException` if `id.package` is not found.
-  /// * Throws an `InvalidOutputException` if the output was not valid.
-  ///
-  /// **NOTE**: Most `Builder` implementations should not need to `await` this
-  /// Future since the runner will be responsible for waiting until all outputs
-  /// are written.
-  @override
-  Future<void> writeAsBytes(AssetId id, FutureOr<List<int>> bytes);
-
-  /// Writes [contents] to a text file located at [id] with [encoding].
-  ///
-  /// Returns a [Future] that completes after writing the asset out.
-  ///
-  /// * Throws a `PackageNotFoundException` if `id.package` is not found.
-  /// * Throws an `InvalidOutputException` if the output was not valid.
-  ///
-  /// **NOTE**: Most `Builder` implementations should not need to `await` this
-  /// Future since the runner will be responsible for waiting until all outputs
-  /// are written.
-  @override
-  Future<void> writeAsString(AssetId id, FutureOr<String> contents,
-      {Encoding encoding = utf8});
-
-  /// A [Resolver] for [inputId].
-  Resolver get resolver;
-
-  /// Tracks performance of [action] separately.
-  ///
-  /// If performance tracking is enabled, tracks [action] as separate stage
-  /// identified by [label]. Otherwise just runs [action].
-  ///
-  /// You can specify [action] as [isExternal] (waiting for some external
-  /// resource like network, process or file IO). In that case [action] will
-  /// be tracked as single time slice from the beginning of the stage till
-  /// completion of Future returned by [action].
-  ///
-  /// Otherwise all separate time slices of asynchronous execution will be
-  /// tracked, but waiting for external resources will be a gap.
-  ///
-  /// Returns value returned by [action].
-  /// [action] can be async function returning [Future].
-  T trackStage<T>(String label, T Function() action, {bool isExternal = false});
-
-  /// Indicates that [ids] were read but their content has no impact on the
-  /// outputs of this step.
-  ///
-  /// **WARNING**: Using this introduces serious risk of non-hermetic builds.
-  ///
-  /// If these files change or become unreadable on the next build this build
-  /// step may not run.
-  ///
-  /// **Note**: This is not guaranteed to have any effect and it should be
-  /// assumed to be a no-op by default. Implementations must explicitly
-  /// choose to support this feature.
-  void reportUnusedAssets(Iterable<AssetId> ids);
-}
-
-abstract class StageTracker {
-  T trackStage<T>(String label, T Function() action, {bool isExternal = false});
-}
-
-class NoOpStageTracker implements StageTracker {
-  static const StageTracker instance = NoOpStageTracker._();
-
-  @override
-  T trackStage<T>(String label, T Function() action,
-          {bool isExternal = false}) =>
-      action();
-
-  const NoOpStageTracker._();
-}
diff --git a/build/lib/src/builder/build_step_impl.dart b/build/lib/src/builder/build_step_impl.dart
deleted file mode 100644
index 65e0aaa..0000000
--- a/build/lib/src/builder/build_step_impl.dart
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:async/async.dart';
-import 'package:build/src/builder/build_step.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-import '../analyzer/resolver.dart';
-import '../asset/exceptions.dart';
-import '../asset/id.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../resource/resource.dart';
-import 'build_step.dart';
-import 'exceptions.dart';
-
-/// A single step in the build processes.
-///
-/// This represents a single input and its expected and real outputs. It also
-/// handles tracking of dependencies.
-class BuildStepImpl implements BuildStep {
-  final Resolvers _resolvers;
-  final StageTracker _stageTracker;
-
-  /// The primary input id for this build step.
-  @override
-  final AssetId inputId;
-
-  @override
-  Future<LibraryElement> get inputLibrary async {
-    if (_isComplete) throw BuildStepCompletedException();
-    return resolver.libraryFor(inputId);
-  }
-
-  /// The list of all outputs which are expected/allowed to be output from this
-  /// step.
-  final Set<AssetId> _expectedOutputs;
-
-  /// The result of any writes which are starting during this step.
-  final _writeResults = <Future<Result<void>>>[];
-
-  /// Used internally for reading files.
-  final AssetReader _reader;
-
-  /// Used internally for writing files.
-  final AssetWriter _writer;
-
-  /// The current root package, used for input/output validation.
-  final String _rootPackage;
-
-  final ResourceManager _resourceManager;
-
-  bool _isComplete = false;
-
-  final void Function(Iterable<AssetId>) _reportUnusedAssets;
-
-  BuildStepImpl(this.inputId, Iterable<AssetId> expectedOutputs, this._reader,
-      this._writer, this._rootPackage, this._resolvers, this._resourceManager,
-      {StageTracker stageTracker,
-      void Function(Iterable<AssetId>) reportUnusedAssets})
-      : _expectedOutputs = expectedOutputs.toSet(),
-        _stageTracker = stageTracker ?? NoOpStageTracker.instance,
-        _reportUnusedAssets = reportUnusedAssets;
-
-  @override
-  Resolver get resolver {
-    if (_isComplete) throw BuildStepCompletedException();
-    return _DelayedResolver(_resolver ??= _resolvers.get(this));
-  }
-
-  Future<ReleasableResolver> _resolver;
-
-  @override
-  Future<bool> canRead(AssetId id) {
-    if (_isComplete) throw BuildStepCompletedException();
-    _checkInput(id);
-    return _reader.canRead(id);
-  }
-
-  @override
-  Future<T> fetchResource<T>(Resource<T> resource) {
-    if (_isComplete) throw BuildStepCompletedException();
-    return _resourceManager.fetch(resource);
-  }
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) {
-    if (_isComplete) throw BuildStepCompletedException();
-    _checkInput(id);
-    return _reader.readAsBytes(id);
-  }
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) {
-    if (_isComplete) throw BuildStepCompletedException();
-    _checkInput(id);
-    return _reader.readAsString(id, encoding: encoding);
-  }
-
-  @override
-  Stream<AssetId> findAssets(Glob glob) {
-    if (_isComplete) throw BuildStepCompletedException();
-    if (_reader is MultiPackageAssetReader) {
-      return (_reader as MultiPackageAssetReader)
-          .findAssets(glob, package: inputId?.package ?? _rootPackage);
-    } else {
-      return _reader.findAssets(glob);
-    }
-  }
-
-  @override
-  Future<void> writeAsBytes(AssetId id, FutureOr<List<int>> bytes) {
-    if (_isComplete) throw BuildStepCompletedException();
-    _checkOutput(id);
-    var done =
-        _futureOrWrite(bytes, (List<int> b) => _writer.writeAsBytes(id, b));
-    _writeResults.add(Result.capture(done));
-    return done;
-  }
-
-  @override
-  Future<void> writeAsString(AssetId id, FutureOr<String> content,
-      {Encoding encoding = utf8}) {
-    if (_isComplete) throw BuildStepCompletedException();
-    _checkOutput(id);
-    var done = _futureOrWrite(content,
-        (String c) => _writer.writeAsString(id, c, encoding: encoding));
-    _writeResults.add(Result.capture(done));
-    return done;
-  }
-
-  @override
-  Future<Digest> digest(AssetId id) {
-    if (_isComplete) throw BuildStepCompletedException();
-    _checkInput(id);
-    return _reader.digest(id);
-  }
-
-  @override
-  T trackStage<T>(String label, T Function() action,
-          {bool isExternal = false}) =>
-      _stageTracker.trackStage(label, action, isExternal: isExternal);
-
-  Future<void> _futureOrWrite<T>(
-          FutureOr<T> content, Future<void> write(T content)) =>
-      (content is Future<T>) ? content.then(write) : write(content as T);
-
-  /// Waits for work to finish and cleans up resources.
-  ///
-  /// This method should be called after a build has completed. After the
-  /// returned [Future] completes then all outputs have been written and the
-  /// [Resolver] for this build step - if any - has been released.
-  Future<void> complete() async {
-    _isComplete = true;
-    await Future.wait(_writeResults.map(Result.release));
-    (await _resolver)?.release();
-  }
-
-  /// Checks that [id] is a valid input, and throws an [InvalidInputException]
-  /// if its not.
-  void _checkInput(AssetId id) {
-    if (id.package != _rootPackage && !id.path.startsWith('lib/')) {
-      throw InvalidInputException(id);
-    }
-  }
-
-  /// Checks that [id] is an expected output, and throws an
-  /// [InvalidOutputException] or [UnexpectedOutputException] if it's not.
-  void _checkOutput(AssetId id) {
-    if (!_expectedOutputs.contains(id)) {
-      throw UnexpectedOutputException(id, expected: _expectedOutputs);
-    }
-  }
-
-  @override
-  void reportUnusedAssets(Iterable<AssetId> assets) {
-    if (_reportUnusedAssets != null) _reportUnusedAssets(assets);
-  }
-}
-
-class _DelayedResolver implements Resolver {
-  final Future<Resolver> _delegate;
-
-  _DelayedResolver(this._delegate);
-
-  @override
-  Future<bool> isLibrary(AssetId assetId) async =>
-      (await _delegate).isLibrary(assetId);
-
-  @override
-  Stream<LibraryElement> get libraries {
-    var completer = StreamCompleter<LibraryElement>();
-    _delegate.then((r) => completer.setSourceStream(r.libraries));
-    return completer.stream;
-  }
-
-  @override
-  Future<LibraryElement> libraryFor(AssetId assetId) async =>
-      (await _delegate).libraryFor(assetId);
-
-  @override
-  Future<LibraryElement> findLibraryByName(String libraryName) async =>
-      (await _delegate).findLibraryByName(libraryName);
-
-  @override
-  Future<AssetId> assetIdForElement(Element element) async =>
-      (await _delegate).assetIdForElement(element);
-}
diff --git a/build/lib/src/builder/builder.dart b/build/lib/src/builder/builder.dart
deleted file mode 100644
index 1c97f40..0000000
--- a/build/lib/src/builder/builder.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-
-import 'build_step.dart';
-
-/// The basic builder class, used to build new files from existing ones.
-abstract class Builder {
-  /// Generates the outputs for a given [BuildStep].
-  FutureOr<void> build(BuildStep buildStep);
-
-  /// Mapping from input file extension to output file extensions.
-  ///
-  /// All input sources matching any key in this map will be passed as build
-  /// step to this builder. Only files with the same basename and an extension
-  /// from the values in this map are expected as outputs.
-  ///
-  /// - If an empty key exists, all inputs are considered matching.
-  /// - A builder must always return the same configuration. Typically this will
-  /// be `const` but may vary based on build arguments.
-  /// - Most builders will use a single input extension and one or more output
-  /// extensions.
-  Map<String, List<String>> get buildExtensions;
-}
-
-class BuilderOptions {
-  /// A configuration with no options set.
-  static const empty = BuilderOptions({});
-
-  /// A configuration with [isRoot] set to `true`, and no options set.
-  static const forRoot = BuilderOptions({}, isRoot: true);
-
-  /// The configuration to apply to a given usage of a [Builder].
-  ///
-  /// A `Map` parsed from json or yaml. The value types will be `String`, `num`,
-  /// `bool` or `List` or `Map` of these types.
-  final Map<String, dynamic> config;
-
-  /// Whether or not this builder is running on the root package.
-  final bool isRoot;
-
-  const BuilderOptions(this.config, {bool isRoot}) : isRoot = isRoot ?? false;
-
-  /// Returns a new set of options with keys from [other] overriding options in
-  /// this instance.
-  ///
-  /// Config values are overridden at a per-key granularity. There is no value
-  /// level merging. [other] may be null, in which case this instance is
-  /// returned directly.
-  ///
-  /// The `isRoot` value will also be overridden to value from [other].
-  BuilderOptions overrideWith(BuilderOptions other) {
-    if (other == null) return this;
-    return BuilderOptions({}..addAll(config)..addAll(other.config),
-        isRoot: other.isRoot);
-  }
-}
-
-/// Creates a [Builder] honoring the configuation in [options].
-typedef BuilderFactory = Builder Function(BuilderOptions options);
diff --git a/build/lib/src/builder/exceptions.dart b/build/lib/src/builder/exceptions.dart
deleted file mode 100644
index 8458b05..0000000
--- a/build/lib/src/builder/exceptions.dart
+++ /dev/null
@@ -1,15 +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 '../asset/id.dart';
-
-class UnexpectedOutputException implements Exception {
-  final AssetId assetId;
-  final Iterable<AssetId> expected;
-
-  UnexpectedOutputException(this.assetId, {this.expected});
-
-  @override
-  String toString() => 'UnexpectedOutputException: $assetId'
-      '${expected == null ? '' : '\nExpected only: $expected'}';
-}
diff --git a/build/lib/src/builder/file_deleting_builder.dart b/build/lib/src/builder/file_deleting_builder.dart
deleted file mode 100644
index 4621039..0000000
--- a/build/lib/src/builder/file_deleting_builder.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:glob/glob.dart';
-
-import 'post_process_build_step.dart';
-import 'post_process_builder.dart';
-
-/// A [PostProcessBuilder] which can be configured to consume any input
-/// extensions and always deletes it primary input.
-class FileDeletingBuilder implements PostProcessBuilder {
-  @override
-  final List<String> inputExtensions;
-
-  final bool isEnabled;
-  final List<Glob> exclude;
-
-  const FileDeletingBuilder(this.inputExtensions, {this.isEnabled = true})
-      : exclude = const [];
-
-  FileDeletingBuilder.withExcludes(
-      this.inputExtensions, Iterable<String> exclude,
-      {this.isEnabled = true})
-      : exclude = exclude?.map((s) => Glob(s))?.toList() ?? const [];
-
-  @override
-  FutureOr<Null> build(PostProcessBuildStep buildStep) {
-    if (!isEnabled) return null;
-    if (exclude.any((g) => g.matches(buildStep.inputId.path))) return null;
-    buildStep.deletePrimaryInput();
-    return null;
-  }
-}
diff --git a/build/lib/src/builder/logging.dart b/build/lib/src/builder/logging.dart
deleted file mode 100644
index a00e67e..0000000
--- a/build/lib/src/builder/logging.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'dart:async';
-
-import 'package:logging/logging.dart';
-
-const Symbol logKey = #buildLog;
-
-final _default = Logger('build.fallback');
-
-/// The log instance for the currently running BuildStep.
-///
-/// Will be `null` when not running within a build.
-Logger get log => Zone.current[logKey] as Logger ?? _default;
-
-/// Runs [fn] in an error handling [Zone].
-///
-/// Any calls to [print] will be logged with `log.warning`, and any errors will
-/// be logged with `log.severe`.
-///
-/// Completes with the first error or result of `fn`, whichever comes first.
-Future<T> scopeLogAsync<T>(Future<T> fn(), Logger log) {
-  var done = Completer<T>();
-  runZoned(fn,
-      zoneSpecification:
-          ZoneSpecification(print: (self, parent, zone, message) {
-        log.warning(message);
-      }),
-      zoneValues: {logKey: log},
-      onError: (Object e, StackTrace s) {
-        log.severe('', e, s);
-        if (done.isCompleted) return;
-        done.completeError(e, s);
-      }).then((result) {
-    if (done.isCompleted) return;
-    done.complete(result);
-  });
-  return done.future;
-}
diff --git a/build/lib/src/builder/multiplexing_builder.dart b/build/lib/src/builder/multiplexing_builder.dart
deleted file mode 100644
index e91ee15..0000000
--- a/build/lib/src/builder/multiplexing_builder.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-
-import 'build_step.dart';
-import 'builder.dart';
-
-/// A [Builder] that runs multiple delegate builders asynchronously.
-///
-/// **Note**: All builders are ran without ordering guarantees. Thus, none of
-/// the builders can use the outputs of other builders in this group. All
-/// builders must also have distinct outputs.
-class MultiplexingBuilder implements Builder {
-  final Iterable<Builder> _builders;
-
-  MultiplexingBuilder(this._builders);
-
-  @override
-  FutureOr<void> build(BuildStep buildStep) {
-    return Future.wait(_builders
-        .where((builder) =>
-            builder.buildExtensions.keys.any(buildStep.inputId.path.endsWith))
-        .map((builder) => builder.build(buildStep))
-        .whereType<Future<void>>());
-  }
-
-  /// Merges output extensions from all builders.
-  ///
-  /// If multiple builders declare the same output it will appear in this List
-  /// more than once. This should be considered an error.
-  @override
-  Map<String, List<String>> get buildExtensions =>
-      _mergeMaps(_builders.map((b) => b.buildExtensions));
-
-  @override
-  String toString() => '$_builders';
-}
-
-Map<String, List<String>> _mergeMaps(Iterable<Map<String, List<String>>> maps) {
-  var result = <String, List<String>>{};
-  for (var map in maps) {
-    for (var key in map.keys) {
-      result.putIfAbsent(key, () => []);
-      result[key].addAll(map[key]);
-    }
-  }
-  return result;
-}
diff --git a/build/lib/src/builder/post_process_build_step.dart b/build/lib/src/builder/post_process_build_step.dart
deleted file mode 100644
index 5fef55f..0000000
--- a/build/lib/src/builder/post_process_build_step.dart
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:crypto/src/digest.dart';
-
-// This is not exported to hack around a package-private constructor.
-PostProcessBuildStep postProcessBuildStep(
-        AssetId inputId,
-        AssetReader reader,
-        AssetWriter writer,
-        void Function(AssetId) addAsset,
-        void Function(AssetId) deleteAsset) =>
-    PostProcessBuildStep._(inputId, reader, writer, addAsset, deleteAsset);
-
-/// A simplified [BuildStep] which can only read its primary input, and can't
-/// get a [Resolver] or any [Resource]s, at least for now.
-class PostProcessBuildStep {
-  final AssetId inputId;
-
-  final AssetReader _reader;
-  final AssetWriter _writer;
-  final void Function(AssetId) _addAsset;
-  final void Function(AssetId) _deleteAsset;
-
-  /// The result of any writes which are starting during this step.
-  final _writeResults = <Future<Result<void>>>[];
-
-  PostProcessBuildStep._(this.inputId, this._reader, this._writer,
-      this._addAsset, this._deleteAsset);
-
-  Future<Digest> digest(AssetId id) => inputId == id
-      ? _reader.digest(id)
-      : Future.error(InvalidInputException(id));
-
-  Future<List<int>> readInputAsBytes() => _reader.readAsBytes(inputId);
-
-  Future<String> readInputAsString({Encoding encoding = utf8}) =>
-      _reader.readAsString(inputId, encoding: encoding);
-
-  Future<void> writeAsBytes(AssetId id, FutureOr<List<int>> bytes) {
-    _addAsset(id);
-    var done =
-        _futureOrWrite(bytes, (List<int> b) => _writer.writeAsBytes(id, b));
-    _writeResults.add(Result.capture(done));
-    return done;
-  }
-
-  Future<void> writeAsString(AssetId id, FutureOr<String> content,
-      {Encoding encoding = utf8}) {
-    _addAsset(id);
-    var done = _futureOrWrite(content,
-        (String c) => _writer.writeAsString(id, c, encoding: encoding));
-    _writeResults.add(Result.capture(done));
-    return done;
-  }
-
-  /// Marks an asset for deletion in the post process step.
-  void deletePrimaryInput() {
-    _deleteAsset(inputId);
-  }
-
-  /// Waits for work to finish and cleans up resources.
-  ///
-  /// This method should be called after a build has completed. After the
-  /// returned [Future] completes then all outputs have been written.
-  Future<void> complete() async {
-    await Future.wait(_writeResults.map(Result.release));
-  }
-}
-
-Future<void> _futureOrWrite<T>(
-        FutureOr<T> content, Future<void> write(T content)) =>
-    (content is Future<T>) ? content.then(write) : write(content as T);
diff --git a/build/lib/src/builder/post_process_builder.dart b/build/lib/src/builder/post_process_builder.dart
deleted file mode 100644
index 074f1d1..0000000
--- a/build/lib/src/builder/post_process_builder.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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 'builder.dart';
-import 'post_process_build_step.dart';
-
-/// A builder which runes in a special phase at the end of the build.
-///
-/// They are different from a normal [Builder] in several ways:
-///
-/// - They don't have to declare output extensions, and can output any file as
-///   long as it doesn't conflict with an existing one.
-/// - They can only read their primary input.
-/// - They will not cause optional actions to run - they will only run on assets
-///   that were built as a part of the normal build.
-/// - They all run in a single phase, and thus can not see the outputs of any
-///   other [PostProcessBuilder]s.
-/// - Because they run in a separate phase, after other builders, none of thier
-///   outputs can be consumed by [Builder]s.
-///
-/// Because of these restrictions, these builders should never be used to output
-/// Dart files, or any other file which would should be processed by normal
-/// [Builder]s.
-abstract class PostProcessBuilder {
-  /// The extensions this builder expects for its inputs.
-  Iterable<String> get inputExtensions;
-
-  /// Generates the outputs and deletes for [buildStep].
-  FutureOr<void> build(PostProcessBuildStep buildStep);
-}
-
-typedef PostProcessBuilderFactory = PostProcessBuilder Function(BuilderOptions);
diff --git a/build/lib/src/generate/expected_outputs.dart b/build/lib/src/generate/expected_outputs.dart
deleted file mode 100644
index 9d3425a..0000000
--- a/build/lib/src/generate/expected_outputs.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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 '../asset/id.dart';
-import '../builder/builder.dart';
-
-/// Collects the expected AssetIds created by [builder] when given [input] based
-/// on the extension configuration.
-Iterable<AssetId> expectedOutputs(Builder builder, AssetId input) {
-  var matchingExtensions =
-      builder.buildExtensions.keys.where((e) => input.path.endsWith(e));
-  return matchingExtensions
-      .expand((e) => _replaceExtensions(input, e, builder.buildExtensions[e]));
-}
-
-Iterable<AssetId> _replaceExtensions(
-        AssetId assetId, String oldExtension, List<String> newExtensions) =>
-    newExtensions.map((n) => _replaceExtension(assetId, oldExtension, n));
-
-AssetId _replaceExtension(
-    AssetId assetId, String oldExtension, String newExtension) {
-  var path = assetId.path;
-  assert(path.endsWith(oldExtension));
-  return AssetId(
-      assetId.package,
-      path.replaceRange(
-          path.length - oldExtension.length, path.length, newExtension));
-}
diff --git a/build/lib/src/generate/run_builder.dart b/build/lib/src/generate/run_builder.dart
deleted file mode 100644
index fbceb53..0000000
--- a/build/lib/src/generate/run_builder.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-
-import 'package:logging/logging.dart';
-
-import '../analyzer/resolver.dart';
-import '../asset/id.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../builder/build_step.dart';
-import '../builder/build_step_impl.dart';
-import '../builder/builder.dart';
-import '../builder/logging.dart';
-import '../resource/resource.dart';
-import 'expected_outputs.dart';
-
-/// Run [builder] with each asset in [inputs] as the primary input.
-///
-/// Builds for all inputs are run asynchronously and ordering is not guaranteed.
-/// The [log] instance inside the builds will be scoped to [logger] which is
-/// defaulted to a [Logger] name 'runBuilder'.
-///
-/// If a [resourceManager] is provided it will be used and it will not be
-/// automatically disposed of (its up to the caller to dispose of it later). If
-/// one is not provided then one will be created and disposed at the end of
-/// this function call.
-///
-/// If [reportUnusedAssetsForInput] is provided then all calls to
-/// `BuildStep.reportUnusedAssets` in [builder] will be forwarded to this
-/// function with the associated primary input.
-Future<void> runBuilder(Builder builder, Iterable<AssetId> inputs,
-    AssetReader reader, AssetWriter writer, Resolvers resolvers,
-    {Logger logger,
-    ResourceManager resourceManager,
-    String rootPackage,
-    StageTracker stageTracker = NoOpStageTracker.instance,
-    void Function(AssetId input, Iterable<AssetId> assets)
-        reportUnusedAssetsForInput}) async {
-  var shouldDisposeResourceManager = resourceManager == null;
-  resourceManager ??= ResourceManager();
-  logger ??= Logger('runBuilder');
-  //TODO(nbosch) check overlapping outputs?
-  Future<void> buildForInput(AssetId input) async {
-    var outputs = expectedOutputs(builder, input);
-    if (outputs.isEmpty) return;
-    var buildStep = BuildStepImpl(input, outputs, reader, writer,
-        rootPackage ?? input.package, resolvers, resourceManager,
-        stageTracker: stageTracker,
-        reportUnusedAssets: reportUnusedAssetsForInput == null
-            ? null
-            : (assets) => reportUnusedAssetsForInput(input, assets));
-    try {
-      await builder.build(buildStep);
-    } finally {
-      await buildStep.complete();
-    }
-  }
-
-  await scopeLogAsync(() => Future.wait(inputs.map(buildForInput)), logger);
-
-  if (shouldDisposeResourceManager) {
-    await resourceManager.disposeAll();
-    await resourceManager.beforeExit();
-  }
-}
diff --git a/build/lib/src/generate/run_post_process_builder.dart b/build/lib/src/generate/run_post_process_builder.dart
deleted file mode 100644
index a4945fb..0000000
--- a/build/lib/src/generate/run_post_process_builder.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:logging/logging.dart';
-import 'package:meta/meta.dart';
-
-import '../asset/id.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../builder/logging.dart';
-import '../builder/post_process_build_step.dart';
-import '../builder/post_process_builder.dart';
-
-/// Run [builder] with [inputId] as the primary input.
-///
-/// [addAsset] should update the build systems knowledge of what assets exist.
-/// If an asset should not be written this function should throw.
-/// [deleteAsset] should remove the asset from the build system, it will not be
-/// deleted on disk since the `writer` has no mechanism for delete.
-Future<void> runPostProcessBuilder(PostProcessBuilder builder, AssetId inputId,
-    AssetReader reader, AssetWriter writer, Logger logger,
-    {@required void Function(AssetId) addAsset,
-    @required void Function(AssetId) deleteAsset}) async {
-  await scopeLogAsync(() async {
-    var buildStep =
-        postProcessBuildStep(inputId, reader, writer, addAsset, deleteAsset);
-    try {
-      await builder.build(buildStep);
-    } finally {
-      await buildStep.complete();
-    }
-  }, logger);
-}
diff --git a/build/lib/src/resource/resource.dart b/build/lib/src/resource/resource.dart
deleted file mode 100644
index 8e786de..0000000
--- a/build/lib/src/resource/resource.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-typedef CreateInstance<T> = FutureOr<T> Function();
-typedef DisposeInstance<T> = FutureOr<void> Function(T instance);
-typedef BeforeExit = FutureOr<void> Function();
-
-/// A [Resource] encapsulates the logic for creating and disposing of some
-/// expensive object which has a lifecycle.
-///
-/// Actual [Resource]s should be retrieved using `BuildStep#fetchResource`.
-///
-/// Build system implementations should be the only users that directly
-/// instantiate a [ResourceManager] since they can handle the lifecycle
-/// guarantees in a sane way.
-class Resource<T> {
-  /// Factory method which creates an instance of this resource.
-  final CreateInstance<T> _create;
-
-  /// Optional method which is given an existing instance that is ready to be
-  /// disposed.
-  final DisposeInstance<T> _userDispose;
-
-  /// Optional method which is called before the process is going to exit.
-  ///
-  /// This allows resources to do any final cleanup, and is not given an
-  /// instance.
-  final BeforeExit _userBeforeExit;
-
-  /// A Future instance of this resource if one has ever been requested.
-  final _instanceByManager = <ResourceManager, Future<T>>{};
-
-  Resource(this._create, {DisposeInstance<T> dispose, BeforeExit beforeExit})
-      : _userDispose = dispose,
-        _userBeforeExit = beforeExit;
-
-  /// Fetches an actual instance of this resource for [manager].
-  Future<T> _fetch(ResourceManager manager) =>
-      _instanceByManager.putIfAbsent(manager, () async => await _create());
-
-  /// Disposes the actual instance of this resource for [manager] if present.
-  Future<void> _dispose(ResourceManager manager) {
-    if (!_instanceByManager.containsKey(manager)) return Future.value(null);
-    var oldInstance = _fetch(manager);
-    _instanceByManager.remove(manager);
-    if (_userDispose != null) {
-      return oldInstance.then(_userDispose);
-    } else {
-      return Future.value(null);
-    }
-  }
-}
-
-/// Manages fetching and disposing of a group of [Resource]s.
-///
-/// This is an internal only API which should only be used by build system
-/// implementations and not general end users. Instead end users should use
-/// the `buildStep#fetchResource` method to get [Resource]s.
-class ResourceManager {
-  final _resources = Set<Resource<void>>();
-
-  /// The [Resource]s that we need to call `beforeExit` on.
-  ///
-  /// We have to hang on to these forever, but they should be small in number,
-  /// and we don't hold on to the actual created instances, just the [Resource]
-  /// instances.
-  final _resourcesWithBeforeExit = Set<Resource<void>>();
-
-  /// Fetches an instance of [resource].
-  Future<T> fetch<T>(Resource<T> resource) async {
-    if (resource._userBeforeExit != null) {
-      _resourcesWithBeforeExit.add(resource);
-    }
-    _resources.add(resource);
-    return resource._fetch(this);
-  }
-
-  /// Disposes of all [Resource]s fetched since the last call to [disposeAll].
-  Future<Null> disposeAll() {
-    var done = Future.wait(_resources.map((r) => r._dispose(this)));
-    _resources.clear();
-    return done.then((_) => null);
-  }
-
-  /// Invokes the `beforeExit` callbacks of all [Resource]s that had one.
-  Future<Null> beforeExit() async {
-    await Future.wait(_resourcesWithBeforeExit.map((r) async {
-      if (r._userBeforeExit != null) return r._userBeforeExit();
-    }));
-    _resourcesWithBeforeExit.clear();
-  }
-}
diff --git a/build/mono_pkg.yaml b/build/mono_pkg.yaml
deleted file mode 100644
index dc1b387..0000000
--- a/build/mono_pkg.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-      - dartfmt: sdk
-      - dartanalyzer: --fatal-infos --fatal-warnings .
-    - dartanalyzer: --fatal-warnings .
-      dart:
-        - 2.3.0
-  - unit_test:
-    - command: pub run build_runner test
-      os:
-        - linux
-        - windows
-
-cache:
-  directories:
-  - .dart_tool/build
diff --git a/build/pubspec.yaml b/build/pubspec.yaml
deleted file mode 100644
index dbbe0c0..0000000
--- a/build/pubspec.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: build
-version: 1.2.2
-description: A build system for Dart.
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/build/tree/master/build
-
-environment:
-  sdk: ">=2.3.0 <3.0.0"
-
-dependencies:
-  analyzer: '>=0.35.0 <0.40.0'
-  async: ">=1.13.3 <3.0.0"
-  convert: ^2.0.0
-  crypto: ">=0.9.2 <3.0.0"
-  logging: ^0.11.2
-  meta: ^1.1.0
-  path: ^1.1.0
-  glob: ^1.1.0
-
-dev_dependencies:
-  build_resolvers: ^1.0.0
-  build_runner: ^1.0.0
-  build_test: ^0.10.0
-  build_vm_compilers: ">=0.1.0 <2.0.0"
-  pedantic: ^1.0.0
-  test: ^1.2.0
diff --git a/build_config/BUILD.gn b/build_config/BUILD.gn
deleted file mode 100644
index 2b434b9..0000000
--- a/build_config/BUILD.gn
+++ /dev/null
@@ -1,22 +0,0 @@
-# This file is generated by importer.py for build_config-0.4.2
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_config") {
-  package_name = "build_config"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/yaml",
-    "//third_party/dart-pkg/pub/meta",
-    "//third_party/dart-pkg/pub/json_annotation",
-    "//third_party/dart-pkg/pub/pubspec_parse",
-    "//third_party/dart-pkg/pub/path",
-    "//third_party/dart-pkg/pub/checked_yaml",
-  ]
-}
diff --git a/build_config/CHANGELOG.md b/build_config/CHANGELOG.md
deleted file mode 100644
index 80d5976..0000000
--- a/build_config/CHANGELOG.md
+++ /dev/null
@@ -1,174 +0,0 @@
-## 0.4.2
-
-- Add support for an `auto_apply_builders` option to the `target` config.
-  - Defaults to `true` (the previous behavior), setting it to `false`
-    means all builders have to be explicitly enabled. 
-
-## 0.4.1+1
-
-- Support the latest release of `package:json_annotation`.
-- Increased the lower bound for the Dart SDK to `>=2.3.0`.
-
-## 0.4.1
-
-- Added optional `configYamlPath` parameter to `BuildConfig.parse`. When
-  provided, errors reported when parsing build configuration will include
-  the file path.
-
-## 0.4.0
-
-- Breaking for build systems - change type of `BuilderOptions` fields to
-  `Map<String, dynamic>` to drop dependency on `build`. Does not impact packages
-  only depending on `build.yaml` parsing.
-- Breaking for build systems - versioning scheme is changing to match
-  `package:build`. Changes which are breaking to _users_ - those with
-  `build.yaml` files will be indicated with a breaking major version bump.
-  Changed which are breaking to build system _implementors_ - those who use the
-  Dart API for this package, will be indicated with a minor version bump.
-
-## 0.3.2
-
-- Add an explicit error when `buildExtensions` is configured to overwrite it's
-  input.
-- Add an explicit error when an `InputSet` has an empty or null value in a glob
-  list.
-- Increase lower bound SDK constraint to 2.0.0.
-- Normalize builder keys with the legacy `|` separator to use `:` instead.
-
-## 0.3.1+4
-
-- Support the latest `package:json_annotation`.
-
-## 0.3.1+3
-
-- Support `package:build` version `1.x.x`.
-
-## 0.3.1+2
-
-- Support `package:json_annotation` v1.
-
-## 0.3.1+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.3.1
-
-- Improve validation and errors when parsing `build.yaml`.
-- Add `BuildConfig.globalOptions` support.
-
-## 0.3.0
-
-- Parsing of `build.yaml` files is now done with the `json_serializable` package
-  and is Dart 2 compatible.
-
-  - The error reporting will be a bit different, but generally should be better,
-    and will include the yaml spans of the problem sections.
-
-### Breaking Changes
-
-There are no changes to the `build.yaml` format, the following changes only
-affect the imperative apis of this package.
-
-- The Constructors for most of the build config classes other than `BuildConfig`
-  itself now have to be ran inside a build config zone, which can be done using
-  the `runInBuildConfigZone` function. This gives the context about what package
-  is currently being parsed, as well as what the default dependencies should be
-  for targets.
-- Many constructor signatures have changed, for the most part removing the
-  `package` parameter (it is now read off the zone).
-
-## 0.2.6+2
-
-- Restore error for missing default target.
-
-## 0.2.6+1
-
-- Restore error for missing build extensions.
-
-## 0.2.6
-
-- The `target` and `build_extensions` keys for builder definitions are now
-  optional and should be omitted in most cases since they are currently unused.
-- Support options based on mode, add `devOptions` and `releaseOptions` on
-  `TargetBuilderConfig`.
-- Support applying default options based on builder definitions, add `option`,
-  `devOptions`, and `releaseOptions` to `TargetBuilderConfigDefaults`.
-- Ensure that `defaults` and `generateFor` fields are never null.
-- Add `InputSet.anything` to name the input sets that don't filter out any
-  assets.
-
-## 0.2.5
-
-- Added `post_process_builders` section to `build.yaml`. See README.md for more
-  information.-dev
-- Adds support for `$default` as a _dependency_, i.e.:
-
-```yaml
-targets:
-  $default:
-    ...
-  foo:
-    dependencies:
-      - $default
-```
-
-## 0.2.4
-
-- Add support for `runs_before` in `BuilderDefinition`.
-
-## 0.2.3
-
-- Expose key normalization methods publicly, these include:
-  - `normalizeBuilderKeyUsage`
-  - `normalizeTargetKeyUsage`
-
-## 0.2.2+1
-
-- Expand support for `package:build` to include version `0.12.0`.
-
-## 0.2.2
-
-- **Bug fix**: Empty build.yaml files no longer fail to parse.
-- Allow `$default` as a target name to get he package name automatically filled
-  in.
-
-## 0.2.1
-
-- Change the default for `BuilderDefinition.buildTo` to `BuildTo.cache`.
-  Builders which want to operate on the source tree will need to explicitly opt
-  in. Allow this regardless of the value of `autoApply` and the build system
-  will need to filter out the builders that can't run.
-- By default including any configuration for a Builder within a BuildTarget will
-  enabled that builder.
-
-## 0.2.0
-
-- Add `build_to` option to Builder configuration.
-- Add `BuildConfig.fromBuildConfigDir` for cases where the package name and
-  dependencies are already known.
-- Add `TargetBuilderConfig` class to configure builders applied to specific
-  targets.
-- Add `TargetBuilderConfigDefaults` class for Builder authors to provide default
-  configuration.
-- Add `InputSet` and change `sources` and `generate_for` to use it.
-- Remove `BuildTarget.isDefault` and related config parsing. The default will be
-  determined by the target which matches the package name.
-- Normalize Target and Builder names so they are scoped to the package they are
-  defined in.
-
-### Breaking
-
-- Remove `BuildConfigSet` class. This was unused.
-- Hide `Pubspec` class. Construct `BuildConfig` instances with a package path
-  rather than an already created `Pubspec` instance.
-
-## 0.1.1
-
-- Add `auto_apply` option to Builder configuration.
-- Add `required_inputs` option to Builder configuration.
-- Add `is_optional` option to Builder configuration.
-
-## 0.1.0
-
-- Initial release - pulled from `package:dazel`. Updated to support
-  `build_extensions` instead of `input_extension` and `output_extensions`.
diff --git a/build_config/LICENSE b/build_config/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/build_config/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_config/README.md b/build_config/README.md
deleted file mode 100644
index e759cf4..0000000
--- a/build_config/README.md
+++ /dev/null
@@ -1,239 +0,0 @@
-# Customizing builds
-
-Customizing the build behavior of a package is done  by creating a `build.yaml`
-file, which describes your configuration.
-
-The full format is described in the
-[docs/build_yaml_format.md](https://github.com/dart-lang/build/blob/master/docs/build_yaml_format.md)
-file, while this documentation is more focused on specific usage scenarios of
-the file.
-
-## Dividing a package into Build targets
-
-When a `Builder` should be applied to a subset of files in a package the package
-can be broken up into multiple 'targets'. Targets are configured in the
-`targets` section of the `build.yaml`. The key for each target makes up the name
-for that target. Targets can be referred to in
-`'$definingPackageName:$targetname'`. When the target name matches the package
-name it can also be referred to as just the package name. One target in every
-package _must_ use the package name so that consumers will use it by default.
-In the `build.yaml` file this target can be defined with the key `$default` or
-with the name of the package.
-
-Each target may also contain the following keys:
-
-- **sources**: List of Strings or Map, Optional. The set of files within the
-  package which make up this target. Files are specified using glob syntax. If a
-  List of Strings is used they are considered the 'include' globs. If a Map is
-  used can only have the keys `include` and `exclude`. Any file which matches
-  any glob in `include` and no globs in `exclude` is considered a source of the
-  target. When `include` is omitted every file is considered a match.
-- **dependencies**: List of Strings, Optional. The targets that this target
-  depends on. Strings in the format `'$packageName:$targetName'` to depend on a
-  target within a package or `$packageName` to depend on a package's default
-  target. By default this is all of the package names this package depends on
-  (from the `pubspec.yaml`).
-- **builders**: Map, Optional. See "configuring builders" below.
-
-## Configuring `Builder`s applied to your package
-Each target can specify a `builders` key which configures the builders which are
-applied to that target. The value is a Map from builder to configuration for
-that builder. The key is in the format `'$packageName:$builderName'`. The
-configuration may have the following keys:
-
-- **enabled**: Boolean, Optional: Whether to apply the builder to this target.
-  Omit this key if you want the default behavior based on the builder's
-  `auto_apply` configuration. Builders which are manually applied
-  (`auto_apply: none`) are only ever used when there is a target specifying the
-  builder with `enabled: True`.
-- **generate_for**: List of String or Map, Optional:. The subset of files within
-  the target's `sources` which should have this Builder applied. See `sources`
-  configuration above for how to configure this.
-- **options**: Map, Optional: A free-form map which will be passed to the
-  `Builder` as a `BuilderOptions` when it is constructed. Usage varies depending
-  on the particular builder. Values in this map will override the default
-  provided by builder authors. Values may also be overridden based on the build
-  mode with `dev_options` or `release_options`.
-- **dev_options**: Map, Optional: A free-form map which will be passed to the
-  `Builder` as a `BuilderOptions` when it is constructed. Usage varies depending
-  on the particular builder. The values in this map override Builder defaults or
-  non mode-specific options per-key when the build is done in dev mode.
-- **release_options**: Map, Optional: A free-form map which will be passed to
-  the `Builder` as a `BuilderOptions` when it is constructed. Usage varies
-  depending on the particular builder. The values in this map override Builder
-  defaults or non mode-specific options when the build is done in release mode.
-
-## Configuring `Builder`s globally
-Target level builder options can be overridden globally across all packages with
-the `global_options` section. These options are applied _after_ all Builder
-defaults and target level configuration, and _before_ `--define` command line
-arguments.
-
-- **options**: Map, Optional: A free-form map which will be passed to the
-  `Builder` as a `BuilderOptions` when it is constructed. Usage varies depending
-  on the particular builder. Values in this map will override the default
-  provided by builder authors or at the target level. Values may also be
-  overridden based on the build mode with `dev_options` or `release_options`.
-- **dev_options**: Map, Optional: A free-form map which will be passed to the
-  `Builder` as a `BuilderOptions` when it is constructed. Usage varies depending
-  on the particular builder. The values in this map override all other values
-  per-key when the build is done in dev mode.
-- **release_options**: Map, Optional: A free-form map which will be passed to
-  the `Builder` as a `BuilderOptions` when it is constructed. Usage varies
-  depending on the particular builder. The values in this map override all other
-  values per-key when the build is done in release mode.
-
-## Defining `Builder`s to apply to dependents
-
-If users of your package need to apply some code generation to their package,
-then you can define `Builder`s and have those applied to packages with a
-dependency on yours.
-
-The key for a Builder will be normalized so that consumers of the builder can
-refer to it in `'$definingPackageName:$builderName'` format. If the builder name
-matches the package name it can also be referred to with just the package name.
-
-Exposed `Builder`s are configured in the `builders` section of the `build.yaml`.
-This is a map of builder names to configuration. Each builder config may contain
-the following keys:
-
-- **import**: Required. The import uri that should be used to import the library
-  containing the `Builder` class. This should always be a `package:` uri.
-- **builder_factories**: A `List<String>` which contains the names of the
-  top-level methods in the imported library which are a function fitting the
-  typedef `Builder factoryName(BuilderOptions options)`.
-- **build_extensions**: Required. A map from input extension to the list of
-  output extensions that may be created for that input. This must match the
-  merged `buildExtensions` maps from each `Builder` in `builder_factories`.
-- **auto_apply**: Optional. The packages which should have this builder
-  automatically to applied. Defaults to `'none'` The possibilities are:
-  - `"none"`: Never apply this Builder unless it is manually configured
-  - `"dependents"`: Apply this Builder to the package with a direct dependency
-    on the package exposing the builder.
-  - `"all_packages"`: Apply this Builder to all packages in the transitive
-    dependency graph.
-  - `"root_package"`: Apply this Builder only to the top-level package.
-- **required_inputs**: Optional, see [adjusting builder ordering][]
-- **runs_before**: Optional, see [adjusting builder ordering][]
-- **applies_builders**: Optional, list of Builder keys. Specifies that other
-  builders should be run on any target which will run this Builder.
-- **is_optional**: Optional, boolean. Specifies whether a Builder can be run
-  lazily, such that it won't execute until one of it's outputs is requested by a
-  later Builder. This option should be rare. Defaults to `False`.
-- **build_to**: Optional. The location that generated assets should be output
-  to. The possibilities are:
-  - `"source"`: Outputs go to the source tree next to their primary inputs.
-  - `"cache"`: Outputs go to a hidden build cache and won't be published.
-  The default is "cache". If a Builder specifies that it outputs to "source" it
-  will never run on any package other than the root - but does not necessarily
-  need to use the "root_package" value for "auto_apply". If it would otherwise
-  run on a non-root package it will be filtered out.
-- **defaults**: Optional: Default values to apply when a user does not specify
-  the corresponding key in their `builders` section. May contain the following
-  keys:
-  - **generate_for**: A list of globs that this Builder should run on as a
-    subset of the corresponding target, or a map with `include` and `exclude`
-    lists of globs.
-  - **options**: Arbitrary yaml map, provided as the `config` map in
-    `BuilderOptions` to the `BuilderFactory` for this builder. Individual keys
-    will be overridden by configuration provided in either `dev_options` or
-    `release_options` based on the build mode, and then overridden by any user
-    specified configuration.
-  - **dev_options**: Arbitrary yaml map. Values will replace the defaults from
-    `options` when the build is done in dev mode (the default mode).
-  - **release_options**: Arbitrary yaml map. Values will replace the defaults
-    from `options` when the build is done in release mode (with `--release`).
-
-Example `builders` config:
-
-```yaml
-builders:
-  my_builder:
-    import: "package:my_package/builder.dart"
-    builder_factories: ["myBuilder"]
-    build_extensions: {".dart": [".my_package.dart"]}
-    auto_apply: dependents
-    defaults:
-      release_options:
-        some_key: "Some value the users will want in release mode"
-```
-
-## Defining `PostProcessBuilder`s
-
-`PostProcessBuilder`s are configured similarly to normal `Builder`s, but they
-have some different/missing options.
-
-These builders can not be auto-applied on their own, and must always build to
-cache because their outputs are not declared ahead of time. To apply them a
-user will need to explicitly enable them on a target, or a `Builder` definition
-can add them to `apply_builders`.
-
-Exposed `PostProcessBuilder`s are configured in the `post_process_builders`
-section of the  `build.yaml`. This is a map of builder names to configuration.
-Each post process builder config may contain the following keys:
-
-- **import**: Required. The import uri that should be used to import the library
-  containing the `Builder` class. This should always be a `package:` uri.
-- **builder_factory**: A `String` which contains the name of the top-level
-  method in the imported library which is a function fitting the
-  typedef `PostProcessBuilder factoryName(BuilderOptions options)`.
-- **input_extensions**: Required. A list of input extensions that will be
-  processed. This must match the `inputExtensions` from the `PostProcessBuilder`
-  returned by the `builder_factory`.
-- **defaults**: Optional: Default values to apply when a user does not specify
-  the corresponding key in their `builders` section. May contain the following
-  keys:
-  - **generate_for**: A list of globs that this Builder should run on as a
-    subset of the corresponding target, or a map with `include` and `exclude`
-    lists of globs.
-
-Example config with a normal `builder` which auto-applies a
-`post_process_builder`:
-
-```yaml
-builders:
-  # The regular builder config, creates `.tar.gz` files.
-  regular_builder:
-    import: "package:my_package/builder.dart"
-    builder_factories: ["myBuilder"]
-    build_extensions: {".dart": [".tar.gz"]}
-    auto_apply: dependents
-    apply_builders: [":archive_extract_builder"]
-post_process_builders:
-  # The post process builder config, extracts `.tar.gz` files.
-  extract_archive_builder:
-    import: "package:my_package/extract_archive_builder.dart"
-    builder_factory: "myExtractArchiveBuilder"
-    input_extensions: [".tar.gz"]
-```
-
-[adjusting builder ordering]: #adjusting-builder-ordering
-
-### Adjusting Builder Ordering
-
-Both `required_inputs` and `runs_before` can be used to tweak the order that
-Builders run in on a given target. These work by indicating a given builder is a
-_dependency_ of another. The resulting dependency graph must not have cycles and
-these options should be used rarely.
-
-- **required_inputs**: Optional, list of extensions, defaults to empty list. If
-  a Builder must see every input with one or more file extensions they can be
-  specified here and it will be guaranteed to run after any Builder which might
-  produce an output of that type. For instance a compiler must run after any
-  Builder which can produce `.dart` outputs or those libraries can't be
-  compiled. A Builder may not specify that it requires an output that it also
-  produces since this would be a self-cycle.
-- **runs_before**: Optional, list of Builder keys. If a Builder is producing
-  outputs which are intended to be inputs to other Builders they may be
-  specified here. This guarantees that the specified Builders will be ordered
-  later than this one. This will not cause Builders to be applied if they would
-  not otherwise run, it only affects ordering.
-
-# Publishing `build.yaml` files
-
-`build.yaml` configuration should be published to pub with the package and
-checked in to source control. Whenever a package is published with a
-`build.yaml` it should mark a `dependency` on `build_config` to ensure that
-the package consuming the config has a compatible version. Breaking version
-changes which do not impact the configuration file format will be clearly marked
-in the changelog.
diff --git a/build_config/build.yaml b/build_config/build.yaml
deleted file mode 100644
index 2f30635..0000000
--- a/build_config/build.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-targets:
-  $default:
-    builders:
-      json_serializable:
-        options:
-          any_map: true
-          checked: true
diff --git a/build_config/lib/build_config.dart b/build_config/lib/build_config.dart
deleted file mode 100644
index c2a6553..0000000
--- a/build_config/lib/build_config.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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.
-
-export 'src/build_config.dart' show BuildConfig;
-export 'src/build_target.dart'
-    show BuildTarget, TargetBuilderConfig, GlobalBuilderConfig;
-export 'src/builder_definition.dart'
-    show
-        BuilderDefinition,
-        AutoApply,
-        BuildTo,
-        PostProcessBuilderDefinition,
-        TargetBuilderConfigDefaults;
-export 'src/common.dart' show runInBuildConfigZone;
-export 'src/input_set.dart' show InputSet;
-export 'src/key_normalization.dart'
-    show normalizeBuilderKeyUsage, normalizeTargetKeyUsage;
diff --git a/build_config/lib/src/build_config.dart b/build_config/lib/src/build_config.dart
deleted file mode 100644
index ac3f903..0000000
--- a/build_config/lib/src/build_config.dart
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:checked_yaml/checked_yaml.dart';
-import 'package:json_annotation/json_annotation.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-import 'package:pubspec_parse/pubspec_parse.dart';
-
-import 'build_target.dart';
-import 'builder_definition.dart';
-import 'common.dart';
-import 'expandos.dart';
-import 'input_set.dart';
-import 'key_normalization.dart';
-
-part 'build_config.g.dart';
-
-/// The parsed values from a `build.yaml` file.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class BuildConfig {
-  /// Returns a parsed [BuildConfig] file in [path], if one exist, otherwise a
-  /// default config.
-  ///
-  /// [path] must be a directory which contains a `pubspec.yaml` file and
-  /// optionally a `build.yaml`.
-  static Future<BuildConfig> fromPackageDir(String path) async {
-    final pubspec = await _fromPackageDir(path);
-    return fromBuildConfigDir(pubspec.name, pubspec.dependencies.keys, path);
-  }
-
-  /// Returns a parsed [BuildConfig] file in [path], if one exists, otherwise a
-  /// default config.
-  ///
-  /// [path] should the path to a directory which may contain a `build.yaml`.
-  static Future<BuildConfig> fromBuildConfigDir(
-      String packageName, Iterable<String> dependencies, String path) async {
-    final configPath = p.join(path, 'build.yaml');
-    final file = File(configPath);
-    if (await file.exists()) {
-      return BuildConfig.parse(
-        packageName,
-        dependencies,
-        await file.readAsString(),
-        configYamlPath: file.path,
-      );
-    } else {
-      return BuildConfig.useDefault(packageName, dependencies);
-    }
-  }
-
-  @JsonKey(ignore: true)
-  final String packageName;
-
-  /// All the `builders` defined in a `build.yaml` file.
-  @JsonKey(name: 'builders')
-  final Map<String, BuilderDefinition> builderDefinitions;
-
-  /// All the `post_process_builders` defined in a `build.yaml` file.
-  @JsonKey(name: 'post_process_builders')
-  final Map<String, PostProcessBuilderDefinition> postProcessBuilderDefinitions;
-
-  /// All the `targets` defined in a `build.yaml` file.
-  @JsonKey(name: 'targets', fromJson: _buildTargetsFromJson)
-  final Map<String, BuildTarget> buildTargets;
-
-  @JsonKey(name: 'global_options')
-  final Map<String, GlobalBuilderConfig> globalOptions;
-
-  /// The default config if you have no `build.yaml` file.
-  factory BuildConfig.useDefault(
-      String packageName, Iterable<String> dependencies) {
-    return runInBuildConfigZone(() {
-      final key = '$packageName:$packageName';
-      final target = BuildTarget(
-        dependencies: dependencies
-            .map((dep) => normalizeTargetKeyUsage(dep, packageName))
-            .toList(),
-        sources: InputSet.anything,
-      );
-      return BuildConfig(
-        packageName: packageName,
-        buildTargets: {key: target},
-        globalOptions: {},
-      );
-    }, packageName, dependencies.toList());
-  }
-
-  /// Create a [BuildConfig] by parsing [configYaml].
-  ///
-  /// If [configYamlPath] is passed, it's used as the URL from which
-  /// [configYaml] for error reporting.
-  factory BuildConfig.parse(
-    String packageName,
-    Iterable<String> dependencies,
-    String configYaml, {
-    String configYamlPath,
-  }) {
-    try {
-      return checkedYamlDecode(
-        configYaml,
-        (map) =>
-            BuildConfig.fromMap(packageName, dependencies, map ?? const {}),
-        allowNull: true,
-        sourceUrl: configYamlPath,
-      );
-    } on ParsedYamlException catch (e) {
-      throw ArgumentError(e.formattedMessage);
-    }
-  }
-
-  /// Create a [BuildConfig] read a map which was already parsed.
-  factory BuildConfig.fromMap(
-      String packageName, Iterable<String> dependencies, Map config) {
-    return runInBuildConfigZone(() => BuildConfig._fromJson(config),
-        packageName, dependencies.toList());
-  }
-
-  BuildConfig({
-    String packageName,
-    @required Map<String, BuildTarget> buildTargets,
-    Map<String, GlobalBuilderConfig> globalOptions,
-    Map<String, BuilderDefinition> builderDefinitions,
-    Map<String, PostProcessBuilderDefinition> postProcessBuilderDefinitions =
-        const {},
-  })  : buildTargets = buildTargets ??
-            {
-              _defaultTarget(packageName ?? currentPackage): BuildTarget(
-                dependencies: currentPackageDefaultDependencies,
-              )
-            },
-        globalOptions = (globalOptions ?? const {}).map((key, config) =>
-            MapEntry(normalizeBuilderKeyUsage(key, currentPackage), config)),
-        builderDefinitions = _normalizeBuilderDefinitions(
-            builderDefinitions ?? const {}, packageName ?? currentPackage),
-        postProcessBuilderDefinitions = _normalizeBuilderDefinitions(
-            postProcessBuilderDefinitions ?? const {},
-            packageName ?? currentPackage),
-        packageName = packageName ?? currentPackage {
-    // Set up the expandos for all our build targets and definitions so they
-    // can know which package and builder key they refer to.
-    this.buildTargets.forEach((key, target) {
-      packageExpando[target] = this.packageName;
-      builderKeyExpando[target] = key;
-    });
-    this.builderDefinitions.forEach((key, definition) {
-      packageExpando[definition] = this.packageName;
-      builderKeyExpando[definition] = key;
-    });
-    this.postProcessBuilderDefinitions.forEach((key, definition) {
-      packageExpando[definition] = this.packageName;
-      builderKeyExpando[definition] = key;
-    });
-  }
-
-  factory BuildConfig._fromJson(Map json) => _$BuildConfigFromJson(json);
-}
-
-String _defaultTarget(String package) => '$package:$package';
-
-Map<String, T> _normalizeBuilderDefinitions<T>(
-        Map<String, T> builderDefinitions, String packageName) =>
-    builderDefinitions.map((key, definition) =>
-        MapEntry(normalizeBuilderKeyDefinition(key, packageName), definition));
-
-Map<String, BuildTarget> _buildTargetsFromJson(Map json) {
-  if (json == null) {
-    return null;
-  }
-  var targets = json.map((key, target) => MapEntry(
-      normalizeTargetKeyDefinition(key as String, currentPackage),
-      BuildTarget.fromJson(target as Map)));
-
-  if (!targets.containsKey(_defaultTarget(currentPackage))) {
-    throw ArgumentError('Must specify a target with the name '
-        '`$currentPackage` or `\$default`.');
-  }
-
-  return targets;
-}
-
-Future<Pubspec> _fromPackageDir(String path) async {
-  final pubspec = p.join(path, 'pubspec.yaml');
-  final file = File(pubspec);
-  if (await file.exists()) {
-    return Pubspec.parse(await file.readAsString());
-  }
-  throw FileSystemException('No file found', p.absolute(pubspec));
-}
diff --git a/build_config/lib/src/build_config.g.dart b/build_config/lib/src/build_config.g.dart
deleted file mode 100644
index dbbe12b..0000000
--- a/build_config/lib/src/build_config.g.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'build_config.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BuildConfig _$BuildConfigFromJson(Map json) {
-  return $checkedNew('BuildConfig', json, () {
-    $checkKeys(json, allowedKeys: const [
-      'builders',
-      'post_process_builders',
-      'targets',
-      'global_options'
-    ]);
-    final val = BuildConfig(
-      buildTargets: $checkedConvert(
-          json, 'targets', (v) => _buildTargetsFromJson(v as Map)),
-      globalOptions: $checkedConvert(
-          json,
-          'global_options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String,
-                    e == null ? null : GlobalBuilderConfig.fromJson(e as Map)),
-              )),
-      builderDefinitions: $checkedConvert(
-          json,
-          'builders',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String,
-                    e == null ? null : BuilderDefinition.fromJson(e as Map)),
-              )),
-      postProcessBuilderDefinitions: $checkedConvert(
-          json,
-          'post_process_builders',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(
-                    k as String,
-                    e == null
-                        ? null
-                        : PostProcessBuilderDefinition.fromJson(e as Map)),
-              )),
-    );
-    return val;
-  }, fieldKeyMap: const {
-    'buildTargets': 'targets',
-    'globalOptions': 'global_options',
-    'builderDefinitions': 'builders',
-    'postProcessBuilderDefinitions': 'post_process_builders'
-  });
-}
diff --git a/build_config/lib/src/build_target.dart b/build_config/lib/src/build_target.dart
deleted file mode 100644
index 740a048..0000000
--- a/build_config/lib/src/build_target.dart
+++ /dev/null
@@ -1,163 +0,0 @@
-// 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:json_annotation/json_annotation.dart';
-
-import 'builder_definition.dart';
-import 'common.dart';
-import 'expandos.dart';
-import 'input_set.dart';
-import 'key_normalization.dart';
-
-part 'build_target.g.dart';
-
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class BuildTarget {
-  @JsonKey(name: 'auto_apply_builders')
-  final bool autoApplyBuilders;
-
-  /// A map from builder key to the configuration used for this target.
-  ///
-  /// Builder keys are in the format `"$package|$builder"`. This does not
-  /// represent the full set of builders that are applied to the target, only
-  /// those which have configuration customized against the default.
-  final Map<String, TargetBuilderConfig> builders;
-
-  final List<String> dependencies;
-
-  final InputSet sources;
-
-  /// A unique key for this target in `'$package:$target'` format.
-  String get key => builderKeyExpando[this];
-
-  String get package => packageExpando[this];
-
-  BuildTarget({
-    bool autoApplyBuilders,
-    InputSet sources,
-    Iterable<String> dependencies,
-    Map<String, TargetBuilderConfig> builders,
-  })  : autoApplyBuilders = autoApplyBuilders ?? true,
-        dependencies = (dependencies ?? currentPackageDefaultDependencies)
-            .map((d) => normalizeTargetKeyUsage(d, currentPackage))
-            .toList(),
-        builders = (builders ?? const {}).map((key, config) =>
-            MapEntry(normalizeBuilderKeyUsage(key, currentPackage), config)),
-        sources = sources ?? InputSet.anything;
-
-  factory BuildTarget.fromJson(Map json) => _$BuildTargetFromJson(json);
-
-  @override
-  String toString() => {
-        'package': package,
-        'sources': sources,
-        'dependencies': dependencies,
-        'builders': builders,
-        'autoApplyBuilders': autoApplyBuilders,
-      }.toString();
-}
-
-/// The configuration a particular [BuildTarget] applies to a Builder.
-///
-/// Build targets may have builders applied automatically based on
-/// [BuilderDefinition.autoApply] and may override with more specific
-/// configuration.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class TargetBuilderConfig {
-  /// Overrides the setting of whether the Builder would run on this target.
-  ///
-  /// Builders may run on this target by default based on the `apply_to`
-  /// argument, set to `false` to disable a Builder which would otherwise run.
-  ///
-  /// By default including a config for a Builder enables that builder.
-  @JsonKey(name: 'enabled')
-  final bool isEnabled;
-
-  /// Sources to use as inputs for this Builder in glob format.
-  ///
-  /// This is always a subset of the `include` argument in the containing
-  /// [BuildTarget]. May be `null` in which cases it will be all the sources in
-  /// the target.
-  @JsonKey(name: 'generate_for')
-  final InputSet generateFor;
-
-  /// The options to pass to the `BuilderFactory` when constructing this
-  /// builder.
-  ///
-  /// The `options` key in the configuration.
-  ///
-  /// Individual keys may be overridden by either [devOptions] or
-  /// [releaseOptions].
-  final Map<String, dynamic> options;
-
-  /// Overrides for [options] in dev mode.
-  @JsonKey(name: 'dev_options')
-  final Map<String, dynamic> devOptions;
-
-  /// Overrides for [options] in release mode.
-  @JsonKey(name: 'release_options')
-  final Map<String, dynamic> releaseOptions;
-
-  TargetBuilderConfig({
-    bool isEnabled,
-    this.generateFor,
-    Map<String, dynamic> options,
-    Map<String, dynamic> devOptions,
-    Map<String, dynamic> releaseOptions,
-  })  : isEnabled = isEnabled ?? true,
-        options = options ?? const {},
-        devOptions = devOptions ?? const {},
-        releaseOptions = releaseOptions ?? const {};
-
-  factory TargetBuilderConfig.fromJson(Map json) =>
-      _$TargetBuilderConfigFromJson(json);
-
-  @override
-  String toString() => {
-        'isEnabled': isEnabled,
-        'generateFor': generateFor,
-        'options': options,
-        'devOptions': devOptions,
-        'releaseOptions': releaseOptions,
-      }.toString();
-}
-
-/// The configuration for a Builder applied globally.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class GlobalBuilderConfig {
-  /// The options to pass to the `BuilderFactory` when constructing this
-  /// builder.
-  ///
-  /// The `options` key in the configuration.
-  ///
-  /// Individual keys may be overridden by either [devOptions] or
-  /// [releaseOptions].
-  final Map<String, dynamic> options;
-
-  /// Overrides for [options] in dev mode.
-  @JsonKey(name: 'dev_options')
-  final Map<String, dynamic> devOptions;
-
-  /// Overrides for [options] in release mode.
-  @JsonKey(name: 'release_options')
-  final Map<String, dynamic> releaseOptions;
-
-  GlobalBuilderConfig({
-    Map<String, dynamic> options,
-    Map<String, dynamic> devOptions,
-    Map<String, dynamic> releaseOptions,
-  })  : options = options ?? const {},
-        devOptions = devOptions ?? const {},
-        releaseOptions = releaseOptions ?? const {};
-
-  factory GlobalBuilderConfig.fromJson(Map json) =>
-      _$GlobalBuilderConfigFromJson(json);
-
-  @override
-  String toString() => {
-        'options': options,
-        'devOptions': devOptions,
-        'releaseOptions': releaseOptions,
-      }.toString();
-}
diff --git a/build_config/lib/src/build_target.g.dart b/build_config/lib/src/build_target.g.dart
deleted file mode 100644
index 44143e2..0000000
--- a/build_config/lib/src/build_target.g.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'build_target.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BuildTarget _$BuildTargetFromJson(Map json) {
-  return $checkedNew('BuildTarget', json, () {
-    $checkKeys(json, allowedKeys: const [
-      'auto_apply_builders',
-      'builders',
-      'dependencies',
-      'sources'
-    ]);
-    final val = BuildTarget(
-      autoApplyBuilders:
-          $checkedConvert(json, 'auto_apply_builders', (v) => v as bool),
-      sources: $checkedConvert(
-          json, 'sources', (v) => v == null ? null : InputSet.fromJson(v)),
-      dependencies: $checkedConvert(
-          json, 'dependencies', (v) => (v as List)?.map((e) => e as String)),
-      builders: $checkedConvert(
-          json,
-          'builders',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String,
-                    e == null ? null : TargetBuilderConfig.fromJson(e as Map)),
-              )),
-    );
-    return val;
-  }, fieldKeyMap: const {'autoApplyBuilders': 'auto_apply_builders'});
-}
-
-TargetBuilderConfig _$TargetBuilderConfigFromJson(Map json) {
-  return $checkedNew('TargetBuilderConfig', json, () {
-    $checkKeys(json, allowedKeys: const [
-      'enabled',
-      'generate_for',
-      'options',
-      'dev_options',
-      'release_options'
-    ]);
-    final val = TargetBuilderConfig(
-      isEnabled: $checkedConvert(json, 'enabled', (v) => v as bool),
-      generateFor: $checkedConvert(
-          json, 'generate_for', (v) => v == null ? null : InputSet.fromJson(v)),
-      options: $checkedConvert(
-          json,
-          'options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-      devOptions: $checkedConvert(
-          json,
-          'dev_options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-      releaseOptions: $checkedConvert(
-          json,
-          'release_options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-    );
-    return val;
-  }, fieldKeyMap: const {
-    'isEnabled': 'enabled',
-    'generateFor': 'generate_for',
-    'devOptions': 'dev_options',
-    'releaseOptions': 'release_options'
-  });
-}
-
-GlobalBuilderConfig _$GlobalBuilderConfigFromJson(Map json) {
-  return $checkedNew('GlobalBuilderConfig', json, () {
-    $checkKeys(json,
-        allowedKeys: const ['options', 'dev_options', 'release_options']);
-    final val = GlobalBuilderConfig(
-      options: $checkedConvert(
-          json,
-          'options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-      devOptions: $checkedConvert(
-          json,
-          'dev_options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-      releaseOptions: $checkedConvert(
-          json,
-          'release_options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-    );
-    return val;
-  }, fieldKeyMap: const {
-    'devOptions': 'dev_options',
-    'releaseOptions': 'release_options'
-  });
-}
diff --git a/build_config/lib/src/builder_definition.dart b/build_config/lib/src/builder_definition.dart
deleted file mode 100644
index 0abdfc1..0000000
--- a/build_config/lib/src/builder_definition.dart
+++ /dev/null
@@ -1,251 +0,0 @@
-// 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:json_annotation/json_annotation.dart';
-import 'package:meta/meta.dart';
-
-import 'build_target.dart';
-import 'common.dart';
-import 'expandos.dart';
-import 'input_set.dart';
-import 'key_normalization.dart';
-
-part 'builder_definition.g.dart';
-
-enum AutoApply {
-  none,
-  dependents,
-  @JsonValue('all_packages')
-  allPackages,
-  @JsonValue('root_package')
-  rootPackage
-}
-
-enum BuildTo {
-  /// Generated files are written to the source directory next to their primary
-  /// inputs.
-  source,
-
-  /// Generated files are written to the hidden 'generated' directory.
-  cache
-}
-
-/// Definition of a builder parsed from the `builders` section of `build.yaml`.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class BuilderDefinition {
-  /// The package which provides this Builder.
-  String get package => packageExpando[this];
-
-  /// A unique key for this Builder in `'$package:$builder'` format.
-  String get key => builderKeyExpando[this];
-
-  /// The names of the top-level methods in [import] from args -> Builder.
-  @JsonKey(
-      name: 'builder_factories',
-      nullable: false,
-      required: true,
-      disallowNullValue: true)
-  final List<String> builderFactories;
-
-  /// The import to be used to load `clazz`.
-  @JsonKey(nullable: false, required: true, disallowNullValue: true)
-  final String import;
-
-  /// A map from input extension to the output extensions created for matching
-  /// inputs.
-  @JsonKey(
-      name: 'build_extensions',
-      nullable: false,
-      required: true,
-      disallowNullValue: true)
-  final Map<String, List<String>> buildExtensions;
-
-  /// The name of the dart_library target that contains `import`.
-  ///
-  /// May be null or unreliable and should not be used.
-  @deprecated
-  final String target;
-
-  /// Which packages should have this builder applied automatically.
-  @JsonKey(name: 'auto_apply')
-  final AutoApply autoApply;
-
-  /// A list of file extensions which are required to run this builder.
-  ///
-  /// No builder which outputs any extension in this list is allowed to run
-  /// after this builder.
-  @JsonKey(name: 'required_inputs')
-  final List<String> requiredInputs;
-
-  /// Builder keys in `$package:$builder` format which should only be run after
-  /// this Builder.
-  @JsonKey(name: 'runs_before')
-  final List<String> runsBefore;
-
-  /// Builder keys in `$package:$builder` format which should be run on any
-  /// target which also runs this Builder.
-  @JsonKey(name: 'applies_builders')
-  final List<String> appliesBuilders;
-
-  /// Whether this Builder should be deferred until it's output is requested.
-  ///
-  /// Optional builders are lazy and will not run unless some later builder
-  /// requests one of it's possible outputs through either `readAs*` or
-  /// `canRead`.
-  @JsonKey(name: 'is_optional')
-  final bool isOptional;
-
-  /// Where the outputs of this builder should be written.
-  @JsonKey(name: 'build_to')
-  final BuildTo buildTo;
-
-  final TargetBuilderConfigDefaults defaults;
-
-  BuilderDefinition({
-    @required this.builderFactories,
-    @required this.buildExtensions,
-    @required this.import,
-    String target,
-    AutoApply autoApply,
-    Iterable<String> requiredInputs,
-    Iterable<String> runsBefore,
-    Iterable<String> appliesBuilders,
-    bool isOptional,
-    BuildTo buildTo,
-    TargetBuilderConfigDefaults defaults,
-  })  :
-        // ignore: deprecated_member_use
-        target = target != null
-            ? normalizeTargetKeyUsage(target, currentPackage)
-            : null,
-        autoApply = autoApply ?? AutoApply.none,
-        requiredInputs = requiredInputs?.toList() ?? const [],
-        runsBefore = runsBefore
-                ?.map((builder) =>
-                    normalizeBuilderKeyUsage(builder, currentPackage))
-                ?.toList() ??
-            const [],
-        appliesBuilders = appliesBuilders
-                ?.map((builder) =>
-                    normalizeBuilderKeyUsage(builder, currentPackage))
-                ?.toList() ??
-            const [],
-        isOptional = isOptional ?? false,
-        buildTo = buildTo ?? BuildTo.cache,
-        defaults = defaults ?? const TargetBuilderConfigDefaults() {
-    if (builderFactories.isEmpty) {
-      throw ArgumentError.value(builderFactories, 'builderFactories',
-          'Must have at least one value.');
-    }
-    if (buildExtensions.entries.any((e) => e.value.contains(e.key))) {
-      throw ArgumentError.value(
-          buildExtensions,
-          'buildExtensions',
-          'May not overwrite an input, '
-              'the output extensions must not contain the input extension');
-    }
-  }
-
-  factory BuilderDefinition.fromJson(Map json) =>
-      _$BuilderDefinitionFromJson(json);
-
-  @override
-  String toString() => {
-        'autoApply': autoApply,
-        'import': import,
-        'builderFactories': builderFactories,
-        'buildExtensions': buildExtensions,
-        'requiredInputs': requiredInputs,
-        'runsBefore': runsBefore,
-        'isOptional': isOptional,
-        'buildTo': buildTo,
-        'defaults': defaults,
-      }.toString();
-}
-
-/// The definition of a `PostProcessBuilder` in the `post_process_builders`
-/// section of a `build.yaml`.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class PostProcessBuilderDefinition {
-  /// The package which provides this Builder.
-  String get package => packageExpando[this];
-
-  /// A unique key for this Builder in `'$package:$builder'` format.
-  String get key => builderKeyExpando[this];
-
-  /// The name of the top-level method in [import] from
-  /// Map<String, dynamic> -> Builder.
-  @JsonKey(
-      name: 'builder_factory',
-      nullable: false,
-      required: true,
-      disallowNullValue: true)
-  final String builderFactory;
-
-  /// The import to be used to load `clazz`.
-  @JsonKey(nullable: false, required: true, disallowNullValue: true)
-  final String import;
-
-  /// A list of input extensions for this builder.
-  ///
-  /// May be null or unreliable and should not be used.
-  @deprecated
-  @JsonKey(name: 'input_extensions')
-  final Iterable<String> inputExtensions;
-
-  /// The name of the dart_library target that contains `import`.
-  ///
-  /// May be null or unreliable and should not be used.
-  @deprecated
-  final String target;
-
-  final TargetBuilderConfigDefaults defaults;
-
-  PostProcessBuilderDefinition({
-    @required this.builderFactory,
-    @required this.import,
-    this.inputExtensions,
-    this.target,
-    TargetBuilderConfigDefaults defaults,
-  }) : defaults = defaults ?? const TargetBuilderConfigDefaults();
-
-  factory PostProcessBuilderDefinition.fromJson(Map json) =>
-      _$PostProcessBuilderDefinitionFromJson(json);
-
-  @override
-  String toString() => {
-        'import': import,
-        'builderFactory': builderFactory,
-        'defaults': defaults,
-      }.toString();
-}
-
-/// Default values that builder authors can specify when users don't fill in the
-/// corresponding key for [TargetBuilderConfig].
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class TargetBuilderConfigDefaults {
-  @JsonKey(name: 'generate_for')
-  final InputSet generateFor;
-
-  final Map<String, dynamic> options;
-
-  @JsonKey(name: 'dev_options')
-  final Map<String, dynamic> devOptions;
-
-  @JsonKey(name: 'release_options')
-  final Map<String, dynamic> releaseOptions;
-
-  const TargetBuilderConfigDefaults({
-    InputSet generateFor,
-    Map<String, dynamic> options,
-    Map<String, dynamic> devOptions,
-    Map<String, dynamic> releaseOptions,
-  })  : generateFor = generateFor ?? InputSet.anything,
-        options = options ?? const {},
-        devOptions = devOptions ?? const {},
-        releaseOptions = releaseOptions ?? const {};
-
-  factory TargetBuilderConfigDefaults.fromJson(Map json) =>
-      _$TargetBuilderConfigDefaultsFromJson(json);
-}
diff --git a/build_config/lib/src/builder_definition.g.dart b/build_config/lib/src/builder_definition.g.dart
deleted file mode 100644
index 550710f..0000000
--- a/build_config/lib/src/builder_definition.g.dart
+++ /dev/null
@@ -1,191 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'builder_definition.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BuilderDefinition _$BuilderDefinitionFromJson(Map json) {
-  return $checkedNew('BuilderDefinition', json, () {
-    $checkKeys(json, allowedKeys: const [
-      'builder_factories',
-      'import',
-      'build_extensions',
-      'target',
-      'auto_apply',
-      'required_inputs',
-      'runs_before',
-      'applies_builders',
-      'is_optional',
-      'build_to',
-      'defaults'
-    ], requiredKeys: const [
-      'builder_factories',
-      'import',
-      'build_extensions'
-    ], disallowNullValues: const [
-      'builder_factories',
-      'import',
-      'build_extensions'
-    ]);
-    final val = BuilderDefinition(
-      builderFactories: $checkedConvert(json, 'builder_factories',
-          (v) => (v as List).map((e) => e as String).toList()),
-      buildExtensions: $checkedConvert(
-          json,
-          'build_extensions',
-          (v) => (v as Map).map(
-                (k, e) => MapEntry(
-                    k as String, (e as List).map((e) => e as String).toList()),
-              )),
-      import: $checkedConvert(json, 'import', (v) => v as String),
-      target: $checkedConvert(json, 'target', (v) => v as String),
-      autoApply: $checkedConvert(json, 'auto_apply',
-          (v) => _$enumDecodeNullable(_$AutoApplyEnumMap, v)),
-      requiredInputs: $checkedConvert(
-          json, 'required_inputs', (v) => (v as List)?.map((e) => e as String)),
-      runsBefore: $checkedConvert(
-          json, 'runs_before', (v) => (v as List)?.map((e) => e as String)),
-      appliesBuilders: $checkedConvert(json, 'applies_builders',
-          (v) => (v as List)?.map((e) => e as String)),
-      isOptional: $checkedConvert(json, 'is_optional', (v) => v as bool),
-      buildTo: $checkedConvert(
-          json, 'build_to', (v) => _$enumDecodeNullable(_$BuildToEnumMap, v)),
-      defaults: $checkedConvert(
-          json,
-          'defaults',
-          (v) => v == null
-              ? null
-              : TargetBuilderConfigDefaults.fromJson(v as Map)),
-    );
-    return val;
-  }, fieldKeyMap: const {
-    'builderFactories': 'builder_factories',
-    'buildExtensions': 'build_extensions',
-    'autoApply': 'auto_apply',
-    'requiredInputs': 'required_inputs',
-    'runsBefore': 'runs_before',
-    'appliesBuilders': 'applies_builders',
-    'isOptional': 'is_optional',
-    'buildTo': 'build_to'
-  });
-}
-
-T _$enumDecode<T>(
-  Map<T, dynamic> enumValues,
-  dynamic source, {
-  T unknownValue,
-}) {
-  if (source == null) {
-    throw ArgumentError('A value must be provided. Supported values: '
-        '${enumValues.values.join(', ')}');
-  }
-
-  final value = enumValues.entries
-      .singleWhere((e) => e.value == source, orElse: () => null)
-      ?.key;
-
-  if (value == null && unknownValue == null) {
-    throw ArgumentError('`$source` is not one of the supported values: '
-        '${enumValues.values.join(', ')}');
-  }
-  return value ?? unknownValue;
-}
-
-T _$enumDecodeNullable<T>(
-  Map<T, dynamic> enumValues,
-  dynamic source, {
-  T unknownValue,
-}) {
-  if (source == null) {
-    return null;
-  }
-  return _$enumDecode<T>(enumValues, source, unknownValue: unknownValue);
-}
-
-const _$AutoApplyEnumMap = {
-  AutoApply.none: 'none',
-  AutoApply.dependents: 'dependents',
-  AutoApply.allPackages: 'all_packages',
-  AutoApply.rootPackage: 'root_package',
-};
-
-const _$BuildToEnumMap = {
-  BuildTo.source: 'source',
-  BuildTo.cache: 'cache',
-};
-
-PostProcessBuilderDefinition _$PostProcessBuilderDefinitionFromJson(Map json) {
-  return $checkedNew('PostProcessBuilderDefinition', json, () {
-    $checkKeys(json, allowedKeys: const [
-      'builder_factory',
-      'import',
-      'input_extensions',
-      'target',
-      'defaults'
-    ], requiredKeys: const [
-      'builder_factory',
-      'import'
-    ], disallowNullValues: const [
-      'builder_factory',
-      'import'
-    ]);
-    final val = PostProcessBuilderDefinition(
-      builderFactory:
-          $checkedConvert(json, 'builder_factory', (v) => v as String),
-      import: $checkedConvert(json, 'import', (v) => v as String),
-      inputExtensions: $checkedConvert(json, 'input_extensions',
-          (v) => (v as List)?.map((e) => e as String)),
-      target: $checkedConvert(json, 'target', (v) => v as String),
-      defaults: $checkedConvert(
-          json,
-          'defaults',
-          (v) => v == null
-              ? null
-              : TargetBuilderConfigDefaults.fromJson(v as Map)),
-    );
-    return val;
-  }, fieldKeyMap: const {
-    'builderFactory': 'builder_factory',
-    'inputExtensions': 'input_extensions'
-  });
-}
-
-TargetBuilderConfigDefaults _$TargetBuilderConfigDefaultsFromJson(Map json) {
-  return $checkedNew('TargetBuilderConfigDefaults', json, () {
-    $checkKeys(json, allowedKeys: const [
-      'generate_for',
-      'options',
-      'dev_options',
-      'release_options'
-    ]);
-    final val = TargetBuilderConfigDefaults(
-      generateFor: $checkedConvert(
-          json, 'generate_for', (v) => v == null ? null : InputSet.fromJson(v)),
-      options: $checkedConvert(
-          json,
-          'options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-      devOptions: $checkedConvert(
-          json,
-          'dev_options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-      releaseOptions: $checkedConvert(
-          json,
-          'release_options',
-          (v) => (v as Map)?.map(
-                (k, e) => MapEntry(k as String, e),
-              )),
-    );
-    return val;
-  }, fieldKeyMap: const {
-    'generateFor': 'generate_for',
-    'devOptions': 'dev_options',
-    'releaseOptions': 'release_options'
-  });
-}
diff --git a/build_config/lib/src/common.dart b/build_config/lib/src/common.dart
deleted file mode 100644
index ad77ebd..0000000
--- a/build_config/lib/src/common.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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';
-
-final _defaultDependenciesZoneKey = Symbol('buildConfigDefaultDependencies');
-final _packageZoneKey = Symbol('buildConfigPackage');
-
-T runInBuildConfigZone<T>(
-        T Function() fn, String package, List<String> defaultDependencies) =>
-    runZoned(fn, zoneValues: {
-      _packageZoneKey: package,
-      _defaultDependenciesZoneKey: defaultDependencies,
-    });
-
-String get currentPackage {
-  var package = Zone.current[_packageZoneKey] as String;
-  if (package == null) {
-    throw StateError(
-        'Must be running inside a build config zone, which can be done using '
-        'the `runInBuildConfigZone` function.');
-  }
-  return package;
-}
-
-List<String> get currentPackageDefaultDependencies {
-  var defaultDependencies =
-      Zone.current[_defaultDependenciesZoneKey] as List<String>;
-  if (defaultDependencies == null) {
-    throw StateError(
-        'Must be running inside a build config zone, which can be done using '
-        'the `runInBuildConfigZone` function.');
-  }
-  return defaultDependencies;
-}
diff --git a/build_config/lib/src/expandos.dart b/build_config/lib/src/expandos.dart
deleted file mode 100644
index 2cc9e01..0000000
--- a/build_config/lib/src/expandos.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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.
-
-final builderKeyExpando = Expando<String>();
-
-final packageExpando = Expando<String>();
diff --git a/build_config/lib/src/input_set.dart b/build_config/lib/src/input_set.dart
deleted file mode 100644
index e077b3b..0000000
--- a/build_config/lib/src/input_set.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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:json_annotation/json_annotation.dart';
-
-part 'input_set.g.dart';
-
-/// A filter on files inputs or sources.
-///
-/// Takes a list of strings in glob format for [include] and [exclude]. Matches
-/// the `glob()` function in skylark.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class InputSet {
-  static const anything = InputSet();
-
-  /// The globs to include in the set.
-  ///
-  /// May be null or empty which means every possible path (like `'**'`).
-  final List<String> include;
-
-  /// The globs as a subset of [include] to remove from the set.
-  ///
-  /// May be null or empty which means every path in [include].
-  final List<String> exclude;
-
-  const InputSet({this.include, this.exclude});
-
-  factory InputSet.fromJson(dynamic json) {
-    if (json is List) {
-      json = {'include': json};
-    } else if (json is! Map) {
-      throw ArgumentError.value(json, 'sources',
-          'Expected a Map or a List but got a ${json.runtimeType}');
-    }
-    final parsed = _$InputSetFromJson(json as Map);
-    if (parsed.include != null &&
-        parsed.include.any((s) => s == null || s.isEmpty)) {
-      throw ArgumentError.value(
-          parsed.include, 'include', 'Include globs must not be empty');
-    }
-    if (parsed.exclude != null &&
-        parsed.exclude.any((s) => s == null || s.isEmpty)) {
-      throw ArgumentError.value(
-          parsed.exclude, 'exclude', 'Exclude globs must not be empty');
-    }
-    return parsed;
-  }
-
-  @override
-  String toString() {
-    final result = StringBuffer();
-    if (include == null || include.isEmpty) {
-      result.write('any path');
-    } else {
-      result.write('paths matching $include');
-    }
-    if (exclude != null && exclude.isNotEmpty) {
-      result.write(' except $exclude');
-    }
-    return '$result';
-  }
-}
diff --git a/build_config/lib/src/input_set.g.dart b/build_config/lib/src/input_set.g.dart
deleted file mode 100644
index 6733313..0000000
--- a/build_config/lib/src/input_set.g.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'input_set.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-InputSet _$InputSetFromJson(Map json) {
-  return $checkedNew('InputSet', json, () {
-    $checkKeys(json, allowedKeys: const ['include', 'exclude']);
-    final val = InputSet(
-      include: $checkedConvert(json, 'include',
-          (v) => (v as List)?.map((e) => e as String)?.toList()),
-      exclude: $checkedConvert(json, 'exclude',
-          (v) => (v as List)?.map((e) => e as String)?.toList()),
-    );
-    return val;
-  });
-}
diff --git a/build_config/lib/src/key_normalization.dart b/build_config/lib/src/key_normalization.dart
deleted file mode 100644
index 62b5eae..0000000
--- a/build_config/lib/src/key_normalization.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// 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.
-
-const _defaultTargetNamePlaceholder = r'$default';
-
-/// Returns the normalized [builderKey] definition when used from [packageName].
-///
-/// Example normalizations:
-///
-///   - "some_builder" => "$packageName:some_builder"
-///   - ":some_builder" => "$packageName:some_builder"
-///   - "some_package:some_builder" => "some_package:some_builder"
-///
-/// If the legacy separator `|` is used it will be transformed to `:`
-String normalizeBuilderKeyDefinition(String builderKey, String packageName) =>
-    _normalizeDefinition(
-        builderKey.contains('|')
-            ? builderKey.replaceFirst('|', ':')
-            : builderKey,
-        packageName);
-
-/// Returns the normalized [builderKey] usage when used from [packageName].
-///
-/// Example normalizations:
-///
-///   - "some_package" => "some_package:some_package"
-///   - ":some_builder" => "$packageName:some_builder"
-///   - "some_package:some_builder" => "some_package:some_builder"
-///
-/// If the legacy separator `|` is used it will be transformed to `:`
-String normalizeBuilderKeyUsage(String builderKey, String packageName) =>
-    _normalizeUsage(
-        builderKey.contains('|')
-            ? builderKey.replaceFirst('|', ':')
-            : builderKey,
-        packageName);
-
-/// Returns the normalized [targetKey] definition when used from [packageName].
-///
-/// Example normalizations:
-///
-///   - "$default" => "$packageName:$packageName"
-///   - "some_target" => "$packageName:some_target"
-///   - ":some_target" => "$packageName:some_target"
-///   - "some_package:some_target" => "some_package|some_target"
-String normalizeTargetKeyDefinition(String targetKey, String packageName) =>
-    targetKey == _defaultTargetNamePlaceholder
-        ? '$packageName:$packageName'
-        : _normalizeDefinition(targetKey, packageName);
-
-/// Returns the normalized [targetKey] usage when used from [packageName].
-///
-/// Example normalizations:
-///
-///   - "$default" => "$packageName:$packageName"
-///   - ":$default" => "$packageName:$packageName"
-///   - "$default:$default" => "$packageName:$packageName"
-///   - "some_package" => "some_package:some_package"
-///   - ":some_target" => "$packageName:some_target"
-///   - "some_package:some_target" => "some_package:some_target"
-String normalizeTargetKeyUsage(String targetKey, String packageName) {
-  switch (targetKey) {
-    case _defaultTargetNamePlaceholder:
-    case ':$_defaultTargetNamePlaceholder':
-    case '$_defaultTargetNamePlaceholder:$_defaultTargetNamePlaceholder':
-      return '$packageName:$packageName';
-    default:
-      return _normalizeUsage(targetKey, packageName);
-  }
-}
-
-/// Gives a full unique key for [name] used from [packageName].
-///
-/// If [name] omits the separator we assume it's referring to a target or
-/// builder named after a package (which is not this package). If [name] starts
-/// with the separator we assume it's referring to a target within the package
-/// it's used from.
-///
-/// For example: If I depend on `angular` from `my_package` it is treated as a
-/// dependency on the globally unique `angular:angular`.
-String _normalizeUsage(String name, String packageName) {
-  if (name.startsWith(':')) return '$packageName$name';
-  if (!name.contains(':')) return '$name:$name';
-  return name;
-}
-
-/// Gives a full unique key for [name] definied within [packageName].
-///
-/// The result is always '$packageName$separator$name since at definition the
-/// key must be referring to something within [packageName].
-///
-/// For example: If I expose a builder `my_builder` within `my_package` it is
-/// turned into the globally unique `my_package|my_builder`.
-String _normalizeDefinition(String name, String packageName) {
-  if (name.startsWith(':')) return '$packageName$name';
-  if (!name.contains(':')) return '$packageName:$name';
-  return name;
-}
diff --git a/build_config/mono_pkg.yaml b/build_config/mono_pkg.yaml
deleted file mode 100644
index e317dee..0000000
--- a/build_config/mono_pkg.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-        - dartfmt: sdk
-        - dartanalyzer: --fatal-infos --fatal-warnings .
-    - dartanalyzer: --fatal-warnings .
-      dart:
-        - 2.6.0
-  - unit_test:
-    - command: pub run test
-      os:
-        - linux
-        - windows
-
-cache:
-  directories:
-    - .dart_tool/build
diff --git a/build_config/pubspec.yaml b/build_config/pubspec.yaml
deleted file mode 100644
index 12a59db..0000000
--- a/build_config/pubspec.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: build_config
-version: 0.4.2
-description: Support for parsing `build.yaml` configuration.
-homepage: https://github.com/dart-lang/build/tree/master/build_config
-
-environment:
-  sdk: '>=2.6.0 <3.0.0'
-
-dependencies:
-  checked_yaml: ^1.0.0
-  json_annotation: '>=1.0.0 <4.0.0'
-  meta: ^1.1.0
-  path: ^1.4.0
-  pubspec_parse: ^0.1.5
-  yaml: ^2.1.11
-
-dev_dependencies:
-  build_runner: ^1.0.0
-  json_serializable: ^3.0.0
-  term_glyph: ^1.0.0
-  test: ^1.6.0
diff --git a/build_modules/BUILD.gn b/build_modules/BUILD.gn
deleted file mode 100644
index cee16c9..0000000
--- a/build_modules/BUILD.gn
+++ /dev/null
@@ -1,31 +0,0 @@
-# This file is generated by importer.py for build_modules-2.8.0
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_modules") {
-  package_name = "build_modules"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/pedantic",
-    "//third_party/dart-pkg/pub/logging",
-    "//third_party/dart-pkg/pub/glob",
-    "//third_party/dart-pkg/pub/crypto",
-    "//third_party/dart-pkg/pub/collection",
-    "//third_party/dart-pkg/pub/graphs",
-    "//third_party/dart-pkg/pub/build",
-    "//third_party/dart-pkg/pub/meta",
-    "//third_party/dart-pkg/pub/scratch_space",
-    "//third_party/dart-pkg/pub/analyzer",
-    "//third_party/dart-pkg/pub/async",
-    "//third_party/dart-pkg/pub/build_config",
-    "//third_party/dart-pkg/pub/path",
-    "//third_party/dart-pkg/pub/bazel_worker",
-    "//third_party/dart-pkg/pub/json_annotation",
-  ]
-}
diff --git a/build_modules/CHANGELOG.md b/build_modules/CHANGELOG.md
deleted file mode 100644
index 92c2fbe..0000000
--- a/build_modules/CHANGELOG.md
+++ /dev/null
@@ -1,346 +0,0 @@
-## 2.8.0
-
-- Add the ability to pass a list of experiments to enable to the KernelBuilder.
-
-## 2.7.0
-
-- Add support for an environment variable `BUILD_DART2JS_VM_ARGS` which can
-  be used to supply Dart vm arguments for the dart2js processes.
-
-## 2.6.3
-
-- Keep cached deserialized module instances in more cases. This may improve
-  performance of incremental builds in watch mode.
-- **Deprecated**: The package specific unsupported module whitelist option
-  provided by `computeTransitiveDependencies`. The only known uses are being
-  removed.
-- Allow analyzer version `0.39.x`.
-
-## 2.6.2
-
-Republish of `2.6.0` with the proper min sdk contraint.
-
-## 2.6.1
-
-### Bug fix for issue #2464
-
-Ignore the `trackUnusedInputs` option that was added in `2.6.0`.
-
-This option will be respected again in the next release which will have the
-proper minimum sdk constraint.
-
-## 2.6.0
-
-Add support for dependency pruning to the `KernelBuilder`. This should greatly
-improve the invalidation semantics for builds, meaning that less code will be
-recompiled for each edit you make.
-
-This is not enabled by default but can be enabled by passing
-`trackUnusedInputs: true` to the `KernelBuilder` constructor.
-
-## 2.5.0
-
-- Add an option to skip the unsupported module check for modules in specified
-  packages.
-
-## 2.4.3
-
-- Allow analyzer version 0.38.0.
-
-## 2.4.2
-
-- Support the latest release of `package:json_annotation`.
-
-## 2.4.1
-
-- Require non-empty output from kernel build steps.
-
-## 2.4.0
-
-- Allow overriding the target name passed to the kernel worker.
-
-## 2.3.1
-
-- Allow analyzer version 0.37.0.
-
-## 2.3.0
-
-- Add a `hasMain` boolean to the `ModuleLibrary` class.
-  - This is now used instead of `isEntrypoint` for determining whether or not
-    to copy module files for application discovery.
-- Fix `computeTransitiveDeps` to do error checking for the root module as well
-  as transitive modules.
-
-## 2.2.0
-
-- Make the `librariesPath` in the `KernelBuilder` configurable.
-- Fixed bug where the configured dart SDK was ignored.
-
-## 2.1.3
-
-- Skip compiling modules with kernel when the primary source isn't the primary
-  input (only shows up in non-lazy builds - essentially just tests).
-
-## 2.1.2
-
-- Output additional `.module` files for all entrypoints to ease discovery of
-  modules for compilers.
-
-## 2.1.1
-
-- Allow `build_config` `0.4.x`.
-
-## 2.1.0
-
-- Make using the incremental compiler in the `KernelBuilder` configurable.
-
-## 2.0.0
-
-### Breaking Changes
-
-- Remove the `merge` method from `Module` and replace with a static
-  `Module.merge`. Module instances are now immutable.
-- Remove `jsId`, and `jsSourceMapId` from `Module`.
-- `DartPlatform` no longer has hard coded platforms, and its constructor is now
-  public. Anybody is now free to create their own `platform`.
-- Removed the platform specific builder factories from the `builders.dart` file.
-  - Packages that want to target compilation for a platform should create their
-    own builder factories.
-- Removed completely the analyzer based builders - `UnlinkedSummaryBuilder` and
-  `LinkedSummaryBuilder`.
-  - All backends should now be using the `KernelBuilder` instead.
-- Removed the default module builders for each supported platform. These
-  must now be created by the packages that want to add compilation targeting a
-  specific platform.
-  - This will help reduce asset graph bloat caused by platforms that you weren't
-    actually targeting.
-
-### Improvements
-
-- Update the kernel worker to pass input digests, along with
-  `--reuse-compiler-result` and `--use-incremental-compiler`.
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-
-## 1.0.11
-
-- Allow build_config 0.4.x.
-
-## 1.0.10
-
-- Fix a performance issue in the kernel_builder, especially for larger projects.
-
-## 1.0.9
-
-- Allow configuring the platform SDK directory in the `KernelBuilder` builder.
-
-## 1.0.8
-
-- Don't follow `dart.library.isolate` conditional imports for the DDC
-  platform.
-
-## 1.0.7+2
-
-- Update `dart2js` snapshot arguments for upcoming SDK.
-
-## 1.0.7+1
-
-- Fix broken release by updating `dart2js` worker and restricting sdk version.
-
-## 1.0.7
-
-- Explicitly skip dart-ext uris during module creation.
-  - Filed Issue #2047 to track real support for native extensions.
-- Run workers with mode `detachedWithStdio` if no terminal is connected.
-
-## 1.0.6
-
-- Improved the time tracking for kernel and analyzer actions by not reporting
-  time spent waiting for a worker to be available.
-
-## 1.0.5
-
-- Increased the upper bound for `package:analyzer` to `<0.36.0`.
-
-## 1.0.4
-
-- Update to `package:graphs` version `0.2.0`.
-- Use `dartdevc --kernel` instead of `dartdevk`.
-
-## 1.0.3
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 1.0.2
-
-- Support the latest `package:json_annotation`.
-
-## 1.0.1
-
-- Increased the upper bound for `package:analyzer` to '<0.34.0'.
-
-## 1.0.0
-
-### Breaking Changes
-
-- The `Module` constructor has an additional required parameter `isSupported`,
-  which indicates if a module is supported on that module's platform.
-
-## 0.4.0
-
-### Improvements
-
-- Modules are now platform specific, and config specific imports using
-  `dart.library.*` constants are supported.
-
-### Breaking Configuration Changes
-
-- Module granularity now has to be configured per platform, so instead of
-  configuring it using the `build_modules|modules` builder, you now need to
-  configure the builder for each specific platform:
-
-```yaml
-targets:
-  $default:
-    build_modules|dartdevc:
-      options:
-        strategy: fine
-```
-
-  The supported platforms are currently `dart2js`, `dartdevc`, `flutter`, and
-  `vm`.
-
-### Breaking API Changes
-
-- Output extensions of builders have changed to include the platform being built
-  for.
-  - All the top level file extension getters are now methods that take a
-    platform and return the extension for that platform.
-- Most builders are no longer applied by default, you must manually apply them
-  using applies_builders in your builder.
-- Most builder constructors now require a `platform` argument.
-
-## 0.3.2
-
-- Module strategies are now respected for all packages instead of just the root
-  package.
-- Can now mix and match fine and coarse strategies at will, even within package
-  cycles (although this may cause larger modules).
-- Removed analyzer dependency.
-
-## 0.3.1+1
-
-- Support `package:json_annotation` v1.
-
-## 0.3.1
-
-- Change the default module strategy for the root package to `coarse`.
-
-## 0.3.0
-
-### Improvements
-
-- Updated dart2js support so that it can do multiple builds concurrently and
-  will restart workers periodically to mitigate the effects of
-  dart-lang/sdk#33708.
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-### Breaking Changes
-
-- Removed the `kernelSummaryExtension`, and renamed the `KernelSummaryBuilder`
-  to `KernelBuilder`. The new builder can be used to create summaries or full
-  kernel files, and requires users to give it a custom sdk.
-- Changed `metaModuleCleanBuilder` to read `.module.library` files which are
-  produced by the `moduleLibrayBuilder`. Clients using the automatically
-  generated build script will get this automatically. Clients which have
-  manually written build scripts will need to add it.
-
-## 0.2.3
-
-- Update to the latest `package:scratch_space` and don't manually clear it out
-  between builds. This provides significant speed improvements for large
-  projects.
-
-## 0.2.2+6
-
-- Support the latest `package:build_config`.
-
-## 0.2.2+5
-
-- Updated the missing modules message to highlight that the error is likely due
-  to a missing dependency.
-
-## 0.2.2+4
-
-- Support `package:analyzer` `0.32.0`.
-
-## 0.2.2+3
-
-- Fix a race condition where we could fail to find the modules for some
-  dependencies.
-
-## 0.2.2+2
-
-- Fix an issue where modules were unnecessarily being built with DDC.
-  [#1375](https://github.com/dart-lang/build/issues/1375).
-
-## 0.2.2+1
-
-- Fix an issue with new files causing subsequent build failures
-  [#1358](https://github.com/dart-lang/build/issues/1358).
-- Expose `MetaModuleCleanBuilder` and `metaModuleCleanExtension` publicly for
-  usage in tests and manual build scripts.
-
-## 0.2.2
-
-- Clean up `.module` and summary files from the output and server.
-- Add new `ModuleBuilder` strategies. By default the `coarse` strategy is used
-  for all non-root packages and will create a minimum number of modules. This
-  strategy can not be overridden. However, for the root package, the `fine`
-  strategy will be used which creates a module for each strongly
-  connected component. You can override this behavior by providing `coarse`
-  to the `strategy` option.
-
-  Example configuration:
-
-  ```yaml
-  targets:
-    $default:
-      builders:
-        build_modules|modules:
-          options:
-            strategy: coarse
-  ```
-
-## 0.2.1
-
-- Give a guaranteed reverse dependency order for
-  `Module.computeTransitiveDependencies`
-
-## 0.2.0+2
-
-- Fix use of `whereType` in `MissingModulesException`,
-  https://github.com/dart-lang/build/issues/1123.
-
-## 0.2.0+1
-
-- Fix null pointer error in `MissingModulesException`,
-  https://github.com/dart-lang/build/issues/1092.
-
-## 0.2.0
-
-- `computeTransitiveDependencies` now throws a `MissingModulesException` instead
-  of logging a warning if it discovers a missing module.
-
-## 0.1.0+2
-
-- Fix a bug with the dart2js workers where the worker could hang if you try to
-  re-use it after calling `terminateWorkers`. This only really surfaces in test
-  environments.
-
-## 0.1.0+1
-
-- Fix a bug with imports to libraries that have names starting with `dart.`
-
-## 0.1.0
-
-- Split from `build_web_compilers`.
diff --git a/build_modules/LICENSE b/build_modules/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/build_modules/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_modules/README.md b/build_modules/README.md
deleted file mode 100644
index 4ce5c7d..0000000
--- a/build_modules/README.md
+++ /dev/null
@@ -1,102 +0,0 @@
-<p align="center">
-  Module builders for modular compilation pipelines.
-  <br>
-  <a href="https://travis-ci.org/dart-lang/build">
-    <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
-  </a>
-  <a href="https://github.com/dart-lang/build/labels/package%3A%20build_modules">
-    <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_modules.svg" alt="Issues related to build_modules" />
-  </a>
-  <a href="https://pub.dev/packages/build_modules">
-    <img src="https://img.shields.io/pub/v/build_modules.svg" alt="Pub Package Version" />
-  </a>
-  <a href="https://pub.dev/documentation/build_modules/latest/">
-    <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
-  </a>
-  <a href="https://gitter.im/dart-lang/build">
-    <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
-  </a>
-</p>
-
-This package provides generic module builders which can be used to create custom
-compilation pipelines. It is used by [`build_web_compilers`][] and
-[`build_vm_compilers`][] package which provides standard builders for the web
-and vm platforms.
-
-## Usage
-
-There should be no need to import this package directly unless you are
-developing a custom compiler pipeline. See documentation in
-[`build_web_compilers`][] and [`build_vm_compilers`][] for more details on
-building your Dart code.
-
-[`build_web_compilers`]: https://pub.dev/packages/build_web_compilers
-[`build_vm_compilers`]: https://pub.dev/packages/build_vm_compilers
-
-## Module creation
-
-The overall process for emitting modules follows these steps:
-
-1. Emit a `.module.library` asset for every `.dart` library containing a
-   description of the directives (imports, exports, and parts), a list of the
-   `dart:` imports used, and a determination of whether the library is an
-   "entrypoint". Entrypoint libraries are either those which are likely to be
-   directly imported (they are under `lib/` but not `lib/src/`) or which have a
-   `main`. Only the libraries that can be imported (they aren't part files) will
-   have an output. This step is mainly separated out for better invalidation
-   behavior since the output will change less frequently than the code. The
-   outputs from this step are non differentiated by platform.
-2. Emit package level `.meta_module` assets. This is an aggregation of the
-   `.module.library` information with a first run at creating a module
-   structure. The output depends on the algorithm, described below. The outputs
-   from this step are specific to a platform and will indicate which libraries
-   contain unsupported `dart:` imports for a platform. Conditional imports will
-   also be resolved to a concrete dependency based on the platform. In this step
-   the dependencies of modules references the imported library, which may not
-   match the primary source of the module containing that library.
-3. Emit package level `.meta_module.clean` assets. This step performs an extra
-   run of the strongly connected components algorithm so that any libraries
-   which are in an import cycle are grouped into a single module. This is done
-   as a separate step so that it can be sure it may read all the `.meta_module`
-   results across packages in a dependency cycle so that it may resolve import
-   cycles across packages. As modules are merged due to import cycles the new
-   module becomes the union of their sources and dependencies. Dependencies are
-   resolved to the "primary source" of the module containing the imported
-   library.
-4. Emit `.module` assets which contain a filtered view of the package level
-   meta-module specific to a single module. These are emitted for the "primary
-   source" of each module, as well as each library which is an entrypoint.
-
-## Module algorithms
-
-### Fine
-
-The fine-grained module algorithm is straightforward - any dart library which
-_can_ be it's own module, _is_ it's own module. Libraries are only grouped into
-a module when there is an import cycle between them.
-
-The `.meta_module` step filters unsupported libraries and does no clustering.
-Import cycles are resolved by the `.meta_module.clean` step.
-
-### Coarse
-
-The coarse-grained module algorithm attempts to cluster libraries into larger
-modules without bringing in more code than may be imported by downstream code.
-It assumes that libraries under `lib/src/` won't be imported directly outside of
-the package. Assuming that external packages only import the libraries outside
-of `lib/src/` then no code outside of the transitive imports will be brought in
-due to module clustering.
-
-The `.meta_module` step performs strongly connected components and libraries
-which are in an import cycle are grouped into modules since they can't be
-ordered otherwise. Within each top level directory under the package (`lib/`,
-`test/`, etc) the libraries are further bundled into modules where possible.
-Each "entrypoint" library is always kept in it's own modules (other than in the
-case of import cycles). Non entrypoint libraries are grouped where possible
-based on the entrypoints that transitively import them. Any non-entrypoint which
-is only transitively imported by a single entrypoint is merged into the module
-for that entrypoint. Any non-entrypoints which are imported by the same set of
-entrypoints are merged into their own module. The "primary source" for any
-module is always the lowest alpha-sorted source, regardless of whether it is an
-entrypoint. As libraries are merged the module becomes the union of their
-sources and dependencies.
diff --git a/build_modules/build.yaml b/build_modules/build.yaml
deleted file mode 100644
index a73fedf..0000000
--- a/build_modules/build.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-builders:
-  module_library:
-    import: "package:build_modules/builders.dart"
-    builder_factories:
-      - moduleLibraryBuilder
-    build_extensions:
-      .dart:
-        - .module.library
-    auto_apply: all_packages
-    is_optional: True
-    required_inputs: [".dart"]
-    applies_builders: ["|module_cleanup"]
-post_process_builders:
-  module_cleanup:
-    import: "package:build_modules/builders.dart"
-    builder_factory: "moduleCleanup"
diff --git a/build_modules/dart_test.yaml b/build_modules/dart_test.yaml
deleted file mode 100644
index 56f2311..0000000
--- a/build_modules/dart_test.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-tags:
-  presubmit-only:
-    skip: "Should only be run during presubmit"
-    presets: {presubmit: {skip: false}}
diff --git a/build_modules/lib/build_modules.dart b/build_modules/lib/build_modules.dart
deleted file mode 100644
index 216b65d..0000000
--- a/build_modules/lib/build_modules.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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.
-
-export 'src/errors.dart' show MissingModulesException, UnsupportedModules;
-export 'src/kernel_builder.dart'
-    show KernelBuilder, multiRootScheme, reportUnusedKernelInputs;
-export 'src/meta_module_builder.dart'
-    show MetaModuleBuilder, metaModuleExtension;
-export 'src/meta_module_clean_builder.dart'
-    show MetaModuleCleanBuilder, metaModuleCleanExtension;
-export 'src/module_builder.dart' show ModuleBuilder, moduleExtension;
-export 'src/module_library_builder.dart'
-    show ModuleLibraryBuilder, moduleLibraryExtension;
-export 'src/modules.dart';
-export 'src/platform.dart' show DartPlatform;
-export 'src/scratch_space.dart' show scratchSpace, scratchSpaceResource;
-export 'src/workers.dart' show dart2JsWorkerResource, dartdevkDriverResource;
diff --git a/build_modules/lib/builders.dart b/build_modules/lib/builders.dart
deleted file mode 100644
index 4366a82..0000000
--- a/build_modules/lib/builders.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:build_modules/src/module_cleanup.dart';
-import 'package:build_modules/src/module_library_builder.dart';
-
-Builder moduleLibraryBuilder(_) => const ModuleLibraryBuilder();
-
-PostProcessBuilder moduleCleanup(_) => const ModuleCleanup();
diff --git a/build_modules/lib/src/common.dart b/build_modules/lib/src/common.dart
deleted file mode 100644
index e7b7197..0000000
--- a/build_modules/lib/src/common.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-
-import 'kernel_builder.dart';
-
-final defaultAnalysisOptionsId =
-    AssetId('build_modules', 'lib/src/analysis_options.default.yaml');
-
-String defaultAnalysisOptionsArg(ScratchSpace scratchSpace) =>
-    '--options=${scratchSpace.fileFor(defaultAnalysisOptionsId).path}';
-
-// TODO: better solution for a .packages file, today we just create a new one
-// for every kernel build action.
-Future<File> createPackagesFile(Iterable<AssetId> allAssets) async {
-  var allPackages = allAssets.map((id) => id.package).toSet();
-  var packagesFileDir =
-      await Directory.systemTemp.createTemp('kernel_builder_');
-  var packagesFile = File(p.join(packagesFileDir.path, '.packages'));
-  await packagesFile.create();
-  await packagesFile.writeAsString(allPackages
-      .map((pkg) => '$pkg:$multiRootScheme:///packages/$pkg')
-      .join('\r\n'));
-  return packagesFile;
-}
-
-enum ModuleStrategy { fine, coarse }
-
-ModuleStrategy moduleStrategy(BuilderOptions options) {
-  var config = options.config['strategy'] as String ?? 'coarse';
-  switch (config) {
-    case 'coarse':
-      return ModuleStrategy.coarse;
-    case 'fine':
-      return ModuleStrategy.fine;
-    default:
-      throw ArgumentError('Unexpected ModuleBuilder strategy: $config');
-  }
-}
-
-/// Validates that [config] only has the top level keys [supportedOptions].
-///
-/// Throws an [ArgumentError] if not.
-void validateOptions(Map<String, dynamic> config, List<String> supportedOptions,
-    String builderKey) {
-  var unsupportedOptions =
-      config.keys.where((o) => !supportedOptions.contains(o));
-  if (unsupportedOptions.isNotEmpty) {
-    throw ArgumentError.value(unsupportedOptions.join(', '), builderKey,
-        'only $supportedOptions are supported options, but got');
-  }
-}
diff --git a/build_modules/lib/src/errors.dart b/build_modules/lib/src/errors.dart
deleted file mode 100644
index d3dfbf1..0000000
--- a/build_modules/lib/src/errors.dart
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart';
-import 'package:build/build.dart';
-
-import 'module_library.dart';
-import 'module_library_builder.dart';
-import 'modules.dart';
-
-/// An [Exception] that is thrown when a worker returns an error.
-abstract class _WorkerException implements Exception {
-  final AssetId failedAsset;
-
-  final String error;
-
-  /// A message to prepend to [toString] output.
-  String get message;
-
-  _WorkerException(this.failedAsset, this.error);
-
-  @override
-  String toString() => '$message:$failedAsset\n\nResponse:$error\n';
-}
-
-/// An [Exception] that is thrown when the analyzer fails to create a summary.
-class AnalyzerSummaryException extends _WorkerException {
-  @override
-  final String message = 'Error creating summary for module';
-
-  AnalyzerSummaryException(AssetId summaryId, String error)
-      : super(summaryId, error);
-}
-
-/// An [Exception] that is thrown when the common frontend fails to create a
-/// kernel summary.
-class KernelException extends _WorkerException {
-  @override
-  final String message = 'Error creating kernel summary for module';
-
-  KernelException(AssetId summaryId, String error) : super(summaryId, error);
-}
-
-/// An [Exception] that is thrown when there are some missing modules.
-class MissingModulesException implements Exception {
-  final String message;
-
-  @override
-  String toString() => message;
-
-  MissingModulesException._(this.message);
-
-  static Future<MissingModulesException> create(Set<AssetId> missingSources,
-      Iterable<Module> transitiveModules, AssetReader reader) async {
-    var buffer = StringBuffer('''
-Unable to find modules for some sources, this is usually the result of either a
-bad import, a missing dependency in a package (or possibly a dev_dependency
-needs to move to a real dependency), or a build failure (if importing a
-generated file).
-
-Please check the following imports:\n
-''');
-
-    var checkedSourceDependencies = <AssetId, Set<AssetId>>{};
-    for (var module in transitiveModules) {
-      var missingIds = module.directDependencies.intersection(missingSources);
-      for (var missingId in missingIds) {
-        var checkedAlready =
-            checkedSourceDependencies.putIfAbsent(missingId, () => <AssetId>{});
-        for (var sourceId in module.sources) {
-          if (checkedAlready.contains(sourceId)) {
-            continue;
-          }
-          checkedAlready.add(sourceId);
-          var message =
-              await _missingImportMessage(sourceId, missingId, reader);
-          if (message != null) buffer.writeln(message);
-        }
-      }
-    }
-
-    return MissingModulesException._(buffer.toString());
-  }
-}
-
-/// Checks if [sourceId] directly imports [missingId], and returns an error
-/// message if so.
-Future<String> _missingImportMessage(
-    AssetId sourceId, AssetId missingId, AssetReader reader) async {
-  var contents = await reader.readAsString(sourceId);
-  // ignore: deprecated_member_use
-  var parsed = parseDirectives(contents, suppressErrors: true);
-  var import =
-      parsed.directives.whereType<UriBasedDirective>().firstWhere((directive) {
-    var uriString = directive.uri.stringValue;
-    if (uriString.startsWith('dart:')) return false;
-    var id = AssetId.resolve(uriString, from: sourceId);
-    return id == missingId;
-  }, orElse: () => null);
-  if (import == null) return null;
-  var lineInfo = parsed.lineInfo.getLocation(import.offset);
-  return '`$import` from $sourceId at $lineInfo';
-}
-
-/// An [Exception] that is thrown when there are some unsupported modules.
-class UnsupportedModules implements Exception {
-  final Set<Module> unsupportedModules;
-
-  UnsupportedModules(this.unsupportedModules);
-
-  Stream<ModuleLibrary> exactLibraries(AssetReader reader) async* {
-    for (var module in unsupportedModules) {
-      for (var source in module.sources) {
-        var libraryId = source.changeExtension(moduleLibraryExtension);
-        ModuleLibrary library;
-        if (await reader.canRead(libraryId)) {
-          library = ModuleLibrary.deserialize(
-              libraryId, await reader.readAsString(libraryId));
-        } else {
-          // A missing .module.library file indicates a part file, which can't
-          // have import statements, so we just skip them.
-          continue;
-        }
-        if (library.sdkDeps
-            .any((lib) => !module.platform.supportsLibrary(lib))) {
-          yield library;
-        }
-      }
-    }
-  }
-
-  @override
-  String toString() =>
-      'Some modules contained libraries that were incompatible '
-      'with the current platform.';
-}
diff --git a/build_modules/lib/src/kernel_builder.dart b/build_modules/lib/src/kernel_builder.dart
deleted file mode 100644
index 24e2abf..0000000
--- a/build_modules/lib/src/kernel_builder.dart
+++ /dev/null
@@ -1,424 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:graphs/graphs.dart' show crawlAsync;
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-
-import 'common.dart';
-import 'errors.dart';
-import 'module_builder.dart';
-import 'module_cache.dart';
-import 'modules.dart';
-import 'platform.dart';
-import 'scratch_space.dart';
-import 'workers.dart';
-
-const multiRootScheme = 'org-dartlang-app';
-
-/// A builder which can output kernel files for a given sdk.
-///
-/// This creates kernel files based on [moduleExtension] files, which are what
-/// determine the module structure of an application.
-class KernelBuilder implements Builder {
-  @override
-  final Map<String, List<String>> buildExtensions;
-
-  final bool useIncrementalCompiler;
-
-  final bool trackUnusedInputs;
-
-  final String outputExtension;
-
-  final DartPlatform platform;
-
-  /// Whether this should create summary kernel files or full kernel files.
-  ///
-  /// Summary files only contain the "outline" of the module - you can think of
-  /// this as everything but the method bodies.
-  final bool summaryOnly;
-
-  /// The sdk kernel file for the current platform.
-  final String sdkKernelPath;
-
-  /// The root directory of the platform's dart SDK.
-  ///
-  /// If not provided, defaults to the directory of
-  /// [Platform.resolvedExecutable].
-  ///
-  /// On flutter this is the path to the root of the flutter_patched_sdk
-  /// directory, which contains the platform kernel files.
-  final String platformSdk;
-
-  /// The absolute path to the libraries file for the current platform.
-  ///
-  /// If not provided, defaults to "lib/libraries.json" in the sdk directory.
-  final String librariesPath;
-
-  /// The `--target` argument passed to the kernel worker.
-  ///
-  /// Optional. When omitted the [platform] name is used.
-  final String kernelTargetName;
-
-  /// Experiments to pass to kernel (as --enable-experiment=<experiment> args).
-  final Iterable<String> experiments;
-
-  KernelBuilder(
-      {@required this.platform,
-      @required this.summaryOnly,
-      @required this.sdkKernelPath,
-      @required this.outputExtension,
-      String librariesPath,
-      bool useIncrementalCompiler,
-      bool trackUnusedInputs,
-      String platformSdk,
-      String kernelTargetName,
-      Iterable<String> experiments})
-      : platformSdk = platformSdk ?? sdkDir,
-        kernelTargetName = kernelTargetName ?? platform.name,
-        librariesPath = librariesPath ??
-            p.join(platformSdk ?? sdkDir, 'lib', 'libraries.json'),
-        useIncrementalCompiler = useIncrementalCompiler ?? false,
-        trackUnusedInputs = trackUnusedInputs ?? false,
-        buildExtensions = {
-          moduleExtension(platform): [outputExtension]
-        },
-        experiments = experiments ?? [];
-
-  @override
-  Future build(BuildStep buildStep) async {
-    var module = Module.fromJson(
-        json.decode(await buildStep.readAsString(buildStep.inputId))
-            as Map<String, dynamic>);
-    // Entrypoints always have a `.module` file for ease of looking them up,
-    // but they might not be the primary source.
-    if (module.primarySource.changeExtension(moduleExtension(platform)) !=
-        buildStep.inputId) {
-      return;
-    }
-
-    try {
-      await _createKernel(
-          module: module,
-          buildStep: buildStep,
-          summaryOnly: summaryOnly,
-          outputExtension: outputExtension,
-          targetName: kernelTargetName,
-          dartSdkDir: platformSdk,
-          sdkKernelPath: sdkKernelPath,
-          librariesPath: librariesPath,
-          useIncrementalCompiler: useIncrementalCompiler,
-          trackUnusedInputs: trackUnusedInputs,
-          experiments: experiments);
-    } on MissingModulesException catch (e) {
-      log.severe(e.toString());
-    } on KernelException catch (e, s) {
-      log.severe(
-          'Error creating '
-          '${module.primarySource.changeExtension(outputExtension)}',
-          e,
-          s);
-    }
-  }
-}
-
-/// Creates a kernel file for [module].
-Future<void> _createKernel(
-    {@required Module module,
-    @required BuildStep buildStep,
-    @required bool summaryOnly,
-    @required String outputExtension,
-    @required String targetName,
-    @required String dartSdkDir,
-    @required String sdkKernelPath,
-    @required String librariesPath,
-    @required bool useIncrementalCompiler,
-    @required bool trackUnusedInputs,
-    @required Iterable<String> experiments}) async {
-  var request = WorkRequest();
-  var scratchSpace = await buildStep.fetchResource(scratchSpaceResource);
-  var outputId = module.primarySource.changeExtension(outputExtension);
-  var outputFile = scratchSpace.fileFor(outputId);
-
-  File packagesFile;
-  var kernelDeps = <AssetId>[];
-
-  // Maps the inputs paths we provide to the kernel worker to asset ids,
-  // if `trackUnusedInputs` is `true`.
-  Map<String, AssetId> kernelInputPathToId;
-  // If `trackUnusedInputs` is `true`, this is the file we will use to
-  // communicate the used inputs with the kernel worker.
-  File usedInputsFile;
-
-  await buildStep.trackStage('CollectDeps', () async {
-    var sourceDeps = <AssetId>[];
-
-    await _findModuleDeps(
-        module, kernelDeps, sourceDeps, buildStep, outputExtension);
-
-    var allAssetIds = <AssetId>{
-      ...module.sources,
-      ...kernelDeps,
-      ...sourceDeps,
-    };
-    await scratchSpace.ensureAssets(allAssetIds, buildStep);
-
-    packagesFile = await createPackagesFile(allAssetIds);
-    if (trackUnusedInputs) {
-      usedInputsFile = await File(p.join(
-              (await Directory.systemTemp.createTemp('kernel_builder_')).path,
-              'used_inputs.txt'))
-          .create();
-      kernelInputPathToId = {};
-    }
-
-    await _addRequestArguments(
-        request,
-        module,
-        kernelDeps,
-        targetName,
-        dartSdkDir,
-        sdkKernelPath,
-        librariesPath,
-        outputFile,
-        packagesFile,
-        summaryOnly,
-        useIncrementalCompiler,
-        buildStep,
-        experiments,
-        usedInputsFile: usedInputsFile,
-        kernelInputPathToId: kernelInputPathToId);
-  });
-
-  // We need to make sure and clean up the temp dir, even if we fail to compile.
-  try {
-    var frontendWorker = await buildStep.fetchResource(frontendDriverResource);
-    var response = await frontendWorker.doWork(request,
-        trackWork: (response) => buildStep
-            .trackStage('Kernel Generate', () => response, isExternal: true));
-    if (response.exitCode != EXIT_CODE_OK || !await outputFile.exists()) {
-      throw KernelException(
-          outputId, '${request.arguments.join(' ')}\n${response.output}');
-    }
-
-    if (response.output?.isEmpty == false) {
-      log.info(response.output);
-    }
-
-    // Copy the output back using the buildStep.
-    await scratchSpace.copyOutput(outputId, buildStep, requireContent: true);
-
-    // Note that we only want to do this on success, we can't trust the unused
-    // inputs if there is a failure.
-    if (usedInputsFile != null) {
-      await reportUnusedKernelInputs(
-          usedInputsFile, kernelDeps, kernelInputPathToId, buildStep);
-    }
-  } finally {
-    await packagesFile.parent.delete(recursive: true);
-    await usedInputsFile?.parent?.delete(recursive: true);
-  }
-}
-
-/// Reports any unused kernel inputs based on the [usedInputsFile] we get
-/// back from the kernel/ddk workers.
-///
-/// This file logs paths as they were given in the original [WorkRequest],
-/// so [inputPathToId] is used to map those paths back to the kernel asset ids.
-///
-/// This function will not report any unused dependencies if:
-///
-/// - It isn't able to match all reported used dependencies to an asset id (it
-///   would be unsafe to do so in that case).
-/// - No used dependencies are reported (it is assumed something went wrong
-///   or there were zero deps to begin with).
-Future<void> reportUnusedKernelInputs(
-    File usedInputsFile,
-    Iterable<AssetId> transitiveKernelDeps,
-    Map<String, AssetId> inputPathToId,
-    BuildStep buildStep) async {
-  var usedPaths = await usedInputsFile.readAsLines();
-  if (usedPaths.isEmpty || usedPaths.first == '') return;
-
-  String firstMissingInputPath;
-  var usedIds = usedPaths.map((usedPath) {
-    var id = inputPathToId[usedPath];
-    if (id == null) firstMissingInputPath ??= usedPath;
-    return id;
-  }).toSet();
-
-  if (firstMissingInputPath != null) {
-    log.warning('Error reporting unused kernel deps, unable to map path: '
-        '`$firstMissingInputPath` back to an asset id.\n\nPlease file an issue '
-        'at https://github.com/dart-lang/build/issues/new.');
-    return;
-  }
-
-  buildStep.reportUnusedAssets(
-      transitiveKernelDeps.where((id) => !usedIds.contains(id)));
-}
-
-/// Finds the transitive dependencies of [root] and categorizes them as
-/// [kernelDeps] or [sourceDeps].
-///
-/// A module will have it's kernel file in [kernelDeps] if it and all of it's
-/// transitive dependencies have readable kernel files. If any module has no
-/// readable kernel file then it, and all of it's dependents will be categorized
-/// as [sourceDeps] which will have all of their [Module.sources].
-Future<void> _findModuleDeps(
-    Module root,
-    List<AssetId> kernelDeps,
-    List<AssetId> sourceDeps,
-    BuildStep buildStep,
-    String outputExtension) async {
-  final resolvedModules = await _resolveTransitiveModules(root, buildStep);
-
-  final sourceOnly = await _parentsOfMissingKernelFiles(
-      resolvedModules, buildStep, outputExtension);
-
-  for (final module in resolvedModules) {
-    if (sourceOnly.contains(module.primarySource)) {
-      sourceDeps.addAll(module.sources);
-    } else {
-      kernelDeps.add(module.primarySource.changeExtension(outputExtension));
-    }
-  }
-}
-
-/// The transitive dependencies of [root], not including [root] itself.
-Future<List<Module>> _resolveTransitiveModules(
-    Module root, BuildStep buildStep) async {
-  var missing = <AssetId>{};
-  var modules = await crawlAsync<AssetId, Module>(
-          [root.primarySource],
-          (id) => buildStep.fetchResource(moduleCache).then((c) async {
-                var moduleId =
-                    id.changeExtension(moduleExtension(root.platform));
-                var module = await c.find(moduleId, buildStep);
-                if (module == null) {
-                  missing.add(moduleId);
-                } else if (module.isMissing) {
-                  missing.add(module.primarySource);
-                }
-                return module;
-              }),
-          (id, module) => module.directDependencies)
-      .skip(1) // Skip the root.
-      .toList();
-
-  if (missing.isNotEmpty) {
-    throw await MissingModulesException.create(
-        missing, [...modules, root], buildStep);
-  }
-
-  return modules;
-}
-
-/// Finds the primary source of all transitive parents of any module which does
-/// not have a readable kernel file.
-///
-/// Inverts the direction of the graph and then crawls to all reachables nodes
-/// from the modules which do not have a readable kernel file
-Future<Set<AssetId>> _parentsOfMissingKernelFiles(
-    List<Module> modules, BuildStep buildStep, String outputExtension) async {
-  final sourceOnly = <AssetId>{};
-  final parents = <AssetId, Set<AssetId>>{};
-  for (final module in modules) {
-    for (final dep in module.directDependencies) {
-      parents.putIfAbsent(dep, () => <AssetId>{}).add(module.primarySource);
-    }
-    if (!await buildStep
-        .canRead(module.primarySource.changeExtension(outputExtension))) {
-      sourceOnly.add(module.primarySource);
-    }
-  }
-  final toCrawl = Queue.of(sourceOnly);
-  while (toCrawl.isNotEmpty) {
-    final current = toCrawl.removeFirst();
-    if (!parents.containsKey(current)) continue;
-    for (final next in parents[current]) {
-      if (!sourceOnly.add(next)) {
-        toCrawl.add(next);
-      }
-    }
-  }
-  return sourceOnly;
-}
-
-/// Fills in all the required arguments for [request] in order to compile the
-/// kernel file for [module].
-Future<void> _addRequestArguments(
-  WorkRequest request,
-  Module module,
-  Iterable<AssetId> transitiveKernelDeps,
-  String targetName,
-  String sdkDir,
-  String sdkKernelPath,
-  String librariesPath,
-  File outputFile,
-  File packagesFile,
-  bool summaryOnly,
-  bool useIncrementalCompiler,
-  AssetReader reader,
-  Iterable<String> experiments, {
-  File usedInputsFile,
-  Map<String, AssetId> kernelInputPathToId,
-}) async {
-  // Add all kernel outlines as summary inputs, with digests.
-  var inputs = await Future.wait(transitiveKernelDeps.map((id) async {
-    var relativePath = p.url.relative(scratchSpace.fileFor(id).uri.path,
-        from: scratchSpace.tempDir.uri.path);
-    var path = '$multiRootScheme:///$relativePath';
-    if (kernelInputPathToId != null) {
-      kernelInputPathToId[path] = id;
-    }
-    return Input()
-      ..path = path
-      ..digest = (await reader.digest(id)).bytes;
-  }));
-  request.arguments.addAll([
-    '--dart-sdk-summary=${Uri.file(p.join(sdkDir, sdkKernelPath))}',
-    '--output=${outputFile.path}',
-    '--packages-file=${packagesFile.uri}',
-    '--multi-root-scheme=$multiRootScheme',
-    '--exclude-non-sources',
-    summaryOnly ? '--summary-only' : '--no-summary-only',
-    '--target=$targetName',
-    '--libraries-file=${p.toUri(librariesPath)}',
-    if (useIncrementalCompiler) ...[
-      '--reuse-compiler-result',
-      '--use-incremental-compiler',
-    ],
-    if (usedInputsFile != null)
-      '--used-inputs=${usedInputsFile.uri.toFilePath()}',
-    for (var input in inputs)
-      '--input-${summaryOnly ? 'summary' : 'linked'}=${input.path}',
-    for (var experiment in experiments) '--enable-experiment=$experiment',
-    for (var source in module.sources) _sourceArg(source),
-  ]);
-
-  request.inputs.addAll([
-    ...inputs,
-    Input()
-      ..path = '${Uri.file(p.join(sdkDir, sdkKernelPath))}'
-      // Sdk updates fully invalidate the build anyways.
-      ..digest = md5.convert(utf8.encode(targetName)).bytes,
-  ]);
-}
-
-String _sourceArg(AssetId id) {
-  var uri = id.path.startsWith('lib')
-      ? canonicalUriFor(id)
-      : '$multiRootScheme:///${id.path}';
-  return '--source=$uri';
-}
diff --git a/build_modules/lib/src/meta_module.dart b/build_modules/lib/src/meta_module.dart
deleted file mode 100644
index 476cace..0000000
--- a/build_modules/lib/src/meta_module.dart
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:graphs/graphs.dart';
-import 'package:path/path.dart' as p;
-import 'package:json_annotation/json_annotation.dart';
-
-import 'common.dart';
-import 'module_library.dart';
-import 'modules.dart';
-import 'platform.dart';
-
-part 'meta_module.g.dart';
-
-/// Returns the top level directory in [path].
-///
-/// Throws an [ArgumentError] if [path] is just a filename with no directory.
-String _topLevelDir(String path) {
-  var parts = p.url.split(p.url.normalize(path));
-  String error;
-  if (parts.length == 1) {
-    error = 'The path `$path` does not contain a directory.';
-  } else if (parts.first == '..') {
-    error = 'The path `$path` reaches outside the root directory.';
-  }
-  if (error != null) {
-    throw ArgumentError(
-        'Cannot compute top level dir for path `$path`. $error');
-  }
-  return parts.first;
-}
-
-/// Creates a module containing [componentLibraries].
-Module _moduleForComponent(
-    List<ModuleLibrary> componentLibraries, DartPlatform platform) {
-  // Name components based on first alphabetically sorted node, preferring
-  // public srcs (not under lib/src).
-  var sources = componentLibraries.map((n) => n.id).toSet();
-  var nonSrcIds = sources.where((id) => !id.path.startsWith('lib/src/'));
-  var primaryId =
-      nonSrcIds.isNotEmpty ? nonSrcIds.reduce(_min) : sources.reduce(_min);
-  // Expand to include all the part files of each node, these aren't
-  // included as individual `_AssetNodes`s in `connectedComponents`.
-  sources.addAll(componentLibraries.expand((n) => n.parts));
-  var directDependencies = <AssetId>{}
-    ..addAll(componentLibraries.expand((n) => n.depsForPlatform(platform)))
-    ..removeAll(sources);
-  var isSupported = componentLibraries
-      .expand((l) => l.sdkDeps)
-      .every(platform.supportsLibrary);
-  return Module(primaryId, sources, directDependencies, platform, isSupported);
-}
-
-/// Gets the local (same top level dir of the same package) transitive deps of
-/// [module] using [assetsToModules].
-Set<AssetId> _localTransitiveDeps(
-    Module module, Map<AssetId, Module> assetsToModules) {
-  var localTransitiveDeps = <AssetId>{};
-  var nextIds = module.directDependencies;
-  var seenIds = <AssetId>{};
-  while (nextIds.isNotEmpty) {
-    var ids = nextIds;
-    seenIds.addAll(ids);
-    nextIds = <AssetId>{};
-    for (var id in ids) {
-      var module = assetsToModules[id];
-      if (module == null) continue; // Skip non-local modules
-      if (localTransitiveDeps.add(module.primarySource)) {
-        nextIds.addAll(module.directDependencies.difference(seenIds));
-      }
-    }
-  }
-  return localTransitiveDeps;
-}
-
-/// Creates a map of modules to the entrypoint modules that transitively
-/// depend on those modules.
-Map<AssetId, Set<AssetId>> _findReverseEntrypointDeps(
-    Iterable<Module> entrypointModules, Iterable<Module> modules) {
-  var reverseDeps = <AssetId, Set<AssetId>>{};
-  var assetsToModules = <AssetId, Module>{};
-  for (var module in modules) {
-    for (var assetId in module.sources) {
-      assetsToModules[assetId] = module;
-    }
-  }
-  for (var module in entrypointModules) {
-    for (var moduleDep in _localTransitiveDeps(module, assetsToModules)) {
-      reverseDeps
-          .putIfAbsent(moduleDep, () => <AssetId>{})
-          .add(module.primarySource);
-    }
-  }
-  return reverseDeps;
-}
-
-/// Merges [modules] into a minimum set of [Module]s using the
-/// following rules:
-///
-///   * If it is an entrypoint module do not merge it.
-///   * If it is not depended on my any entrypoint do not merge it.
-///   * If it is depended on by no entrypoint merge it into the entrypoint
-///   modules
-///   * Else merge it into with others that are depended on by the same set of
-///   entrypoints
-List<Module> _mergeModules(Iterable<Module> modules, Set<AssetId> entrypoints) {
-  var entrypointModules =
-      modules.where((m) => m.sources.any(entrypoints.contains)).toList();
-
-  // Groups of modules that can be merged into an existing entrypoint module.
-  var entrypointModuleGroups = {
-    for (var m in entrypointModules) m.primarySource: [m],
-  };
-
-  // Maps modules to entrypoint modules that transitively depend on them.
-  var modulesToEntryPoints =
-      _findReverseEntrypointDeps(entrypointModules, modules);
-
-  // Modules which are not depended on by any entrypoint
-  var standaloneModules = <Module>[];
-
-  // Modules which are merged with others.
-  var mergedModules = <String, List<Module>>{};
-
-  for (var module in modules) {
-    // Skip entrypoint modules.
-    if (entrypointModuleGroups.containsKey(module.primarySource)) continue;
-
-    // The entry points that transitively import this module.
-    var entrypointIds = modulesToEntryPoints[module.primarySource];
-
-    // If no entrypoint imports the module, just leave it alone.
-    if (entrypointIds == null || entrypointIds.isEmpty) {
-      standaloneModules.add(module);
-      continue;
-    }
-
-    // If there are multiple entry points for a given resource we must create
-    // a new shared module. Use `$` to signal that it is a shared module.
-    if (entrypointIds.length > 1) {
-      var mId = (entrypointIds.toList()..sort()).map((m) => m.path).join('\$');
-      mergedModules.putIfAbsent(mId, () => []).add(module);
-    } else {
-      entrypointModuleGroups[entrypointIds.single].add(module);
-    }
-  }
-
-  return mergedModules.values
-      .map(Module.merge)
-      .map(_withConsistentPrimarySource)
-      .followedBy(entrypointModuleGroups.values.map(Module.merge))
-      .followedBy(standaloneModules)
-      .toList();
-}
-
-Module _withConsistentPrimarySource(Module m) => Module(m.sources.reduce(_min),
-    m.sources, m.directDependencies, m.platform, m.isSupported);
-
-T _min<T extends Comparable<T>>(T a, T b) => a.compareTo(b) < 0 ? a : b;
-
-/// Compute modules for the  internal strongly connected components of
-/// [libraries].
-///
-/// This should only be called with [libraries] all in the same package and top
-/// level directory within the package.
-///
-/// A dependency is considered "internal" if it is within [libraries]. Any
-/// "external" deps are ignored during this computation since we are only
-/// considering the strongly connected components within [libraries], but they
-/// will be maintained as a dependency of the module to be used at a later step.
-///
-/// Part files are also tracked but ignored during computation of strongly
-/// connected components, as they must always be a part of the containing
-/// library's module.
-List<Module> _computeModules(
-    Map<AssetId, ModuleLibrary> libraries, DartPlatform platform) {
-  assert(() {
-    var dir = _topLevelDir(libraries.values.first.id.path);
-    return libraries.values.every((l) => _topLevelDir(l.id.path) == dir);
-  }());
-
-  final connectedComponents = stronglyConnectedComponents<ModuleLibrary>(
-      libraries.values,
-      (n) => n
-          .depsForPlatform(platform)
-          // Only "internal" dependencies
-          .where(libraries.containsKey)
-          .map((dep) => libraries[dep]),
-      equals: (a, b) => a.id == b.id,
-      hashCode: (l) => l.id.hashCode);
-
-  final entryIds =
-      libraries.values.where((l) => l.isEntryPoint).map((l) => l.id).toSet();
-  return _mergeModules(
-      connectedComponents.map((c) => _moduleForComponent(c, platform)),
-      entryIds);
-}
-
-@JsonSerializable()
-class MetaModule {
-  @JsonKey(name: 'm', nullable: false)
-  final List<Module> modules;
-
-  MetaModule(List<Module> modules) : modules = List.unmodifiable(modules);
-
-  /// Generated factory constructor.
-  factory MetaModule.fromJson(Map<String, dynamic> json) =>
-      _$MetaModuleFromJson(json);
-
-  Map<String, dynamic> toJson() => _$MetaModuleToJson(this);
-
-  static Future<MetaModule> forLibraries(
-      AssetReader reader,
-      List<AssetId> libraryIds,
-      ModuleStrategy strategy,
-      DartPlatform platform) async {
-    var libraries = <ModuleLibrary>[];
-    for (var id in libraryIds) {
-      libraries.add(ModuleLibrary.deserialize(
-          id.changeExtension('').changeExtension('.dart'),
-          await reader.readAsString(id)));
-    }
-    switch (strategy) {
-      case ModuleStrategy.fine:
-        return _fineModulesForLibraries(reader, libraries, platform);
-      case ModuleStrategy.coarse:
-        return _coarseModulesForLibraries(reader, libraries, platform);
-    }
-    throw StateError('Unrecognized module strategy $strategy');
-  }
-}
-
-MetaModule _coarseModulesForLibraries(
-    AssetReader reader, List<ModuleLibrary> libraries, DartPlatform platform) {
-  var librariesByDirectory = <String, Map<AssetId, ModuleLibrary>>{};
-  for (var library in libraries) {
-    final dir = _topLevelDir(library.id.path);
-    if (!librariesByDirectory.containsKey(dir)) {
-      librariesByDirectory[dir] = <AssetId, ModuleLibrary>{};
-    }
-    librariesByDirectory[dir][library.id] = library;
-  }
-  final modules = librariesByDirectory.values
-      .expand((libs) => _computeModules(libs, platform))
-      .toList();
-  _sortModules(modules);
-  return MetaModule(modules);
-}
-
-MetaModule _fineModulesForLibraries(
-    AssetReader reader, List<ModuleLibrary> libraries, DartPlatform platform) {
-  var modules = libraries
-      .map((library) => Module(
-          library.id,
-          library.parts.followedBy([library.id]),
-          library.depsForPlatform(platform),
-          platform,
-          library.sdkDeps.every(platform.supportsLibrary)))
-      .toList();
-  _sortModules(modules);
-  return MetaModule(modules);
-}
-
-/// Sorts [modules] in place so we get deterministic output.
-void _sortModules(List<Module> modules) {
-  modules.sort((a, b) => a.primarySource.compareTo(b.primarySource));
-}
diff --git a/build_modules/lib/src/meta_module.g.dart b/build_modules/lib/src/meta_module.g.dart
deleted file mode 100644
index 908194a..0000000
--- a/build_modules/lib/src/meta_module.g.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'meta_module.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-MetaModule _$MetaModuleFromJson(Map<String, dynamic> json) {
-  return MetaModule(
-    (json['m'] as List)
-        .map((e) => Module.fromJson(e as Map<String, dynamic>))
-        .toList(),
-  );
-}
-
-Map<String, dynamic> _$MetaModuleToJson(MetaModule instance) =>
-    <String, dynamic>{
-      'm': instance.modules,
-    };
diff --git a/build_modules/lib/src/meta_module_builder.dart b/build_modules/lib/src/meta_module_builder.dart
deleted file mode 100644
index bc92e96..0000000
--- a/build_modules/lib/src/meta_module_builder.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-import 'common.dart';
-import 'meta_module.dart';
-import 'module_cache.dart';
-import 'module_library_builder.dart';
-import 'platform.dart';
-
-/// The extension for serialized meta module assets for a specific platform.
-String metaModuleExtension(DartPlatform platform) =>
-    '.${platform.name}.meta_module.raw';
-
-/// Creates `.meta_module` file for any Dart library.
-///
-/// This file contains information about the full computed
-/// module structure for the package.
-class MetaModuleBuilder implements Builder {
-  @override
-  final Map<String, List<String>> buildExtensions;
-
-  final ModuleStrategy strategy;
-
-  final DartPlatform _platform;
-
-  MetaModuleBuilder(this._platform, {ModuleStrategy strategy})
-      : strategy = strategy ?? ModuleStrategy.coarse,
-        buildExtensions = {
-          r'$lib$': [metaModuleExtension(_platform)]
-        };
-
-  factory MetaModuleBuilder.forOptions(
-          DartPlatform platform, BuilderOptions options) =>
-      MetaModuleBuilder(platform, strategy: moduleStrategy(options));
-
-  @override
-  Future build(BuildStep buildStep) async {
-    if (buildStep.inputId.package == r'$sdk') return;
-
-    var libraryAssets =
-        await buildStep.findAssets(Glob('**$moduleLibraryExtension')).toList();
-
-    var metaModule = await MetaModule.forLibraries(
-        buildStep, libraryAssets, strategy, _platform);
-    var id = AssetId(
-        buildStep.inputId.package, 'lib/${metaModuleExtension(_platform)}');
-    var metaModules = await buildStep.fetchResource(metaModuleCache);
-    await metaModules.write(id, buildStep, metaModule);
-  }
-}
diff --git a/build_modules/lib/src/meta_module_clean_builder.dart b/build_modules/lib/src/meta_module_clean_builder.dart
deleted file mode 100644
index fb05802..0000000
--- a/build_modules/lib/src/meta_module_clean_builder.dart
+++ /dev/null
@@ -1,167 +0,0 @@
-// 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:collection';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:graphs/graphs.dart';
-
-import 'meta_module.dart';
-import 'meta_module_builder.dart';
-import 'module_cache.dart';
-import 'modules.dart';
-import 'platform.dart';
-
-/// The extension for serialized clean meta module assets.
-///
-/// Clean in this context means all dependencies are primary sources.
-/// Furthermore cyclic modules are merged into a single module.
-String metaModuleCleanExtension(DartPlatform platform) =>
-    '.${platform.name}.meta_module.clean';
-
-/// Creates `.meta_module.clean` file for any Dart library.
-///
-/// This file contains information about the full computed
-/// module structure for the package where each module's dependencies
-/// are only primary sources.
-///
-/// Note if the raw meta module file can't be found for any of the
-/// module's transitive dependencies there will be no output.
-class MetaModuleCleanBuilder implements Builder {
-  @override
-  final Map<String, List<String>> buildExtensions;
-
-  final DartPlatform _platform;
-
-  MetaModuleCleanBuilder(this._platform)
-      : buildExtensions = {
-          metaModuleExtension(_platform): [metaModuleCleanExtension(_platform)]
-        };
-
-  @override
-  Future build(BuildStep buildStep) async {
-    var assetToModule = (await buildStep.fetchResource(_assetToModule))
-        .putIfAbsent(_platform, () => {});
-    var assetToPrimary = (await buildStep.fetchResource(_assetToPrimary))
-        .putIfAbsent(_platform, () => {});
-    var modules = await _transitiveModules(
-        buildStep, buildStep.inputId, assetToModule, assetToPrimary, _platform);
-    var connectedComponents = stronglyConnectedComponents<Module>(
-        modules,
-        (m) => m.directDependencies.map((d) =>
-            assetToModule[d] ??
-            Module(d, [d], [], _platform, false, isMissing: true)),
-        equals: (a, b) => a.primarySource == b.primarySource,
-        hashCode: (m) => m.primarySource.hashCode);
-    Module merge(List<Module> c) =>
-        _mergeComponent(c, assetToPrimary, _platform);
-    bool primarySourceInPackage(Module m) =>
-        m.primarySource.package == buildStep.inputId.package;
-    // Ensure deterministic output by sorting the modules.
-    var cleanModules = SplayTreeSet<Module>(
-        (a, b) => a.primarySource.compareTo(b.primarySource))
-      ..addAll(connectedComponents.map(merge).where(primarySourceInPackage));
-    await buildStep.writeAsString(
-        AssetId(buildStep.inputId.package,
-            'lib/${metaModuleCleanExtension(_platform)}'),
-        jsonEncode(MetaModule(cleanModules.toList())));
-  }
-}
-
-/// Map of [AssetId] to corresponding non clean containing [Module] per
-/// [DartPlatform].
-final _assetToModule = Resource<Map<DartPlatform, Map<AssetId, Module>>>(
-    () => {},
-    dispose: (map) => map.clear());
-
-/// Map of [AssetId] to corresponding primary [AssetId] within the same
-/// clean [Module] per platform.
-final _assetToPrimary = Resource<Map<DartPlatform, Map<AssetId, AssetId>>>(
-    () => {},
-    dispose: (map) => map.clear());
-
-/// Returns a set of all modules transitively reachable from the provided meta
-/// module asset.
-Future<Set<Module>> _transitiveModules(
-    BuildStep buildStep,
-    AssetId metaAsset,
-    Map<AssetId, Module> assetToModule,
-    Map<AssetId, AssetId> assetToPrimary,
-    DartPlatform platform) async {
-  var dependentModules = <Module>{};
-  // Ensures we only process a meta file once.
-  var seenMetas = <AssetId>{}..add(metaAsset);
-  var metaModules = await buildStep.fetchResource(metaModuleCache);
-  var meta = await metaModules.find(buildStep.inputId, buildStep);
-  var nextModules = List.of(meta.modules);
-  while (nextModules.isNotEmpty) {
-    var module = nextModules.removeLast();
-    dependentModules.add(module);
-    for (var source in module.sources) {
-      assetToModule[source] = module;
-      // The asset to primary map will be updated when the merged modules are
-      // created. This is why we can't use the assetToModule map.
-      assetToPrimary[source] = module.primarySource;
-    }
-    for (var dep in module.directDependencies) {
-      var depMetaAsset =
-          AssetId(dep.package, 'lib/${metaModuleExtension(platform)}');
-      // The testing package is an odd package used by package:frontend_end
-      // which doesn't really exist.
-      // https://github.com/dart-lang/sdk/issues/32952
-      if (seenMetas.contains(depMetaAsset) || dep.package == 'testing') {
-        continue;
-      }
-      seenMetas.add(depMetaAsset);
-      if (!await buildStep.canRead(depMetaAsset)) {
-        log.warning('Unable to read module information for '
-            'package:${depMetaAsset.package}, make sure you have a dependency '
-            'on it in your pubspec.');
-        continue;
-      }
-      var depMeta = await metaModules.find(depMetaAsset, buildStep);
-      nextModules.addAll(depMeta.modules);
-    }
-  }
-  return dependentModules;
-}
-
-/// Merges the modules in a strongly connected component.
-///
-/// Note this will clean the module dependencies as the merge happens.
-/// The result will be that all dependencies are primary sources.
-Module _mergeComponent(List<Module> connectedComponent,
-    Map<AssetId, AssetId> assetToPrimary, DartPlatform platform) {
-  var sources = <AssetId>{};
-  var deps = <AssetId>{};
-  // Sort the modules to deterministicly select the primary source.
-  var components =
-      SplayTreeSet<Module>((a, b) => a.primarySource.compareTo(b.primarySource))
-        ..addAll(connectedComponent);
-  var primarySource = components.first.primarySource;
-  var isSupported = true;
-  for (var module in connectedComponent) {
-    sources.addAll(module.sources);
-    isSupported = isSupported && module.isSupported;
-    for (var dep in module.directDependencies) {
-      var primaryDep = assetToPrimary[dep];
-      if (primaryDep == null) continue;
-      // This dep is now merged into sources so skip it.
-      if (!components
-          .map((c) => c.sources)
-          .any((s) => s.contains(primaryDep))) {
-        deps.add(primaryDep);
-      }
-    }
-  }
-  // Update map so that sources now point to the merged module.
-  var mergedModule =
-      Module(primarySource, sources, deps, platform, isSupported);
-  for (var source in mergedModule.sources) {
-    assetToPrimary[source] = mergedModule.primarySource;
-  }
-  return mergedModule;
-}
diff --git a/build_modules/lib/src/module_builder.dart b/build_modules/lib/src/module_builder.dart
deleted file mode 100644
index ee8dcb9..0000000
--- a/build_modules/lib/src/module_builder.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-
-import 'meta_module_clean_builder.dart';
-import 'module_cache.dart';
-import 'module_library.dart';
-import 'module_library_builder.dart' show moduleLibraryExtension;
-import 'modules.dart';
-import 'platform.dart';
-
-/// The extension for serialized module assets.
-String moduleExtension(DartPlatform platform) => '.${platform.name}.module';
-
-/// Creates `.module` files for any `.dart` file that is the primary dart
-/// source of a [Module].
-class ModuleBuilder implements Builder {
-  final DartPlatform _platform;
-
-  ModuleBuilder(this._platform)
-      : buildExtensions = {
-          '.dart': [moduleExtension(_platform)]
-        };
-
-  @override
-  final Map<String, List<String>> buildExtensions;
-
-  @override
-  Future build(BuildStep buildStep) async {
-    final cleanMetaModules = await buildStep.fetchResource(metaModuleCache);
-    final metaModule = await cleanMetaModules.find(
-        AssetId(buildStep.inputId.package,
-            'lib/${metaModuleCleanExtension(_platform)}'),
-        buildStep);
-    var outputModule = metaModule.modules.firstWhere(
-        (m) => m.primarySource == buildStep.inputId,
-        orElse: () => null);
-    if (outputModule == null) {
-      final serializedLibrary = await buildStep.readAsString(
-          buildStep.inputId.changeExtension(moduleLibraryExtension));
-      final libraryModule =
-          ModuleLibrary.deserialize(buildStep.inputId, serializedLibrary);
-      if (libraryModule.hasMain) {
-        outputModule = metaModule.modules
-            .firstWhere((m) => m.sources.contains(buildStep.inputId));
-      }
-    }
-    if (outputModule == null) return;
-    final modules = await buildStep.fetchResource(moduleCache);
-    await modules.write(
-        buildStep.inputId.changeExtension(moduleExtension(_platform)),
-        buildStep,
-        outputModule);
-  }
-}
diff --git a/build_modules/lib/src/module_cache.dart b/build_modules/lib/src/module_cache.dart
deleted file mode 100644
index 5a91108..0000000
--- a/build_modules/lib/src/module_cache.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-
-import 'meta_module.dart';
-import 'modules.dart';
-
-Map<String, dynamic> _deserialize(List<int> bytes) =>
-    jsonDecode(utf8.decode(bytes)) as Map<String, dynamic>;
-
-List<int> _serialize(Map<String, dynamic> data) =>
-    utf8.encode(jsonEncode(data));
-
-final metaModuleCache = DecodingCache.resource(
-    (m) => MetaModule.fromJson(_deserialize(m)), (m) => _serialize(m.toJson()));
-
-final moduleCache = DecodingCache.resource(
-    (m) => Module.fromJson(_deserialize(m)), (m) => _serialize(m.toJson()));
-
-/// A cache of objects decoded from written assets suitable for use as a
-/// [Resource].
-///
-/// Instances that are decoded will be cached throughout the duration of a build
-/// and invalidated between builds. Instances that are shared through the cache
-/// should be treated as immutable to avoid leaking any information which was
-/// not loaded from the underlying asset.
-class DecodingCache<T> {
-  /// Create a [Resource] which can decoded instances of [T] serialized via json
-  /// to assets.
-  static Resource<DecodingCache<T>> resource<T>(
-          T Function(List<int>) fromBytes, List<int> Function(T) toBytes) =>
-      Resource<DecodingCache<T>>(() => DecodingCache._(fromBytes, toBytes),
-          dispose: (c) => c._dispose());
-
-  final _cached = <AssetId, _Entry<T>>{};
-
-  final T Function(List<int>) _fromBytes;
-  final List<int> Function(T) _toBytes;
-
-  DecodingCache._(this._fromBytes, this._toBytes);
-
-  void _dispose() {
-    _cached.removeWhere((_, entry) => entry.digest == null);
-    for (var entry in _cached.values) {
-      entry.needsCheck = true;
-    }
-  }
-
-  /// Find and deserialize a [T] stored in [id].
-  ///
-  /// If the asset at [id] is unreadable the returned future will resolve to
-  /// `null`. If the instance is cached it will not be decoded again, but the
-  /// content dependencies will be tracked through [reader].
-  Future<T> find(AssetId id, AssetReader reader) async {
-    if (!await reader.canRead(id)) return null;
-    _Entry<T> entry;
-    if (!_cached.containsKey(id)) {
-      entry = _cached[id] = _Entry()
-        ..needsCheck = false
-        ..value = Result.capture(reader.readAsBytes(id).then(_fromBytes))
-        ..digest = Result.capture(reader.digest(id));
-    } else {
-      entry = _cached[id];
-      if (entry.needsCheck) {
-        await (entry.onGoingCheck ??= () async {
-          var previousDigest = await Result.release(entry.digest);
-          entry.digest = Result.capture(reader.digest(id));
-          if (await Result.release(entry.digest) != previousDigest) {
-            entry.value =
-                Result.capture(reader.readAsBytes(id).then(_fromBytes));
-          }
-          entry
-            ..needsCheck = false
-            ..onGoingCheck = null;
-        }());
-      }
-    }
-    return Result.release(entry.value);
-  }
-
-  /// Serialized and write a [T] to [id].
-  ///
-  /// The instance will be cached so that later calls to [find] may return the
-  /// instances without deserializing it.
-  Future<void> write(AssetId id, AssetWriter writer, T instance) async {
-    await writer.writeAsBytes(id, _toBytes(instance));
-    _cached[id] = _Entry()
-      ..needsCheck = false
-      ..value = Result.capture(Future.value(instance));
-  }
-}
-
-class _Entry<T> {
-  bool needsCheck = false;
-  Future<Result<T>> value;
-  Future<Result<Digest>> digest;
-  Future<void> onGoingCheck;
-}
diff --git a/build_modules/lib/src/module_cleanup.dart b/build_modules/lib/src/module_cleanup.dart
deleted file mode 100644
index ff1af73..0000000
--- a/build_modules/lib/src/module_cleanup.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-
-import 'module_library_builder.dart';
-
-class ModuleCleanup implements PostProcessBuilder {
-  const ModuleCleanup();
-
-  @override
-  void build(PostProcessBuildStep buildStep) {
-    buildStep.deletePrimaryInput();
-  }
-
-  @override
-  final inputExtensions = const [
-    moduleLibraryExtension,
-    '.meta_module.raw',
-    '.meta_module.clean',
-    '.module',
-  ];
-}
diff --git a/build_modules/lib/src/module_library.dart b/build_modules/lib/src/module_library.dart
deleted file mode 100644
index c00c93a..0000000
--- a/build_modules/lib/src/module_library.dart
+++ /dev/null
@@ -1,224 +0,0 @@
-// 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:convert';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart';
-import 'package:build/build.dart';
-import 'package:meta/meta.dart';
-
-import 'platform.dart';
-
-/// A Dart library within a module.
-///
-/// Modules can be computed based on library dependencies (imports and exports)
-/// and parts.
-class ModuleLibrary {
-  /// The AssetId of the original Dart source file.
-  final AssetId id;
-
-  /// Whether this library can be imported.
-  ///
-  /// This will be false if the source file is a "part of", or imports code that
-  /// can't be used outside the SDK.
-  final bool isImportable;
-
-  /// Whether this library is an entrypoint.
-  ///
-  /// True if the library is in `lib/` but not `lib/src`, or if it is outside of
-  /// `lib/` and contains a `main` method. Always false if this is not an
-  /// importable library.
-  final bool isEntryPoint;
-
-  /// Deps that are imported with a conditional import.
-  ///
-  /// Keys are the stringified ast node for the conditional, and the default
-  /// import is under the magic `$default` key.
-  final List<Map<String, AssetId>> conditionalDeps;
-
-  /// The IDs of libraries that are imported or exported by this library.
-  ///
-  /// Null if this is not an importable library.
-  final Set<AssetId> _deps;
-
-  /// The "part" files for this library.
-  ///
-  /// Null if this is not an importable library.
-  final Set<AssetId> parts;
-
-  /// The `dart:` libraries that this library directly depends on.
-  final Set<String> sdkDeps;
-
-  /// Whether this library has a `main` function.
-  final bool hasMain;
-
-  ModuleLibrary._(this.id,
-      {@required this.isEntryPoint,
-      @required Set<AssetId> deps,
-      @required this.parts,
-      @required this.conditionalDeps,
-      @required this.sdkDeps,
-      @required this.hasMain})
-      : _deps = deps,
-        isImportable = true;
-
-  ModuleLibrary._nonImportable(this.id)
-      : isImportable = false,
-        isEntryPoint = false,
-        _deps = null,
-        parts = null,
-        conditionalDeps = null,
-        sdkDeps = null,
-        hasMain = false;
-
-  factory ModuleLibrary._fromCompilationUnit(
-      AssetId id, bool isEntryPoint, CompilationUnit parsed) {
-    var deps = <AssetId>{};
-    var parts = <AssetId>{};
-    var sdkDeps = <String>{};
-    var conditionalDeps = <Map<String, AssetId>>[];
-    for (var directive in parsed.directives) {
-      if (directive is! UriBasedDirective) continue;
-      var path = (directive as UriBasedDirective).uri.stringValue;
-      var uri = Uri.parse(path);
-      if (uri.isScheme('dart-ext')) {
-        // TODO: What should we do for native extensions?
-        continue;
-      }
-      if (uri.scheme == 'dart') {
-        sdkDeps.add(uri.path);
-        continue;
-      }
-      var linkedId = AssetId.resolve(path, from: id);
-      if (linkedId == null) continue;
-      if (directive is PartDirective) {
-        parts.add(linkedId);
-        continue;
-      }
-
-      List<Configuration> conditionalDirectiveConfigurations;
-
-      if (directive is ImportDirective && directive.configurations.isNotEmpty) {
-        conditionalDirectiveConfigurations = directive.configurations;
-      } else if (directive is ExportDirective &&
-          directive.configurations.isNotEmpty) {
-        conditionalDirectiveConfigurations = directive.configurations;
-      }
-      if (conditionalDirectiveConfigurations != null) {
-        var conditions = <String, AssetId>{r'$default': linkedId};
-        for (var condition in conditionalDirectiveConfigurations) {
-          if (Uri.parse(condition.uri.stringValue).scheme == 'dart') {
-            throw ArgumentError('Unsupported conditional import of '
-                '`${condition.uri.stringValue}` found in $id.');
-          }
-          conditions[condition.name.toSource()] =
-              AssetId.resolve(condition.uri.stringValue, from: id);
-        }
-        conditionalDeps.add(conditions);
-      } else {
-        deps.add(linkedId);
-      }
-    }
-    return ModuleLibrary._(id,
-        isEntryPoint: isEntryPoint,
-        deps: deps,
-        parts: parts,
-        sdkDeps: sdkDeps,
-        conditionalDeps: conditionalDeps,
-        hasMain: _hasMainMethod(parsed));
-  }
-
-  /// Parse the directives from [source] and compute the library information.
-  static ModuleLibrary fromSource(AssetId id, String source) {
-    final isLibDir = id.path.startsWith('lib/');
-    // ignore: deprecated_member_use
-    final parsed = parseCompilationUnit(source,
-        name: id.path, suppressErrors: true, parseFunctionBodies: false);
-    // Packages within the SDK but published might have libraries that can't be
-    // used outside the SDK.
-    if (parsed.directives.any((d) =>
-        d is UriBasedDirective &&
-        d.uri.stringValue.startsWith('dart:_') &&
-        id.package != 'dart_internal')) {
-      return ModuleLibrary._nonImportable(id);
-    }
-    if (_isPart(parsed)) {
-      return ModuleLibrary._nonImportable(id);
-    }
-
-    final isEntryPoint =
-        (isLibDir && !id.path.startsWith('lib/src/')) || _hasMainMethod(parsed);
-    return ModuleLibrary._fromCompilationUnit(id, isEntryPoint, parsed);
-  }
-
-  /// Parses the output of [serialize] back into a [ModuleLibrary].
-  ///
-  /// Importable libraries can be round tripped to a String. Non-importable
-  /// libraries should not be printed or parsed.
-  factory ModuleLibrary.deserialize(AssetId id, String encoded) {
-    var json = jsonDecode(encoded);
-
-    return ModuleLibrary._(id,
-        isEntryPoint: json['isEntrypoint'] as bool,
-        deps: _deserializeAssetIds(json['deps'] as Iterable),
-        parts: _deserializeAssetIds(json['parts'] as Iterable),
-        sdkDeps: Set.of((json['sdkDeps'] as Iterable).cast<String>()),
-        conditionalDeps:
-            (json['conditionalDeps'] as Iterable).map((conditions) {
-          return Map.of((conditions as Map<String, dynamic>)
-              .map((k, v) => MapEntry(k, AssetId.parse(v as String))));
-        }).toList(),
-        hasMain: json['hasMain'] as bool);
-  }
-
-  String serialize() => jsonEncode({
-        'isEntrypoint': isEntryPoint,
-        'deps': _deps.map((id) => id.toString()).toList(),
-        'parts': parts.map((id) => id.toString()).toList(),
-        'conditionalDeps': conditionalDeps
-            .map((conditions) =>
-                conditions.map((k, v) => MapEntry(k, v.toString())))
-            .toList(),
-        'sdkDeps': sdkDeps.toList(),
-        'hasMain': hasMain,
-      });
-
-  List<AssetId> depsForPlatform(DartPlatform platform) {
-    return _deps.followedBy(conditionalDeps.map((conditions) {
-      var selectedImport = conditions[r'$default'];
-      assert(selectedImport != null);
-      for (var condition in conditions.keys) {
-        if (condition == r'$default') continue;
-        if (!condition.startsWith('dart.library.')) {
-          throw UnsupportedError(
-              '$condition not supported for config specific imports. Only the '
-              'dart.library.<name> constants are supported.');
-        }
-        var library = condition.substring('dart.library.'.length);
-        if (platform.supportsLibrary(library)) {
-          selectedImport = conditions[condition];
-          break;
-        }
-      }
-      return selectedImport;
-    })).toList();
-  }
-}
-
-Set<AssetId> _deserializeAssetIds(Iterable serlialized) =>
-    Set.from(serlialized.map((decoded) => AssetId.parse(decoded as String)));
-
-bool _isPart(CompilationUnit dart) =>
-    dart.directives.any((directive) => directive is PartOfDirective);
-
-/// Allows two or fewer arguments to `main` so that entrypoints intended for
-/// use with `spawnUri` get counted.
-//
-// TODO: This misses the case where a Dart file doesn't contain main(),
-// but has a part that does, or it exports a `main` from another library.
-bool _hasMainMethod(CompilationUnit dart) => dart.declarations.any((node) =>
-    node is FunctionDeclaration &&
-    node.name.name == 'main' &&
-    node.functionExpression.parameters.parameters.length <= 2);
diff --git a/build_modules/lib/src/module_library_builder.dart b/build_modules/lib/src/module_library_builder.dart
deleted file mode 100644
index e5defec..0000000
--- a/build_modules/lib/src/module_library_builder.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-
-import 'module_library.dart';
-
-const moduleLibraryExtension = '.module.library';
-
-/// Creates `.module.library` assets listing the dependencies and parts for a
-/// Dart library, as well as whether it is an entrypoint.
-///
-///
-/// The output format is determined by [ModuleLibrary.serialize] and can be
-/// restored by [ModuleLibrary.deserialize].
-///
-/// Non-importable Dart source files will not get a `.module.library` asset
-/// output. See [ModuleLibrary.isImportable].
-class ModuleLibraryBuilder implements Builder {
-  const ModuleLibraryBuilder();
-
-  @override
-  final buildExtensions = const {
-    '.dart': [moduleLibraryExtension]
-  };
-
-  @override
-  Future build(BuildStep buildStep) async {
-    final library = ModuleLibrary.fromSource(
-        buildStep.inputId, await buildStep.readAsString(buildStep.inputId));
-    if (!library.isImportable) return;
-    await buildStep.writeAsString(
-        buildStep.inputId.changeExtension(moduleLibraryExtension),
-        library.serialize());
-  }
-}
diff --git a/build_modules/lib/src/modules.dart b/build_modules/lib/src/modules.dart
deleted file mode 100644
index 8f3e3b0..0000000
--- a/build_modules/lib/src/modules.dart
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:build/build.dart';
-import 'package:collection/collection.dart' show UnmodifiableSetView;
-import 'package:graphs/graphs.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-import 'errors.dart';
-import 'module_builder.dart';
-import 'module_cache.dart';
-import 'platform.dart';
-
-part 'modules.g.dart';
-
-/// A collection of Dart libraries in a strongly connected component of the
-/// import graph.
-///
-/// Modules track their sources and the other modules they depend on.
-/// modules they depend on.
-/// Modules can span pub package boundaries when there are import cycles across
-/// packages.
-@JsonSerializable()
-@_AssetIdConverter()
-@_DartPlatformConverter()
-class Module {
-  /// Merge the sources and dependencies from [modules] into a single module.
-  ///
-  /// All modules must have the same [platform].
-  /// [primarySource] will be the earliest value from the combined [sources] if
-  /// they were sorted.
-  /// [isMissing] will be true if any input module is missing.
-  /// [isSupported] will be true if all input modules are supported.
-  /// [directDependencies] will be merged for all modules, but if any module
-  /// depended on a source from any other they will be filtered out.
-  static Module merge(List<Module> modules) {
-    assert(modules.isNotEmpty);
-    if (modules.length == 1) return modules.single;
-    assert(modules.every((m) => m.platform == modules.first.platform));
-
-    final allSources = HashSet.of(modules.expand((m) => m.sources));
-    final allDependencies =
-        HashSet.of(modules.expand((m) => m.directDependencies))
-          ..removeAll(allSources);
-    final primarySource =
-        allSources.reduce((a, b) => a.compareTo(b) < 0 ? a : b);
-    final isMissing = modules.any((m) => m.isMissing);
-    final isSupported = modules.every((m) => m.isSupported);
-    return Module(primarySource, allSources, allDependencies,
-        modules.first.platform, isSupported,
-        isMissing: isMissing);
-  }
-
-  /// The library which will be used to reference any library in [sources].
-  ///
-  /// The assets which are built once per module, such as DDC compiled output or
-  /// Analyzer summaries, will be named after the primary source and will
-  /// encompass everything in [sources].
-  @JsonKey(name: 'p', nullable: false)
-  final AssetId primarySource;
-
-  /// The libraries in the strongly connected import cycle with [primarySource].
-  ///
-  /// In most cases without cyclic imports this will contain only the primary
-  /// source. For libraries with an import cycle all of the libraries in the
-  /// cycle will be contained in `sources`. For example:
-  ///
-  /// ```dart
-  /// library foo;
-  ///
-  /// import 'bar.dart';
-  /// ```
-  ///
-  /// ```dart
-  /// library bar;
-  ///
-  /// import 'foo.dart';
-  /// ```
-  ///
-  /// Libraries `foo` and `bar` form an import cycle so they would be grouped in
-  /// the same module. Every Dart library will only be contained in a single
-  /// [Module].
-  @JsonKey(name: 's', nullable: false, toJson: _toJsonAssetIds)
-  final Set<AssetId> sources;
-
-  /// The [primarySource]s of the [Module]s which contain any library imported
-  /// from any of the [sources] in this module.
-  @JsonKey(name: 'd', nullable: false, toJson: _toJsonAssetIds)
-  final Set<AssetId> directDependencies;
-
-  /// Missing modules are created if a module depends on another non-existent
-  /// module.
-  ///
-  /// We want to report these errors lazily to allow for builds to succeed if it
-  /// won't actually impact any apps negatively.
-  @JsonKey(name: 'm', nullable: true, defaultValue: false)
-  final bool isMissing;
-
-  /// Whether or not this module is supported for [platform].
-  ///
-  /// Note that this only indicates support for the [sources] within this
-  /// module, and not its transitive (or direct) dependencies.
-  ///
-  /// Compilers can use this to either silently skip compilation of this module
-  /// or throw early errors or warnings.
-  ///
-  /// Modules are allowed to exist even if they aren't supported, which can help
-  /// with discovering root causes of incompatibility.
-  @JsonKey(name: 'is', nullable: false)
-  final bool isSupported;
-
-  @JsonKey(name: 'pf', nullable: false)
-  final DartPlatform platform;
-
-  Module(this.primarySource, Iterable<AssetId> sources,
-      Iterable<AssetId> directDependencies, this.platform, this.isSupported,
-      {bool isMissing})
-      : sources = UnmodifiableSetView(HashSet.of(sources)),
-        directDependencies =
-            UnmodifiableSetView(HashSet.of(directDependencies)),
-        isMissing = isMissing ?? false;
-
-  /// Generated factory constructor.
-  factory Module.fromJson(Map<String, dynamic> json) => _$ModuleFromJson(json);
-
-  Map<String, dynamic> toJson() => _$ModuleToJson(this);
-
-  /// Returns all [Module]s in the transitive dependencies of this module in
-  /// reverse dependency order.
-  ///
-  /// Throws a [MissingModulesException] if there are any missing modules. This
-  /// typically means that somebody is trying to import a non-existing file.
-  ///
-  /// If [throwIfUnsupported] is `true`, then an [UnsupportedModules]
-  /// will be thrown if there are any modules that are not supported.
-  Future<List<Module>> computeTransitiveDependencies(BuildStep buildStep,
-      {bool throwIfUnsupported = false,
-      @deprecated Set<String> skipPlatformCheckPackages = const {}}) async {
-    throwIfUnsupported ??= false;
-    skipPlatformCheckPackages ??= const {};
-    final modules = await buildStep.fetchResource(moduleCache);
-    var transitiveDeps = <AssetId, Module>{};
-    var modulesToCrawl = {primarySource};
-    var missingModuleSources = <AssetId>{};
-    var unsupportedModules = <Module>{};
-
-    while (modulesToCrawl.isNotEmpty) {
-      var next = modulesToCrawl.last;
-      modulesToCrawl.remove(next);
-      if (transitiveDeps.containsKey(next)) continue;
-      var nextModuleId = next.changeExtension(moduleExtension(platform));
-      var module = await modules.find(nextModuleId, buildStep);
-      if (module == null || module.isMissing) {
-        missingModuleSources.add(next);
-        continue;
-      }
-      if (throwIfUnsupported &&
-          !module.isSupported &&
-          !skipPlatformCheckPackages.contains(module.primarySource.package)) {
-        unsupportedModules.add(module);
-      }
-      // Don't include the root module in the transitive deps.
-      if (next != primarySource) transitiveDeps[next] = module;
-      modulesToCrawl.addAll(module.directDependencies);
-    }
-
-    if (missingModuleSources.isNotEmpty) {
-      throw await MissingModulesException.create(missingModuleSources,
-          transitiveDeps.values.toList()..add(this), buildStep);
-    }
-    if (throwIfUnsupported && unsupportedModules.isNotEmpty) {
-      throw UnsupportedModules(unsupportedModules);
-    }
-    var orderedModules = stronglyConnectedComponents<Module>(
-        transitiveDeps.values,
-        (m) => m.directDependencies.map((s) => transitiveDeps[s]),
-        equals: (a, b) => a.primarySource == b.primarySource,
-        hashCode: (m) => m.primarySource.hashCode);
-    return orderedModules.map((c) => c.single).toList();
-  }
-}
-
-class _AssetIdConverter implements JsonConverter<AssetId, List> {
-  const _AssetIdConverter();
-
-  @override
-  AssetId fromJson(List json) => AssetId.deserialize(json);
-
-  @override
-  List toJson(AssetId object) => object.serialize() as List;
-}
-
-class _DartPlatformConverter implements JsonConverter<DartPlatform, String> {
-  const _DartPlatformConverter();
-
-  @override
-  DartPlatform fromJson(String json) => DartPlatform.byName(json);
-
-  @override
-  String toJson(DartPlatform object) => object.name;
-}
-
-/// Ensure sets of asset IDs are sorted before writing them for a consistent
-/// output.
-List<List> _toJsonAssetIds(Set<AssetId> ids) =>
-    (ids.toList()..sort()).map((i) => i.serialize() as List).toList();
diff --git a/build_modules/lib/src/modules.g.dart b/build_modules/lib/src/modules.g.dart
deleted file mode 100644
index 1e7a80d..0000000
--- a/build_modules/lib/src/modules.g.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'modules.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-Module _$ModuleFromJson(Map<String, dynamic> json) {
-  return Module(
-    const _AssetIdConverter().fromJson(json['p'] as List),
-    (json['s'] as List)
-        .map((e) => const _AssetIdConverter().fromJson(e as List)),
-    (json['d'] as List)
-        .map((e) => const _AssetIdConverter().fromJson(e as List)),
-    const _DartPlatformConverter().fromJson(json['pf'] as String),
-    json['is'] as bool,
-    isMissing: json['m'] as bool ?? false,
-  );
-}
-
-Map<String, dynamic> _$ModuleToJson(Module instance) => <String, dynamic>{
-      'p': const _AssetIdConverter().toJson(instance.primarySource),
-      's': _toJsonAssetIds(instance.sources),
-      'd': _toJsonAssetIds(instance.directDependencies),
-      'm': instance.isMissing,
-      'is': instance.isSupported,
-      'pf': const _DartPlatformConverter().toJson(instance.platform),
-    };
diff --git a/build_modules/lib/src/platform.dart b/build_modules/lib/src/platform.dart
deleted file mode 100644
index c74e47a..0000000
--- a/build_modules/lib/src/platform.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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.
-
-/// A supported "platform" for compilation of Dart libraries.
-///
-/// Each "platform" has its own compilation pipeline and builders, and could
-/// differ from other platforms in many ways:
-///
-/// - The core libs that are supported
-/// - The implementations of the core libs
-/// - The compilation steps that are required (frontends or backends could be
-///   different).
-///
-/// Typically these should correspond to `libraries.json` files in the SDK.
-///
-/// New platforms should be created with [register], and can later be
-/// fetched by name using the [DartPlatform.byName] static method.
-class DartPlatform {
-  /// A list of all registered platforms by name, populated by
-  /// [register].
-  static final _platformsByName = <String, DartPlatform>{};
-
-  final List<String> _supportedLibraries;
-
-  final String name;
-
-  /// Returns a [DartPlatform] instance by name.
-  ///
-  /// Throws an [UnrecognizedDartPlatform] if [name] has not been
-  /// registered with [DartPlatform.register].
-  static DartPlatform byName(String name) =>
-      _platformsByName[name] ?? (throw UnrecognizedDartPlatform(name));
-
-  /// Registers a new [DartPlatform].
-  ///
-  /// Throws a [DartPlatformAlreadyRegistered] if [name] has already
-  /// been registered by somebody else.
-  static DartPlatform register(String name, List<String> supportedLibraries) {
-    if (_platformsByName.containsKey(name)) {
-      throw DartPlatformAlreadyRegistered(name);
-    }
-
-    return _platformsByName[name] =
-        DartPlatform._(name, List.unmodifiable(supportedLibraries));
-  }
-
-  const DartPlatform._(this.name, this._supportedLibraries);
-
-  /// Returns whether or not [library] is supported on this platform.
-  ///
-  /// The [library] is path portion of a `dart:` import (should not include the
-  /// scheme).
-  bool supportsLibrary(String library) => _supportedLibraries.contains(library);
-
-  @override
-  int get hashCode => name.hashCode;
-
-  @override
-  bool operator ==(other) => other is DartPlatform && other.name == name;
-}
-
-class DartPlatformAlreadyRegistered implements Exception {
-  final String name;
-
-  const DartPlatformAlreadyRegistered(this.name);
-
-  @override
-  String toString() => 'The platform `$name`, has already been registered.';
-}
-
-class UnrecognizedDartPlatform implements Exception {
-  final String name;
-
-  const UnrecognizedDartPlatform(this.name);
-
-  @override
-  String toString() => 'Unrecognized platform `$name`, it must be registered '
-      'first using `DartPlatform.register`';
-}
diff --git a/build_modules/lib/src/scratch_space.dart b/build_modules/lib/src/scratch_space.dart
deleted file mode 100644
index 6149341..0000000
--- a/build_modules/lib/src/scratch_space.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-import 'dart:math' as math;
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:scratch_space/scratch_space.dart';
-
-import 'workers.dart';
-
-final _logger = Logger('BuildModules');
-
-/// A shared [ScratchSpace] for ddc and analyzer workers that persists
-/// throughout builds.
-final scratchSpace = ScratchSpace();
-
-/// A shared [Resource] for a [ScratchSpace], which cleans up the contents of
-/// the [ScratchSpace] in dispose, but doesn't delete it entirely.
-final scratchSpaceResource = Resource<ScratchSpace>(() {
-  if (!scratchSpace.exists) {
-    scratchSpace.tempDir.createSync(recursive: true);
-    scratchSpace.exists = true;
-  }
-  return scratchSpace;
-}, beforeExit: () async {
-  // The workers are running inside the scratch space, so wait for them to
-  // shut down before deleting it.
-  await dartdevkWorkersAreDone;
-  await frontendWorkersAreDone;
-  await dart2jsWorkersAreDone;
-  // Attempt to clean up the scratch space. Even after waiting for the workers
-  // to shut down we might get file system exceptions on windows for an
-  // arbitrary amount of time, so do retries with an exponential backoff.
-  var numTries = 0;
-  while (true) {
-    numTries++;
-    if (numTries > 3) {
-      _logger
-          .warning('Failed to clean up temp dir ${scratchSpace.tempDir.path}.');
-      return;
-    }
-    try {
-      // TODO(https://github.com/dart-lang/build/issues/656):  The scratch
-      // space throws on `delete` if it thinks it was already deleted.
-      // Manually clean up in this case.
-      if (scratchSpace.exists) {
-        await scratchSpace.delete();
-      } else {
-        await scratchSpace.tempDir.delete(recursive: true);
-      }
-      return;
-    } on FileSystemException {
-      var delayMs = math.pow(10, numTries).floor();
-      _logger.info('Failed to delete temp dir ${scratchSpace.tempDir.path}, '
-          'retrying in ${delayMs}ms');
-      await Future.delayed(Duration(milliseconds: delayMs));
-    }
-  }
-});
diff --git a/build_modules/lib/src/workers.dart b/build_modules/lib/src/workers.dart
deleted file mode 100644
index c7fc0b2..0000000
--- a/build_modules/lib/src/workers.dart
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math' show min;
-
-import 'package:bazel_worker/driver.dart';
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-import 'package:pedantic/pedantic.dart';
-
-import 'scratch_space.dart';
-
-final sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));
-
-// If no terminal is attached, prevent a new one from launching.
-final _processMode = stdin.hasTerminal
-    ? ProcessStartMode.normal
-    : ProcessStartMode.detachedWithStdio;
-
-/// Completes once the dartdevk workers have been shut down.
-Future<void> get dartdevkWorkersAreDone =>
-    _dartdevkWorkersAreDoneCompleter?.future ?? Future.value();
-Completer<void> _dartdevkWorkersAreDoneCompleter;
-
-/// Completes once the dart2js workers have been shut down.
-Future<void> get dart2jsWorkersAreDone =>
-    _dart2jsWorkersAreDoneCompleter?.future ?? Future.value();
-Completer<void> _dart2jsWorkersAreDoneCompleter;
-
-/// Completes once the common frontend workers have been shut down.
-Future<void> get frontendWorkersAreDone =>
-    _frontendWorkersAreDoneCompleter?.future ?? Future.value();
-Completer<void> _frontendWorkersAreDoneCompleter;
-
-final int _defaultMaxWorkers = min((Platform.numberOfProcessors / 2).ceil(), 4);
-
-const _maxWorkersEnvVar = 'BUILD_MAX_WORKERS_PER_TASK';
-
-final int _maxWorkersPerTask = () {
-  var toParse =
-      Platform.environment[_maxWorkersEnvVar] ?? '$_defaultMaxWorkers';
-  var parsed = int.tryParse(toParse);
-  if (parsed == null) {
-    log.warning('Invalid value for $_maxWorkersEnvVar environment variable, '
-        'expected an int but got `$toParse`. Falling back to default value '
-        'of $_defaultMaxWorkers.');
-    return _defaultMaxWorkers;
-  }
-  return parsed;
-}();
-
-/// Manages a shared set of persistent dartdevk workers.
-BazelWorkerDriver get _dartdevkDriver {
-  _dartdevkWorkersAreDoneCompleter ??= Completer<void>();
-  return __dartdevkDriver ??= BazelWorkerDriver(
-      () => Process.start(
-          p.join(sdkDir, 'bin', 'dart'),
-          [
-            p.join(sdkDir, 'bin', 'snapshots', 'dartdevc.dart.snapshot'),
-            '--kernel',
-            '--persistent_worker'
-          ],
-          mode: _processMode,
-          workingDirectory: scratchSpace.tempDir.path),
-      maxWorkers: _maxWorkersPerTask);
-}
-
-BazelWorkerDriver __dartdevkDriver;
-
-/// Resource for fetching the current [BazelWorkerDriver] for dartdevk.
-final dartdevkDriverResource =
-    Resource<BazelWorkerDriver>(() => _dartdevkDriver, beforeExit: () async {
-  await _dartdevkDriver?.terminateWorkers();
-  _dartdevkWorkersAreDoneCompleter.complete();
-  _dartdevkWorkersAreDoneCompleter = null;
-  __dartdevkDriver = null;
-});
-
-/// Manages a shared set of persistent common frontend workers.
-BazelWorkerDriver get _frontendDriver {
-  _frontendWorkersAreDoneCompleter ??= Completer<void>();
-  return __frontendDriver ??= BazelWorkerDriver(
-      () => Process.start(
-          p.join(sdkDir, 'bin', 'dart'),
-          [
-            p.join(sdkDir, 'bin', 'snapshots', 'kernel_worker.dart.snapshot'),
-            '--persistent_worker'
-          ],
-          mode: _processMode,
-          workingDirectory: scratchSpace.tempDir.path),
-      maxWorkers: _maxWorkersPerTask);
-}
-
-BazelWorkerDriver __frontendDriver;
-
-/// Resource for fetching the current [BazelWorkerDriver] for common frontend.
-final frontendDriverResource =
-    Resource<BazelWorkerDriver>(() => _frontendDriver, beforeExit: () async {
-  await _frontendDriver?.terminateWorkers();
-  _frontendWorkersAreDoneCompleter.complete();
-  _frontendWorkersAreDoneCompleter = null;
-  __frontendDriver = null;
-});
-
-const _dart2jsVmArgsEnvVar = 'BUILD_DART2JS_VM_ARGS';
-final _dart2jsVmArgs = () {
-  var env = Platform.environment[_dart2jsVmArgsEnvVar];
-  return env?.split(' ') ?? <String>[];
-}();
-
-/// Manages a shared set of persistent dart2js workers.
-Dart2JsBatchWorkerPool get _dart2jsWorkerPool {
-  _dart2jsWorkersAreDoneCompleter ??= Completer<void>();
-  var librariesSpec = p.joinAll([sdkDir, 'lib', 'libraries.json']);
-  return __dart2jsWorkerPool ??= Dart2JsBatchWorkerPool(() => Process.start(
-      p.join(sdkDir, 'bin', 'dart'),
-      [
-        ..._dart2jsVmArgs,
-        p.join(sdkDir, 'bin', 'snapshots', 'dart2js.dart.snapshot'),
-        '--libraries-spec=$librariesSpec',
-        '--batch',
-      ],
-      mode: _processMode,
-      workingDirectory: scratchSpace.tempDir.path));
-}
-
-Dart2JsBatchWorkerPool __dart2jsWorkerPool;
-
-/// Resource for fetching the current [Dart2JsBatchWorkerPool] for dart2js.
-final dart2JsWorkerResource = Resource<Dart2JsBatchWorkerPool>(
-    () => _dart2jsWorkerPool, beforeExit: () async {
-  await _dart2jsWorkerPool.terminateWorkers();
-  _dart2jsWorkersAreDoneCompleter.complete();
-  _dart2jsWorkersAreDoneCompleter = null;
-});
-
-/// Manages a pool of persistent [_Dart2JsWorker]s running in batch mode and
-/// schedules jobs among them.
-class Dart2JsBatchWorkerPool {
-  final Future<Process> Function() _spawnWorker;
-
-  final _workQueue = Queue<_Dart2JsJob>();
-
-  bool _queueIsActive = false;
-
-  final _availableWorkers = Queue<_Dart2JsWorker>();
-
-  final _allWorkers = <_Dart2JsWorker>[];
-
-  Dart2JsBatchWorkerPool(this._spawnWorker);
-
-  Future<Dart2JsResult> compile(List<String> args) async {
-    var job = _Dart2JsJob(args);
-    _workQueue.add(job);
-    if (!_queueIsActive) _startWorkQueue();
-    return job.result;
-  }
-
-  void _startWorkQueue() {
-    assert(!_queueIsActive);
-    _queueIsActive = true;
-    () async {
-      while (_workQueue.isNotEmpty) {
-        _Dart2JsWorker worker;
-        if (_availableWorkers.isEmpty &&
-            _allWorkers.length < _maxWorkersPerTask) {
-          worker = _Dart2JsWorker(_spawnWorker);
-          _allWorkers.add(worker);
-        }
-
-        _Dart2JsWorker nextWorker() => _availableWorkers.isNotEmpty
-            ? _availableWorkers.removeFirst()
-            : null;
-
-        worker ??= nextWorker();
-        while (worker == null) {
-          // TODO: something smarter here? in practice this seems to work
-          // reasonably well though and simplifies things a lot ¯\_(ツ)_/¯.
-          await Future.delayed(Duration(seconds: 1));
-          worker = nextWorker();
-        }
-        unawaited(worker
-            .doJob(_workQueue.removeFirst())
-            .whenComplete(() => _availableWorkers.add(worker)));
-      }
-      _queueIsActive = false;
-    }();
-  }
-
-  Future<void> terminateWorkers() async {
-    var allWorkers = _allWorkers.toList();
-    _allWorkers.clear();
-    _availableWorkers.clear();
-    await Future.wait(allWorkers.map((w) => w.terminate()));
-  }
-}
-
-/// A single dart2js worker process running in batch mode.
-///
-/// This may actually spawn multiple processes over time, if a running worker
-/// dies or it decides that it should be restarted for some reason.
-class _Dart2JsWorker {
-  final Future<Process> Function() _spawnWorker;
-
-  int _jobsSinceLastRestartCount = 0;
-  static const int _jobsBeforeRestartMax = 5;
-  static const int _retryCountMax = 2;
-
-  Stream<String> __workerStderrLines;
-  Stream<String> get _workerStderrLines {
-    assert(__worker != null);
-    return __workerStderrLines ??= __worker.stderr
-        .transform(utf8.decoder)
-        .transform(const LineSplitter())
-        .asBroadcastStream();
-  }
-
-  Stream<String> __workerStdoutLines;
-  Stream<String> get _workerStdoutLines {
-    assert(__worker != null);
-    return __workerStdoutLines ??= __worker.stdout
-        .transform(utf8.decoder)
-        .transform(const LineSplitter())
-        .asBroadcastStream();
-  }
-
-  Process __worker;
-  Future<Process> _spawningWorker;
-  Future<Process> get _worker {
-    if (__worker != null) return Future.value(__worker);
-    return _spawningWorker ??= () async {
-      if (__worker == null) {
-        _jobsSinceLastRestartCount = 0;
-        __worker ??= await _spawnWorker();
-        _spawningWorker = null;
-        // exitCode can be null: https://github.com/dart-lang/sdk/issues/35874
-        unawaited(__worker.exitCode?.then((_) {
-          __worker = null;
-          __workerStdoutLines = null;
-          __workerStderrLines = null;
-          _currentJobResult
-              ?.completeError('Dart2js exited with an unknown error');
-        }));
-      }
-      return __worker;
-    }();
-  }
-
-  Completer<Dart2JsResult> _currentJobResult;
-
-  _Dart2JsWorker(this._spawnWorker);
-
-  /// Performs [job], gracefully handling worker failures by retrying
-  /// [_retryCountMax] times and restarting the worker between jobs based on
-  /// [_jobsBeforeRestartMax] to limit memory consumption.
-  ///
-  /// Only one job may be performed at a time.
-  Future<void> doJob(_Dart2JsJob job) async {
-    assert(_currentJobResult == null);
-    var tryCount = 0;
-    var succeeded = false;
-    while (tryCount < _retryCountMax && !succeeded) {
-      tryCount++;
-      _jobsSinceLastRestartCount++;
-      var worker = await _worker;
-      var output = StringBuffer();
-      _currentJobResult = Completer<Dart2JsResult>();
-      var sawError = false;
-      var stderrListener = _workerStderrLines.listen((line) {
-        if (line == '>>> EOF STDERR') {
-          _currentJobResult?.complete(
-              Dart2JsResult(!sawError, 'Dart2Js finished with:\n\n$output'));
-        }
-        if (!line.startsWith('>>> ')) {
-          output.writeln(line);
-        }
-      });
-      var stdoutListener = _workerStdoutLines.listen((line) {
-        if (line.contains('>>> TEST FAIL')) {
-          sawError = true;
-        }
-        if (!line.startsWith('>>> ')) {
-          output.writeln(line);
-        }
-      });
-
-      log.info('Running dart2js with ${job.args.join(' ')}\n');
-      worker.stdin.writeln(job.args.join(' '));
-
-      Dart2JsResult result;
-      try {
-        result = await _currentJobResult.future;
-        job.resultCompleter.complete(result);
-        succeeded = true;
-      } catch (e) {
-        log.warning('Dart2Js failure: $e');
-        succeeded = false;
-        if (tryCount >= _retryCountMax) {
-          job.resultCompleter.complete(_currentJobResult.future);
-        }
-      } finally {
-        _currentJobResult = null;
-        // TODO: Remove this hack once dart-lang/sdk#33708 is resolved.
-        if (_jobsSinceLastRestartCount >= _jobsBeforeRestartMax) {
-          await terminate();
-        }
-        await stderrListener.cancel();
-        await stdoutListener.cancel();
-      }
-    }
-  }
-
-  Future<void> terminate() async {
-    var worker = __worker ?? await _spawningWorker;
-    __worker = null;
-    __workerStdoutLines = null;
-    __workerStderrLines = null;
-    if (worker != null) {
-      worker.kill();
-      await worker.stdin.close();
-    }
-    await worker?.exitCode;
-  }
-}
-
-/// A single dart2js job, consisting of [args] and a [result].
-class _Dart2JsJob {
-  final List<String> args;
-
-  final resultCompleter = Completer<Dart2JsResult>();
-  Future<Dart2JsResult> get result => resultCompleter.future;
-
-  _Dart2JsJob(this.args);
-}
-
-/// The result of a [_Dart2JsJob]
-class Dart2JsResult {
-  final bool succeeded;
-  final String output;
-
-  Dart2JsResult(this.succeeded, this.output);
-}
diff --git a/build_modules/mono_pkg.yaml b/build_modules/mono_pkg.yaml
deleted file mode 100644
index 3d1ec9e..0000000
--- a/build_modules/mono_pkg.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-        - dartfmt: sdk
-        - dartanalyzer: --fatal-infos --fatal-warnings .
-    - dartanalyzer: --fatal-warnings .
-      dart:
-        - 2.5.0
-  - unit_test:
-    # Run the script directly - running from snapshot has issues for packages
-    # that are depended on by build_runner itself.
-    - command: dart $(pub run build_runner generate-build-script) test --delete-conflicting-outputs -- -P presubmit
-      os:
-        - linux
-        - windows
-
-cache:
-  directories:
-    - .dart_tool/build
diff --git a/build_modules/pubspec.yaml b/build_modules/pubspec.yaml
deleted file mode 100644
index 4161b17..0000000
--- a/build_modules/pubspec.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: build_modules
-version: 2.8.0
-description: Builders for Dart modules
-homepage: https://github.com/dart-lang/build/tree/master/build_modules
-
-environment:
-  sdk: ">=2.5.0 <3.0.0"
-
-dependencies:
-  analyzer: ">0.35.0 <0.40.0"
-  async: ^2.0.0
-  bazel_worker: ^0.1.20
-  build: ">=1.2.0 <2.0.0"
-  build_config: ">=0.3.0 <0.5.0"
-  collection: ^1.0.0
-  crypto: ^2.0.0
-  glob: ^1.0.0
-  graphs: ^0.2.0
-  json_annotation: ">=1.2.0 <4.0.0"
-  logging: ^0.11.2
-  meta: ^1.1.0
-  path: ^1.4.2
-  pedantic: ^1.0.0
-  scratch_space: ^0.0.4
-
-dev_dependencies:
-  build_runner: ^1.0.0
-  build_test: ^0.10.9
-  build_vm_compilers: ^1.0.0
-  test: ^1.6.0
-  a:
-    path: test/fixtures/a
-  b:
-    path: test/fixtures/b
-
-dependency_overrides:
-  build_vm_compilers:
-    path: ../build_vm_compilers
diff --git a/build_resolvers/BUILD.gn b/build_resolvers/BUILD.gn
deleted file mode 100644
index 5abdb1a..0000000
--- a/build_resolvers/BUILD.gn
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file is generated by importer.py for build_resolvers-1.3.3
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_resolvers") {
-  package_name = "build_resolvers"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/logging",
-    "//third_party/dart-pkg/pub/graphs",
-    "//third_party/dart-pkg/pub/crypto",
-    "//third_party/dart-pkg/pub/analyzer",
-    "//third_party/dart-pkg/pub/yaml",
-    "//third_party/dart-pkg/pub/build",
-    "//third_party/dart-pkg/pub/package_resolver",
-    "//third_party/dart-pkg/pub/path",
-  ]
-}
diff --git a/build_resolvers/CHANGELOG.md b/build_resolvers/CHANGELOG.md
deleted file mode 100644
index cc491dc..0000000
--- a/build_resolvers/CHANGELOG.md
+++ /dev/null
@@ -1,190 +0,0 @@
-## 1.3.3
-
-- Fix an issue where non-existing Dart assets weren't visible to the analyzer, even
-  when they are created later.
-
-## 1.3.2
-
-- Improve detection of the flutter SDK for older flutter versions.  
-
-## 1.3.1
-
-- Add an exception on trying to resolve an `AssetId` that is not a Dart
-  library with `libraryFor` to fit the contract expressed by the doc comment on
-  `Resolver`.
-
-## 1.3.0
-
-### New feature
-
-You can now resolve additional libraries other than those imported by the
-primary entrypoint.
-
-  - This is supported through the `isLibrary` and `libraryFor` methods on
-    `Resolver`, which will now resolve the provided asset if it is not already
-    resolved.
-  - **Note**: Doing this may affect the result of subsequent calls to
-    `resolver.libraries` and `resolver.findLibraryByName` if new libraries are
-    discovered.
-
-**Note**: If using `build_runner` then this will also require you to upgrade
-to version `4.2.0` of `build_runner_core` .
-
-### Other
-
-- Changed a `hide` declaration to a `show` declaration to support a
-`package:analyzer` change.
-
-## 1.2.2
-
-- Update to `package:analyzer` version `0.39.0`.
-
-## 1.2.1
-
-Check the build_resolvers version as a part of sdk summary invalidation.
-
-## 1.2.0
-
-Add flutters embedded sdk to the summary if available. This has the effect of
-making `dart:ui` and any future libraries available if using the flutter sdk
-instead of the dart sdk.
-
-## 1.1.1
-
-### Bug Fix
-
-Check the analyzer path before reading cached summaries in addition to the
-SDK version.
-
-## 1.1.0
-
-### Bug Fix: #38499
-
-Update the `AnalysisResolvers` class to no longer use the SDK summary that is
-shipped with the SDK by default. This is not guaranteed compatible with
-analyzer versions shipped on pub and should not be used by any non-sdk code.
-
-In order to fix this the `AnalysisResolvers` class now takes an optional method
-that returns the path to an arbitrary SDK summary. By default it will lazily
-generate a summary under `.dart_tool/build_resolvers` which is invalidated
-based on the `Platform.version` from `dart:io`.
-
-## 1.0.8
-
-- Allow `build` version 1.2.x.
-
-## 1.0.7
-
-- Allow analyzer version 0.38.0.
-
-## 1.0.6
-
-- Allow analyzer version 0.37.0.
-
-## 1.0.5
-
-- Fix a race condition where some assets may be resolved with missing
-  dependencies. This was likely to have only manifested in tests using
-  `resolveSource`.
-
-## 1.0.4
-
-- Increase lower bound sdk constraint to 2.1.0.
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-
-## 1.0.3
-
-- Fixes a bug where transitive `dart-ext:` imports would cause the resolver
-  to fail. These uris will now be ignored.
-
-## 1.0.2
-
-- Ensure that `BuildAssetUriResolver.restoreAbsolute` never returns null.
-  - Fixes a crash when a resolver is requested but not all transitive sources
-    are available yet.
-
-## 1.0.1
-
-- Fix a bug causing crashes on windows.
-
-## 1.0.0
-
-- Migrate to `AnalysisDriver`. There are behavior changes which may be breaking.
-  The `LibraryElement` instances returned by the resolver will now:
-  - Have non-working `context` fields.
-  - Have no source offsets for annotations or their errors.
-  - Have working `session` fields.
-  - Have `Source` instances with different URIs than before.
-  - Not include missing libraries in the `importedLibraries` getter. You can
-    instead use the `imports` getter to see all the imports.
-
-## 0.2.3
-
-- Update to `build` `1.1.0` and add `assetIdForElement`.
-
-## 0.2.2+7
-
-- Updated _AssetUriResolver to prepare for a future release of the analyzer.
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 0.2.2+6
-
-- Increased the upper bound for `package:analyzer` to `<0.34.0`.
-
-## 0.2.2+5
-
-- Increased the upper bound for the `build` to `<1.1.0`.
-
-## 0.2.2+4
-
-- Removed dependency on cli_util.
-- Increased the upper bound for the `build` to `<0.12.9`.
-
-## 0.2.2+3
-
-- Don't log a severe message when a URI cannot be resolved. Just return `null`.
-
-## 0.2.2+2
-
-- Use sdk summaries for the analysis context, which makes getting the initial
-  resolver faster (reapplied).
-
-## 0.2.2+1
-
-- Restore `new` keyword for a working release on Dart 1 VM.
-
-## 0.2.2
-
-- Use sdk summaries for the analysis context, which makes getting the initial
-  resolver faster.
-- Release broken on Dart 1 VM.
-
-## 0.2.1+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.2.1
-
-- Allow passing in custom `AnalysisOptions`.
-
-## 0.2.0+2
-
-- Support `package:analyzer` `0.32.0`.
-
-## 0.2.0+1
-
-- Switch to `firstWhere(orElse)` for compatibility with the SDK dev.45
-
-## 0.2.0
-
-- Removed locking between uses of the Resolver and added a mandatory `reset`
-  call to indicate that a complete build is finished.
-
-## 0.1.1
-
-- Support the latest `analyzer` package.
-
-## 0.1.0
-
-- Initial release as a migration from `code_transformers` with a near-identical
-  implementation.
diff --git a/build_resolvers/LICENSE b/build_resolvers/LICENSE
deleted file mode 100644
index c4dc9ba..0000000
--- a/build_resolvers/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_resolvers/README.md b/build_resolvers/README.md
deleted file mode 100644
index 9aa64bf..0000000
--- a/build_resolvers/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Provides an in-memory `Resolvers` implementation for use with `package:build`.
-
-This implementation does a monolithic analysis from source, with fine grained
-invalidation, which works well when it can be shared across multiple build steps
-in the same process. It is not however suitable for use in more general build
-systems, which should build up their analysis context using analyzer summaries.
diff --git a/build_resolvers/lib/build_resolvers.dart b/build_resolvers/lib/build_resolvers.dart
deleted file mode 100644
index 9a72353..0000000
--- a/build_resolvers/lib/build_resolvers.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-export 'src/resolver.dart' show AnalyzerResolvers;
diff --git a/build_resolvers/lib/src/analysis_driver.dart b/build_resolvers/lib/src/analysis_driver.dart
deleted file mode 100644
index acfbd8d..0000000
--- a/build_resolvers/lib/src/analysis_driver.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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/dart/analysis/byte_store.dart'
-    show MemoryByteStore;
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart'
-    show PerformanceLog;
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisOptionsImpl, AnalysisOptions;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
-
-import 'build_asset_uri_resolver.dart';
-
-/// Builds an [AnalysisDriver] backed by a summary SDK and package summary
-/// files.
-///
-/// Any code which is not covered by the summaries must be resolvable through
-/// [buildAssetUriResolver].
-AnalysisDriver analysisDriver(BuildAssetUriResolver buildAssetUriResolver,
-    AnalysisOptions analysisOptions, String sdkSummaryPath) {
-  var sdk = SummaryBasedDartSdk(sdkSummaryPath, true);
-  var sdkResolver = DartUriResolver(sdk);
-
-  var resolvers = [sdkResolver, buildAssetUriResolver];
-  var sourceFactory = SourceFactory(resolvers);
-
-  var dataStore = SummaryDataStore([sdkSummaryPath]);
-
-  var logger = PerformanceLog(null);
-  var scheduler = AnalysisDriverScheduler(logger);
-  var driver = AnalysisDriver(
-    scheduler,
-    logger,
-    buildAssetUriResolver.resourceProvider,
-    MemoryByteStore(),
-    FileContentOverlay(),
-    null,
-    sourceFactory,
-    (analysisOptions as AnalysisOptionsImpl) ?? AnalysisOptionsImpl(),
-    externalSummaries: dataStore,
-  );
-
-  scheduler.start();
-  return driver;
-}
diff --git a/build_resolvers/lib/src/build_asset_uri_resolver.dart b/build_resolvers/lib/src/build_asset_uri_resolver.dart
deleted file mode 100644
index 35b34a5..0000000
--- a/build_resolvers/lib/src/build_asset_uri_resolver.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// 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:collection';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart' show parseDirectives;
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:build/build.dart' show AssetId, BuildStep;
-import 'package:crypto/crypto.dart';
-import 'package:graphs/graphs.dart';
-import 'package:path/path.dart' as p;
-
-const _ignoredSchemes = ['dart', 'dart-ext'];
-
-class BuildAssetUriResolver extends UriResolver {
-  /// A cache of the directives for each Dart library.
-  ///
-  /// This is stored across builds and is only invalidated if we read a file and
-  /// see that it's content is different from what it was last time it was read.
-  final _cachedAssetDependencies = <AssetId, Set<AssetId>>{};
-
-  /// A cache of the digest for each Dart asset.
-  ///
-  /// This is stored across builds and used to invalidate the values in
-  /// [_cachedAssetDependencies] only when the actual content of the library
-  /// changed.
-  final _cachedAssetDigests = <AssetId, Digest>{};
-
-  final resourceProvider = MemoryResourceProvider(context: p.posix);
-
-  /// The assets which are known to be readable at some point during the current
-  /// build.
-  ///
-  /// When actions can run out of order an asset can move from being readable
-  /// (in the later phase) to being unreadable (in the earlier phase which ran
-  /// later). If this happens we don't want to hide the asset from the analyzer.
-  final globallySeenAssets = HashSet<AssetId>();
-
-  /// The assets which have been resolved from a [BuildStep], either as an
-  /// input, subsequent calls to a resolver, or a transitive import thereof.
-  final _buildStepAssets = <BuildStep, HashSet<AssetId>>{};
-
-  /// Crawl the transitive imports from [entryPoints] and ensure that the
-  /// content of each asset is updated in [resourceProvider] and [driver].
-  Future<void> performResolve(BuildStep buildStep, List<AssetId> entryPoints,
-      AnalysisDriver driver) async {
-    final seenInBuildStep =
-        _buildStepAssets.putIfAbsent(buildStep, () => HashSet());
-    bool notCrawled(AssetId asset) => !seenInBuildStep.contains(asset);
-
-    final changedPaths = await crawlAsync<AssetId, _AssetState>(
-            entryPoints.where(notCrawled), (id) async {
-      final path = assetPath(id);
-      if (!await buildStep.canRead(id)) {
-        if (globallySeenAssets.contains(id)) {
-          // ignore from this graph, some later build step may still be using it
-          // so it shouldn't be removed from [resourceProvider], but we also
-          // don't care about it's transitive imports.
-          return null;
-        }
-        _cachedAssetDependencies.remove(id);
-        _cachedAssetDigests.remove(id);
-        if (resourceProvider.getFile(path).exists) {
-          resourceProvider.deleteFile(path);
-        }
-        return _AssetState.removed(path);
-      }
-      globallySeenAssets.add(id);
-      seenInBuildStep.add(id);
-      final digest = await buildStep.digest(id);
-      if (_cachedAssetDigests[id] == digest) {
-        return _AssetState.unchanged(path, _cachedAssetDependencies[id]);
-      } else {
-        final isChange = _cachedAssetDigests.containsKey(id);
-        final content = await buildStep.readAsString(id);
-        _cachedAssetDigests[id] = digest;
-        final dependencies =
-            _cachedAssetDependencies[id] = _parseDirectives(content, id);
-        if (isChange) {
-          resourceProvider.updateFile(path, content);
-          return _AssetState.changed(path, dependencies);
-        } else {
-          resourceProvider.newFile(path, content);
-          return _AssetState.newAsset(path, dependencies);
-        }
-      }
-    }, (id, state) => state.directives.where(notCrawled))
-        .where((state) => state.isAssetUpdate)
-        .map((state) => state.path)
-        .toList();
-    changedPaths.forEach(driver.changeFile);
-  }
-
-  /// Attempts to parse [uri] into an [AssetId].
-  ///
-  /// Handles 'package:' or 'asset:' URIs, as well as 'file:' URIs that have the
-  /// same pattern used by [assetPath].
-  ///
-  /// Returns null if the Uri cannot be parsed.
-  AssetId parseAsset(Uri uri) {
-    if (_ignoredSchemes.any(uri.isScheme)) return null;
-    if (uri.isScheme('package') || uri.isScheme('asset')) {
-      return AssetId.resolve('$uri');
-    }
-    if (uri.isScheme('file')) {
-      final parts = p.split(uri.path);
-      return AssetId(parts[1], p.posix.joinAll(parts.skip(2)));
-    }
-    return null;
-  }
-
-  /// Attempts to parse [uri] into an [AssetId] and returns it if it is cached.
-  ///
-  /// Handles 'package:' or 'asset:' URIs, as well as 'file:' URIs that have the
-  /// same pattern used by [assetPath].
-  ///
-  /// Returns null if the Uri cannot be parsed or is not cached.
-  AssetId lookupCachedAsset(Uri uri) {
-    final assetId = parseAsset(uri);
-    if (assetId == null || !_cachedAssetDigests.containsKey(assetId)) {
-      return null;
-    }
-
-    return assetId;
-  }
-
-  void notifyComplete(BuildStep step) {
-    _buildStepAssets.remove(step);
-  }
-
-  /// Clear cached information specific to an individual build.
-  void reset() {
-    assert(_buildStepAssets.isEmpty,
-        'Reset was called before all build steps completed');
-    globallySeenAssets.clear();
-  }
-
-  @override
-  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
-    final assetId = parseAsset(uri);
-    if (assetId == null) return null;
-
-    return resourceProvider
-        .getFile(assetPath(assetId))
-        .createSource(assetId.uri);
-  }
-
-  @override
-  Uri restoreAbsolute(Source source) =>
-      lookupCachedAsset(source.uri)?.uri ?? source.uri;
-}
-
-String assetPath(AssetId assetId) =>
-    p.posix.join('/${assetId.package}', assetId.path);
-
-/// Returns all the directives from a Dart library that can be resolved to an
-/// [AssetId].
-Set<AssetId> _parseDirectives(String content, AssetId from) =>
-    // ignore: deprecated_member_use
-    HashSet.of(parseDirectives(content, suppressErrors: true)
-        .directives
-        .whereType<UriBasedDirective>()
-        .where((directive) {
-          var uri = Uri.parse(directive.uri.stringValue);
-          return !_ignoredSchemes.any(uri.isScheme);
-        })
-        .map((d) => AssetId.resolve(d.uri.stringValue, from: from))
-        .where((id) => id != null));
-
-class _AssetState {
-  final String path;
-  final bool isAssetUpdate;
-  final Iterable<AssetId> directives;
-
-  _AssetState.removed(this.path)
-      : isAssetUpdate = false,
-        directives = const [];
-  _AssetState.changed(this.path, this.directives) : isAssetUpdate = true;
-  _AssetState.unchanged(this.path, this.directives) : isAssetUpdate = false;
-  _AssetState.newAsset(this.path, this.directives) : isAssetUpdate = true;
-}
diff --git a/build_resolvers/lib/src/human_readable_duration.dart b/build_resolvers/lib/src/human_readable_duration.dart
deleted file mode 100644
index 736e915..0000000
--- a/build_resolvers/lib/src/human_readable_duration.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Returns a human readable string for a duration.
-///
-/// Handles durations that span up to hours - this will not be a good fit for
-/// durations that are longer than days.
-///
-/// Always attempts 2 'levels' of precision. Will show hours/minutes,
-/// minutes/seconds, seconds/tenths of a second, or milliseconds depending on
-/// the largest level that needs to be displayed.
-///
-// TODO: This is copied from `package:build_runner_core`, at some point we
-// may want to move this to a shared dependency.
-String humanReadable(Duration duration) {
-  if (duration < const Duration(seconds: 1)) {
-    return '${duration.inMilliseconds}ms';
-  }
-  if (duration < const Duration(minutes: 1)) {
-    return '${(duration.inMilliseconds / 1000.0).toStringAsFixed(1)}s';
-  }
-  if (duration < const Duration(hours: 1)) {
-    final minutes = duration.inMinutes;
-    final remaining = duration - Duration(minutes: minutes);
-    return '${minutes}m ${remaining.inSeconds}s';
-  }
-  final hours = duration.inHours;
-  final remaining = duration - Duration(hours: hours);
-  return '${hours}h ${remaining.inMinutes}m';
-}
diff --git a/build_resolvers/lib/src/resolver.dart b/build_resolvers/lib/src/resolver.dart
deleted file mode 100644
index 35c255a..0000000
--- a/build_resolvers/lib/src/resolver.dart
+++ /dev/null
@@ -1,335 +0,0 @@
-// 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:collection';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:analyzer/src/summary/summary_file_builder.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/file_system/file_system.dart' hide File;
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
-import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisOptions, AnalysisOptionsImpl;
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:package_resolver/package_resolver.dart';
-import 'package:path/path.dart' as p;
-import 'package:yaml/yaml.dart';
-
-import 'analysis_driver.dart';
-import 'build_asset_uri_resolver.dart';
-import 'human_readable_duration.dart';
-
-final _logger = Logger('build_resolvers');
-
-/// Implements [Resolver.libraries] and [Resolver.findLibraryByName] by crawling
-/// down from entrypoints.
-class PerActionResolver implements ReleasableResolver {
-  final AnalyzerResolver _delegate;
-  final BuildStep _step;
-
-  final Set<AssetId> _entryPoints;
-
-  PerActionResolver(this._delegate, this._step, Iterable<AssetId> entryPoints)
-      : _entryPoints = entryPoints.toSet();
-
-  @override
-  Stream<LibraryElement> get libraries async* {
-    final seen = <LibraryElement>{};
-    final toVisit = Queue<LibraryElement>();
-
-    // keep a copy of entry points in case [_resolveIfNecessary] is called
-    // before this stream is done.
-    final entryPoints = _entryPoints.toList();
-    for (final entryPoint in entryPoints) {
-      if (!await _delegate.isLibrary(entryPoint)) continue;
-      final library = await _delegate.libraryFor(entryPoint);
-      toVisit.add(library);
-      seen.add(library);
-    }
-    while (toVisit.isNotEmpty) {
-      final current = toVisit.removeFirst();
-      // TODO - avoid crawling or returning libraries which are not visible via
-      // `BuildStep.canRead`. They'd still be reachable by crawling the element
-      // model manually.
-      yield current;
-      final toCrawl = current.importedLibraries
-          .followedBy(current.exportedLibraries)
-          .where((l) => !seen.contains(l))
-          .toSet();
-      toVisit.addAll(toCrawl);
-      seen.addAll(toCrawl);
-    }
-  }
-
-  @override
-  Future<LibraryElement> findLibraryByName(String libraryName) async =>
-      libraries.firstWhere((l) => l.name == libraryName, orElse: () => null);
-
-  @override
-  Future<bool> isLibrary(AssetId assetId) async {
-    await _resolveIfNecesssary(assetId);
-    return _delegate.isLibrary(assetId);
-  }
-
-  @override
-  Future<LibraryElement> libraryFor(AssetId assetId) async {
-    await _resolveIfNecesssary(assetId);
-    return _delegate.libraryFor(assetId);
-  }
-
-  Future<void> _resolveIfNecesssary(AssetId id) async {
-    if (!_entryPoints.contains(id)) {
-      _entryPoints.add(id);
-
-      // the resolver will only visit assets that haven't been resolved in this
-      // step yet
-      await _delegate._uriResolver
-          .performResolve(_step, [id], _delegate._driver);
-    }
-  }
-
-  @override
-  void release() {
-    _delegate._uriResolver.notifyComplete(_step);
-    _delegate.release();
-  }
-
-  @override
-  Future<AssetId> assetIdForElement(Element element) =>
-      _delegate.assetIdForElement(element);
-}
-
-class AnalyzerResolver implements ReleasableResolver {
-  final BuildAssetUriResolver _uriResolver;
-  final AnalysisDriver _driver;
-
-  AnalyzerResolver(this._driver, this._uriResolver);
-
-  @override
-  Future<bool> isLibrary(AssetId assetId) async {
-    var source = _driver.sourceFactory.forUri2(assetId.uri);
-    return source != null &&
-        (await _driver.getSourceKind(assetPath(assetId))) == SourceKind.LIBRARY;
-  }
-
-  @override
-  Future<LibraryElement> libraryFor(AssetId assetId) async {
-    var path = assetPath(assetId);
-    var uri = assetId.uri;
-    var source = _driver.sourceFactory.forUri2(uri);
-    if (source == null) throw ArgumentError('missing source for $uri');
-    var kind = await _driver.getSourceKind(path);
-    if (kind != SourceKind.LIBRARY) throw NonLibraryAssetException(assetId);
-    return _driver.getLibraryByUri(assetId.uri.toString());
-  }
-
-  @override
-  // Do nothing
-  void release() {}
-
-  @override
-  Stream<LibraryElement> get libraries {
-    // We don't know what libraries to expose without leaking libraries written
-    // by later phases.
-    throw UnimplementedError();
-  }
-
-  @override
-  Future<LibraryElement> findLibraryByName(String libraryName) {
-    // We don't know what libraries to expose without leaking libraries written
-    // by later phases.
-    throw UnimplementedError();
-  }
-
-  @override
-  Future<AssetId> assetIdForElement(Element element) async {
-    final uri = element.source.uri;
-    if (!uri.isScheme('package') && !uri.isScheme('asset')) {
-      throw UnresolvableAssetException(
-          '${element.name} in ${element.source.uri}');
-    }
-    return AssetId.resolve('${element.source.uri}');
-  }
-}
-
-class AnalyzerResolvers implements Resolvers {
-  /// Nullable, the default analysis options are used if not provided.
-  final AnalysisOptions _analysisOptions;
-
-  /// A function that returns the path to the SDK summary when invoked.
-  ///
-  /// Defaults to [_defaultSdkSummaryGenerator].
-  final Future<String> Function() _sdkSummaryGenerator;
-
-  // Lazy, all access must be preceded by a call to `_ensureInitialized`.
-  AnalyzerResolver _resolver;
-  BuildAssetUriResolver _uriResolver;
-
-  /// Nullable, should not be accessed outside of [_ensureInitialized].
-  Future<void> _initialized;
-
-  AnalyzerResolvers(
-      [this._analysisOptions, Future<String> Function() sdkSummaryGenerator])
-      : _sdkSummaryGenerator =
-            sdkSummaryGenerator ?? _defaultSdkSummaryGenerator;
-
-  /// Create a Resolvers backed by an `AnalysisContext` using options
-  /// [_analysisOptions].
-  Future<void> _ensureInitialized() {
-    return _initialized ??= () async {
-      _uriResolver = BuildAssetUriResolver();
-      var driver = analysisDriver(
-          _uriResolver, _analysisOptions, await _sdkSummaryGenerator());
-      _resolver = AnalyzerResolver(driver, _uriResolver);
-    }();
-  }
-
-  @override
-  Future<ReleasableResolver> get(BuildStep buildStep) async {
-    await _ensureInitialized();
-
-    await _uriResolver.performResolve(
-        buildStep, [buildStep.inputId], _resolver._driver);
-    return PerActionResolver(_resolver, buildStep, [buildStep.inputId]);
-  }
-
-  /// Must be called between each build.
-  @override
-  void reset() {
-    _uriResolver?.reset();
-  }
-}
-
-/// Lazily creates a summary of the users SDK and caches it under
-/// `.dart_tool/build_resolvers`.
-///
-/// This is only intended for use in typical dart packages, which must
-/// have an already existing `.dart_tool` directory (this is how we
-/// validate we are running under a typical dart package and not a custom
-/// environment).
-Future<String> _defaultSdkSummaryGenerator() async {
-  var dartToolPath = '.dart_tool';
-  if (!await Directory(dartToolPath).exists()) {
-    throw StateError(
-        'The default analyzer resolver can only be used when the current '
-        'working directory is a standard pub package.');
-  }
-
-  var cacheDir = p.join(dartToolPath, 'build_resolvers');
-  var summaryPath = p.join(cacheDir, 'sdk.sum');
-  var depsFile = File('$summaryPath.deps');
-  var summaryFile = File(summaryPath);
-
-  var currentDeps = {
-    'sdk': Platform.version,
-    for (var package in _packageDepsToCheck)
-      package: await PackageResolver.current.packagePath(package),
-  };
-
-  // Invalidate existing summary/version/analyzer files if present.
-  if (await depsFile.exists()) {
-    if (!await _checkDeps(depsFile, currentDeps)) {
-      await depsFile.delete();
-      if (await summaryFile.exists()) await summaryFile.delete();
-    }
-  } else if (await summaryFile.exists()) {
-    // Fallback for cases where we could not do a proper version check.
-    await summaryFile.delete();
-  }
-
-  // Generate the summary and version files if necessary.
-  if (!await summaryFile.exists()) {
-    var watch = Stopwatch()..start();
-    _logger.info('Generating SDK summary...');
-    await summaryFile.create(recursive: true);
-    await summaryFile.writeAsBytes(_buildSdkSummary());
-
-    await _createDepsFile(depsFile, currentDeps);
-    watch.stop();
-    _logger.info('Generating SDK summary completed, took '
-        '${humanReadable(watch.elapsed)}\n');
-  }
-
-  return p.absolute(summaryPath);
-}
-
-final _packageDepsToCheck = ['analyzer', 'build_resolvers'];
-
-Future<bool> _checkDeps(
-    File versionsFile, Map<String, Object> currentDeps) async {
-  var previous =
-      jsonDecode(await versionsFile.readAsString()) as Map<String, Object>;
-
-  if (previous.keys.length != currentDeps.keys.length) return false;
-
-  for (var entry in previous.entries) {
-    if (entry.value != currentDeps[entry.key]) return false;
-  }
-
-  return true;
-}
-
-Future<void> _createDepsFile(
-    File depsFile, Map<String, Object> currentDeps) async {
-  await depsFile.create(recursive: true);
-  await depsFile.writeAsString(jsonEncode(currentDeps));
-}
-
-List<int> _buildSdkSummary() {
-  var resourceProvider = PhysicalResourceProvider.INSTANCE;
-  var dartSdkFolder = resourceProvider.getFolder(_runningDartSdkPath);
-  var sdk = FolderBasedDartSdk(resourceProvider, dartSdkFolder)
-    ..useSummary = false
-    ..analysisOptions = AnalysisOptionsImpl();
-
-  if (isFlutter) {
-    _addFlutterLibraries(sdk, resourceProvider);
-  }
-
-  var sdkSources = {
-    for (var library in sdk.sdkLibraries) sdk.mapDartUri(library.shortName),
-  };
-
-  return SummaryBuilder(sdkSources, sdk.context).build();
-}
-
-/// Loads the flutter engine _embedder.yaml file and adds any new libraries to
-/// [sdk].
-void _addFlutterLibraries(
-    AbstractDartSdk sdk, ResourceProvider resourceProvider) {
-  var embedderYamlFile =
-      resourceProvider.getFile(p.join(_dartUiPath, '_embedder.yaml'));
-  if (!embedderYamlFile.exists) {
-    throw StateError('Unable to find flutter libraries, please run '
-        '`flutter precache` and try again.');
-  }
-
-  var embedderYaml = loadYaml(embedderYamlFile.readAsStringSync()) as YamlMap;
-  var flutterSdk = EmbedderSdk(resourceProvider,
-      {resourceProvider.getFolder(_dartUiPath): embedderYaml});
-
-  for (var library in flutterSdk.sdkLibraries) {
-    if (sdk.libraryMap.getLibrary(library.shortName) != null) continue;
-    sdk.libraryMap.setLibrary(library.shortName, library as SdkLibraryImpl);
-  }
-}
-
-/// Path to the running dart's SDK root.
-final _runningDartSdkPath = p.dirname(p.dirname(Platform.resolvedExecutable));
-
-/// Path where the dart:ui package will be found, if executing via the dart
-/// binary provided by the Flutter SDK.
-final _dartUiPath =
-    p.normalize(p.join(_runningDartSdkPath, '..', 'pkg', 'sky_engine', 'lib'));
-
-/// `true` if the currently running dart was provided by the Flutter SDK.
-final isFlutter =
-    Platform.version.contains('flutter') || Directory(_dartUiPath).existsSync();
diff --git a/build_resolvers/mono_pkg.yaml b/build_resolvers/mono_pkg.yaml
deleted file mode 100644
index 3e88b03..0000000
--- a/build_resolvers/mono_pkg.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-        - dartfmt: sdk
-        - dartanalyzer: --fatal-infos --fatal-warnings .
-    - dartanalyzer: --fatal-warnings .
-      dart:
-        - 2.3.0
-  - unit_test:
-    - group:
-      - command: pub run build_runner test
-      - command: test/flutter_test.sh
-      os:
-        - linux
-        - windows
-
-cache:
-  directories:
-    - .dart_tool/build
diff --git a/build_resolvers/pubspec.yaml b/build_resolvers/pubspec.yaml
deleted file mode 100644
index a129cfb..0000000
--- a/build_resolvers/pubspec.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: build_resolvers
-version: 1.3.3
-description: Resolve Dart code in a Builder
-homepage: https://github.com/dart-lang/build/tree/master/build_resolvers
-
-environment:
-  sdk: ">=2.3.0 <3.0.0"
-
-dependencies:
-  analyzer: ^0.39.0
-  build: ">=1.1.0 <1.3.0"
-  crypto: ^2.0.0
-  graphs: ^0.2.0
-  logging: ^0.11.2
-  package_resolver: ^1.0.0
-  path: ^1.1.0
-  yaml: ^2.0.0
-
-dev_dependencies:
-  test: ^1.0.0
-  build_test: ^0.10.1
-  build_runner: ^1.0.0
-  build_vm_compilers: ">=0.1.0 <2.0.0"
-  build_modules: any
-
-dependency_overrides:
-  build_vm_compilers:
-    path: ../build_vm_compilers
-  build_modules:
-    path: ../build_modules
diff --git a/build_runner/BUILD.gn b/build_runner/BUILD.gn
deleted file mode 100644
index 6a8d0eb..0000000
--- a/build_runner/BUILD.gn
+++ /dev/null
@@ -1,48 +0,0 @@
-# This file is generated by importer.py for build_runner-1.7.4
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_runner") {
-  package_name = "build_runner"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/shelf_web_socket",
-    "//third_party/dart-pkg/pub/code_builder",
-    "//third_party/dart-pkg/pub/watcher",
-    "//third_party/dart-pkg/pub/pubspec_parse",
-    "//third_party/dart-pkg/pub/meta",
-    "//third_party/dart-pkg/pub/io",
-    "//third_party/dart-pkg/pub/build_config",
-    "//third_party/dart-pkg/pub/pub_semver",
-    "//third_party/dart-pkg/pub/graphs",
-    "//third_party/dart-pkg/pub/web_socket_channel",
-    "//third_party/dart-pkg/pub/yaml",
-    "//third_party/dart-pkg/pub/build",
-    "//third_party/dart-pkg/pub/dart_style",
-    "//third_party/dart-pkg/pub/build_runner_core",
-    "//third_party/dart-pkg/pub/stack_trace",
-    "//third_party/dart-pkg/pub/pedantic",
-    "//third_party/dart-pkg/pub/build_daemon",
-    "//third_party/dart-pkg/pub/shelf",
-    "//third_party/dart-pkg/pub/glob",
-    "//third_party/dart-pkg/pub/args",
-    "//third_party/dart-pkg/pub/http_multi_server",
-    "//third_party/dart-pkg/pub/collection",
-    "//third_party/dart-pkg/pub/js",
-    "//third_party/dart-pkg/pub/mime",
-    "//third_party/dart-pkg/pub/timing",
-    "//third_party/dart-pkg/pub/path",
-    "//third_party/dart-pkg/pub/pool",
-    "//third_party/dart-pkg/pub/logging",
-    "//third_party/dart-pkg/pub/crypto",
-    "//third_party/dart-pkg/pub/stream_transform",
-    "//third_party/dart-pkg/pub/build_resolvers",
-    "//third_party/dart-pkg/pub/async",
-  ]
-}
diff --git a/build_runner/CHANGELOG.md b/build_runner/CHANGELOG.md
deleted file mode 100644
index 684e5b2..0000000
--- a/build_runner/CHANGELOG.md
+++ /dev/null
@@ -1,962 +0,0 @@
-## 1.7.4
-
-- Give a warning instead of a stack trace when using a build config override
-  file for a package that does not exist.
-- Allow the latest build_config version.
-
-## 1.7.3
-
-- Improve the error message when a `--hostname` argument is invalid.
-- Require SDK version `2.6.0` to enable extension methods.
-- Allow the latest `stream_transform`.
-
-## 1.7.2
-
-- Enable the native windows directory watcher by default.
-  - Added a --use-polling-watcher option which overrides this to use a polling
-    watcher again.
-  - Increased the lower bound for the SDK to a version which contains various
-    fixes for the native windows directory watcher.
-- Give a more consistent ordering for Builders when their ordering is allowed to
-  be arbitrary.
-- Handle more `--help` invocations without generating the build script.
-
-## 1.7.1
-
-- Allow `build` version 1.2.x.
-
-## 1.7.0
-
-### New Feature: Build Filters
-
-Build filters allow you to choose explicitly which files to build instead of
-building entire directories.
-
-A build filter is a combination of a package and a path, with glob syntax
-supported for each.
-
-Whenever a build filter is provided, only required outputs matching one of the
-build filters will be built, in addition to the inputs to those outputs.
-
-### Command Line Usage
-
-Build filters are supplied using the new `--build-filter` option, which accepts
-relative paths under the package as well as `package:` uris.
-
-Glob syntax is allowed in both package names and paths.
-
-**Example**: The following would build and serve the JS output for an
-application, as well as copy over the required SDK resources for that app:
-
-```
-pub run build_runner serve \
-  --build-filter="web/main.dart.js" \
-  --build-filter="package:build_web_compilers/**/*.js"
-```
-
-### Build Daemon Usage
-
-The build daemon now accepts build filters when registering a build target. If
-no filters are supplied these default filters are used, which is designed to
-match the previous behavior as closely as possible:
-
-- `<target-dir>/**`
-- `package:*/**`
-
-**Note**: There is one small difference compared to the previous behavior,
-which is that build to source outputs from other top level directories in the
-root package will no longer be built when they would have before. This should
-have no meaningful impact other than being more efficient.
-
-### Common Use Cases
-
-**Note**: For all the listed use cases it is up to the user or tool the user is
-using to request all the required files for the desired task. This package only
-provides the core building blocks for these use cases.
-
-#### Testing
-
-If you have a large number of tests but only want to run a single one you can
-now build just that test instead of all tests under the `test` directory.
-
-This can greatly speed up iteration times in packages with lots of tests.
-
-**Example**: This will build a single web test and run it:
-
-```
-pub run build_runner test \
-  --build-filter="test/my_test.dart.browser_test.dart.js" \
-  --build-filter="package:build_web_compilers/**/*.js" \
-  -- -p chrome test/my_test.dart
-```
-
-**Note**: If your test requires any other generated files (css, etc) you will
-need to add additional filters.
-
-#### Applications
-
-This feature works as expected with the `--output <dir>` and the `serve`
-command.  This means you can create an output directory for a single
-application in your package instead of all applications under the same
-directory.
-
-The serve command also uses the build filters to restrict what files are
-available, which means it ensures if something works in serve mode it will
-also work when you create an output directory.
-
-## 1.6.9
-
-- Fix bugs in snapshot invalidation logic that prevented invalidation when
-  core packages changed and always created a new snapshot on the second build.
-
-## 1.6.8
-
-- Improve the manual change detector to do a file system scan on demand instead
-  of using a file watcher.
-
-## 1.6.7
-
-- Set the `charset` to `utf-8` for Dart content returned by the `AssetHandler`.
-
-## 1.6.6
-
-- Added watch event debouncing to the `daemon` command to line up with the
-  `watch` command. This makes things work more nicely with swap files as well
-  as "save all" type scenarios (you will only get a single build most times).
-
-## 1.6.5
-
-- Require `package:build_config` `">=0.4.1 <0.4.2"`. Use new API that improves
-  error information when a build configuration file is malformed.
-
-## 1.6.4
-
-- Fix an issue where warning logs on startup were accidentally upgraded to
-  severe logs in the daemon mode.
-
-## 1.6.3
-
-- Preemptively re-snapshot when the `build_runner` or `build_daemon` packages
-  are updated.
-
-## 1.6.2
-
-- Support the latest `build_daemon` version.
-- Expose `assetServerPort` as a top level helper method.
-
-## 1.6.1
-
-- Update the `test` command to wait to exit until the inner test process exits.
-
-## 1.6.0
-
-- Depend on the latest `build_daemon` and provide a shutdown notification on
-  build script updates.
-
-## 1.5.2
-
-- Use a polling directory watcher by default on windows again.
-
-## 1.5.1
-
-- Fix an issue where exit codes were not set correctly when running the
-  generated build script directly.
-
-## 1.5.0
-
-- Update to the latest `build_daemon`.
-
-## 1.4.0
-
-- Add a `run` command to execute VM entrypoints with generated sources.
-
-## 1.3.5
-
-- Use the latest `build_daemon`.
-
-## 1.3.4
-
-- Use the latest `build_config`.
-
-## 1.3.3
-
-- Use `HttpMultiServer.loopback` for the daemon asset server.
-
-## 1.3.2
-
-- Fix an error where daemon mode would claim support for prompts when it can't
-  actually support them and would hang instead.
-- Improve logging when the daemon fails to start up, previously no logs would
-  be shown.
-
-## 1.3.1
-
-- Remove usage of set literals to fix errors on older sdks that don't support
-  them.
-
-## 1.3.0
-
-- Fix an issue where we might re-use stale build snapshots, which could only be
-  resolved by deleting the `.dart_tool` dir (or doing a `clean`).
-- Depend on the latest `build_runner_core` and `build_daemon` releases.
-
-## 1.2.8
-
-- Fix issue where daemon command wouldn't properly shutdown.
-- Allow running when the root package, or a path dependency, is named `test`.
-
-## 1.2.7
-
-- Fix issue where daemon command would occasionally color a log.
-
-## 1.2.6
-
-- Prevent terminals being launched when running the daemon command on Windows.
-- No longer assumeTty when logging through the daemon command.
-- Update `build_daemon` to version `0.4.0`.
-- Update `build_runner_core` to version `2.0.3`.
-- Ensure the daemon command always exits.
-
-## 1.2.5
-
-- Fix a bug with the build daemon where the output options were ignored.
-
-## 1.2.4
-
-- Update `build_resolvers` to version `1.0.0`.
-
-## 1.2.3
-
-- Fix a bug where changing between `--live-reload` and `--hot-reload` might not
-  work due to the etags for the injected JS not changing when they should.
-
-## 1.2.2
-
-- Change the format of Build Daemon messages.
-- Build Daemon asset server now properly waits for build results.
-- Build Daemon now properly signals the start of a build.
-- Fix path issues with Daemon command under Windows.
-
-## 1.2.1
-
-- Update `package:build_runner_core` to version `2.0.1`.
-
-## 1.2.0
-
-- Support building through `package:build_daemon`.
-- Update `package:build_runner_core` to version `2.0.0`.
-
-## 1.1.3
-
-- Update to `package:graphs` version `0.2.0`.
-- Fix an issue where when running from source in watch mode the script would
-  delete itself when it shouldn't.
-- Add digest string to the asset graph visualization.
-- Added a filter box to the asset graph visualization.
-- Allow `build` version `1.1.x`.
-
-## 1.1.2
-
-- Improve error message when the generated build script cannot be parsed or
-  compiled and exit with code `78` to indicate that there is a problem with
-  configuration in the project or a dependency's `build.yaml`.
-
-## 1.1.1
-
-### Bug Fixes
-
-- Handle re-snapshotting the build script on SDK updates.
-- Suppress header for the `Bootstrap` logger.
-
-## 1.1.0
-
-### New Features
-
-- The build script will now be ran from snapshot, which improves startup times.
-- The build script will automatically re-run itself when the build script is
-  changed, instead of requiring the user to re-run it manually.
-
-## 1.0.0
-
-### Breaking Changes
-
-- Massive cleanup of the public api. The only thing exported from this package
-  is now the `run` method. The goal is to reduce the surface area in order to
-  stabilize this package, since it is directly depended on by all users.
-  - Removed all exports from build_runner_core, if you are creating a custom
-    build script you will need to import build_runner_core directly and add a
-    dependency on it.
-  - Stopped exporting the `build` and `watch` functions directly, as well as the
-    `ServeHandler`.
-  - If this has broken your use case please file an issue on the package and
-    request that we export the api you were using previously. These will be
-    considered on an individual basis but the bar for additional exports will be
-    high.
-- Removed support for the --[no-]assume-tty command line argument as it is no
-  longer needed.
-
-## 0.10.3
-
-- Improve performance tracking and visualization using the `timing` package.
-- Handle bad asset graph in the `clean` command.
-
-## 0.10.2
-
-- Added `--hot-reload` cli option and appropriate functionality.
-  See [hot-module-reloading](../docs/hot_module_reloading.md) for more info.
-- Removed dependency on cli_util.
-
-## 0.10.1+1
-
-- Added better error handling when a socket is already in use in `serve` mode.
-
-## 0.10.1
-
-- Added `--live-reload` cli option and appropriate functionality
-- Migrated glob tracking to a specialized node type to fix dart-lang/build#1702.
-
-## 0.10.0
-
-### Breaking Changes
-
-- Implementations of `BuildEnvironment` must now implement the `finalizeBuild`
-  method. There is a default implementation if you extend `BuildEnvironment`
-  that is a no-op.
-  - This method is invoked at the end of the build that allows you to do
-    arbitrary additional work, such as creating merged output directories.
-- The `assumeTty` argument on `IOEnvironment` has moved to a named argument
-  since `null` is an accepted value.
-- The `outputMap` field on `BuildOptions` has moved to the `IOEnvironment`
-  class.
-
-### New Features/Updates
-
-- Added a `outputSymlinksOnly` option to `IOEnvironment` constructor, that
-  causes the merged output directories to contain only symlinks, which is much
-  faster than copying files.
-- Added the `FinalizedAssetView` class which provides a list of all available
-  assets to the `BuildEnvironment` during the build finalization phase.
-  - `outputMap` has moved from `BuildOptions` to this constructor, as a named
-    argument.
-- The `OverridableEnvironment` now supports overriding the new `finalizeBuild`
-  api.
-- The number of concurrent actions per phase is now limited (currently to 16),
-  which should help with memory and cpu usage for large builds.
-
-## 0.9.2
-
-- Changed the default file caching logic to use an LRU cache.
-
-## 0.9.1+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.9.1
-
-- The hash dir for the asset graph under `.dart_tool/build` is now based on a
-  relative path to the build script instead of the absolute path.
-  - This enables `.dart_tool/build` directories to be reused across different
-    computers and directories for the same project.
-
-## 0.9.0
-
-### New Features
-
-- Added the `--log-performance <dir>` option which will dump performance
-  information to `<dir>` after each build.
-- The `BuildPerformance` class is now serializable, it has a `fromJson`
-  constructor and a `toJson` instance method.
-- Added support for `global_options` in `build.yaml` of the root package.
-- Allow overriding the default `Resolvers` implementation.
-- Allows building with symlinked files. Note that changes to the linked files
-  will not trigger rebuilds in watch or serve mode.
-
-### Breaking changes
-
-- `BuildPhasePerformance.action` has been replaced with
-  `BuildPhasePerformance.builderKeys`.
-- `BuilderActionPerformance.builder` has been replaced with
-  `BuilderActionPerformance.builderKey`.
-- `BuildResult` no longer has an `exception` or `stackTrace` field.
-- The 'test' command through `run` will no longer set an exit code. All manual
-  build scripts which call `run` should use the `Future<int>` return to set the
-  exit code for the process.
-- Dropped `failOnSevere` arguments and `--fail-on-severe` flag. Severe logs are
-  always considered failing.
-- Severe level logs now go to `stdout` along with other logs rather than
-  `stderr`. Uncaught exceptions from the `build_runner` system itself still go
-  to `stderr`.
-
-## Other
-
-- Updated to the latest camel case constants from the sdk.
-- Minimum sdk version is now `>=2.0.0-dev.61`.
-
-## 0.8.10
-
-- All builders with `build_to: source` will now be ran regardless of which
-  directory is currently being built, see
-  https://github.com/dart-lang/build/issues/1454 for context.
-- `build` will now throw instead of returning a failed build result if nothing
-  was built.
-- Improve error message when a dependency has a bad `build.yaml` with a missing
-  dependency.
-- Sources that are not a part of a `target` will no longer appear in the asset
-  graph, so they will not be readable or globbable.
-- Updated the generated build script to not rely on json encode/decode for the
-  builder options object. Instead it now directly inlines a map literal.
-
-## 0.8.9
-
-- Added support for building only specified top level directories.
-  - The `build`, `watch` commands support positional arguments which are the
-    directories to build. For example, `pub run build_runner build web` will
-    only build the `web` directory.
-  - The `serve` command treats positional args as it did before, except it will
-    only build the directories you ask it to serve.
-  - The `test` command will automatically only build the `test` directory.
-  - If using the `-o` option, with the `<dir-to-build>:<output-dir>` syntax,
-    then the `<dir-to-build>` will be added to the list of directories to build.
-    - If additional directories are supplied with positional arguments, then
-      those will also be built.
-- Update to latest analyzer and build packages.
-- Updated the `serve` logic to only serve files which were part of the actual
-  build, and not stale assets. This brings the semantics exactly in line with
-  what would be copied to the `-o` output directory.
-
-## 0.8.8
-
-- Improve search behavior on the `/$graph` page. Users can now query for
-  paths and `AssetID` values – `pkg_name|lib/pkg_name.dart`.
-- Commands that don't support trailing args will now appropriately fail with a
-  usage exception.
-- Fix a bug where some rebuilds would not happen after adding a new file that
-  has outputs which were missing during the previous build.
-- Fix a bug where failing actions which are no longer required can still cause
-  the overall build to fail.
-
-## 0.8.7
-
-- Improve error handling on the `/$graph` page.
-- Support the latest `package:builde`
-
-## 0.8.6
-
-- Forward default options for `PostProcessBuilder`s in the generated build
-  script.
-- If a build appears to be not making progress (no actions completed for 15
-  seconds), then a warning will now be logged with the pending actions.
-- Now fail when a build is requested which does not build anything.
-- Clean up some error messages.
-
-## 0.8.5
-
-- Add log message for merged output errors.
-
-## 0.8.4
-
-- Log the number of completed actions on successful builds.
-- Support the new `isRoot` field for `BuilderOptions` so that builders can
-  do different things for the root package.
-- Deprecated `PostProcessBuilder` and `PostProcessBuildStep`. These should be
-  imported from `package:build` instead.
-
-## 0.8.3
-
-- Clean and summarize stack traces printed with `--verbose`.
-- Added a `clean` command which deletes generated to source files and the entire
-  build cache directory.
-- Bug Fix: Use the same order to compute the digest of input files to a build
-  step when writing it as when comparing it. Previously builds would not be
-  pruned as efficiently as they can be because the inputs erroneously looked
-  different.
-
-## 0.8.2+2
-
-- The `.packages` file is now always created in the root of the output directory
-  instead of under each top level directory.
-
-## 0.8.2+1
-
-- Bug Fix: Correctly parse Window's paths with new `--output` semantics.
-
-## 0.8.2
-
-- Allow passing multiple `--output` options. Each option will be split on
-  `:`. The first value will be the root input directory, the second value will
-  be the output directory. If no delimeter is provided, all resources
-  will be copied to the output directory.
-- Allow deleting files in the post process build step.
-- Bug Fix: Correctly include the default whitelist when multiple targets
-  without include are provided.
-- Allow logging from within a build factory.
-- Allow serving assets from successful build steps if the overall build fails.
-- Add a `--release` flag to choose the options from `release_options` in
-  `build.yaml`. This should replace the need to use `--config` pointing to a
-  release version of `build.yaml`.
-
-## 0.8.1
-
-- Improved the layout of `/$perf`, especially after browser window resize.
-- `pub run build_runner` exits with a error when invoked with an unsupported
-  command.
-- Bug Fix: Update outputs in merged directory for sources which are not used
-  during the build. For example if `web/index.html` is not read to produce any
-  generated outputs changes to this file will now get picked up during `pub run
-  build_runner watch --output build`.
-- Don't allow a thrown exception from a Builder to take down the entire build
-  process - instead record it as a failed action. The overall build will still
-  be marked as a failure, but it won't crash the process.
-
-## 0.8.0
-
-### New Features
-
-- Added the new `PostProcessBuilder` class. These are not supported in bazel,
-  and are different than a normal `Builder` in some fundamental ways:
-  - They don't have to declare output extensions, and can output any file as
-    long as it doesn't conflict with an existing one. This is only checked at
-    build time.
-  - They can only read their primary input.
-  - They will not cause optional actions to run - they will only run on assets
-    that were built as a part of the normal build.
-  - They can not be optional themselves, and can only output to cache.
-  - Because they all run in a single phase, after other builders, none of their
-    outputs can be used as inputs to any actions.
-- Added `applyPostProccess` method which takes `PostProcessBuilderFactory`s
-  instead of `BuilderFactory`s.
-
-### Breaking Changes
-
-- `BuilderApplication` now has a `builderActionFactories` getter instead of a
-  `builderFactories` getter.
-- The default constructor for `BuilderApplication` has been replaced with
-  `BuilderApplication.forBuilder` and
-  `BuilderApplication.forPostProcessBuilder`.
-
-## 0.7.14
-
-- Warn when using `--define` or `build.yaml` configuration for invalid builders.
-
-## 0.7.13+1
-
-- Fix a concurrent modification error when using `listAssets` when an asset
-  could be written.
-
-## 0.7.13
-
-- Fix a bug where a chain of `Builder`s would fail to run on some outputs from
-  previous steps when the generated asset did not match the target's `sources`.
-- Added support for serving on IPv4 loopback when the server hostname is
-  'localhost' (the default).
-- Added support for serving on any connection (both IPv4 and IPv6) when the
-  hostname is 'any'.
-- Improved stdout output.
-
-## 0.7.12
-
-- Added the `--log-requests` flag to the `serve` command, which will log all
-  requests to the server.
-- Build actions using `findAssets` will be more smartly invalidated.
-- Added a warning if using `serve` mode but no directories were found to serve.
-- The `--output` option now only outputs files that were required for the latest
-  build. Previously when switching js compilers you could end up with ddc
-  modules in your dart2js output, even though they weren't required. See
-  https://github.com/dart-lang/build/issues/1033.
-- The experimental `create_merged_dir` binary is now removed, it can't be easily
-  supported any more and has been replaced by the `--output` option.
-- Builders which write to `source` are no longer guaranteed to run before
-  builders which write to `cache`.
-- Honors `runs_before` configuration from Builder definitions.
-- Honors `applies_builders` configuration from Builder definitions.
-
-## 0.7.11+1
-
-- Switch to use a `PollingDirectoryWatcher` on windows, which should fix file
-  watching with the `--output` option. Follow along at
-  https://github.com/dart-lang/watcher/issues/52 for more details.
-
-## 0.7.11
-
-- Performance tracking is now disabled by default, and you must pass the
-  `--track-performance` flag to enable it.
-- The heartbeat logger will now log the current number of completed versus
-  scheduled actions, and it will log once a second instead of every 5 seconds.
-- Builds will now be invalidated when the dart SDK is updated.
-- Fixed the error message when missing a build_test dependency but trying to run
-  the `test` command.
-- The build script will now exit on changes to `build.yaml` files.
-
-## 0.7.10+1
-
-- Fix bug where relative imports in a dependencies build.yaml would break
-  all downstream users, https://github.com/dart-lang/build/issues/995.
-
-## 0.7.10
-
-### New Features
-
-- Added a basic performance visualization. When running with `serve` you can
-  now navigate to `/$perf` and get a timeline of all actions. If you are
-  experiencing slow builds (especially incremental ones), you can save the
-  html of that page and attach it to bug reports!
-
-### Bug Fixes
-
-- When using `--output` we will only clean up files we know we previously output
-  to the specified directory. This should allow running long lived processes
-  such as servers in that directory (as long as they don't hold open file
-  handles).
-
-## 0.7.9+2
-
-- Fixed a bug with build to source and watch mode that would result in an
-  infinite build loop, [#962](https://github.com/dart-lang/build/issues/962).
-
-## 0.7.9+1
-
-- Support the latest `analyzer` package.
-
-## 0.7.9
-
-### New Features
-
-- Added command line args to override config for builders globally. The format
-  is `--define "<builder_key>=<option>=<value>"`. As an example, enabling the
-  dart2js compiler for the `build_web_compilers|entrypoint` builder would look
-  like this: `--define "build_web_compilers|entrypoint=compiler=dart2js"`.
-
-### Bug Fixes
-
-- Fixed an issue with mixed mode builds, see
-  https://github.com/dart-lang/build/issues/924.
-- Fixed some issues with exit codes and --fail-on-severe, although there are
-  still some outstanding problems. See
-  https://github.com/dart-lang/build/issues/910 for status updates.
-- Fixed an issue where the process would hang on exceptions, see
-  https://github.com/dart-lang/build/issues/883.
-- Fixed an issue with etags not getting updated for source files that weren't
-  inputs to any build actions, https://github.com/dart-lang/build/issues/894.
-- Fixed an issue with hidden .DS_Store files on mac in the generated directory,
-  https://github.com/dart-lang/build/issues/902.
-- Fixed test output so it will use the compact reporter,
-  https://github.com/dart-lang/build/issues/821.
-
-## 0.7.8
-
-- Add `--config` option to use a different `build.yaml` at build time.
-
-## 0.7.7+1
-
-- Avoid watching hosted dependencies for file changes.
-
-## 0.7.7
-
-- The top level `run` method now returns an `int` which represents an `exitCode`
-  for the command that was executed.
-  - For now we still set the exitCode manually as well but this will likely
-    change in the next breaking release. In manual scripts you should `await`
-    the call to `run` and assign that to `exitCode` to be future-proofed.
-
-## 0.7.6
-
-- Update to package:build version `0.12.0`.
-- Removed the `DigestAssetReader` interface, the `digest` method has now moved
-  to the core `AssetReader` interface. We are treating this as a non-breaking
-  change because there are no known users of this interface.
-
-## 0.7.5+1
-
-- Bug fix for using the `--output` flag when you have no `test` directory.
-
-## 0.7.5
-
-- Add more human friendly duration printing.
-- Added the `--output <dir>` (or `-o`) argument which will create a merged
-  output directory after each build.
-- Added the `--verbose` (or `-v`) flag which enables verbose logging.
-  - Disables stack trace folding and terse stack traces.
-  - Disables the overwriting of previous info logs.
-  - Sets the default log level to `Level.ALL`.
-- Added `pubspec.yaml` and `pubspec.lock` to the whitelist for the root package
-  sources.
-
-## 0.7.4
-
-- Allows using files in any build targets in the root package as sources if they
-  fall outside the hardcoded whitelist.
-- Changes to the root `.packages` file during watch mode will now cause the
-  build script to exit and prompt the user to restart the build.
-
-## 0.7.3
-
-- Added the flag `--low-resources-mode`, which defaults to `false`.
-
-## 0.7.2
-
-- Added the flag `--fail-on-severe`, which defaults to `false`. In a future
-  version this will default to `true`, which means that logging a message via
-  `log.severe` will fail the build instead of just printing to the terminal.
-  This would match the current behavior in `bazel_codegen`.
-- Added the `test` command to the `build_runner` binary.
-
-## 0.7.1+1
-
-- **BUG FIX**: Running the `build_runner` binary without arguments no longer
-  causes a crash saying `Could not find an option named "assume-tty".`.
-
-## 0.7.1
-
-- Run Builders which write to the source tree before those which write to the
-  build cache.
-
-## 0.7.0
-
-### New Features
-
-- Added `toRoot` Package filter.
-- Actions are now invalidated at a fine grained level when `BuilderOptions`
-  change.
-- Added magic placeholder files in all packages, which can be used when your
-  builder doesn't have a clear primary input file.
-  - For non-root packages the placeholder exists at `lib/$lib$`, you should
-    declare your `buildExtensions` like this `{r'$lib$': 'my_output_file.txt'}`,
-    which would result in an output file at `lib/my_output_file.txt` in the
-    package.
-  - For the root package there are also placeholders at `web/$web$` and
-    `test/$test$` which should cover most use cases. Please file an issue if you
-    need additional placeholders.
-  - Note that these placeholders are not real assets and attempting to read them
-    will result in an `AssetNotFoundException`.
-
-### Breaking Changes
-
-- Removed `BuildAction`. Changed `build` and `watch` to take a
-  `List<BuilderApplication>`. See `apply` and `applyToRoot` to set these up.
-- Changed `apply` to take a single String argument - a Builder key from
-  `package:build_config` rather than a separate package and builder name.
-- Changed the default value of `hideOutput` from `false` to `true` for `apply`.
-  With `applyToRoot` the value remains `false`.
-- There is now a whitelist of top level directories that will be used as a part
-  of the build, and other files will be ignored. For now those directories
-  include 'benchmark', 'bin', 'example', 'lib', 'test', 'tool', and 'web'.
-  - If this breaks your workflow please file an issue and we can look at either
-    adding additional directories or making the list configurable per project.
-- Remove `PackageGraph.orderedPackages` and `PackageGraph.dependentsOf`.
-- Remove `writeToCache` argument of `build` and `watch`. Each `apply` call
-  should specify `hideOutput` to keep this behavior.
-- Removed `PackageBuilder` and `PackageBuildActions` classes. Use the new
-  magic placeholder files instead (see new features section for this release).
-
-The following changes are technically breaking but should not impact most
-clients:
-
-- Upgrade to `build_barback` v0.5.0 which uses strong mode analysis and no
-  longer analyzes method bodies.
-- Removed `dependencyType`, `version`, `includes`, and `excludes` from
-  `PackageNode`.
-- Removed `PackageNode.noPubspec` constructor.
-- Removed `InputSet`.
-- PackageGraph instances enforce that the `root` node is the only node with
-  `isRoot == true`.
-
-## 0.6.1
-
-### New Features
-
-- Add an `enableLowResourcesMode` option to `build` and `watch`, which will
-  consume less memory at the cost of slower builds. This is intended for use in
-  resource constrained environments such as Travis.
-- Add `createBuildActions`. After finding a list of Builders to run, and defining
-  which packages need them applied, use this tool to apply them in the correct
-  order across the package graph.
-
-### Deprecations
-
-- Deprecate `PackageGraph.orderedPackages` and `PackageGraph.dependentsOf`.
-
-### Internal Improvements
-
-- Outputs will no longer be rebuilt unless their inputs actually changed,
-  previously if any transtive dependency changed they would be invalidated.
-- Switched to using semantic analyzer summaries, this combined with the better
-  input validation means that, ddc/summary builds are much faster on non-api
-  affecting edits (dependent modules will no longer be rebuilt).
-- Build script invalidation is now much faster, which speeds up all builds.
-
-### Bug Fixes
-
-- The build actions are now checked against the previous builds actions, and if
-  they do not match then a full build is performed. Previously the behavior in
-  this case was undefined.
-- Fixed an issue where once an edge between an output and an input was created
-  it was never removed, causing extra builds to happen that weren't necessary.
-- Build actions are now checked for overlapping outputs in non-checked mode,
-  previously this was only an assert.
-- Fixed an issue where nodes could get in an inconsistent state for short
-  periods of time, leading to various errors.
-- Fixed an issue on windows where incremental builds didn't work.
-
-## 0.6.0+1
-
-### Internal Improvements
-
-- Now using `package:pool` to limit the number of open file handles.
-
-### Bug fixes
-
-- Fixed an issue where the asset graph could get in an invalid state if you
-  aren't setting `writeToCache: true`.
-
-## 0.6.0
-
-### New features
-
-- Added `orderedPackages` and `dependentsOf` utilities to `PackageGraph`.
-- Added the `noPubspec` constructor to `PackageNode`.
-- Added the `PackageBuilder` and `PackageBuildAction` classes. These builders
-  only run once per package, and have no primary input. Outputs must be well
-  known ahead of time and are declared with the `Iterable<String> get outputs`
-  field, which returns relative paths under the current package.
-- Added the `isOptional` field to `BuildAction`. Setting this to `true` means
-  that the action will not run unless some other non-optional action tries to
-  read one of the outputs of the action.
-- **Breaking**: `PackageNode.location` has become `PackageNode.path`, and is
-  now a `String` (absolute path) instead of a `Uri`; this prevents needing
-  conversions to/from `Uri` across the package.
-- **Breaking**: `RunnerAssetReader` interface requires you to implement
-  `MultiPackageAssetReader` and `DigestAssetReader`. This means the
-  `packageName` named argument has changed to `package`, and you have to add the
-  `Future<Digest> digest(AssetId id)` method. While technically breaking most
-  users do not rely on this interface explicitly.
-  - You also no longer have to implement the
-    `Future<DateTime> lastModified(AssetId id)` method, as it has been replaced
-    with the `DigestAssetReader` interface.
-- **Breaking**: `ServeHandler.handle` has been replaced with
-  `Handler ServeHandler.handleFor(String rootDir)`. This allows you to create
-  separate handlers per directory you want to serve, which maintains pub serve
-  conventions and allows interoperation with `pub run test --pub-serve=$PORT`.
-
-### Bug fixes
-
-- **Breaking**: All `AssetReader#findAssets` implementations now return a
-  `Stream<AssetId>` to match the latest `build` package. This should not affect
-  most users unless you are extending the built in `AssetReader`s or using them
-  in a custom way.
-- Fixed an issue where `findAssets` could return declared outputs from previous
-  phases that did not actually output the asset.
-- Fixed two issues with `writeToCache`:
-  - Over-declared outputs will no longer attempt to build on each startup.
-  - Unrecognized files in the cache dir will no longer be treated as inputs.
-- Asset invalidation has changed from using last modified timestamps to content
-  hashes. This is generally much more reliable, and unblocks other desired
-  features.
-
-### Internal changes
-
-- Added `PackageGraphWatcher` and `PackageNodeWatcher` as a wrapper API,
-  including an `AssetChange` class that is now consistently used across the
-  package.
-
-## 0.5.0
-
-- **Breaking**: Removed `buildType` field from `BuildResult`.
-- **Breaking**: `watch` now returns a `ServeHandler` instead of a
-  `Stream<BuildResult>`. Use `ServeHandler.buildResults` to get back to the
-  original stream.
-- **Breaking**: `serve` has been removed. Instead use `watch` and use the
-  resulting `ServeHandler.handle` method along with a server created in the
-  client script to start a server.
-- Prevent reads into `.dart_tool` for more hermetic builds.
-- Bug Fix: Rebuild entire asset graph if the build script changes.
-- Add `writeToCache` argument to `build` and `watch` which separates generated
-  files from the source directory and allows running builders against other
-  packages.
-- Allow the latest version of `package:shelf`.
-
-## 0.4.0+3
-
-- Bug fix: Don't try to delete files generated for other packages.
-
-## 0.4.0+2
-
-- Bug fix: Don't crash after a Builder reads a file from another package.
-
-## 0.4.0+1
-
-- Depend on `build` 0.10.x and `build_barback` 0.4.x
-
-## 0.4.0
-
-- **Breaking**: The `PhaseGroup` class has been replaced with a
-  `List<BuildAction>` in `build`, `watch`, and `serve`. The `PhaseGroup` and
-  `Phase` classes are removed.
-  If your current build has multiple actions in a single phase which are
-  depending on *not* seeing the outputs from other actions in the phase you will
-  need to instead set up the `InputSet`s so that the outputs are filtered out.
-- **Breaking**: The `resolvers` argument has been removed from `build`, `watch`,
-  and `serve`.
-- Allow `package:build` v0.10.x
-
-## 0.3.4+1
-
-- Support the latest release of `build_barback`.
-
-## 0.3.4
-
-- Support the latest release of `analyzer`.
-
-## 0.3.2
-
-- Support for build 0.9.0
-
-## 0.3.1+1
-
-- Bug Fix: Update AssetGraph version so builds can be run without manually
-  deleting old build directory.
-- Bug Fix: Check for unreadable assets in an async method rather than throw
-  synchronously
-
-## 0.3.1
-
-- Internal refactoring of RunnerAssetReader.
-- Support for build 0.8.0
-- Add findAssets on AssetReader implementations
-- Limit Asset reads to those which were available at the start of the phase.
-  This might cause some reads which uses to succeed to fail.
-
-## 0.3.0
-
-### Bug Fixes
-
-- Fixed a race condition bug [175](https://github.com/dart-lang/build/issues/175)
-  that could cause invalid output errors.
-
-### Breaking Changes
-
-- `RunnerAssetWriter` now requires an additional field, `onDelete` which is a
-  callback that must be called synchronously within `delete`.
-
-## 0.2.0
-
-Add support for the new bytes apis in `build`.
-
-### New Features
-
-- `FileBasedAssetReader` and `FileBasedAssetWriter` now support reading/writing
-  as bytes.
-
-### Breaking Changes
-
-- Removed the `AssetCache`, `CachedAssetReader`, and `CachedAssetWriter`. These
-  may come back at a later time if deemed necessary, but for now they just
-  complicate things unnecessarily without proven benefits.
-- `BuildResult#outputs` now has a type of `List<AssetId>` instead of
-  `List<Asset>`, since the `Asset` class no longer exists. Additionally this was
-  wasting memory by keeping all output contents around when it's not generally
-  a very useful thing outside of tests (which retain this information in other
-  ways).
-
-## 0.0.1
-
-- Initial separate release - split off from `build` package.
diff --git a/build_runner/LICENSE b/build_runner/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/build_runner/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_runner/README.md b/build_runner/README.md
deleted file mode 100644
index 8845b2f..0000000
--- a/build_runner/README.md
+++ /dev/null
@@ -1,256 +0,0 @@
-<p align="center">
-  Standalone generator and watcher for Dart using <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
-  <br>
-  <a href="https://travis-ci.org/dart-lang/build">
-    <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
-  </a>
-  <a href="https://github.com/dart-lang/build/labels/package%3A%20build_runner">
-    <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_runner.svg" alt="Issues related to build_runner" />
-  </a>
-  <a href="https://pub.dev/packages/build_runner">
-    <img src="https://img.shields.io/pub/v/build_runner.svg" alt="Pub Package Version" />
-  </a>
-  <a href="https://pub.dev/documentation/build_runner/latest">
-    <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
-  </a>
-  <a href="https://gitter.im/dart-lang/build">
-    <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
-  </a>
-</p>
-
-The `build_runner` package provides a concrete way of generating files using
-Dart code, outside of tools like `pub`. Unlike `pub serve/build`, files are
-always generated directly on disk, and rebuilds are _incremental_ - inspired by
-tools such as [Bazel][].
-
-> **NOTE**: Are you a user of this package? You may be interested in
-> simplified user-facing documentation, such as our
-> [getting started guide][getting-started-link].
-
-[getting-started-link]: https://goo.gl/b9o2j6
-
-* [Installation](#installation)
-* [Usage](#usage)
-  * [Built-in commands](#built-in-commands)
-  * [Inputs](#inputs)
-  * [Outputs](#outputs)
-  * [Source control](#source-control)
-  * [Publishing packages](#publishing-packages)
-* [Contributing](#contributing)
-  * [Testing](#testing)
-
-## Installation
-
-This package is intended to support development of Dart projects with
-[`package:build`][]. In general, put it under [dev_dependencies][], in your
-[`pubspec.yaml`][pubspec].
-
-```yaml
-dev_dependencies:
-  build_runner:
-```
-
-## Usage
-
-When the packages providing `Builder`s are configured with a `build.yaml` file
-they are designed to be consumed using an generated build script. Most builders
-should need little or no configuration, see the documentation provided with the
-Builder to decide whether the build needs to be customized. If it does you may
-also provide a `build.yaml` with the configuration. See the
-`package:build_config` README for more information on this file.
-
-To have web code compiled to js add a `dev_dependency` on `build_web_compilers`.
-
-### Built-in Commands
-
-The `build_runner` package exposes a binary by the same name, which can be
-invoked using `pub run build_runner <command>`.
-
-The available commands are `build`, `watch`, `serve`, and `test`.
-
-- `build`: Runs a single build and exits.
-- `watch`: Runs a persistent build server that watches the files system for
-  edits and does rebuilds as necessary.
-- `serve`: Same as `watch`, but runs a development server as well.
-  - By default this serves the `web` and `test` directories, on port `8080` and
-    `8081` respectively. See below for how to configure this.
-- `test`: Runs a single build, creates a merged output directory, and then runs
-  `pub run test --precompiled <merged-output-dir>`. See below for instructions
-  on passing custom args to the test command.
-
-#### Command Line Options
-
-All the above commands support the following arguments:
-
-- `--help`: Print usage information for the command.
-- `--assume-tty`: Enables colors and interactive input when the script does not
-  appear to be running directly in a terminal, for instance when it is a
-  subprocess.
-- `--delete-conflicting-outputs`: Assume conflicting outputs in the users
-  package are from previous builds, and skip the user prompt that would usually
-  be provided.
-- `--[no-]fail-on-severe`: Whether to consider the build a failure on an error
-  logged. By default this is false.
-
-Some commands also have additional options:
-
-##### serve
-
-- `--hostname`: The host to run the server on.
-- `--live-reload`: Enables automatic page reloading on rebuilds.
-  Can't be used together with `--hot-reload`.
-- `--hot-reload`: Enables automatic reloading of changed modules on rebuilds.
-  See [hot-module-reloading](../docs/hot_module_reloading.md) for more info.
-  Can't be used together with `--live-reload`.
-
-Trailing args of the form `<directory>:<port>` are supported to customize what
-directories are served, and on what ports.
-
-For example to serve the `example` and `web` directories on ports 8000 and 8001
-you would do `pub run build_runner serve example:8000 web:8001`.
-
-##### test
-
-The test command will forward any arguments after an empty `--` arg to the
-`pub run test` command.
-
-For example if you wanted to pass `-p chrome` you would do
-`pub run build_runner test -- -p chrome`.
-
-### Inputs
-
-Valid inputs follow the general dart package rules. You can read any files under
-the top level `lib` folder any package dependency, and you can read all files
-from the current package.
-
-In general it is best to be as specific as possible with your `InputSet`s,
-because all matching files will be checked against a `Builder`'s
-[`buildExtensions`][build_extensions] - see [outputs](#outputs) for more
-information.
-
-### Outputs
-
-* You may output files anywhere in the current package.
-
-> **NOTE**: When a `BuilderApplication` specifies `hideOutput: true` it may
-> output under the `lib` folder of _any_ package you depend on.
-
-* Builders are not allowed to overwrite existing files, only create new ones.
-* Outputs from previous builds will not be treated as inputs to later ones.
-* You may use a previous `BuilderApplications`'s outputs as an input to a later
-  action.
-
-### Source control
-
-This package creates a top level `.dart_tool` folder in your package, which
-should not be submitted to your source control repository. You can see [our own
-`.gitignore`](https://github.com/dart-lang/build/blob/master/.gitignore) as an
-example.
-
-```git
-# Files generated by dart tools
-.dart_tool
-```
-
-When it comes to _generated_ files it is generally best to not submit them to
-source control, but a specific `Builder` may provide a recommendation otherwise.
-
-It should be noted that if you do submit generated files to your repo then when
-you change branches or merge in changes you may get a warning on your next build
-about declared outputs that already exist. This will be followed up with a
-prompt to delete those files. You can type `l` to list the files, and then type
-`y` to delete them if everything looks correct. If you think something is wrong
-you can type `n` to abandon the build without taking any action.
-
-### Publishing packages
-
-In general generated files **should** be published with your package, but this
-may not always be the case. Some `Builder`s may provide a recommendation for
-this as well.
-
-
-## Legacy Usage
-
-If the generated script does not do everything you need it's possible to
-manually write one. With this approach every package which *uses* a
-[`Builder`][builder] must have it's own script, they cannot be reused
-from other packages. A package which defines a [`Builder`][builder] may have an
-example you can reference, but a unique script must be written for the consuming
-packages as well. You can reference the generated script at
-`.dart_tool/build/entrypoint/build.dart` for an example.
-
-Your script should use one of the following functions defined by this library:
-
-- [**`run`**][run_fn]: Use the same argument parsing as the generated approach.
-- [**`build`**][build_fn]: Run a single build and exit.
-- [**`watch`**][watch_fn]: Continuously run builds as you edit files.
-
-### Configuring
-
-[`run`][run_fn], [`build`][build_fn], and [`watch`][watch_fn] have a required
-argument which is a `List<BuilderApplication>`. These correspond to the
-`BuilderDefinition` class from `package:build_config`. See `apply` and
-`applyToRoot` to create instances of this class. These will be translated into
-actions by crawling through dependencies. The order of this list is important.
-Each Builder may read the generated outputs of any Builder that ran on a package
-earlier in the dependency graph, but for the package it is running on it may
-only read the generated outputs from Builders earlier in the list of
-`BuilderApplication`s.
-
-**NOTE**: Any time you change your build script (or any of its dependencies),
-the next build will be a full rebuild. This is because the system has no way
-of knowing how that change may have affected the outputs.
-
-## Contributing
-
-We welcome a diverse set of contributions, including, but not limited to:
-
-* [Filing bugs and feature requests][file_an_issue]
-* [Send a pull request][pull_request]
-* Or, create something awesome using this API and share with us and others!
-
-For the stability of the API and existing users, consider opening an issue
-first before implementing a large new feature or breaking an API. For smaller
-changes (like documentation, minor bug fixes), just send a pull request.
-
-### Testing
-
-All pull requests are validated against [travis][travis], and must pass. The
-`build_runner` package lives in a mono repository with other `build` packages,
-and _all_ of the following checks must pass for _each_ package.
-
-Ensure code passes all our [analyzer checks][analysis_options]:
-
-```sh
-$ dartanalyzer .
-```
-
-Ensure all code is formatted with the latest [dev-channel SDK][dev_sdk].
-
-```sh
-$ dartfmt -w .
-```
-
-Run all of our unit tests:
-
-```sh
-$ pub run test
-```
-
-[Bazel]: https://bazel.build/
-[`package:build`]: https://pub.dev/packages/build
-[analysis_options]: https://github.com/dart-lang/build/blob/master/analysis_options.yaml
-
-[builder]: https://pub.dev/documentation/build/latest/build/Builder-class.html
-[run_fn]: https://pub.dev/documentation/build_runner/latest/build_runner/run.html
-[build_fn]: https://pub.dev/documentation/build_runner/latest/build_runner/build.html
-[watch_fn]: https://pub.dev/documentation/build_runner/latest/build_runner/watch.html
-[builder_application]: https://pub.dev/documentation/build_runner/latest/build_runner/BuilderApplication-class.html
-[build_extensions]: https://pub.dev/documentation/build/latest/build/Builder/buildExtensions.html
-
-[travis]: https://travis-ci.org/
-[dev_sdk]: https://dart.dev/get-dart
-[dev_dependencies]: https://dart.dev/tools/pub/dependencies#dev-dependencies
-[pubspec]: https://dart.dev/tools/pub/pubspec
-[file_an_issue]: https://github.com/dart-lang/build/issues/new
-[pull_request]: https://github.com/dart-lang/build/pulls
diff --git a/build_runner/bin/build_runner.dart b/build_runner/bin/build_runner.dart
deleted file mode 100644
index e790a51..0000000
--- a/build_runner/bin/build_runner.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:io/ansi.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-
-import 'package:build_runner/src/build_script_generate/bootstrap.dart';
-import 'package:build_runner/src/entrypoint/runner.dart';
-import 'package:build_runner/src/logging/std_io_logging.dart';
-
-import 'src/commands/clean.dart';
-import 'src/commands/generate_build_script.dart';
-
-Future<void> main(List<String> args) async {
-  // Use the actual command runner to parse the args and immediately print the
-  // usage information if there is no command provided or the help command was
-  // explicitly invoked.
-  var commandRunner = BuildCommandRunner([]);
-  var localCommands = [CleanCommand(), GenerateBuildScript()];
-  var localCommandNames = localCommands.map((c) => c.name).toSet();
-  localCommands.forEach(commandRunner.addCommand);
-
-  ArgResults parsedArgs;
-  try {
-    parsedArgs = commandRunner.parse(args);
-  } on UsageException catch (e) {
-    print(red.wrap(e.message));
-    print('');
-    print(e.usage);
-    exitCode = ExitCode.usage.code;
-    return;
-  }
-
-  var commandName = parsedArgs.command?.name;
-
-  if (parsedArgs.rest.isNotEmpty) {
-    print(
-        yellow.wrap('Could not find a command named "${parsedArgs.rest[0]}".'));
-    print('');
-    print(commandRunner.usageWithoutDescription);
-    exitCode = ExitCode.usage.code;
-    return;
-  }
-
-  if (commandName == 'help' ||
-      parsedArgs.wasParsed('help') ||
-      (parsedArgs.command?.wasParsed('help') ?? false)) {
-    await commandRunner.runCommand(parsedArgs);
-    return;
-  }
-
-  if (commandName == null) {
-    commandRunner.printUsage();
-    exitCode = ExitCode.usage.code;
-    return;
-  }
-
-  StreamSubscription logListener;
-  if (commandName == 'daemon') {
-    // Simple logs only in daemon mode. These get converted into info or
-    // severe logs by the client.
-    logListener = Logger.root.onRecord.listen((record) {
-      if (record.level >= Level.SEVERE) {
-        var buffer = StringBuffer(record.message);
-        if (record.error != null) buffer.writeln(record.error);
-        if (record.stackTrace != null) buffer.writeln(record.stackTrace);
-        stderr.writeln(buffer);
-      } else {
-        stdout.writeln(record.message);
-      }
-    });
-  } else {
-    logListener = Logger.root.onRecord.listen(stdIOLogListener());
-  }
-  if (localCommandNames.contains(commandName)) {
-    exitCode = await commandRunner.runCommand(parsedArgs);
-  } else {
-    while ((exitCode = await generateAndRun(args)) == ExitCode.tempFail.code) {}
-  }
-  await logListener?.cancel();
-}
diff --git a/build_runner/bin/graph_inspector.dart b/build_runner/bin/graph_inspector.dart
deleted file mode 100644
index 21e6ea0..0000000
--- a/build_runner/bin/graph_inspector.dart
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-
-AssetGraph assetGraph;
-PackageGraph packageGraph;
-
-final logger = Logger('graph_inspector');
-
-Future<void> main(List<String> args) async {
-  final logSubscription =
-      Logger.root.onRecord.listen((record) => print(record.message));
-  logger.warning(
-      'Warning: this tool is unsupported and usage may change at any time, '
-      'use at your own risk.');
-
-  final argParser = ArgParser()
-    ..addOption('graph-file',
-        abbr: 'g', help: 'Specify the asset_graph.json file to inspect.')
-    ..addOption('build-script',
-        abbr: 'b',
-        help: 'Specify the build script to find the asset graph for.',
-        defaultsTo: '.dart_tool/build/entrypoint/build.dart');
-
-  final results = argParser.parse(args);
-
-  if (results.wasParsed('graph-file') && results.wasParsed('build-script')) {
-    throw ArgumentError(
-        'Expected exactly one of `--graph-file` or `--build-script`.');
-  }
-
-  var assetGraphFile = File(_findAssetGraph(results));
-  if (!assetGraphFile.existsSync()) {
-    throw ArgumentError('Unable to find AssetGraph.');
-  }
-  stdout.writeln('Loading asset graph at ${assetGraphFile.path}...');
-
-  assetGraph = AssetGraph.deserialize(assetGraphFile.readAsBytesSync());
-  packageGraph = PackageGraph.forThisPackage();
-
-  var commandRunner = CommandRunner<bool>(
-      '', 'A tool for inspecting the AssetGraph for your build')
-    ..addCommand(InspectNodeCommand())
-    ..addCommand(GraphCommand())
-    ..addCommand(QuitCommand());
-
-  stdout.writeln('Ready, please type in a command:');
-
-  var shouldExit = false;
-  while (!shouldExit) {
-    stdout
-      ..writeln('')
-      ..write('> ');
-    var nextCommand = stdin.readLineSync();
-    stdout.writeln('');
-    try {
-      shouldExit = await commandRunner.run(nextCommand.split(' '));
-    } on UsageException {
-      stdout.writeln('Unrecognized option');
-      await commandRunner.run(['help']);
-    }
-  }
-  await logSubscription.cancel();
-}
-
-String _findAssetGraph(ArgResults results) {
-  if (results.wasParsed('graph-file')) return results['graph-file'] as String;
-  final scriptPath = results['build-script'] as String;
-  final scriptFile = File(scriptPath);
-  if (!scriptFile.existsSync()) {
-    throw ArgumentError(
-        'Expected a build script at $scriptPath but didn\'t find one.');
-  }
-  return assetGraphPathFor(p.url.joinAll(p.split(scriptPath)));
-}
-
-class InspectNodeCommand extends Command<bool> {
-  @override
-  String get name => 'inspect';
-
-  @override
-  String get description =>
-      'Lists all the information about an asset using a relative or package: uri';
-
-  @override
-  String get invocation => '${super.invocation} <dart-uri>';
-
-  InspectNodeCommand() {
-    argParser.addFlag('verbose', abbr: 'v');
-  }
-
-  @override
-  bool run() {
-    var stringUris = argResults.rest;
-    if (stringUris.isEmpty) {
-      stderr.writeln('Expected at least one uri for a node to inspect.');
-    }
-    for (var stringUri in stringUris) {
-      var id = _idFromString(stringUri);
-      if (id == null) {
-        continue;
-      }
-      var node = assetGraph.get(id);
-      if (node == null) {
-        stderr.writeln('Unable to find an asset node for $stringUri.');
-        continue;
-      }
-
-      var description = StringBuffer()
-        ..writeln('Asset: $stringUri')
-        ..writeln('  type: ${node.runtimeType}');
-
-      if (node is GeneratedAssetNode) {
-        description
-          ..writeln('  state: ${node.state}')
-          ..writeln('  wasOutput: ${node.wasOutput}')
-          ..writeln('  phase: ${node.phaseNumber}')
-          ..writeln('  isFailure: ${node.isFailure}');
-      }
-
-      void _printAsset(AssetId asset) =>
-          _listAsset(asset, description, indentation: '    ');
-
-      if (argResults['verbose'] == true) {
-        description.writeln('  primary outputs:');
-        node.primaryOutputs.forEach(_printAsset);
-
-        description.writeln('  secondary outputs:');
-        node.outputs.difference(node.primaryOutputs).forEach(_printAsset);
-
-        if (node is NodeWithInputs) {
-          description.writeln('  inputs:');
-          assetGraph.allNodes
-              .where((n) => n.outputs.contains(node.id))
-              .map((n) => n.id)
-              .forEach(_printAsset);
-        }
-      }
-
-      stdout.write(description);
-    }
-    return false;
-  }
-}
-
-class GraphCommand extends Command<bool> {
-  @override
-  String get name => 'graph';
-
-  @override
-  String get description => 'Lists all the nodes in the graph.';
-
-  @override
-  String get invocation => '${super.invocation} <dart-uri>';
-
-  GraphCommand() {
-    argParser
-      ..addFlag('generated',
-          abbr: 'g', help: 'Show only generated assets.', defaultsTo: false)
-      ..addFlag('original',
-          abbr: 'o',
-          help: 'Show only original source assets.',
-          defaultsTo: false)
-      ..addOption('package',
-          abbr: 'p', help: 'Filters nodes to a certain package')
-      ..addOption('pattern', abbr: 'm', help: 'glob pattern for path matching');
-  }
-
-  @override
-  bool run() {
-    var showGenerated = argResults['generated'] as bool;
-    var showSources = argResults['original'] as bool;
-    Iterable<AssetId> assets;
-    if (showGenerated) {
-      assets = assetGraph.outputs;
-    } else if (showSources) {
-      assets = assetGraph.sources;
-    } else {
-      assets = assetGraph.allNodes.map((n) => n.id);
-    }
-
-    var package = argResults['package'] as String;
-    if (package != null) {
-      assets = assets.where((id) => id.package == package);
-    }
-
-    var pattern = argResults['pattern'] as String;
-    if (pattern != null) {
-      var glob = Glob(pattern);
-      assets = assets.where((id) => glob.matches(id.path));
-    }
-
-    for (var id in assets) {
-      _listAsset(id, stdout, indentation: '  ');
-    }
-    return false;
-  }
-}
-
-class QuitCommand extends Command<bool> {
-  @override
-  String get name => 'quit';
-
-  @override
-  String get description => 'Exit the inspector';
-
-  @override
-  bool run() => true;
-}
-
-AssetId _idFromString(String stringUri) {
-  var uri = Uri.parse(stringUri);
-  if (uri.scheme == 'package') {
-    return AssetId(uri.pathSegments.first,
-        p.url.join('lib', p.url.joinAll(uri.pathSegments.skip(1))));
-  } else if (!uri.isAbsolute && (uri.scheme == '' || uri.scheme == 'file')) {
-    return AssetId(packageGraph.root.name, uri.path);
-  } else {
-    stderr.writeln('Unrecognized uri $uri, must be a package: uri or a '
-        'relative path.');
-    return null;
-  }
-}
-
-void _listAsset(AssetId output, StringSink buffer,
-    {String indentation = '  '}) {
-  var outputUri = output.uri;
-  if (outputUri.scheme == 'package') {
-    buffer.writeln('$indentation${output.uri}');
-  } else {
-    buffer.writeln('$indentation${output.path}');
-  }
-}
diff --git a/build_runner/bin/src/commands/clean.dart b/build_runner/bin/src/commands/clean.dart
deleted file mode 100644
index 70b0113..0000000
--- a/build_runner/bin/src/commands/clean.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:logging/logging.dart';
-
-import 'package:build_runner/src/build_script_generate/build_script_generate.dart';
-import 'package:build_runner/src/entrypoint/base_command.dart' show lineLength;
-import 'package:build_runner/src/entrypoint/clean.dart' show cleanFor;
-
-class CleanCommand extends Command<int> {
-  @override
-  final argParser = ArgParser(usageLineLength: lineLength);
-
-  @override
-  String get name => 'clean';
-  final logger = Logger('clean');
-
-  @override
-  String get description =>
-      'Cleans up output from previous builds. Does not clean up --output '
-      'directories.';
-
-  @override
-  Future<int> run() async {
-    await cleanFor(assetGraphPathFor(scriptLocation), logger);
-    return 0;
-  }
-}
diff --git a/build_runner/bin/src/commands/generate_build_script.dart b/build_runner/bin/src/commands/generate_build_script.dart
deleted file mode 100644
index 002abc8..0000000
--- a/build_runner/bin/src/commands/generate_build_script.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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:args/command_runner.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import 'package:build_runner/src/build_script_generate/build_script_generate.dart';
-import 'package:build_runner/src/entrypoint/base_command.dart' show lineLength;
-
-class GenerateBuildScript extends Command<int> {
-  @override
-  final argParser = ArgParser(usageLineLength: lineLength);
-
-  @override
-  String get description =>
-      'Generate a script to run builds and print the file path '
-      'with no other logging. Useful for wrapping builds with other tools.';
-
-  @override
-  String get name => 'generate-build-script';
-
-  @override
-  bool get hidden => true;
-
-  @override
-  Future<int> run() async {
-    Logger.root.clearListeners();
-    var buildScript = await generateBuildScript();
-    File(scriptLocation)
-      ..createSync(recursive: true)
-      ..writeAsStringSync(buildScript);
-    print(p.absolute(scriptLocation));
-    return 0;
-  }
-}
diff --git a/build_runner/build.yaml b/build_runner/build.yaml
deleted file mode 100644
index d1e3e0f..0000000
--- a/build_runner/build.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-targets:
-  $default:
-    builders:
-      build_web_compilers:entrypoint:
-        options:
-          compiler: dart2js
-          dart2js_args:
-            - -O4
-        generate_for:
-          - web/graph_viz_main.dart
-          - web/hot_reload_client.dart
-      build_runner:client_js_copy_builder:
-        enabled: true
-builders:
-  client_js_copy_builder:
-    import: "tool/builders.dart"
-    builder_factories:
-        - copyCompiledJs
-    build_extensions:
-      web/graph_viz_main.dart.js:
-        - lib/src/server/graph_viz_main.dart.js
-      web/hot_reload_client.dart.js:
-        - lib/src/server/build_updates_client/hot_reload_client.dart.js
-    auto_apply: none
-    build_to: source
diff --git a/build_runner/dart_test.yaml b/build_runner/dart_test.yaml
deleted file mode 100644
index 112148b..0000000
--- a/build_runner/dart_test.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-tags:
-  integration:
-    timeout: 16x
diff --git a/build_runner/lib/build_runner.dart b/build_runner/lib/build_runner.dart
deleted file mode 100644
index e4ce00d..0000000
--- a/build_runner/lib/build_runner.dart
+++ /dev/null
@@ -1,6 +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.
-
-export 'src/daemon/constants.dart' show assetServerPort;
-export 'src/entrypoint/run.dart' show run;
diff --git a/build_runner/lib/build_script_generate.dart b/build_runner/lib/build_script_generate.dart
deleted file mode 100644
index ee76280..0000000
--- a/build_runner/lib/build_script_generate.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-export 'src/build_script_generate/build_script_generate.dart'
-    show generateBuildScript, scriptLocation;
diff --git a/build_runner/lib/src/build_script_generate/bootstrap.dart b/build_runner/lib/src/build_script_generate/bootstrap.dart
deleted file mode 100644
index 3426822..0000000
--- a/build_runner/lib/src/build_script_generate/bootstrap.dart
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:isolate';
-
-import 'package:build_runner/src/build_script_generate/build_script_generate.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-import 'package:stack_trace/stack_trace.dart';
-
-final _logger = Logger('Bootstrap');
-
-/// Generates the build script, snapshots it if needed, and runs it.
-///
-/// Will retry once on [IsolateSpawnException]s to handle SDK updates.
-///
-/// Returns the exit code from running the build script.
-///
-/// If an exit code of 75 is returned, this function should be re-ran.
-Future<int> generateAndRun(List<String> args, {Logger logger}) async {
-  logger ??= _logger;
-  ReceivePort exitPort;
-  ReceivePort errorPort;
-  ReceivePort messagePort;
-  StreamSubscription errorListener;
-  int scriptExitCode;
-
-  var tryCount = 0;
-  var succeeded = false;
-  while (tryCount < 2 && !succeeded) {
-    tryCount++;
-    exitPort?.close();
-    errorPort?.close();
-    messagePort?.close();
-    await errorListener?.cancel();
-
-    try {
-      var buildScript = File(scriptLocation);
-      var oldContents = '';
-      if (buildScript.existsSync()) {
-        oldContents = buildScript.readAsStringSync();
-      }
-      var newContents = await generateBuildScript();
-      // Only trigger a build script update if necessary.
-      if (newContents != oldContents) {
-        buildScript
-          ..createSync(recursive: true)
-          ..writeAsStringSync(newContents);
-      }
-    } on CannotBuildException {
-      return ExitCode.config.code;
-    }
-
-    scriptExitCode = await _createSnapshotIfNeeded(logger);
-    if (scriptExitCode != 0) return scriptExitCode;
-
-    exitPort = ReceivePort();
-    errorPort = ReceivePort();
-    messagePort = ReceivePort();
-    errorListener = errorPort.listen((e) {
-      final error = e[0];
-      final trace = e[1] as String;
-      stderr
-        ..writeln('\n\nYou have hit a bug in build_runner')
-        ..writeln('Please file an issue with reproduction steps at '
-            'https://github.com/dart-lang/build/issues\n\n')
-        ..writeln(error)
-        ..writeln(Trace.parse(trace).terse);
-      if (scriptExitCode == 0) scriptExitCode = 1;
-    });
-    try {
-      await Isolate.spawnUri(Uri.file(p.absolute(scriptSnapshotLocation)), args,
-          messagePort.sendPort,
-          errorsAreFatal: true,
-          onExit: exitPort.sendPort,
-          onError: errorPort.sendPort);
-      succeeded = true;
-    } on IsolateSpawnException catch (e) {
-      if (tryCount > 1) {
-        logger.severe(
-            'Failed to spawn build script after retry. '
-            'This is likely due to a misconfigured builder definition. '
-            'See the generated script at $scriptLocation to find errors.',
-            e);
-        messagePort.sendPort.send(ExitCode.config.code);
-        exitPort.sendPort.send(null);
-      } else {
-        logger.warning(
-            'Error spawning build script isolate, this is likely due to a Dart '
-            'SDK update. Deleting snapshot and retrying...');
-      }
-      await File(scriptSnapshotLocation).delete();
-    }
-  }
-
-  StreamSubscription exitCodeListener;
-  exitCodeListener = messagePort.listen((isolateExitCode) {
-    if (isolateExitCode is int) {
-      scriptExitCode = isolateExitCode;
-    } else {
-      throw StateError(
-          'Bad response from isolate, expected an exit code but got '
-          '$isolateExitCode');
-    }
-    exitCodeListener.cancel();
-    exitCodeListener = null;
-  });
-  await exitPort.first;
-  await errorListener.cancel();
-  await exitCodeListener?.cancel();
-
-  return scriptExitCode;
-}
-
-/// Creates a script snapshot for the build script in necessary.
-///
-/// A snapshot is generated if:
-///
-/// - It doesn't exist currently
-/// - Either build_runner or build_daemon point at a different location than
-///   they used to, see https://github.com/dart-lang/build/issues/1929.
-///
-/// Returns zero for success or a number for failure which should be set to the
-/// exit code.
-Future<int> _createSnapshotIfNeeded(Logger logger) async {
-  var assetGraphFile = File(assetGraphPathFor(scriptSnapshotLocation));
-  var snapshotFile = File(scriptSnapshotLocation);
-
-  if (await snapshotFile.exists()) {
-    // If we failed to serialize an asset graph for the snapshot, then we don't
-    // want to re-use it because we can't check if it is up to date.
-    if (!await assetGraphFile.exists()) {
-      await snapshotFile.delete();
-      logger.warning('Deleted previous snapshot due to missing asset graph.');
-    } else if (!await _checkImportantPackageDeps()) {
-      await snapshotFile.delete();
-      logger.warning('Deleted previous snapshot due to core package update');
-    }
-  }
-
-  String stderr;
-  if (!await snapshotFile.exists()) {
-    var mode = stdin.hasTerminal
-        ? ProcessStartMode.normal
-        : ProcessStartMode.detachedWithStdio;
-    await logTimedAsync(logger, 'Creating build script snapshot...', () async {
-      var snapshot = await Process.start(Platform.executable,
-          ['--snapshot=$scriptSnapshotLocation', scriptLocation],
-          mode: mode);
-      stderr = (await snapshot.stderr
-              .transform(utf8.decoder)
-              .transform(LineSplitter())
-              .toList())
-          .join('');
-    });
-    if (!await snapshotFile.exists()) {
-      logger.severe('Failed to snapshot build script $scriptLocation.\n'
-          'This is likely caused by a misconfigured builder definition.');
-      if (stderr.isNotEmpty) {
-        logger.severe(stderr);
-      }
-      return ExitCode.config.code;
-    }
-    // Create _previousLocationsFile.
-    await _checkImportantPackageDeps();
-  }
-  return 0;
-}
-
-const _importantPackages = [
-  'build_daemon',
-  'build_runner',
-];
-final _previousLocationsFile = File(
-    p.url.join(p.url.dirname(scriptSnapshotLocation), '.packageLocations'));
-
-/// Returns whether the [_importantPackages] are all pointing at same locations
-/// from the previous run.
-///
-/// Also updates the [_previousLocationsFile] with the new locations if not.
-///
-/// This is used to detect potential changes to the user facing api and
-/// pre-emptively resolve them by resnapshotting, see
-/// https://github.com/dart-lang/build/issues/1929.
-Future<bool> _checkImportantPackageDeps() async {
-  var currentLocations = await Future.wait(_importantPackages.map((pkg) =>
-      Isolate.resolvePackageUri(
-          Uri(scheme: 'package', path: '$pkg/fake.dart'))));
-  var currentLocationsContent = currentLocations.join('\n');
-
-  if (!_previousLocationsFile.existsSync()) {
-    _logger.fine('Core package locations file does not exist');
-    _previousLocationsFile.writeAsStringSync(currentLocationsContent);
-    return false;
-  }
-
-  if (currentLocationsContent != _previousLocationsFile.readAsStringSync()) {
-    _logger.fine('Core packages locations have changed');
-    _previousLocationsFile.writeAsStringSync(currentLocationsContent);
-    return false;
-  }
-
-  return true;
-}
diff --git a/build_runner/lib/src/build_script_generate/build_script_generate.dart b/build_runner/lib/src/build_script_generate/build_script_generate.dart
deleted file mode 100644
index b06e2ba..0000000
--- a/build_runner/lib/src/build_script_generate/build_script_generate.dart
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart' show BuilderOptions;
-import 'package:build_config/build_config.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-import 'package:graphs/graphs.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import '../package_graph/build_config_overrides.dart';
-import 'builder_ordering.dart';
-
-const scriptLocation = '$entryPointDir/build.dart';
-const scriptSnapshotLocation = '$scriptLocation.snapshot';
-
-final _log = Logger('Entrypoint');
-
-Future<String> generateBuildScript() =>
-    logTimedAsync(_log, 'Generating build script', _generateBuildScript);
-
-Future<String> _generateBuildScript() async {
-  final builders = await _findBuilderApplications();
-  final library = Library((b) => b.body.addAll([
-        literalList(
-                builders,
-                refer('BuilderApplication',
-                    'package:build_runner_core/build_runner_core.dart'))
-            .assignFinal('_builders')
-            .statement,
-        _main()
-      ]));
-  final emitter = DartEmitter(Allocator.simplePrefixing());
-  try {
-    return DartFormatter().format('''
-      // ignore_for_file: directives_ordering
-
-      ${library.accept(emitter)}''');
-  } on FormatterException {
-    _log.severe('Generated build script could not be parsed.\n'
-        'This is likely caused by a misconfigured builder definition.');
-    throw CannotBuildException();
-  }
-}
-
-/// Finds expressions to create all the `BuilderApplication` instances that
-/// should be applied packages in the build.
-///
-/// Adds `apply` expressions based on the BuildefDefinitions from any package
-/// which has a `build.yaml`.
-Future<Iterable<Expression>> _findBuilderApplications() async {
-  final builderApplications = <Expression>[];
-  final packageGraph = PackageGraph.forThisPackage();
-  final orderedPackages = stronglyConnectedComponents<PackageNode>(
-    [packageGraph.root],
-    (node) => node.dependencies,
-    equals: (a, b) => a.name == b.name,
-    hashCode: (n) => n.name.hashCode,
-  ).expand((c) => c);
-  final buildConfigOverrides =
-      await findBuildConfigOverrides(packageGraph, null);
-  Future<BuildConfig> _packageBuildConfig(PackageNode package) async {
-    if (buildConfigOverrides.containsKey(package.name)) {
-      return buildConfigOverrides[package.name];
-    }
-    try {
-      return await BuildConfig.fromBuildConfigDir(
-          package.name, package.dependencies.map((n) => n.name), package.path);
-    } on ArgumentError catch (_) {
-      // During the build an error will be logged.
-      return BuildConfig.useDefault(
-          package.name, package.dependencies.map((n) => n.name));
-    }
-  }
-
-  bool _isValidDefinition(dynamic definition) {
-    // Filter out builderDefinitions with relative imports that aren't
-    // from the root package, because they will never work.
-    if (definition.import.startsWith('package:') as bool) return true;
-    return definition.package == packageGraph.root.name;
-  }
-
-  final orderedConfigs =
-      await Future.wait(orderedPackages.map(_packageBuildConfig));
-  final builderDefinitions = orderedConfigs
-      .expand((c) => c.builderDefinitions.values)
-      .where(_isValidDefinition);
-
-  final orderedBuilders = findBuilderOrder(builderDefinitions).toList();
-  builderApplications.addAll(orderedBuilders.map(_applyBuilder));
-
-  final postProcessBuilderDefinitions = orderedConfigs
-      .expand((c) => c.postProcessBuilderDefinitions.values)
-      .where(_isValidDefinition);
-  builderApplications
-      .addAll(postProcessBuilderDefinitions.map(_applyPostProcessBuilder));
-
-  return builderApplications;
-}
-
-/// A method forwarding to `run`.
-Method _main() => Method((b) => b
-  ..name = 'main'
-  ..returns = refer('void')
-  ..modifier = MethodModifier.async
-  ..requiredParameters.add(Parameter((b) => b
-    ..name = 'args'
-    ..type = TypeReference((b) => b
-      ..symbol = 'List'
-      ..types.add(refer('String')))))
-  ..optionalParameters.add(Parameter((b) => b
-    ..name = 'sendPort'
-    ..type = refer('SendPort', 'dart:isolate')))
-  ..body = Block.of([
-    refer('run', 'package:build_runner/build_runner.dart')
-        .call([refer('args'), refer('_builders')])
-        .awaited
-        .assignVar('result')
-        .statement,
-    refer('sendPort')
-        .nullSafeProperty('send')
-        .call([refer('result')]).statement,
-    refer('exitCode', 'dart:io').assign(refer('result')).statement,
-  ]));
-
-/// An expression calling `apply` with appropriate setup for a Builder.
-Expression _applyBuilder(BuilderDefinition definition) {
-  final namedArgs = <String, Expression>{};
-  if (definition.isOptional) {
-    namedArgs['isOptional'] = literalTrue;
-  }
-  if (definition.buildTo == BuildTo.cache) {
-    namedArgs['hideOutput'] = literalTrue;
-  } else {
-    namedArgs['hideOutput'] = literalFalse;
-  }
-  if (!identical(definition.defaults?.generateFor, InputSet.anything)) {
-    final inputSetArgs = <String, Expression>{};
-    if (definition.defaults.generateFor.include != null) {
-      inputSetArgs['include'] =
-          literalConstList(definition.defaults.generateFor.include);
-    }
-    if (definition.defaults.generateFor.exclude != null) {
-      inputSetArgs['exclude'] =
-          literalConstList(definition.defaults.generateFor.exclude);
-    }
-    namedArgs['defaultGenerateFor'] =
-        refer('InputSet', 'package:build_config/build_config.dart')
-            .constInstance([], inputSetArgs);
-  }
-  if (definition.defaults?.options?.isNotEmpty ?? false) {
-    namedArgs['defaultOptions'] =
-        _constructBuilderOptions(definition.defaults.options);
-  }
-  if (definition.defaults?.devOptions?.isNotEmpty ?? false) {
-    namedArgs['defaultDevOptions'] =
-        _constructBuilderOptions(definition.defaults.devOptions);
-  }
-  if (definition.defaults?.releaseOptions?.isNotEmpty ?? false) {
-    namedArgs['defaultReleaseOptions'] =
-        _constructBuilderOptions(definition.defaults.releaseOptions);
-  }
-  if (definition.appliesBuilders.isNotEmpty) {
-    namedArgs['appliesBuilders'] = literalList(definition.appliesBuilders);
-  }
-  var import = _buildScriptImport(definition.import);
-  return refer('apply', 'package:build_runner_core/build_runner_core.dart')
-      .call([
-    literalString(definition.key),
-    literalList(
-        definition.builderFactories.map((f) => refer(f, import)).toList()),
-    _findToExpression(definition),
-  ], namedArgs);
-}
-
-/// An expression calling `applyPostProcess` with appropriate setup for a
-/// PostProcessBuilder.
-Expression _applyPostProcessBuilder(PostProcessBuilderDefinition definition) {
-  final namedArgs = <String, Expression>{};
-  if (definition.defaults?.generateFor != null) {
-    final inputSetArgs = <String, Expression>{};
-    if (definition.defaults.generateFor.include != null) {
-      inputSetArgs['include'] =
-          literalConstList(definition.defaults.generateFor.include);
-    }
-    if (definition.defaults.generateFor.exclude != null) {
-      inputSetArgs['exclude'] =
-          literalConstList(definition.defaults.generateFor.exclude);
-    }
-    if (definition.defaults?.options?.isNotEmpty ?? false) {
-      namedArgs['defaultOptions'] =
-          _constructBuilderOptions(definition.defaults.options);
-    }
-    if (definition.defaults?.devOptions?.isNotEmpty ?? false) {
-      namedArgs['defaultDevOptions'] =
-          _constructBuilderOptions(definition.defaults.devOptions);
-    }
-    if (definition.defaults?.releaseOptions?.isNotEmpty ?? false) {
-      namedArgs['defaultReleaseOptions'] =
-          _constructBuilderOptions(definition.defaults.releaseOptions);
-    }
-    namedArgs['defaultGenerateFor'] =
-        refer('InputSet', 'package:build_config/build_config.dart')
-            .constInstance([], inputSetArgs);
-  }
-  var import = _buildScriptImport(definition.import);
-  return refer('applyPostProcess',
-          'package:build_runner_core/build_runner_core.dart')
-      .call([
-    literalString(definition.key),
-    refer(definition.builderFactory, import),
-  ], namedArgs);
-}
-
-/// Returns the actual import to put in the generated script based on an import
-/// found in the build.yaml.
-String _buildScriptImport(String import) {
-  if (import.startsWith('package:')) {
-    return import;
-  } else if (import.startsWith('../') || import.startsWith('/')) {
-    _log.warning('The `../` import syntax in build.yaml is now deprecated, '
-        'instead do a normal relative import as if it was from the root of '
-        'the package. Found `$import` in your `build.yaml` file.');
-    return import;
-  } else {
-    return p.url.relative(import, from: p.url.dirname(scriptLocation));
-  }
-}
-
-Expression _findToExpression(BuilderDefinition definition) {
-  switch (definition.autoApply) {
-    case AutoApply.none:
-      return refer('toNoneByDefault',
-              'package:build_runner_core/build_runner_core.dart')
-          .call([]);
-    case AutoApply.dependents:
-      return refer('toDependentsOf',
-              'package:build_runner_core/build_runner_core.dart')
-          .call([literalString(definition.package)]);
-    case AutoApply.allPackages:
-      return refer('toAllPackages',
-              'package:build_runner_core/build_runner_core.dart')
-          .call([]);
-    case AutoApply.rootPackage:
-      return refer('toRoot', 'package:build_runner_core/build_runner_core.dart')
-          .call([]);
-  }
-  throw ArgumentError('Unhandled AutoApply type: ${definition.autoApply}');
-}
-
-/// An expression creating a [BuilderOptions] from a json string.
-Expression _constructBuilderOptions(Map<String, dynamic> options) =>
-    refer('BuilderOptions', 'package:build/build.dart')
-        .newInstance([literalMap(options)]);
diff --git a/build_runner/lib/src/build_script_generate/builder_ordering.dart b/build_runner/lib/src/build_script_generate/builder_ordering.dart
deleted file mode 100644
index c681697..0000000
--- a/build_runner/lib/src/build_script_generate/builder_ordering.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build_config/build_config.dart';
-import 'package:graphs/graphs.dart';
-
-/// Put [builders] into an order such that any builder which specifies
-/// [BuilderDefinition.requiredInputs] will come after any builder which
-/// produces a desired output.
-///
-/// Builders will be ordered such that their `required_inputs` and `runs_before`
-/// constraints are met, but the rest of the ordering is arbitrary.
-Iterable<BuilderDefinition> findBuilderOrder(
-    Iterable<BuilderDefinition> builders) {
-  final consistentOrderBuilders = builders.toList()
-    ..sort((a, b) => a.key.compareTo(b.key));
-  Iterable<BuilderDefinition> dependencies(BuilderDefinition parent) =>
-      consistentOrderBuilders.where((child) =>
-          _hasInputDependency(parent, child) || _mustRunBefore(parent, child));
-  var components = stronglyConnectedComponents<BuilderDefinition>(
-    consistentOrderBuilders,
-    dependencies,
-    equals: (a, b) => a.key == b.key,
-    hashCode: (b) => b.key.hashCode,
-  );
-  return components.map((component) {
-    if (component.length > 1) {
-      throw ArgumentError('Required input cycle for ${component.toList()}');
-    }
-    return component.single;
-  }).toList();
-}
-
-/// Whether [parent] has a `required_input` that wants to read outputs produced
-/// by [child].
-bool _hasInputDependency(BuilderDefinition parent, BuilderDefinition child) {
-  final childOutputs = child.buildExtensions.values.expand((v) => v).toSet();
-  return parent.requiredInputs
-      .any((input) => childOutputs.any((output) => output.endsWith(input)));
-}
-
-/// Whether [child] specifies that it wants to run before [parent].
-bool _mustRunBefore(BuilderDefinition parent, BuilderDefinition child) =>
-    child.runsBefore.contains(parent.key);
diff --git a/build_runner/lib/src/daemon/asset_server.dart b/build_runner/lib/src/daemon/asset_server.dart
deleted file mode 100644
index 524a7d6..0000000
--- a/build_runner/lib/src/daemon/asset_server.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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:http_multi_server/http_multi_server.dart';
-import 'package:shelf/shelf.dart';
-import 'package:shelf/shelf_io.dart' as shelf_io;
-
-import '../server/server.dart';
-import 'daemon_builder.dart';
-
-class AssetServer {
-  final HttpServer _server;
-
-  AssetServer._(this._server);
-
-  int get port => _server.port;
-
-  Future<void> stop() => _server.close(force: true);
-
-  static Future<AssetServer> run(
-    BuildRunnerDaemonBuilder builder,
-    String rootPackage,
-  ) async {
-    var server = await HttpMultiServer.loopback(0);
-    var cascade = Cascade().add((_) async {
-      await builder.building;
-      return Response.notFound('');
-    }).add(AssetHandler(builder.reader, rootPackage).handle);
-    shelf_io.serveRequests(server, cascade.handler);
-    return AssetServer._(server);
-  }
-}
diff --git a/build_runner/lib/src/daemon/change_providers.dart b/build_runner/lib/src/daemon/change_providers.dart
deleted file mode 100644
index 8d52c0a..0000000
--- a/build_runner/lib/src/daemon/change_providers.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build_daemon/change_provider.dart';
-import 'package:build_runner_core/src/generate/build_definition.dart';
-import 'package:watcher/src/watch_event.dart';
-
-/// Continually updates the [changes] stream as watch events are seen on the
-/// input stream.
-///
-/// The [collectChanges] method is a no-op for this implementation.
-class AutoChangeProvider implements ChangeProvider {
-  @override
-  final Stream<List<WatchEvent>> changes;
-
-  AutoChangeProvider(this.changes);
-
-  @override
-  Future<List<WatchEvent>> collectChanges() async => [];
-}
-
-/// Computes changes with a file scan when requested by a call to
-/// [collectChanges].
-class ManualChangeProvider implements ChangeProvider {
-  final AssetTracker _assetTracker;
-
-  ManualChangeProvider(this._assetTracker);
-
-  @override
-  Future<List<WatchEvent>> collectChanges() async {
-    var updates = await _assetTracker.collectChanges();
-    return List.of(updates.entries
-        .map((entry) => WatchEvent(entry.value, '${entry.key}')));
-  }
-
-  @override
-  Stream<List<WatchEvent>> get changes => Stream.empty();
-}
diff --git a/build_runner/lib/src/daemon/constants.dart b/build_runner/lib/src/daemon/constants.dart
deleted file mode 100644
index 956fcea..0000000
--- a/build_runner/lib/src/daemon/constants.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:build_daemon/constants.dart';
-import 'package:path/path.dart' as p;
-
-String assetServerPortFilePath(String workingDirectory) =>
-    p.join(daemonWorkspace(workingDirectory), '.asset_server_port');
-
-/// Returns the port of the daemon asset server.
-int assetServerPort(String workingDirectory) {
-  var portFile = File(assetServerPortFilePath(workingDirectory));
-  if (!portFile.existsSync()) {
-    throw Exception('Unable to read daemon asset port file.');
-  }
-  return int.parse(portFile.readAsStringSync());
-}
diff --git a/build_runner/lib/src/daemon/daemon_builder.dart b/build_runner/lib/src/daemon/daemon_builder.dart
deleted file mode 100644
index b9104af..0000000
--- a/build_runner/lib/src/daemon/daemon_builder.dart
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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:build/build.dart';
-import 'package:build_daemon/change_provider.dart';
-import 'package:build_daemon/constants.dart';
-import 'package:build_daemon/daemon_builder.dart';
-import 'package:build_daemon/data/build_status.dart';
-import 'package:build_daemon/data/build_target.dart' hide OutputLocation;
-import 'package:build_daemon/data/server_log.dart';
-import 'package:build_runner/src/entrypoint/options.dart';
-import 'package:build_runner/src/package_graph/build_config_overrides.dart';
-import 'package:build_runner/src/watcher/asset_change.dart';
-import 'package:build_runner/src/watcher/change_filter.dart';
-import 'package:build_runner/src/watcher/collect_changes.dart';
-import 'package:build_runner/src/watcher/delete_writer.dart';
-import 'package:build_runner/src/watcher/graph_watcher.dart';
-import 'package:build_runner/src/watcher/node_watcher.dart';
-import 'package:build_runner_core/build_runner_core.dart'
-    hide BuildResult, BuildStatus;
-import 'package:build_runner_core/build_runner_core.dart' as core
-    show BuildStatus;
-import 'package:build_runner_core/src/generate/build_definition.dart';
-import 'package:build_runner_core/src/generate/build_impl.dart';
-import 'package:stream_transform/stream_transform.dart';
-import 'package:watcher/watcher.dart';
-
-import 'change_providers.dart';
-
-/// A Daemon Builder that uses build_runner_core for building.
-class BuildRunnerDaemonBuilder implements DaemonBuilder {
-  final _buildResults = StreamController<BuildResults>();
-
-  final BuildImpl _builder;
-  final BuildOptions _buildOptions;
-  final StreamController<ServerLog> _outputStreamController;
-  final ChangeProvider changeProvider;
-
-  Completer<Null> _buildingCompleter;
-
-  @override
-  final Stream<ServerLog> logs;
-
-  BuildRunnerDaemonBuilder._(
-    this._builder,
-    this._buildOptions,
-    this._outputStreamController,
-    this.changeProvider,
-  ) : logs = _outputStreamController.stream.asBroadcastStream();
-
-  /// Waits for a running build to complete before returning.
-  ///
-  /// If there is no running build, it will return immediately.
-  Future<void> get building => _buildingCompleter?.future;
-
-  @override
-  Stream<BuildResults> get builds => _buildResults.stream;
-
-  FinalizedReader get reader => _builder.finalizedReader;
-
-  final _buildScriptUpdateCompleter = Completer();
-  Future<void> get buildScriptUpdated => _buildScriptUpdateCompleter.future;
-
-  @override
-  Future<void> build(
-      Set<BuildTarget> targets, Iterable<WatchEvent> fileChanges) async {
-    var defaultTargets = targets.cast<DefaultBuildTarget>();
-    var changes = fileChanges
-        .map<AssetChange>(
-            (change) => AssetChange(AssetId.parse(change.path), change.type))
-        .toList();
-    if (!_buildOptions.skipBuildScriptCheck &&
-        _builder.buildScriptUpdates.hasBeenUpdated(
-            changes.map<AssetId>((change) => change.id).toSet())) {
-      _buildScriptUpdateCompleter.complete();
-      return;
-    }
-    var targetNames = targets.map((t) => t.target).toSet();
-    _logMessage(Level.INFO, 'About to build ${targetNames.toList()}...');
-    _signalStart(targetNames);
-    var results = <BuildResult>[];
-    var buildDirs = <BuildDirectory>{};
-    var buildFilters = <BuildFilter>{};
-    for (var target in defaultTargets) {
-      OutputLocation outputLocation;
-      if (target.outputLocation != null) {
-        outputLocation = OutputLocation(target.outputLocation.output,
-            useSymlinks: target.outputLocation.useSymlinks,
-            hoist: target.outputLocation.hoist);
-      }
-      buildDirs
-          .add(BuildDirectory(target.target, outputLocation: outputLocation));
-      if (target.buildFilters != null && target.buildFilters.isNotEmpty) {
-        buildFilters.addAll([
-          for (var pattern in target.buildFilters)
-            BuildFilter.fromArg(pattern, _buildOptions.packageGraph.root.name)
-        ]);
-      } else {
-        buildFilters
-          ..add(BuildFilter.fromArg(
-              'package:*/**', _buildOptions.packageGraph.root.name))
-          ..add(BuildFilter.fromArg(
-              '${target.target}/**', _buildOptions.packageGraph.root.name));
-      }
-    }
-    try {
-      var mergedChanges = collectChanges([changes]);
-      var result = await _builder.run(mergedChanges,
-          buildDirs: buildDirs, buildFilters: buildFilters);
-      for (var target in targets) {
-        if (result.status == core.BuildStatus.success) {
-          // TODO(grouma) - Can we notify if a target was cached?
-          results.add(DefaultBuildResult((b) => b
-            ..status = BuildStatus.succeeded
-            ..target = target.target));
-        } else {
-          results.add(DefaultBuildResult((b) => b
-            ..status = BuildStatus.failed
-            // TODO(grouma) - We should forward the error messages instead.
-            // We can use the AssetGraph and FailureReporter to provide a better
-            // error message.
-            ..error = 'FailureType: ${result.failureType.exitCode}'
-            ..target = target.target));
-        }
-      }
-    } catch (e) {
-      for (var target in targets) {
-        results.add(DefaultBuildResult((b) => b
-          ..status = BuildStatus.failed
-          ..error = '$e'
-          ..target = target.target));
-      }
-      _logMessage(Level.SEVERE, 'Build Failed:\n${e.toString()}');
-    }
-    _signalEnd(results);
-  }
-
-  @override
-  Future<void> stop() async {
-    await _builder.beforeExit();
-    await _buildOptions.logListener.cancel();
-  }
-
-  void _logMessage(Level level, String message) =>
-      _outputStreamController.add(ServerLog(
-        (b) => b
-          ..message = message
-          ..level = level,
-      ));
-
-  void _signalEnd(Iterable<BuildResult> results) {
-    _buildingCompleter.complete();
-    _buildResults.add(BuildResults((b) => b..results.addAll(results)));
-  }
-
-  void _signalStart(Iterable<String> targets) {
-    _buildingCompleter = Completer();
-    var results = <BuildResult>[];
-    for (var target in targets) {
-      results.add(DefaultBuildResult((b) => b
-        ..status = BuildStatus.started
-        ..target = target));
-    }
-    _buildResults.add(BuildResults((b) => b..results.addAll(results)));
-  }
-
-  static Future<BuildRunnerDaemonBuilder> create(
-    PackageGraph packageGraph,
-    List<BuilderApplication> builders,
-    DaemonOptions daemonOptions,
-  ) async {
-    var expectedDeletes = <AssetId>{};
-    var outputStreamController = StreamController<ServerLog>();
-
-    var environment = OverrideableEnvironment(
-        IOEnvironment(packageGraph,
-            outputSymlinksOnly: daemonOptions.outputSymlinksOnly),
-        onLog: (record) {
-      outputStreamController.add(ServerLog.fromLogRecord(record));
-    });
-
-    var daemonEnvironment = OverrideableEnvironment(environment,
-        writer: OnDeleteWriter(environment.writer, expectedDeletes.add));
-
-    var logSubscription =
-        LogSubscription(environment, verbose: daemonOptions.verbose);
-
-    var overrideBuildConfig =
-        await findBuildConfigOverrides(packageGraph, daemonOptions.configKey);
-
-    var buildOptions = await BuildOptions.create(
-      logSubscription,
-      packageGraph: packageGraph,
-      deleteFilesByDefault: daemonOptions.deleteFilesByDefault,
-      overrideBuildConfig: overrideBuildConfig,
-      skipBuildScriptCheck: daemonOptions.skipBuildScriptCheck,
-      enableLowResourcesMode: daemonOptions.enableLowResourcesMode,
-      trackPerformance: daemonOptions.trackPerformance,
-      logPerformanceDir: daemonOptions.logPerformanceDir,
-    );
-
-    var builder = await BuildImpl.create(buildOptions, daemonEnvironment,
-        builders, daemonOptions.builderConfigOverrides,
-        isReleaseBuild: daemonOptions.isReleaseBuild);
-
-    // Only actually used for the AutoChangeProvider.
-    Stream<List<WatchEvent>> graphEvents() => PackageGraphWatcher(packageGraph,
-            watch: (node) => PackageNodeWatcher(node,
-                watch: daemonOptions.directoryWatcherFactory))
-        .watch()
-        .where((change) => shouldProcess(
-              change,
-              builder.assetGraph,
-              buildOptions,
-              // Assume we will create an outputDir.
-              true,
-              expectedDeletes,
-            ))
-        .map((data) => WatchEvent(data.type, '${data.id}'))
-        .debounceBuffer(buildOptions.debounceDelay);
-
-    var changeProvider = daemonOptions.buildMode == BuildMode.Auto
-        ? AutoChangeProvider(graphEvents())
-        : ManualChangeProvider(AssetTracker(builder.assetGraph,
-            daemonEnvironment.reader, buildOptions.targetGraph));
-
-    return BuildRunnerDaemonBuilder._(
-        builder, buildOptions, outputStreamController, changeProvider);
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/base_command.dart b/build_runner/lib/src/entrypoint/base_command.dart
deleted file mode 100644
index 27a8873..0000000
--- a/build_runner/lib/src/entrypoint/base_command.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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:io';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:logging/logging.dart';
-
-import 'options.dart';
-import 'runner.dart';
-
-final lineLength = stdout.hasTerminal ? stdout.terminalColumns : 80;
-
-abstract class BuildRunnerCommand extends Command<int> {
-  Logger get logger => Logger(name);
-
-  List<BuilderApplication> get builderApplications =>
-      (runner as BuildCommandRunner).builderApplications;
-
-  PackageGraph get packageGraph => (runner as BuildCommandRunner).packageGraph;
-
-  BuildRunnerCommand({bool symlinksDefault}) {
-    _addBaseFlags(symlinksDefault ?? false);
-  }
-
-  @override
-  final argParser = ArgParser(usageLineLength: lineLength);
-
-  void _addBaseFlags(bool symlinksDefault) {
-    argParser
-      ..addFlag(deleteFilesByDefaultOption,
-          help:
-              'By default, the user will be prompted to delete any files which '
-              'already exist but were not known to be generated by this '
-              'specific build script.\n\n'
-              'Enabling this option skips the prompt and deletes the files. '
-              'This should typically be used in continues integration servers '
-              'and tests, but not otherwise.',
-          negatable: false,
-          defaultsTo: false)
-      ..addFlag(lowResourcesModeOption,
-          help: 'Reduce the amount of memory consumed by the build process. '
-              'This will slow down builds but allow them to progress in '
-              'resource constrained environments.',
-          negatable: false,
-          defaultsTo: false)
-      ..addOption(configOption,
-          help: 'Read `build.<name>.yaml` instead of the default `build.yaml`',
-          abbr: 'c')
-      ..addFlag('fail-on-severe',
-          help: 'Deprecated argument - always enabled',
-          negatable: true,
-          defaultsTo: true,
-          hide: true)
-      ..addFlag(trackPerformanceOption,
-          help: r'Enables performance tracking and the /$perf page.',
-          negatable: true,
-          defaultsTo: false)
-      ..addOption(logPerformanceOption,
-          help: 'A directory to write performance logs to, must be in the '
-              'current package. Implies `--track-performance`.')
-      ..addFlag(skipBuildScriptCheckOption,
-          help: r'Skip validation for the digests of files imported by the '
-              'build script.',
-          hide: true,
-          defaultsTo: false)
-      ..addMultiOption(outputOption,
-          help: 'A directory to copy the fully built package to. Or a mapping '
-              'from a top-level directory in the package to the directory to '
-              'write a filtered build output to. For example "web:deploy".',
-          abbr: 'o')
-      ..addFlag(verboseOption,
-          abbr: 'v',
-          defaultsTo: false,
-          negatable: false,
-          help: 'Enables verbose logging.')
-      ..addFlag(releaseOption,
-          abbr: 'r',
-          defaultsTo: false,
-          negatable: true,
-          help: 'Build with release mode defaults for builders.')
-      ..addMultiOption(defineOption,
-          splitCommas: false,
-          help: 'Sets the global `options` config for a builder by key.')
-      ..addFlag(symlinkOption,
-          defaultsTo: symlinksDefault,
-          negatable: true,
-          help: 'Symlink files in the output directories, instead of copying.')
-      ..addMultiOption(buildFilterOption,
-          help: 'An explicit filter of files to build. Relative paths and '
-              '`package:` uris are supported, including glob syntax for paths '
-              'portions (but not package names).\n\n'
-              'If multiple filters are applied then outputs matching any filter '
-              'will be built (they do not need to match all filters).');
-  }
-
-  /// Must be called inside [run] so that [argResults] is non-null.
-  ///
-  /// You may override this to return more specific options if desired, but they
-  /// must extend [SharedOptions].
-  SharedOptions readOptions() {
-    return SharedOptions.fromParsedArgs(
-        argResults, argResults.rest, packageGraph.root.name, this);
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/build.dart b/build_runner/lib/src/entrypoint/build.dart
deleted file mode 100644
index 2b983ee..0000000
--- a/build_runner/lib/src/entrypoint/build.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-
-import '../generate/build.dart';
-import 'base_command.dart';
-
-/// A command that does a single build and then exits.
-class BuildCommand extends BuildRunnerCommand {
-  @override
-  String get invocation => '${super.invocation} [directories]';
-
-  @override
-  String get name => 'build';
-
-  @override
-  String get description =>
-      'Performs a single build on the specified targets and then exits.';
-
-  @override
-  Future<int> run() async {
-    var options = readOptions();
-    var result = await build(
-      builderApplications,
-      buildFilters: options.buildFilters,
-      deleteFilesByDefault: options.deleteFilesByDefault,
-      enableLowResourcesMode: options.enableLowResourcesMode,
-      configKey: options.configKey,
-      buildDirs: options.buildDirs,
-      outputSymlinksOnly: options.outputSymlinksOnly,
-      packageGraph: packageGraph,
-      verbose: options.verbose,
-      builderConfigOverrides: options.builderConfigOverrides,
-      isReleaseBuild: options.isReleaseBuild,
-      trackPerformance: options.trackPerformance,
-      skipBuildScriptCheck: options.skipBuildScriptCheck,
-      logPerformanceDir: options.logPerformanceDir,
-    );
-    if (result.status == BuildStatus.success) {
-      return ExitCode.success.code;
-    } else {
-      return result.failureType.exitCode;
-    }
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/clean.dart b/build_runner/lib/src/entrypoint/clean.dart
deleted file mode 100644
index 9aa4fba..0000000
--- a/build_runner/lib/src/entrypoint/clean.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-import 'package:logging/logging.dart';
-
-import '../logging/std_io_logging.dart';
-import 'base_command.dart';
-
-class CleanCommand extends Command<int> {
-  @override
-  final argParser = ArgParser(usageLineLength: lineLength);
-
-  @override
-  String get name => 'clean';
-
-  @override
-  String get description =>
-      'Cleans up output from previous builds. Does not clean up --output '
-      'directories.';
-
-  Logger get logger => Logger(name);
-
-  @override
-  Future<int> run() async {
-    var logSubscription = Logger.root.onRecord.listen(stdIOLogListener());
-    await cleanFor(assetGraphPath, logger);
-    await logSubscription.cancel();
-    return 0;
-  }
-}
-
-Future<void> cleanFor(String assetGraphPath, Logger logger) async {
-  logger.warning('Deleting cache and generated source files.\n'
-      'This shouldn\'t be necessary for most applications, unless you have '
-      'made intentional edits to generated files (i.e. for testing). '
-      'Consider filing a bug at '
-      'https://github.com/dart-lang/build/issues/new if you are using this '
-      'to work around an apparent (and reproducible) bug.');
-
-  await logTimedAsync(logger, 'Cleaning up source outputs', () async {
-    var assetGraphFile = File(assetGraphPath);
-    if (!assetGraphFile.existsSync()) {
-      logger.warning('No asset graph found. '
-          'Skipping cleanup of generated files in source directories.');
-      return;
-    }
-    AssetGraph assetGraph;
-    try {
-      assetGraph = AssetGraph.deserialize(await assetGraphFile.readAsBytes());
-    } catch (_) {
-      logger.warning('Failed to deserialize AssetGraph. '
-          'Skipping cleanup of generated files in source directories.');
-      return;
-    }
-    var packageGraph = PackageGraph.forThisPackage();
-    await _cleanUpSourceOutputs(assetGraph, packageGraph);
-  });
-
-  await logTimedAsync(
-      logger, 'Cleaning up cache directory', _cleanUpGeneratedDirectory);
-}
-
-Future<void> _cleanUpSourceOutputs(
-    AssetGraph assetGraph, PackageGraph packageGraph) async {
-  var writer = FileBasedAssetWriter(packageGraph);
-  for (var id in assetGraph.outputs) {
-    if (id.package != packageGraph.root.name) continue;
-    var node = assetGraph.get(id) as GeneratedAssetNode;
-    if (node.wasOutput) {
-      // Note that this does a file.exists check in the root package and
-      // only tries to delete the file if it exists. This way we only
-      // actually delete to_source outputs, without reading in the build
-      // actions.
-      await writer.delete(id);
-    }
-  }
-}
-
-Future<void> _cleanUpGeneratedDirectory() async {
-  var generatedDir = Directory(cacheDir);
-  if (await generatedDir.exists()) {
-    await generatedDir.delete(recursive: true);
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/daemon.dart b/build_runner/lib/src/entrypoint/daemon.dart
deleted file mode 100644
index b7ef05b..0000000
--- a/build_runner/lib/src/entrypoint/daemon.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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:build_daemon/constants.dart';
-import 'package:build_daemon/daemon.dart';
-import 'package:build_daemon/data/serializers.dart';
-import 'package:build_daemon/data/server_log.dart';
-import 'package:build_runner/src/daemon/constants.dart';
-import 'package:logging/logging.dart' hide Level;
-import 'package:pedantic/pedantic.dart';
-
-import '../daemon/asset_server.dart';
-import '../daemon/daemon_builder.dart';
-import 'options.dart';
-import 'watch.dart';
-
-/// A command that starts the Build Daemon.
-class DaemonCommand extends WatchCommand {
-  @override
-  String get description => 'Starts the build daemon.';
-
-  @override
-  bool get hidden => true;
-
-  @override
-  String get name => 'daemon';
-
-  DaemonCommand() {
-    argParser.addOption(buildModeFlag,
-        help: 'Specify the build mode of the daemon, e.g. auto or manual.',
-        defaultsTo: 'BuildMode.Auto');
-  }
-
-  @override
-  DaemonOptions readOptions() => DaemonOptions.fromParsedArgs(
-      argResults, argResults.rest, packageGraph.root.name, this);
-
-  @override
-  Future<int> run() async {
-    var workingDirectory = Directory.current.path;
-    var options = readOptions();
-    var daemon = Daemon(workingDirectory);
-    var requestedOptions = argResults.arguments.toSet();
-    if (!daemon.hasLock) {
-      var runningOptions = await daemon.currentOptions();
-      var version = await daemon.runningVersion();
-      if (version != currentVersion) {
-        stdout
-          ..writeln('Running Version: $version')
-          ..writeln('Current Version: $currentVersion')
-          ..writeln(versionSkew);
-        return 1;
-      } else if (!(runningOptions.length == requestedOptions.length &&
-          runningOptions.containsAll(requestedOptions))) {
-        stdout
-          ..writeln('Running Options: $runningOptions')
-          ..writeln('Requested Options: $requestedOptions')
-          ..writeln(optionsSkew);
-        return 1;
-      } else {
-        stdout.writeln('Daemon is already running.');
-        print(readyToConnectLog);
-        return 0;
-      }
-    } else {
-      stdout.writeln('Starting daemon...');
-      BuildRunnerDaemonBuilder builder;
-      // Ensure we capture any logs that happen during startup.
-      //
-      // These are serialized between special `<log-record>` and `</log-record>`
-      // tags to make parsing them on stdout easier. They can have multiline
-      // strings so we can't just serialize the json on a single line.
-      var startupLogSub =
-          Logger.root.onRecord.listen((record) => stdout.writeln('''
-$logStartMarker
-${jsonEncode(serializers.serialize(ServerLog.fromLogRecord(record)))}
-$logEndMarker'''));
-      builder = await BuildRunnerDaemonBuilder.create(
-        packageGraph,
-        builderApplications,
-        options,
-      );
-      await startupLogSub.cancel();
-
-      // Forward server logs to daemon command STDIO.
-      var logSub = builder.logs.listen((log) {
-        if (log.level > Level.INFO) {
-          var buffer = StringBuffer(log.message);
-          if (log.error != null) buffer.writeln(log.error);
-          if (log.stackTrace != null) buffer.writeln(log.stackTrace);
-          stderr.writeln(buffer);
-        } else {
-          stdout.writeln(log.message);
-        }
-      });
-      var server = await AssetServer.run(builder, packageGraph.root.name);
-      File(assetServerPortFilePath(workingDirectory))
-          .writeAsStringSync('${server.port}');
-      unawaited(builder.buildScriptUpdated.then((_) async {
-        await daemon.stop(
-            message: 'Build script updated. Shutting down the Build Daemon.',
-            failureType: 75);
-      }));
-      await daemon.start(requestedOptions, builder, builder.changeProvider,
-          timeout: Duration(seconds: 60));
-      stdout.writeln(readyToConnectLog);
-      await logSub.cancel();
-      await daemon.onDone.whenComplete(() async {
-        await server.stop();
-      });
-      // Clients can disconnect from the daemon mid build.
-      // As a result we try to relinquish resources which can
-      // cause the build to hang. To ensure there are no ghost processes
-      // fast exit.
-      exit(0);
-    }
-    return 0;
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/doctor.dart b/build_runner/lib/src/entrypoint/doctor.dart
deleted file mode 100644
index c1325e4..0000000
--- a/build_runner/lib/src/entrypoint/doctor.dart
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/generate/phase.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-
-import '../logging/std_io_logging.dart';
-import '../package_graph/build_config_overrides.dart';
-import 'base_command.dart';
-
-/// A command that validates the build environment.
-class DoctorCommand extends BuildRunnerCommand {
-  @override
-  String get name => 'doctor';
-
-  @override
-  bool get hidden => true;
-
-  @override
-  String get description => 'Check for misconfiguration of the build.';
-
-  @override
-  Future<int> run() async {
-    final options = readOptions();
-    final verbose = options.verbose ?? false;
-    Logger.root.level = verbose ? Level.ALL : Level.INFO;
-    final logSubscription =
-        Logger.root.onRecord.listen(stdIOLogListener(verbose: verbose));
-
-    final config = await _loadBuilderDefinitions();
-
-    var isOk = true;
-    for (final builderApplication in builderApplications) {
-      final builderOk = _checkBuildExtensions(builderApplication, config);
-      isOk = isOk && builderOk;
-    }
-
-    if (isOk) {
-      logger.info('No problems found!\n');
-    }
-    await logSubscription.cancel();
-    return isOk ? ExitCode.success.code : ExitCode.config.code;
-  }
-
-  Future<Map<String, BuilderDefinition>> _loadBuilderDefinitions() async {
-    final packageGraph = PackageGraph.forThisPackage();
-    final buildConfigOverrides =
-        await findBuildConfigOverrides(packageGraph, null);
-    Future<BuildConfig> _packageBuildConfig(PackageNode package) async {
-      if (buildConfigOverrides.containsKey(package.name)) {
-        return buildConfigOverrides[package.name];
-      }
-      try {
-        return await BuildConfig.fromBuildConfigDir(package.name,
-            package.dependencies.map((n) => n.name), package.path);
-      } on ArgumentError catch (e) {
-        logger.severe(
-            'Failed to parse a `build.yaml` file for ${package.name}', e);
-        return BuildConfig.useDefault(
-            package.name, package.dependencies.map((n) => n.name));
-      }
-    }
-
-    final allConfig = await Future.wait(
-        packageGraph.allPackages.values.map(_packageBuildConfig));
-    final allBuilders = <String, BuilderDefinition>{};
-    for (final config in allConfig) {
-      allBuilders.addAll(config.builderDefinitions);
-    }
-    return allBuilders;
-  }
-
-  /// Returns true of [builderApplication] has sane build extension
-  /// configuration.
-  ///
-  /// If there are any problems they will be logged and `false` returned.
-  bool _checkBuildExtensions(BuilderApplication builderApplication,
-      Map<String, BuilderDefinition> config) {
-    var phases = builderApplication.buildPhaseFactories
-        .map((f) => f(PackageNode(null, null, null, isRoot: true),
-            BuilderOptions.empty, InputSet.anything, InputSet.anything, true))
-        .whereType<InBuildPhase>()
-        .toList();
-    if (phases.isEmpty) return true;
-    if (!config.containsKey(builderApplication.builderKey)) return false;
-
-    var problemFound = false;
-    var allowed = Map.of(config[builderApplication.builderKey].buildExtensions);
-    for (final phase in phases.whereType<InBuildPhase>()) {
-      final extensions = phase.builder.buildExtensions;
-      for (final extension in extensions.entries) {
-        if (!allowed.containsKey(extension.key)) {
-          logger.warning('Builder ${builderApplication.builderKey} '
-              'uses input extension ${extension.key} '
-              'which is not specified in the `build.yaml`');
-          problemFound = true;
-          continue;
-        }
-        final allowedOutputs = List.of(allowed[extension.key]);
-        for (final output in extension.value) {
-          if (!allowedOutputs.contains(output)) {
-            logger.warning('Builder ${builderApplication.builderKey} '
-                'outputs $output  from ${extension.key} '
-                'which is not specified in the `build.yaml`');
-            problemFound = true;
-          }
-          // Allow subsequent phases to use these outputs as inputs
-          if (allowedOutputs.length > 1) {
-            allowed.putIfAbsent(output, () => []).addAll(allowedOutputs);
-          }
-        }
-      }
-    }
-    return !problemFound;
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/options.dart b/build_runner/lib/src/entrypoint/options.dart
deleted file mode 100644
index ad4099d..0000000
--- a/build_runner/lib/src/entrypoint/options.dart
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_config/build_config.dart';
-import 'package:build_daemon/constants.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-import 'package:watcher/watcher.dart';
-
-import '../generate/directory_watcher_factory.dart';
-
-const buildFilterOption = 'build-filter';
-const configOption = 'config';
-const defineOption = 'define';
-const deleteFilesByDefaultOption = 'delete-conflicting-outputs';
-const failOnSevereOption = 'fail-on-severe';
-const hostnameOption = 'hostname';
-const hotReloadOption = 'hot-reload';
-const liveReloadOption = 'live-reload';
-const logPerformanceOption = 'log-performance';
-const logRequestsOption = 'log-requests';
-const lowResourcesModeOption = 'low-resources-mode';
-const outputOption = 'output';
-const releaseOption = 'release';
-const trackPerformanceOption = 'track-performance';
-const skipBuildScriptCheckOption = 'skip-build-script-check';
-const symlinkOption = 'symlink';
-const usePollingWatcherOption = 'use-polling-watcher';
-const verboseOption = 'verbose';
-
-enum BuildUpdatesOption { none, liveReload, hotReload }
-
-final _defaultWebDirs = const ['web', 'test', 'example', 'benchmark'];
-
-/// Base options that are shared among all commands.
-class SharedOptions {
-  /// A set of explicit filters for files to build.
-  ///
-  /// If provided no other files will be built that don't match these filters
-  /// unless they are an input to something matching a filter.
-  final Set<BuildFilter> buildFilters;
-
-  /// By default, the user will be prompted to delete any files which already
-  /// exist but were not generated by this specific build script.
-  ///
-  /// This option can be set to `true` to skip this prompt.
-  final bool deleteFilesByDefault;
-
-  final bool enableLowResourcesMode;
-
-  /// Read `build.$configKey.yaml` instead of `build.yaml`.
-  final String configKey;
-
-  /// A set of targets to build with their corresponding output locations.
-  final Set<BuildDirectory> buildDirs;
-
-  /// Whether or not the output directories should contain only symlinks,
-  /// or full copies of all files.
-  final bool outputSymlinksOnly;
-
-  /// Enables performance tracking and the `/$perf` page.
-  final bool trackPerformance;
-
-  /// A directory to log performance information to.
-  String logPerformanceDir;
-
-  /// Check digest of imports to the build script to invalidate the build.
-  final bool skipBuildScriptCheck;
-
-  final bool verbose;
-
-  // Global config overrides by builder.
-  //
-  // Keys are the builder keys, such as my_package|my_builder, and values
-  // represent config objects. All keys in the config will override the parsed
-  // config for that key.
-  final Map<String, Map<String, dynamic>> builderConfigOverrides;
-
-  final bool isReleaseBuild;
-
-  SharedOptions._({
-    @required this.buildFilters,
-    @required this.deleteFilesByDefault,
-    @required this.enableLowResourcesMode,
-    @required this.configKey,
-    @required this.buildDirs,
-    @required this.outputSymlinksOnly,
-    @required this.trackPerformance,
-    @required this.skipBuildScriptCheck,
-    @required this.verbose,
-    @required this.builderConfigOverrides,
-    @required this.isReleaseBuild,
-    @required this.logPerformanceDir,
-  });
-
-  factory SharedOptions.fromParsedArgs(ArgResults argResults,
-      Iterable<String> positionalArgs, String rootPackage, Command command) {
-    var buildDirs = {
-      ..._parseBuildDirs(argResults),
-      ..._parsePositionalBuildDirs(positionalArgs, command),
-    };
-    var buildFilters = _parseBuildFilters(argResults, rootPackage);
-
-    return SharedOptions._(
-      buildFilters: buildFilters,
-      deleteFilesByDefault: argResults[deleteFilesByDefaultOption] as bool,
-      enableLowResourcesMode: argResults[lowResourcesModeOption] as bool,
-      configKey: argResults[configOption] as String,
-      buildDirs: buildDirs,
-      outputSymlinksOnly: argResults[symlinkOption] as bool,
-      trackPerformance: argResults[trackPerformanceOption] as bool,
-      skipBuildScriptCheck: argResults[skipBuildScriptCheckOption] as bool,
-      verbose: argResults[verboseOption] as bool,
-      builderConfigOverrides:
-          _parseBuilderConfigOverrides(argResults[defineOption], rootPackage),
-      isReleaseBuild: argResults[releaseOption] as bool,
-      logPerformanceDir: argResults[logPerformanceOption] as String,
-    );
-  }
-}
-
-/// Options specific to the `daemon` command.
-class DaemonOptions extends WatchOptions {
-  BuildMode buildMode;
-
-  DaemonOptions._({
-    @required Set<BuildFilter> buildFilters,
-    @required this.buildMode,
-    @required bool deleteFilesByDefault,
-    @required bool enableLowResourcesMode,
-    @required String configKey,
-    @required Set<BuildDirectory> buildDirs,
-    @required bool outputSymlinksOnly,
-    @required bool trackPerformance,
-    @required bool skipBuildScriptCheck,
-    @required bool verbose,
-    @required Map<String, Map<String, dynamic>> builderConfigOverrides,
-    @required bool isReleaseBuild,
-    @required String logPerformanceDir,
-    @required bool usePollingWatcher,
-  }) : super._(
-          buildFilters: buildFilters,
-          deleteFilesByDefault: deleteFilesByDefault,
-          enableLowResourcesMode: enableLowResourcesMode,
-          configKey: configKey,
-          buildDirs: buildDirs,
-          outputSymlinksOnly: outputSymlinksOnly,
-          trackPerformance: trackPerformance,
-          skipBuildScriptCheck: skipBuildScriptCheck,
-          verbose: verbose,
-          builderConfigOverrides: builderConfigOverrides,
-          isReleaseBuild: isReleaseBuild,
-          logPerformanceDir: logPerformanceDir,
-          usePollingWatcher: usePollingWatcher,
-        );
-
-  factory DaemonOptions.fromParsedArgs(ArgResults argResults,
-      Iterable<String> positionalArgs, String rootPackage, Command command) {
-    var buildDirs = {
-      ..._parseBuildDirs(argResults),
-      ..._parsePositionalBuildDirs(positionalArgs, command),
-    };
-    var buildFilters = _parseBuildFilters(argResults, rootPackage);
-
-    var buildModeValue = argResults[buildModeFlag] as String;
-    BuildMode buildMode;
-    if (buildModeValue == BuildMode.Auto.toString()) {
-      buildMode = BuildMode.Auto;
-    } else if (buildModeValue == BuildMode.Manual.toString()) {
-      buildMode = BuildMode.Manual;
-    } else {
-      throw UsageException(
-          'Unexpected value for $buildModeFlag: $buildModeValue',
-          command.usage);
-    }
-
-    return DaemonOptions._(
-      buildFilters: buildFilters,
-      buildMode: buildMode,
-      deleteFilesByDefault: argResults[deleteFilesByDefaultOption] as bool,
-      enableLowResourcesMode: argResults[lowResourcesModeOption] as bool,
-      configKey: argResults[configOption] as String,
-      buildDirs: buildDirs,
-      outputSymlinksOnly: argResults[symlinkOption] as bool,
-      trackPerformance: argResults[trackPerformanceOption] as bool,
-      skipBuildScriptCheck: argResults[skipBuildScriptCheckOption] as bool,
-      verbose: argResults[verboseOption] as bool,
-      builderConfigOverrides:
-          _parseBuilderConfigOverrides(argResults[defineOption], rootPackage),
-      isReleaseBuild: argResults[releaseOption] as bool,
-      logPerformanceDir: argResults[logPerformanceOption] as String,
-      usePollingWatcher: argResults[usePollingWatcherOption] as bool,
-    );
-  }
-}
-
-class WatchOptions extends SharedOptions {
-  final bool usePollingWatcher;
-
-  DirectoryWatcher Function(String) get directoryWatcherFactory =>
-      usePollingWatcher
-          ? pollingDirectoryWatcherFactory
-          : defaultDirectoryWatcherFactory;
-
-  WatchOptions._({
-    @required this.usePollingWatcher,
-    @required Set<BuildFilter> buildFilters,
-    @required bool deleteFilesByDefault,
-    @required bool enableLowResourcesMode,
-    @required String configKey,
-    @required Set<BuildDirectory> buildDirs,
-    @required bool outputSymlinksOnly,
-    @required bool trackPerformance,
-    @required bool skipBuildScriptCheck,
-    @required bool verbose,
-    @required Map<String, Map<String, dynamic>> builderConfigOverrides,
-    @required bool isReleaseBuild,
-    @required String logPerformanceDir,
-  }) : super._(
-          buildFilters: buildFilters,
-          deleteFilesByDefault: deleteFilesByDefault,
-          enableLowResourcesMode: enableLowResourcesMode,
-          configKey: configKey,
-          buildDirs: buildDirs,
-          outputSymlinksOnly: outputSymlinksOnly,
-          trackPerformance: trackPerformance,
-          skipBuildScriptCheck: skipBuildScriptCheck,
-          verbose: verbose,
-          builderConfigOverrides: builderConfigOverrides,
-          isReleaseBuild: isReleaseBuild,
-          logPerformanceDir: logPerformanceDir,
-        );
-
-  factory WatchOptions.fromParsedArgs(ArgResults argResults,
-      Iterable<String> positionalArgs, String rootPackage, Command command) {
-    var buildDirs = {
-      ..._parseBuildDirs(argResults),
-      ..._parsePositionalBuildDirs(positionalArgs, command),
-    };
-    var buildFilters = _parseBuildFilters(argResults, rootPackage);
-
-    return WatchOptions._(
-      buildFilters: buildFilters,
-      deleteFilesByDefault: argResults[deleteFilesByDefaultOption] as bool,
-      enableLowResourcesMode: argResults[lowResourcesModeOption] as bool,
-      configKey: argResults[configOption] as String,
-      buildDirs: buildDirs,
-      outputSymlinksOnly: argResults[symlinkOption] as bool,
-      trackPerformance: argResults[trackPerformanceOption] as bool,
-      skipBuildScriptCheck: argResults[skipBuildScriptCheckOption] as bool,
-      verbose: argResults[verboseOption] as bool,
-      builderConfigOverrides:
-          _parseBuilderConfigOverrides(argResults[defineOption], rootPackage),
-      isReleaseBuild: argResults[releaseOption] as bool,
-      logPerformanceDir: argResults[logPerformanceOption] as String,
-      usePollingWatcher: argResults[usePollingWatcherOption] as bool,
-    );
-  }
-}
-
-/// Options specific to the `serve` command.
-class ServeOptions extends WatchOptions {
-  final String hostName;
-  final BuildUpdatesOption buildUpdates;
-  final bool logRequests;
-  final List<ServeTarget> serveTargets;
-
-  ServeOptions._({
-    @required this.hostName,
-    @required this.buildUpdates,
-    @required this.logRequests,
-    @required this.serveTargets,
-    @required Set<BuildFilter> buildFilters,
-    @required bool deleteFilesByDefault,
-    @required bool enableLowResourcesMode,
-    @required String configKey,
-    @required Set<BuildDirectory> buildDirs,
-    @required bool outputSymlinksOnly,
-    @required bool trackPerformance,
-    @required bool skipBuildScriptCheck,
-    @required bool verbose,
-    @required Map<String, Map<String, dynamic>> builderConfigOverrides,
-    @required bool isReleaseBuild,
-    @required String logPerformanceDir,
-    @required bool usePollingWatcher,
-  }) : super._(
-          buildFilters: buildFilters,
-          deleteFilesByDefault: deleteFilesByDefault,
-          enableLowResourcesMode: enableLowResourcesMode,
-          configKey: configKey,
-          buildDirs: buildDirs,
-          outputSymlinksOnly: outputSymlinksOnly,
-          trackPerformance: trackPerformance,
-          skipBuildScriptCheck: skipBuildScriptCheck,
-          verbose: verbose,
-          builderConfigOverrides: builderConfigOverrides,
-          isReleaseBuild: isReleaseBuild,
-          logPerformanceDir: logPerformanceDir,
-          usePollingWatcher: usePollingWatcher,
-        );
-
-  factory ServeOptions.fromParsedArgs(ArgResults argResults,
-      Iterable<String> positionalArgs, String rootPackage, Command command) {
-    var serveTargets = <ServeTarget>[];
-    var nextDefaultPort = 8080;
-    for (var arg in positionalArgs) {
-      var parts = arg.split(':');
-      if (parts.length > 2) {
-        throw UsageException(
-            'Invalid format for positional argument to serve `$arg`'
-            ', expected <directory>:<port>.',
-            command.usage);
-      }
-
-      var port = parts.length == 2 ? int.tryParse(parts[1]) : nextDefaultPort++;
-      if (port == null) {
-        throw UsageException(
-            'Unable to parse port number in `$arg`', command.usage);
-      }
-
-      var path = parts.first;
-      var pathParts = p.split(path);
-      if (pathParts.length > 1 || path == '.') {
-        throw UsageException(
-            'Only top level directories such as `web` or `test` are allowed as '
-            'positional args, but got `$path`',
-            command.usage);
-      }
-
-      serveTargets.add(ServeTarget(path, port));
-    }
-    if (serveTargets.isEmpty) {
-      for (var dir in _defaultWebDirs) {
-        if (Directory(dir).existsSync()) {
-          serveTargets.add(ServeTarget(dir, nextDefaultPort++));
-        }
-      }
-    }
-
-    var buildDirs = _parseBuildDirs(argResults);
-    for (var target in serveTargets) {
-      buildDirs.add(BuildDirectory(target.dir));
-    }
-
-    var buildFilters = _parseBuildFilters(argResults, rootPackage);
-
-    BuildUpdatesOption buildUpdates;
-    if (argResults[liveReloadOption] as bool &&
-        argResults[hotReloadOption] as bool) {
-      throw UsageException(
-          'Options --$liveReloadOption and --$hotReloadOption '
-          "can't both be used together",
-          command.usage);
-    } else if (argResults[liveReloadOption] as bool) {
-      buildUpdates = BuildUpdatesOption.liveReload;
-    } else if (argResults[hotReloadOption] as bool) {
-      buildUpdates = BuildUpdatesOption.hotReload;
-    }
-
-    return ServeOptions._(
-      buildFilters: buildFilters,
-      hostName: argResults[hostnameOption] as String,
-      buildUpdates: buildUpdates,
-      logRequests: argResults[logRequestsOption] as bool,
-      serveTargets: serveTargets,
-      deleteFilesByDefault: argResults[deleteFilesByDefaultOption] as bool,
-      enableLowResourcesMode: argResults[lowResourcesModeOption] as bool,
-      configKey: argResults[configOption] as String,
-      buildDirs: buildDirs,
-      outputSymlinksOnly: argResults[symlinkOption] as bool,
-      trackPerformance: argResults[trackPerformanceOption] as bool,
-      skipBuildScriptCheck: argResults[skipBuildScriptCheckOption] as bool,
-      verbose: argResults[verboseOption] as bool,
-      builderConfigOverrides:
-          _parseBuilderConfigOverrides(argResults[defineOption], rootPackage),
-      isReleaseBuild: argResults[releaseOption] as bool,
-      logPerformanceDir: argResults[logPerformanceOption] as String,
-      usePollingWatcher: argResults[usePollingWatcherOption] as bool,
-    );
-  }
-}
-
-/// A target to serve, representing a directory and a port.
-class ServeTarget {
-  final String dir;
-  final int port;
-
-  ServeTarget(this.dir, this.port);
-}
-
-Map<String, Map<String, dynamic>> _parseBuilderConfigOverrides(
-    dynamic parsedArg, String rootPackage) {
-  final builderConfigOverrides = <String, Map<String, dynamic>>{};
-  if (parsedArg == null) return builderConfigOverrides;
-  var allArgs = parsedArg is List<String> ? parsedArg : [parsedArg as String];
-  for (final define in allArgs) {
-    final parts = define.split('=');
-    const expectedFormat = '--define "<builder_key>=<option>=<value>"';
-    if (parts.length < 3) {
-      throw ArgumentError.value(
-          define,
-          defineOption,
-          'Expected at least 2 `=` signs, should be of the format like '
-          '$expectedFormat');
-    } else if (parts.length > 3) {
-      var rest = parts.sublist(2);
-      parts
-        ..removeRange(2, parts.length)
-        ..add(rest.join('='));
-    }
-    final builderKey = normalizeBuilderKeyUsage(parts[0], rootPackage);
-    final option = parts[1];
-    dynamic value;
-    // Attempt to parse the value as JSON, and if that fails then treat it as
-    // a normal string.
-    try {
-      value = json.decode(parts[2]);
-    } on FormatException catch (_) {
-      value = parts[2];
-    }
-    final config = builderConfigOverrides.putIfAbsent(
-        builderKey, () => <String, dynamic>{});
-    if (config.containsKey(option)) {
-      throw ArgumentError(
-          'Got duplicate overrides for the same builder option: '
-          '$builderKey=$option. Only one is allowed.');
-    }
-    config[option] = value;
-  }
-  return builderConfigOverrides;
-}
-
-/// Returns build directories with output information parsed from output
-/// arguments.
-///
-/// Each output option is split on `:` where the first value is the
-/// root input directory and the second value output directory.
-/// If no delimeter is provided the root input directory will be null.
-Set<BuildDirectory> _parseBuildDirs(ArgResults argResults) {
-  var outputs = argResults[outputOption] as List<String>;
-  if (outputs == null) return <BuildDirectory>{};
-  var result = <BuildDirectory>{};
-  var outputPaths = <String>{};
-
-  void checkExisting(String outputDir) {
-    if (outputPaths.contains(outputDir)) {
-      throw ArgumentError.value(outputs.join(' '), '--output',
-          'Duplicate output directories are not allowed, got');
-    }
-    outputPaths.add(outputDir);
-  }
-
-  for (var option in argResults[outputOption] as List<String>) {
-    var split = option.split(':');
-    if (split.length == 1) {
-      var output = split.first;
-      checkExisting(output);
-      result.add(BuildDirectory('',
-          outputLocation: OutputLocation(output, hoist: false)));
-    } else if (split.length >= 2) {
-      var output = split.sublist(1).join(':');
-      checkExisting(output);
-      var root = split.first;
-      if (root.contains('/')) {
-        throw ArgumentError.value(
-            option, '--output', 'Input root can not be nested');
-      }
-      result.add(
-          BuildDirectory(split.first, outputLocation: OutputLocation(output)));
-    }
-  }
-  return result;
-}
-
-/// Throws a [UsageException] if [arg] looks like anything other than a top
-/// level directory.
-String _checkTopLevel(String arg, Command command) {
-  var parts = p.split(arg);
-  if (parts.length > 1 || arg == '.') {
-    throw UsageException(
-        'Only top level directories such as `web` or `test` are allowed as '
-        'positional args, but got `$arg`',
-        command.usage);
-  }
-  return arg;
-}
-
-/// Parses positional arguments as plain build directories.
-Set<BuildDirectory> _parsePositionalBuildDirs(
-        Iterable<String> positionalArgs, Command command) =>
-    {
-      for (var arg in positionalArgs)
-        BuildDirectory(_checkTopLevel(arg, command))
-    };
-
-/// Returns build filters parsed from [buildFilterOption] arguments.
-///
-/// These support `package:` uri syntax as well as regular path syntax,
-/// with glob support for both package names and paths.
-Set<BuildFilter> _parseBuildFilters(ArgResults argResults, String rootPackage) {
-  var filterArgs = argResults[buildFilterOption] as List<String>;
-  if (filterArgs?.isEmpty ?? true) return null;
-  try {
-    return {
-      for (var arg in filterArgs) BuildFilter.fromArg(arg, rootPackage),
-    };
-  } on FormatException catch (e) {
-    throw ArgumentError.value(
-        e.source,
-        '--build-filter',
-        'Not a valid build filter, must be either a relative path or '
-            '`package:` uri.\n\n$e');
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/run.dart b/build_runner/lib/src/entrypoint/run.dart
deleted file mode 100644
index ceba164..0000000
--- a/build_runner/lib/src/entrypoint/run.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/ansi.dart' as ansi;
-import 'package:io/io.dart' show ExitCode;
-
-import 'clean.dart';
-import 'runner.dart';
-
-/// A common entry point to parse command line arguments and build or serve with
-/// [builders].
-///
-/// Returns the exit code that should be set when the calling process exits. `0`
-/// implies success.
-Future<int> run(List<String> args, List<BuilderApplication> builders) async {
-  var runner = BuildCommandRunner(builders)..addCommand(CleanCommand());
-  try {
-    var result = await runner.run(args);
-    return result ?? 0;
-  } on UsageException catch (e) {
-    print(ansi.red.wrap(e.message));
-    print('');
-    print(e.usage);
-    return ExitCode.usage.code;
-  } on ArgumentError catch (e) {
-    print(ansi.red.wrap(e.toString()));
-    return ExitCode.usage.code;
-  } on CannotBuildException {
-    // A message should have already been logged.
-    return ExitCode.config.code;
-  } on BuildScriptChangedException {
-    _deleteAssetGraph();
-    if (_runningFromSnapshot) _deleteSelf();
-    return ExitCode.tempFail.code;
-  } on BuildConfigChangedException {
-    return ExitCode.tempFail.code;
-  }
-}
-
-/// Deletes the asset graph for the current build script from disk.
-void _deleteAssetGraph() {
-  var graph = File(assetGraphPath);
-  if (graph.existsSync()) {
-    graph.deleteSync();
-  }
-}
-
-/// Deletes the current running script.
-///
-/// This should only happen if the current script is a snapshot, and it has
-/// been invalidated.
-void _deleteSelf() {
-  var self = File(Platform.script.toFilePath());
-  if (self.existsSync()) {
-    self.deleteSync();
-  }
-}
-
-bool get _runningFromSnapshot => !Platform.script.path.endsWith('.dart');
diff --git a/build_runner/lib/src/entrypoint/run_script.dart b/build_runner/lib/src/entrypoint/run_script.dart
deleted file mode 100644
index 6c4fbd3..0000000
--- a/build_runner/lib/src/entrypoint/run_script.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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:isolate';
-
-import 'package:args/command_runner.dart';
-import 'package:build_runner/src/logging/std_io_logging.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import '../generate/build.dart';
-import 'base_command.dart';
-import 'options.dart';
-
-class RunCommand extends BuildRunnerCommand {
-  @override
-  String get name => 'run';
-
-  @override
-  String get description => 'Performs a single build, and executes '
-      'a Dart script with the given arguments.';
-
-  @override
-  String get invocation =>
-      '${super.invocation.replaceFirst('[arguments]', '[build-arguments]')} '
-      '<executable> [-- [script-arguments]]';
-
-  @override
-  SharedOptions readOptions() {
-    // Here we validate that [argResults.rest] is exactly equal to all the
-    // arguments after the `--`.
-
-    var separatorPos = argResults.arguments.indexOf('--');
-
-    if (separatorPos >= 0) {
-      void throwUsageException() {
-        throw UsageException(
-            'The `run` command does not support positional args before the '
-            '`--` separator which should separate build args from script args.',
-            usage);
-      }
-
-      var expectedRest = argResults.arguments.skip(separatorPos + 1).toList();
-
-      // Since we expect the first argument to be the name of a script,
-      // we should skip it when comparing extra arguments.
-      var effectiveRest = argResults.rest.skip(1).toList();
-
-      if (effectiveRest.length != expectedRest.length) {
-        throwUsageException();
-      }
-
-      for (var i = 0; i < effectiveRest.length; i++) {
-        if (expectedRest[i] != effectiveRest[i]) {
-          throwUsageException();
-        }
-      }
-    }
-
-    return SharedOptions.fromParsedArgs(
-        argResults, [], packageGraph.root.name, this);
-  }
-
-  @override
-  FutureOr<int> run() async {
-    var options = readOptions();
-    var logSubscription =
-        Logger.root.onRecord.listen(stdIOLogListener(verbose: options.verbose));
-
-    try {
-      // Ensure that the user passed the name of a file to run.
-      if (argResults.rest.isEmpty) {
-        logger..severe('Must specify an executable to run.')..severe(usage);
-        return ExitCode.usage.code;
-      }
-
-      var scriptName = argResults.rest[0];
-      var passedArgs = argResults.rest.skip(1).toList();
-
-      // Ensure the extension is .dart.
-      if (p.extension(scriptName) != '.dart') {
-        logger.severe('$scriptName is not a valid Dart file '
-            'and cannot be run in the VM.');
-        return ExitCode.usage.code;
-      }
-
-      // Create a temporary directory in which to execute the script.
-      var tempPath = Directory.systemTemp
-          .createTempSync('build_runner_run_script')
-          .absolute
-          .uri
-          .toFilePath();
-
-      // Create two ReceivePorts, so that we can quit when the isolate is done.
-      //
-      // Define these before starting the isolate, so that we can close
-      // them if there is a spawn exception.
-      ReceivePort onExit, onError;
-
-      // Use a completer to determine the exit code.
-      var exitCodeCompleter = Completer<int>();
-
-      try {
-        var buildDirs = (options.buildDirs ?? <BuildDirectory>{})
-          ..add(BuildDirectory('',
-              outputLocation: OutputLocation(tempPath,
-                  useSymlinks: options.outputSymlinksOnly, hoist: false)));
-        var result = await build(
-          builderApplications,
-          deleteFilesByDefault: options.deleteFilesByDefault,
-          enableLowResourcesMode: options.enableLowResourcesMode,
-          configKey: options.configKey,
-          buildDirs: buildDirs,
-          packageGraph: packageGraph,
-          verbose: options.verbose,
-          builderConfigOverrides: options.builderConfigOverrides,
-          isReleaseBuild: options.isReleaseBuild,
-          trackPerformance: options.trackPerformance,
-          skipBuildScriptCheck: options.skipBuildScriptCheck,
-          logPerformanceDir: options.logPerformanceDir,
-          buildFilters: options.buildFilters,
-        );
-
-        if (result.status == BuildStatus.failure) {
-          logger.warning('Skipping script run due to build failure');
-          return result.failureType.exitCode;
-        }
-
-        // Find the path of the script to run.
-        var scriptPath = p.join(tempPath, scriptName);
-        var packageConfigPath = p.join(tempPath, '.packages');
-
-        onExit = ReceivePort();
-        onError = ReceivePort();
-
-        // Cleanup after exit.
-        onExit.listen((_) {
-          // If no error was thrown, return 0.
-          if (!exitCodeCompleter.isCompleted) exitCodeCompleter.complete(0);
-        });
-
-        // On an error, kill the isolate, and log the error.
-        onError.listen((e) {
-          onExit.close();
-          onError.close();
-          logger.severe('Unhandled error from script: $scriptName', e[0],
-              StackTrace.fromString(e[1].toString()));
-          if (!exitCodeCompleter.isCompleted) exitCodeCompleter.complete(1);
-        });
-
-        await Isolate.spawnUri(
-          p.toUri(scriptPath),
-          passedArgs,
-          null,
-          errorsAreFatal: true,
-          onExit: onExit.sendPort,
-          onError: onError.sendPort,
-          packageConfig: p.toUri(packageConfigPath),
-        );
-
-        return await exitCodeCompleter.future;
-      } on IsolateSpawnException catch (e) {
-        logger.severe(
-            'Could not spawn isolate. Ensure that your file is in a valid directory (i.e. "bin", "benchmark", "example", "test", "tool").',
-            e);
-        return ExitCode.ioError.code;
-      } finally {
-        // Clean up the output dir.
-        var dir = Directory(tempPath);
-        if (await dir.exists()) await dir.delete(recursive: true);
-
-        onExit?.close();
-        onError?.close();
-        if (!exitCodeCompleter.isCompleted) {
-          exitCodeCompleter.complete(ExitCode.success.code);
-        }
-      }
-    } finally {
-      await logSubscription.cancel();
-    }
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/runner.dart b/build_runner/lib/src/entrypoint/runner.dart
deleted file mode 100644
index 4cb309f..0000000
--- a/build_runner/lib/src/entrypoint/runner.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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:convert';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-
-import 'base_command.dart' show lineLength;
-import 'build.dart';
-import 'daemon.dart';
-import 'doctor.dart';
-import 'run_script.dart';
-import 'serve.dart';
-import 'test.dart';
-import 'watch.dart';
-
-/// Unified command runner for all build_runner commands.
-class BuildCommandRunner extends CommandRunner<int> {
-  @override
-  final argParser = ArgParser(usageLineLength: lineLength);
-
-  final List<BuilderApplication> builderApplications;
-
-  final packageGraph = PackageGraph.forThisPackage();
-
-  BuildCommandRunner(List<BuilderApplication> builderApplications)
-      : builderApplications = List.unmodifiable(builderApplications),
-        super('build_runner', 'Unified interface for running Dart builds.') {
-    addCommand(BuildCommand());
-    addCommand(DaemonCommand());
-    addCommand(DoctorCommand());
-    addCommand(RunCommand());
-    addCommand(ServeCommand());
-    addCommand(TestCommand(packageGraph));
-    addCommand(WatchCommand());
-  }
-
-  // CommandRunner._usageWithoutDescription is private – this is a reasonable
-  // facsimile.
-  /// Returns [usage] with [description] removed from the beginning.
-  String get usageWithoutDescription => LineSplitter.split(usage)
-      .skipWhile((line) => line == description || line.isEmpty)
-      .join('\n');
-}
diff --git a/build_runner/lib/src/entrypoint/serve.dart b/build_runner/lib/src/entrypoint/serve.dart
deleted file mode 100644
index aacc363..0000000
--- a/build_runner/lib/src/entrypoint/serve.dart
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:http_multi_server/http_multi_server.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-import 'package:shelf/shelf_io.dart';
-
-import '../generate/build.dart';
-import '../logging/std_io_logging.dart';
-import '../server/server.dart';
-import 'options.dart';
-import 'watch.dart';
-
-/// Extends [WatchCommand] with dev server functionality.
-class ServeCommand extends WatchCommand {
-  ServeCommand() {
-    argParser
-      ..addOption(hostnameOption,
-          help: 'Specify the hostname to serve on', defaultsTo: 'localhost')
-      ..addFlag(logRequestsOption,
-          defaultsTo: false,
-          negatable: false,
-          help: 'Enables logging for each request to the server.')
-      ..addFlag(liveReloadOption,
-          defaultsTo: false,
-          negatable: false,
-          help: 'Enables automatic page reloading on rebuilds. '
-              "Can't be used together with --$hotReloadOption.")
-      ..addFlag(hotReloadOption,
-          defaultsTo: false,
-          negatable: false,
-          help: 'Enables automatic reloading of changed modules on rebuilds. '
-              "Can't be used together with --$liveReloadOption.");
-  }
-
-  @override
-  String get invocation => '${super.invocation} [<directory>[:<port>]]...';
-
-  @override
-  String get name => 'serve';
-
-  @override
-  String get description =>
-      'Runs a development server that serves the specified targets and runs '
-      'builds based on file system updates.';
-
-  @override
-  ServeOptions readOptions() => ServeOptions.fromParsedArgs(
-      argResults, argResults.rest, packageGraph.root.name, this);
-
-  @override
-  Future<int> run() async {
-    final servers = <ServeTarget, HttpServer>{};
-    return _runServe(servers).whenComplete(() async {
-      await Future.wait(
-          servers.values.map((server) => server.close(force: true)));
-    });
-  }
-
-  Future<int> _runServe(Map<ServeTarget, HttpServer> servers) async {
-    var options = readOptions();
-    try {
-      await Future.wait(options.serveTargets.map((target) async {
-        servers[target] =
-            await HttpMultiServer.bind(options.hostName, target.port);
-      }));
-    } on SocketException catch (e) {
-      var listener = Logger.root.onRecord.listen(stdIOLogListener());
-      if (e.address != null && e.port != null) {
-        logger.severe(
-            'Error starting server at ${e.address.address}:${e.port}, address '
-            'is already in use. Please kill the server running on that port or '
-            'serve on a different port and restart this process.');
-      } else {
-        logger.severe('Error starting server on ${options.hostName}.');
-      }
-      await listener.cancel();
-      return ExitCode.osError.code;
-    }
-
-    var handler = await watch(
-      builderApplications,
-      deleteFilesByDefault: options.deleteFilesByDefault,
-      enableLowResourcesMode: options.enableLowResourcesMode,
-      configKey: options.configKey,
-      buildDirs: options.buildDirs,
-      outputSymlinksOnly: options.outputSymlinksOnly,
-      packageGraph: packageGraph,
-      trackPerformance: options.trackPerformance,
-      skipBuildScriptCheck: options.skipBuildScriptCheck,
-      verbose: options.verbose,
-      builderConfigOverrides: options.builderConfigOverrides,
-      isReleaseBuild: options.isReleaseBuild,
-      logPerformanceDir: options.logPerformanceDir,
-      directoryWatcherFactory: options.directoryWatcherFactory,
-      buildFilters: options.buildFilters,
-    );
-
-    if (handler == null) return ExitCode.config.code;
-
-    servers.forEach((target, server) {
-      serveRequests(
-          server,
-          handler.handlerFor(target.dir,
-              logRequests: options.logRequests,
-              buildUpdates: options.buildUpdates));
-    });
-
-    _ensureBuildWebCompilersDependency(packageGraph, logger);
-
-    final completer = Completer<int>();
-    handleBuildResultsStream(handler.buildResults, completer);
-    _logServerPorts(handler, options, logger);
-    return completer.future;
-  }
-
-  void _logServerPorts(
-      ServeHandler serveHandler, ServeOptions options, Logger logger) async {
-    await serveHandler.currentBuild;
-    // Warn if in serve mode with no servers.
-    if (options.serveTargets.isEmpty) {
-      logger.warning(
-          'Found no known web directories to serve, but running in `serve` '
-          'mode. You may expliclity provide a directory to serve with trailing '
-          'args in <dir>[:<port>] format.');
-    } else {
-      for (var target in options.serveTargets) {
-        stdout.writeln('Serving `${target.dir}` on '
-            'http://${options.hostName}:${target.port}');
-      }
-    }
-  }
-}
-
-void _ensureBuildWebCompilersDependency(PackageGraph packageGraph, Logger log) {
-  if (!packageGraph.allPackages.containsKey('build_web_compilers')) {
-    log.warning('''
-    Missing dev dependency on package:build_web_compilers, which is required to serve Dart compiled to JavaScript.
-
-    Please update your dev_dependencies section of your pubspec.yaml:
-
-    dev_dependencies:
-      build_runner: any
-      build_test: any
-      build_web_compilers: any''');
-  }
-}
diff --git a/build_runner/lib/src/entrypoint/test.dart b/build_runner/lib/src/entrypoint/test.dart
deleted file mode 100644
index fbd69db..0000000
--- a/build_runner/lib/src/entrypoint/test.dart
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/command_runner.dart';
-import 'package:async/async.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-import 'package:path/path.dart' as p;
-import 'package:pub_semver/pub_semver.dart';
-import 'package:pubspec_parse/pubspec_parse.dart';
-
-import '../generate/build.dart';
-import 'base_command.dart';
-import 'options.dart';
-
-/// A command that does a single build and then runs tests using the compiled
-/// assets.
-class TestCommand extends BuildRunnerCommand {
-  TestCommand(PackageGraph packageGraph)
-      : super(
-          // Use symlinks by default, if package:test supports it.
-          symlinksDefault:
-              _packageTestSupportsSymlinks(packageGraph) && !Platform.isWindows,
-        );
-
-  @override
-  String get invocation =>
-      '${super.invocation.replaceFirst('[arguments]', '[build-arguments]')} '
-      '[-- [test-arguments]]';
-
-  @override
-  String get name => 'test';
-
-  @override
-  String get description =>
-      'Performs a single build of the test directory only and then runs tests '
-      'using the compiled assets.';
-
-  @override
-  SharedOptions readOptions() {
-    // This command doesn't allow specifying directories to build, instead it
-    // always builds the `test` directory.
-    //
-    // Here we validate that [argResults.rest] is exactly equal to all the
-    // arguments after the `--`.
-    if (argResults.rest.isNotEmpty) {
-      void throwUsageException() {
-        throw UsageException(
-            'The `test` command does not support positional args before the, '
-            '`--` separator, which should separate build args from test args.',
-            usage);
-      }
-
-      var separatorPos = argResults.arguments.indexOf('--');
-      if (separatorPos < 0) {
-        throwUsageException();
-      }
-      var expectedRest = argResults.arguments.skip(separatorPos + 1).toList();
-      if (argResults.rest.length != expectedRest.length) {
-        throwUsageException();
-      }
-      for (var i = 0; i < argResults.rest.length; i++) {
-        if (expectedRest[i] != argResults.rest[i]) {
-          throwUsageException();
-        }
-      }
-    }
-
-    return SharedOptions.fromParsedArgs(
-        argResults, ['test'], packageGraph.root.name, this);
-  }
-
-  @override
-  Future<int> run() async {
-    SharedOptions options;
-    // We always run our tests in a temp dir.
-    var tempPath = Directory.systemTemp
-        .createTempSync('build_runner_test')
-        .absolute
-        .uri
-        .toFilePath();
-    try {
-      _ensureBuildTestDependency(packageGraph);
-      options = readOptions();
-      var buildDirs = (options.buildDirs ?? <BuildDirectory>{})
-        // Build test by default.
-        ..add(BuildDirectory('test',
-            outputLocation: OutputLocation(tempPath,
-                useSymlinks: options.outputSymlinksOnly, hoist: false)));
-
-      var result = await build(
-        builderApplications,
-        deleteFilesByDefault: options.deleteFilesByDefault,
-        enableLowResourcesMode: options.enableLowResourcesMode,
-        configKey: options.configKey,
-        buildDirs: buildDirs,
-        outputSymlinksOnly: options.outputSymlinksOnly,
-        packageGraph: packageGraph,
-        trackPerformance: options.trackPerformance,
-        skipBuildScriptCheck: options.skipBuildScriptCheck,
-        verbose: options.verbose,
-        builderConfigOverrides: options.builderConfigOverrides,
-        isReleaseBuild: options.isReleaseBuild,
-        logPerformanceDir: options.logPerformanceDir,
-        buildFilters: options.buildFilters,
-      );
-
-      if (result.status == BuildStatus.failure) {
-        stdout.writeln('Skipping tests due to build failure');
-        return result.failureType.exitCode;
-      }
-
-      return await _runTests(tempPath);
-    } on _BuildTestDependencyError catch (e) {
-      stdout.writeln(e);
-      return ExitCode.config.code;
-    } finally {
-      // Clean up the output dir.
-      await Directory(tempPath).delete(recursive: true);
-    }
-  }
-
-  /// Runs tests using [precompiledPath] as the precompiled test directory.
-  Future<int> _runTests(String precompiledPath) async {
-    stdout.writeln('Running tests...\n');
-    var extraTestArgs = argResults.rest;
-    var testProcess = await Process.start(
-        pubBinary,
-        [
-          'run',
-          'test',
-          '--precompiled',
-          precompiledPath,
-          ...extraTestArgs,
-        ],
-        mode: ProcessStartMode.inheritStdio);
-    _ensureProcessExit(testProcess);
-    return testProcess.exitCode;
-  }
-}
-
-bool _packageTestSupportsSymlinks(PackageGraph packageGraph) {
-  var testPackage = packageGraph['test'];
-  if (testPackage == null) return false;
-  var pubspecPath = p.join(testPackage.path, 'pubspec.yaml');
-  var pubspec = Pubspec.parse(File(pubspecPath).readAsStringSync());
-  if (pubspec.version == null) return false;
-  return pubspec.version >= Version(1, 3, 0);
-}
-
-void _ensureBuildTestDependency(PackageGraph packageGraph) {
-  if (!packageGraph.allPackages.containsKey('build_test')) {
-    throw _BuildTestDependencyError();
-  }
-}
-
-void _ensureProcessExit(Process process) {
-  var signalsSub = _exitProcessSignals.listen((signal) async {
-    stdout.writeln('waiting for subprocess to exit...');
-  });
-  process.exitCode.then((_) {
-    signalsSub?.cancel();
-    signalsSub = null;
-  });
-}
-
-Stream<ProcessSignal> get _exitProcessSignals => Platform.isWindows
-    ? ProcessSignal.sigint.watch()
-    : StreamGroup.merge(
-        [ProcessSignal.sigterm.watch(), ProcessSignal.sigint.watch()]);
-
-class _BuildTestDependencyError extends StateError {
-  _BuildTestDependencyError() : super('''
-Missing dev dependency on package:build_test, which is required to run tests.
-
-Please update your dev_dependencies section of your pubspec.yaml:
-
-  dev_dependencies:
-    build_runner: any
-    build_test: any
-    # If you need to run web tests, you will also need this dependency.
-    build_web_compilers: any
-''');
-}
diff --git a/build_runner/lib/src/entrypoint/watch.dart b/build_runner/lib/src/entrypoint/watch.dart
deleted file mode 100644
index fea22ac..0000000
--- a/build_runner/lib/src/entrypoint/watch.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build_runner/src/entrypoint/options.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-
-import '../generate/build.dart';
-import 'base_command.dart';
-
-/// A command that watches the file system for updates and rebuilds as
-/// appropriate.
-class WatchCommand extends BuildRunnerCommand {
-  @override
-  String get invocation => '${super.invocation} [directories]';
-
-  @override
-  String get name => 'watch';
-
-  @override
-  String get description =>
-      'Builds the specified targets, watching the file system for updates and '
-      'rebuilding as appropriate.';
-
-  WatchCommand() {
-    argParser.addFlag(usePollingWatcherOption,
-        help: 'Use a polling watcher instead of the current platforms default '
-            'watcher implementation. This should generally only be used if '
-            'you are having problems with the default watcher, as it is '
-            'generally less efficient.');
-  }
-
-  @override
-  WatchOptions readOptions() => WatchOptions.fromParsedArgs(
-      argResults, argResults.rest, packageGraph.root.name, this);
-
-  @override
-  Future<int> run() async {
-    var options = readOptions();
-    var handler = await watch(
-      builderApplications,
-      deleteFilesByDefault: options.deleteFilesByDefault,
-      enableLowResourcesMode: options.enableLowResourcesMode,
-      configKey: options.configKey,
-      buildDirs: options.buildDirs,
-      outputSymlinksOnly: options.outputSymlinksOnly,
-      packageGraph: packageGraph,
-      trackPerformance: options.trackPerformance,
-      skipBuildScriptCheck: options.skipBuildScriptCheck,
-      verbose: options.verbose,
-      builderConfigOverrides: options.builderConfigOverrides,
-      isReleaseBuild: options.isReleaseBuild,
-      logPerformanceDir: options.logPerformanceDir,
-      directoryWatcherFactory: options.directoryWatcherFactory,
-      buildFilters: options.buildFilters,
-    );
-    if (handler == null) return ExitCode.config.code;
-
-    final completer = Completer<int>();
-    handleBuildResultsStream(handler.buildResults, completer);
-    return completer.future;
-  }
-
-  /// Listens to [buildResults], handling certain types of errors and completing
-  /// [completer] appropriately.
-  void handleBuildResultsStream(
-      Stream<BuildResult> buildResults, Completer<int> completer) async {
-    var subscription = buildResults.listen((result) {
-      if (completer.isCompleted) return;
-      if (result.status == BuildStatus.failure) {
-        if (result.failureType == FailureType.buildScriptChanged) {
-          completer.completeError(BuildScriptChangedException());
-        } else if (result.failureType == FailureType.buildConfigChanged) {
-          completer.completeError(BuildConfigChangedException());
-        }
-      }
-    });
-    await subscription.asFuture();
-    if (!completer.isCompleted) completer.complete(ExitCode.success.code);
-  }
-}
diff --git a/build_runner/lib/src/generate/build.dart b/build_runner/lib/src/generate/build.dart
deleted file mode 100644
index c17594a..0000000
--- a/build_runner/lib/src/generate/build.dart
+++ /dev/null
@@ -1,183 +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 'package:build/build.dart';
-import 'package:build_runner/src/generate/terminator.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:logging/logging.dart';
-import 'package:shelf/shelf.dart';
-import 'package:watcher/watcher.dart';
-
-import '../logging/std_io_logging.dart';
-import '../package_graph/build_config_overrides.dart';
-import '../server/server.dart';
-import 'watch_impl.dart' as watch_impl;
-
-/// Runs all of the BuilderApplications in [builders] once.
-///
-/// By default, the user will be prompted to delete any files which already
-/// exist but were not generated by this specific build script. The
-/// [deleteFilesByDefault] option can be set to `true` to skip this prompt.
-///
-/// A [packageGraph] may be supplied, otherwise one will be constructed using
-/// [PackageGraph.forThisPackage]. The default functionality assumes you are
-/// running in the root directory of a package, with both a `pubspec.yaml` and
-/// `.packages` file present.
-///
-/// A [reader] and [writer] may also be supplied, which can read/write assets
-/// to arbitrary locations or file systems. By default they will write directly
-/// to the root package directory, and will use the [packageGraph] to know where
-/// to read files from.
-///
-/// Logging may be customized by passing a custom [logLevel] below which logs
-/// will be ignored, as well as an [onLog] handler which defaults to [print].
-///
-/// The [terminateEventStream] is a stream which can send termination events.
-/// By default the [ProcessSignal.sigint] stream is used. In this mode, it
-/// will simply consume the first event and allow the build to continue.
-/// Multiple termination events will cause a normal shutdown.
-///
-/// If [outputSymlinksOnly] is `true`, then the merged output directories will
-/// contain only symlinks, which is much faster but not generally suitable for
-/// deployment.
-///
-/// If [verbose] is `true` then verbose logging will be enabled. This changes
-/// the default [logLevel] to [Level.ALL] and removes stack frame folding, among
-/// other things.
-Future<BuildResult> build(List<BuilderApplication> builders,
-    {bool deleteFilesByDefault,
-    bool assumeTty,
-    String configKey,
-    PackageGraph packageGraph,
-    RunnerAssetReader reader,
-    RunnerAssetWriter writer,
-    Resolvers resolvers,
-    Level logLevel,
-    void Function(LogRecord) onLog,
-    Stream terminateEventStream,
-    bool enableLowResourcesMode,
-    Set<BuildDirectory> buildDirs,
-    bool outputSymlinksOnly,
-    bool trackPerformance,
-    bool skipBuildScriptCheck,
-    bool verbose,
-    bool isReleaseBuild,
-    Map<String, Map<String, dynamic>> builderConfigOverrides,
-    String logPerformanceDir,
-    Set<BuildFilter> buildFilters}) async {
-  builderConfigOverrides ??= const {};
-  packageGraph ??= PackageGraph.forThisPackage();
-  var environment = OverrideableEnvironment(
-      IOEnvironment(
-        packageGraph,
-        assumeTty: assumeTty,
-        outputSymlinksOnly: outputSymlinksOnly,
-      ),
-      reader: reader,
-      writer: writer,
-      onLog: onLog ?? stdIOLogListener(assumeTty: assumeTty, verbose: verbose));
-  var logSubscription =
-      LogSubscription(environment, verbose: verbose, logLevel: logLevel);
-  var options = await BuildOptions.create(
-    logSubscription,
-    deleteFilesByDefault: deleteFilesByDefault,
-    packageGraph: packageGraph,
-    skipBuildScriptCheck: skipBuildScriptCheck,
-    overrideBuildConfig:
-        await findBuildConfigOverrides(packageGraph, configKey),
-    enableLowResourcesMode: enableLowResourcesMode,
-    trackPerformance: trackPerformance,
-    logPerformanceDir: logPerformanceDir,
-    resolvers: resolvers,
-  );
-  var terminator = Terminator(terminateEventStream);
-  try {
-    var build = await BuildRunner.create(
-      options,
-      environment,
-      builders,
-      builderConfigOverrides,
-      isReleaseBuild: isReleaseBuild ?? false,
-    );
-    var result =
-        await build.run({}, buildDirs: buildDirs, buildFilters: buildFilters);
-    await build?.beforeExit();
-    return result;
-  } finally {
-    await terminator.cancel();
-    await options.logListener.cancel();
-  }
-}
-
-/// Same as [build], except it watches the file system and re-runs builds
-/// automatically.
-///
-/// Call [ServeHandler.handlerFor] to create a [Handler] for use with
-/// `package:shelf`. Requests for assets will be blocked while builds are
-/// running then served with the latest version of the asset. Only source and
-/// generated assets can be served through this handler.
-///
-/// The [debounceDelay] controls how often builds will run. As long as files
-/// keep changing with less than that amount of time apart, builds will be put
-/// off.
-///
-/// The [directoryWatcherFactory] allows you to inject a way of creating custom
-/// `DirectoryWatcher`s. By default a normal `DirectoryWatcher` will be used.
-///
-/// The [terminateEventStream] is a stream which can send termination events.
-/// By default the [ProcessSignal.sigint] stream is used. In this mode, the
-/// first event will allow any ongoing builds to finish, and then the program
-/// will complete normally. Subsequent events are not handled (and will
-/// typically cause a shutdown).
-Future<ServeHandler> watch(List<BuilderApplication> builders,
-        {bool deleteFilesByDefault,
-        bool assumeTty,
-        String configKey,
-        PackageGraph packageGraph,
-        RunnerAssetReader reader,
-        RunnerAssetWriter writer,
-        Resolvers resolvers,
-        Level logLevel,
-        void Function(LogRecord) onLog,
-        Duration debounceDelay,
-        DirectoryWatcher Function(String) directoryWatcherFactory,
-        Stream terminateEventStream,
-        bool enableLowResourcesMode,
-        Set<BuildDirectory> buildDirs,
-        bool outputSymlinksOnly,
-        bool trackPerformance,
-        bool skipBuildScriptCheck,
-        bool verbose,
-        bool isReleaseBuild,
-        Map<String, Map<String, dynamic>> builderConfigOverrides,
-        String logPerformanceDir,
-        Set<BuildFilter> buildFilters}) =>
-    watch_impl.watch(
-      builders,
-      assumeTty: assumeTty,
-      deleteFilesByDefault: deleteFilesByDefault,
-      configKey: configKey,
-      packageGraph: packageGraph,
-      reader: reader,
-      writer: writer,
-      resolvers: resolvers,
-      logLevel: logLevel,
-      onLog: onLog,
-      debounceDelay: debounceDelay,
-      directoryWatcherFactory: directoryWatcherFactory,
-      terminateEventStream: terminateEventStream,
-      enableLowResourcesMode: enableLowResourcesMode,
-      buildDirs: buildDirs,
-      outputSymlinksOnly: outputSymlinksOnly,
-      trackPerformance: trackPerformance,
-      skipBuildScriptCheck: skipBuildScriptCheck,
-      verbose: verbose,
-      builderConfigOverrides: builderConfigOverrides,
-      isReleaseBuild: isReleaseBuild,
-      logPerformanceDir: logPerformanceDir,
-      buildFilters: buildFilters,
-    );
diff --git a/build_runner/lib/src/generate/directory_watcher_factory.dart b/build_runner/lib/src/generate/directory_watcher_factory.dart
deleted file mode 100644
index a211528..0000000
--- a/build_runner/lib/src/generate/directory_watcher_factory.dart
+++ /dev/null
@@ -1,11 +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 'package:watcher/watcher.dart';
-
-DirectoryWatcher defaultDirectoryWatcherFactory(String path) =>
-    DirectoryWatcher(path);
-
-DirectoryWatcher pollingDirectoryWatcherFactory(String path) =>
-    PollingDirectoryWatcher(path);
diff --git a/build_runner/lib/src/generate/terminator.dart b/build_runner/lib/src/generate/terminator.dart
deleted file mode 100644
index 3e44b8c..0000000
--- a/build_runner/lib/src/generate/terminator.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-/// Fires [shouldTerminate] once a `SIGINT` is intercepted.
-///
-/// The `SIGINT` stream can optionally be replaced with another Stream in the
-/// constructor. [cancel] should be called after work is finished. If multiple
-/// events are receieved on the terminate event stream before work is finished
-/// the process will be terminated with [exit].
-class Terminator {
-  /// A Future that fires when a signal has been received indicating that builds
-  /// should stop.
-  final Future shouldTerminate;
-  final StreamSubscription _subscription;
-
-  factory Terminator([Stream terminateEventStream]) {
-    var shouldTerminate = Completer<void>();
-    terminateEventStream ??= ProcessSignal.sigint.watch();
-    var numEventsSeen = 0;
-    var terminateListener = terminateEventStream.listen((_) {
-      numEventsSeen++;
-      if (numEventsSeen == 1) {
-        shouldTerminate.complete();
-      } else {
-        exit(2);
-      }
-    });
-    return Terminator._(shouldTerminate.future, terminateListener);
-  }
-
-  Terminator._(this.shouldTerminate, this._subscription);
-
-  Future cancel() => _subscription.cancel();
-}
diff --git a/build_runner/lib/src/generate/watch_impl.dart b/build_runner/lib/src/generate/watch_impl.dart
deleted file mode 100644
index 3be7ee4..0000000
--- a/build_runner/lib/src/generate/watch_impl.dart
+++ /dev/null
@@ -1,361 +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:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:build_runner/src/package_graph/build_config_overrides.dart';
-import 'package:build_runner/src/watcher/asset_change.dart';
-import 'package:build_runner/src/watcher/change_filter.dart';
-import 'package:build_runner/src/watcher/collect_changes.dart';
-import 'package:build_runner/src/watcher/delete_writer.dart';
-import 'package:build_runner/src/watcher/graph_watcher.dart';
-import 'package:build_runner/src/watcher/node_watcher.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/generate/build_impl.dart';
-import 'package:crypto/crypto.dart';
-import 'package:logging/logging.dart';
-import 'package:pedantic/pedantic.dart';
-import 'package:stream_transform/stream_transform.dart';
-import 'package:watcher/watcher.dart';
-
-import '../logging/std_io_logging.dart';
-import '../server/server.dart';
-import 'terminator.dart';
-
-final _logger = Logger('Watch');
-
-Future<ServeHandler> watch(
-  List<BuilderApplication> builders, {
-  bool deleteFilesByDefault,
-  bool assumeTty,
-  String configKey,
-  PackageGraph packageGraph,
-  RunnerAssetReader reader,
-  RunnerAssetWriter writer,
-  Resolvers resolvers,
-  Level logLevel,
-  void Function(LogRecord) onLog,
-  Duration debounceDelay,
-  DirectoryWatcher Function(String) directoryWatcherFactory,
-  Stream terminateEventStream,
-  bool skipBuildScriptCheck,
-  bool enableLowResourcesMode,
-  Map<String, BuildConfig> overrideBuildConfig,
-  Set<BuildDirectory> buildDirs,
-  bool outputSymlinksOnly,
-  bool trackPerformance,
-  bool verbose,
-  Map<String, Map<String, dynamic>> builderConfigOverrides,
-  bool isReleaseBuild,
-  String logPerformanceDir,
-  Set<BuildFilter> buildFilters,
-}) async {
-  builderConfigOverrides ??= const {};
-  packageGraph ??= PackageGraph.forThisPackage();
-  buildDirs ??= <BuildDirectory>{};
-  buildFilters ??= <BuildFilter>{};
-
-  var environment = OverrideableEnvironment(
-      IOEnvironment(packageGraph,
-          assumeTty: assumeTty, outputSymlinksOnly: outputSymlinksOnly),
-      reader: reader,
-      writer: writer,
-      onLog: onLog ?? stdIOLogListener(assumeTty: assumeTty, verbose: verbose));
-  var logSubscription =
-      LogSubscription(environment, verbose: verbose, logLevel: logLevel);
-  overrideBuildConfig ??=
-      await findBuildConfigOverrides(packageGraph, configKey);
-  var options = await BuildOptions.create(
-    logSubscription,
-    deleteFilesByDefault: deleteFilesByDefault,
-    packageGraph: packageGraph,
-    overrideBuildConfig: overrideBuildConfig,
-    debounceDelay: debounceDelay,
-    skipBuildScriptCheck: skipBuildScriptCheck,
-    enableLowResourcesMode: enableLowResourcesMode,
-    trackPerformance: trackPerformance,
-    logPerformanceDir: logPerformanceDir,
-    resolvers: resolvers,
-  );
-  var terminator = Terminator(terminateEventStream);
-
-  var watch = _runWatch(
-      options,
-      environment,
-      builders,
-      builderConfigOverrides,
-      terminator.shouldTerminate,
-      directoryWatcherFactory,
-      configKey,
-      buildDirs
-          .any((target) => target?.outputLocation?.path?.isNotEmpty ?? false),
-      buildDirs,
-      buildFilters,
-      isReleaseMode: isReleaseBuild ?? false);
-
-  unawaited(watch.buildResults.drain().then((_) async {
-    await terminator.cancel();
-    await options.logListener.cancel();
-  }));
-
-  return createServeHandler(watch);
-}
-
-/// Repeatedly run builds as files change on disk until [until] fires.
-///
-/// Sets up file watchers and collects changes then triggers new builds. When
-/// [until] fires the file watchers will be stopped and up to one additional
-/// build may run if there were pending changes.
-///
-/// The [BuildState.buildResults] stream will end after the final build has been
-/// run.
-WatchImpl _runWatch(
-        BuildOptions options,
-        BuildEnvironment environment,
-        List<BuilderApplication> builders,
-        Map<String, Map<String, dynamic>> builderConfigOverrides,
-        Future until,
-        DirectoryWatcher Function(String) directoryWatcherFactory,
-        String configKey,
-        bool willCreateOutputDirs,
-        Set<BuildDirectory> buildDirs,
-        Set<BuildFilter> buildFilters,
-        {bool isReleaseMode = false}) =>
-    WatchImpl(
-        options,
-        environment,
-        builders,
-        builderConfigOverrides,
-        until,
-        directoryWatcherFactory,
-        configKey,
-        willCreateOutputDirs,
-        buildDirs,
-        buildFilters,
-        isReleaseMode: isReleaseMode);
-
-class WatchImpl implements BuildState {
-  BuildImpl _build;
-
-  AssetGraph get assetGraph => _build?.assetGraph;
-
-  final _readyCompleter = Completer<void>();
-  Future<void> get ready => _readyCompleter.future;
-
-  final String _configKey; // may be null
-
-  /// Delay to wait for more file watcher events.
-  final Duration _debounceDelay;
-
-  /// Injectable factory for creating directory watchers.
-  final DirectoryWatcher Function(String) _directoryWatcherFactory;
-
-  /// Whether or not we will be creating any output directories.
-  ///
-  /// If not, then we don't care about source edits that don't have outputs.
-  final bool _willCreateOutputDirs;
-
-  /// Should complete when we need to kill the build.
-  final _terminateCompleter = Completer<Null>();
-
-  /// The [PackageGraph] for the current program.
-  final PackageGraph packageGraph;
-
-  /// The directories to build upon file changes and where to output them.
-  final Set<BuildDirectory> _buildDirs;
-
-  /// Filters for specific files to build.
-  final Set<BuildFilter> _buildFilters;
-
-  @override
-  Future<BuildResult> currentBuild;
-
-  /// Pending expected delete events from the build.
-  final Set<AssetId> _expectedDeletes = <AssetId>{};
-
-  FinalizedReader _reader;
-  FinalizedReader get reader => _reader;
-
-  WatchImpl(
-      BuildOptions options,
-      BuildEnvironment environment,
-      List<BuilderApplication> builders,
-      Map<String, Map<String, dynamic>> builderConfigOverrides,
-      Future until,
-      this._directoryWatcherFactory,
-      this._configKey,
-      this._willCreateOutputDirs,
-      this._buildDirs,
-      this._buildFilters,
-      {bool isReleaseMode = false})
-      : _debounceDelay = options.debounceDelay,
-        packageGraph = options.packageGraph {
-    buildResults = _run(
-            options, environment, builders, builderConfigOverrides, until,
-            isReleaseMode: isReleaseMode)
-        .asBroadcastStream();
-  }
-
-  @override
-  Stream<BuildResult> buildResults;
-
-  /// Runs a build any time relevant files change.
-  ///
-  /// Only one build will run at a time, and changes are batched.
-  ///
-  /// File watchers are scheduled synchronously.
-  Stream<BuildResult> _run(
-      BuildOptions options,
-      BuildEnvironment environment,
-      List<BuilderApplication> builders,
-      Map<String, Map<String, dynamic>> builderConfigOverrides,
-      Future until,
-      {bool isReleaseMode = false}) {
-    var watcherEnvironment = OverrideableEnvironment(environment,
-        writer: OnDeleteWriter(environment.writer, _expectedDeletes.add));
-    var firstBuildCompleter = Completer<BuildResult>();
-    currentBuild = firstBuildCompleter.future;
-    var controller = StreamController<BuildResult>();
-
-    Future<BuildResult> doBuild(List<List<AssetChange>> changes) async {
-      assert(_build != null);
-      _logger..info('${'-' * 72}\n')..info('Starting Build\n');
-      var mergedChanges = collectChanges(changes);
-
-      _expectedDeletes.clear();
-      if (!options.skipBuildScriptCheck) {
-        if (_build.buildScriptUpdates
-            .hasBeenUpdated(mergedChanges.keys.toSet())) {
-          _terminateCompleter.complete();
-          _logger.severe('Terminating builds due to build script update');
-          return BuildResult(BuildStatus.failure, [],
-              failureType: FailureType.buildScriptChanged);
-        }
-      }
-      return _build.run(mergedChanges,
-          buildDirs: _buildDirs, buildFilters: _buildFilters);
-    }
-
-    var terminate = Future.any([until, _terminateCompleter.future]).then((_) {
-      _logger.info('Terminating. No further builds will be scheduled\n');
-    });
-
-    Digest originalRootPackagesDigest;
-    final rootPackagesId = AssetId(packageGraph.root.name, '.packages');
-
-    // Start watching files immediately, before the first build is even started.
-    var graphWatcher = PackageGraphWatcher(packageGraph,
-        logger: _logger,
-        watch: (node) =>
-            PackageNodeWatcher(node, watch: _directoryWatcherFactory));
-    graphWatcher
-        .watch()
-        .asyncMap<AssetChange>((change) {
-          // Delay any events until the first build is completed.
-          if (firstBuildCompleter.isCompleted) return change;
-          return firstBuildCompleter.future.then((_) => change);
-        })
-        .asyncMap<AssetChange>((change) {
-          var id = change.id;
-          assert(originalRootPackagesDigest != null);
-          if (id == rootPackagesId) {
-            // Kill future builds if the root packages file changes.
-            return watcherEnvironment.reader
-                .readAsBytes(rootPackagesId)
-                .then((bytes) {
-              if (md5.convert(bytes) != originalRootPackagesDigest) {
-                _terminateCompleter.complete();
-                _logger
-                    .severe('Terminating builds due to package graph update, '
-                        'please restart the build.');
-              }
-              return change;
-            });
-          } else if (_isBuildYaml(id) ||
-              _isConfiguredBuildYaml(id) ||
-              _isPackageBuildYamlOverride(id)) {
-            controller.add(BuildResult(BuildStatus.failure, [],
-                failureType: FailureType.buildConfigChanged));
-
-            // Kill future builds if the build.yaml files change.
-            _terminateCompleter.complete();
-            _logger.severe(
-                'Terminating builds due to ${id.package}:${id.path} update.');
-          }
-          return change;
-        })
-        .where((change) {
-          assert(_readyCompleter.isCompleted);
-          return shouldProcess(
-            change,
-            assetGraph,
-            options,
-            _willCreateOutputDirs,
-            _expectedDeletes,
-          );
-        })
-        .debounceBuffer(_debounceDelay)
-        .takeUntil(terminate)
-        .asyncMapBuffer((changes) => currentBuild = doBuild(changes)
-          ..whenComplete(() => currentBuild = null))
-        .listen((BuildResult result) {
-          if (controller.isClosed) return;
-          controller.add(result);
-        })
-        .onDone(() async {
-          await currentBuild;
-          await _build?.beforeExit();
-          if (!controller.isClosed) await controller.close();
-          _logger.info('Builds finished. Safe to exit\n');
-        });
-
-    // Schedule the actual first build for the future so we can return the
-    // stream synchronously.
-    () async {
-      await logTimedAsync(_logger, 'Waiting for all file watchers to be ready',
-          () => graphWatcher.ready);
-      originalRootPackagesDigest = md5
-          .convert(await watcherEnvironment.reader.readAsBytes(rootPackagesId));
-
-      BuildResult firstBuild;
-      try {
-        _build = await BuildImpl.create(
-            options, watcherEnvironment, builders, builderConfigOverrides,
-            isReleaseBuild: isReleaseMode);
-
-        firstBuild = await _build
-            .run({}, buildDirs: _buildDirs, buildFilters: _buildFilters);
-      } on CannotBuildException {
-        _terminateCompleter.complete();
-
-        firstBuild = BuildResult(BuildStatus.failure, []);
-      } on BuildScriptChangedException {
-        _terminateCompleter.complete();
-
-        firstBuild = BuildResult(BuildStatus.failure, [],
-            failureType: FailureType.buildScriptChanged);
-      }
-
-      _reader = _build?.finalizedReader;
-      _readyCompleter.complete();
-      // It is possible this is already closed if the user kills the process
-      // early, which results in an exception without this check.
-      if (!controller.isClosed) controller.add(firstBuild);
-      firstBuildCompleter.complete(firstBuild);
-    }();
-
-    return controller.stream;
-  }
-
-  bool _isBuildYaml(AssetId id) => id.path == 'build.yaml';
-  bool _isConfiguredBuildYaml(AssetId id) =>
-      id.package == packageGraph.root.name &&
-      id.path == 'build.$_configKey.yaml';
-  bool _isPackageBuildYamlOverride(AssetId id) =>
-      id.package == packageGraph.root.name &&
-      id.path.contains(_packageBuildYamlRegexp);
-  final _packageBuildYamlRegexp = RegExp(r'^[a-z0-9_]+\.build\.yaml$');
-}
diff --git a/build_runner/lib/src/logging/std_io_logging.dart b/build_runner/lib/src/logging/std_io_logging.dart
deleted file mode 100644
index fab916b..0000000
--- a/build_runner/lib/src/logging/std_io_logging.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:io/ansi.dart';
-import 'package:logging/logging.dart';
-import 'package:stack_trace/stack_trace.dart';
-
-void Function(LogRecord) stdIOLogListener({bool assumeTty, bool verbose}) =>
-    (record) => overrideAnsiOutput(assumeTty == true || ansiOutputEnabled, () {
-          _stdIOLogListener(record, verbose: verbose ?? false);
-        });
-
-StringBuffer colorLog(LogRecord record, {bool verbose}) {
-  AnsiCode color;
-  if (record.level < Level.WARNING) {
-    color = cyan;
-  } else if (record.level < Level.SEVERE) {
-    color = yellow;
-  } else {
-    color = red;
-  }
-  final level = color.wrap('[${record.level}]');
-  final eraseLine = ansiOutputEnabled && !verbose ? '\x1b[2K\r' : '';
-  var lines = <Object>[
-    '$eraseLine$level ${_recordHeader(record, verbose)}${record.message}'
-  ];
-
-  if (record.error != null) {
-    lines.add(record.error);
-  }
-
-  if (record.stackTrace != null && verbose) {
-    var trace = Trace.from(record.stackTrace).foldFrames((f) {
-      return f.package == 'build_runner' || f.package == 'build';
-    }, terse: true);
-
-    lines.add(trace);
-  }
-
-  var message = StringBuffer(lines.join('\n'));
-
-  // We always add an extra newline at the end of each message, so it
-  // isn't multiline unless we see > 2 lines.
-  var multiLine = LineSplitter.split(message.toString()).length > 2;
-
-  if (record.level > Level.INFO || !ansiOutputEnabled || multiLine || verbose) {
-    // Add an extra line to the output so the last line isn't written over.
-    message.writeln('');
-  }
-  return message;
-}
-
-void _stdIOLogListener(LogRecord record, {bool verbose}) =>
-    stdout.write(colorLog(record, verbose: verbose));
-
-/// Filter out the Logger names which aren't coming from specific builders and
-/// splits the header for levels >= WARNING.
-String _recordHeader(LogRecord record, bool verbose) {
-  var maybeSplit = record.level >= Level.WARNING ? '\n' : '';
-  return verbose || record.loggerName.contains(' ')
-      ? '${record.loggerName}:$maybeSplit'
-      : '';
-}
diff --git a/build_runner/lib/src/package_graph/build_config_overrides.dart b/build_runner/lib/src/package_graph/build_config_overrides.dart
deleted file mode 100644
index 8210b93..0000000
--- a/build_runner/lib/src/package_graph/build_config_overrides.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:build_config/build_config.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-final _log = Logger('BuildConfigOverrides');
-
-Future<Map<String, BuildConfig>> findBuildConfigOverrides(
-    PackageGraph packageGraph, String configKey) async {
-  final configs = <String, BuildConfig>{};
-  final configFiles = Glob('*.build.yaml').list();
-  await for (final file in configFiles) {
-    if (file is File) {
-      final packageName = p.basename(file.path).split('.').first;
-      final packageNode = packageGraph.allPackages[packageName];
-      if (packageNode == null) {
-        _log.warning('A build config override is provided for $packageName but '
-            'that package does not exist. '
-            'Remove the ${p.basename(file.path)} override or add a dependency '
-            'on $packageName.');
-        continue;
-      }
-      final yaml = file.readAsStringSync();
-      final config = BuildConfig.parse(
-        packageName,
-        packageNode.dependencies.map((n) => n.name),
-        yaml,
-        configYamlPath: file.path,
-      );
-      configs[packageName] = config;
-    }
-  }
-  if (configKey != null) {
-    final file = File('build.$configKey.yaml');
-    if (!file.existsSync()) {
-      _log.warning('Cannot find build.$configKey.yaml for specified config.');
-      throw CannotBuildException();
-    }
-    final yaml = file.readAsStringSync();
-    final config = BuildConfig.parse(
-      packageGraph.root.name,
-      packageGraph.root.dependencies.map((n) => n.name),
-      yaml,
-      configYamlPath: file.path,
-    );
-    configs[packageGraph.root.name] = config;
-  }
-  return configs;
-}
diff --git a/build_runner/lib/src/server/README.md b/build_runner/lib/src/server/README.md
deleted file mode 100644
index e40bb70..0000000
--- a/build_runner/lib/src/server/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-## Regenerating the graph_vis_main.dart.js{.map} files
-
-To regenerate these files, you should use the custom build script at
-`tool/build.dart`. This supports all the normal build_runner commands.
diff --git a/build_runner/lib/src/server/asset_graph_handler.dart b/build_runner/lib/src/server/asset_graph_handler.dart
deleted file mode 100644
index 78921e2..0000000
--- a/build_runner/lib/src/server/asset_graph_handler.dart
+++ /dev/null
@@ -1,145 +0,0 @@
-// 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:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:shelf/shelf.dart' as shelf;
-
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-import 'path_to_asset_id.dart';
-
-/// A handler for `/$graph` requests under a specific `rootDir`.
-class AssetGraphHandler {
-  final AssetReader _reader;
-  final String _rootPackage;
-  final AssetGraph _assetGraph;
-
-  AssetGraphHandler(this._reader, this._rootPackage, this._assetGraph);
-
-  /// Returns a response with the information about a specific node in the
-  /// graph.
-  ///
-  /// For an empty path, returns the HTML page to render the graph.
-  ///
-  /// For queries with `q=QUERY` will look for the assetNode referenced.
-  /// QUERY can be an [AssetId] or a path.
-  ///
-  /// [AssetId] as `package|path`
-  ///
-  /// path as:
-  /// - `packages/<package>/<path_under_lib>`
-  /// - `<path_under_root_package>`
-  /// - `<path_under_rootDir>`
-  ///
-  /// There may be some ambiguity between paths which are under the top-level of
-  /// the root package, and those which are under the rootDir. Preference is
-  /// given to the asset (if it exists) which is not under the implicit
-  /// `rootDir`. For instance if the request is `$graph/web/main.dart` this will
-  /// prefer to serve `<package>|web/main.dart`, but if it does not exist will
-  /// fall back to `<package>|web/web/main.dart`.
-  FutureOr<shelf.Response> handle(shelf.Request request, String rootDir) async {
-    switch (request.url.path) {
-      case '':
-        if (!request.url.hasQuery) {
-          return shelf.Response.ok(
-              await _reader.readAsString(
-                  AssetId('build_runner', 'lib/src/server/graph_viz.html')),
-              headers: {HttpHeaders.contentTypeHeader: 'text/html'});
-        }
-
-        var query = request.url.queryParameters['q']?.trim();
-        if (query != null && query.isNotEmpty) {
-          var filter = request.url.queryParameters['f']?.trim();
-          return _handleQuery(query, rootDir, filter: filter);
-        }
-        break;
-      case 'assets.json':
-        return _jsonResponse(_assetGraph.serialize());
-    }
-
-    return shelf.Response.notFound('Bad request: "${request.url}".');
-  }
-
-  Future<shelf.Response> _handleQuery(String query, String rootDir,
-      {String filter}) async {
-    var filterGlob = filter != null ? Glob(filter) : null;
-    var pipeIndex = query.indexOf('|');
-
-    AssetId assetId;
-    if (pipeIndex < 0) {
-      var querySplit = query.split('/');
-
-      assetId = pathToAssetId(
-          _rootPackage, querySplit.first, querySplit.skip(1).toList());
-
-      if (!_assetGraph.contains(assetId)) {
-        var secondTry = pathToAssetId(_rootPackage, rootDir, querySplit);
-
-        if (!_assetGraph.contains(secondTry)) {
-          return shelf.Response.notFound(
-              'Could not find asset for path "$query". Tried:\n'
-              '- $assetId\n'
-              '- $secondTry');
-        }
-        assetId = secondTry;
-      }
-    } else {
-      assetId = AssetId.parse(query);
-      if (!_assetGraph.contains(assetId)) {
-        return shelf.Response.notFound(
-            'Could not find asset in build graph: $assetId');
-      }
-    }
-    var node = _assetGraph.get(assetId);
-    var currentEdge = 0;
-    var nodes = [
-      {'id': '${node.id}', 'label': '${node.id}'}
-    ];
-    var edges = <Map<String, String>>[];
-    for (final output in node.outputs) {
-      if (filterGlob != null && !filterGlob.matches(output.toString())) {
-        continue;
-      }
-      edges.add(
-          {'from': '${node.id}', 'to': '$output', 'id': 'e${currentEdge++}'});
-      nodes.add({'id': '$output', 'label': '$output'});
-    }
-    if (node is NodeWithInputs) {
-      for (final input in node.inputs) {
-        if (filterGlob != null && !filterGlob.matches(input.toString())) {
-          continue;
-        }
-        edges.add(
-            {'from': '$input', 'to': '${node.id}', 'id': 'e${currentEdge++}'});
-        nodes.add({'id': '$input', 'label': '$input'});
-      }
-    }
-    var result = <String, dynamic>{
-      'primary': {
-        'id': '${node.id}',
-        'hidden': node is GeneratedAssetNode ? node.isHidden : null,
-        'state': node is NodeWithInputs ? '${node.state}' : null,
-        'wasOutput': node is GeneratedAssetNode ? node.wasOutput : null,
-        'isFailure': node is GeneratedAssetNode ? node.isFailure : null,
-        'phaseNumber': node is NodeWithInputs ? node.phaseNumber : null,
-        'type': node.runtimeType.toString(),
-        'glob': node is GlobAssetNode ? node.glob.pattern : null,
-        'lastKnownDigest': node.lastKnownDigest.toString(),
-      },
-      'edges': edges,
-      'nodes': nodes,
-    };
-    return _jsonResponse(_jsonUtf8Encoder.convert(result));
-  }
-}
-
-final _jsonUtf8Encoder = JsonUtf8Encoder();
-
-shelf.Response _jsonResponse(List<int> body) => shelf.Response.ok(body,
-    headers: {HttpHeaders.contentTypeHeader: 'application/json'});
diff --git a/build_runner/lib/src/server/build_updates_client/module.dart b/build_runner/lib/src/server/build_updates_client/module.dart
deleted file mode 100644
index 6604f9b..0000000
--- a/build_runner/lib/src/server/build_updates_client/module.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.
-
-abstract class Library {
-  Object onDestroy();
-
-  bool onSelfUpdate([Object data]);
-
-  bool onChildUpdate(String childId, Library child, [Object data]);
-}
-
-/// Used for representation of amd modules that wraps several dart libraries
-/// inside
-class Module {
-  /// Grouped by absolute library path starting with `package:`
-  final Map<String, Library> libraries;
-
-  Module(this.libraries);
-
-  /// Calls onDestroy on each of underlined libraries and combines returned data
-  Map<String, Object> onDestroy() {
-    var data = <String, Object>{};
-    for (var key in libraries.keys) {
-      data[key] = libraries[key].onDestroy();
-    }
-    return data;
-  }
-
-  /// Calls onSelfUpdate on each of underlined libraries, returns aggregated
-  /// result as "maximum" assuming true < null < false. Stops execution on first
-  /// false result
-  bool onSelfUpdate(Map<String, Object> data) {
-    var result = true;
-    for (var key in libraries.keys) {
-      var success = libraries[key].onSelfUpdate(data[key]);
-      if (success == false) {
-        return false;
-      } else if (success == null) {
-        result = success;
-      }
-    }
-    return result;
-  }
-
-  /// Calls onChildUpdate on each of underlined libraries, returns aggregated
-  /// result as "maximum" assuming true < null < false. Stops execution on first
-  /// false result
-  bool onChildUpdate(String childId, Module child, Map<String, Object> data) {
-    var result = true;
-    // TODO(inayd): This is a rought implementation with lots of false positive
-    // reloads. In current implementation every library in parent module should
-    // know how to handle each library in child module. Also [roughLibraryKeyDecode]
-    // depends on unreliable implementation details. Proper implementation
-    // should rely on inner graph of dependencies between libraries in module,
-    // to require only parent libraries which really depend on child ones to
-    // handle it's updates. See dart-lang/build#1767.
-    for (var parentKey in libraries.keys) {
-      for (var childKey in child.libraries.keys) {
-        var success = libraries[parentKey]
-            .onChildUpdate(childKey, child.libraries[childKey], data[childKey]);
-        if (success == false) {
-          return false;
-        } else if (success == null) {
-          result = success;
-        }
-      }
-    }
-    return result;
-  }
-}
diff --git a/build_runner/lib/src/server/build_updates_client/reload_handler.dart b/build_runner/lib/src/server/build_updates_client/reload_handler.dart
deleted file mode 100644
index 0087931..0000000
--- a/build_runner/lib/src/server/build_updates_client/reload_handler.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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:convert';
-
-import 'reloading_manager.dart';
-
-/// Provides [listener] to handle web socket connection and reload invalidated
-/// modules using [ReloadingManager]
-class ReloadHandler {
-  final String Function(String) _moduleIdByPath;
-  final Map<String, String> _digests;
-  final ReloadingManager _reloadingManager;
-
-  ReloadHandler(this._digests, this._moduleIdByPath, this._reloadingManager);
-
-  void listener(String data) async {
-    var updatedAssetDigests = json.decode(data) as Map<String, dynamic>;
-    var moduleIdsToReload = <String>[];
-    for (var path in updatedAssetDigests.keys) {
-      if (_digests[path] == updatedAssetDigests[path]) {
-        continue;
-      }
-      var moduleId = _moduleIdByPath(path);
-      if (_digests.containsKey(path) && moduleId != null) {
-        moduleIdsToReload.add(moduleId);
-      }
-      _digests[path] = updatedAssetDigests[path] as String;
-    }
-    if (moduleIdsToReload.isNotEmpty) {
-      _reloadingManager.updateGraph();
-      await _reloadingManager.reload(moduleIdsToReload);
-    }
-  }
-}
diff --git a/build_runner/lib/src/server/build_updates_client/reloading_manager.dart b/build_runner/lib/src/server/build_updates_client/reloading_manager.dart
deleted file mode 100644
index 969aaee..0000000
--- a/build_runner/lib/src/server/build_updates_client/reloading_manager.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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:collection';
-
-import 'package:graphs/graphs.dart' as graphs;
-
-import 'module.dart';
-
-class HotReloadFailedException implements Exception {
-  HotReloadFailedException(this._s);
-
-  @override
-  String toString() => "HotReloadFailedException: '$_s'";
-  final String _s;
-}
-
-/// Handles reloading order and hooks invocation
-class ReloadingManager {
-  final Future<Module> Function(String) _reloadModule;
-  final Module Function(String) _moduleLibraries;
-  final void Function() _reloadPage;
-  final List<String> Function(String moduleId) _moduleParents;
-  final Iterable<String> Function() _allModules;
-
-  final Map<String, int> _moduleOrdering = {};
-  SplayTreeSet<String> _dirtyModules;
-  Completer<void> _running = Completer()..complete();
-
-  int moduleTopologicalCompare(String module1, String module2) {
-    var topological =
-        Comparable.compare(_moduleOrdering[module2], _moduleOrdering[module1]);
-    // If modules are in cycle (same strongly connected component) compare their
-    // string id, to ensure total ordering for SplayTreeSet uniqueness.
-    return topological != 0 ? topological : module1.compareTo(module2);
-  }
-
-  void updateGraph() {
-    var allModules = _allModules();
-    var stronglyConnectedComponents =
-        graphs.stronglyConnectedComponents(allModules, _moduleParents);
-    _moduleOrdering.clear();
-    for (var i = 0; i < stronglyConnectedComponents.length; i++) {
-      for (var module in stronglyConnectedComponents[i]) {
-        _moduleOrdering[module] = i;
-      }
-    }
-  }
-
-  ReloadingManager(this._reloadModule, this._moduleLibraries, this._reloadPage,
-      this._moduleParents, this._allModules) {
-    _dirtyModules = SplayTreeSet(moduleTopologicalCompare);
-  }
-
-  Future<void> reload(List<String> modules) async {
-    _dirtyModules.addAll(modules);
-
-    // As function is async, it can potentially be called second time while
-    // first invocation is still running. In this case just mark as dirty and
-    // wait until loop from the first call will do the work
-    if (!_running.isCompleted) return await _running.future;
-    _running = Completer();
-
-    var reloadedModules = 0;
-
-    try {
-      while (_dirtyModules.isNotEmpty) {
-        var moduleId = _dirtyModules.first;
-        _dirtyModules.remove(moduleId);
-        ++reloadedModules;
-
-        var existing = _moduleLibraries(moduleId);
-        var data = existing.onDestroy();
-
-        var newVersion = await _reloadModule(moduleId);
-        var success = newVersion.onSelfUpdate(data);
-        if (success == true) continue;
-        if (success == false) {
-          print("Module '$moduleId' is marked as unreloadable. "
-              'Firing full page reload.');
-          _reloadPage();
-          _running.complete();
-          return;
-        }
-
-        var parentIds = _moduleParents(moduleId);
-        if (parentIds == null || parentIds.isEmpty) {
-          print("Module reloading wasn't handled by any of parents. "
-              'Firing full page reload.');
-          _reloadPage();
-          _running.complete();
-          return;
-        }
-        parentIds.sort(moduleTopologicalCompare);
-        for (var parentId in parentIds) {
-          var parentModule = _moduleLibraries(parentId);
-          success = parentModule.onChildUpdate(moduleId, newVersion, data);
-          if (success == true) continue;
-          if (success == false) {
-            print("Module '$moduleId' is marked as unreloadable. "
-                'Firing full page reload.');
-            _reloadPage();
-            _running.complete();
-            return;
-          }
-          _dirtyModules.add(parentId);
-        }
-      }
-      print('$reloadedModules modules were hot-reloaded.');
-    } on HotReloadFailedException catch (e) {
-      print('Error during script reloading. Firing full page reload. $e');
-      _reloadPage();
-    }
-    _running.complete();
-  }
-}
diff --git a/build_runner/lib/src/server/path_to_asset_id.dart b/build_runner/lib/src/server/path_to_asset_id.dart
deleted file mode 100644
index 3169b0f..0000000
--- a/build_runner/lib/src/server/path_to_asset_id.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-
-AssetId pathToAssetId(
-    String rootPackage, String rootDir, List<String> pathSegments) {
-  var packagesIndex = pathSegments.indexOf('packages');
-  rootDir ??= '';
-  return packagesIndex >= 0
-      ? AssetId(pathSegments[packagesIndex + 1],
-          p.join('lib', p.joinAll(pathSegments.sublist(packagesIndex + 2))))
-      : AssetId(rootPackage, p.joinAll([rootDir].followedBy(pathSegments)));
-}
-
-/// Returns null for paths that neither a lib nor starts from a rootDir
-String assetIdToPath(AssetId assetId, String rootDir) =>
-    assetId.path.startsWith('lib/')
-        ? assetId.path.replaceFirst('lib/', 'packages/${assetId.package}/')
-        : assetId.path.startsWith('$rootDir/')
-            ? assetId.path.substring(rootDir.length + 1)
-            : null;
diff --git a/build_runner/lib/src/server/server.dart b/build_runner/lib/src/server/server.dart
deleted file mode 100644
index 9c568b8..0000000
--- a/build_runner/lib/src/server/server.dart
+++ /dev/null
@@ -1,681 +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:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:build_runner/src/entrypoint/options.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/generate/performance_tracker.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:mime/mime.dart';
-import 'package:path/path.dart' as p;
-import 'package:shelf/shelf.dart' as shelf;
-import 'package:shelf_web_socket/shelf_web_socket.dart';
-import 'package:timing/timing.dart';
-import 'package:web_socket_channel/web_socket_channel.dart';
-
-import '../generate/watch_impl.dart';
-import 'asset_graph_handler.dart';
-import 'path_to_asset_id.dart';
-
-const _performancePath = r'$perf';
-final _graphPath = r'$graph';
-final _assetsDigestPath = r'$assetDigests';
-final _buildUpdatesProtocol = r'$buildUpdates';
-final entrypointExtensionMarker = '/* ENTRYPOINT_EXTENTION_MARKER */';
-
-final _logger = Logger('Serve');
-
-enum PerfSortOrder {
-  startTimeAsc,
-  startTimeDesc,
-  stopTimeAsc,
-  stopTimeDesc,
-  durationAsc,
-  durationDesc,
-  innerDurationAsc,
-  innerDurationDesc
-}
-
-ServeHandler createServeHandler(WatchImpl watch) {
-  var rootPackage = watch.packageGraph.root.name;
-  var assetGraphHanderCompleter = Completer<AssetGraphHandler>();
-  var assetHandlerCompleter = Completer<AssetHandler>();
-  watch.ready.then((_) async {
-    assetHandlerCompleter.complete(AssetHandler(watch.reader, rootPackage));
-    assetGraphHanderCompleter.complete(
-        AssetGraphHandler(watch.reader, rootPackage, watch.assetGraph));
-  });
-  return ServeHandler._(watch, assetHandlerCompleter.future,
-      assetGraphHanderCompleter.future, rootPackage);
-}
-
-class ServeHandler implements BuildState {
-  final WatchImpl _state;
-  BuildResult _lastBuildResult;
-  final String _rootPackage;
-
-  final Future<AssetHandler> _assetHandler;
-  final Future<AssetGraphHandler> _assetGraphHandler;
-
-  final BuildUpdatesWebSocketHandler _webSocketHandler;
-
-  ServeHandler._(this._state, this._assetHandler, this._assetGraphHandler,
-      this._rootPackage)
-      : _webSocketHandler = BuildUpdatesWebSocketHandler(_state) {
-    _state.buildResults.listen((result) {
-      _lastBuildResult = result;
-      _webSocketHandler.emitUpdateMessage(result);
-    }).onDone(_webSocketHandler.close);
-  }
-
-  @override
-  Future<BuildResult> get currentBuild => _state.currentBuild;
-
-  @override
-  Stream<BuildResult> get buildResults => _state.buildResults;
-
-  shelf.Handler handlerFor(String rootDir,
-      {bool logRequests, BuildUpdatesOption buildUpdates}) {
-    buildUpdates ??= BuildUpdatesOption.none;
-    logRequests ??= false;
-    if (p.url.split(rootDir).length != 1 || rootDir == '.') {
-      throw ArgumentError.value(
-        rootDir,
-        'directory',
-        'Only top level directories such as `web` or `test` can be served, got',
-      );
-    }
-    _state.currentBuild.then((_) {
-      // If the first build fails with a handled exception, we might not have
-      // an asset graph and can't do this check.
-      if (_state.assetGraph == null) return;
-      _warnForEmptyDirectory(rootDir);
-    });
-    var cascade = shelf.Cascade();
-    if (buildUpdates != BuildUpdatesOption.none) {
-      cascade = cascade.add(_webSocketHandler.createHandlerByRootDir(rootDir));
-    }
-    cascade =
-        cascade.add(_blockOnCurrentBuild).add((shelf.Request request) async {
-      if (request.url.path == _performancePath) {
-        return _performanceHandler(request);
-      }
-      if (request.url.path == _assetsDigestPath) {
-        return _assetsDigestHandler(request, rootDir);
-      }
-      if (request.url.path.startsWith(_graphPath)) {
-        var graphHandler = await _assetGraphHandler;
-        return await graphHandler.handle(
-            request.change(path: _graphPath), rootDir);
-      }
-      var assetHandler = await _assetHandler;
-      return assetHandler.handle(request, rootDir: rootDir);
-    });
-    var pipeline = shelf.Pipeline();
-    if (logRequests) {
-      pipeline = pipeline.addMiddleware(_logRequests);
-    }
-    switch (buildUpdates) {
-      case BuildUpdatesOption.liveReload:
-        pipeline = pipeline.addMiddleware(_injectLiveReloadClientCode);
-        break;
-      case BuildUpdatesOption.hotReload:
-        pipeline = pipeline.addMiddleware(_injectHotReloadClientCode);
-        break;
-      case BuildUpdatesOption.none:
-        break;
-    }
-    return pipeline.addHandler(cascade.handler);
-  }
-
-  Future<shelf.Response> _blockOnCurrentBuild(void _) async {
-    await currentBuild;
-    return shelf.Response.notFound('');
-  }
-
-  shelf.Response _performanceHandler(shelf.Request request) {
-    var hideSkipped = false;
-    var detailedSlices = false;
-    var slicesResolution = 5;
-    var sortOrder = PerfSortOrder.startTimeAsc;
-    var filter = request.url.queryParameters['filter'] ?? '';
-    if (request.url.queryParameters['hideSkipped']?.toLowerCase() == 'true') {
-      hideSkipped = true;
-    }
-    if (request.url.queryParameters['detailedSlices']?.toLowerCase() ==
-        'true') {
-      detailedSlices = true;
-    }
-    if (request.url.queryParameters.containsKey('slicesResolution')) {
-      slicesResolution =
-          int.parse(request.url.queryParameters['slicesResolution']);
-    }
-    if (request.url.queryParameters.containsKey('sortOrder')) {
-      sortOrder = PerfSortOrder
-          .values[int.parse(request.url.queryParameters['sortOrder'])];
-    }
-    return shelf.Response.ok(
-        _renderPerformance(_lastBuildResult.performance, hideSkipped,
-            detailedSlices, slicesResolution, sortOrder, filter),
-        headers: {HttpHeaders.contentTypeHeader: 'text/html'});
-  }
-
-  Future<shelf.Response> _assetsDigestHandler(
-      shelf.Request request, String rootDir) async {
-    var assertPathList =
-        (jsonDecode(await request.readAsString()) as List).cast<String>();
-    var rootPackage = _state.packageGraph.root.name;
-    var results = <String, String>{};
-    for (final path in assertPathList) {
-      try {
-        var assetId = pathToAssetId(rootPackage, rootDir, p.url.split(path));
-        var digest = await _state.reader.digest(assetId);
-        results[path] = digest.toString();
-      } on AssetNotFoundException {
-        results.remove(path);
-      }
-    }
-    return shelf.Response.ok(jsonEncode(results),
-        headers: {HttpHeaders.contentTypeHeader: 'application/json'});
-  }
-
-  void _warnForEmptyDirectory(String rootDir) {
-    if (!_state.assetGraph
-        .packageNodes(_rootPackage)
-        .any((n) => n.id.path.startsWith('$rootDir/'))) {
-      _logger.warning('Requested a server for `$rootDir` but this directory '
-          'has no assets in the build. You may need to add some sources or '
-          'include this directory in some target in your `build.yaml`');
-    }
-  }
-}
-
-/// Class that manages web socket connection handler to inform clients about
-/// build updates
-class BuildUpdatesWebSocketHandler {
-  final connectionsByRootDir = <String, List<WebSocketChannel>>{};
-  final shelf.Handler Function(Function, {Iterable<String> protocols})
-      _handlerFactory;
-  final _internalHandlers = <String, shelf.Handler>{};
-  final WatchImpl _state;
-
-  BuildUpdatesWebSocketHandler(this._state,
-      [this._handlerFactory = webSocketHandler]);
-
-  shelf.Handler createHandlerByRootDir(String rootDir) {
-    if (!_internalHandlers.containsKey(rootDir)) {
-      var closureForRootDir = (WebSocketChannel webSocket, String protocol) =>
-          _handleConnection(webSocket, protocol, rootDir);
-      _internalHandlers[rootDir] = _handlerFactory(closureForRootDir,
-          protocols: [_buildUpdatesProtocol]);
-    }
-    return _internalHandlers[rootDir];
-  }
-
-  Future emitUpdateMessage(BuildResult buildResult) async {
-    if (buildResult.status != BuildStatus.success) return;
-    var digests = <AssetId, String>{};
-    for (var assetId in buildResult.outputs) {
-      var digest = await _state.reader.digest(assetId);
-      digests[assetId] = digest.toString();
-    }
-    for (var rootDir in connectionsByRootDir.keys) {
-      var resultMap = <String, String>{};
-      for (var assetId in digests.keys) {
-        var path = assetIdToPath(assetId, rootDir);
-        if (path != null) {
-          resultMap[path] = digests[assetId];
-        }
-      }
-      for (var connection in connectionsByRootDir[rootDir]) {
-        connection.sink.add(jsonEncode(resultMap));
-      }
-    }
-  }
-
-  void _handleConnection(
-      WebSocketChannel webSocket, String protocol, String rootDir) async {
-    if (!connectionsByRootDir.containsKey(rootDir)) {
-      connectionsByRootDir[rootDir] = [];
-    }
-    connectionsByRootDir[rootDir].add(webSocket);
-    await webSocket.stream.drain();
-    connectionsByRootDir[rootDir].remove(webSocket);
-    if (connectionsByRootDir[rootDir].isEmpty) {
-      connectionsByRootDir.remove(rootDir);
-    }
-  }
-
-  Future<void> close() {
-    return Future.wait(connectionsByRootDir.values
-        .expand((x) => x)
-        .map((connection) => connection.sink.close()));
-  }
-}
-
-shelf.Handler Function(shelf.Handler) _injectBuildUpdatesClientCode(
-        String scriptName) =>
-    (innerHandler) {
-      return (shelf.Request request) async {
-        if (!request.url.path.endsWith('.js')) {
-          return innerHandler(request);
-        }
-        var response = await innerHandler(request);
-        // TODO: Find a way how to check and/or modify body without reading it
-        // whole.
-        var body = await response.readAsString();
-        if (body.startsWith(entrypointExtensionMarker)) {
-          body += _buildUpdatesInjectedJS(scriptName);
-          var originalEtag = response.headers[HttpHeaders.etagHeader];
-          if (originalEtag != null) {
-            var newEtag = base64.encode(md5.convert(body.codeUnits).bytes);
-            var newHeaders = Map.of(response.headers);
-            newHeaders[HttpHeaders.etagHeader] = newEtag;
-
-            if (request.headers[HttpHeaders.ifNoneMatchHeader] == newEtag) {
-              return shelf.Response.notModified(headers: newHeaders);
-            }
-
-            response = response.change(headers: newHeaders);
-          }
-        }
-        return response.change(body: body);
-      };
-    };
-
-final _injectHotReloadClientCode =
-    _injectBuildUpdatesClientCode('hot_reload_client.dart');
-
-final _injectLiveReloadClientCode =
-    _injectBuildUpdatesClientCode('live_reload_client');
-
-/// Hot-/live- reload config
-///
-/// Listen WebSocket for updates in build results
-String _buildUpdatesInjectedJS(String scriptName) => '''\n
-// Injected by build_runner for build updates support
-window.\$dartLoader.forceLoadModule('packages/build_runner/src/server/build_updates_client/$scriptName');
-''';
-
-class AssetHandler {
-  final FinalizedReader _reader;
-  final String _rootPackage;
-
-  final _typeResolver = MimeTypeResolver();
-
-  AssetHandler(this._reader, this._rootPackage);
-
-  Future<shelf.Response> handle(shelf.Request request, {String rootDir}) =>
-      (request.url.path.endsWith('/') || request.url.path.isEmpty)
-          ? _handle(
-              request.headers,
-              pathToAssetId(
-                  _rootPackage,
-                  rootDir,
-                  request.url.pathSegments
-                      .followedBy(const ['index.html']).toList()),
-              fallbackToDirectoryList: true)
-          : _handle(request.headers,
-              pathToAssetId(_rootPackage, rootDir, request.url.pathSegments));
-
-  Future<shelf.Response> _handle(
-      Map<String, String> requestHeaders, AssetId assetId,
-      {bool fallbackToDirectoryList = false}) async {
-    try {
-      if (!await _reader.canRead(assetId)) {
-        var reason = await _reader.unreadableReason(assetId);
-        switch (reason) {
-          case UnreadableReason.failed:
-            return shelf.Response.internalServerError(
-                body: 'Build failed for $assetId');
-          case UnreadableReason.notOutput:
-            return shelf.Response.notFound('$assetId was not output');
-          case UnreadableReason.notFound:
-            if (fallbackToDirectoryList) {
-              return shelf.Response.notFound(await _findDirectoryList(assetId));
-            }
-            return shelf.Response.notFound('Not Found');
-          default:
-            return shelf.Response.notFound('Not Found');
-        }
-      }
-    } on ArgumentError catch (_) {
-      return shelf.Response.notFound('Not Found');
-    }
-
-    var etag = base64.encode((await _reader.digest(assetId)).bytes);
-    var contentType = _typeResolver.lookup(assetId.path);
-    if (contentType == 'text/x-dart') contentType += '; charset=utf-8';
-    var headers = {
-      HttpHeaders.contentTypeHeader: contentType,
-      HttpHeaders.etagHeader: etag,
-      // We always want this revalidated, which requires specifying both
-      // max-age=0 and must-revalidate.
-      //
-      // See spec https://goo.gl/Lhvttg for more info about this header.
-      HttpHeaders.cacheControlHeader: 'max-age=0, must-revalidate',
-    };
-
-    if (requestHeaders[HttpHeaders.ifNoneMatchHeader] == etag) {
-      // This behavior is still useful for cases where a file is hit
-      // without a cache-busting query string.
-      return shelf.Response.notModified(headers: headers);
-    }
-
-    var bytes = await _reader.readAsBytes(assetId);
-    headers[HttpHeaders.contentLengthHeader] = '${bytes.length}';
-    return shelf.Response.ok(bytes, headers: headers);
-  }
-
-  Future<String> _findDirectoryList(AssetId from) async {
-    var directoryPath = p.url.dirname(from.path);
-    var glob = p.url.join(directoryPath, '*');
-    var result =
-        await _reader.findAssets(Glob(glob)).map((a) => a.path).toList();
-    var message = StringBuffer('Could not find ${from.path}');
-    if (result.isEmpty) {
-      message.write(' or any files in $directoryPath. ');
-    } else {
-      message
-        ..write('. $directoryPath contains:')
-        ..writeAll(result, '\n')
-        ..writeln();
-    }
-    message
-        .write(' See https://github.com/dart-lang/build/blob/master/docs/faq.md'
-            '#why-cant-i-see-a-file-i-know-exists');
-    return '$message';
-  }
-}
-
-String _renderPerformance(
-    BuildPerformance performance,
-    bool hideSkipped,
-    bool detailedSlices,
-    int slicesResolution,
-    PerfSortOrder sortOrder,
-    String filter) {
-  try {
-    var rows = StringBuffer();
-    final resolution = Duration(milliseconds: slicesResolution);
-    var count = 0,
-        maxSlices = 1,
-        max = 0,
-        min = performance.stopTime.millisecondsSinceEpoch -
-            performance.startTime.millisecondsSinceEpoch;
-
-    void writeRow(BuilderActionPerformance action,
-        BuilderActionStagePerformance stage, TimeSlice slice) {
-      var actionKey = '${action.builderKey}:${action.primaryInput}';
-      var tooltip = '<div class=perf-tooltip>'
-          '<p><b>Builder:</b> ${action.builderKey}</p>'
-          '<p><b>Input:</b> ${action.primaryInput}</p>'
-          '<p><b>Stage:</b> ${stage.label}</p>'
-          '<p><b>Stage time:</b> '
-          '${stage.startTime.difference(performance.startTime).inMilliseconds / 1000}s - '
-          '${stage.stopTime.difference(performance.startTime).inMilliseconds / 1000}s</p>'
-          '<p><b>Stage real duration:</b> ${stage.duration.inMilliseconds / 1000} seconds</p>'
-          '<p><b>Stage user duration:</b> ${stage.innerDuration.inMilliseconds / 1000} seconds</p>';
-      if (slice != stage) {
-        tooltip += '<p><b>Slice time:</b> '
-            '${slice.startTime.difference(performance.startTime).inMilliseconds / 1000}s - '
-            '${slice.stopTime.difference(performance.startTime).inMilliseconds / 1000}s</p>'
-            '<p><b>Slice duration:</b> ${slice.duration.inMilliseconds / 1000} seconds</p>';
-      }
-      tooltip += '</div>';
-      var start = slice.startTime.millisecondsSinceEpoch -
-          performance.startTime.millisecondsSinceEpoch;
-      var end = slice.stopTime.millisecondsSinceEpoch -
-          performance.startTime.millisecondsSinceEpoch;
-
-      if (min > start) min = start;
-      if (max < end) max = end;
-
-      rows.writeln(
-          '          ["$actionKey", "${stage.label}", "$tooltip", $start, $end],');
-      ++count;
-    }
-
-    final filterRegex = filter.isNotEmpty ? RegExp(filter) : null;
-
-    final actions = performance.actions
-        .where((action) =>
-            !hideSkipped ||
-            action.stages.any((stage) => stage.label == 'Build'))
-        .where((action) =>
-            filterRegex == null ||
-            filterRegex.hasMatch('${action.builderKey}:${action.primaryInput}'))
-        .toList();
-
-    int Function(BuilderActionPerformance, BuilderActionPerformance) comparator;
-    switch (sortOrder) {
-      case PerfSortOrder.startTimeAsc:
-        comparator = (a1, a2) => a1.startTime.compareTo(a2.startTime);
-        break;
-      case PerfSortOrder.startTimeDesc:
-        comparator = (a1, a2) => a2.startTime.compareTo(a1.startTime);
-        break;
-      case PerfSortOrder.stopTimeAsc:
-        comparator = (a1, a2) => a1.stopTime.compareTo(a2.stopTime);
-        break;
-      case PerfSortOrder.stopTimeDesc:
-        comparator = (a1, a2) => a2.stopTime.compareTo(a1.stopTime);
-        break;
-      case PerfSortOrder.durationAsc:
-        comparator = (a1, a2) => a1.duration.compareTo(a2.duration);
-        break;
-      case PerfSortOrder.durationDesc:
-        comparator = (a1, a2) => a2.duration.compareTo(a1.duration);
-        break;
-      case PerfSortOrder.innerDurationAsc:
-        comparator = (a1, a2) => a1.innerDuration.compareTo(a2.innerDuration);
-        break;
-      case PerfSortOrder.innerDurationDesc:
-        comparator = (a1, a2) => a2.innerDuration.compareTo(a1.innerDuration);
-        break;
-    }
-    actions.sort(comparator);
-
-    for (var action in actions) {
-      if (hideSkipped &&
-          !action.stages.any((stage) => stage.label == 'Build')) {
-        continue;
-      }
-      for (var stage in action.stages) {
-        if (!detailedSlices) {
-          writeRow(action, stage, stage);
-          continue;
-        }
-        var slices = stage.slices.fold<List<TimeSlice>>([], (list, slice) {
-          if (list.isNotEmpty &&
-              slice.startTime.difference(list.last.stopTime) < resolution) {
-            // concat with previous if gap less than resolution
-            list.last = TimeSlice(list.last.startTime, slice.stopTime);
-          } else {
-            if (list.length > 1 && list.last.duration < resolution) {
-              // remove previous if its duration less than resolution
-              list.last = slice;
-            } else {
-              list.add(slice);
-            }
-          }
-          return list;
-        });
-        if (slices.isNotEmpty) {
-          for (var slice in slices) {
-            writeRow(action, stage, slice);
-          }
-        } else {
-          writeRow(action, stage, stage);
-        }
-        if (maxSlices < slices.length) maxSlices = slices.length;
-      }
-    }
-    if (max - min < 1000) {
-      rows.writeln('          ['
-          '"https://github.com/google/google-visualization-issues/issues/2269"'
-          ', "", "", $min, ${min + 1000}]');
-    }
-    return '''
-  <html>
-    <head>
-      <script src="https://www.gstatic.com/charts/loader.js"></script>
-      <script>
-        google.charts.load('current', {'packages':['timeline']});
-        google.charts.setOnLoadCallback(drawChart);
-        function drawChart() {
-          var container = document.getElementById('timeline');
-          var chart = new google.visualization.Timeline(container);
-          var dataTable = new google.visualization.DataTable();
-
-          dataTable.addColumn({ type: 'string', id: 'ActionKey' });
-          dataTable.addColumn({ type: 'string', id: 'Stage' });
-          dataTable.addColumn({ type: 'string', role: 'tooltip', p: { html: true } });
-          dataTable.addColumn({ type: 'number', id: 'Start' });
-          dataTable.addColumn({ type: 'number', id: 'End' });
-          dataTable.addRows([
-  $rows
-          ]);
-
-          console.log('rendering', $count, 'blocks, max', $maxSlices,
-            'slices in stage, resolution', $slicesResolution, 'ms');
-          var options = {
-            tooltip: { isHtml: true }
-          };
-          var statusText = document.getElementById('status');
-          var timeoutId;
-          var updateFunc = function () {
-              if (timeoutId) {
-                  // don't schedule more than one at a time
-                  return;
-              }
-              statusText.innerText = 'Drawing table...';
-              console.time('draw-time');
-
-              timeoutId = setTimeout(function () {
-                  chart.draw(dataTable, options);
-                  console.timeEnd('draw-time');
-                  statusText.innerText = '';
-                  timeoutId = null;
-              });
-          };
-
-          updateFunc();
-
-          window.addEventListener('resize', updateFunc);
-        }
-      </script>
-      <style>
-      html, body {
-        width: 100%;
-        height: 100%;
-        margin: 0;
-      }
-
-      body {
-        display: flex;
-        flex-direction: column;
-      }
-
-      #timeline {
-        display: flex;
-        flex-direction: row;
-        flex: 1;
-      }
-      .controls-header p {
-        display: inline-block;
-        margin: 0.5em;
-      }
-      .perf-tooltip {
-        margin: 0.5em;
-      }
-      </style>
-    </head>
-    <body>
-      <form class="controls-header" action="/$_performancePath" onchange="this.submit()">
-        <p><label><input type="checkbox" name="hideSkipped" value="true" ${hideSkipped ? 'checked' : ''}> Hide Skipped Actions</label></p>
-        <p><label><input type="checkbox" name="detailedSlices" value="true" ${detailedSlices ? 'checked' : ''}> Show Async Slices</label></p>
-        <p>Sort by: <select name="sortOrder">
-          <option value="0" ${sortOrder.index == 0 ? 'selected' : ''}>Start Time Asc</option>
-          <option value="1" ${sortOrder.index == 1 ? 'selected' : ''}>Start Time Desc</option>
-          <option value="2" ${sortOrder.index == 2 ? 'selected' : ''}>Stop Time Asc</option>
-          <option value="3" ${sortOrder.index == 3 ? 'selected' : ''}>Stop Time Desc</option>
-          <option value="5" ${sortOrder.index == 4 ? 'selected' : ''}>Real Duration Asc</option>
-          <option value="5" ${sortOrder.index == 5 ? 'selected' : ''}>Real Duration Desc</option>
-          <option value="6" ${sortOrder.index == 6 ? 'selected' : ''}>User Duration Asc</option>
-          <option value="7" ${sortOrder.index == 7 ? 'selected' : ''}>User Duration Desc</option>
-        </select></p>
-        <p>Slices Resolution: <select name="slicesResolution">
-          <option value="0" ${slicesResolution == 0 ? 'selected' : ''}>0</option>
-          <option value="1" ${slicesResolution == 1 ? 'selected' : ''}>1</option>
-          <option value="3" ${slicesResolution == 3 ? 'selected' : ''}>3</option>
-          <option value="5" ${slicesResolution == 5 ? 'selected' : ''}>5</option>
-          <option value="10" ${slicesResolution == 10 ? 'selected' : ''}>10</option>
-          <option value="15" ${slicesResolution == 15 ? 'selected' : ''}>15</option>
-          <option value="20" ${slicesResolution == 20 ? 'selected' : ''}>20</option>
-          <option value="25" ${slicesResolution == 25 ? 'selected' : ''}>25</option>
-        </select></p>
-        <p>Filter (RegExp): <input type="text" name="filter" value="$filter"></p>
-        <p id="status"></p>
-      </form>
-      <div id="timeline"></div>
-    </body>
-  </html>
-  ''';
-  } on UnimplementedError catch (_) {
-    return _enablePerformanceTracking;
-  } on UnsupportedError catch (_) {
-    return _enablePerformanceTracking;
-  }
-}
-
-final _enablePerformanceTracking = '''
-<html>
-  <body>
-    <p>
-      Performance information not available, you must pass the
-      `--track-performance` command line arg to enable performance tracking.
-    </p>
-  <body>
-</html>
-''';
-
-/// [shelf.Middleware] that logs all requests, inspired by [shelf.logRequests].
-shelf.Handler _logRequests(shelf.Handler innerHandler) {
-  return (shelf.Request request) {
-    var startTime = DateTime.now();
-    var watch = Stopwatch()..start();
-
-    return Future.sync(() => innerHandler(request)).then((response) {
-      var logFn = response.statusCode >= 500 ? _logger.warning : _logger.info;
-      var msg = _getMessage(startTime, response.statusCode,
-          request.requestedUri, request.method, watch.elapsed);
-      logFn(msg);
-      return response;
-    }, onError: (dynamic error, StackTrace stackTrace) {
-      if (error is shelf.HijackException) throw error;
-      var msg = _getMessage(
-          startTime, 500, request.requestedUri, request.method, watch.elapsed);
-      _logger.severe('$msg\r\n$error\r\n$stackTrace', true);
-      throw error;
-    });
-  };
-}
-
-String _getMessage(DateTime requestTime, int statusCode, Uri requestedUri,
-    String method, Duration elapsedTime) {
-  return '${requestTime.toIso8601String()} '
-      '${humanReadable(elapsedTime)} '
-      '$method [$statusCode] '
-      '${requestedUri.path}${_formatQuery(requestedUri.query)}\r\n';
-}
-
-String _formatQuery(String query) {
-  return query == '' ? '' : '?$query';
-}
diff --git a/build_runner/lib/src/watcher/asset_change.dart b/build_runner/lib/src/watcher/asset_change.dart
deleted file mode 100644
index 7796ede..0000000
--- a/build_runner/lib/src/watcher/asset_change.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-import 'package:watcher/watcher.dart';
-
-import 'package:build_runner_core/build_runner_core.dart';
-
-/// Represents an [id] that was modified on disk as a result of [type].
-class AssetChange {
-  /// Asset that was changed.
-  final AssetId id;
-
-  /// What caused the asset to be detected as changed.
-  final ChangeType type;
-
-  const AssetChange(this.id, this.type);
-
-  /// Creates a new change record in [package] from an existing watcher [event].
-  factory AssetChange.fromEvent(PackageNode package, WatchEvent event) {
-    return AssetChange(
-      AssetId(
-        package.name,
-        _normalizeRelativePath(package, event),
-      ),
-      event.type,
-    );
-  }
-
-  static String _normalizeRelativePath(PackageNode package, WatchEvent event) {
-    final pkgPath = package.path;
-    var absoluteEventPath =
-        p.isAbsolute(event.path) ? event.path : p.absolute(event.path);
-    if (!p.isWithin(pkgPath, absoluteEventPath)) {
-      throw ArgumentError('"$absoluteEventPath" is not in "$pkgPath".');
-    }
-    return p.relative(absoluteEventPath, from: pkgPath);
-  }
-
-  @override
-  int get hashCode => id.hashCode ^ type.hashCode;
-
-  @override
-  bool operator ==(Object other) =>
-      other is AssetChange && other.id == id && other.type == type;
-
-  @override
-  String toString() => 'AssetChange {asset: $id, type: $type}';
-}
diff --git a/build_runner/lib/src/watcher/change_filter.dart b/build_runner/lib/src/watcher/change_filter.dart
deleted file mode 100644
index 3da8192..0000000
--- a/build_runner/lib/src/watcher/change_filter.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:build_runner/src/watcher/asset_change.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-import 'package:watcher/watcher.dart';
-
-/// Returns if a given asset change should be considered for building.
-bool shouldProcess(
-  AssetChange change,
-  AssetGraph assetGraph,
-  BuildOptions buildOptions,
-  bool willCreateOutputDir,
-  Set<AssetId> expectedDeletes,
-) {
-  if (_isCacheFile(change) && !assetGraph.contains(change.id)) return false;
-  var node = assetGraph.get(change.id);
-  if (node != null) {
-    if (!willCreateOutputDir && !node.isInteresting) return false;
-    if (_isAddOrEditOnGeneratedFile(node, change.type)) return false;
-  } else {
-    if (change.type != ChangeType.ADD) return false;
-    if (!buildOptions.targetGraph.anyMatchesAsset(change.id)) return false;
-  }
-  if (_isExpectedDelete(change, expectedDeletes)) return false;
-  return true;
-}
-
-bool _isAddOrEditOnGeneratedFile(AssetNode node, ChangeType changeType) =>
-    node.isGenerated && changeType != ChangeType.REMOVE;
-
-bool _isCacheFile(AssetChange change) => change.id.path.startsWith(cacheDir);
-
-bool _isExpectedDelete(AssetChange change, Set<AssetId> expectedDeletes) =>
-    expectedDeletes.remove(change.id);
diff --git a/build_runner/lib/src/watcher/collect_changes.dart b/build_runner/lib/src/watcher/collect_changes.dart
deleted file mode 100644
index eb6b8d8..0000000
--- a/build_runner/lib/src/watcher/collect_changes.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:build_runner/src/watcher/asset_change.dart';
-import 'package:watcher/watcher.dart';
-
-/// Merges [AssetChange] events.
-///
-/// For example, if an asset was added then immediately deleted, no event will
-/// be recorded for the given asset.
-Map<AssetId, ChangeType> collectChanges(List<List<AssetChange>> changes) {
-  var changeMap = <AssetId, ChangeType>{};
-  for (var change in changes.expand((l) => l)) {
-    var originalChangeType = changeMap[change.id];
-    if (originalChangeType != null) {
-      switch (originalChangeType) {
-        case ChangeType.ADD:
-          if (change.type == ChangeType.REMOVE) {
-            // ADD followed by REMOVE, just remove the change.
-            changeMap.remove(change.id);
-          }
-          break;
-        case ChangeType.REMOVE:
-          if (change.type == ChangeType.ADD) {
-            // REMOVE followed by ADD, convert to a MODIFY
-            changeMap[change.id] = ChangeType.MODIFY;
-          } else if (change.type == ChangeType.MODIFY) {
-            // REMOVE followed by MODIFY isn't sensible, just throw.
-            throw StateError(
-                'Internal error, got REMOVE event followed by MODIFY event for '
-                '${change.id}.');
-          }
-          break;
-        case ChangeType.MODIFY:
-          if (change.type == ChangeType.REMOVE) {
-            // MODIFY followed by REMOVE, convert to REMOVE
-            changeMap[change.id] = change.type;
-          } else if (change.type == ChangeType.ADD) {
-            // MODIFY followed by ADD isn't sensible, just throw.
-            throw StateError(
-                'Internal error, got MODIFY event followed by ADD event for '
-                '${change.id}.');
-          }
-          break;
-      }
-    } else {
-      changeMap[change.id] = change.type;
-    }
-  }
-  return changeMap;
-}
diff --git a/build_runner/lib/src/watcher/delete_writer.dart b/build_runner/lib/src/watcher/delete_writer.dart
deleted file mode 100644
index e8092f5..0000000
--- a/build_runner/lib/src/watcher/delete_writer.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-
-/// A [RunnerAssetWriter] that forwards delete events to [_onDelete];
-class OnDeleteWriter implements RunnerAssetWriter {
-  final RunnerAssetWriter _writer;
-  final void Function(AssetId id) _onDelete;
-
-  OnDeleteWriter(this._writer, this._onDelete);
-
-  @override
-  Future delete(AssetId id) {
-    _onDelete(id);
-    return _writer.delete(id);
-  }
-
-  @override
-  Future writeAsBytes(AssetId id, List<int> bytes) =>
-      _writer.writeAsBytes(id, bytes);
-
-  @override
-  Future writeAsString(AssetId id, String contents,
-          {Encoding encoding = utf8}) =>
-      _writer.writeAsString(id, contents, encoding: encoding);
-}
diff --git a/build_runner/lib/src/watcher/graph_watcher.dart b/build_runner/lib/src/watcher/graph_watcher.dart
deleted file mode 100644
index 816d1dd..0000000
--- a/build_runner/lib/src/watcher/graph_watcher.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:async/async.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:logging/logging.dart';
-
-import 'asset_change.dart';
-import 'node_watcher.dart';
-
-PackageNodeWatcher _default(PackageNode node) => PackageNodeWatcher(node);
-
-/// Allows watching an entire graph of packages to schedule rebuilds.
-class PackageGraphWatcher {
-  // TODO: Consider pulling logging out and providing hooks instead.
-  final Logger _logger;
-  final PackageNodeWatcher Function(PackageNode) _strategy;
-  final PackageGraph _graph;
-
-  final _readyCompleter = Completer<void>();
-  Future<void> get ready => _readyCompleter.future;
-
-  bool _isWatching = false;
-
-  /// Creates a new watcher for a [PackageGraph].
-  ///
-  /// May optionally specify a [watch] strategy, otherwise will attempt a
-  /// reasonable default based on the current platform.
-  PackageGraphWatcher(
-    this._graph, {
-    Logger logger,
-    PackageNodeWatcher Function(PackageNode node) watch,
-  })  : _logger = logger ?? Logger('build_runner'),
-        _strategy = watch ?? _default;
-
-  /// Returns a stream of records for assets that changed in the package graph.
-  Stream<AssetChange> watch() {
-    assert(!_isWatching);
-    _isWatching = true;
-    return LazyStream(
-        () => logTimedSync(_logger, 'Setting up file watchers', _watch));
-  }
-
-  Stream<AssetChange> _watch() {
-    final allWatchers = _graph.allPackages.values
-        .where((node) => node.dependencyType == DependencyType.path)
-        .map(_strategy)
-        .toList();
-    final filteredEvents = allWatchers
-        .map((w) => w
-                .watch()
-                .where(_nestedPathFilter(w.node))
-                .handleError((dynamic e, StackTrace s) {
-              _logger.severe(
-                  'Error from directory watcher for package:${w.node.name}\n\n'
-                  'If you see this consistently then it is recommended that '
-                  'you enable the polling file watcher with '
-                  '--use-polling-watcher.');
-              throw e;
-            }))
-        .toList();
-    // Asynchronously complete the `_readyCompleter` once all the watchers
-    // are done.
-    () async {
-      await Future.wait(
-          allWatchers.map((nodeWatcher) => nodeWatcher.watcher.ready));
-      _readyCompleter.complete();
-    }();
-    return StreamGroup.merge(filteredEvents);
-  }
-
-  bool Function(AssetChange) _nestedPathFilter(PackageNode rootNode) {
-    final ignorePaths = _nestedPaths(rootNode);
-    return (change) => !ignorePaths.any(change.id.path.startsWith);
-  }
-
-  // Returns a set of all package paths that are "nested" within a node.
-  //
-  // This allows the watcher to optimize and avoid duplicate events.
-  List<String> _nestedPaths(PackageNode rootNode) {
-    return _graph.allPackages.values
-        .where((node) {
-          return node.path.length > rootNode.path.length &&
-              node.path.startsWith(rootNode.path);
-        })
-        .map((node) =>
-            node.path.substring(rootNode.path.length + 1) +
-            Platform.pathSeparator)
-        .toList();
-  }
-}
diff --git a/build_runner/lib/src/watcher/node_watcher.dart b/build_runner/lib/src/watcher/node_watcher.dart
deleted file mode 100644
index ebfd119..0000000
--- a/build_runner/lib/src/watcher/node_watcher.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:watcher/watcher.dart';
-
-import 'asset_change.dart';
-
-Watcher _default(String path) => Watcher(path);
-
-/// Allows watching significant files and directories in a given package.
-class PackageNodeWatcher {
-  final Watcher Function(String) _strategy;
-  final PackageNode node;
-
-  /// The actual watcher instance.
-  Watcher _watcher;
-  Watcher get watcher => _watcher;
-
-  /// Creates a new watcher for a [PackageNode].
-  ///
-  /// May optionally specify a [watch] strategy, otherwise will attempt a
-  /// reasonable default based on the current platform and the type of path
-  /// (i.e. a file versus directory).
-  PackageNodeWatcher(
-    this.node, {
-    Watcher Function(String path) watch,
-  }) : _strategy = watch ?? _default;
-
-  /// Returns a stream of records for assets that change recursively.
-  Stream<AssetChange> watch() {
-    assert(_watcher == null);
-    _watcher = _strategy(node.path);
-    final events = _watcher.events;
-    return events.map((e) => AssetChange.fromEvent(node, e));
-  }
-}
diff --git a/build_runner/mono_pkg.yaml b/build_runner/mono_pkg.yaml
deleted file mode 100644
index f61139b..0000000
--- a/build_runner/mono_pkg.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-      - dartfmt: sdk
-      - dartanalyzer: --fatal-infos --fatal-warnings .
-  - unit_test:
-    - test: -x integration
-  - e2e_test:
-    - test: -t integration --total-shards 5 --shard-index 0
-    - test: -t integration --total-shards 5 --shard-index 1
-    - test: -t integration --total-shards 5 --shard-index 2
-    - test: -t integration --total-shards 5 --shard-index 3
-    - test: -t integration --total-shards 5 --shard-index 4
diff --git a/build_runner/pubspec.yaml b/build_runner/pubspec.yaml
deleted file mode 100644
index 9429017..0000000
--- a/build_runner/pubspec.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
-name: build_runner
-version: 1.7.4
-description: Tools to write binaries that run builders.
-homepage: https://github.com/dart-lang/build/tree/master/build_runner
-
-environment:
-  sdk: ">=2.6.0 <3.0.0"
-
-dependencies:
-  args: ">=1.4.0 <2.0.0"
-  async: ">=1.13.3 <3.0.0"
-  build: ">=1.0.0 <1.3.0"
-  build_config: ">=0.4.1 <0.4.3"
-  build_daemon: ^2.1.0
-  build_resolvers: "^1.0.0"
-  build_runner_core: ^4.0.0
-  code_builder: ">2.3.0 <4.0.0"
-  collection: ^1.14.0
-  crypto: ">=0.9.2 <3.0.0"
-  dart_style: ^1.0.0
-  glob: ^1.1.0
-  graphs: ^0.2.0
-  http_multi_server: ^2.1.0
-  io: ^0.3.0
-  js: ^0.6.1+1
-  logging: ^0.11.2
-  meta: ^1.1.0
-  mime: ^0.9.3+3
-  path: ^1.1.0
-  pedantic: ^1.0.0
-  pool: ^1.0.0
-  pub_semver: ^1.4.0
-  pubspec_parse: ^0.1.0
-  shelf: ">=0.6.5 <0.8.0"
-  shelf_web_socket: ^0.2.2+4
-  stack_trace: ^1.9.0
-  stream_transform: ">=0.0.20 <2.0.0"
-  timing: ^0.1.1
-  watcher: ^0.9.7
-  web_socket_channel: ^1.0.9
-  yaml: ^2.1.0
-
-dev_dependencies:
-  build_test: ^0.10.0
-  build_web_compilers: ^2.0.0
-  mockito: ^4.0.0
-  package_resolver: ^1.0.2
-  stream_channel: ">=1.6.0 <3.0.0"
-  test: ^1.3.3
-  test_descriptor: ^1.0.0
-  test_process: ^1.0.0
-  _test_common:
-    path: ../_test_common
diff --git a/build_runner/tool/builders.dart b/build_runner/tool/builders.dart
deleted file mode 100644
index c8eb2ff..0000000
--- a/build_runner/tool/builders.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-
-Builder copyCompiledJs(void _) => _CopyBuilder();
-
-/// A Builder to copy compiled dart2js output to source.
-class _CopyBuilder extends Builder {
-  @override
-  final buildExtensions = {
-    'web/graph_viz_main.dart.js': ['lib/src/server/graph_viz_main.dart.js'],
-    'web/hot_reload_client.dart.js': [
-      'lib/src/server/build_updates_client/hot_reload_client.dart.js'
-    ]
-  };
-
-  @override
-  void build(BuildStep buildStep) {
-    if (!buildExtensions.containsKey(buildStep.inputId.path)) {
-      throw StateError('Unexpected input for `CopyBuilder` '
-          'expected only ${buildExtensions.keys}');
-    }
-    buildStep.writeAsString(
-        AssetId(buildStep.inputId.package,
-            buildExtensions[buildStep.inputId.path].single),
-        buildStep.readAsString(buildStep.inputId));
-  }
-}
diff --git a/build_runner/web/graph_viz_main.dart b/build_runner/web/graph_viz_main.dart
deleted file mode 100644
index b2d5e54..0000000
--- a/build_runner/web/graph_viz_main.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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:html';
-import 'dart:js' as js;
-
-final _graphReference = js.context[r'$build'];
-final _details = document.getElementById('details');
-
-void main() async {
-  var filterBox = document.getElementById('filter') as InputElement;
-  var searchBox = document.getElementById('searchbox') as InputElement;
-  var searchForm = document.getElementById('searchform');
-  searchForm.onSubmit.listen((e) {
-    e.preventDefault();
-    _focus(searchBox.value.trim(),
-        filter: filterBox.value.isNotEmpty ? filterBox.value : null);
-    return null;
-  });
-  _graphReference.callMethod('initializeGraph', [_focus]);
-}
-
-void _error(String message, [Object error, StackTrace stack]) {
-  var msg = [message, error, stack].where((e) => e != null).join('\n');
-  _details.innerHtml = '<pre>$msg</pre>';
-}
-
-Future _focus(String query, {String filter}) async {
-  if (query.isEmpty) {
-    _error('Provide content in the query.');
-    return;
-  }
-
-  Map nodeInfo;
-  var queryParams = {'q': query};
-  if (filter != null) queryParams['f'] = filter;
-  var uri = Uri(queryParameters: queryParams);
-  try {
-    nodeInfo = json.decode(await HttpRequest.getString(uri.toString()))
-        as Map<String, dynamic>;
-  } catch (e, stack) {
-    var msg = 'Error requesting query "$query".';
-    if (e is ProgressEvent) {
-      var target = e.target;
-      if (target is HttpRequest) {
-        msg = [
-          msg,
-          '${target.status} ${target.statusText}',
-          target.responseText
-        ].join('\n');
-      }
-      _error(msg);
-    } else {
-      _error(msg, e, stack);
-    }
-    return;
-  }
-
-  var graphData = {'edges': nodeInfo['edges'], 'nodes': nodeInfo['nodes']};
-  _graphReference.callMethod('setData', [js.JsObject.jsify(graphData)]);
-  var primaryNode = nodeInfo['primary'];
-  _details.innerHtml = '<strong>ID:</strong> ${primaryNode['id']} <br />'
-      '<strong>Type:</strong> ${primaryNode['type']}<br />'
-      '<strong>Hidden:</strong> ${primaryNode['hidden']} <br />'
-      '<strong>State:</strong> ${primaryNode['state']} <br />'
-      '<strong>Was Output:</strong> ${primaryNode['wasOutput']} <br />'
-      '<strong>Failed:</strong> ${primaryNode['isFailure']} <br />'
-      '<strong>Phase:</strong> ${primaryNode['phaseNumber']} <br />'
-      '<strong>Glob:</strong> ${primaryNode['glob']}<br />'
-      '<strong>Last Digest:</strong> ${primaryNode['lastKnownDigest']}<br />';
-}
diff --git a/build_runner/web/hot_reload_client.dart b/build_runner/web/hot_reload_client.dart
deleted file mode 100644
index 5735341..0000000
--- a/build_runner/web/hot_reload_client.dart
+++ /dev/null
@@ -1,203 +0,0 @@
-// 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.
-
-@JS()
-library hot_reload_client;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:html';
-
-import 'package:js/js.dart';
-import 'package:js/js_util.dart';
-
-import 'package:build_runner/src/server/build_updates_client/module.dart';
-import 'package:build_runner/src/server/build_updates_client/reload_handler.dart';
-import 'package:build_runner/src/server/build_updates_client/reloading_manager.dart';
-
-final _assetsDigestPath = r'$assetDigests';
-final _buildUpdatesProtocol = r'$buildUpdates';
-
-@anonymous
-@JS()
-abstract class HotReloadableLibrary {
-  /// Implement this function with any code to release resources before destroy.
-  ///
-  /// Any object returned from this function will be passed to update hooks. Use
-  /// it to save any state you need to be preserved between hot reloadings.
-  /// Try do not use any custom types here, as it might prevent their code from
-  /// reloading. Better serialise to JSON or plain types.
-  ///
-  /// This function will be called on old version of module before unloading.
-  @JS()
-  external Object hot$onDestroy();
-
-  /// Implement this function to handle update of the module itself.
-  ///
-  /// May return nullable bool. To indicate that reload completes successfully
-  /// return true. To indicate that hot-reload is undoable return false - this
-  /// will lead to full page reload. If null returned, reloading will be
-  /// propagated to parent.
-  ///
-  /// If any state was saved from previous version, it will be passed to [data].
-  ///
-  /// This function will be called on new version of module after reloading.
-  @JS()
-  external bool hot$onSelfUpdate([Object data]);
-
-  /// Implement this function to handle update of child modules.
-  ///
-  /// May return nullable bool. To indicate that reload of child completes
-  /// successfully return true. To indicate that hot-reload is undoable for this
-  /// child return false - this will lead to full page reload. If null returned,
-  /// reloading will be propagated to current module itself.
-  ///
-  /// The name of the child will be provided in [childId]. New version of child
-  /// module object will be provided in [child].
-  /// If any state was saved from previous version, it will be passed to [data].
-  ///
-  /// This function will be called on old version of module current after child
-  /// reloading.
-  @JS()
-  external bool hot$onChildUpdate(String childId, HotReloadableLibrary child,
-      [Object data]);
-}
-
-class LibraryWrapper implements Library {
-  final HotReloadableLibrary _internal;
-
-  LibraryWrapper(this._internal);
-
-  @override
-  Object onDestroy() {
-    if (_internal != null && hasProperty(_internal, r'hot$onDestroy')) {
-      return _internal.hot$onDestroy();
-    }
-    return null;
-  }
-
-  @override
-  bool onSelfUpdate([Object data]) {
-    if (_internal != null && hasProperty(_internal, r'hot$onSelfUpdate')) {
-      return _internal.hot$onSelfUpdate(data);
-    }
-    // ignore: avoid_returning_null
-    return null;
-  }
-
-  @override
-  bool onChildUpdate(String childId, Library child, [Object data]) {
-    if (_internal != null && hasProperty(_internal, r'hot$onChildUpdate')) {
-      return _internal.hot$onChildUpdate(
-          childId, (child as LibraryWrapper)._internal, data);
-    }
-    // ignore: avoid_returning_null
-    return null;
-  }
-}
-
-@JS('Map')
-abstract class JsMap<K, V> {
-  @JS()
-  external Object keys();
-
-  @JS()
-  external V get(K key);
-}
-
-@JS('Error')
-abstract class JsError {
-  @JS()
-  external String get message;
-
-  @JS()
-  external String get stack;
-}
-
-@anonymous
-@JS()
-class DartLoader {
-  @JS()
-  external JsMap<String, String> get urlToModuleId;
-
-  @JS()
-  external JsMap<String, List<String>> get moduleParentsGraph;
-
-  @JS()
-  external void forceLoadModule(String moduleId, void Function() callback,
-      void Function(JsError e) onError);
-
-  @JS()
-  external Object getModuleLibraries(String moduleId);
-}
-
-@JS(r'$dartLoader')
-external DartLoader get dartLoader;
-
-@JS('Array.from')
-external List _jsArrayFrom(Object any);
-
-@JS('Object.keys')
-external List _jsObjectKeys(Object any);
-
-@JS('Object.values')
-external List _jsObjectValues(Object any);
-
-List<K> keys<K, V>(JsMap<K, V> map) {
-  return List.from(_jsArrayFrom(map.keys()));
-}
-
-Module _moduleLibraries(String moduleId) {
-  var moduleObj = dartLoader.getModuleLibraries(moduleId);
-  if (moduleObj == null) {
-    throw HotReloadFailedException("Failed to get module '$moduleId'. "
-        "This error might appear if such module doesn't exist or isn't already loaded");
-  }
-  var moduleKeys = List<String>.from(_jsObjectKeys(moduleObj));
-  var moduleValues =
-      List<HotReloadableLibrary>.from(_jsObjectValues(moduleObj));
-  var moduleLibraries = moduleValues.map((x) => LibraryWrapper(x));
-  return Module(Map.fromIterables(moduleKeys, moduleLibraries));
-}
-
-Future<Module> _reloadModule(String moduleId) {
-  var completer = Completer<Module>();
-  var stackTrace = StackTrace.current;
-  dartLoader.forceLoadModule(moduleId, allowInterop(() {
-    completer.complete(_moduleLibraries(moduleId));
-  }),
-      allowInterop((e) => completer.completeError(
-          HotReloadFailedException(e.message), stackTrace)));
-  return completer.future;
-}
-
-void _reloadPage() {
-  window.location.reload();
-}
-
-void main() async {
-  var currentOrigin = '${window.location.origin}/';
-  var modulePaths = keys(dartLoader.urlToModuleId)
-      .map((key) => key.replaceFirst(currentOrigin, ''))
-      .toList();
-  var modulePathsJson = json.encode(modulePaths);
-
-  var request = await HttpRequest.request('/$_assetsDigestPath',
-      responseType: 'json', sendData: modulePathsJson, method: 'POST');
-  var digests = (request.response as Map).cast<String, String>();
-
-  var manager = ReloadingManager(
-      _reloadModule,
-      _moduleLibraries,
-      _reloadPage,
-      (module) => dartLoader.moduleParentsGraph.get(module),
-      () => keys(dartLoader.moduleParentsGraph));
-
-  var handler = ReloadHandler(digests,
-      (path) => dartLoader.urlToModuleId.get(currentOrigin + path), manager);
-
-  var webSocket =
-      WebSocket('ws://${window.location.host}', [_buildUpdatesProtocol]);
-  webSocket.onMessage.listen((event) => handler.listener(event.data as String));
-}
diff --git a/build_runner_core/BUILD.gn b/build_runner_core/BUILD.gn
deleted file mode 100644
index f234d4c..0000000
--- a/build_runner_core/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is generated by importer.py for build_runner_core-4.4.0
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_runner_core") {
-  package_name = "build_runner_core"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/pedantic",
-    "//third_party/dart-pkg/pub/glob",
-    "//third_party/dart-pkg/pub/collection",
-    "//third_party/dart-pkg/pub/watcher",
-    "//third_party/dart-pkg/pub/meta",
-    "//third_party/dart-pkg/pub/path",
-    "//third_party/dart-pkg/pub/timing",
-    "//third_party/dart-pkg/pub/build_config",
-    "//third_party/dart-pkg/pub/pool",
-    "//third_party/dart-pkg/pub/convert",
-    "//third_party/dart-pkg/pub/logging",
-    "//third_party/dart-pkg/pub/graphs",
-    "//third_party/dart-pkg/pub/crypto",
-    "//third_party/dart-pkg/pub/yaml",
-    "//third_party/dart-pkg/pub/build",
-    "//third_party/dart-pkg/pub/build_resolvers",
-    "//third_party/dart-pkg/pub/async",
-    "//third_party/dart-pkg/pub/json_annotation",
-  ]
-}
diff --git a/build_runner_core/CHANGELOG.md b/build_runner_core/CHANGELOG.md
deleted file mode 100644
index 466bba4..0000000
--- a/build_runner_core/CHANGELOG.md
+++ /dev/null
@@ -1,305 +0,0 @@
-## 4.4.0
-
-- Support the `auto_apply_builders` target configuration added in
-  `build_config` version `0.4.2`.
-
-## 4.3.0
-
-- Add the `$package$` synthetic placeholder file and update the docs to prefer
-  using only that or `lib/$lib$`.
-- Add the `assets` directory and `$package$` placeholders to the default
-  sources whitelist.
-
-## 4.2.1
-
-- Bug fix: Changing the root package name will no longer cause subsequent
-  builds to fail (Issue #2566).
-
-## 4.2.0
-
-### New Feature
-
-- Allow reading assets created previously by the same `BuildStep`.
-
-## 4.1.0
-
-- Add support for trimming builds based on `BuildStep.reportUnusedAssets`
-  calls. See the `build` package for more details.
-- Include `node/**` in the default set of sources (when there is no target
-  defined) for the root package.
-
-## 4.0.0
-
-### New Feature: Build Filters
-
-- Added a new `BuildFilter` class which matches a set of assets with glob
-  syntax support for both package and file names.
-- Added `buildFilters` to `BuildOptions` which is a `Set<BuildFilter>` and
-  is used to filter exactly which outputs will be generated.
-  - Note that any inputs to the specified files will also necessarily be built.
-- `BuildRunner.run` also now accepts an optional `Set<BuildFilter>` argument.
-- `FinalizedReader` also  now accepts a `Set<BuildFilter>` optional parameter
-  and will only allow reading matched files.
-  - This means you can create output directories or servers that respect build
-    filters.
-
-### Breaking Changes
-
-- `FinalizedReader.reset` now requires an additional `Set<BuildFilter>`
-  argument.
-
-## 3.1.1
-
-- When skipping build script updates, don't check if the build script is a
-  part of the asset graph either.
-
-## 3.1.0
-
-- Factor out the logic to do a manual file system scan for changes into a
-  new `AssetTracker` class.
-  - This is not exposed publicly and is only intended to be used from the
-    `build_runner` package.
-
-## 3.0.9
-
-- Support the latest release of `package:json_annotation`.
-
-## 3.0.8
-
-- Fix --log-performance crash on windows by ensuring we use valid
-  windows directory names.
-
-## 3.0.7
-
-- Support the latest `package:build_config`.
-
-## 3.0.6
-
-- Handle symlink creation failures and link to dev mode docs for windows.
-
-## 3.0.5
-
-- Explicitly require Dart SDK `>=2.2.0 <3.0.0`.
-- Fix an error that could occur when serializing outdated glob nodes.
-
-## 3.0.4
-
-- Add additional error details and a fallback for
-  https://github.com/dart-lang/build/issues/1804
-
-## 3.0.3
-
-- Share an asset graph when building regardless of whether the build script was
-  started from a snapshot.
-
-## 3.0.2
-
-- Only track valid and readable assets as inputs to globs. Fixes a crash when
-  attempting to check outputs from an invalid asset.
-
-## 3.0.1
-
-- Remove usage of set literals to fix errors on older sdks that don't support
-  them.
-
-## 3.0.0
-
-- Fix an issue where `--symlink` was forcing outputs to not be hoisted.
-- `BuildImpl` now takes an optional list of  `BuildTargets` instead of a list of
-  `buildDirs`.
-- Warn when there are no assets to write in a specified output directory.
-
-## 2.0.3
-
-- Handle asset graph decode failures.
-
-## 2.0.2
-
-- Update `build_resolvers` to version `1.0.0`.
-
-## 2.0.1
-
-- Fix an issue where the `finalizedReader` was not `reset` prior to build.
-
-## 2.0.0
-
-- The `build` method now requires a list of `buildDirs`.
-- Remove `buildDirs` from `BuildOptions`.
-- Added the `overrideGeneratedDirectory` method which overrides the directory
-  for generated outputs.
-  - Must be invoked before creating a `BuildRunner` instance.
-
-## 1.1.3
-
-- Update to `package:graphs` version `0.2.0`.
-- Allow `build` version `1.1.x`.
-- Update the way combined input hashes are computed to not rely on ordering.
-  - Digest implementations must now include the AssetId, not just the contents.
-- Require package:build version 1.1.0, which meets the new requirements for
-  digests.
-
-## 1.1.2
-
-- Fix a `NoSuchMethodError` that the user could get when adding new
-  dependencies.
-
-## 1.1.1
-
-- Fix a bug where adding new dependencies or removing dependencies could cause
-  subsequent build errors, requiring a `pub run build_runner clean` to fix.
-
-## 1.1.0
-
-- Support running the build script as a snapshot.
-- Added new exceptions, `BuildScriptChangedException` and
-  `BuildConfigChangedException`. These should be handled by scripts as described
-  in the documentation.
-- Added new `FailureType`s of `buildScriptChanged` and `buildConfigChanged`.
-
-## 1.0.2
-
-- Support the latest `package:json_annotation`.
-
-## 1.0.1
-
-- Update `package:build` version constraint to `>1.0.0 <1.0.1`.
-
-## 1.0.0
-
-### Breaking Changes
-
-- The performance tracking apis have changed significantly, and performance
-  tracking now uses the `timing` package.
-- The `BuildOptions` static factory now takes a `LogSubscription` instead of a
-  `BuildEnvironment`. Logging should be start as early as possible to catch logs
-  emitted during setup.
-
-### New Features
-
-- Use the `timing` package for performance tracking.
-- Added support for `BuildStep.trackStage` to track performance of custom build
-  stages within your builder.
-
-### Bug Fixes
-
-- Fixed a node invalidation issue when fixing build errors that could cause a
-  situation which was only resolvable with a full rebuild.
-
-## 0.3.1+5
-
-- Fixed an issue where builders that didn't read their primary input would get
-  invalidated on fresh builds when they shouldn't.
-
-## 0.3.1+4
-
-- Removed the constraint on reading files that output to cache from files that
-  output to source.
-
-## 0.3.1+3
-
-- Bug Fix: Don't output a `packages` symlink within the `packages` directory.
-
-## 0.3.1+2
-
-- Restore `new` keyword for a working release on Dart 1 VM.
-- Bug Fix: Don't include any non-lib assets from dependencies in the build, even
-  if they are a source in a target.
-
-## 0.3.1+1
-
-- Bug Fix: Don't include any non-lib assets from dependencies in the build, even
-  if they are a source in a target.
-- Release broken on Dart 1 VM.
-
-## 0.3.1
-
-- Migrated glob tracking to a specialized node type to fix dart-lang/build#1702.
-
-## 0.3.0
-
-### Breaking Changes
-
-- Implementations of `BuildEnvironment` must now implement the `finalizeBuild`
-  method. There is a default implementation if you extend `BuildEnvironment`
-  that is a no-op.
-  - This method is invoked at the end of the build that allows you to do
-    arbitrary additional work, such as creating merged output directories.
-- The `assumeTty` argument on `IOEnvironment` has moved to a named argument
-  since `null` is an accepted value.
-- The `outputMap` field on `BuildOptions` has moved to the `IOEnvironment`
-  class.
-
-### New Features/Updates
-
-- Added a `outputSymlinksOnly` option to `IOEnvironment` constructor, that
-  causes the merged output directories to contain only symlinks, which is much
-  faster than copying files.
-- Added the `FinalizedAssetView` class which provides a list of all available
-  assets to the `BuildEnvironment` during the build finalization phase.
-  - `outputMap` has moved from `BuildOptions` to this constructor, as a named
-    argument.
-- The `OverridableEnvironment` now supports overriding the new `finalizeBuild`
-  api.
-- The number of concurrent actions per phase is now limited (currently to 16),
-  which should help with memory and cpu usage for large builds.
-
-## 0.2.2+2
-
-- Support `package:json_annotation` v1.
-
-## 0.2.2+1
-
-- Tag errors from cached actions when they are printed.
-
-## 0.2.2
-
-- Changed the default file caching logic to use an LRU cache.
-
-## 0.2.1+2
-
-- Clarify wording for conflicting output directory options. No behavioral
-  differences.
-- Reduce the memory consumption required to create an output dir significantly.
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.2.1+1
-
-- Allow reuse cache between machines with different OS
-
-## 0.2.1
-
-- The hash dir for the asset graph under `.dart_tool/build` is now based on a
-  relative path to the build script instead of the absolute path.
-  - This enables `.dart_tool/build` directories to be reused across different
-    computers and directories for the same project.
-
-## 0.2.0
-
-### New Features
-
-- The `BuildPerformance` class is now serializable, it has a `fromJson`
-  constructor and a `toJson` instance method.
-- Added `BuildOptions.logPerformanceDir`, performance logs will be continuously
-  written to that directory if provided.
-- Added support for `global_options` in `build.yaml` of the root package.
-- Allow overriding the default `Resolvers` implementation.
-- Allows building with symlinked files. Note that changes to the linked files
-  will not trigger rebuilds in watch or serve mode.
-
-### Breaking changes
-
-- `BuildPhasePerformance.action` has been replaced with
-  `BuildPhasePerformance.builderKeys`.
-- `BuilderActionPerformance.builder` has been replaced with
-  `BuilderActionPerformance.builderKey`.
-- `BuildResult` no longer has an `exception` or `stackTrace` field.
-- Dropped `failOnSevere` arguments. Severe logs are always considered failing.
-
-### Internal changes
-
-- Remove dependency on package:cli_util.
-
-## 0.1.0
-
-Initial release, migrating the core functionality of package:build_runner to
-this package.
diff --git a/build_runner_core/LICENSE b/build_runner_core/LICENSE
deleted file mode 100644
index c4dc9ba..0000000
--- a/build_runner_core/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_runner_core/README.md b/build_runner_core/README.md
deleted file mode 100644
index 0fabf3e..0000000
--- a/build_runner_core/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-<p align="center">
-  Core functionality of the build_runner package. Exposes the imperative apis
-  for running pure Dart builds for
-  <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
-  <br>
-  <a href="https://travis-ci.org/dart-lang/build">
-    <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
-  </a>
-  <a href="https://github.com/dart-lang/build/labels/package%3A%20build_runner">
-    <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_runner_core.svg" alt="Issues related to build_runner_core" />
-  </a>
-  <a href="https://pub.dev/packages/build_runner_core">
-    <img src="https://img.shields.io/pub/v/build_runner_core.svg" alt="Pub Package Version" />
-  </a>
-  <a href="https://pub.dev/documentation/build_runner_core/latest">
-    <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
-  </a>
-  <a href="https://gitter.im/dart-lang/build">
-    <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
-  </a>
-</p>
diff --git a/build_runner_core/lib/build_runner_core.dart b/build_runner_core/lib/build_runner_core.dart
deleted file mode 100644
index e908e19..0000000
--- a/build_runner_core/lib/build_runner_core.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-export 'package:build/build.dart' show PostProcessBuilder, PostProcessBuildStep;
-
-export 'src/asset/file_based.dart';
-export 'src/asset/finalized_reader.dart';
-export 'src/asset/reader.dart' show RunnerAssetReader;
-export 'src/asset/writer.dart';
-export 'src/environment/build_environment.dart';
-export 'src/environment/io_environment.dart';
-export 'src/environment/overridable_environment.dart';
-export 'src/generate/build_directory.dart';
-export 'src/generate/build_result.dart';
-export 'src/generate/build_runner.dart';
-export 'src/generate/exceptions.dart'
-    show
-        BuildConfigChangedException,
-        BuildScriptChangedException,
-        CannotBuildException;
-export 'src/generate/finalized_assets_view.dart' show FinalizedAssetsView;
-export 'src/generate/options.dart'
-    show
-        defaultRootPackageWhitelist,
-        LogSubscription,
-        BuildOptions,
-        BuildFilter;
-export 'src/generate/performance_tracker.dart'
-    show BuildPerformance, BuilderActionPerformance, BuildPhasePerformance;
-export 'src/logging/human_readable_duration.dart';
-export 'src/logging/logging.dart';
-export 'src/package_graph/apply_builders.dart'
-    show
-        BuilderApplication,
-        apply,
-        applyPostProcess,
-        applyToRoot,
-        toAll,
-        toAllPackages,
-        toDependentsOf,
-        toNoneByDefault,
-        toPackage,
-        toPackages,
-        toRoot;
-export 'src/package_graph/package_graph.dart';
-export 'src/util/constants.dart';
diff --git a/build_runner_core/lib/src/asset/build_cache.dart b/build_runner_core/lib/src/asset/build_cache.dart
deleted file mode 100644
index b052ba3..0000000
--- a/build_runner_core/lib/src/asset/build_cache.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../util/constants.dart';
-import 'reader.dart';
-import 'writer.dart';
-
-/// Wraps an [AssetReader] and translates reads for generated files into reads
-/// from the build cache directory
-class BuildCacheReader implements AssetReader {
-  final AssetGraph _assetGraph;
-  final AssetReader _delegate;
-  final String _rootPackage;
-
-  BuildCacheReader._(this._delegate, this._assetGraph, this._rootPackage);
-
-  factory BuildCacheReader(
-          AssetReader delegate, AssetGraph assetGraph, String rootPackage) =>
-      delegate is PathProvidingAssetReader
-          ? _PathProvidingBuildCacheReader._(delegate, assetGraph, rootPackage)
-          : BuildCacheReader._(delegate, assetGraph, rootPackage);
-
-  @override
-  Future<bool> canRead(AssetId id) =>
-      _delegate.canRead(_cacheLocation(id, _assetGraph, _rootPackage));
-
-  @override
-  Future<Digest> digest(AssetId id) =>
-      _delegate.digest(_cacheLocation(id, _assetGraph, _rootPackage));
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) =>
-      _delegate.readAsBytes(_cacheLocation(id, _assetGraph, _rootPackage));
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) =>
-      _delegate.readAsString(_cacheLocation(id, _assetGraph, _rootPackage),
-          encoding: encoding);
-
-  @override
-  Stream<AssetId> findAssets(Glob glob) => throw UnimplementedError(
-      'Asset globbing should be done per phase with the AssetGraph');
-}
-
-class _PathProvidingBuildCacheReader extends BuildCacheReader
-    implements PathProvidingAssetReader {
-  @override
-  PathProvidingAssetReader get _delegate =>
-      super._delegate as PathProvidingAssetReader;
-
-  _PathProvidingBuildCacheReader._(PathProvidingAssetReader delegate,
-      AssetGraph assetGraph, String rootPackage)
-      : super._(delegate, assetGraph, rootPackage);
-
-  @override
-  String pathTo(AssetId id) =>
-      _delegate.pathTo(_cacheLocation(id, _assetGraph, _rootPackage));
-}
-
-class BuildCacheWriter implements RunnerAssetWriter {
-  final AssetGraph _assetGraph;
-  final RunnerAssetWriter _delegate;
-  final String _rootPackage;
-
-  BuildCacheWriter(this._delegate, this._assetGraph, this._rootPackage);
-
-  @override
-  Future writeAsBytes(AssetId id, List<int> content) => _delegate.writeAsBytes(
-      _cacheLocation(id, _assetGraph, _rootPackage), content);
-
-  @override
-  Future writeAsString(AssetId id, String content,
-          {Encoding encoding = utf8}) =>
-      _delegate.writeAsString(
-          _cacheLocation(id, _assetGraph, _rootPackage), content,
-          encoding: encoding);
-
-  @override
-  Future delete(AssetId id) =>
-      _delegate.delete(_cacheLocation(id, _assetGraph, _rootPackage));
-}
-
-AssetId _cacheLocation(AssetId id, AssetGraph assetGraph, String rootPackage) {
-  if (id.path.startsWith(generatedOutputDirectory) ||
-      id.path.startsWith(cacheDir)) {
-    return id;
-  }
-  if (!assetGraph.contains(id)) {
-    return id;
-  }
-  final assetNode = assetGraph.get(id);
-  if (assetNode is GeneratedAssetNode && assetNode.isHidden) {
-    return AssetId(
-        rootPackage, '$generatedOutputDirectory/${id.package}/${id.path}');
-  }
-  return id;
-}
diff --git a/build_runner_core/lib/src/asset/cache.dart b/build_runner_core/lib/src/asset/cache.dart
deleted file mode 100644
index 12fabeb..0000000
--- a/build_runner_core/lib/src/asset/cache.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:typed_data';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-import 'lru_cache.dart';
-import 'reader.dart';
-
-/// An [AssetReader] that caches all results from the delegate.
-///
-/// Assets are cached until [invalidate] is invoked.
-///
-/// Does not implement [findAssets].
-class CachingAssetReader implements AssetReader {
-  /// Cached results of [readAsBytes].
-  final _bytesContentCache = LruCache<AssetId, List<int>>(
-      1024 * 1024,
-      1024 * 1024 * 512,
-      (value) => value is Uint8List ? value.lengthInBytes : value.length * 8);
-
-  /// Pending [readAsBytes] operations.
-  final _pendingBytesContentCache = <AssetId, Future<List<int>>>{};
-
-  /// Cached results of [canRead].
-  ///
-  /// Don't bother using an LRU cache for this since it's just booleans.
-  final _canReadCache = <AssetId, Future<bool>>{};
-
-  /// Cached results of [readAsString].
-  ///
-  /// These are computed and stored lazily using [readAsBytes].
-  ///
-  /// Only files read with [utf8] encoding (the default) will ever be cached.
-  final _stringContentCache = LruCache<AssetId, String>(
-      1024 * 1024, 1024 * 1024 * 512, (value) => value.length);
-
-  /// Pending `readAsString` operations.
-  final _pendingStringContentCache = <AssetId, Future<String>>{};
-
-  final AssetReader _delegate;
-
-  CachingAssetReader._(this._delegate);
-
-  factory CachingAssetReader(AssetReader delegate) =>
-      delegate is PathProvidingAssetReader
-          ? _PathProvidingCachingAssetReader._(delegate)
-          : CachingAssetReader._(delegate);
-
-  @override
-  Future<bool> canRead(AssetId id) =>
-      _canReadCache.putIfAbsent(id, () => _delegate.canRead(id));
-
-  @override
-  Future<Digest> digest(AssetId id) => _delegate.digest(id);
-
-  @override
-  Stream<AssetId> findAssets(Glob glob) =>
-      throw UnimplementedError('unimplemented!');
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id, {bool cache = true}) {
-    var cached = _bytesContentCache[id];
-    if (cached != null) return Future.value(cached);
-
-    return _pendingBytesContentCache.putIfAbsent(
-        id,
-        () => _delegate.readAsBytes(id).then((result) {
-              if (cache) _bytesContentCache[id] = result;
-              _pendingBytesContentCache.remove(id);
-              return result;
-            }));
-  }
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding}) {
-    encoding ??= utf8;
-
-    if (encoding != utf8) {
-      // Fallback case, we never cache the String value for the non-default,
-      // encoding but we do allow it to cache the bytes.
-      return readAsBytes(id).then(encoding.decode);
-    }
-
-    var cached = _stringContentCache[id];
-    if (cached != null) return Future.value(cached);
-
-    return _pendingStringContentCache.putIfAbsent(
-        id,
-        () => readAsBytes(id, cache: false).then((bytes) {
-              var decoded = encoding.decode(bytes);
-              _stringContentCache[id] = decoded;
-              _pendingStringContentCache.remove(id);
-              return decoded;
-            }));
-  }
-
-  /// Clears all [ids] from all caches.
-  void invalidate(Iterable<AssetId> ids) {
-    for (var id in ids) {
-      _bytesContentCache.remove(id);
-      _canReadCache.remove(id);
-      _stringContentCache.remove(id);
-
-      _pendingBytesContentCache.remove(id);
-      _pendingStringContentCache.remove(id);
-    }
-  }
-}
-
-/// A version of a [CachingAssetReader] that implements
-/// [PathProvidingAssetReader].
-class _PathProvidingCachingAssetReader extends CachingAssetReader
-    implements PathProvidingAssetReader {
-  @override
-  PathProvidingAssetReader get _delegate =>
-      super._delegate as PathProvidingAssetReader;
-
-  _PathProvidingCachingAssetReader._(AssetReader delegate) : super._(delegate);
-
-  @override
-  String pathTo(AssetId id) => _delegate.pathTo(id);
-}
diff --git a/build_runner_core/lib/src/asset/file_based.dart b/build_runner_core/lib/src/asset/file_based.dart
deleted file mode 100644
index 4b1efc0..0000000
--- a/build_runner_core/lib/src/asset/file_based.dart
+++ /dev/null
@@ -1,137 +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:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:path/path.dart' as path;
-import 'package:pool/pool.dart';
-
-import '../package_graph/package_graph.dart';
-import 'reader.dart';
-import 'writer.dart';
-
-/// Pool for async file operations, we don't want to use too many file handles.
-final _descriptorPool = Pool(32);
-
-/// Basic [AssetReader] which uses a [PackageGraph] to look up where to read
-/// files from disk.
-class FileBasedAssetReader extends AssetReader
-    implements RunnerAssetReader, PathProvidingAssetReader {
-  final PackageGraph packageGraph;
-
-  FileBasedAssetReader(this.packageGraph);
-
-  @override
-  Future<bool> canRead(AssetId id) =>
-      _descriptorPool.withResource(() => _fileFor(id, packageGraph).exists());
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) => _fileForOrThrow(id, packageGraph)
-      .then((file) => _descriptorPool.withResource(file.readAsBytes));
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding}) =>
-      _fileForOrThrow(id, packageGraph).then((file) => _descriptorPool
-          .withResource(() => file.readAsString(encoding: encoding ?? utf8)));
-
-  @override
-  Stream<AssetId> findAssets(Glob glob, {String package}) {
-    var packageNode =
-        package == null ? packageGraph.root : packageGraph[package];
-    if (packageNode == null) {
-      throw ArgumentError(
-          "Could not find package '$package' which was listed as "
-          'an input. Please ensure you have that package in your deps, or '
-          'remove it from your input sets.');
-    }
-    return glob
-        .list(followLinks: true, root: packageNode.path)
-        .where((e) => e is File && !path.basename(e.path).startsWith('._'))
-        .cast<File>()
-        .map((file) => _fileToAssetId(file, packageNode));
-  }
-
-  @override
-  String pathTo(AssetId id) => _filePathFor(id, packageGraph);
-}
-
-/// Creates an [AssetId] for [file], which is a part of [packageNode].
-AssetId _fileToAssetId(File file, PackageNode packageNode) {
-  var filePath = path.normalize(file.absolute.path);
-  var relativePath = path.relative(filePath, from: packageNode.path);
-  return AssetId(packageNode.name, relativePath);
-}
-
-/// Basic [AssetWriter] which uses a [PackageGraph] to look up where to write
-/// files to disk.
-class FileBasedAssetWriter implements RunnerAssetWriter {
-  final PackageGraph packageGraph;
-
-  FileBasedAssetWriter(this.packageGraph);
-
-  @override
-  Future writeAsBytes(AssetId id, List<int> bytes) async {
-    var file = _fileFor(id, packageGraph);
-    await _descriptorPool.withResource(() async {
-      await file.create(recursive: true);
-      await file.writeAsBytes(bytes);
-    });
-  }
-
-  @override
-  Future writeAsString(AssetId id, String contents,
-      {Encoding encoding = utf8}) async {
-    var file = _fileFor(id, packageGraph);
-    await _descriptorPool.withResource(() async {
-      await file.create(recursive: true);
-      await file.writeAsString(contents, encoding: encoding);
-    });
-  }
-
-  @override
-  Future delete(AssetId id) {
-    if (id.package != packageGraph.root.name) {
-      throw InvalidOutputException(
-          id, 'Should not delete assets outside of ${packageGraph.root.name}');
-    }
-
-    var file = _fileFor(id, packageGraph);
-    return _descriptorPool.withResource(() async {
-      if (await file.exists()) {
-        await file.delete();
-      }
-    });
-  }
-}
-
-/// Returns the path to [id] for a given [packageGraph].
-String _filePathFor(AssetId id, PackageGraph packageGraph) {
-  var package = packageGraph[id.package];
-  if (package == null) {
-    throw PackageNotFoundException(id.package);
-  }
-  return path.join(package.path, id.path);
-}
-
-/// Returns a [File] for [id] given [packageGraph].
-File _fileFor(AssetId id, PackageGraph packageGraph) {
-  return File(_filePathFor(id, packageGraph));
-}
-
-/// Returns a [Future<File>] for [id] given [packageGraph].
-///
-/// Throws an `AssetNotFoundException` if it doesn't exist.
-Future<File> _fileForOrThrow(AssetId id, PackageGraph packageGraph) {
-  if (packageGraph[id.package] == null) {
-    return Future.error(PackageNotFoundException(id.package));
-  }
-  var file = _fileFor(id, packageGraph);
-  return _descriptorPool.withResource(file.exists).then((exists) {
-    if (!exists) throw AssetNotFoundException(id);
-    return file;
-  });
-}
diff --git a/build_runner_core/lib/src/asset/finalized_reader.dart b/build_runner_core/lib/src/asset/finalized_reader.dart
deleted file mode 100644
index 38bdb03..0000000
--- a/build_runner_core/lib/src/asset/finalized_reader.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/generate/phase.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../asset_graph/optional_output_tracker.dart';
-
-/// An [AssetReader] which ignores deleted files.
-class FinalizedReader implements AssetReader {
-  final AssetReader _delegate;
-  final AssetGraph _assetGraph;
-  OptionalOutputTracker _optionalOutputTracker;
-  final String _rootPackage;
-  final List<BuildPhase> _buildPhases;
-
-  void reset(Set<String> buildDirs, Set<BuildFilter> buildFilters) {
-    _optionalOutputTracker = OptionalOutputTracker(
-        _assetGraph, buildDirs, buildFilters, _buildPhases);
-  }
-
-  FinalizedReader(
-      this._delegate, this._assetGraph, this._buildPhases, this._rootPackage);
-
-  /// Returns a reason why [id] is not readable, or null if it is readable.
-  Future<UnreadableReason> unreadableReason(AssetId id) async {
-    if (!_assetGraph.contains(id)) return UnreadableReason.notFound;
-    var node = _assetGraph.get(id);
-    if (node.isDeleted) return UnreadableReason.deleted;
-    if (!node.isReadable) return UnreadableReason.assetType;
-    if (node is GeneratedAssetNode) {
-      if (node.isFailure) return UnreadableReason.failed;
-      if (!(node.wasOutput && (_optionalOutputTracker.isRequired(node.id)))) {
-        return UnreadableReason.notOutput;
-      }
-    }
-    if (await _delegate.canRead(id)) return null;
-    return UnreadableReason.unknown;
-  }
-
-  @override
-  Future<bool> canRead(AssetId id) async =>
-      (await unreadableReason(id)) == null;
-
-  @override
-  Future<Digest> digest(AssetId id) => _delegate.digest(id);
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) => _delegate.readAsBytes(id);
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) async {
-    if (_assetGraph.get(id)?.isDeleted ?? true) {
-      throw AssetNotFoundException(id);
-    }
-    return _delegate.readAsString(id, encoding: encoding);
-  }
-
-  @override
-  Stream<AssetId> findAssets(Glob glob) async* {
-    var potentialNodes = _assetGraph
-        .packageNodes(_rootPackage)
-        .where((n) => glob.matches(n.id.path))
-        .toList();
-    var potentialIds = potentialNodes.map((n) => n.id).toList();
-
-    for (var id in potentialIds) {
-      if (await _delegate.canRead(id)) {
-        yield id;
-      }
-    }
-  }
-}
-
-enum UnreadableReason {
-  notFound,
-  notOutput,
-  assetType,
-  deleted,
-  failed,
-  unknown,
-}
diff --git a/build_runner_core/lib/src/asset/lru_cache.dart b/build_runner_core/lib/src/asset/lru_cache.dart
deleted file mode 100644
index c1e2299..0000000
--- a/build_runner_core/lib/src/asset/lru_cache.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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.
-
-/// A basic LRU Cache.
-class LruCache<K, V> {
-  _Link<K, V> _head;
-  _Link<K, V> _tail;
-
-  final int Function(V) _computeWeight;
-
-  int _currentWeightTotal = 0;
-  final int _individualWeightMax;
-  final int _totalWeightMax;
-
-  final _entries = <K, _Link<K, V>>{};
-
-  LruCache(
-      this._individualWeightMax, this._totalWeightMax, this._computeWeight);
-
-  V operator [](K key) {
-    var entry = _entries[key];
-    if (entry == null) return null;
-
-    _promote(entry);
-    return entry.value;
-  }
-
-  void operator []=(K key, V value) {
-    var entry = _Link(key, value, _computeWeight(value));
-    // Don't cache at all if above the individual weight max.
-    if (entry.weight > _individualWeightMax) {
-      return;
-    }
-
-    _entries[key] = entry;
-    _currentWeightTotal += entry.weight;
-    _promote(entry);
-
-    while (_currentWeightTotal > _totalWeightMax) {
-      assert(_tail != null);
-      remove(_tail.key);
-    }
-  }
-
-  /// Removes the value at [key] from the cache, and returns the value if it
-  /// existed.
-  V remove(K key) {
-    var entry = _entries[key];
-    if (entry == null) return null;
-
-    _currentWeightTotal -= entry.weight;
-    _entries.remove(key);
-
-    if (entry == _tail) {
-      _tail = entry.next;
-      _tail?.previous = null;
-    }
-    if (entry == _head) {
-      _head = entry.previous;
-      _head?.next = null;
-    }
-
-    return entry.value;
-  }
-
-  /// Moves [link] to the [_head] of the list.
-  void _promote(_Link<K, V> link) {
-    if (link == _head) return;
-
-    if (link == _tail) {
-      _tail = link.next;
-    }
-
-    if (link.previous != null) {
-      link.previous.next = link.next;
-    }
-    if (link.next != null) {
-      link.next.previous = link.previous;
-    }
-
-    _head?.next = link;
-    link.previous = _head;
-    _head = link;
-    _tail ??= link;
-    link.next = null;
-  }
-}
-
-/// A [MapEntry] which is also a part of a doubly linked list.
-class _Link<K, V> implements MapEntry<K, V> {
-  _Link<K, V> next;
-  _Link<K, V> previous;
-
-  final int weight;
-
-  @override
-  final K key;
-
-  @override
-  final V value;
-
-  _Link(this.key, this.value, this.weight);
-}
diff --git a/build_runner_core/lib/src/asset/reader.dart b/build_runner_core/lib/src/asset/reader.dart
deleted file mode 100644
index f3c0131..0000000
--- a/build_runner_core/lib/src/asset/reader.dart
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:convert';
-
-import 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:meta/meta.dart';
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../util/async.dart';
-
-/// A [RunnerAssetReader] must implement [MultiPackageAssetReader].
-abstract class RunnerAssetReader implements MultiPackageAssetReader {}
-
-/// An [AssetReader] that can provide actual paths to assets on disk.
-abstract class PathProvidingAssetReader implements AssetReader {
-  String pathTo(AssetId id);
-}
-
-/// Describes if and how a [SingleStepReader] should read an [AssetId].
-class Readability {
-  final bool canRead;
-  final bool inSamePhase;
-
-  const Readability({@required this.canRead, @required this.inSamePhase});
-
-  /// Determines readability for a node written in a previous build phase, which
-  /// means that [ownOutput] is impossible.
-  factory Readability.fromPreviousPhase(bool readable) =>
-      readable ? Readability.readable : Readability.notReadable;
-
-  static const Readability notReadable =
-      Readability(canRead: false, inSamePhase: false);
-  static const Readability readable =
-      Readability(canRead: true, inSamePhase: false);
-  static const Readability ownOutput =
-      Readability(canRead: true, inSamePhase: true);
-}
-
-typedef IsReadable = FutureOr<Readability> Function(
-    AssetNode node, int phaseNum, AssetWriterSpy writtenAssets);
-
-/// An [AssetReader] with a lifetime equivalent to that of a single step in a
-/// build.
-///
-/// A step is a single Builder and primary input (or package for package
-/// builders) combination.
-///
-/// Limits reads to the assets which are sources or were generated by previous
-/// phases.
-///
-/// Tracks the assets and globs read during this step for input dependency
-/// tracking.
-class SingleStepReader implements AssetReader {
-  final AssetGraph _assetGraph;
-  final AssetReader _delegate;
-  final int _phaseNumber;
-  final String _primaryPackage;
-  final AssetWriterSpy _writtenAssets;
-  final IsReadable _isReadableNode;
-  final FutureOr<GlobAssetNode> Function(
-      Glob glob, String package, int phaseNum) _getGlobNode;
-
-  /// The assets read during this step.
-  final assetsRead = HashSet<AssetId>();
-
-  SingleStepReader(this._delegate, this._assetGraph, this._phaseNumber,
-      this._primaryPackage, this._isReadableNode,
-      [this._getGlobNode, this._writtenAssets]);
-
-  /// Checks whether [id] can be read by this step - attempting to build the
-  /// asset if necessary.
-  FutureOr<bool> _isReadable(AssetId id) {
-    final node = _assetGraph.get(id);
-    if (node == null) {
-      assetsRead.add(id);
-      _assetGraph.add(SyntheticSourceAssetNode(id));
-      return false;
-    }
-
-    return doAfter(_isReadableNode(node, _phaseNumber, _writtenAssets),
-        (Readability readability) {
-      if (!readability.inSamePhase) {
-        assetsRead.add(id);
-      }
-
-      return readability.canRead;
-    });
-  }
-
-  @override
-  Future<bool> canRead(AssetId id) {
-    return toFuture(doAfter(_isReadable(id), (bool isReadable) {
-      if (!isReadable) return false;
-      var node = _assetGraph.get(id);
-      FutureOr<bool> _canRead() {
-        if (node is GeneratedAssetNode) {
-          // Short circut, we know this file exists because its readable and it was
-          // output.
-          return true;
-        } else {
-          return _delegate.canRead(id);
-        }
-      }
-
-      return doAfter(_canRead(), (bool canRead) {
-        if (!canRead) return false;
-        return doAfter(_ensureDigest(id), (_) => true);
-      });
-    }));
-  }
-
-  @override
-  Future<Digest> digest(AssetId id) {
-    return toFuture(doAfter(_isReadable(id), (bool isReadable) {
-      if (!isReadable) {
-        return Future.error(AssetNotFoundException(id));
-      }
-      return _ensureDigest(id);
-    }));
-  }
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) {
-    return toFuture(doAfter(_isReadable(id), (bool isReadable) {
-      if (!isReadable) {
-        return Future.error(AssetNotFoundException(id));
-      }
-      return doAfter(_ensureDigest(id), (_) => _delegate.readAsBytes(id));
-    }));
-  }
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) {
-    return toFuture(doAfter(_isReadable(id), (bool isReadable) {
-      if (!isReadable) {
-        return Future.error(AssetNotFoundException(id));
-      }
-      return doAfter(_ensureDigest(id),
-          (_) => _delegate.readAsString(id, encoding: encoding));
-    }));
-  }
-
-  @override
-  Stream<AssetId> findAssets(Glob glob) {
-    var streamCompleter = StreamCompleter<AssetId>();
-
-    doAfter(_getGlobNode(glob, _primaryPackage, _phaseNumber),
-        (GlobAssetNode globNode) {
-      assetsRead.add(globNode.id);
-      streamCompleter.setSourceStream(Stream.fromIterable(globNode.results));
-    });
-    return streamCompleter.stream;
-  }
-
-  FutureOr<Digest> _ensureDigest(AssetId id) {
-    var node = _assetGraph.get(id);
-    if (node?.lastKnownDigest != null) return node.lastKnownDigest;
-    return _delegate.digest(id).then((digest) => node.lastKnownDigest = digest);
-  }
-}
diff --git a/build_runner_core/lib/src/asset/writer.dart b/build_runner_core/lib/src/asset/writer.dart
deleted file mode 100644
index e0c1827..0000000
--- a/build_runner_core/lib/src/asset/writer.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-
-@deprecated
-typedef OnDelete = void Function(AssetId id);
-
-abstract class RunnerAssetWriter implements AssetWriter {
-  Future delete(AssetId id);
-}
diff --git a/build_runner_core/lib/src/asset_graph/exceptions.dart b/build_runner_core/lib/src/asset_graph/exceptions.dart
deleted file mode 100644
index 46f9d69..0000000
--- a/build_runner_core/lib/src/asset_graph/exceptions.dart
+++ /dev/null
@@ -1,26 +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 'package:build/build.dart';
-
-class DuplicateAssetNodeException implements Exception {
-  final String rootPackage;
-  final AssetId assetId;
-  final String initialBuilderLabel;
-  final String newBuilderLabel;
-
-  DuplicateAssetNodeException(this.rootPackage, this.assetId,
-      this.initialBuilderLabel, this.newBuilderLabel);
-  @override
-  String toString() {
-    final friendlyAsset =
-        assetId.package == rootPackage ? assetId.path : assetId.uri;
-    return 'Both $initialBuilderLabel and $newBuilderLabel may output '
-        '$friendlyAsset. Potential outputs must be unique across all builders. '
-        'See https://github.com/dart-lang/build/blob/master/docs/faq.md'
-        '#why-do-builders-need-unique-outputs';
-  }
-}
-
-class AssetGraphCorruptedException implements Exception {}
diff --git a/build_runner_core/lib/src/asset_graph/graph.dart b/build_runner_core/lib/src/asset_graph/graph.dart
deleted file mode 100644
index d7e6444..0000000
--- a/build_runner_core/lib/src/asset_graph/graph.dart
+++ /dev/null
@@ -1,556 +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:collection';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:convert/convert.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:meta/meta.dart';
-import 'package:watcher/watcher.dart';
-
-import '../generate/phase.dart';
-import '../package_graph/package_graph.dart';
-import 'exceptions.dart';
-import 'node.dart';
-
-part 'serialization.dart';
-
-/// All the [AssetId]s involved in a build, and all of their outputs.
-class AssetGraph {
-  /// All the [AssetNode]s in the graph, indexed by package and then path.
-  final _nodesByPackage = <String, Map<String, AssetNode>>{};
-
-  /// A [Digest] of the build actions this graph was originally created with.
-  ///
-  /// When an [AssetGraph] is deserialized we check whether or not it matches
-  /// the new [BuildPhase]s and throw away the graph if it doesn't.
-  final Digest buildPhasesDigest;
-
-  /// The [Platform.version] this graph was created with.
-  final String dartVersion;
-
-  AssetGraph._(this.buildPhasesDigest, this.dartVersion);
-
-  /// Deserializes this graph.
-  factory AssetGraph.deserialize(List<int> serializedGraph) =>
-      _AssetGraphDeserializer(serializedGraph).deserialize();
-
-  static Future<AssetGraph> build(
-      List<BuildPhase> buildPhases,
-      Set<AssetId> sources,
-      Set<AssetId> internalSources,
-      PackageGraph packageGraph,
-      AssetReader digestReader) async {
-    var graph =
-        AssetGraph._(computeBuildPhasesDigest(buildPhases), Platform.version);
-    var placeholders = graph._addPlaceHolderNodes(packageGraph);
-    var sourceNodes = graph._addSources(sources);
-    graph
-      .._addBuilderOptionsNodes(buildPhases)
-      .._addOutputsForSources(buildPhases, sources, packageGraph.root.name,
-          placeholders: placeholders);
-    // Pre-emptively compute digests for the nodes we know have outputs.
-    await graph._setLastKnownDigests(
-        sourceNodes.where((node) => node.primaryOutputs.isNotEmpty),
-        digestReader);
-    // Always compute digests for all internal nodes.
-    var internalNodes = graph._addInternalSources(internalSources);
-    await graph._setLastKnownDigests(internalNodes, digestReader);
-    return graph;
-  }
-
-  List<int> serialize() => _AssetGraphSerializer(this).serialize();
-
-  /// Checks if [id] exists in the graph.
-  bool contains(AssetId id) =>
-      _nodesByPackage[id.package]?.containsKey(id.path) ?? false;
-
-  /// Gets the [AssetNode] for [id], if one exists.
-  AssetNode get(AssetId id) {
-    var pkg = _nodesByPackage[id?.package];
-    if (pkg == null) return null;
-    return pkg[id.path];
-  }
-
-  /// Adds [node] to the graph if it doesn't exist.
-  ///
-  /// Throws a [StateError] if it already exists in the graph.
-  void _add(AssetNode node) {
-    var existing = get(node.id);
-    if (existing != null) {
-      if (existing is SyntheticSourceAssetNode) {
-        // Don't call _removeRecursive, that recursively removes all transitive
-        // primary outputs. We only want to remove this node.
-        _nodesByPackage[existing.id.package].remove(existing.id.path);
-        node.outputs.addAll(existing.outputs);
-        node.primaryOutputs.addAll(existing.primaryOutputs);
-      } else {
-        throw StateError(
-            'Tried to add node ${node.id} to the asset graph but it already '
-            'exists.');
-      }
-    }
-    _nodesByPackage.putIfAbsent(node.id.package, () => {})[node.id.path] = node;
-  }
-
-  /// Adds [assetIds] as [InternalAssetNode]s to this graph.
-  Iterable<AssetNode> _addInternalSources(Set<AssetId> assetIds) sync* {
-    for (var id in assetIds) {
-      var node = InternalAssetNode(id);
-      _add(node);
-      yield node;
-    }
-  }
-
-  /// Adds [PlaceHolderAssetNode]s for every package in [packageGraph].
-  Set<AssetId> _addPlaceHolderNodes(PackageGraph packageGraph) {
-    var placeholders = placeholderIdsFor(packageGraph);
-    for (var id in placeholders) {
-      _add(PlaceHolderAssetNode(id));
-    }
-    return placeholders;
-  }
-
-  /// Adds [assetIds] as [AssetNode]s to this graph, and returns the newly
-  /// created nodes.
-  List<AssetNode> _addSources(Set<AssetId> assetIds) {
-    return assetIds.map((id) {
-      var node = SourceAssetNode(id);
-      _add(node);
-      return node;
-    }).toList();
-  }
-
-  /// Adds [BuilderOptionsAssetNode]s for all [buildPhases] to this graph.
-  void _addBuilderOptionsNodes(List<BuildPhase> buildPhases) {
-    for (var phaseNum = 0; phaseNum < buildPhases.length; phaseNum++) {
-      var phase = buildPhases[phaseNum];
-      if (phase is InBuildPhase) {
-        add(BuilderOptionsAssetNode(builderOptionsIdForAction(phase, phaseNum),
-            computeBuilderOptionsDigest(phase.builderOptions)));
-      } else if (phase is PostBuildPhase) {
-        var actionNum = 0;
-        for (var builderAction in phase.builderActions) {
-          add(BuilderOptionsAssetNode(
-              builderOptionsIdForAction(builderAction, actionNum),
-              computeBuilderOptionsDigest(builderAction.builderOptions)));
-          actionNum++;
-        }
-      } else {
-        throw StateError('Invalid action type $phase');
-      }
-    }
-  }
-
-  /// Uses [digestReader] to compute the [Digest] for [nodes] and set the
-  /// `lastKnownDigest` field.
-  Future<void> _setLastKnownDigests(
-      Iterable<AssetNode> nodes, AssetReader digestReader) async {
-    await Future.wait(nodes.map((node) async {
-      node.lastKnownDigest = await digestReader.digest(node.id);
-    }));
-  }
-
-  /// Removes the node representing [id] from the graph, and all of its
-  /// `primaryOutput`s.
-  ///
-  /// Also removes all edges between all removed nodes and other nodes.
-  ///
-  /// Returns a [Set<AssetId>] of all removed nodes.
-  Set<AssetId> _removeRecursive(AssetId id, {Set<AssetId> removedIds}) {
-    removedIds ??= <AssetId>{};
-    var node = get(id);
-    if (node == null) return removedIds;
-    removedIds.add(id);
-    for (var anchor in node.anchorOutputs.toList()) {
-      _removeRecursive(anchor, removedIds: removedIds);
-    }
-    for (var output in node.primaryOutputs.toList()) {
-      _removeRecursive(output, removedIds: removedIds);
-    }
-    for (var output in node.outputs) {
-      var inputsNode = get(output) as NodeWithInputs;
-      if (inputsNode != null) {
-        inputsNode.inputs.remove(id);
-        if (inputsNode is GlobAssetNode) {
-          inputsNode.results.remove(id);
-        }
-      }
-    }
-    if (node is NodeWithInputs) {
-      for (var input in node.inputs) {
-        var inputNode = get(input);
-        // We may have already removed this node entirely.
-        if (inputNode != null) {
-          inputNode.outputs.remove(id);
-          inputNode.primaryOutputs.remove(id);
-        }
-      }
-      if (node is GeneratedAssetNode) {
-        get(node.builderOptionsId).outputs.remove(id);
-      }
-    }
-    // Synthetic nodes need to be kept to retain dependency tracking.
-    if (node is! SyntheticSourceAssetNode) {
-      _nodesByPackage[id.package].remove(id.path);
-    }
-    return removedIds;
-  }
-
-  /// All nodes in the graph, whether source files or generated outputs.
-  Iterable<AssetNode> get allNodes =>
-      _nodesByPackage.values.expand((pkdIds) => pkdIds.values);
-
-  /// All nodes in the graph for `package`.
-  Iterable<AssetNode> packageNodes(String package) =>
-      _nodesByPackage[package]?.values ?? [];
-
-  /// All the generated outputs in the graph.
-  Iterable<AssetId> get outputs =>
-      allNodes.where((n) => n.isGenerated).map((n) => n.id);
-
-  /// The outputs which were, or would have been, produced by failing actions.
-  Iterable<GeneratedAssetNode> get failedOutputs => allNodes
-      .where((n) =>
-          n is GeneratedAssetNode &&
-          n.isFailure &&
-          n.state == NodeState.upToDate)
-      .map((n) => n as GeneratedAssetNode);
-
-  /// All the generated outputs for a particular phase.
-  Iterable<GeneratedAssetNode> outputsForPhase(String package, int phase) =>
-      packageNodes(package)
-          .whereType<GeneratedAssetNode>()
-          .where((n) => n.phaseNumber == phase);
-
-  /// All the source files in the graph.
-  Iterable<AssetId> get sources =>
-      allNodes.whereType<SourceAssetNode>().map((n) => n.id);
-
-  /// Updates graph structure, invalidating and deleting any outputs that were
-  /// affected.
-  ///
-  /// Returns the list of [AssetId]s that were invalidated.
-  Future<Set<AssetId>> updateAndInvalidate(
-      List<BuildPhase> buildPhases,
-      Map<AssetId, ChangeType> updates,
-      String rootPackage,
-      Future Function(AssetId id) delete,
-      AssetReader digestReader) async {
-    var newIds = <AssetId>{};
-    var modifyIds = <AssetId>{};
-    var removeIds = <AssetId>{};
-    updates.forEach((id, changeType) {
-      if (changeType != ChangeType.ADD && get(id) == null) return;
-      switch (changeType) {
-        case ChangeType.ADD:
-          newIds.add(id);
-          break;
-        case ChangeType.MODIFY:
-          modifyIds.add(id);
-          break;
-        case ChangeType.REMOVE:
-          removeIds.add(id);
-          break;
-      }
-    });
-
-    var newAndModifiedNodes = modifyIds.map(get).toList()
-      ..addAll(_addSources(newIds));
-    // Pre-emptively compute digests for the new and modified nodes we know have
-    // outputs.
-    await _setLastKnownDigests(
-        newAndModifiedNodes.where((node) =>
-            node.isValidInput &&
-            (node.outputs.isNotEmpty ||
-                node.primaryOutputs.isNotEmpty ||
-                node.lastKnownDigest != null)),
-        digestReader);
-
-    // Collects the set of all transitive ids to be removed from the graph,
-    // based on the removed `SourceAssetNode`s by following the
-    // `primaryOutputs`.
-    var transitiveRemovedIds = <AssetId>{};
-    void addTransitivePrimaryOutputs(AssetId id) {
-      transitiveRemovedIds.add(id);
-      get(id).primaryOutputs.forEach(addTransitivePrimaryOutputs);
-    }
-
-    removeIds
-        .where((id) => get(id) is SourceAssetNode)
-        .forEach(addTransitivePrimaryOutputs);
-
-    // The generated nodes to actually delete from the file system.
-    var idsToDelete = Set<AssetId>.from(transitiveRemovedIds)
-      ..removeAll(removeIds);
-
-    // We definitely need to update manually deleted outputs.
-    for (var deletedOutput
-        in removeIds.map(get).whereType<GeneratedAssetNode>()) {
-      deletedOutput.state = NodeState.definitelyNeedsUpdate;
-    }
-
-    // Transitively invalidates all assets. This needs to happen after the
-    // structure of the graph has been updated.
-    var invalidatedIds = <AssetId>{};
-
-    var newGeneratedOutputs =
-        _addOutputsForSources(buildPhases, newIds, rootPackage);
-    var allNewAndDeletedIds =
-        Set.of(newGeneratedOutputs.followedBy(transitiveRemovedIds));
-
-    void invalidateNodeAndDeps(AssetId id) {
-      var node = get(id);
-      if (node == null) return;
-      if (!invalidatedIds.add(id)) return;
-
-      if (node is NodeWithInputs && node.state == NodeState.upToDate) {
-        node.state = NodeState.mayNeedUpdate;
-      }
-
-      // Update all outputs of this asset as well.
-      for (var output in node.outputs) {
-        invalidateNodeAndDeps(output);
-      }
-    }
-
-    for (var changed in updates.keys.followedBy(newGeneratedOutputs)) {
-      invalidateNodeAndDeps(changed);
-    }
-
-    // For all new or deleted assets, check if they match any glob nodes and
-    // invalidate those.
-    for (var id in allNewAndDeletedIds) {
-      var samePackageGlobNodes = packageNodes(id.package)
-          .whereType<GlobAssetNode>()
-          .where((n) => n.state == NodeState.upToDate);
-      for (final node in samePackageGlobNodes) {
-        if (node.glob.matches(id.path)) {
-          invalidateNodeAndDeps(node.id);
-          node.state = NodeState.mayNeedUpdate;
-        }
-      }
-    }
-
-    // Delete all the invalidated assets, then remove them from the graph. This
-    // order is important because some `AssetWriter`s throw if the id is not in
-    // the graph.
-    await Future.wait(idsToDelete.map(delete));
-
-    // Remove all deleted source assets from the graph, which also recursively
-    // removes all their primary outputs.
-    for (var id in removeIds.where((id) => get(id) is SourceAssetNode)) {
-      invalidateNodeAndDeps(id);
-      _removeRecursive(id);
-    }
-
-    return invalidatedIds;
-  }
-
-  /// Crawl up primary inputs to see if the original Source file matches the
-  /// glob on [action].
-  bool _actionMatches(BuildAction action, AssetId input) {
-    if (input.package != action.package) return false;
-    if (!action.generateFor.matches(input)) return false;
-    Iterable<String> inputExtensions;
-    if (action is InBuildPhase) {
-      inputExtensions = action.builder.buildExtensions.keys;
-    } else if (action is PostBuildAction) {
-      inputExtensions = action.builder.inputExtensions;
-    } else {
-      throw StateError('Unrecognized action type $action');
-    }
-    if (!inputExtensions.any(input.path.endsWith)) {
-      return false;
-    }
-    var inputNode = get(input);
-    while (inputNode is GeneratedAssetNode) {
-      inputNode = get((inputNode as GeneratedAssetNode).primaryInput);
-    }
-    return action.targetSources.matches(inputNode.id);
-  }
-
-  /// Returns a set containing [newSources] plus any new generated sources
-  /// based on [buildPhases], and updates this graph to contain all the
-  /// new outputs.
-  ///
-  /// If [placeholders] is supplied they will be added to [newSources] to create
-  /// the full input set.
-  Set<AssetId> _addOutputsForSources(
-      List<BuildPhase> buildPhases, Set<AssetId> newSources, String rootPackage,
-      {Set<AssetId> placeholders}) {
-    var allInputs = Set<AssetId>.from(newSources);
-    if (placeholders != null) allInputs.addAll(placeholders);
-
-    for (var phaseNum = 0; phaseNum < buildPhases.length; phaseNum++) {
-      var phase = buildPhases[phaseNum];
-      if (phase is InBuildPhase) {
-        allInputs.addAll(_addInBuildPhaseOutputs(
-          phase,
-          phaseNum,
-          allInputs,
-          buildPhases,
-          rootPackage,
-        ));
-      } else if (phase is PostBuildPhase) {
-        _addPostBuildPhaseAnchors(phase, allInputs);
-      } else {
-        throw StateError('Unrecognized phase type $phase');
-      }
-    }
-    return allInputs;
-  }
-
-  /// Adds all [GeneratedAssetNode]s for [phase] given [allInputs].
-  ///
-  /// May remove some items from [allInputs], if they are deemed to actually be
-  /// outputs of this phase and not original sources.
-  ///
-  /// Returns all newly created asset ids.
-  Set<AssetId> _addInBuildPhaseOutputs(
-      InBuildPhase phase,
-      int phaseNum,
-      Set<AssetId> allInputs,
-      List<BuildPhase> buildPhases,
-      String rootPackage) {
-    var phaseOutputs = <AssetId>{};
-    var buildOptionsNodeId = builderOptionsIdForAction(phase, phaseNum);
-    var builderOptionsNode = get(buildOptionsNodeId) as BuilderOptionsAssetNode;
-    var inputs =
-        allInputs.where((input) => _actionMatches(phase, input)).toList();
-    for (var input in inputs) {
-      // We might have deleted some inputs during this loop, if they turned
-      // out to be generated assets.
-      if (!allInputs.contains(input)) continue;
-      var node = get(input);
-      assert(node != null, 'The node from `$input` does not exist.');
-
-      var outputs = expectedOutputs(phase.builder, input);
-      phaseOutputs.addAll(outputs);
-      node.primaryOutputs.addAll(outputs);
-      var deleted = _addGeneratedOutputs(
-          outputs, phaseNum, builderOptionsNode, buildPhases, rootPackage,
-          primaryInput: input, isHidden: phase.hideOutput);
-      allInputs.removeAll(deleted);
-      // We may delete source nodes that were producing outputs previously.
-      // Detect this by checking for deleted nodes that no longer exist in the
-      // graph at all, and remove them from `phaseOutputs`.
-      phaseOutputs.removeAll(deleted.where((id) => !contains(id)));
-    }
-    return phaseOutputs;
-  }
-
-  /// Adds all [PostProcessAnchorNode]s for [phase] given [allInputs];
-  ///
-  /// Does not return anything because [PostProcessAnchorNode]s are synthetic
-  /// and should not be treated as inputs.
-  void _addPostBuildPhaseAnchors(PostBuildPhase phase, Set<AssetId> allInputs) {
-    var actionNum = 0;
-    for (var action in phase.builderActions) {
-      var inputs = allInputs.where((input) => _actionMatches(action, input));
-      for (var input in inputs) {
-        var buildOptionsNodeId = builderOptionsIdForAction(action, actionNum);
-        var anchor = PostProcessAnchorNode.forInputAndAction(
-            input, actionNum, buildOptionsNodeId);
-        add(anchor);
-        get(input).anchorOutputs.add(anchor.id);
-      }
-      actionNum++;
-    }
-  }
-
-  /// Adds [outputs] as [GeneratedAssetNode]s to the graph.
-  ///
-  /// If there are existing [SourceAssetNode]s or [SyntheticSourceAssetNode]s
-  /// that overlap the [GeneratedAssetNode]s, then they will be replaced with
-  /// [GeneratedAssetNode]s, and all their `primaryOutputs` will be removed
-  /// from the graph as well. The return value is the set of assets that were
-  /// removed from the graph.
-  Set<AssetId> _addGeneratedOutputs(
-      Iterable<AssetId> outputs,
-      int phaseNumber,
-      BuilderOptionsAssetNode builderOptionsNode,
-      List<BuildPhase> buildPhases,
-      String rootPackage,
-      {AssetId primaryInput,
-      @required bool isHidden}) {
-    var removed = <AssetId>{};
-    for (var output in outputs) {
-      AssetNode existing;
-      // When any outputs aren't hidden we can pick up old generated outputs as
-      // regular `AssetNode`s, we need to delete them and all their primary
-      // outputs, and replace them with a `GeneratedAssetNode`.
-      if (contains(output)) {
-        existing = get(output);
-        if (existing is GeneratedAssetNode) {
-          throw DuplicateAssetNodeException(
-              rootPackage,
-              existing.id,
-              (buildPhases[existing.phaseNumber] as InBuildPhase).builderLabel,
-              (buildPhases[phaseNumber] as InBuildPhase).builderLabel);
-        }
-        _removeRecursive(output, removedIds: removed);
-      }
-
-      var newNode = GeneratedAssetNode(output,
-          phaseNumber: phaseNumber,
-          primaryInput: primaryInput,
-          state: NodeState.definitelyNeedsUpdate,
-          wasOutput: false,
-          isFailure: false,
-          builderOptionsId: builderOptionsNode.id,
-          isHidden: isHidden);
-      if (existing != null) {
-        newNode.outputs.addAll(existing.outputs);
-      }
-      builderOptionsNode.outputs.add(output);
-      _add(newNode);
-    }
-    return removed;
-  }
-
-  @override
-  String toString() => allNodes.toList().toString();
-
-  // TODO remove once tests are updated
-  void add(AssetNode node) => _add(node);
-  Set<AssetId> remove(AssetId id) => _removeRecursive(id);
-}
-
-/// Computes a [Digest] for [buildPhases] which can be used to compare one set
-/// of [BuildPhase]s against another.
-Digest computeBuildPhasesDigest(Iterable<BuildPhase> buildPhases) {
-  var digestSink = AccumulatorSink<Digest>();
-  md5.startChunkedConversion(digestSink)
-    ..add(buildPhases.map((phase) => phase.identity).toList())
-    ..close();
-  assert(digestSink.events.length == 1);
-  return digestSink.events.first;
-}
-
-Digest computeBuilderOptionsDigest(BuilderOptions options) =>
-    md5.convert(utf8.encode(json.encode(options.config)));
-
-AssetId builderOptionsIdForAction(BuildAction action, int actionNum) {
-  if (action is InBuildPhase) {
-    return AssetId(action.package, 'Phase$actionNum.builderOptions');
-  } else if (action is PostBuildAction) {
-    return AssetId(action.package, 'PostPhase$actionNum.builderOptions');
-  } else {
-    throw StateError('Unsupported action type $action');
-  }
-}
-
-Set<AssetId> placeholderIdsFor(PackageGraph packageGraph) =>
-    Set<AssetId>.from(packageGraph.allPackages.keys.expand((package) => [
-          AssetId(package, r'lib/$lib$'),
-          AssetId(package, r'test/$test$'),
-          AssetId(package, r'web/$web$'),
-          AssetId(package, r'$package$'),
-        ]));
diff --git a/build_runner_core/lib/src/asset_graph/node.dart b/build_runner_core/lib/src/asset_graph/node.dart
deleted file mode 100644
index 5419caa..0000000
--- a/build_runner_core/lib/src/asset_graph/node.dart
+++ /dev/null
@@ -1,300 +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:collection';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:meta/meta.dart';
-
-import '../generate/phase.dart';
-
-/// A node in the asset graph which may be an input to other assets.
-abstract class AssetNode {
-  final AssetId id;
-
-  /// The assets that any [Builder] in the build graph declares it may output
-  /// when run on this asset.
-  final Set<AssetId> primaryOutputs = <AssetId>{};
-
-  /// The [AssetId]s of all generated assets which are output by a [Builder]
-  /// which reads this asset.
-  final Set<AssetId> outputs = <AssetId>{};
-
-  /// The [AssetId]s of all [PostProcessAnchorNode] assets for which this node
-  /// is the primary input.
-  final Set<AssetId> anchorOutputs = <AssetId>{};
-
-  /// The [Digest] for this node in its last known state.
-  ///
-  /// May be `null` if this asset has no outputs, or if it doesn't actually
-  /// exist.
-  Digest lastKnownDigest;
-
-  /// Whether or not this node was an output of this build.
-  bool get isGenerated => false;
-
-  /// Whether or not this asset type can be read.
-  ///
-  /// This does not indicate whether or not this specific node actually exists
-  /// at this moment in time.
-  bool get isReadable => true;
-
-  /// The IDs of the [PostProcessAnchorNode] for post process builder which
-  /// requested to delete this asset.
-  final Set<AssetId> deletedBy = <AssetId>{};
-
-  /// Whether the node is deleted.
-  ///
-  /// Deleted nodes are ignored in the final merge step and watch handlers.
-  bool get isDeleted => deletedBy.isNotEmpty;
-
-  /// Whether or not this node can be read by a builder as a primary or
-  /// secondary input.
-  ///
-  /// Some nodes are valid primary inputs but are not readable (see
-  /// [PlaceHolderAssetNode]), while others are readable in the overall build
-  /// system  but are not valid builder inputs (see [InternalAssetNode]).
-  bool get isValidInput => true;
-
-  /// Whether or not changes to this node will have any effect on other nodes.
-  ///
-  /// Be default, if we haven't computed a digest for this asset and it has no
-  /// outputs, then it isn't interesting.
-  ///
-  /// Checking for a digest alone isn't enough because a file may be deleted
-  /// and re-added, in which case it won't have a digest.
-  bool get isInteresting => outputs.isNotEmpty || lastKnownDigest != null;
-
-  AssetNode(this.id, {this.lastKnownDigest});
-
-  /// Work around issue where you can't mixin classes into a class with optional
-  /// constructor args.
-  AssetNode._forMixins(this.id);
-
-  /// Work around issue where you can't mixin classes into a class with optional
-  /// constructor args, this one includes the digest.
-  AssetNode._forMixinsWithDigest(this.id, this.lastKnownDigest);
-
-  @override
-  String toString() => 'AssetNode: $id';
-}
-
-/// A node representing some internal asset.
-///
-/// These nodes are not used as primary inputs, but they are tracked in the
-/// asset graph and are readable.
-class InternalAssetNode extends AssetNode {
-  // These don't have [outputs] but they are interesting regardless.
-  @override
-  bool get isInteresting => true;
-
-  @override
-  bool get isValidInput => false;
-
-  InternalAssetNode(AssetId id, {Digest lastKnownDigest})
-      : super(id, lastKnownDigest: lastKnownDigest);
-
-  @override
-  String toString() => 'InternalAssetNode: $id';
-}
-
-/// A node which is an original source asset (not generated).
-class SourceAssetNode extends AssetNode {
-  SourceAssetNode(AssetId id, {Digest lastKnownDigest})
-      : super(id, lastKnownDigest: lastKnownDigest);
-
-  @override
-  String toString() => 'SourceAssetNode: $id';
-}
-
-/// States for nodes that can be invalidated.
-enum NodeState {
-  // This node does not need an update, and no checks need to be performed.
-  upToDate,
-  // This node may need an update, the inputs hash should be checked for
-  // changes.
-  mayNeedUpdate,
-  // This node definitely needs an update, the inputs hash check can be skipped.
-  definitelyNeedsUpdate,
-}
-
-/// A generated node in the asset graph.
-class GeneratedAssetNode extends AssetNode implements NodeWithInputs {
-  @override
-  bool get isGenerated => true;
-
-  @override
-  final int phaseNumber;
-
-  /// The primary input which generated this node.
-  final AssetId primaryInput;
-
-  @override
-  NodeState state;
-
-  /// Whether the asset was actually output.
-  bool wasOutput;
-
-  /// All the inputs that were read when generating this asset, or deciding not
-  /// to generate it.
-  ///
-  /// This needs to be an ordered set because we compute combined input digests
-  /// using this later on.
-  @override
-  HashSet<AssetId> inputs;
-
-  /// A digest combining all digests of all previous inputs.
-  ///
-  /// Used to determine whether all the inputs to a build step are identical to
-  /// the previous run, indicating that the previous output is still valid.
-  Digest previousInputsDigest;
-
-  /// Whether the action which did or would produce this node failed.
-  bool isFailure;
-
-  /// The [AssetId] of the node representing the [BuilderOptions] used to create
-  /// this node.
-  final AssetId builderOptionsId;
-
-  /// Whether the asset should be placed in the build cache.
-  final bool isHidden;
-
-  GeneratedAssetNode(
-    AssetId id, {
-    Digest lastKnownDigest,
-    Iterable<AssetId> inputs,
-    this.previousInputsDigest,
-    @required this.isHidden,
-    @required this.state,
-    @required this.phaseNumber,
-    @required this.wasOutput,
-    @required this.isFailure,
-    @required this.primaryInput,
-    @required this.builderOptionsId,
-  })  : inputs = inputs != null ? HashSet.from(inputs) : HashSet(),
-        super(id, lastKnownDigest: lastKnownDigest);
-
-  @override
-  String toString() =>
-      'GeneratedAssetNode: $id generated from input $primaryInput.';
-}
-
-/// A node which is not a generated or source asset.
-///
-/// These are typically not readable or valid as inputs.
-abstract class _SyntheticAssetNode implements AssetNode {
-  @override
-  bool get isReadable => false;
-
-  @override
-  bool get isValidInput => false;
-}
-
-/// A [_SyntheticAssetNode] representing a non-existent source.
-///
-/// Typically these are created as a result of `canRead` calls for assets that
-/// don't exist in the graph. We still need to set up proper dependencies so
-/// that if that asset gets added later the outputs are properly invalidated.
-class SyntheticSourceAssetNode extends AssetNode with _SyntheticAssetNode {
-  SyntheticSourceAssetNode(AssetId id) : super._forMixins(id);
-}
-
-/// A [_SyntheticAssetNode] which represents an individual [BuilderOptions]
-/// object.
-///
-/// These are used to track the state of a [BuilderOptions] object, and all
-/// [GeneratedAssetNode]s should depend on one of these nodes, which represents
-/// their configuration.
-class BuilderOptionsAssetNode extends AssetNode with _SyntheticAssetNode {
-  BuilderOptionsAssetNode(AssetId id, Digest lastKnownDigest)
-      : super._forMixinsWithDigest(id, lastKnownDigest);
-
-  @override
-  String toString() => 'BuildOptionsAssetNode: $id';
-}
-
-/// Placeholder assets are magic files that are usable as inputs but are not
-/// readable.
-class PlaceHolderAssetNode extends AssetNode with _SyntheticAssetNode {
-  @override
-  bool get isValidInput => true;
-
-  PlaceHolderAssetNode(AssetId id) : super._forMixins(id);
-
-  @override
-  String toString() => 'PlaceHolderAssetNode: $id';
-}
-
-/// A [_SyntheticAssetNode] which is created for each [primaryInput] to a
-/// [PostBuildAction].
-///
-/// The [outputs] of this node are the individual outputs created for the
-/// [primaryInput] during the [PostBuildAction] at index [actionNumber].
-class PostProcessAnchorNode extends AssetNode with _SyntheticAssetNode {
-  final int actionNumber;
-  final AssetId builderOptionsId;
-  final AssetId primaryInput;
-  Digest previousInputsDigest;
-
-  PostProcessAnchorNode(
-      AssetId id, this.primaryInput, this.actionNumber, this.builderOptionsId,
-      {this.previousInputsDigest})
-      : super._forMixins(id);
-
-  factory PostProcessAnchorNode.forInputAndAction(
-      AssetId primaryInput, int actionNumber, AssetId builderOptionsId) {
-    return PostProcessAnchorNode(
-        primaryInput.addExtension('.post_anchor.$actionNumber'),
-        primaryInput,
-        actionNumber,
-        builderOptionsId);
-  }
-}
-
-/// A node representing a glob ran from a builder.
-///
-/// The [id] must always be unique to a given package, phase, and glob
-/// pattern.
-class GlobAssetNode extends InternalAssetNode implements NodeWithInputs {
-  final Glob glob;
-
-  /// All the potential inputs matching this glob.
-  ///
-  /// This field differs from [results] in that [GeneratedAssetNode] which may
-  /// have been readable but were not output are included here and not in
-  /// [results].
-  @override
-  HashSet<AssetId> inputs;
-
-  @override
-  bool get isReadable => false;
-
-  @override
-  final int phaseNumber;
-
-  /// The actual results of the glob.
-  List<AssetId> results;
-
-  @override
-  NodeState state;
-
-  GlobAssetNode(AssetId id, this.glob, this.phaseNumber, this.state,
-      {this.inputs, Digest lastKnownDigest, this.results})
-      : super(id, lastKnownDigest: lastKnownDigest);
-
-  static AssetId createId(String package, Glob glob, int phaseNum) => AssetId(
-      package, 'glob.$phaseNum.${base64.encode(utf8.encode(glob.pattern))}');
-}
-
-/// A node which has [inputs], a [NodeState], and a [phaseNumber].
-abstract class NodeWithInputs implements AssetNode {
-  HashSet<AssetId> inputs;
-
-  int get phaseNumber;
-
-  NodeState state;
-}
diff --git a/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart b/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart
deleted file mode 100644
index f5a40b4..0000000
--- a/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-
-import '../generate/phase.dart';
-import '../util/build_dirs.dart';
-import 'graph.dart';
-import 'node.dart';
-
-/// A cache of the results of checking whether outputs from optional build steps
-/// were required by in the current build.
-///
-/// An optional output becomes required if:
-/// - Any of it's transitive outputs is required (based on the criteria below).
-/// - It was output by the same build step as any required output.
-///
-/// Any outputs from non-optional phases are considered required, unless the
-/// following are all true.
-///  - [_buildDirs] is non-empty.
-///  - The output lives in a non-lib directory.
-///  - The outputs path is not prefixed by one of [_buildDirs].
-///  - If [_buildFilters] is non-empty and the output doesn't match one of the
-///    filters.
-///
-/// Non-required optional output might still exist in the generated directory
-/// and the asset graph but we should avoid serving them, outputting them in
-/// the merged directories, or considering a failed output as an overall.
-class OptionalOutputTracker {
-  final _checkedOutputs = <AssetId, bool>{};
-  final AssetGraph _assetGraph;
-  final Set<String> _buildDirs;
-  final Set<BuildFilter> _buildFilters;
-  final List<BuildPhase> _buildPhases;
-
-  OptionalOutputTracker(
-      this._assetGraph, this._buildDirs, this._buildFilters, this._buildPhases);
-
-  /// Returns whether [output] is required.
-  ///
-  /// If necessary crawls transitive outputs that read [output] or any other
-  /// assets generated by the same phase until it finds one which is required.
-  ///
-  /// [currentlyChecking] is used to aovid repeatedly checking the same outputs.
-  bool isRequired(AssetId output, [Set<AssetId> currentlyChecking]) {
-    currentlyChecking ??= <AssetId>{};
-    if (currentlyChecking.contains(output)) return false;
-    currentlyChecking.add(output);
-
-    final node = _assetGraph.get(output);
-    if (node is! GeneratedAssetNode) return true;
-    final generatedNode = node as GeneratedAssetNode;
-    final phase = _buildPhases[generatedNode.phaseNumber];
-    if (!phase.isOptional &&
-        shouldBuildForDirs(output, _buildDirs, _buildFilters, phase)) {
-      return true;
-    }
-    return _checkedOutputs.putIfAbsent(
-        output,
-        () =>
-            generatedNode.outputs
-                .any((o) => isRequired(o, currentlyChecking)) ||
-            _assetGraph
-                .outputsForPhase(output.package, generatedNode.phaseNumber)
-                .where((n) => n.primaryInput == generatedNode.primaryInput)
-                .map((n) => n.id)
-                .any((o) => isRequired(o, currentlyChecking)));
-  }
-
-  /// Clears the cache of which assets were required.
-  ///
-  /// If the tracker is used across multiple builds it must be reset in between
-  /// each one.
-  void reset() {
-    _checkedOutputs.clear();
-  }
-}
diff --git a/build_runner_core/lib/src/asset_graph/serialization.dart b/build_runner_core/lib/src/asset_graph/serialization.dart
deleted file mode 100644
index de14470..0000000
--- a/build_runner_core/lib/src/asset_graph/serialization.dart
+++ /dev/null
@@ -1,513 +0,0 @@
-// 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.
-
-part of 'graph.dart';
-
-/// Part of the serialized graph, used to ensure versioning constraints.
-///
-/// This should be incremented any time the serialize/deserialize formats
-/// change.
-const _version = 22;
-
-/// Deserializes an [AssetGraph] from a [Map].
-class _AssetGraphDeserializer {
-  // Iteration order does not matter
-  final _idToAssetId = HashMap<int, AssetId>();
-  final Map _serializedGraph;
-
-  _AssetGraphDeserializer._(this._serializedGraph);
-
-  factory _AssetGraphDeserializer(List<int> bytes) {
-    dynamic decoded;
-    try {
-      decoded = jsonDecode(utf8.decode(bytes));
-    } on FormatException {
-      throw AssetGraphCorruptedException();
-    }
-    if (decoded is! Map) throw AssetGraphCorruptedException();
-    final serializedGraph = decoded as Map;
-    if (serializedGraph['version'] != _version) {
-      throw AssetGraphCorruptedException();
-    }
-    return _AssetGraphDeserializer._(serializedGraph);
-  }
-
-  /// Perform the deserialization, should only be called once.
-  AssetGraph deserialize() {
-    var graph = AssetGraph._(
-        _deserializeDigest(_serializedGraph['buildActionsDigest'] as String),
-        _serializedGraph['dart_version'] as String);
-
-    var packageNames = _serializedGraph['packages'] as List;
-
-    // Read in the id => AssetId map from the graph first.
-    var assetPaths = _serializedGraph['assetPaths'] as List;
-    for (var i = 0; i < assetPaths.length; i += 2) {
-      var packageName = packageNames[assetPaths[i + 1] as int] as String;
-      _idToAssetId[i ~/ 2] = AssetId(packageName, assetPaths[i] as String);
-    }
-
-    // Read in all the nodes and their outputs.
-    //
-    // Note that this does not read in the inputs of generated nodes.
-    for (var serializedItem in _serializedGraph['nodes']) {
-      graph._add(_deserializeAssetNode(serializedItem as List));
-    }
-
-    // Update the inputs of all generated nodes based on the outputs of the
-    // current nodes.
-    for (var node in graph.allNodes) {
-      // These aren't explicitly added as inputs.
-      if (node is BuilderOptionsAssetNode) continue;
-
-      for (var output in node.outputs) {
-        if (output == null) {
-          log.severe('Found a null output from ${node.id} which is a '
-              '${node.runtimeType}. If you encounter this error please copy '
-              'the details from this message and add them to '
-              'https://github.com/dart-lang/build/issues/1804.');
-          throw AssetGraphCorruptedException();
-        }
-        var inputsNode = graph.get(output) as NodeWithInputs;
-        if (inputsNode == null) {
-          log.severe('Failed to locate $output referenced from ${node.id} '
-              'which is a ${node.runtimeType}. If you encounter this error '
-              'please copy the details from this message and add them to '
-              'https://github.com/dart-lang/build/issues/1804.');
-          throw AssetGraphCorruptedException();
-        }
-        inputsNode.inputs ??= HashSet<AssetId>();
-        inputsNode.inputs.add(node.id);
-      }
-
-      if (node is PostProcessAnchorNode) {
-        graph.get(node.primaryInput).anchorOutputs.add(node.id);
-      }
-    }
-
-    return graph;
-  }
-
-  AssetNode _deserializeAssetNode(List serializedNode) {
-    AssetNode node;
-    var typeId =
-        _NodeType.values[serializedNode[_AssetField.NodeType.index] as int];
-    var id = _idToAssetId[serializedNode[_AssetField.Id.index] as int];
-    var serializedDigest = serializedNode[_AssetField.Digest.index] as String;
-    var digest = _deserializeDigest(serializedDigest);
-    switch (typeId) {
-      case _NodeType.Source:
-        assert(serializedNode.length == _WrappedAssetNode._length);
-        node = SourceAssetNode(id, lastKnownDigest: digest);
-        break;
-      case _NodeType.SyntheticSource:
-        assert(serializedNode.length == _WrappedAssetNode._length);
-        node = SyntheticSourceAssetNode(id);
-        break;
-      case _NodeType.Generated:
-        assert(serializedNode.length == _WrappedGeneratedAssetNode._length);
-        var offset = _AssetField.values.length;
-        node = GeneratedAssetNode(
-          id,
-          phaseNumber:
-              serializedNode[_GeneratedField.PhaseNumber.index + offset] as int,
-          primaryInput: _idToAssetId[
-              serializedNode[_GeneratedField.PrimaryInput.index + offset]
-                  as int],
-          state: NodeState.values[
-              serializedNode[_GeneratedField.State.index + offset] as int],
-          wasOutput: _deserializeBool(
-              serializedNode[_GeneratedField.WasOutput.index + offset] as int),
-          isFailure: _deserializeBool(
-              serializedNode[_GeneratedField.IsFailure.index + offset] as int),
-          builderOptionsId: _idToAssetId[
-              serializedNode[_GeneratedField.BuilderOptions.index + offset]
-                  as int],
-          lastKnownDigest: digest,
-          previousInputsDigest: _deserializeDigest(serializedNode[
-              _GeneratedField.PreviousInputsDigest.index + offset] as String),
-          isHidden: _deserializeBool(
-              serializedNode[_GeneratedField.IsHidden.index + offset] as int),
-        );
-        break;
-      case _NodeType.Glob:
-        assert(serializedNode.length == _WrappedGlobAssetNode._length);
-        var offset = _AssetField.values.length;
-        node = GlobAssetNode(
-          id,
-          Glob(serializedNode[_GlobField.Glob.index + offset] as String),
-          serializedNode[_GlobField.PhaseNumber.index + offset] as int,
-          NodeState
-              .values[serializedNode[_GlobField.State.index + offset] as int],
-          lastKnownDigest: digest,
-          results: _deserializeAssetIds(
-                  serializedNode[_GlobField.Results.index + offset] as List)
-              ?.toList(),
-        );
-        break;
-      case _NodeType.Internal:
-        assert(serializedNode.length == _WrappedAssetNode._length);
-        node = InternalAssetNode(id, lastKnownDigest: digest);
-        break;
-      case _NodeType.BuilderOptions:
-        assert(serializedNode.length == _WrappedAssetNode._length);
-        node = BuilderOptionsAssetNode(id, digest);
-        break;
-      case _NodeType.Placeholder:
-        assert(serializedNode.length == _WrappedAssetNode._length);
-        node = PlaceHolderAssetNode(id);
-        break;
-      case _NodeType.PostProcessAnchor:
-        assert(serializedNode.length == _WrappedPostProcessAnchorNode._length);
-        var offset = _AssetField.values.length;
-        node = PostProcessAnchorNode(
-            id,
-            _idToAssetId[
-                serializedNode[_PostAnchorField.PrimaryInput.index + offset]
-                    as int],
-            serializedNode[_PostAnchorField.ActionNumber.index + offset] as int,
-            _idToAssetId[
-                serializedNode[_PostAnchorField.BuilderOptions.index + offset]
-                    as int],
-            previousInputsDigest: _deserializeDigest(serializedNode[
-                    _PostAnchorField.PreviousInputsDigest.index + offset]
-                as String));
-        break;
-    }
-    node.outputs.addAll(_deserializeAssetIds(
-        serializedNode[_AssetField.Outputs.index] as List));
-    node.primaryOutputs.addAll(_deserializeAssetIds(
-        serializedNode[_AssetField.PrimaryOutputs.index] as List));
-    node.deletedBy.addAll(_deserializeAssetIds(
-        (serializedNode[_AssetField.DeletedBy.index] as List)?.cast<int>()));
-    return node;
-  }
-
-  Iterable<AssetId> _deserializeAssetIds(List serializedIds) =>
-      serializedIds.map((id) => _idToAssetId[id]);
-
-  bool _deserializeBool(int value) => value != 0;
-}
-
-/// Serializes an [AssetGraph] into a [Map].
-class _AssetGraphSerializer {
-  // Iteration order does not matter
-  final _assetIdToId = HashMap<AssetId, int>();
-
-  final AssetGraph _graph;
-
-  _AssetGraphSerializer(this._graph);
-
-  /// Perform the serialization, should only be called once.
-  List<int> serialize() {
-    var pathId = 0;
-    // [path0, packageId0, path1, packageId1, ...]
-    var assetPaths = <dynamic>[];
-    var packages = _graph._nodesByPackage.keys.toList(growable: false);
-    for (var node in _graph.allNodes) {
-      _assetIdToId[node.id] = pathId;
-      pathId++;
-      assetPaths..add(node.id.path)..add(packages.indexOf(node.id.package));
-    }
-
-    var result = <String, dynamic>{
-      'version': _version,
-      'dart_version': _graph.dartVersion,
-      'nodes': _graph.allNodes.map(_serializeNode).toList(growable: false),
-      'buildActionsDigest': _serializeDigest(_graph.buildPhasesDigest),
-      'packages': packages,
-      'assetPaths': assetPaths,
-    };
-    return utf8.encode(json.encode(result));
-  }
-
-  List _serializeNode(AssetNode node) {
-    if (node is GeneratedAssetNode) {
-      return _WrappedGeneratedAssetNode(node, this);
-    } else if (node is PostProcessAnchorNode) {
-      return _WrappedPostProcessAnchorNode(node, this);
-    } else if (node is GlobAssetNode) {
-      return _WrappedGlobAssetNode(node, this);
-    } else {
-      return _WrappedAssetNode(node, this);
-    }
-  }
-
-  int findAssetIndex(AssetId id,
-      {@required AssetId from, @required String field}) {
-    final index = _assetIdToId[id];
-    if (index == null) {
-      log.severe('The $field field in $from references a non-existent asset '
-          '$id and will corrupt the asset graph. '
-          'If you encounter this error please copy '
-          'the details from this message and add them to '
-          'https://github.com/dart-lang/build/issues/1804.');
-    }
-    return index;
-  }
-}
-
-/// Used to serialize the type of a node using an int.
-enum _NodeType {
-  Source,
-  SyntheticSource,
-  Generated,
-  Internal,
-  BuilderOptions,
-  Placeholder,
-  PostProcessAnchor,
-  Glob,
-}
-
-/// Field indexes for all [AssetNode]s
-enum _AssetField {
-  NodeType,
-  Id,
-  Outputs,
-  PrimaryOutputs,
-  Digest,
-  DeletedBy,
-}
-
-/// Field indexes for [GeneratedAssetNode]s
-enum _GeneratedField {
-  PrimaryInput,
-  WasOutput,
-  IsFailure,
-  PhaseNumber,
-  State,
-  PreviousInputsDigest,
-  BuilderOptions,
-  IsHidden,
-}
-
-/// Field indexes for [GlobAssetNode]s
-enum _GlobField {
-  PhaseNumber,
-  State,
-  Glob,
-  Results,
-}
-
-/// Field indexes for [PostProcessAnchorNode]s.
-enum _PostAnchorField {
-  ActionNumber,
-  BuilderOptions,
-  PreviousInputsDigest,
-  PrimaryInput,
-}
-
-/// Wraps an [AssetNode] in a class that implements [List] instead of
-/// creating a new list for each one.
-class _WrappedAssetNode extends Object with ListMixin implements List {
-  final AssetNode node;
-  final _AssetGraphSerializer serializer;
-
-  _WrappedAssetNode(this.node, this.serializer);
-
-  static final int _length = _AssetField.values.length;
-
-  @override
-  int get length => _length;
-
-  @override
-  set length(void _) => throw UnsupportedError(
-      'length setter not unsupported for WrappedAssetNode');
-
-  @override
-  Object operator [](int index) {
-    var fieldId = _AssetField.values[index];
-    switch (fieldId) {
-      case _AssetField.NodeType:
-        if (node is SourceAssetNode) {
-          return _NodeType.Source.index;
-        } else if (node is GeneratedAssetNode) {
-          return _NodeType.Generated.index;
-        } else if (node is GlobAssetNode) {
-          return _NodeType.Glob.index;
-        } else if (node is SyntheticSourceAssetNode) {
-          return _NodeType.SyntheticSource.index;
-        } else if (node is InternalAssetNode) {
-          return _NodeType.Internal.index;
-        } else if (node is BuilderOptionsAssetNode) {
-          return _NodeType.BuilderOptions.index;
-        } else if (node is PlaceHolderAssetNode) {
-          return _NodeType.Placeholder.index;
-        } else if (node is PostProcessAnchorNode) {
-          return _NodeType.PostProcessAnchor.index;
-        } else {
-          throw StateError('Unrecognized node type');
-        }
-        break;
-      case _AssetField.Id:
-        return serializer.findAssetIndex(node.id, from: node.id, field: 'id');
-      case _AssetField.Outputs:
-        return node.outputs
-            .map((id) =>
-                serializer.findAssetIndex(id, from: node.id, field: 'outputs'))
-            .toList(growable: false);
-      case _AssetField.PrimaryOutputs:
-        return node.primaryOutputs
-            .map((id) => serializer.findAssetIndex(id,
-                from: node.id, field: 'primaryOutputs'))
-            .toList(growable: false);
-      case _AssetField.Digest:
-        return _serializeDigest(node.lastKnownDigest);
-      case _AssetField.DeletedBy:
-        return node.deletedBy
-            .map((id) => serializer.findAssetIndex(id,
-                from: node.id, field: 'deletedBy'))
-            .toList(growable: false);
-      default:
-        throw RangeError.index(index, this);
-    }
-  }
-
-  @override
-  operator []=(void _, void __) =>
-      throw UnsupportedError('[]= not supported for WrappedAssetNode');
-}
-
-/// Wraps a [GeneratedAssetNode] in a class that implements [List] instead of
-/// creating a new list for each one.
-class _WrappedGeneratedAssetNode extends _WrappedAssetNode {
-  final GeneratedAssetNode generatedNode;
-
-  /// Offset in the serialized format for additional fields in this class but
-  /// not in [_WrappedAssetNode].
-  ///
-  /// Indexes below this number are forwarded to `super[index]`.
-  static final int _serializedOffset = _AssetField.values.length;
-
-  static final int _length = _serializedOffset + _GeneratedField.values.length;
-
-  @override
-  int get length => _length;
-
-  _WrappedGeneratedAssetNode(
-      this.generatedNode, _AssetGraphSerializer serializer)
-      : super(generatedNode, serializer);
-
-  @override
-  Object operator [](int index) {
-    if (index < _serializedOffset) return super[index];
-    var fieldId = _GeneratedField.values[index - _serializedOffset];
-    switch (fieldId) {
-      case _GeneratedField.PrimaryInput:
-        return generatedNode.primaryInput != null
-            ? serializer.findAssetIndex(generatedNode.primaryInput,
-                from: generatedNode.id, field: 'primaryInput')
-            : null;
-      case _GeneratedField.WasOutput:
-        return _serializeBool(generatedNode.wasOutput);
-      case _GeneratedField.IsFailure:
-        return _serializeBool(generatedNode.isFailure);
-      case _GeneratedField.PhaseNumber:
-        return generatedNode.phaseNumber;
-      case _GeneratedField.State:
-        return generatedNode.state.index;
-      case _GeneratedField.PreviousInputsDigest:
-        return _serializeDigest(generatedNode.previousInputsDigest);
-      case _GeneratedField.BuilderOptions:
-        return serializer.findAssetIndex(generatedNode.builderOptionsId,
-            from: generatedNode.id, field: 'builderOptions');
-      case _GeneratedField.IsHidden:
-        return _serializeBool(generatedNode.isHidden);
-      default:
-        throw RangeError.index(index, this);
-    }
-  }
-}
-
-/// Wraps a [GlobAssetNode] in a class that implements [List] instead of
-/// creating a new list for each one.
-class _WrappedGlobAssetNode extends _WrappedAssetNode {
-  final GlobAssetNode globNode;
-
-  /// Offset in the serialized format for additional fields in this class but
-  /// not in [_WrappedAssetNode].
-  ///
-  /// Indexes below this number are forwarded to `super[index]`.
-  static final int _serializedOffset = _AssetField.values.length;
-
-  static final int _length = _serializedOffset + _GlobField.values.length;
-
-  @override
-  int get length => _length;
-
-  _WrappedGlobAssetNode(this.globNode, _AssetGraphSerializer serializer)
-      : super(globNode, serializer);
-
-  @override
-  Object operator [](int index) {
-    if (index < _serializedOffset) return super[index];
-    var fieldId = _GlobField.values[index - _serializedOffset];
-    switch (fieldId) {
-      case _GlobField.PhaseNumber:
-        return globNode.phaseNumber;
-      case _GlobField.State:
-        return globNode.state.index;
-      case _GlobField.Glob:
-        return globNode.glob.pattern;
-      case _GlobField.Results:
-        return globNode.results
-            .map((id) => serializer.findAssetIndex(id,
-                from: globNode.id, field: 'results'))
-            .toList(growable: false);
-      default:
-        throw RangeError.index(index, this);
-    }
-  }
-}
-
-/// Wraps a [PostProcessAnchorNode] in a class that implements [List] instead of
-/// creating a new list for each one.
-class _WrappedPostProcessAnchorNode extends _WrappedAssetNode {
-  final PostProcessAnchorNode wrappedNode;
-
-  /// Offset in the serialized format for additional fields in this class but
-  /// not in [_WrappedAssetNode].
-  ///
-  /// Indexes below this number are forwarded to `super[index]`.
-  static final int _serializedOffset = _AssetField.values.length;
-
-  static final int _length = _serializedOffset + _PostAnchorField.values.length;
-
-  @override
-  int get length => _length;
-
-  _WrappedPostProcessAnchorNode(
-      this.wrappedNode, _AssetGraphSerializer serializer)
-      : super(wrappedNode, serializer);
-
-  @override
-  Object operator [](int index) {
-    if (index < _serializedOffset) return super[index];
-    var fieldId = _PostAnchorField.values[index - _serializedOffset];
-    switch (fieldId) {
-      case _PostAnchorField.ActionNumber:
-        return wrappedNode.actionNumber;
-      case _PostAnchorField.BuilderOptions:
-        return serializer.findAssetIndex(wrappedNode.builderOptionsId,
-            from: wrappedNode.id, field: 'builderOptions');
-      case _PostAnchorField.PreviousInputsDigest:
-        return _serializeDigest(wrappedNode.previousInputsDigest);
-      case _PostAnchorField.PrimaryInput:
-        return wrappedNode.primaryInput != null
-            ? serializer.findAssetIndex(wrappedNode.primaryInput,
-                from: wrappedNode.id, field: 'primaryInput')
-            : null;
-      default:
-        throw RangeError.index(index, this);
-    }
-  }
-}
-
-Digest _deserializeDigest(String serializedDigest) =>
-    serializedDigest == null ? null : Digest(base64.decode(serializedDigest));
-
-String _serializeDigest(Digest digest) =>
-    digest == null ? null : base64.encode(digest.bytes);
-
-int _serializeBool(bool value) => value ? 1 : 0;
diff --git a/build_runner_core/lib/src/changes/build_script_updates.dart b/build_runner_core/lib/src/changes/build_script_updates.dart
deleted file mode 100644
index ed4c4f1..0000000
--- a/build_runner_core/lib/src/changes/build_script_updates.dart
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:mirrors';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import '../asset/reader.dart';
-import '../asset_graph/graph.dart';
-import '../package_graph/package_graph.dart';
-
-/// Functionality for detecting if the build script itself or any of its
-/// transitive imports have changed.
-abstract class BuildScriptUpdates {
-  /// Checks if the current running program has been updated, based on
-  /// [updatedIds].
-  bool hasBeenUpdated(Set<AssetId> updatedIds);
-
-  /// Creates a [BuildScriptUpdates] object, using [reader] to ensure that
-  /// the [assetGraph] is tracking digests for all transitive sources.
-  ///
-  /// If [disabled] is `true` then all checks are skipped and
-  /// [hasBeenUpdated] will always return `false`.
-  static Future<BuildScriptUpdates> create(RunnerAssetReader reader,
-      PackageGraph packageGraph, AssetGraph assetGraph,
-      {bool disabled = false}) async {
-    disabled ??= false;
-    if (disabled) return _NoopBuildScriptUpdates();
-    return _MirrorBuildScriptUpdates.create(reader, packageGraph, assetGraph);
-  }
-}
-
-/// Uses mirrors to find all transitive imports of the current script.
-class _MirrorBuildScriptUpdates implements BuildScriptUpdates {
-  final Set<AssetId> _allSources;
-  final bool _supportsIncrementalRebuilds;
-
-  _MirrorBuildScriptUpdates._(
-      this._supportsIncrementalRebuilds, this._allSources);
-
-  static Future<BuildScriptUpdates> create(RunnerAssetReader reader,
-      PackageGraph packageGraph, AssetGraph graph) async {
-    var supportsIncrementalRebuilds = true;
-    var rootPackage = packageGraph.root.name;
-    Set<AssetId> allSources;
-    var logger = Logger('BuildScriptUpdates');
-    try {
-      allSources = _urisForThisScript
-          .map((id) => _idForUri(id, rootPackage))
-          .where((id) => id != null)
-          .toSet();
-      var missing = allSources.firstWhere((id) => !graph.contains(id),
-          orElse: () => null);
-      if (missing != null) {
-        supportsIncrementalRebuilds = false;
-        logger.warning('$missing was not found in the asset graph, '
-            'incremental builds will not work.\n This probably means you '
-            'don\'t have your dependencies specified fully in your '
-            'pubspec.yaml.');
-      } else {
-        // Make sure we are tracking changes for all ids in [allSources].
-        for (var id in allSources) {
-          graph.get(id).lastKnownDigest ??= await reader.digest(id);
-        }
-      }
-    } on ArgumentError catch (_) {
-      supportsIncrementalRebuilds = false;
-      allSources = <AssetId>{};
-    }
-    return _MirrorBuildScriptUpdates._(supportsIncrementalRebuilds, allSources);
-  }
-
-  static Iterable<Uri> get _urisForThisScript =>
-      currentMirrorSystem().libraries.keys;
-
-  /// Checks if the current running program has been updated, based on
-  /// [updatedIds].
-  @override
-  bool hasBeenUpdated(Set<AssetId> updatedIds) {
-    if (!_supportsIncrementalRebuilds) return true;
-    return updatedIds.intersection(_allSources).isNotEmpty;
-  }
-
-  /// Attempts to return an [AssetId] for [uri].
-  ///
-  /// Returns `null` if the uri should be ignored, or throws an [ArgumentError]
-  /// if the [uri] is not recognized.
-  static AssetId _idForUri(Uri uri, String _rootPackage) {
-    switch (uri.scheme) {
-      case 'dart':
-        // TODO: check for sdk updates!
-        break;
-      case 'package':
-        var parts = uri.pathSegments;
-        return AssetId(parts[0],
-            p.url.joinAll(['lib', ...parts.getRange(1, parts.length)]));
-      case 'file':
-        var relativePath = p.relative(uri.toFilePath(), from: p.current);
-        return AssetId(_rootPackage, relativePath);
-      case 'data':
-        // Test runner uses a `data` scheme, don't invalidate for those.
-        if (uri.path.contains('package:test')) break;
-        continue unsupported;
-      case 'http':
-        continue unsupported;
-      unsupported:
-      default:
-        throw ArgumentError('Unsupported uri scheme `${uri.scheme}` found for '
-            'library in build script.\n'
-            'This probably means you are running in an unsupported '
-            'context, such as in an isolate or via `pub run`.\n'
-            'Full uri was: $uri.');
-    }
-    return null;
-  }
-}
-
-/// Always returns false for [hasBeenUpdated], used when we want to skip
-/// the build script checks.
-class _NoopBuildScriptUpdates implements BuildScriptUpdates {
-  @override
-  bool hasBeenUpdated(void _) => false;
-}
diff --git a/build_runner_core/lib/src/environment/build_environment.dart b/build_runner_core/lib/src/environment/build_environment.dart
deleted file mode 100644
index 23335d8..0000000
--- a/build_runner_core/lib/src/environment/build_environment.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../generate/build_directory.dart';
-import '../generate/build_result.dart';
-import '../generate/finalized_assets_view.dart';
-
-/// Utilities to interact with the environment in which a build is running.
-///
-/// All side effects and user interaction should go through the build
-/// environment. An IO based environment can write to disk and interact through
-/// stdout/stdin, while a theoretical web or remote environment might interact
-/// over HTTP.
-abstract class BuildEnvironment {
-  RunnerAssetReader get reader;
-  RunnerAssetWriter get writer;
-
-  void onLog(LogRecord record);
-
-  /// Prompt the user for input.
-  ///
-  /// The message and choices are displayed to the user and the index of the
-  /// chosen option is returned.
-  ///
-  /// If this environmment is non-interactive (such as when running in a test)
-  /// this method should throw [NonInteractiveBuildException].
-  Future<int> prompt(String message, List<String> choices);
-
-  /// Invoked after each build, can modify the [BuildResult] in any way, even
-  /// converting it to a failure.
-  ///
-  /// The [finalizedAssetsView] can only be used until the returned [Future]
-  /// completes, it will expire afterwords since it can no longer guarantee a
-  /// consistent state.
-  ///
-  /// By default this returns the original result.
-  ///
-  /// Any operation may be performed, as determined by environment.
-  Future<BuildResult> finalizeBuild(
-          BuildResult buildResult,
-          FinalizedAssetsView finalizedAssetsView,
-          AssetReader assetReader,
-          Set<BuildDirectory> buildDirs) =>
-      Future.value(buildResult);
-}
-
-/// Thrown when the build attempts to prompt the users but no prompt is
-/// possible.
-class NonInteractiveBuildException implements Exception {}
diff --git a/build_runner_core/lib/src/environment/create_merged_dir.dart b/build_runner_core/lib/src/environment/create_merged_dir.dart
deleted file mode 100644
index 24ea463..0000000
--- a/build_runner_core/lib/src/environment/create_merged_dir.dart
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-import 'package:pool/pool.dart';
-
-import '../asset/reader.dart';
-import '../environment/build_environment.dart';
-import '../generate/build_directory.dart';
-import '../generate/finalized_assets_view.dart';
-import '../logging/logging.dart';
-import '../package_graph/package_graph.dart';
-
-/// Pool for async file operations, we don't want to use too many file handles.
-final _descriptorPool = Pool(32);
-
-final _logger = Logger('CreateOutputDir');
-const _manifestName = '.build.manifest';
-const _manifestSeparator = '\n';
-
-/// Creates merged output directories for each [OutputLocation].
-///
-/// Returns whether it succeeded or not.
-Future<bool> createMergedOutputDirectories(
-    Set<BuildDirectory> buildDirs,
-    PackageGraph packageGraph,
-    BuildEnvironment environment,
-    AssetReader reader,
-    FinalizedAssetsView finalizedAssetsView,
-    bool outputSymlinksOnly) async {
-  if (outputSymlinksOnly && reader is! PathProvidingAssetReader) {
-    _logger.severe(
-        'The current environment does not support symlinks, but symlinks were '
-        'requested.');
-    return false;
-  }
-  var conflictingOutputs = _conflicts(buildDirs);
-  if (conflictingOutputs.isNotEmpty) {
-    _logger.severe('Unable to create merged directory. '
-        'Conflicting outputs for $conflictingOutputs');
-    return false;
-  }
-
-  for (var target in buildDirs) {
-    var output = target.outputLocation?.path;
-    if (output != null) {
-      if (!await _createMergedOutputDir(
-          output,
-          target.directory,
-          packageGraph,
-          environment,
-          reader,
-          finalizedAssetsView,
-          // TODO(grouma) - retrieve symlink information from target only.
-          outputSymlinksOnly || target.outputLocation.useSymlinks,
-          target.outputLocation.hoist)) {
-        _logger.severe('Unable to create merged directory for $output.');
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-Set<String> _conflicts(Set<BuildDirectory> buildDirs) {
-  final seen = <String>{};
-  final conflicts = <String>{};
-  var outputLocations =
-      buildDirs.map((d) => d.outputLocation?.path).where((p) => p != null);
-  for (var location in outputLocations) {
-    if (!seen.add(location)) conflicts.add(location);
-  }
-  return conflicts;
-}
-
-Future<bool> _createMergedOutputDir(
-    String outputPath,
-    String root,
-    PackageGraph packageGraph,
-    BuildEnvironment environment,
-    AssetReader reader,
-    FinalizedAssetsView finalizedOutputsView,
-    bool symlinkOnly,
-    bool hoist) async {
-  try {
-    if (root == null) return false;
-    var outputDir = Directory(outputPath);
-    var outputDirExists = await outputDir.exists();
-    if (outputDirExists) {
-      if (!await _cleanUpOutputDir(outputDir, environment)) return false;
-    }
-    var builtAssets = finalizedOutputsView.allAssets(rootDir: root).toList();
-    if (root != '' &&
-        !builtAssets
-            .where((id) => id.package == packageGraph.root.name)
-            .any((id) => p.isWithin(root, id.path))) {
-      _logger.severe('No assets exist in $root, skipping output');
-      return false;
-    }
-
-    var outputAssets = <AssetId>[];
-
-    await logTimedAsync(_logger, 'Creating merged output dir `$outputPath`',
-        () async {
-      if (!outputDirExists) {
-        await outputDir.create(recursive: true);
-      }
-
-      outputAssets.addAll(await Future.wait(builtAssets.map((id) => _writeAsset(
-          id, outputDir, root, packageGraph, reader, symlinkOnly, hoist))));
-
-      var packagesFileContent = packageGraph.allPackages.keys
-          .map((p) => '$p:packages/$p/')
-          .join('\r\n');
-      var packagesAsset = AssetId(packageGraph.root.name, '.packages');
-      await _writeAsString(outputDir, packagesAsset, packagesFileContent);
-      outputAssets.add(packagesAsset);
-
-      if (!hoist) {
-        for (var dir in _findRootDirs(builtAssets, outputPath)) {
-          var link = Link(p.join(outputDir.path, dir, 'packages'));
-          if (!link.existsSync()) {
-            link.createSync(p.join('..', 'packages'), recursive: true);
-          }
-        }
-      }
-    });
-
-    await logTimedAsync(_logger, 'Writing asset manifest', () async {
-      var paths = outputAssets.map((id) => id.path).toList()..sort();
-      var content = paths.join(_manifestSeparator);
-      await _writeAsString(
-          outputDir, AssetId(packageGraph.root.name, _manifestName), content);
-    });
-
-    return true;
-  } on FileSystemException catch (e) {
-    if (e.osError?.errorCode != 1314) rethrow;
-    var devModeLink =
-        'https://docs.microsoft.com/en-us/windows/uwp/get-started/'
-        'enable-your-device-for-development';
-    _logger.severe('Unable to create symlink ${e.path}. Note that to create '
-        'symlinks on windows you need to either run in a console with admin '
-        'privileges or enable developer mode (see $devModeLink).');
-    return false;
-  }
-}
-
-Set<String> _findRootDirs(Iterable<AssetId> allAssets, String outputPath) {
-  var rootDirs = <String>{};
-  for (var id in allAssets) {
-    var parts = p.url.split(id.path);
-    if (parts.length == 1) continue;
-    var dir = parts.first;
-    if (dir == outputPath || dir == 'lib') continue;
-    rootDirs.add(parts.first);
-  }
-  return rootDirs;
-}
-
-Future<AssetId> _writeAsset(
-    AssetId id,
-    Directory outputDir,
-    String root,
-    PackageGraph packageGraph,
-    AssetReader reader,
-    bool symlinkOnly,
-    bool hoist) {
-  return _descriptorPool.withResource(() async {
-    String assetPath;
-    if (id.path.startsWith('lib/')) {
-      assetPath =
-          p.url.join('packages', id.package, id.path.substring('lib/'.length));
-    } else {
-      assetPath = id.path;
-      assert(id.package == packageGraph.root.name);
-      if (hoist && p.isWithin(root, id.path)) {
-        assetPath = p.relative(id.path, from: root);
-      }
-    }
-
-    var outputId = AssetId(packageGraph.root.name, assetPath);
-    try {
-      if (symlinkOnly) {
-        await Link(_filePathFor(outputDir, outputId)).create(
-            // We assert at the top of `createMergedOutputDirectories` that the
-            // reader implements this type when requesting symlinks.
-            (reader as PathProvidingAssetReader).pathTo(id),
-            recursive: true);
-      } else {
-        await _writeAsBytes(outputDir, outputId, await reader.readAsBytes(id));
-      }
-    } on AssetNotFoundException catch (e, __) {
-      if (p.basename(id.path).startsWith('.')) {
-        _logger.fine('Skipping missing hidden file ${id.path}');
-      } else {
-        _logger.severe(
-            'Missing asset ${e.assetId}, it may have been deleted during the '
-            'build. Please try rebuilding and if you continue to see the '
-            'error then file a bug at '
-            'https://github.com/dart-lang/build/issues/new.');
-        rethrow;
-      }
-    }
-    return outputId;
-  });
-}
-
-Future<void> _writeAsBytes(Directory outputDir, AssetId id, List<int> bytes) =>
-    _fileFor(outputDir, id).then((file) => file.writeAsBytes(bytes));
-
-Future<void> _writeAsString(Directory outputDir, AssetId id, String contents) =>
-    _fileFor(outputDir, id).then((file) => file.writeAsString(contents));
-
-Future<File> _fileFor(Directory outputDir, AssetId id) {
-  return File(_filePathFor(outputDir, id)).create(recursive: true);
-}
-
-String _filePathFor(Directory outputDir, AssetId id) {
-  String relativePath;
-  if (id.path.startsWith('lib')) {
-    relativePath =
-        p.join('packages', id.package, p.joinAll(p.url.split(id.path).skip(1)));
-  } else {
-    relativePath = id.path;
-  }
-  return p.join(outputDir.path, relativePath);
-}
-
-/// Checks for a manifest file in [outputDir] and deletes all referenced files.
-///
-/// Prompts the user with a few options if no manifest file is found.
-///
-/// Returns whether or not the directory was successfully cleaned up.
-Future<bool> _cleanUpOutputDir(
-    Directory outputDir, BuildEnvironment environment) async {
-  var outputPath = outputDir.path;
-  var manifestFile = File(p.join(outputPath, _manifestName));
-  if (!manifestFile.existsSync()) {
-    if (outputDir.listSync(recursive: false).isNotEmpty) {
-      var choices = [
-        'Leave the directory unchanged and skip writing the build output',
-        'Delete the directory and all contents',
-        'Leave the directory in place and write over any existing files',
-      ];
-      int choice;
-      try {
-        choice = await environment.prompt(
-            'Found existing directory `$outputPath` but no manifest file.\n'
-            'Please choose one of the following options:',
-            choices);
-      } on NonInteractiveBuildException catch (_) {
-        _logger.severe('Unable to create merged directory at $outputPath.\n'
-            'Choose a different directory or delete the contents of that '
-            'directory.');
-        return false;
-      }
-      switch (choice) {
-        case 0:
-          _logger.severe('Skipped creation of the merged output directory.');
-          return false;
-        case 1:
-          try {
-            outputDir.deleteSync(recursive: true);
-          } catch (e) {
-            _logger.severe(
-                'Failed to delete output dir at `$outputPath` with error:\n\n'
-                '$e');
-            return false;
-          }
-          // Actually recreate the directory, but as an empty one.
-          outputDir.createSync();
-          break;
-        case 2:
-          // Just do nothing here, we overwrite files by default.
-          break;
-      }
-    }
-  } else {
-    var previousOutputs = logTimedSync(
-        _logger,
-        'Reading manifest at ${manifestFile.path}',
-        () => manifestFile.readAsStringSync().split(_manifestSeparator));
-
-    logTimedSync(_logger, 'Deleting previous outputs in `$outputPath`', () {
-      for (var path in previousOutputs) {
-        var file = File(p.join(outputPath, path));
-        if (file.existsSync()) file.deleteSync();
-      }
-      _cleanEmptyDirectories(outputPath, previousOutputs);
-    });
-  }
-  return true;
-}
-
-/// Deletes all the directories which used to contain any path in
-/// [removedFilePaths] if that directory is now empty.
-void _cleanEmptyDirectories(
-    String outputPath, Iterable<String> removedFilePaths) {
-  for (var directory in removedFilePaths
-      .map((path) => p.join(outputPath, p.dirname(path)))
-      .toSet()) {
-    _deleteUp(directory, outputPath);
-  }
-}
-
-/// Deletes the directory at [from] and and any parent directories which are
-/// subdirectories of [to] if they are empty.
-void _deleteUp(String from, String to) {
-  var directoryPath = from;
-  while (p.isWithin(to, directoryPath)) {
-    var directory = Directory(directoryPath);
-    if (!directory.existsSync() || directory.listSync().isNotEmpty) return;
-    directory.deleteSync();
-    directoryPath = p.dirname(directoryPath);
-  }
-}
diff --git a/build_runner_core/lib/src/environment/io_environment.dart b/build_runner_core/lib/src/environment/io_environment.dart
deleted file mode 100644
index a2d4948..0000000
--- a/build_runner_core/lib/src/environment/io_environment.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-
-import '../asset/file_based.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../generate/build_directory.dart';
-import '../generate/build_result.dart';
-import '../generate/finalized_assets_view.dart';
-import '../package_graph/package_graph.dart';
-import 'build_environment.dart';
-import 'create_merged_dir.dart';
-
-final _logger = Logger('IOEnvironment');
-
-/// A [BuildEnvironment] writing to disk and stdout.
-class IOEnvironment implements BuildEnvironment {
-  @override
-  final RunnerAssetReader reader;
-
-  @override
-  final RunnerAssetWriter writer;
-
-  final bool _isInteractive;
-
-  final bool _outputSymlinksOnly;
-
-  final PackageGraph _packageGraph;
-
-  IOEnvironment(this._packageGraph, {bool assumeTty, bool outputSymlinksOnly})
-      : _isInteractive = assumeTty == true || _canPrompt(),
-        _outputSymlinksOnly = outputSymlinksOnly ?? false,
-        reader = FileBasedAssetReader(_packageGraph),
-        writer = FileBasedAssetWriter(_packageGraph) {
-    if (_outputSymlinksOnly && Platform.isWindows) {
-      _logger.warning('Symlinks to files are not yet working on Windows, you '
-          'may experience issues using this mode. Follow '
-          'https://github.com/dart-lang/sdk/issues/33966 for updates.');
-    }
-  }
-
-  @override
-  void onLog(LogRecord record) {
-    if (record.level >= Level.SEVERE) {
-      stderr.writeln(record);
-    } else {
-      stdout.writeln(record);
-    }
-  }
-
-  @override
-  Future<int> prompt(String message, List<String> choices) async {
-    if (!_isInteractive) throw NonInteractiveBuildException();
-    while (true) {
-      stdout.writeln('\n$message');
-      for (var i = 0, l = choices.length; i < l; i++) {
-        stdout.writeln('${i + 1} - ${choices[i]}');
-      }
-      final input = stdin.readLineSync();
-      final choice = int.tryParse(input) ?? -1;
-      if (choice > 0 && choice <= choices.length) return choice - 1;
-      stdout.writeln('Unrecognized option $input, '
-          'a number between 1 and ${choices.length} expected');
-    }
-  }
-
-  @override
-  Future<BuildResult> finalizeBuild(
-      BuildResult buildResult,
-      FinalizedAssetsView finalizedAssetsView,
-      AssetReader reader,
-      Set<BuildDirectory> buildDirs) async {
-    if (buildDirs.any(
-            (target) => target.outputLocation?.path?.isNotEmpty ?? false) &&
-        buildResult.status == BuildStatus.success) {
-      if (!await createMergedOutputDirectories(buildDirs, _packageGraph, this,
-          reader, finalizedAssetsView, _outputSymlinksOnly)) {
-        return _convertToFailure(buildResult,
-            failureType: FailureType.cantCreate);
-      }
-    }
-    return buildResult;
-  }
-}
-
-bool _canPrompt() =>
-    stdioType(stdin) == StdioType.terminal &&
-    // Assume running inside a test if the code is running as a `data:` URI
-    Platform.script.scheme != 'data';
-
-BuildResult _convertToFailure(BuildResult previous,
-        {FailureType failureType}) =>
-    BuildResult(
-      BuildStatus.failure,
-      previous.outputs,
-      performance: previous.performance,
-      failureType: failureType,
-    );
diff --git a/build_runner_core/lib/src/environment/overridable_environment.dart b/build_runner_core/lib/src/environment/overridable_environment.dart
deleted file mode 100644
index a5575aa..0000000
--- a/build_runner_core/lib/src/environment/overridable_environment.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../generate/build_directory.dart';
-import '../generate/build_result.dart';
-import '../generate/finalized_assets_view.dart';
-import 'build_environment.dart';
-
-/// A [BuildEnvironment] which can have individual features overridden.
-class OverrideableEnvironment implements BuildEnvironment {
-  final BuildEnvironment _default;
-
-  final RunnerAssetReader _reader;
-  final RunnerAssetWriter _writer;
-
-  final void Function(LogRecord) _onLog;
-
-  final Future<BuildResult> Function(
-          BuildResult, FinalizedAssetsView, AssetReader, Set<BuildDirectory>)
-      _finalizeBuild;
-
-  OverrideableEnvironment(
-    this._default, {
-    RunnerAssetReader reader,
-    RunnerAssetWriter writer,
-    void Function(LogRecord) onLog,
-    Future<BuildResult> Function(
-            BuildResult, FinalizedAssetsView, AssetReader, Set<BuildDirectory>)
-        finalizeBuild,
-  })  : _reader = reader,
-        _writer = writer,
-        _onLog = onLog,
-        _finalizeBuild = finalizeBuild;
-
-  @override
-  RunnerAssetReader get reader => _reader ?? _default.reader;
-
-  @override
-  RunnerAssetWriter get writer => _writer ?? _default.writer;
-
-  @override
-  Future<BuildResult> finalizeBuild(
-          BuildResult buildResult,
-          FinalizedAssetsView finalizedAssetsView,
-          AssetReader reader,
-          Set<BuildDirectory> buildDirs) =>
-      (_finalizeBuild ?? _default.finalizeBuild)(
-          buildResult, finalizedAssetsView, reader, buildDirs);
-
-  @override
-  void onLog(LogRecord record) {
-    if (_onLog != null) {
-      _onLog(record);
-    } else {
-      _default.onLog(record);
-    }
-  }
-
-  @override
-  Future<int> prompt(String message, List<String> choices) =>
-      _default.prompt(message, choices);
-}
diff --git a/build_runner_core/lib/src/generate/build_definition.dart b/build_runner_core/lib/src/generate/build_definition.dart
deleted file mode 100644
index 447ef22..0000000
--- a/build_runner_core/lib/src/generate/build_definition.dart
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:watcher/watcher.dart';
-
-import '../asset/build_cache.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../asset_graph/exceptions.dart';
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../changes/build_script_updates.dart';
-import '../environment/build_environment.dart';
-import '../logging/failure_reporter.dart';
-import '../logging/logging.dart';
-import '../package_graph/package_graph.dart';
-import '../package_graph/target_graph.dart';
-import '../util/constants.dart';
-import '../util/sdk_version_match.dart';
-import 'exceptions.dart';
-import 'options.dart';
-import 'phase.dart';
-
-final _logger = Logger('BuildDefinition');
-
-class BuildDefinition {
-  final AssetGraph assetGraph;
-  final TargetGraph targetGraph;
-
-  final AssetReader reader;
-  final RunnerAssetWriter writer;
-
-  final PackageGraph packageGraph;
-  final bool deleteFilesByDefault;
-  final ResourceManager resourceManager;
-
-  final BuildScriptUpdates buildScriptUpdates;
-
-  /// Whether or not to run in a mode that conserves RAM at the cost of build
-  /// speed.
-  final bool enableLowResourcesMode;
-
-  final BuildEnvironment environment;
-
-  BuildDefinition._(
-      this.assetGraph,
-      this.targetGraph,
-      this.reader,
-      this.writer,
-      this.packageGraph,
-      this.deleteFilesByDefault,
-      this.resourceManager,
-      this.buildScriptUpdates,
-      this.enableLowResourcesMode,
-      this.environment);
-
-  static Future<BuildDefinition> prepareWorkspace(BuildEnvironment environment,
-          BuildOptions options, List<BuildPhase> buildPhases) =>
-      _Loader(environment, options, buildPhases).prepareWorkspace();
-}
-
-/// Understands how to find all assets relevant to a build as well as compute
-/// updates to those assets.
-class AssetTracker {
-  final AssetGraph _assetGraph;
-  final RunnerAssetReader _reader;
-  final TargetGraph _targetGraph;
-
-  AssetTracker(this._assetGraph, this._reader, this._targetGraph);
-
-  /// Checks for and returns any file system changes compared to the current
-  /// state of the asset graph.
-  Future<Map<AssetId, ChangeType>> collectChanges() async {
-    var inputSources = await _findInputSources();
-    var generatedSources = await _findCacheDirSources();
-    var internalSources = await _findInternalSources();
-    return _computeSourceUpdates(
-        inputSources, generatedSources, internalSources);
-  }
-
-  /// Returns the all the sources found in the cache directory.
-  Future<Set<AssetId>> _findCacheDirSources() =>
-      _listGeneratedAssetIds().toSet();
-
-  /// Returns the set of original package inputs on disk.
-  Future<Set<AssetId>> _findInputSources() {
-    final targets =
-        Stream<TargetNode>.fromIterable(_targetGraph.allModules.values);
-    return targets.asyncExpand(_listAssetIds).toSet();
-  }
-
-  /// Returns all the internal sources, such as those under [entryPointDir].
-  Future<Set<AssetId>> _findInternalSources() =>
-      _listIdsSafe(Glob('$entryPointDir/**')).toSet();
-
-  /// Finds the asset changes which have happened while unwatched between builds
-  /// by taking a difference between the assets in the graph and the assets on
-  /// disk.
-  Future<Map<AssetId, ChangeType>> _computeSourceUpdates(
-      Set<AssetId> inputSources,
-      Set<AssetId> generatedSources,
-      Set<AssetId> internalSources) async {
-    final allSources = <AssetId>{}
-      ..addAll(inputSources)
-      ..addAll(generatedSources)
-      ..addAll(internalSources);
-    var updates = <AssetId, ChangeType>{};
-    void addUpdates(Iterable<AssetId> assets, ChangeType type) {
-      for (var asset in assets) {
-        updates[asset] = type;
-      }
-    }
-
-    var newSources = inputSources.difference(_assetGraph.allNodes
-        .where((node) => node.isValidInput)
-        .map((node) => node.id)
-        .toSet());
-    addUpdates(newSources, ChangeType.ADD);
-    var removedAssets = _assetGraph.allNodes
-        .where((n) {
-          if (!n.isReadable) return false;
-          if (n is GeneratedAssetNode) return n.wasOutput;
-          return true;
-        })
-        .map((n) => n.id)
-        .where((id) => !allSources.contains(id));
-
-    addUpdates(removedAssets, ChangeType.REMOVE);
-
-    var originalGraphSources = _assetGraph.sources.toSet();
-    var preExistingSources = originalGraphSources.intersection(inputSources)
-      ..addAll(internalSources.where(_assetGraph.contains));
-    var modifyChecks = preExistingSources.map((id) async {
-      var node = _assetGraph.get(id);
-      assert(node != null);
-      var originalDigest = node.lastKnownDigest;
-      if (originalDigest == null) return;
-      var currentDigest = await _reader.digest(id);
-      if (currentDigest != originalDigest) {
-        updates[id] = ChangeType.MODIFY;
-      }
-    });
-    await Future.wait(modifyChecks);
-    return updates;
-  }
-
-  Stream<AssetId> _listAssetIds(TargetNode targetNode) => targetNode
-          .sourceIncludes.isEmpty
-      ? Stream<AssetId>.empty()
-      : StreamGroup.merge(targetNode.sourceIncludes.map((glob) =>
-          _listIdsSafe(glob, package: targetNode.package.name)
-              .where((id) =>
-                  targetNode.package.isRoot || id.pathSegments.first == 'lib')
-              .where((id) => !targetNode.excludesSource(id))));
-
-  Stream<AssetId> _listGeneratedAssetIds() {
-    var glob = Glob('$generatedOutputDirectory/**');
-
-    return _listIdsSafe(glob).map((id) {
-      var packagePath = id.path.substring(generatedOutputDirectory.length + 1);
-      var firstSlash = packagePath.indexOf('/');
-      if (firstSlash == -1) return null;
-      var package = packagePath.substring(0, firstSlash);
-      var path = packagePath.substring(firstSlash + 1);
-      return AssetId(package, path);
-    }).where((id) => id != null);
-  }
-
-  /// Lists asset ids and swallows file not found errors.
-  ///
-  /// Ideally we would warn but in practice the default whitelist will give this
-  /// error a lot and it would be noisy.
-  Stream<AssetId> _listIdsSafe(Glob glob, {String package}) =>
-      _reader.findAssets(glob, package: package).handleError((void _) {},
-          test: (e) => e is FileSystemException && e.osError.errorCode == 2);
-}
-
-class _Loader {
-  final List<BuildPhase> _buildPhases;
-  final BuildOptions _options;
-  final BuildEnvironment _environment;
-
-  _Loader(this._environment, this._options, this._buildPhases);
-
-  Future<BuildDefinition> prepareWorkspace() async {
-    _checkBuildPhases();
-
-    _logger.info('Initializing inputs');
-
-    var assetGraph = await _tryReadCachedAssetGraph();
-    var assetTracker =
-        AssetTracker(assetGraph, _environment.reader, _options.targetGraph);
-    var inputSources = await assetTracker._findInputSources();
-    var cacheDirSources = await assetTracker._findCacheDirSources();
-    var internalSources = await assetTracker._findInternalSources();
-
-    BuildScriptUpdates buildScriptUpdates;
-    if (assetGraph != null) {
-      var updates = await logTimedAsync(
-          _logger,
-          'Checking for updates since last build',
-          () => _updateAssetGraph(assetGraph, assetTracker, _buildPhases,
-              inputSources, cacheDirSources, internalSources));
-
-      buildScriptUpdates = await BuildScriptUpdates.create(
-          _environment.reader, _options.packageGraph, assetGraph,
-          disabled: _options.skipBuildScriptCheck);
-      if (!_options.skipBuildScriptCheck &&
-          buildScriptUpdates.hasBeenUpdated(updates.keys.toSet())) {
-        _logger.warning('Invalidating asset graph due to build script update!');
-        var deletedSourceOutputs = await _cleanupOldOutputs(assetGraph);
-
-        if (_runningFromSnapshot) {
-          // We have to be regenerated if running from a snapshot.
-          throw BuildScriptChangedException();
-        }
-
-        inputSources.removeAll(deletedSourceOutputs);
-        assetGraph = null;
-        buildScriptUpdates = null;
-      }
-    }
-
-    if (assetGraph == null) {
-      Set<AssetId> conflictingOutputs;
-
-      await logTimedAsync(_logger, 'Building new asset graph', () async {
-        try {
-          assetGraph = await AssetGraph.build(_buildPhases, inputSources,
-              internalSources, _options.packageGraph, _environment.reader);
-        } on DuplicateAssetNodeException catch (e, st) {
-          _logger.severe('Conflicting outputs', e, st);
-          throw CannotBuildException();
-        }
-        buildScriptUpdates = await BuildScriptUpdates.create(
-            _environment.reader, _options.packageGraph, assetGraph,
-            disabled: _options.skipBuildScriptCheck);
-        conflictingOutputs = assetGraph.outputs
-            .where((n) => n.package == _options.packageGraph.root.name)
-            .where(inputSources.contains)
-            .toSet();
-        final conflictsInDeps = assetGraph.outputs
-            .where((n) => n.package != _options.packageGraph.root.name)
-            .where(inputSources.contains)
-            .toSet();
-        if (conflictsInDeps.isNotEmpty) {
-          log.severe('There are existing files in dependencies which conflict '
-              'with files that a Builder may produce. These must be removed or '
-              'the Builders disabled before a build can continue: '
-              '${conflictsInDeps.map((a) => a.uri).join('\n')}');
-          throw CannotBuildException();
-        }
-      });
-
-      await logTimedAsync(
-          _logger,
-          'Checking for unexpected pre-existing outputs.',
-          () => _initialBuildCleanup(conflictingOutputs,
-              _wrapWriter(_environment.writer, assetGraph)));
-    }
-
-    return BuildDefinition._(
-        assetGraph,
-        _options.targetGraph,
-        _wrapReader(_environment.reader, assetGraph),
-        _wrapWriter(_environment.writer, assetGraph),
-        _options.packageGraph,
-        _options.deleteFilesByDefault,
-        ResourceManager(),
-        buildScriptUpdates,
-        _options.enableLowResourcesMode,
-        _environment);
-  }
-
-  /// Checks that the [_buildPhases] are valid based on whether they are
-  /// written to the build cache.
-  void _checkBuildPhases() {
-    final root = _options.packageGraph.root.name;
-    for (final action in _buildPhases) {
-      if (!action.hideOutput) {
-        // Only `InBuildPhase`s can be not hidden.
-        if (action is InBuildPhase && action.package != root) {
-          // This should happen only with a manual build script since the build
-          // script generation filters these out.
-          _logger.severe('A build phase (${action.builderLabel}) is attempting '
-              'to operate on package "${action.package}", but the build script '
-              'is located in package "$root". It\'s not valid to attempt to '
-              'generate files for another package unless the BuilderApplication'
-              'specified "hideOutput".'
-              '\n\n'
-              'Did you mean to write:\n'
-              '  new BuilderApplication(..., toRoot())\n'
-              'or\n'
-              '  new BuilderApplication(..., hideOutput: true)\n'
-              '... instead?');
-          throw CannotBuildException();
-        }
-      }
-    }
-  }
-
-  /// Deletes the generated output directory.
-  ///
-  /// Typically this should be done whenever an asset graph is thrown away.
-  Future<void> _deleteGeneratedDir() async {
-    var generatedDir = Directory(generatedOutputDirectory);
-    if (await generatedDir.exists()) {
-      await generatedDir.delete(recursive: true);
-    }
-  }
-
-  /// Attempts to read in an [AssetGraph] from disk, and returns `null` if it
-  /// fails for any reason.
-  Future<AssetGraph> _tryReadCachedAssetGraph() async {
-    final assetGraphId =
-        AssetId(_options.packageGraph.root.name, assetGraphPath);
-    if (!await _environment.reader.canRead(assetGraphId)) {
-      return null;
-    }
-
-    return logTimedAsync(_logger, 'Reading cached asset graph', () async {
-      try {
-        var cachedGraph = AssetGraph.deserialize(
-            await _environment.reader.readAsBytes(assetGraphId));
-        if (computeBuildPhasesDigest(_buildPhases) !=
-            cachedGraph.buildPhasesDigest) {
-          _logger.warning(
-              'Throwing away cached asset graph because the build phases have '
-              'changed. This most commonly would happen as a result of adding a '
-              'new dependency or updating your dependencies.');
-          await Future.wait([
-            _cleanupOldOutputs(cachedGraph),
-            FailureReporter.cleanErrorCache(),
-          ]);
-          if (_runningFromSnapshot) {
-            throw BuildScriptChangedException();
-          }
-          return null;
-        }
-        if (!isSameSdkVersion(cachedGraph.dartVersion, Platform.version)) {
-          _logger.warning(
-              'Throwing away cached asset graph due to Dart SDK update.');
-          await Future.wait([
-            _cleanupOldOutputs(cachedGraph),
-            FailureReporter.cleanErrorCache(),
-          ]);
-          if (_runningFromSnapshot) {
-            throw BuildScriptChangedException();
-          }
-          return null;
-        }
-        return cachedGraph;
-      } on AssetGraphCorruptedException catch (_) {
-        // Start fresh if the cached asset_graph cannot be deserialized
-        _logger.warning('Throwing away cached asset graph due to '
-            'version mismatch or corrupted asset graph.');
-        await Future.wait([
-          _deleteGeneratedDir(),
-          FailureReporter.cleanErrorCache(),
-        ]);
-        return null;
-      }
-    });
-  }
-
-  /// Deletes all the old outputs from [graph] that were written to the source
-  /// tree, and deletes the entire generated directory.
-  Future<Iterable<AssetId>> _cleanupOldOutputs(AssetGraph graph) async {
-    var deletedSources = <AssetId>[];
-    await logTimedAsync(_logger, 'Cleaning up outputs from previous builds.',
-        () async {
-      // Delete all the non-hidden outputs.
-      await Future.wait(graph.outputs.map((id) {
-        var node = graph.get(id) as GeneratedAssetNode;
-        if (node.wasOutput && !node.isHidden) {
-          var idToDelete = id;
-          // If the package no longer exists, then the user must have renamed
-          // the root package.
-          //
-          // In that case we change `idToDelete` to be in the root package.
-          if (_options.packageGraph[id.package] == null) {
-            idToDelete = AssetId(_options.packageGraph.root.name, id.path);
-          }
-          deletedSources.add(idToDelete);
-          return _environment.writer.delete(idToDelete);
-        }
-        return null;
-      }).whereType<Future>());
-
-      await _deleteGeneratedDir();
-    });
-    return deletedSources;
-  }
-
-  /// Updates [assetGraph] based on a the new view of the world.
-  ///
-  /// Once done, this returns a map of [AssetId] to [ChangeType] for all the
-  /// changes.
-  Future<Map<AssetId, ChangeType>> _updateAssetGraph(
-      AssetGraph assetGraph,
-      AssetTracker assetTracker,
-      List<BuildPhase> buildPhases,
-      Set<AssetId> inputSources,
-      Set<AssetId> cacheDirSources,
-      Set<AssetId> internalSources) async {
-    var updates = await assetTracker._computeSourceUpdates(
-        inputSources, cacheDirSources, internalSources);
-    updates.addAll(_computeBuilderOptionsUpdates(assetGraph, buildPhases));
-    await assetGraph.updateAndInvalidate(
-        _buildPhases,
-        updates,
-        _options.packageGraph.root.name,
-        (id) => _wrapWriter(_environment.writer, assetGraph).delete(id),
-        _wrapReader(_environment.reader, assetGraph));
-    return updates;
-  }
-
-  /// Wraps [original] in a [BuildCacheWriter].
-  RunnerAssetWriter _wrapWriter(
-      RunnerAssetWriter original, AssetGraph assetGraph) {
-    assert(assetGraph != null);
-    return BuildCacheWriter(
-        original, assetGraph, _options.packageGraph.root.name);
-  }
-
-  /// Wraps [original] in a [BuildCacheReader].
-  AssetReader _wrapReader(AssetReader original, AssetGraph assetGraph) {
-    assert(assetGraph != null);
-    return BuildCacheReader(
-        original, assetGraph, _options.packageGraph.root.name);
-  }
-
-  /// Checks for any updates to the [BuilderOptionsAssetNode]s for
-  /// [buildPhases] compared to the last known state.
-  Map<AssetId, ChangeType> _computeBuilderOptionsUpdates(
-      AssetGraph assetGraph, List<BuildPhase> buildPhases) {
-    var result = <AssetId, ChangeType>{};
-
-    void updateBuilderOptionsNode(
-        AssetId builderOptionsId, BuilderOptions options) {
-      var builderOptionsNode =
-          assetGraph.get(builderOptionsId) as BuilderOptionsAssetNode;
-      var oldDigest = builderOptionsNode.lastKnownDigest;
-      builderOptionsNode.lastKnownDigest = computeBuilderOptionsDigest(options);
-      if (builderOptionsNode.lastKnownDigest != oldDigest) {
-        result[builderOptionsId] = ChangeType.MODIFY;
-      }
-    }
-
-    for (var phase = 0; phase < buildPhases.length; phase++) {
-      var action = buildPhases[phase];
-      if (action is InBuildPhase) {
-        updateBuilderOptionsNode(
-            builderOptionsIdForAction(action, phase), action.builderOptions);
-      } else if (action is PostBuildPhase) {
-        var actionNum = 0;
-        for (var builderAction in action.builderActions) {
-          updateBuilderOptionsNode(
-              builderOptionsIdForAction(builderAction, actionNum),
-              builderAction.builderOptions);
-          actionNum++;
-        }
-      }
-    }
-    return result;
-  }
-
-  /// Handles cleanup of pre-existing outputs for initial builds (where there is
-  /// no cached graph).
-  Future<void> _initialBuildCleanup(
-      Set<AssetId> conflictingAssets, RunnerAssetWriter writer) async {
-    if (conflictingAssets.isEmpty) return;
-
-    // Skip the prompt if using this option.
-    if (_options.deleteFilesByDefault) {
-      _logger.info('Deleting ${conflictingAssets.length} declared outputs '
-          'which already existed on disk.');
-      await Future.wait(conflictingAssets.map((id) => writer.delete(id)));
-      return;
-    }
-
-    // Prompt the user to delete files that are declared as outputs.
-    _logger.info('Found ${conflictingAssets.length} declared outputs '
-        'which already exist on disk. This is likely because the'
-        '`$cacheDir` folder was deleted, or you are submitting generated '
-        'files to your source repository.');
-
-    var done = false;
-    while (!done) {
-      try {
-        var choice = await _environment.prompt('Delete these files?',
-            ['Delete', 'Cancel build', 'List conflicts']);
-        switch (choice) {
-          case 0:
-            _logger.info('Deleting files...');
-            done = true;
-            await Future.wait(conflictingAssets.map((id) => writer.delete(id)));
-            break;
-          case 1:
-            _logger.severe('The build will not be able to contiue until the '
-                'conflicting assets are removed or the Builders which may '
-                'output them are disabled. The outputs are: '
-                '${conflictingAssets.map((a) => a.path).join('\n')}');
-            throw CannotBuildException();
-            break;
-          case 2:
-            _logger.info('Conflicts:\n${conflictingAssets.join('\n')}');
-            // Logging should be sync :(
-            await Future(() {});
-        }
-      } on NonInteractiveBuildException {
-        _logger.severe('Conflicting outputs were detected and the build '
-            'is unable to prompt for permission to remove them. '
-            'These outputs must be removed manually or the build can be '
-            'run with `--delete-conflicting-outputs`. The outputs are: '
-            '${conflictingAssets.map((a) => a.path).join('\n')}');
-        throw CannotBuildException();
-      }
-    }
-  }
-}
-
-bool get _runningFromSnapshot => !Platform.script.path.endsWith('.dart');
diff --git a/build_runner_core/lib/src/generate/build_directory.dart b/build_runner_core/lib/src/generate/build_directory.dart
deleted file mode 100644
index bbfedff..0000000
--- a/build_runner_core/lib/src/generate/build_directory.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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 '../util/hash.dart';
-
-class BuildDirectory {
-  final String directory;
-  final OutputLocation outputLocation;
-  BuildDirectory(this.directory, {this.outputLocation});
-
-  @override
-  bool operator ==(Object other) =>
-      other is BuildDirectory &&
-      other.directory == directory &&
-      other.outputLocation == outputLocation;
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = hashCombine(hash, directory.hashCode);
-    hash = hashCombine(hash, outputLocation.hashCode);
-    return hashComplete(hash);
-  }
-}
-
-class OutputLocation {
-  final String path;
-  final bool useSymlinks;
-  final bool hoist;
-  OutputLocation(this.path, {bool useSymlinks, bool hoist})
-      : useSymlinks = useSymlinks ?? false,
-        hoist = hoist ?? true {
-    if (path.isEmpty && hoist) {
-      throw ArgumentError('Can not build everything and hoist');
-    }
-  }
-
-  @override
-  bool operator ==(Object other) =>
-      other is OutputLocation &&
-      other.path == path &&
-      other.useSymlinks == useSymlinks &&
-      other.hoist == hoist;
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = hashCombine(hash, path.hashCode);
-    hash = hashCombine(hash, useSymlinks.hashCode);
-    hash = hashCombine(hash, hoist.hashCode);
-    return hashComplete(hash);
-  }
-}
diff --git a/build_runner_core/lib/src/generate/build_impl.dart b/build_runner_core/lib/src/generate/build_impl.dart
deleted file mode 100644
index 4c3180a..0000000
--- a/build_runner_core/lib/src/generate/build_impl.dart
+++ /dev/null
@@ -1,896 +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:collection';
-import 'dart:convert';
-import 'dart:typed_data';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-import 'package:pedantic/pedantic.dart';
-import 'package:pool/pool.dart';
-import 'package:watcher/watcher.dart';
-
-import '../asset/cache.dart';
-import '../asset/finalized_reader.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../asset_graph/optional_output_tracker.dart';
-import '../changes/build_script_updates.dart';
-import '../environment/build_environment.dart';
-import '../logging/build_for_input_logger.dart';
-import '../logging/failure_reporter.dart';
-import '../logging/human_readable_duration.dart';
-import '../logging/logging.dart';
-import '../package_graph/apply_builders.dart';
-import '../package_graph/package_graph.dart';
-import '../performance_tracking/performance_tracking_resolvers.dart';
-import '../util/async.dart';
-import '../util/build_dirs.dart';
-import '../util/constants.dart';
-import 'build_definition.dart';
-import 'build_directory.dart';
-import 'build_result.dart';
-import 'finalized_assets_view.dart';
-import 'heartbeat.dart';
-import 'options.dart';
-import 'performance_tracker.dart';
-import 'phase.dart';
-
-final _logger = Logger('Build');
-
-Set<String> _buildPaths(Set<BuildDirectory> buildDirs) =>
-    // The empty string means build everything.
-    buildDirs.any((b) => b.directory == '')
-        ? <String>{}
-        : buildDirs.map((b) => b.directory).toSet();
-
-class BuildImpl {
-  final FinalizedReader finalizedReader;
-
-  final AssetGraph assetGraph;
-
-  final BuildScriptUpdates buildScriptUpdates;
-
-  final List<BuildPhase> _buildPhases;
-  final PackageGraph _packageGraph;
-  final AssetReader _reader;
-  final Resolvers _resolvers;
-  final ResourceManager _resourceManager;
-  final RunnerAssetWriter _writer;
-  final bool _trackPerformance;
-  final BuildEnvironment _environment;
-  final String _logPerformanceDir;
-
-  Future<void> beforeExit() => _resourceManager.beforeExit();
-
-  BuildImpl._(BuildDefinition buildDefinition, BuildOptions options,
-      this._buildPhases, this.finalizedReader)
-      : buildScriptUpdates = buildDefinition.buildScriptUpdates,
-        _packageGraph = buildDefinition.packageGraph,
-        _reader = options.enableLowResourcesMode
-            ? buildDefinition.reader
-            : CachingAssetReader(buildDefinition.reader),
-        _resolvers = options.resolvers,
-        _writer = buildDefinition.writer,
-        assetGraph = buildDefinition.assetGraph,
-        _resourceManager = buildDefinition.resourceManager,
-        _environment = buildDefinition.environment,
-        _trackPerformance = options.trackPerformance,
-        _logPerformanceDir = options.logPerformanceDir;
-
-  Future<BuildResult> run(Map<AssetId, ChangeType> updates,
-      {Set<BuildDirectory> buildDirs, Set<BuildFilter> buildFilters}) {
-    buildDirs ??= <BuildDirectory>{};
-    buildFilters ??= {};
-    finalizedReader.reset(_buildPaths(buildDirs), buildFilters);
-    return _SingleBuild(this, buildDirs, buildFilters).run(updates)
-      ..whenComplete(_resolvers.reset);
-  }
-
-  static Future<BuildImpl> create(
-      BuildOptions options,
-      BuildEnvironment environment,
-      List<BuilderApplication> builders,
-      Map<String, Map<String, dynamic>> builderConfigOverrides,
-      {bool isReleaseBuild = false}) async {
-    // Don't allow any changes to the generated asset directory after this
-    // point.
-    lockGeneratedOutputDirectory();
-
-    var buildPhases = await createBuildPhases(
-        options.targetGraph, builders, builderConfigOverrides, isReleaseBuild);
-    if (buildPhases.isEmpty) {
-      _logger.severe('Nothing can be built, yet a build was requested.');
-    }
-    var buildDefinition = await BuildDefinition.prepareWorkspace(
-        environment, options, buildPhases);
-    var singleStepReader = SingleStepReader(
-        buildDefinition.reader,
-        buildDefinition.assetGraph,
-        buildPhases.length,
-        options.packageGraph.root.name,
-        _isReadableAfterBuildFactory(buildPhases));
-    var finalizedReader = FinalizedReader(
-        singleStepReader,
-        buildDefinition.assetGraph,
-        buildPhases,
-        options.packageGraph.root.name);
-    var build =
-        BuildImpl._(buildDefinition, options, buildPhases, finalizedReader);
-    return build;
-  }
-
-  static IsReadable _isReadableAfterBuildFactory(List<BuildPhase> buildPhases) {
-    return (AssetNode node, int phaseNum, AssetWriterSpy writtenAssets) {
-      if (node is GeneratedAssetNode) {
-        return Readability.fromPreviousPhase(node.wasOutput && !node.isFailure);
-      }
-
-      return Readability.fromPreviousPhase(
-          node.isReadable && node.isValidInput);
-    };
-  }
-}
-
-/// Performs a single build and manages state that only lives for a single
-/// build.
-class _SingleBuild {
-  final AssetGraph _assetGraph;
-  final Set<BuildFilter> _buildFilters;
-  final List<BuildPhase> _buildPhases;
-  final List<Pool> _buildPhasePool;
-  final BuildEnvironment _environment;
-  final _lazyPhases = <String, Future<Iterable<AssetId>>>{};
-  final _lazyGlobs = <AssetId, Future<void>>{};
-  final PackageGraph _packageGraph;
-  final BuildPerformanceTracker _performanceTracker;
-  final AssetReader _reader;
-  final Resolvers _resolvers;
-  final ResourceManager _resourceManager;
-  final RunnerAssetWriter _writer;
-  final Set<BuildDirectory> _buildDirs;
-  final String _logPerformanceDir;
-  final _failureReporter = FailureReporter();
-
-  int actionsCompletedCount = 0;
-  int actionsStartedCount = 0;
-
-  final pendingActions = SplayTreeMap<int, Set<String>>();
-
-  /// Can't be final since it needs access to [pendingActions].
-  HungActionsHeartbeat hungActionsHeartbeat;
-
-  _SingleBuild(BuildImpl buildImpl, Set<BuildDirectory> buildDirs,
-      Set<BuildFilter> buildFilters)
-      : _assetGraph = buildImpl.assetGraph,
-        _buildFilters = buildFilters,
-        _buildPhases = buildImpl._buildPhases,
-        _buildPhasePool = List(buildImpl._buildPhases.length),
-        _environment = buildImpl._environment,
-        _packageGraph = buildImpl._packageGraph,
-        _performanceTracker = buildImpl._trackPerformance
-            ? BuildPerformanceTracker()
-            : BuildPerformanceTracker.noOp(),
-        _reader = buildImpl._reader,
-        _resolvers = buildImpl._resolvers,
-        _resourceManager = buildImpl._resourceManager,
-        _writer = buildImpl._writer,
-        _buildDirs = buildDirs,
-        _logPerformanceDir = buildImpl._logPerformanceDir {
-    hungActionsHeartbeat = HungActionsHeartbeat(() {
-      final message = StringBuffer();
-      const actionsToLogMax = 5;
-      var descriptions = pendingActions.values.fold(
-          <String>[],
-          (combined, actions) =>
-              combined..addAll(actions)).take(actionsToLogMax);
-      for (final description in descriptions) {
-        message.writeln('  - $description');
-      }
-      var additionalActionsCount =
-          actionsStartedCount - actionsCompletedCount - actionsToLogMax;
-      if (additionalActionsCount > 0) {
-        message.writeln('  .. and $additionalActionsCount more');
-      }
-      return '$message';
-    });
-  }
-
-  Future<BuildResult> run(Map<AssetId, ChangeType> updates) async {
-    var watch = Stopwatch()..start();
-    var result = await _safeBuild(updates);
-    var optionalOutputTracker = OptionalOutputTracker(
-        _assetGraph, _buildPaths(_buildDirs), _buildFilters, _buildPhases);
-    if (result.status == BuildStatus.success) {
-      final failures = _assetGraph.failedOutputs
-          .where((n) => optionalOutputTracker.isRequired(n.id));
-      if (failures.isNotEmpty) {
-        await _failureReporter.reportErrors(failures);
-        result = BuildResult(BuildStatus.failure, result.outputs,
-            performance: result.performance);
-      }
-    }
-    await _resourceManager.disposeAll();
-    result = await _environment.finalizeBuild(
-        result,
-        FinalizedAssetsView(_assetGraph, optionalOutputTracker),
-        _reader,
-        _buildDirs);
-    if (result.status == BuildStatus.success) {
-      _logger.info('Succeeded after ${humanReadable(watch.elapsed)} with '
-          '${result.outputs.length} outputs '
-          '($actionsCompletedCount actions)\n');
-    } else {
-      _logger.severe('Failed after ${humanReadable(watch.elapsed)}');
-    }
-    return result;
-  }
-
-  Future<void> _updateAssetGraph(Map<AssetId, ChangeType> updates) async {
-    await logTimedAsync(_logger, 'Updating asset graph', () async {
-      var invalidated = await _assetGraph.updateAndInvalidate(
-          _buildPhases, updates, _packageGraph.root.name, _delete, _reader);
-      if (_reader is CachingAssetReader) {
-        (_reader as CachingAssetReader).invalidate(invalidated);
-      }
-    });
-  }
-
-  /// Runs a build inside a zone with an error handler and stack chain
-  /// capturing.
-  Future<BuildResult> _safeBuild(Map<AssetId, ChangeType> updates) {
-    var done = Completer<BuildResult>();
-
-    var heartbeat = HeartbeatLogger(
-        transformLog: (original) => '$original, ${_buildProgress()}',
-        waitDuration: Duration(seconds: 1))
-      ..start();
-    hungActionsHeartbeat.start();
-    done.future.whenComplete(() {
-      heartbeat.stop();
-      hungActionsHeartbeat.stop();
-    });
-
-    runZoned(() async {
-      if (updates.isNotEmpty) {
-        await _updateAssetGraph(updates);
-      }
-      // Run a fresh build.
-      var result = await logTimedAsync(_logger, 'Running build', _runPhases);
-
-      // Write out the dependency graph file.
-      await logTimedAsync(_logger, 'Caching finalized dependency graph',
-          () async {
-        await _writer.writeAsBytes(
-            AssetId(_packageGraph.root.name, assetGraphPath),
-            _assetGraph.serialize());
-      });
-
-      // Log performance information if requested
-      if (_logPerformanceDir != null) {
-        assert(result.performance != null);
-        var now = DateTime.now();
-        var logPath = p.join(
-            _logPerformanceDir,
-            '${now.year}-${_twoDigits(now.month)}-${_twoDigits(now.day)}'
-            '_${_twoDigits(now.hour)}-${_twoDigits(now.minute)}-'
-            '${_twoDigits(now.second)}');
-        await logTimedAsync(_logger, 'Writing performance log to $logPath', () {
-          var performanceLogId = AssetId(_packageGraph.root.name, logPath);
-          var serialized = jsonEncode(result.performance);
-          return _writer.writeAsString(performanceLogId, serialized);
-        });
-      }
-
-      if (!done.isCompleted) done.complete(result);
-    }, onError: (Object e, StackTrace st) {
-      if (!done.isCompleted) {
-        _logger.severe('Unhandled build failure!', e, st);
-        done.complete(BuildResult(BuildStatus.failure, []));
-      }
-    });
-    return done.future;
-  }
-
-  /// Returns a message describing the progress of the current build.
-  String _buildProgress() =>
-      '$actionsCompletedCount/$actionsStartedCount actions completed.';
-
-  /// Runs the actions in [_buildPhases] and returns a [Future<BuildResult>]
-  /// which completes once all [BuildPhase]s are done.
-  Future<BuildResult> _runPhases() {
-    return _performanceTracker.track(() async {
-      final outputs = <AssetId>[];
-      for (var phaseNum = 0; phaseNum < _buildPhases.length; phaseNum++) {
-        var phase = _buildPhases[phaseNum];
-        if (phase.isOptional) continue;
-        outputs
-            .addAll(await _performanceTracker.trackBuildPhase(phase, () async {
-          if (phase is InBuildPhase) {
-            var primaryInputs =
-                await _matchingPrimaryInputs(phase.package, phaseNum);
-            return _runBuilder(phaseNum, phase, primaryInputs);
-          } else if (phase is PostBuildPhase) {
-            return _runPostProcessPhase(phaseNum, phase);
-          } else {
-            throw StateError('Unrecognized BuildPhase type $phase');
-          }
-        }));
-      }
-      await Future.forEach(
-          _lazyPhases.values,
-          (Future<Iterable<AssetId>> lazyOuts) async =>
-              outputs.addAll(await lazyOuts));
-      // Assume success, `_assetGraph.failedOutputs` will be checked later.
-      return BuildResult(BuildStatus.success, outputs,
-          performance: _performanceTracker);
-    });
-  }
-
-  /// Gets a list of all inputs matching the [phaseNumber], as well as
-  /// its [Builder]s primary inputs.
-  ///
-  /// Lazily builds any optional build actions that might potentially produce
-  /// a primary input to this phase.
-  Future<Set<AssetId>> _matchingPrimaryInputs(
-      String package, int phaseNumber) async {
-    var ids = <AssetId>{};
-    var phase = _buildPhases[phaseNumber];
-    await Future.wait(
-        _assetGraph.outputsForPhase(package, phaseNumber).map((node) async {
-      if (!shouldBuildForDirs(
-          node.id, _buildPaths(_buildDirs), _buildFilters, phase)) {
-        return;
-      }
-
-      var input = _assetGraph.get(node.primaryInput);
-      if (input is GeneratedAssetNode) {
-        if (input.state != NodeState.upToDate) {
-          await _runLazyPhaseForInput(input.phaseNumber, input.primaryInput);
-        }
-        if (!input.wasOutput) return;
-        if (input.isFailure) return;
-      }
-      ids.add(input.id);
-    }));
-    return ids;
-  }
-
-  /// Runs a normal builder with [primaryInputs] as inputs and returns only the
-  /// outputs that were newly created.
-  ///
-  /// Does not return outputs that didn't need to be re-ran or were declared
-  /// but not output.
-  Future<Iterable<AssetId>> _runBuilder(int phaseNumber, InBuildPhase action,
-      Iterable<AssetId> primaryInputs) async {
-    var outputLists = await Future.wait(
-        primaryInputs.map((input) => _runForInput(phaseNumber, action, input)));
-    return outputLists.fold<List<AssetId>>(
-        <AssetId>[], (combined, next) => combined..addAll(next));
-  }
-
-  /// Lazily runs [phaseNumber] with [input]..
-  Future<Iterable<AssetId>> _runLazyPhaseForInput(
-      int phaseNumber, AssetId input) {
-    return _lazyPhases.putIfAbsent('$phaseNumber|$input', () async {
-      // First check if `input` is generated, and whether or not it was
-      // actually output. If it wasn't then we just return an empty list here.
-      var inputNode = _assetGraph.get(input);
-      if (inputNode is GeneratedAssetNode) {
-        // Make sure the `inputNode` is up to date, and rebuild it if not.
-        if (inputNode.state != NodeState.upToDate) {
-          await _runLazyPhaseForInput(
-              inputNode.phaseNumber, inputNode.primaryInput);
-        }
-        if (!inputNode.wasOutput || inputNode.isFailure) return <AssetId>[];
-      }
-
-      // We can never lazily build `PostProcessBuildAction`s.
-      var action = _buildPhases[phaseNumber] as InBuildPhase;
-
-      return _runForInput(phaseNumber, action, input);
-    });
-  }
-
-  /// Checks whether [node] can be read by this step - attempting to build the
-  /// asset if necessary.
-  FutureOr<Readability> _isReadableNode(
-      AssetNode node, int phaseNum, AssetWriterSpy writtenAssets) {
-    if (node is GeneratedAssetNode) {
-      if (node.phaseNumber > phaseNum) {
-        return Readability.notReadable;
-      } else if (node.phaseNumber == phaseNum) {
-        // allow a build step to read its outputs (contained in writtenAssets)
-        final isInBuild = _buildPhases[phaseNum] is InBuildPhase &&
-            writtenAssets.assetsWritten.contains(node.id);
-
-        return isInBuild ? Readability.ownOutput : Readability.notReadable;
-      }
-
-      return doAfter(
-          // ignore: void_checks
-          _ensureAssetIsBuilt(node),
-          (_) =>
-              Readability.fromPreviousPhase(node.wasOutput && !node.isFailure));
-    }
-    return Readability.fromPreviousPhase(node.isReadable && node.isValidInput);
-  }
-
-  FutureOr<void> _ensureAssetIsBuilt(AssetNode node) {
-    if (node is GeneratedAssetNode && node.state != NodeState.upToDate) {
-      return _runLazyPhaseForInput(node.phaseNumber, node.primaryInput);
-    }
-    return null;
-  }
-
-  Future<Iterable<AssetId>> _runForInput(
-      int phaseNumber, InBuildPhase phase, AssetId input) {
-    var pool = _buildPhasePool[phaseNumber] ??= Pool(buildPhasePoolSize);
-    return pool.withResource(() {
-      final builder = phase.builder;
-      var tracker =
-          _performanceTracker.addBuilderAction(input, phase.builderLabel);
-      return tracker.track(() async {
-        var builderOutputs = expectedOutputs(builder, input);
-
-        // Add `builderOutputs` to the primary outputs of the input.
-        var inputNode = _assetGraph.get(input);
-        assert(inputNode != null,
-            'Inputs should be known in the static graph. Missing $input');
-        assert(
-            inputNode.primaryOutputs.containsAll(builderOutputs),
-            'input $input with builder $builder missing primary outputs: \n'
-                    'Got ${inputNode.primaryOutputs.join(', ')} '
-                    'which was missing:\n' +
-                builderOutputs
-                    .where((id) => !inputNode.primaryOutputs.contains(id))
-                    .join(', '));
-
-        var wrappedWriter = AssetWriterSpy(_writer);
-
-        var wrappedReader = SingleStepReader(_reader, _assetGraph, phaseNumber,
-            input.package, _isReadableNode, _getUpdatedGlobNode, wrappedWriter);
-
-        if (!await tracker.trackStage(
-            'Setup', () => _buildShouldRun(builderOutputs, wrappedReader))) {
-          return <AssetId>[];
-        }
-
-        await _cleanUpStaleOutputs(builderOutputs);
-        await FailureReporter.clean(phaseNumber, input);
-
-        // We may have read some inputs in the call to `_buildShouldRun`, we want
-        // to remove those.
-        wrappedReader.assetsRead.clear();
-
-        var actionDescription =
-            _actionLoggerName(phase, input, _packageGraph.root.name);
-        var logger = BuildForInputLogger(Logger(actionDescription));
-
-        actionsStartedCount++;
-        pendingActions
-            .putIfAbsent(phaseNumber, () => <String>{})
-            .add(actionDescription);
-
-        var unusedAssets = <AssetId>{};
-        await tracker.trackStage(
-            'Build',
-            () => runBuilder(
-                  builder,
-                  [input],
-                  wrappedReader,
-                  wrappedWriter,
-                  PerformanceTrackingResolvers(_resolvers, tracker),
-                  logger: logger,
-                  resourceManager: _resourceManager,
-                  stageTracker: tracker,
-                  reportUnusedAssetsForInput: (_, assets) =>
-                      unusedAssets.addAll(assets),
-                ).catchError((void _) {
-                  // Errors tracked through the logger
-                }));
-        actionsCompletedCount++;
-        hungActionsHeartbeat.ping();
-        pendingActions[phaseNumber].remove(actionDescription);
-
-        // Reset the state for all the `builderOutputs` nodes based on what was
-        // read and written.
-        await tracker.trackStage(
-            'Finalize',
-            () => _setOutputsState(
-                  builderOutputs,
-                  wrappedReader,
-                  wrappedWriter,
-                  actionDescription,
-                  logger.errorsSeen,
-                  unusedAssets: unusedAssets,
-                ));
-
-        return wrappedWriter.assetsWritten;
-      });
-    });
-  }
-
-  Future<Iterable<AssetId>> _runPostProcessPhase(
-      int phaseNum, PostBuildPhase phase) async {
-    var actionNum = 0;
-    var outputLists = await Future.wait(phase.builderActions
-        .map((action) => _runPostProcessAction(phaseNum, actionNum++, action)));
-    return outputLists.fold<List<AssetId>>(
-        <AssetId>[], (combined, next) => combined..addAll(next));
-  }
-
-  Future<Iterable<AssetId>> _runPostProcessAction(
-      int phaseNum, int actionNum, PostBuildAction action) async {
-    var anchorNodes = _assetGraph.packageNodes(action.package).where((node) {
-      if (node is PostProcessAnchorNode && node.actionNumber == actionNum) {
-        var inputNode = _assetGraph.get(node.primaryInput);
-        if (inputNode is SourceAssetNode) {
-          return true;
-        } else if (inputNode is GeneratedAssetNode) {
-          return inputNode.wasOutput &&
-              !inputNode.isFailure &&
-              inputNode.state == NodeState.upToDate;
-        }
-      }
-      return false;
-    }).cast<PostProcessAnchorNode>();
-    var outputLists = await Future.wait(anchorNodes.map((anchorNode) =>
-        _runPostProcessBuilderForAnchor(
-            phaseNum, actionNum, action.builder, anchorNode)));
-    return outputLists.fold<List<AssetId>>(
-        <AssetId>[], (combined, next) => combined..addAll(next));
-  }
-
-  Future<Iterable<AssetId>> _runPostProcessBuilderForAnchor(
-      int phaseNum,
-      int actionNum,
-      PostProcessBuilder builder,
-      PostProcessAnchorNode anchorNode) async {
-    var input = anchorNode.primaryInput;
-    var inputNode = _assetGraph.get(input);
-    assert(inputNode != null,
-        'Inputs should be known in the static graph. Missing $input');
-
-    var wrappedWriter = AssetWriterSpy(_writer);
-    var wrappedReader = SingleStepReader(_reader, _assetGraph, phaseNum,
-        input.package, _isReadableNode, null, wrappedWriter);
-
-    if (!await _postProcessBuildShouldRun(anchorNode, wrappedReader)) {
-      return <AssetId>[];
-    }
-    // We may have read some inputs in the call to `_buildShouldRun`, we want
-    // to remove those.
-    wrappedReader.assetsRead.clear();
-
-    // Clean out the impacts of the previous run
-    await FailureReporter.clean(phaseNum, input);
-    await _cleanUpStaleOutputs(anchorNode.outputs);
-    anchorNode.outputs
-      ..toList().forEach(_assetGraph.remove)
-      ..clear();
-    inputNode.deletedBy.remove(anchorNode.id);
-
-    var actionDescription = '$builder on $input';
-    var logger = BuildForInputLogger(Logger(actionDescription));
-
-    actionsStartedCount++;
-    pendingActions
-        .putIfAbsent(phaseNum, () => <String>{})
-        .add(actionDescription);
-
-    await runPostProcessBuilder(
-        builder, input, wrappedReader, wrappedWriter, logger,
-        addAsset: (assetId) {
-      if (_assetGraph.contains(assetId)) {
-        throw InvalidOutputException(assetId, 'Asset already exists');
-      }
-      var node = GeneratedAssetNode(assetId,
-          primaryInput: input,
-          builderOptionsId: anchorNode.builderOptionsId,
-          isHidden: true,
-          phaseNumber: phaseNum,
-          wasOutput: true,
-          isFailure: false,
-          state: NodeState.upToDate);
-      _assetGraph.add(node);
-      anchorNode.outputs.add(assetId);
-    }, deleteAsset: (assetId) {
-      if (!_assetGraph.contains(assetId)) {
-        throw AssetNotFoundException(assetId);
-      }
-      if (assetId != input) {
-        throw InvalidOutputException(assetId, 'Can only delete primary input');
-      }
-      _assetGraph.get(assetId).deletedBy.add(anchorNode.id);
-    }).catchError((void _) {
-      // Errors tracked through the logger
-    });
-    actionsCompletedCount++;
-    hungActionsHeartbeat.ping();
-    pendingActions[phaseNum].remove(actionDescription);
-
-    var assetsWritten = wrappedWriter.assetsWritten.toSet();
-
-    // Reset the state for all the output nodes based on what was read and
-    // written.
-    inputNode.primaryOutputs.addAll(assetsWritten);
-    await _setOutputsState(assetsWritten, wrappedReader, wrappedWriter,
-        actionDescription, logger.errorsSeen);
-
-    return assetsWritten;
-  }
-
-  /// Checks and returns whether any [outputs] need to be updated.
-  Future<bool> _buildShouldRun(
-      Iterable<AssetId> outputs, AssetReader reader) async {
-    assert(
-        outputs.every(_assetGraph.contains),
-        'Outputs should be known statically. Missing '
-        '${outputs.where((o) => !_assetGraph.contains(o)).toList()}');
-    assert(outputs.isNotEmpty, 'Can\'t run a build with no outputs');
-
-    // We only check the first output, because all outputs share the same inputs
-    // and invalidation state.
-    var firstOutput = outputs.first;
-    var node = _assetGraph.get(firstOutput) as GeneratedAssetNode;
-    assert(
-        outputs.skip(1).every((output) =>
-            (_assetGraph.get(output) as GeneratedAssetNode)
-                .inputs
-                .difference(node.inputs)
-                .isEmpty),
-        'All outputs of a build action should share the same inputs.');
-
-    // No need to build an up to date output
-    if (node.state == NodeState.upToDate) return false;
-    // Early bail out condition, this is a forced update.
-    if (node.state == NodeState.definitelyNeedsUpdate) return true;
-    // This is a fresh build or the first time we've seen this output.
-    if (node.previousInputsDigest == null) return true;
-
-    var digest = await _computeCombinedDigest(
-        node.inputs, node.builderOptionsId, reader);
-    if (digest != node.previousInputsDigest) {
-      return true;
-    } else {
-      // Make sure to update the `state` field for all outputs.
-      for (var id in outputs) {
-        (_assetGraph.get(id) as NodeWithInputs).state = NodeState.upToDate;
-      }
-      return false;
-    }
-  }
-
-  /// Checks if a post process build should run based on [anchorNode].
-  Future<bool> _postProcessBuildShouldRun(
-      PostProcessAnchorNode anchorNode, AssetReader reader) async {
-    var inputsDigest = await _computeCombinedDigest(
-        [anchorNode.primaryInput], anchorNode.builderOptionsId, reader);
-
-    if (inputsDigest != anchorNode.previousInputsDigest) {
-      anchorNode.previousInputsDigest = inputsDigest;
-      return true;
-    }
-
-    return false;
-  }
-
-  /// Deletes any of [outputs] which previously were output.
-  ///
-  /// This should be called after deciding that an asset really needs to be
-  /// regenerated based on its inputs hash changing. All assets in [outputs]
-  /// must correspond to a [GeneratedAssetNode].
-  Future<void> _cleanUpStaleOutputs(Iterable<AssetId> outputs) =>
-      Future.wait(outputs
-          .map(_assetGraph.get)
-          .cast<GeneratedAssetNode>()
-          .where((n) => n.wasOutput)
-          .map((n) => _delete(n.id)));
-
-  Future<GlobAssetNode> _getUpdatedGlobNode(
-      Glob glob, String package, int phaseNum) {
-    var globNodeId = GlobAssetNode.createId(package, glob, phaseNum);
-    var globNode = _assetGraph.get(globNodeId) as GlobAssetNode;
-    if (globNode == null) {
-      globNode = GlobAssetNode(
-          globNodeId, glob, phaseNum, NodeState.definitelyNeedsUpdate);
-      _assetGraph.add(globNode);
-    }
-
-    return toFuture(doAfter(
-        // ignore: void_checks
-        _updateGlobNodeIfNecessary(globNode),
-        (_) => globNode));
-  }
-
-  FutureOr<void> _updateGlobNodeIfNecessary(GlobAssetNode globNode) {
-    if (globNode.state == NodeState.upToDate) return null;
-
-    return _lazyGlobs.putIfAbsent(globNode.id, () async {
-      var potentialNodes = _assetGraph
-          .packageNodes(globNode.id.package)
-          .where((n) => n.isReadable && n.isValidInput)
-          .where((n) =>
-              n is! GeneratedAssetNode ||
-              (n as GeneratedAssetNode).phaseNumber < globNode.phaseNumber)
-          .where((n) => globNode.glob.matches(n.id.path))
-          .toList();
-
-      await Future.wait(potentialNodes
-          .whereType<GeneratedAssetNode>()
-          .map(_ensureAssetIsBuilt)
-          .map(toFuture));
-
-      var actualMatches = <AssetId>[];
-      for (var node in potentialNodes) {
-        node.outputs.add(globNode.id);
-        if (node is GeneratedAssetNode && (!node.wasOutput || node.isFailure)) {
-          continue;
-        }
-        actualMatches.add(node.id);
-      }
-
-      globNode
-        ..results = actualMatches
-        ..inputs = HashSet.of(potentialNodes.map((n) => n.id))
-        ..state = NodeState.upToDate
-        ..lastKnownDigest =
-            md5.convert(utf8.encode(globNode.results.join(' ')));
-
-      unawaited(_lazyGlobs.remove(globNode.id));
-    });
-  }
-
-  /// Computes a single [Digest] based on the combined [Digest]s of [ids] and
-  /// [builderOptionsId].
-  Future<Digest> _computeCombinedDigest(Iterable<AssetId> ids,
-      AssetId builderOptionsId, AssetReader reader) async {
-    var combinedBytes = Uint8List.fromList(List.filled(16, 0));
-    void _combine(Uint8List other) {
-      assert(other.length == 16);
-      assert(other is Uint8List);
-      for (var i = 0; i < 16; i++) {
-        combinedBytes[i] ^= other[i];
-      }
-    }
-
-    var builderOptionsNode = _assetGraph.get(builderOptionsId);
-    _combine(builderOptionsNode.lastKnownDigest.bytes as Uint8List);
-
-    // Limit the total number of digests we are computing at a time. Otherwise
-    // this can overload the event queue.
-    await Future.wait(ids.map((id) async {
-      var node = _assetGraph.get(id);
-      if (node is GlobAssetNode) {
-        await _updateGlobNodeIfNecessary(node);
-      } else if (!await reader.canRead(id)) {
-        // We want to add something here, a missing/unreadable input should be
-        // different from no input at all.
-        //
-        // This needs to be unique per input so we use the md5 hash of the id.
-        _combine(md5.convert(id.toString().codeUnits).bytes as Uint8List);
-        return;
-      } else {
-        node.lastKnownDigest ??= await reader.digest(id);
-      }
-      _combine(node.lastKnownDigest.bytes as Uint8List);
-    }));
-
-    return Digest(combinedBytes);
-  }
-
-  /// Sets the state for all [outputs] of a build step, by:
-  ///
-  /// - Setting `needsUpdate` to `false` for each output
-  /// - Setting `wasOutput` based on `writer.assetsWritten`.
-  /// - Setting `isFailed` based on action success.
-  /// - Adding `outputs` as outputs to all `reader.assetsRead`.
-  /// - Setting the `lastKnownDigest` on each output based on the new contents.
-  /// - Setting the `previousInputsDigest` on each output based on the inputs.
-  /// - Storing the error message with the [_failureReporter].
-  Future<void> _setOutputsState(
-      Iterable<AssetId> outputs,
-      SingleStepReader reader,
-      AssetWriterSpy writer,
-      String actionDescription,
-      Iterable<ErrorReport> errors,
-      {Set<AssetId> unusedAssets}) async {
-    if (outputs.isEmpty) return;
-    var usedInputs = unusedAssets != null
-        ? reader.assetsRead.difference(unusedAssets)
-        : reader.assetsRead;
-
-    final inputsDigest = await _computeCombinedDigest(
-        usedInputs,
-        (_assetGraph.get(outputs.first) as GeneratedAssetNode).builderOptionsId,
-        reader);
-
-    final isFailure = errors.isNotEmpty;
-
-    for (var output in outputs) {
-      var wasOutput = writer.assetsWritten.contains(output);
-      var digest = wasOutput ? await _reader.digest(output) : null;
-      var node = _assetGraph.get(output) as GeneratedAssetNode;
-
-      // **IMPORTANT**: All updates to `node` must be synchronous. With lazy
-      // builders we can run arbitrary code between updates otherwise, at which
-      // time a node might not be in a valid state.
-      _removeOldInputs(node, usedInputs);
-      _addNewInputs(node, usedInputs);
-      node
-        ..state = NodeState.upToDate
-        ..wasOutput = wasOutput
-        ..isFailure = isFailure
-        ..lastKnownDigest = digest
-        ..previousInputsDigest = inputsDigest;
-
-      if (isFailure) {
-        await _failureReporter.markReported(actionDescription, node, errors);
-        var needsMarkAsFailure = Queue.of(node.primaryOutputs);
-        var allSkippedFailures = <GeneratedAssetNode>[];
-        while (needsMarkAsFailure.isNotEmpty) {
-          var output = needsMarkAsFailure.removeLast();
-          var outputNode = _assetGraph.get(output) as GeneratedAssetNode
-            ..state = NodeState.upToDate
-            ..wasOutput = false
-            ..isFailure = true
-            ..lastKnownDigest = null
-            ..previousInputsDigest = null;
-          allSkippedFailures.add(outputNode);
-          needsMarkAsFailure.addAll(outputNode.primaryOutputs);
-
-          // Make sure output invalidation follows primary outputs for builds
-          // that won't run.
-          node.outputs.add(output);
-          outputNode.inputs.add(node.id);
-        }
-        await _failureReporter.markSkipped(allSkippedFailures);
-      }
-    }
-  }
-
-  /// Removes old inputs from [node] based on [updatedInputs], and cleans up all
-  /// the old edges.
-  void _removeOldInputs(GeneratedAssetNode node, Set<AssetId> updatedInputs) {
-    var removedInputs = node.inputs.difference(updatedInputs);
-    node.inputs.removeAll(removedInputs);
-    for (var input in removedInputs) {
-      var inputNode = _assetGraph.get(input);
-      assert(inputNode != null, 'Asset Graph is missing $input');
-      inputNode.outputs.remove(node.id);
-    }
-  }
-
-  /// Adds new inputs to [node] based on [updatedInputs], and adds the
-  /// appropriate edges.
-  void _addNewInputs(GeneratedAssetNode node, Set<AssetId> updatedInputs) {
-    var newInputs = updatedInputs.difference(node.inputs);
-    node.inputs.addAll(newInputs);
-    for (var input in newInputs) {
-      var inputNode = _assetGraph.get(input);
-      assert(inputNode != null, 'Asset Graph is missing $input');
-      inputNode.outputs.add(node.id);
-    }
-  }
-
-  Future _delete(AssetId id) => _writer.delete(id);
-}
-
-String _actionLoggerName(
-    InBuildPhase phase, AssetId primaryInput, String rootPackageName) {
-  var asset = primaryInput.package == rootPackageName
-      ? primaryInput.path
-      : primaryInput.uri;
-  return '${phase.builderLabel} on $asset';
-}
-
-String _twoDigits(int n) => '$n'.padLeft(2, '0');
diff --git a/build_runner_core/lib/src/generate/build_result.dart b/build_runner_core/lib/src/generate/build_result.dart
deleted file mode 100644
index d96e52f..0000000
--- a/build_runner_core/lib/src/generate/build_result.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.
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:meta/meta.dart';
-
-import 'performance_tracker.dart';
-
-/// The result of an individual build, this may be an incremental build or
-/// a full build.
-class BuildResult {
-  /// The status of this build.
-  final BuildStatus status;
-
-  /// The type of failure.
-  final FailureType failureType;
-
-  /// All outputs created/updated during this build.
-  final List<AssetId> outputs;
-
-  /// The [BuildPerformance] broken out by build action, may be `null`.
-  @experimental
-  final BuildPerformance performance;
-
-  BuildResult(this.status, List<AssetId> outputs,
-      {this.performance, FailureType failureType})
-      : outputs = List.unmodifiable(outputs),
-        failureType = failureType == null && status == BuildStatus.failure
-            ? FailureType.general
-            : failureType;
-  @override
-  String toString() {
-    if (status == BuildStatus.success) {
-      return '''
-
-Build Succeeded!
-''';
-    } else {
-      return '''
-
-Build Failed :(
-''';
-    }
-  }
-}
-
-/// The status of a build.
-enum BuildStatus {
-  success,
-  failure,
-}
-
-/// The type of failure
-class FailureType {
-  static final general = FailureType._(1);
-  static final cantCreate = FailureType._(73);
-  static final buildConfigChanged = FailureType._(75);
-  static final buildScriptChanged = FailureType._(75);
-  final int exitCode;
-  FailureType._(this.exitCode);
-}
-
-abstract class BuildState {
-  Future<BuildResult> get currentBuild;
-  Stream<BuildResult> get buildResults;
-}
diff --git a/build_runner_core/lib/src/generate/build_runner.dart b/build_runner_core/lib/src/generate/build_runner.dart
deleted file mode 100644
index b19e265..0000000
--- a/build_runner_core/lib/src/generate/build_runner.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:watcher/watcher.dart';
-
-import '../environment/build_environment.dart';
-import '../package_graph/apply_builders.dart';
-import 'build_directory.dart';
-import 'build_impl.dart';
-import 'build_result.dart';
-import 'options.dart';
-
-class BuildRunner {
-  final BuildImpl _build;
-  BuildRunner._(this._build);
-
-  Future<void> beforeExit() => _build.beforeExit();
-
-  Future<BuildResult> run(Map<AssetId, ChangeType> updates,
-          {Set<BuildDirectory> buildDirs, Set<BuildFilter> buildFilters}) =>
-      _build.run(updates, buildDirs: buildDirs, buildFilters: buildFilters);
-
-  static Future<BuildRunner> create(
-      BuildOptions options,
-      BuildEnvironment environment,
-      List<BuilderApplication> builders,
-      Map<String, Map<String, dynamic>> builderConfigOverrides,
-      {bool isReleaseBuild = false}) async {
-    return BuildRunner._(await BuildImpl.create(
-        options, environment, builders, builderConfigOverrides,
-        isReleaseBuild: isReleaseBuild));
-  }
-}
diff --git a/build_runner_core/lib/src/generate/exceptions.dart b/build_runner_core/lib/src/generate/exceptions.dart
deleted file mode 100644
index 659d8ae..0000000
--- a/build_runner_core/lib/src/generate/exceptions.dart
+++ /dev/null
@@ -1,28 +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.
-
-/// Indicates that a build config file has changed, and the build needs to be
-/// re-ran.
-///
-/// An exit code of 75 should be set when handling this exception.
-class BuildConfigChangedException implements Exception {
-  const BuildConfigChangedException();
-}
-
-/// Indicates that the build script itself has changed, and needs to be re-ran.
-///
-/// If the build is running from a snapshot, the snapshot should also be
-/// deleted before exiting.
-///
-/// An exit code of 75 should be set when handling this exception.
-class BuildScriptChangedException implements Exception {
-  const BuildScriptChangedException();
-}
-
-/// Indicates that the build cannot be attempted.
-///
-/// Before throwing this exception a user actionable message should be logged.
-class CannotBuildException implements Exception {
-  const CannotBuildException();
-}
diff --git a/build_runner_core/lib/src/generate/finalized_assets_view.dart b/build_runner_core/lib/src/generate/finalized_assets_view.dart
deleted file mode 100644
index 9f74ae3..0000000
--- a/build_runner_core/lib/src/generate/finalized_assets_view.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../asset_graph/optional_output_tracker.dart';
-
-/// A lazily computed view of all the assets available after a build.
-///
-/// Note that this class has a limited lifetime during which it is available,
-/// and should not be used outside of the scope in which it is given. It will
-/// throw a [StateError] if you attempt to use it once it has expired.
-class FinalizedAssetsView {
-  final AssetGraph _assetGraph;
-  final OptionalOutputTracker _optionalOutputTracker;
-
-  bool _expired = false;
-
-  FinalizedAssetsView(this._assetGraph, this._optionalOutputTracker);
-
-  List<AssetId> allAssets({String rootDir}) {
-    if (_expired) {
-      throw StateError(
-          'Cannot use a FinalizedAssetsView after it has expired!');
-    }
-    return _assetGraph.allNodes
-        .map((node) {
-          if (_shouldSkipNode(node, rootDir, _optionalOutputTracker)) {
-            return null;
-          }
-          return node.id;
-        })
-        .where((id) => id != null)
-        .toList();
-  }
-
-  void markExpired() {
-    assert(!_expired);
-    _expired = true;
-  }
-}
-
-bool _shouldSkipNode(AssetNode node, String rootDir,
-    OptionalOutputTracker optionalOutputTracker) {
-  if (!node.isReadable) return true;
-  if (node.isDeleted) return true;
-  if (rootDir != null &&
-      !node.id.path.startsWith('lib/') &&
-      !p.isWithin(rootDir, node.id.path)) {
-    return true;
-  }
-  if (node is InternalAssetNode) return true;
-  if (node is GeneratedAssetNode) {
-    if (!node.wasOutput || node.isFailure || node.state != NodeState.upToDate) {
-      return true;
-    }
-    return !optionalOutputTracker.isRequired(node.id);
-  }
-  if (node.id.path == '.packages') return true;
-  return false;
-}
diff --git a/build_runner_core/lib/src/generate/heartbeat.dart b/build_runner_core/lib/src/generate/heartbeat.dart
deleted file mode 100644
index 2917f54..0000000
--- a/build_runner_core/lib/src/generate/heartbeat.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:logging/logging.dart';
-
-import '../logging/human_readable_duration.dart';
-
-var _logger = Logger('Heartbeat');
-
-/// Base class for a heartbeat implementation.
-///
-/// Once [start]ed, if [waitDuration] passes between calls to [ping], then
-/// [onTimeout] will be invoked with the duration.
-abstract class Heartbeat {
-  Stopwatch _intervalWatch;
-  Timer _timer;
-
-  /// The interval at which to check if [waitDuration] has passed.
-  final Duration checkInterval;
-
-  /// The amount of time between heartbeats.
-  final Duration waitDuration;
-
-  Heartbeat({Duration checkInterval, Duration waitDuration})
-      : checkInterval = checkInterval ?? const Duration(milliseconds: 100),
-        waitDuration = waitDuration ?? const Duration(seconds: 5);
-
-  /// Invoked if [waitDuration] time has elapsed since the last call to [ping].
-  void onTimeout(Duration elapsed);
-
-  /// Resets the internal timers. If more than [waitDuration] elapses without
-  /// this method being called, then [onTimeout] will be invoked with the
-  /// duration since the last ping.
-  void ping() {
-    _intervalWatch.reset();
-  }
-
-  /// Starts this heartbeat logger, must not already be started.
-  ///
-  /// This method can be overridden to add additional logic for handling calls
-  /// to [ping], but you must call `super.start()`.
-  void start() {
-    if (_intervalWatch != null || _timer != null) {
-      throw StateError('HeartbeatLogger already started');
-    }
-    _intervalWatch = Stopwatch()..start();
-    ping();
-    _timer = Timer.periodic(checkInterval, _checkDuration);
-  }
-
-  /// Stops this heartbeat logger, must already be started.
-  ///
-  /// This method can be overridden to add additional logic for cleanup
-  /// purposes, but you must call `super.stop()`.
-  void stop() {
-    if (_intervalWatch == null || _timer == null) {
-      throw StateError('HeartbeatLogger was never started');
-    }
-    _intervalWatch.stop();
-    _intervalWatch = null;
-    _timer.cancel();
-    _timer = null;
-  }
-
-  void _checkDuration(void _) {
-    if (_intervalWatch.elapsed < waitDuration) return;
-    onTimeout(_intervalWatch.elapsed);
-    ping();
-  }
-}
-
-/// Watches [Logger.root] and if there are no logs for [waitDuration] then it
-/// will log a heartbeat message with the current elapsed time since [start] was
-/// originally invoked.
-class HeartbeatLogger extends Heartbeat {
-  StreamSubscription<LogRecord> _listener;
-  Stopwatch _totalWatch;
-
-  /// Will be invoked with each original log message and the returned value will
-  /// be logged instead.
-  final String Function(String original) transformLog;
-
-  HeartbeatLogger(
-      {Duration checkInterval, Duration waitDuration, this.transformLog})
-      : super(checkInterval: checkInterval, waitDuration: waitDuration);
-
-  /// Start listening to logs.
-  @override
-  void start() {
-    _totalWatch = Stopwatch()..start();
-    super.start();
-    _listener = Logger.root.onRecord.listen((_) => ping());
-  }
-
-  /// Stops listenting to the logger;
-  @override
-  void stop() {
-    super.stop();
-    _listener.cancel();
-    _listener = null;
-    _totalWatch.stop();
-    _totalWatch = null;
-  }
-
-  /// Logs a heartbeat message if we reach the timeout.
-  @override
-  void onTimeout(void _) {
-    var formattedTime = humanReadable(_totalWatch.elapsed);
-    var message = '$formattedTime elapsed';
-    if (transformLog != null) {
-      message = transformLog(message);
-    }
-    _logger.info(message);
-  }
-}
-
-class HungActionsHeartbeat extends Heartbeat {
-  /// Returns a description of pending actions
-  final String Function() listActions;
-
-  HungActionsHeartbeat(this.listActions,
-      {Duration checkInterval, Duration waitDuration})
-      : super(
-            checkInterval: checkInterval,
-            waitDuration: waitDuration ?? Duration(seconds: 15));
-
-  @override
-  void onTimeout(Duration elapsed) {
-    var formattedTime = humanReadable(elapsed);
-    var message = 'No actions completed for $formattedTime, '
-        'waiting on:\n${listActions()}';
-    _logger.warning(message);
-  }
-}
diff --git a/build_runner_core/lib/src/generate/input_matcher.dart b/build_runner_core/lib/src/generate/input_matcher.dart
deleted file mode 100644
index dc644aa..0000000
--- a/build_runner_core/lib/src/generate/input_matcher.dart
+++ /dev/null
@@ -1,77 +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 'package:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:collection/collection.dart';
-import 'package:glob/glob.dart';
-
-/// A filter on files to run through a Builder.
-class InputMatcher {
-  /// The files to include
-  ///
-  /// Null or empty means include everything.
-  final List<Glob> includeGlobs;
-
-  /// The files within [includeGlobs] to exclude.
-  ///
-  /// Null or empty means exclude nothing.
-  final List<Glob> excludeGlobs;
-
-  InputMatcher(InputSet inputSet, {List<String> defaultInclude})
-      : includeGlobs =
-            (inputSet.include ?? defaultInclude)?.map((p) => Glob(p))?.toList(),
-        excludeGlobs = inputSet.exclude?.map((p) => Glob(p))?.toList();
-
-  /// Whether [input] is included in this set of assets.
-  bool matches(AssetId input) => includes(input) && !excludes(input);
-
-  /// Whether [input] matches any [includeGlobs].
-  ///
-  /// If there are no [includeGlobs] this always returns `true`.
-  bool includes(AssetId input) =>
-      includeGlobs == null ||
-      includeGlobs.isEmpty ||
-      includeGlobs.any((g) => g.matches(input.path));
-
-  /// Whether [input] matches any [excludeGlobs].
-  ///
-  /// If there are no [excludeGlobs] this always returns `false`.
-  bool excludes(AssetId input) =>
-      excludeGlobs != null &&
-      excludeGlobs.isNotEmpty &&
-      excludeGlobs.any((g) => g.matches(input.path));
-
-  @override
-  String toString() {
-    final result = StringBuffer();
-    if (includeGlobs == null || includeGlobs.isEmpty) {
-      result.write('any assets');
-    } else {
-      result.write('assets matching ${_patterns(includeGlobs).toList()}');
-    }
-    if (excludeGlobs != null && excludeGlobs.isNotEmpty) {
-      result.write(' except ${_patterns(excludeGlobs).toList()}');
-    }
-    return '$result';
-  }
-
-  @override
-  bool operator ==(Object other) =>
-      identical(this, other) ||
-      (other is InputMatcher &&
-          _deepEquals.equals(
-              _patterns(includeGlobs), _patterns(other.includeGlobs)) &&
-          _deepEquals.equals(
-              _patterns(excludeGlobs), _patterns(other.excludeGlobs)));
-
-  @override
-  int get hashCode =>
-      _deepEquals.hash([_patterns(includeGlobs), _patterns(excludeGlobs)]);
-}
-
-final _deepEquals = const DeepCollectionEquality();
-
-Iterable<String> _patterns(Iterable<Glob> globs) =>
-    globs?.map((g) => g.pattern);
diff --git a/build_runner_core/lib/src/generate/options.dart b/build_runner_core/lib/src/generate/options.dart
deleted file mode 100644
index eb2681e..0000000
--- a/build_runner_core/lib/src/generate/options.dart
+++ /dev/null
@@ -1,207 +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:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:build_resolvers/build_resolvers.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-
-import '../environment/build_environment.dart';
-import '../package_graph/package_graph.dart';
-import '../package_graph/target_graph.dart';
-import '../util/hash.dart';
-import 'exceptions.dart';
-
-/// The default list of files to include when an explicit include is not
-/// provided.
-const List<String> defaultRootPackageWhitelist = [
-  'assets/**',
-  'benchmark/**',
-  'bin/**',
-  'example/**',
-  'lib/**',
-  'test/**',
-  'tool/**',
-  'web/**',
-  'node/**',
-  'pubspec.yaml',
-  'pubspec.lock',
-  r'$package$',
-];
-
-final _logger = Logger('BuildOptions');
-
-class LogSubscription {
-  factory LogSubscription(BuildEnvironment environment,
-      {bool verbose, Level logLevel}) {
-    // Set up logging
-    verbose ??= false;
-    logLevel ??= verbose ? Level.ALL : Level.INFO;
-
-    // Severe logs can fail the build and should always be shown.
-    if (logLevel == Level.OFF) logLevel = Level.SEVERE;
-
-    Logger.root.level = logLevel;
-
-    var logListener = Logger.root.onRecord.listen(environment.onLog);
-    return LogSubscription._(logListener);
-  }
-
-  LogSubscription._(this.logListener);
-
-  final StreamSubscription<LogRecord> logListener;
-}
-
-/// Describes a set of files that should be built.
-class BuildFilter {
-  /// The package name glob that files must live under in order to match.
-  final Glob _package;
-
-  /// A glob for files under [_package] that must match.
-  final Glob _path;
-
-  BuildFilter(this._package, this._path);
-
-  /// Builds a [BuildFilter] from a command line argument.
-  ///
-  /// Both relative paths and package: uris are supported. Relative
-  /// paths are treated as relative to the [rootPackage].
-  ///
-  /// Globs are supported in package names and paths.
-  factory BuildFilter.fromArg(String arg, String rootPackage) {
-    var uri = Uri.parse(arg);
-    if (uri.scheme == 'package') {
-      var package = uri.pathSegments.first;
-      var glob = Glob(p.url.joinAll([
-        'lib',
-        ...uri.pathSegments.skip(1),
-      ]));
-      return BuildFilter(Glob(package), glob);
-    } else if (uri.scheme.isEmpty) {
-      return BuildFilter(Glob(rootPackage), Glob(uri.path));
-    } else {
-      throw FormatException('Unsupported scheme ${uri.scheme}', uri);
-    }
-  }
-
-  /// Returns whether or not [id] mathes this filter.
-  bool matches(AssetId id) =>
-      _package.matches(id.package) && _path.matches(id.path);
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = hashCombine(hash, _package.context.hashCode);
-    hash = hashCombine(hash, _package.pattern.hashCode);
-    hash = hashCombine(hash, _package.recursive.hashCode);
-    hash = hashCombine(hash, _path.context.hashCode);
-    hash = hashCombine(hash, _path.pattern.hashCode);
-    hash = hashCombine(hash, _path.recursive.hashCode);
-    return hashComplete(hash);
-  }
-
-  @override
-  bool operator ==(Object other) =>
-      other is BuildFilter &&
-      other._path.context == _path.context &&
-      other._path.pattern == _path.pattern &&
-      other._path.recursive == _path.recursive &&
-      other._package.context == _package.context &&
-      other._package.pattern == _package.pattern &&
-      other._package.recursive == _package.recursive;
-}
-
-/// Manages setting up consistent defaults for all options and build modes.
-class BuildOptions {
-  final bool deleteFilesByDefault;
-  final bool enableLowResourcesMode;
-  final StreamSubscription logListener;
-
-  /// If present, the path to a directory to write performance logs to.
-  final String logPerformanceDir;
-
-  final PackageGraph packageGraph;
-  final Resolvers resolvers;
-  final TargetGraph targetGraph;
-  final bool trackPerformance;
-
-  // Watch mode options.
-  Duration debounceDelay;
-
-  // For testing only, skips the build script updates check.
-  bool skipBuildScriptCheck;
-
-  BuildOptions._({
-    @required this.debounceDelay,
-    @required this.deleteFilesByDefault,
-    @required this.enableLowResourcesMode,
-    @required this.logListener,
-    @required this.packageGraph,
-    @required this.skipBuildScriptCheck,
-    @required this.trackPerformance,
-    @required this.targetGraph,
-    @required this.logPerformanceDir,
-    @required this.resolvers,
-  });
-
-  static Future<BuildOptions> create(
-    LogSubscription logSubscription, {
-    Duration debounceDelay,
-    bool deleteFilesByDefault,
-    bool enableLowResourcesMode,
-    @required PackageGraph packageGraph,
-    Map<String, BuildConfig> overrideBuildConfig,
-    bool skipBuildScriptCheck,
-    bool trackPerformance,
-    String logPerformanceDir,
-    Resolvers resolvers,
-  }) async {
-    TargetGraph targetGraph;
-    try {
-      targetGraph = await TargetGraph.forPackageGraph(packageGraph,
-          overrideBuildConfig: overrideBuildConfig,
-          defaultRootPackageWhitelist: defaultRootPackageWhitelist);
-    } on BuildConfigParseException catch (e, s) {
-      _logger.severe(
-          'Failed to parse `build.yaml` for ${e.packageName}.', e.exception, s);
-      throw CannotBuildException();
-    }
-
-    /// Set up other defaults.
-    debounceDelay ??= const Duration(milliseconds: 250);
-    deleteFilesByDefault ??= false;
-    skipBuildScriptCheck ??= false;
-    enableLowResourcesMode ??= false;
-    trackPerformance ??= false;
-    if (logPerformanceDir != null) {
-      // Requiring this to be under the root package allows us to use an
-      // `AssetWriter` to write logs.
-      if (!p.isWithin(p.current, logPerformanceDir)) {
-        _logger.severe('Performance logs may only be output under the root '
-            'package, but got `$logPerformanceDir` which is not.');
-        throw CannotBuildException();
-      }
-      trackPerformance = true;
-    }
-    resolvers ??= AnalyzerResolvers();
-
-    return BuildOptions._(
-      debounceDelay: debounceDelay,
-      deleteFilesByDefault: deleteFilesByDefault,
-      enableLowResourcesMode: enableLowResourcesMode,
-      logListener: logSubscription.logListener,
-      packageGraph: packageGraph,
-      skipBuildScriptCheck: skipBuildScriptCheck,
-      trackPerformance: trackPerformance,
-      targetGraph: targetGraph,
-      logPerformanceDir: logPerformanceDir,
-      resolvers: resolvers,
-    );
-  }
-}
diff --git a/build_runner_core/lib/src/generate/performance_tracker.dart b/build_runner_core/lib/src/generate/performance_tracker.dart
deleted file mode 100644
index beb598a..0000000
--- a/build_runner_core/lib/src/generate/performance_tracker.dart
+++ /dev/null
@@ -1,341 +0,0 @@
-// 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.
-
-@experimental
-library build_runner.src.generate.performance_tracker;
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:json_annotation/json_annotation.dart';
-import 'package:meta/meta.dart';
-import 'package:timing/timing.dart';
-
-import 'phase.dart';
-
-part 'performance_tracker.g.dart';
-
-/// The [TimeSlice] of an entire build, including all its [actions].
-@JsonSerializable()
-class BuildPerformance extends TimeSlice {
-  /// The [TimeSlice] of each phase ran in this build.
-  final Iterable<BuildPhasePerformance> phases;
-
-  /// The [TimeSlice] of running an individual [Builder] on an individual input.
-  final Iterable<BuilderActionPerformance> actions;
-
-  BuildPerformance(
-      this.phases, this.actions, DateTime startTime, DateTime stopTime)
-      : super(startTime, stopTime);
-
-  factory BuildPerformance.fromJson(Map<String, dynamic> json) =>
-      _$BuildPerformanceFromJson(json);
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildPerformanceToJson(this);
-}
-
-/// The [TimeSlice] of a full [BuildPhase] within a larger build.
-@JsonSerializable()
-class BuildPhasePerformance extends TimeSlice {
-  final List<String> builderKeys;
-
-  BuildPhasePerformance(this.builderKeys, DateTime startTime, DateTime stopTime)
-      : super(startTime, stopTime);
-
-  factory BuildPhasePerformance.fromJson(Map<String, dynamic> json) =>
-      _$BuildPhasePerformanceFromJson(json);
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildPhasePerformanceToJson(this);
-}
-
-/// The [TimeSlice] of a [builderKey] running on [primaryInput] within a build.
-@JsonSerializable()
-class BuilderActionPerformance extends TimeSlice {
-  final String builderKey;
-
-  @JsonKey(fromJson: _assetIdFromJson, toJson: _assetIdToJson)
-  final AssetId primaryInput;
-
-  final Iterable<BuilderActionStagePerformance> stages;
-
-  Duration get innerDuration => stages.fold(
-      Duration.zero, (duration, stage) => duration + stage.innerDuration);
-
-  BuilderActionPerformance(this.builderKey, this.primaryInput, this.stages,
-      DateTime startTime, DateTime stopTime)
-      : super(startTime, stopTime);
-
-  factory BuilderActionPerformance.fromJson(Map<String, dynamic> json) =>
-      _$BuilderActionPerformanceFromJson(json);
-
-  @override
-  Map<String, dynamic> toJson() => _$BuilderActionPerformanceToJson(this);
-}
-
-/// The [TimeSlice] of a particular task within a builder action.
-///
-/// This is some slice of overall [BuilderActionPerformance].
-@JsonSerializable()
-class BuilderActionStagePerformance extends TimeSliceGroup {
-  final String label;
-
-  BuilderActionStagePerformance(this.label, List<TimeSlice> slices)
-      : super(slices);
-
-  factory BuilderActionStagePerformance.fromJson(Map<String, dynamic> json) =>
-      _$BuilderActionStagePerformanceFromJson(json);
-
-  @override
-  Map<String, dynamic> toJson() => _$BuilderActionStagePerformanceToJson(this);
-}
-
-/// Interface for tracking the overall performance of a build.
-abstract class BuildPerformanceTracker
-    implements TimeTracker, BuildPerformance {
-  /// Tracks [runPhase] which performs [action] on all inputs in a phase, and
-  /// return the outputs generated.
-  Future<Iterable<AssetId>> trackBuildPhase(
-      BuildPhase action, Future<Iterable<AssetId>> Function() runPhase);
-
-  /// Returns a [BuilderActionTracker] for tracking [builderKey] on
-  /// [primaryInput] and adds it to [actions].
-  BuilderActionTracker addBuilderAction(
-      AssetId primaryInput, String builderKey);
-
-  factory BuildPerformanceTracker() => _BuildPerformanceTrackerImpl();
-
-  /// A [BuildPerformanceTracker] with as little overhead as possible. Does no
-  /// actual tracking and does not implement many fields/methods.
-  factory BuildPerformanceTracker.noOp() =>
-      _NoOpBuildPerformanceTracker.sharedInstance;
-}
-
-/// Real implementation of [BuildPerformanceTracker].
-///
-/// Use [BuildPerformanceTracker] factory to get an instance.
-class _BuildPerformanceTrackerImpl extends SimpleAsyncTimeTracker
-    implements BuildPerformanceTracker {
-  @override
-  Iterable<BuildPhaseTracker> get phases => _phases;
-  final _phases = <BuildPhaseTracker>[];
-
-  @override
-  Iterable<BuilderActionTracker> get actions => _actions;
-  final _actions = <BuilderActionTracker>[];
-
-  /// Tracks [action] which is ran with [runPhase].
-  ///
-  /// This represents running a [Builder] on a group of sources.
-  ///
-  /// Returns all the outputs generated by the phase.
-  @override
-  Future<Iterable<AssetId>> trackBuildPhase(
-      BuildPhase action, Future<Iterable<AssetId>> Function() runPhase) {
-    assert(isTracking);
-    var tracker = BuildPhaseTracker(action);
-    _phases.add(tracker);
-    return tracker.track(runPhase);
-  }
-
-  /// Returns a new [BuilderActionTracker] and adds it to [actions].
-  ///
-  /// The [BuilderActionTracker] will already be started, but you must stop it.
-  @override
-  BuilderActionTracker addBuilderAction(
-      AssetId primaryInput, String builderKey) {
-    assert(isTracking);
-    var tracker = BuilderActionTracker(primaryInput, builderKey);
-    _actions.add(tracker);
-    return tracker;
-  }
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildPerformanceToJson(this);
-}
-
-/// No-op implementation of [BuildPerformanceTracker].
-///
-/// Read-only fields will throw, and tracking methods just directly invoke their
-/// closures without tracking anything.
-///
-/// Use [BuildPerformanceTracker.noOp] to get an instance.
-class _NoOpBuildPerformanceTracker extends NoOpTimeTracker
-    implements BuildPerformanceTracker {
-  static final _NoOpBuildPerformanceTracker sharedInstance =
-      _NoOpBuildPerformanceTracker();
-
-  @override
-  Iterable<BuilderActionTracker> get actions => throw UnimplementedError();
-
-  @override
-  Iterable<BuildPhaseTracker> get phases => throw UnimplementedError();
-
-  @override
-  BuilderActionTracker addBuilderAction(
-          AssetId primaryInput, String builderKey) =>
-      BuilderActionTracker.noOp();
-
-  @override
-  Future<Iterable<AssetId>> trackBuildPhase(
-          BuildPhase action, Future<Iterable<AssetId>> Function() runPhase) =>
-      runPhase();
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildPerformanceToJson(this);
-}
-
-/// Internal class that tracks the [TimeSlice] of an entire [BuildPhase].
-///
-/// Tracks total time it took to run on all inputs available to that action.
-///
-/// Use [track] to start actually tracking an operation.
-///
-/// This is only meaningful for non-lazy phases.
-class BuildPhaseTracker extends SimpleAsyncTimeTracker
-    implements BuildPhasePerformance {
-  @override
-  final List<String> builderKeys;
-
-  BuildPhaseTracker(BuildPhase action)
-      : builderKeys = action is InBuildPhase
-            ? [action.builderLabel]
-            : (action as PostBuildPhase)
-                .builderActions
-                .map((action) => action.builderLabel)
-                .toList();
-
-  @override
-  Map<String, dynamic> toJson() => _$BuildPhasePerformanceToJson(this);
-}
-
-/// Interface for tracking the [TimeSlice] of an individual [Builder] on a given
-/// primary input.
-abstract class BuilderActionTracker
-    implements TimeTracker, BuilderActionPerformance, StageTracker {
-  /// Tracks the time of [runStage] and associates it with [label].
-  ///
-  /// You can specify [runStage] as [isExternal] (waiting for some external
-  /// resource like network, process or file IO). In that case [runStage] will
-  /// be tracked as single time slice from the beginning of the stage till
-  /// completion of Future returned by [runStage].
-  ///
-  /// Otherwise all separate time slices of asynchronous execution will be
-  /// tracked, but waiting for external resources will be a gap.
-  @override
-  T trackStage<T>(String label, T Function() runStage,
-      {bool isExternal = false});
-
-  factory BuilderActionTracker(AssetId primaryInput, String builderKey) =>
-      _BuilderActionTrackerImpl(primaryInput, builderKey);
-
-  /// A [BuilderActionTracker] with as little overhead as possible. Does no
-  /// actual tracking and does not implement many fields/methods.
-  factory BuilderActionTracker.noOp() =>
-      _NoOpBuilderActionTracker._sharedInstance;
-}
-
-/// Real implementation of [BuilderActionTracker] which records timings.
-///
-/// Use the [BuilderActionTracker] factory to get an instance.
-class _BuilderActionTrackerImpl extends SimpleAsyncTimeTracker
-    implements BuilderActionTracker {
-  @override
-  final String builderKey;
-  @override
-  final AssetId primaryInput;
-
-  @override
-  final List<BuilderActionStageTracker> stages = [];
-
-  @override
-  Duration get innerDuration => stages.fold(
-      Duration.zero, (duration, stage) => duration + stage.innerDuration);
-
-  _BuilderActionTrackerImpl(this.primaryInput, this.builderKey);
-
-  @override
-  T trackStage<T>(String label, T Function() action,
-      {bool isExternal = false}) {
-    var tracker = isExternal
-        ? BuilderActionStageSimpleTracker(label)
-        : BuilderActionStageAsyncTracker(label);
-    stages.add(tracker);
-    return tracker.track(action);
-  }
-
-  @override
-  Map<String, dynamic> toJson() => _$BuilderActionPerformanceToJson(this);
-}
-
-/// No-op instance of [BuilderActionTracker] which does nothing and throws an
-/// unimplemented error for everything but [trackStage], which delegates directly to
-/// the wrapped function.
-///
-/// Use the [BuilderActionTracker.noOp] factory to get an instance.
-class _NoOpBuilderActionTracker extends NoOpTimeTracker
-    implements BuilderActionTracker {
-  static final _NoOpBuilderActionTracker _sharedInstance =
-      _NoOpBuilderActionTracker();
-
-  @override
-  String get builderKey => throw UnimplementedError();
-
-  @override
-  Duration get duration => throw UnimplementedError();
-
-  @override
-  Iterable<BuilderActionStagePerformance> get stages =>
-      throw UnimplementedError();
-
-  @override
-  Duration get innerDuration => throw UnimplementedError();
-
-  @override
-  AssetId get primaryInput => throw UnimplementedError();
-
-  @override
-  T trackStage<T>(String label, T Function() runStage,
-          {bool isExternal = false}) =>
-      runStage();
-
-  @override
-  Map<String, dynamic> toJson() => _$BuilderActionPerformanceToJson(this);
-}
-
-/// Tracks the [TimeSliceGroup] of an individual task.
-///
-/// These represent a slice of the [BuilderActionPerformance].
-abstract class BuilderActionStageTracker
-    implements BuilderActionStagePerformance {
-  T track<T>(T Function() action);
-}
-
-class BuilderActionStageAsyncTracker extends AsyncTimeTracker
-    implements BuilderActionStageTracker {
-  @override
-  final String label;
-
-  BuilderActionStageAsyncTracker(this.label) : super(trackNested: false);
-
-  @override
-  Map<String, dynamic> toJson() => _$BuilderActionStagePerformanceToJson(this);
-}
-
-class BuilderActionStageSimpleTracker extends BuilderActionStagePerformance
-    implements BuilderActionStageTracker {
-  final _tracker = SimpleAsyncTimeTracker();
-
-  BuilderActionStageSimpleTracker(String label) : super(label, []) {
-    slices.add(_tracker);
-  }
-
-  @override
-  T track<T>(T Function() action) => _tracker.track(action);
-}
-
-AssetId _assetIdFromJson(String json) => AssetId.parse(json);
-
-String _assetIdToJson(AssetId id) => id.toString();
diff --git a/build_runner_core/lib/src/generate/performance_tracker.g.dart b/build_runner_core/lib/src/generate/performance_tracker.g.dart
deleted file mode 100644
index 29ea027..0000000
--- a/build_runner_core/lib/src/generate/performance_tracker.g.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of build_runner.src.generate.performance_tracker;
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BuildPerformance _$BuildPerformanceFromJson(Map<String, dynamic> json) {
-  return BuildPerformance(
-      (json['phases'] as List)?.map((e) => e == null
-          ? null
-          : BuildPhasePerformance.fromJson(e as Map<String, dynamic>)),
-      (json['actions'] as List)?.map((e) => e == null
-          ? null
-          : BuilderActionPerformance.fromJson(e as Map<String, dynamic>)),
-      json['startTime'] == null
-          ? null
-          : DateTime.parse(json['startTime'] as String),
-      json['stopTime'] == null
-          ? null
-          : DateTime.parse(json['stopTime'] as String));
-}
-
-Map<String, dynamic> _$BuildPerformanceToJson(BuildPerformance instance) =>
-    <String, dynamic>{
-      'startTime': instance.startTime?.toIso8601String(),
-      'stopTime': instance.stopTime?.toIso8601String(),
-      'phases': instance.phases?.toList(),
-      'actions': instance.actions?.toList()
-    };
-
-BuildPhasePerformance _$BuildPhasePerformanceFromJson(
-    Map<String, dynamic> json) {
-  return BuildPhasePerformance(
-      (json['builderKeys'] as List)?.map((e) => e as String)?.toList(),
-      json['startTime'] == null
-          ? null
-          : DateTime.parse(json['startTime'] as String),
-      json['stopTime'] == null
-          ? null
-          : DateTime.parse(json['stopTime'] as String));
-}
-
-Map<String, dynamic> _$BuildPhasePerformanceToJson(
-        BuildPhasePerformance instance) =>
-    <String, dynamic>{
-      'startTime': instance.startTime?.toIso8601String(),
-      'stopTime': instance.stopTime?.toIso8601String(),
-      'builderKeys': instance.builderKeys
-    };
-
-BuilderActionPerformance _$BuilderActionPerformanceFromJson(
-    Map<String, dynamic> json) {
-  return BuilderActionPerformance(
-      json['builderKey'] as String,
-      _assetIdFromJson(json['primaryInput'] as String),
-      (json['stages'] as List)?.map((e) => e == null
-          ? null
-          : BuilderActionStagePerformance.fromJson(e as Map<String, dynamic>)),
-      json['startTime'] == null
-          ? null
-          : DateTime.parse(json['startTime'] as String),
-      json['stopTime'] == null
-          ? null
-          : DateTime.parse(json['stopTime'] as String));
-}
-
-Map<String, dynamic> _$BuilderActionPerformanceToJson(
-        BuilderActionPerformance instance) =>
-    <String, dynamic>{
-      'startTime': instance.startTime?.toIso8601String(),
-      'stopTime': instance.stopTime?.toIso8601String(),
-      'builderKey': instance.builderKey,
-      'primaryInput': _assetIdToJson(instance.primaryInput),
-      'stages': instance.stages?.toList()
-    };
-
-BuilderActionStagePerformance _$BuilderActionStagePerformanceFromJson(
-    Map<String, dynamic> json) {
-  return BuilderActionStagePerformance(
-      json['label'] as String,
-      (json['slices'] as List)
-          ?.map((e) =>
-              e == null ? null : TimeSlice.fromJson(e as Map<String, dynamic>))
-          ?.toList());
-}
-
-Map<String, dynamic> _$BuilderActionStagePerformanceToJson(
-        BuilderActionStagePerformance instance) =>
-    <String, dynamic>{'slices': instance.slices, 'label': instance.label};
diff --git a/build_runner_core/lib/src/generate/phase.dart b/build_runner_core/lib/src/generate/phase.dart
deleted file mode 100644
index b6b83b0..0000000
--- a/build_runner_core/lib/src/generate/phase.dart
+++ /dev/null
@@ -1,218 +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 'package:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:collection/collection.dart';
-import 'package:meta/meta.dart';
-
-import 'input_matcher.dart';
-
-/// A "phase" in the build graph, which represents running a one or more
-/// builders on a set of sources.
-abstract class BuildPhase {
-  /// Whether to run lazily when an output is read.
-  ///
-  /// An optional build action will only run if one of its outputs is read by
-  /// a later [Builder], or is used as a primary input to a later [Builder].
-  ///
-  /// If no build actions read the output of an optional action, then it will
-  /// never run.
-  bool get isOptional;
-
-  /// Whether generated assets should be placed in the build cache.
-  ///
-  /// When this is `false` the Builder may not run on any package other than
-  /// the root.
-  bool get hideOutput;
-
-  /// The identity of this action in terms of a build graph. If the identity of
-  /// any action changes the build will be invalidated.
-  ///
-  /// This should take into account everything except for the builderOptions,
-  /// which are tracked separately via a `BuilderOptionsNode` which supports
-  /// more fine grained invalidation.
-  int get identity;
-}
-
-/// An "action" in the build graph which represents running a single builder
-/// on a set of sources.
-abstract class BuildAction {
-  /// Either a [Builder] or a [PostProcessBuilder].
-  dynamic get builder;
-  String get builderLabel;
-  BuilderOptions get builderOptions;
-  InputMatcher get generateFor;
-  String get package;
-  InputMatcher get targetSources;
-}
-
-/// A [BuildPhase] that uses a single [Builder] to generate files.
-class InBuildPhase extends BuildPhase implements BuildAction {
-  @override
-  final Builder builder;
-  @override
-  final String builderLabel;
-  @override
-  final BuilderOptions builderOptions;
-  @override
-  final InputMatcher generateFor;
-  @override
-  final String package;
-  @override
-  final InputMatcher targetSources;
-
-  @override
-  final bool isOptional;
-  @override
-  final bool hideOutput;
-
-  InBuildPhase._(this.package, this.builder, this.builderOptions,
-      {@required this.targetSources,
-      @required this.generateFor,
-      @required this.builderLabel,
-      bool isOptional,
-      bool hideOutput})
-      : isOptional = isOptional ?? false,
-        hideOutput = hideOutput ?? false;
-
-  /// Creates an [BuildPhase] for a normal [Builder].
-  ///
-  /// The build target is defined by [package] as well as [targetSources]. By
-  /// default all sources in the target are used as primary inputs to the
-  /// builder, but it can be further filtered with [generateFor].
-  ///
-  /// [isOptional] specifies that a Builder may not be run unless some other
-  /// Builder in a later phase attempts to read one of the potential outputs.
-  ///
-  /// [hideOutput] specifies that the generated asses should be placed in the
-  /// build cache rather than the source tree.
-  factory InBuildPhase(
-    Builder builder,
-    String package, {
-    String builderKey,
-    InputSet targetSources,
-    InputSet generateFor,
-    BuilderOptions builderOptions,
-    bool isOptional,
-    bool hideOutput,
-  }) {
-    var targetSourceMatcher = InputMatcher(targetSources ?? const InputSet());
-    var generateForMatcher = InputMatcher(generateFor ?? const InputSet());
-    builderOptions ??= const BuilderOptions({});
-    return InBuildPhase._(package, builder, builderOptions,
-        targetSources: targetSourceMatcher,
-        generateFor: generateForMatcher,
-        builderLabel: builderKey == null || builderKey.isEmpty
-            ? _builderLabel(builder)
-            : _simpleBuilderKey(builderKey),
-        isOptional: isOptional,
-        hideOutput: hideOutput);
-  }
-
-  @override
-  String toString() {
-    final settings = <String>[];
-    if (isOptional) settings.add('optional');
-    if (hideOutput) settings.add('hidden');
-    var result = '$builderLabel on $targetSources in $package';
-    if (settings.isNotEmpty) result += ' $settings';
-    return result;
-  }
-
-  @override
-  int get identity => _deepEquals.hash([
-        builderLabel,
-        builder.buildExtensions,
-        package,
-        targetSources,
-        generateFor,
-        isOptional,
-        hideOutput
-      ]);
-}
-
-/// A [BuildPhase] that can run multiple [PostBuildAction]s to
-/// generate files.
-///
-/// There should only be one of these per build, and it should be the final
-/// phase.
-class PostBuildPhase extends BuildPhase {
-  final List<PostBuildAction> builderActions;
-
-  @override
-  bool get hideOutput => true;
-  @override
-  bool get isOptional => false;
-
-  PostBuildPhase(this.builderActions);
-
-  @override
-  String toString() =>
-      '${builderActions.map((a) => a.builderLabel).join(', ')}';
-
-  @override
-  int get identity =>
-      _deepEquals.hash(builderActions.map<dynamic>((b) => b.identity).toList()
-        ..addAll([
-          isOptional,
-          hideOutput,
-        ]));
-}
-
-/// Part of a larger [PostBuildPhase], applies a single
-/// [PostProcessBuilder] to a single [package] with some additional options.
-class PostBuildAction implements BuildAction {
-  @override
-  final PostProcessBuilder builder;
-  @override
-  final String builderLabel;
-  @override
-  final BuilderOptions builderOptions;
-  @override
-  final InputMatcher generateFor;
-  @override
-  final String package;
-  @override
-  final InputMatcher targetSources;
-
-  PostBuildAction(this.builder, this.package,
-      {String builderKey,
-      @required BuilderOptions builderOptions,
-      @required InputSet targetSources,
-      @required InputSet generateFor})
-      : builderLabel = builderKey == null || builderKey.isEmpty
-            ? _builderLabel(builder)
-            : _simpleBuilderKey(builderKey),
-        builderOptions = builderOptions ?? const BuilderOptions({}),
-        targetSources = InputMatcher(targetSources ?? const InputSet()),
-        generateFor = InputMatcher(generateFor ?? const InputSet());
-
-  int get identity => _deepEquals.hash([
-        builderLabel,
-        builder.inputExtensions.toList(),
-        generateFor,
-        package,
-        targetSources,
-      ]);
-}
-
-/// If we have no key find a human friendly name for the Builder.
-String _builderLabel(Object builder) {
-  var label = '$builder';
-  if (label.startsWith('Instance of \'')) {
-    label = label.substring(13, label.length - 1);
-  }
-  return label;
-}
-
-/// Change "angular|angular" to "angular".
-String _simpleBuilderKey(String builderKey) {
-  if (!builderKey.contains('|')) return builderKey;
-  var parts = builderKey.split('|');
-  if (parts[0] == parts[1]) return parts[0];
-  return builderKey;
-}
-
-final _deepEquals = const DeepCollectionEquality();
diff --git a/build_runner_core/lib/src/logging/build_for_input_logger.dart b/build_runner_core/lib/src/logging/build_for_input_logger.dart
deleted file mode 100644
index 1e45120..0000000
--- a/build_runner_core/lib/src/logging/build_for_input_logger.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:logging/logging.dart';
-
-import 'failure_reporter.dart';
-
-/// A delegating [Logger] that records if any logs of level >= [Level.SEVERE]
-/// were seen.
-class BuildForInputLogger implements Logger {
-  final Logger _delegate;
-
-  final errorsSeen = <ErrorReport>[];
-
-  BuildForInputLogger(this._delegate);
-
-  @override
-  Level get level => _delegate.level;
-
-  @override
-  set level(Level level) => _delegate.level = level;
-
-  @override
-  Map<String, Logger> get children => _delegate.children;
-
-  @override
-  void clearListeners() => _delegate.clearListeners();
-
-  @override
-  void config(Object message, [Object error, StackTrace stackTrace]) =>
-      _delegate.config(message, error, stackTrace);
-
-  @override
-  void fine(Object message, [Object error, StackTrace stackTrace]) =>
-      _delegate.fine(message, error, stackTrace);
-
-  @override
-  void finer(Object message, [Object error, StackTrace stackTrace]) =>
-      _delegate.finer(message, error, stackTrace);
-
-  @override
-  void finest(Object message, [Object error, StackTrace stackTrace]) =>
-      _delegate.finest(message, error, stackTrace);
-
-  @override
-  String get fullName => _delegate.fullName;
-
-  @override
-  void info(Object message, [Object error, StackTrace stackTrace]) =>
-      _delegate.info(message, error, stackTrace);
-
-  @override
-  bool isLoggable(Level value) => _delegate.isLoggable(value);
-
-  @override
-  void log(Level logLevel, Object message,
-      [Object error, StackTrace stackTrace, Zone zone]) {
-    if (logLevel >= Level.SEVERE) {
-      errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
-    }
-    _delegate.log(logLevel, message, error, stackTrace, zone);
-  }
-
-  @override
-  String get name => _delegate.name;
-
-  @override
-  Stream<LogRecord> get onRecord => _delegate.onRecord;
-
-  @override
-  Logger get parent => _delegate.parent;
-
-  @override
-  void severe(Object message, [Object error, StackTrace stackTrace]) {
-    errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
-    _delegate.severe(message, error, stackTrace);
-  }
-
-  @override
-  void shout(Object message, [Object error, StackTrace stackTrace]) {
-    errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
-    _delegate.shout(message, error, stackTrace);
-  }
-
-  @override
-  void warning(Object message, [Object error, StackTrace stackTrace]) =>
-      _delegate.warning(message, error, stackTrace);
-}
diff --git a/build_runner_core/lib/src/logging/failure_reporter.dart b/build_runner_core/lib/src/logging/failure_reporter.dart
deleted file mode 100644
index 75bb4f8..0000000
--- a/build_runner_core/lib/src/logging/failure_reporter.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import '../asset_graph/node.dart';
-import '../util/constants.dart';
-
-/// A tracker for the errors which have already been reported during the current
-/// build.
-///
-/// Errors that occur due to actions that are run within this build will be
-/// reported directly as they happen. When an action is skipped and remains a
-/// failure the error will not have been reported by the time we check wether
-/// the build is failed.
-///
-/// The lifetime of this class should be a single build.
-class FailureReporter {
-  /// Removes all stored errors from previous builds.
-  ///
-  /// This should be called any time the build phases change since the naming
-  /// scheme is dependent on the build phases.
-  static Future<void> cleanErrorCache() async {
-    final errorCacheDirectory = Directory(p.fromUri(errorCachePath));
-    if (await errorCacheDirectory.exists()) {
-      await errorCacheDirectory.delete(recursive: true);
-    }
-  }
-
-  /// Remove the stored error for [phaseNumber] runnon on [primaryInput].
-  ///
-  /// This should be called anytime the action is being run.
-  static Future<void> clean(int phaseNumber, AssetId primaryInput) async {
-    final errorFile =
-        File(_errorPathForPrimaryInput(phaseNumber, primaryInput));
-    if (await errorFile.exists()) {
-      await errorFile.delete();
-    }
-  }
-
-  /// A set of Strings which uniquely identify a particular build action and
-  /// it's primary input.
-  final _reportedActions = <String>{};
-
-  /// Indicate that a failure reason for the build step which would produce
-  /// [output] and all other outputs from the same build step has been printed.
-  Future<void> markReported(String actionDescription, GeneratedAssetNode output,
-      Iterable<ErrorReport> errors) async {
-    if (!_reportedActions.add(_actionKey(output))) return;
-    final errorFile =
-        await File(_errorPathForOutput(output)).create(recursive: true);
-    await errorFile.writeAsString(jsonEncode(<dynamic>[actionDescription]
-        .followedBy(errors
-            .map((e) => [e.message, e.error, e.stackTrace?.toString() ?? '']))
-        .toList()));
-  }
-
-  /// Indicate that the build steps which would produce [outputs] are failing
-  /// due to a dependency and being skipped so no actuall error will be
-  /// produced.
-  Future<void> markSkipped(Iterable<GeneratedAssetNode> outputs) =>
-      Future.wait(outputs.map((output) async {
-        if (!_reportedActions.add(_actionKey(output))) return;
-        await clean(output.phaseNumber, output.primaryInput);
-      }));
-
-  /// Log stored errors for any build steps which would output nodes in
-  /// [failingNodes] which haven't already been reported.
-  Future<void> reportErrors(Iterable<GeneratedAssetNode> failingNodes) {
-    final errorFiles = <File>[];
-    for (final failure in failingNodes) {
-      final key = _actionKey(failure);
-      if (!_reportedActions.add(key)) continue;
-      errorFiles.add(File(_errorPathForOutput(failure)));
-    }
-    return Future.wait(errorFiles.map((errorFile) async {
-      if (await errorFile.exists()) {
-        final errorReports = jsonDecode(await errorFile.readAsString());
-        final actionDescription = '${(errorReports as List).first} (cached)';
-        final logger = Logger(actionDescription);
-        for (final List error in errorReports.skip(1)) {
-          final stackTraceString = error[2] as String;
-          final stackTrace = stackTraceString.isEmpty
-              ? null
-              : StackTrace.fromString(stackTraceString);
-          logger.severe(error[0], error[1], stackTrace);
-        }
-      }
-    }));
-  }
-}
-
-/// Matches the call to [Logger.severe] except the [message] and [error] are
-/// eagerly converted to String.
-class ErrorReport {
-  final String message;
-  final String error;
-  final StackTrace stackTrace;
-  ErrorReport(this.message, this.error, this.stackTrace);
-}
-
-String _actionKey(GeneratedAssetNode node) =>
-    '${node.builderOptionsId} on ${node.primaryInput}';
-
-String _errorPathForOutput(GeneratedAssetNode output) => p.join(
-    p.fromUri(errorCachePath),
-    output.id.package,
-    '${output.phaseNumber}',
-    p.fromUri(output.primaryInput.path));
-
-String _errorPathForPrimaryInput(int phaseNumber, AssetId primaryInput) =>
-    p.join(p.fromUri(errorCachePath), primaryInput.package, '$phaseNumber',
-        p.fromUri(primaryInput.path));
diff --git a/build_runner_core/lib/src/logging/human_readable_duration.dart b/build_runner_core/lib/src/logging/human_readable_duration.dart
deleted file mode 100644
index b03aee9..0000000
--- a/build_runner_core/lib/src/logging/human_readable_duration.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.
-
-/// Returns a human readable string for a duration.
-///
-/// Handles durations that span up to hours - this will not be a good fit for
-/// durations that are longer than days.
-///
-/// Always attempts 2 'levels' of precision. Will show hours/minutes,
-/// minutes/seconds, seconds/tenths of a second, or milliseconds depending on
-/// the largest level that needs to be displayed.
-String humanReadable(Duration duration) {
-  if (duration < const Duration(seconds: 1)) {
-    return '${duration.inMilliseconds}ms';
-  }
-  if (duration < const Duration(minutes: 1)) {
-    return '${(duration.inMilliseconds / 1000.0).toStringAsFixed(1)}s';
-  }
-  if (duration < const Duration(hours: 1)) {
-    final minutes = duration.inMinutes;
-    final remaining = duration - Duration(minutes: minutes);
-    return '${minutes}m ${remaining.inSeconds}s';
-  }
-  final hours = duration.inHours;
-  final remaining = duration - Duration(hours: hours);
-  return '${hours}h ${remaining.inMinutes}m';
-}
diff --git a/build_runner_core/lib/src/logging/logging.dart b/build_runner_core/lib/src/logging/logging.dart
deleted file mode 100644
index 1d93542..0000000
--- a/build_runner_core/lib/src/logging/logging.dart
+++ /dev/null
@@ -1,48 +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:logging/logging.dart';
-
-import 'human_readable_duration.dart';
-
-// Ensures this message does not get overwritten by later logs.
-final _logSuffix = '\n';
-
-/// Logs an asynchronous [action] with [description] before and after.
-///
-/// Returns a future that completes after the action and logging finishes.
-Future<T> logTimedAsync<T>(
-  Logger logger,
-  String description,
-  Future<T> Function() action, {
-  Level level = Level.INFO,
-}) async {
-  final watch = Stopwatch()..start();
-  logger.log(level, '$description...');
-  final result = await action();
-  watch.stop();
-  final time = '${humanReadable(watch.elapsed)}$_logSuffix';
-  logger.log(level, '$description completed, took $time');
-  return result;
-}
-
-/// Logs a synchronous [action] with [description] before and after.
-///
-/// Returns a future that completes after the action and logging finishes.
-T logTimedSync<T>(
-  Logger logger,
-  String description,
-  T Function() action, {
-  Level level = Level.INFO,
-}) {
-  final watch = Stopwatch()..start();
-  logger.log(level, '$description...');
-  final result = action();
-  watch.stop();
-  final time = '${humanReadable(watch.elapsed)}$_logSuffix';
-  logger.log(level, '$description completed, took $time');
-  return result;
-}
diff --git a/build_runner_core/lib/src/package_graph/apply_builders.dart b/build_runner_core/lib/src/package_graph/apply_builders.dart
deleted file mode 100644
index a151016..0000000
--- a/build_runner_core/lib/src/package_graph/apply_builders.dart
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:build/src/builder/logging.dart';
-import 'package:build_config/build_config.dart';
-import 'package:graphs/graphs.dart';
-import 'package:logging/logging.dart';
-
-import '../generate/exceptions.dart';
-import '../generate/phase.dart';
-import '../validation/config_validation.dart';
-import 'package_graph.dart';
-import 'target_graph.dart';
-
-typedef BuildPhaseFactory = BuildPhase Function(
-    PackageNode package,
-    BuilderOptions options,
-    InputSet targetSources,
-    InputSet generateFor,
-    bool isReleaseBuild);
-
-typedef PackageFilter = bool Function(PackageNode node);
-
-/// Run a builder on all packages in the package graph.
-PackageFilter toAllPackages() => (_) => true;
-
-/// Require manual configuration to opt in to a builder.
-PackageFilter toNoneByDefault() => (_) => false;
-
-/// Run a builder on all packages with an immediate dependency on [packageName].
-PackageFilter toDependentsOf(String packageName) =>
-    (p) => p.dependencies.any((d) => d.name == packageName);
-
-/// Run a builder on a single package.
-PackageFilter toPackage(String package) => (p) => p.name == package;
-
-/// Run a builder on a collection of packages.
-PackageFilter toPackages(Set<String> packages) =>
-    (p) => packages.contains(p.name);
-
-/// Run a builders if the package matches any of [filters]
-PackageFilter toAll(Iterable<PackageFilter> filters) =>
-    (p) => filters.any((f) => f(p));
-
-PackageFilter toRoot() => (p) => p.isRoot;
-
-/// Apply [builder] to the root package.
-///
-/// Creates a `BuilderApplication` which corresponds to an empty builder key so
-/// that no other `build.yaml` based configuration will apply.
-BuilderApplication applyToRoot(Builder builder,
-        {bool isOptional = false,
-        bool hideOutput = false,
-        InputSet generateFor}) =>
-    BuilderApplication.forBuilder('', [(_) => builder], toRoot(),
-        isOptional: isOptional,
-        hideOutput: hideOutput,
-        defaultGenerateFor: generateFor);
-
-/// Apply each builder from [builderFactories] to the packages matching
-/// [filter].
-///
-/// If the builder should only run on a subset of files within a target pass
-/// globs to [defaultGenerateFor]. This can be overridden by any target which
-/// configured the builder manually.
-///
-/// If [isOptional] is true the builder will only run if one of its outputs is
-/// read by a later builder, or is used as a primary input to a later builder.
-/// If no build actions read the output of an optional action, then it will
-/// never run.
-///
-/// Any existing Builders which match a key in [appliesBuilders] will
-/// automatically be applied to any target which runs this Builder, whether
-/// because it matches [filter] or because it was enabled manually.
-BuilderApplication apply(String builderKey,
-        List<BuilderFactory> builderFactories, PackageFilter filter,
-        {bool isOptional,
-        bool hideOutput,
-        InputSet defaultGenerateFor,
-        BuilderOptions defaultOptions,
-        BuilderOptions defaultDevOptions,
-        BuilderOptions defaultReleaseOptions,
-        Iterable<String> appliesBuilders}) =>
-    BuilderApplication.forBuilder(
-      builderKey,
-      builderFactories,
-      filter,
-      isOptional: isOptional,
-      hideOutput: hideOutput,
-      defaultGenerateFor: defaultGenerateFor,
-      defaultOptions: defaultOptions,
-      defaultDevOptions: defaultDevOptions,
-      defaultReleaseOptions: defaultReleaseOptions,
-      appliesBuilders: appliesBuilders,
-    );
-
-/// Same as [apply] except it takes [PostProcessBuilderFactory]s.
-///
-/// Does not provide options for `isOptional` or `hideOutput` because they
-/// aren't configurable for these types of builders. They are never optional and
-/// always hidden.
-BuilderApplication applyPostProcess(
-        String builderKey, PostProcessBuilderFactory builderFactory,
-        {InputSet defaultGenerateFor,
-        BuilderOptions defaultOptions,
-        BuilderOptions defaultDevOptions,
-        BuilderOptions defaultReleaseOptions}) =>
-    BuilderApplication.forPostProcessBuilder(
-      builderKey,
-      builderFactory,
-      defaultGenerateFor: defaultGenerateFor,
-      defaultOptions: defaultOptions,
-      defaultDevOptions: defaultDevOptions,
-      defaultReleaseOptions: defaultReleaseOptions,
-    );
-
-/// A description of which packages need a given [Builder] or
-/// [PostProcessBuilder] applied.
-class BuilderApplication {
-  /// Factories that create [BuildPhase]s for all [Builder]s or
-  /// [PostProcessBuilder]s that should be applied.
-  final List<BuildPhaseFactory> buildPhaseFactories;
-
-  /// Determines whether a given package needs builder applied.
-  final PackageFilter filter;
-
-  /// Builder keys which, when applied to a target, will also apply this Builder
-  /// even if [filter] does not match.
-  final Iterable<String> appliesBuilders;
-
-  /// A uniqe key for this builder.
-  ///
-  /// Ignored when null or empty.
-  final String builderKey;
-
-  /// Whether genereated assets should be placed in the build cache.
-  final bool hideOutput;
-
-  const BuilderApplication._(
-    this.builderKey,
-    this.buildPhaseFactories,
-    this.filter,
-    this.hideOutput,
-    Iterable<String> appliesBuilders,
-  ) : appliesBuilders = appliesBuilders ?? const [];
-
-  factory BuilderApplication.forBuilder(
-    String builderKey,
-    List<BuilderFactory> builderFactories,
-    PackageFilter filter, {
-    bool isOptional,
-    bool hideOutput,
-    InputSet defaultGenerateFor,
-    BuilderOptions defaultOptions,
-    BuilderOptions defaultDevOptions,
-    BuilderOptions defaultReleaseOptions,
-    Iterable<String> appliesBuilders,
-  }) {
-    hideOutput ??= true;
-    var phaseFactories = builderFactories.map((builderFactory) {
-      return (PackageNode package, BuilderOptions options,
-          InputSet targetSources, InputSet generateFor, bool isReleaseBuild) {
-        generateFor ??= defaultGenerateFor;
-
-        var optionsWithDefaults = (defaultOptions ?? BuilderOptions.empty)
-            .overrideWith(
-                isReleaseBuild ? defaultReleaseOptions : defaultDevOptions)
-            .overrideWith(options);
-        if (package.isRoot) {
-          optionsWithDefaults =
-              optionsWithDefaults.overrideWith(BuilderOptions.forRoot);
-        }
-
-        final logger = Logger(builderKey);
-        final builder =
-            _scopeLogSync(() => builderFactory(optionsWithDefaults), logger);
-        if (builder == null) {
-          logger.severe(_factoryFailure(package.name, optionsWithDefaults));
-          throw CannotBuildException();
-        }
-        return InBuildPhase(builder, package.name,
-            builderKey: builderKey,
-            targetSources: targetSources,
-            generateFor: generateFor,
-            builderOptions: optionsWithDefaults,
-            hideOutput: hideOutput,
-            isOptional: isOptional);
-      };
-    }).toList();
-    return BuilderApplication._(
-        builderKey, phaseFactories, filter, hideOutput, appliesBuilders);
-  }
-
-  /// Note that these builder applications each create their own phase, but they
-  /// will all eventually be merged into a single phase.
-  factory BuilderApplication.forPostProcessBuilder(
-    String builderKey,
-    PostProcessBuilderFactory builderFactory, {
-    InputSet defaultGenerateFor,
-    BuilderOptions defaultOptions,
-    BuilderOptions defaultDevOptions,
-    BuilderOptions defaultReleaseOptions,
-  }) {
-    var phaseFactory = (PackageNode package, BuilderOptions options,
-        InputSet targetSources, InputSet generateFor, bool isReleaseBuild) {
-      generateFor ??= defaultGenerateFor;
-
-      var optionsWithDefaults = (defaultOptions ?? BuilderOptions.empty)
-          .overrideWith(
-              isReleaseBuild ? defaultReleaseOptions : defaultDevOptions)
-          .overrideWith(options);
-      if (package.isRoot) {
-        optionsWithDefaults =
-            optionsWithDefaults.overrideWith(BuilderOptions.forRoot);
-      }
-
-      final logger = Logger(builderKey);
-      final builder =
-          _scopeLogSync(() => builderFactory(optionsWithDefaults), logger);
-      if (builder == null) {
-        logger.severe(_factoryFailure(package.name, optionsWithDefaults));
-        throw CannotBuildException();
-      }
-      var builderAction = PostBuildAction(builder, package.name,
-          builderOptions: optionsWithDefaults,
-          generateFor: generateFor,
-          targetSources: targetSources);
-      return PostBuildPhase([builderAction]);
-    };
-    return BuilderApplication._(
-        builderKey, [phaseFactory], toNoneByDefault(), true, []);
-  }
-}
-
-final _logger = Logger('ApplyBuilders');
-
-/// Creates a [BuildPhase] to apply each builder in [builderApplications] to
-/// each target in [targetGraph] such that all builders are run for dependencies
-/// before moving on to later packages.
-///
-/// When there is a package cycle the builders are applied to each packages
-/// within the cycle before moving on to packages that depend on any package
-/// within the cycle.
-///
-/// Builders may be filtered, for instance to run only on package which have a
-/// dependency on some other package by choosing the appropriate
-/// [BuilderApplication].
-Future<List<BuildPhase>> createBuildPhases(
-    TargetGraph targetGraph,
-    Iterable<BuilderApplication> builderApplications,
-    Map<String, Map<String, dynamic>> builderConfigOverrides,
-    bool isReleaseMode) async {
-  validateBuilderConfig(builderApplications, targetGraph.rootPackageConfig,
-      builderConfigOverrides, _logger);
-  final globalOptions = targetGraph.rootPackageConfig.globalOptions.map(
-      (key, config) => MapEntry(
-          key,
-          _options(config?.options).overrideWith(isReleaseMode
-              ? _options(config?.releaseOptions)
-              : _options(config?.devOptions))));
-  for (final key in builderConfigOverrides.keys) {
-    final overrides = BuilderOptions(builderConfigOverrides[key]);
-    globalOptions[key] =
-        (globalOptions[key] ?? BuilderOptions.empty).overrideWith(overrides);
-  }
-
-  final cycles = stronglyConnectedComponents<TargetNode>(
-      targetGraph.allModules.values,
-      (node) => node.target.dependencies?.map((key) {
-            if (!targetGraph.allModules.containsKey(key)) {
-              _logger.severe('${node.target.key} declares a dependency on $key '
-                  'but it does not exist');
-              throw CannotBuildException();
-            }
-            return targetGraph.allModules[key];
-          })?.where((n) => n != null),
-      equals: (a, b) => a.target.key == b.target.key,
-      hashCode: (node) => node.target.key.hashCode);
-  final applyWith = _applyWith(builderApplications);
-  final allBuilders = Map<String, BuilderApplication>.fromIterable(
-      builderApplications,
-      key: (b) => (b as BuilderApplication).builderKey);
-  final expandedPhases = cycles
-      .expand((cycle) => _createBuildPhasesWithinCycle(
-          cycle,
-          builderApplications,
-          globalOptions,
-          applyWith,
-          allBuilders,
-          isReleaseMode))
-      .toList();
-
-  final inBuildPhases = expandedPhases.whereType<InBuildPhase>();
-
-  final postBuildPhases = expandedPhases.whereType<PostBuildPhase>().toList();
-  final collapsedPostBuildPhase = <PostBuildPhase>[];
-  if (postBuildPhases.isNotEmpty) {
-    collapsedPostBuildPhase.add(postBuildPhases
-        .fold<PostBuildPhase>(PostBuildPhase([]), (previous, next) {
-      previous.builderActions.addAll(next.builderActions);
-      return previous;
-    }));
-  }
-
-  return <BuildPhase>[...inBuildPhases, ...collapsedPostBuildPhase];
-}
-
-Iterable<BuildPhase> _createBuildPhasesWithinCycle(
-        Iterable<TargetNode> cycle,
-        Iterable<BuilderApplication> builderApplications,
-        Map<String, BuilderOptions> globalOptions,
-        Map<String, List<BuilderApplication>> applyWith,
-        Map<String, BuilderApplication> allBuilders,
-        bool isReleaseMode) =>
-    builderApplications.expand((builderApplication) =>
-        _createBuildPhasesForBuilderInCycle(
-            cycle,
-            builderApplication,
-            globalOptions[builderApplication.builderKey] ??
-                BuilderOptions.empty,
-            applyWith,
-            allBuilders,
-            isReleaseMode));
-
-Iterable<BuildPhase> _createBuildPhasesForBuilderInCycle(
-    Iterable<TargetNode> cycle,
-    BuilderApplication builderApplication,
-    BuilderOptions globalOptionOverrides,
-    Map<String, List<BuilderApplication>> applyWith,
-    Map<String, BuilderApplication> allBuilders,
-    bool isReleaseMode) {
-  TargetBuilderConfig targetConfig(TargetNode node) =>
-      node.target.builders[builderApplication.builderKey];
-  return builderApplication.buildPhaseFactories.expand((createPhase) => cycle
-          .where((targetNode) => _shouldApply(
-              builderApplication, targetNode, applyWith, allBuilders))
-          .map((node) {
-        final builderConfig = targetConfig(node);
-        final options = _options(builderConfig?.options)
-            .overrideWith(isReleaseMode
-                ? _options(builderConfig?.releaseOptions)
-                : _options(builderConfig?.devOptions))
-            .overrideWith(globalOptionOverrides);
-        return createPhase(node.package, options, node.target.sources,
-            builderConfig?.generateFor, isReleaseMode);
-      }));
-}
-
-bool _shouldApply(
-    BuilderApplication builderApplication,
-    TargetNode node,
-    Map<String, List<BuilderApplication>> applyWith,
-    Map<String, BuilderApplication> allBuilders) {
-  if (!(builderApplication.hideOutput &&
-          builderApplication.appliesBuilders
-              .every((b) => allBuilders[b]?.hideOutput ?? true)) &&
-      !node.package.isRoot) {
-    return false;
-  }
-  final builderConfig = node.target.builders[builderApplication.builderKey];
-  if (builderConfig?.isEnabled != null) {
-    return builderConfig.isEnabled;
-  }
-  final shouldAutoApply =
-      node.target.autoApplyBuilders && builderApplication.filter(node.package);
-  return shouldAutoApply ||
-      (applyWith[builderApplication.builderKey] ?? const []).any(
-          (anchorBuilder) =>
-              _shouldApply(anchorBuilder, node, applyWith, allBuilders));
-}
-
-/// Inverts the dependency map from 'applies builders' to 'applied with
-/// builders'.
-Map<String, List<BuilderApplication>> _applyWith(
-    Iterable<BuilderApplication> builderApplications) {
-  final applyWith = <String, List<BuilderApplication>>{};
-  for (final builderApplication in builderApplications) {
-    for (final alsoApply in builderApplication.appliesBuilders) {
-      applyWith.putIfAbsent(alsoApply, () => []).add(builderApplication);
-    }
-  }
-  return applyWith;
-}
-
-/// Runs [fn] in an error handling [Zone].
-///
-/// Any calls to [print] will be logged with `log.info`, and any errors will be
-/// logged with `log.severe`.
-T _scopeLogSync<T>(T Function() fn, Logger log) {
-  return runZoned(fn,
-      zoneSpecification:
-          ZoneSpecification(print: (self, parent, zone, message) {
-        log.info(message);
-      }),
-      zoneValues: {logKey: log},
-      onError: (Object e, StackTrace s) {
-        log.severe('', e, s);
-      });
-}
-
-String _factoryFailure(String packageName, BuilderOptions options) =>
-    'Failed to instantiate builder for $packageName with configuration:\n'
-    '${JsonEncoder.withIndent(' ').convert(options.config)}';
-
-BuilderOptions _options(Map<String, dynamic> options) =>
-    options?.isEmpty ?? true ? BuilderOptions.empty : BuilderOptions(options);
diff --git a/build_runner_core/lib/src/package_graph/package_graph.dart b/build_runner_core/lib/src/package_graph/package_graph.dart
deleted file mode 100644
index 2ef4a56..0000000
--- a/build_runner_core/lib/src/package_graph/package_graph.dart
+++ /dev/null
@@ -1,250 +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:io';
-
-import 'package:path/path.dart' as p;
-import 'package:yaml/yaml.dart';
-
-import '../util/constants.dart';
-
-/// The SDK package, we filter this to the core libs and dev compiler
-/// resources.
-final PackageNode _sdkPackageNode =
-    PackageNode(r'$sdk', sdkPath, DependencyType.hosted);
-
-/// A graph of the package dependencies for an application.
-class PackageGraph {
-  /// The root application package.
-  final PackageNode root;
-
-  /// All [PackageNode]s indexed by package name.
-  final Map<String, PackageNode> allPackages;
-
-  PackageGraph._(this.root, Map<String, PackageNode> allPackages)
-      : allPackages = Map.unmodifiable(
-            Map<String, PackageNode>.from(allPackages)
-              ..putIfAbsent(r'$sdk', () => _sdkPackageNode)) {
-    if (!root.isRoot) {
-      throw ArgumentError('Root node must indicate `isRoot`');
-    }
-    if (allPackages.values.where((n) => n != root).any((n) => n.isRoot)) {
-      throw ArgumentError('No nodes other than the root may indicate `isRoot`');
-    }
-  }
-
-  /// Creates a [PackageGraph] given the [root] [PackageNode].
-  factory PackageGraph.fromRoot(PackageNode root) {
-    final allPackages = <String, PackageNode>{root.name: root};
-
-    void addDeps(PackageNode package) {
-      for (var dep in package.dependencies) {
-        if (allPackages.containsKey(dep.name)) continue;
-        allPackages[dep.name] = dep;
-        addDeps(dep);
-      }
-    }
-
-    addDeps(root);
-
-    return PackageGraph._(root, allPackages);
-  }
-
-  /// Creates a [PackageGraph] for the package whose top level directory lives
-  /// at [packagePath] (no trailing slash).
-  factory PackageGraph.forPath(String packagePath) {
-    /// Read in the pubspec file and parse it as yaml.
-    final pubspec = File(p.join(packagePath, 'pubspec.yaml'));
-    if (!pubspec.existsSync()) {
-      throw StateError(
-          'Unable to generate package graph, no `pubspec.yaml` found. '
-          'This program must be ran from the root directory of your package.');
-    }
-    final rootPubspec = _pubspecForPath(packagePath);
-    final rootPackageName = rootPubspec['name'] as String;
-
-    final packageLocations = _parsePackageLocations(packagePath)
-      ..remove(rootPackageName);
-
-    final dependencyTypes = _parseDependencyTypes(packagePath);
-
-    final nodes = <String, PackageNode>{};
-    final rootNode = PackageNode(
-        rootPackageName, packagePath, DependencyType.path,
-        isRoot: true);
-    nodes[rootPackageName] = rootNode;
-    for (final packageName in packageLocations.keys) {
-      if (packageName == rootPackageName) continue;
-      nodes[packageName] = PackageNode(packageName,
-          packageLocations[packageName], dependencyTypes[packageName],
-          isRoot: false);
-    }
-
-    rootNode.dependencies
-        .addAll(_depsFromYaml(rootPubspec, isRoot: true).map((n) => nodes[n]));
-
-    final packageDependencies = _parsePackageDependencies(packageLocations);
-    for (final packageName in packageDependencies.keys) {
-      nodes[packageName]
-          .dependencies
-          .addAll(packageDependencies[packageName].map((n) => nodes[n]));
-    }
-    return PackageGraph._(rootNode, nodes);
-  }
-
-  /// Creates a [PackageGraph] for the package in which you are currently
-  /// running.
-  factory PackageGraph.forThisPackage() => PackageGraph.forPath('./');
-
-  /// Shorthand to get a package by name.
-  PackageNode operator [](String packageName) => allPackages[packageName];
-
-  @override
-  String toString() {
-    var buffer = StringBuffer();
-    for (var package in allPackages.values) {
-      buffer.writeln('$package');
-    }
-    return buffer.toString();
-  }
-}
-
-/// A node in a [PackageGraph].
-class PackageNode {
-  /// The name of the package as listed in `pubspec.yaml`.
-  final String name;
-
-  /// The type of dependency being used to pull in this package.
-  ///
-  /// May be `null`.
-  final DependencyType dependencyType;
-
-  /// All the packages that this package directly depends on.
-  final List<PackageNode> dependencies = [];
-
-  /// The absolute path of the current version of this package.
-  ///
-  /// Paths are platform dependent.
-  final String path;
-
-  /// Whether this node is the [PackageGraph.root].
-  final bool isRoot;
-
-  PackageNode(this.name, String path, this.dependencyType, {bool isRoot})
-      : path = _toAbsolute(path),
-        isRoot = isRoot ?? false;
-
-  @override
-  String toString() => '''
-  $name:
-    type: $dependencyType
-    path: $path
-    dependencies: [${dependencies.map((d) => d.name).join(', ')}]''';
-
-  /// Converts [path] to a canonical absolute path, returns `null` if given
-  /// `null`.
-  static String _toAbsolute(String path) =>
-      (path == null) ? null : p.canonicalize(path);
-}
-
-/// Parse the `.packages` file and return a Map from package name to the file
-/// location for that package.
-Map<String, String> _parsePackageLocations(String rootPackagePath) {
-  var packagesFile = File(p.join(rootPackagePath, '.packages'));
-  if (!packagesFile.existsSync()) {
-    throw StateError('Unable to generate package graph, no `.packages` found. '
-        'This program must be ran from the root directory of your package.');
-  }
-  var packageLocations = <String, String>{};
-  for (final line in packagesFile.readAsLinesSync().skip(1)) {
-    var firstColon = line.indexOf(':');
-    var name = line.substring(0, firstColon);
-    assert(line.endsWith('lib/'));
-    // Start after package_name:, and strip out trailing 'lib/'.
-    var uriString = line.substring(firstColon + 1, line.length - 4);
-    // Strip the trailing slash, if present.
-    if (uriString.endsWith('/')) {
-      uriString = uriString.substring(0, uriString.length - 1);
-    }
-    var uri = Uri.tryParse(uriString) ?? Uri.file(uriString);
-    if (!uri.isAbsolute) {
-      uri = p.toUri(p.join(rootPackagePath, uri.path));
-    }
-    packageLocations[name] = uri.toFilePath(windows: Platform.isWindows);
-  }
-  return packageLocations;
-}
-
-/// The type of dependency being used. This dictates how the package should be
-/// watched for changes.
-enum DependencyType { github, path, hosted }
-
-/// Parse the `pubspec.lock` file and return a Map from package name to the type
-/// of dependency.
-Map<String, DependencyType> _parseDependencyTypes(String rootPackagePath) {
-  final pubspecLock = File(p.join(rootPackagePath, 'pubspec.lock'));
-  if (!pubspecLock.existsSync()) {
-    throw StateError(
-        'Unable to generate package graph, no `pubspec.lock` found. '
-        'This program must be ran from the root directory of your package.');
-  }
-  final dependencyTypes = <String, DependencyType>{};
-  final dependencies = loadYaml(pubspecLock.readAsStringSync()) as YamlMap;
-  for (final packageName in dependencies['packages'].keys) {
-    final source = dependencies['packages'][packageName]['source'];
-    dependencyTypes[packageName as String] =
-        _dependencyTypeFromSource(source as String);
-  }
-  return dependencyTypes;
-}
-
-DependencyType _dependencyTypeFromSource(String source) {
-  switch (source) {
-    case 'git':
-      return DependencyType.github;
-    case 'hosted':
-      return DependencyType.hosted;
-    case 'path':
-    case 'sdk': // Until Flutter supports another type, assum same as path.
-      return DependencyType.path;
-  }
-  throw ArgumentError('Unable to determine dependency type:\n$source');
-}
-
-/// Read the pubspec for each package in [packageLocations] and finds it's
-/// dependencies.
-Map<String, Set<String>> _parsePackageDependencies(
-    Map<String, String> packageLocations) {
-  final dependencies = <String, Set<String>>{};
-  for (final packageName in packageLocations.keys) {
-    final pubspec = _pubspecForPath(packageLocations[packageName]);
-    dependencies[packageName] = _depsFromYaml(pubspec);
-  }
-  return dependencies;
-}
-
-/// Gets the deps from a yaml file, taking into account dependency_overrides.
-Set<String> _depsFromYaml(YamlMap yaml, {bool isRoot = false}) {
-  var deps = <String>{}..addAll(_stringKeys(yaml['dependencies'] as Map));
-  if (isRoot) {
-    deps
-      ..addAll(_stringKeys(yaml['dev_dependencies'] as Map))
-      ..addAll(_stringKeys(yaml['dependency_overrides'] as Map));
-  }
-  return deps;
-}
-
-Iterable<String> _stringKeys(Map m) =>
-    m == null ? const [] : m.keys.cast<String>();
-
-/// Should point to the top level directory for the package.
-YamlMap _pubspecForPath(String absolutePath) {
-  var pubspecPath = p.join(absolutePath, 'pubspec.yaml');
-  var pubspec = File(pubspecPath);
-  if (!pubspec.existsSync()) {
-    throw StateError(
-        'Unable to generate package graph, no `$pubspecPath` found.');
-  }
-  return loadYaml(pubspec.readAsStringSync()) as YamlMap;
-}
diff --git a/build_runner_core/lib/src/package_graph/target_graph.dart b/build_runner_core/lib/src/package_graph/target_graph.dart
deleted file mode 100644
index d66b158..0000000
--- a/build_runner_core/lib/src/package_graph/target_graph.dart
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:glob/glob.dart';
-
-import '../generate/input_matcher.dart';
-import 'package_graph.dart';
-
-/// Like a [PackageGraph] but packages are further broken down into modules
-/// based on build config.
-class TargetGraph {
-  /// All [TargetNode]s indexed by `"$packageName:$targetName"`.
-  final Map<String, TargetNode> allModules;
-
-  /// All [TargetNode]s by package name.
-  final Map<String, List<TargetNode>> modulesByPackage;
-
-  /// The [BuildConfig] of the root package.
-  final BuildConfig rootPackageConfig;
-
-  TargetGraph._(this.allModules, this.modulesByPackage, this.rootPackageConfig);
-
-  static Future<TargetGraph> forPackageGraph(PackageGraph packageGraph,
-      {Map<String, BuildConfig> overrideBuildConfig,
-      List<String> defaultRootPackageWhitelist}) async {
-    overrideBuildConfig ??= const {};
-    final modulesByKey = <String, TargetNode>{};
-    final modulesByPackage = <String, List<TargetNode>>{};
-    BuildConfig rootPackageConfig;
-    for (final package in packageGraph.allPackages.values) {
-      final config = overrideBuildConfig[package.name] ??
-          await _packageBuildConfig(package);
-      List<String> defaultInclude;
-      if (package.isRoot) {
-        defaultInclude = defaultRootPackageWhitelist;
-        rootPackageConfig = config;
-      } else if (package.name == r'$sdk') {
-        defaultInclude = const [
-          'lib/dev_compiler/**.js',
-          'lib/_internal/**.sum',
-        ];
-      } else {
-        defaultInclude = const ['lib/**'];
-      }
-      final nodes = config.buildTargets.values.map((target) =>
-          TargetNode(target, package, defaultInclude: defaultInclude));
-      for (final node in nodes) {
-        modulesByKey[node.target.key] = node;
-        modulesByPackage.putIfAbsent(node.target.package, () => []).add(node);
-      }
-    }
-    return TargetGraph._(modulesByKey, modulesByPackage, rootPackageConfig);
-  }
-
-  /// Whether or not [id] is included in the sources of any target in the graph.
-  bool anyMatchesAsset(AssetId id) =>
-      modulesByPackage[id.package]?.any((t) => t.matchesSource(id)) ?? false;
-}
-
-class TargetNode {
-  final BuildTarget target;
-  final PackageNode package;
-
-  List<Glob> get sourceIncludes => _sourcesMatcher.includeGlobs;
-  final InputMatcher _sourcesMatcher;
-
-  TargetNode(this.target, this.package, {List<String> defaultInclude})
-      : _sourcesMatcher =
-            InputMatcher(target.sources, defaultInclude: defaultInclude);
-
-  bool excludesSource(AssetId id) => _sourcesMatcher.excludes(id);
-
-  bool matchesSource(AssetId id) => _sourcesMatcher.matches(id);
-
-  @override
-  String toString() => target.key;
-}
-
-Future<BuildConfig> _packageBuildConfig(PackageNode package) async {
-  final dependencyNames = package.dependencies.map((n) => n.name);
-  if (package.path == null) {
-    return BuildConfig.useDefault(package.name, dependencyNames);
-  }
-  try {
-    return await BuildConfig.fromBuildConfigDir(
-        package.name, dependencyNames, package.path);
-  } on ArgumentError catch (e) {
-    throw BuildConfigParseException(package.name, e);
-  }
-}
-
-class BuildConfigParseException implements Exception {
-  final String packageName;
-  final dynamic exception;
-
-  BuildConfigParseException(this.packageName, this.exception);
-}
diff --git a/build_runner_core/lib/src/performance_tracking/performance_tracking_resolvers.dart b/build_runner_core/lib/src/performance_tracking/performance_tracking_resolvers.dart
deleted file mode 100644
index 0155e55..0000000
--- a/build_runner_core/lib/src/performance_tracking/performance_tracking_resolvers.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-
-import '../generate/performance_tracker.dart';
-
-class PerformanceTrackingResolvers implements Resolvers {
-  final Resolvers _delegate;
-  final BuilderActionTracker _tracker;
-
-  PerformanceTrackingResolvers(this._delegate, this._tracker);
-
-  @override
-  Future<ReleasableResolver> get(BuildStep buildStep) =>
-      _tracker.trackStage('ResolverGet', () => _delegate.get(buildStep));
-
-  @override
-  void reset() => _delegate.reset();
-}
diff --git a/build_runner_core/lib/src/util/async.dart b/build_runner_core/lib/src/util/async.dart
deleted file mode 100644
index 75d755b..0000000
--- a/build_runner_core/lib/src/util/async.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-/// Invokes [callback] and returns the result as soon as possible. This will
-/// happen synchronously if [value] is available.
-FutureOr<S> doAfter<T, S>(
-    FutureOr<T> value, FutureOr<S> Function(T value) callback) {
-  if (value is Future<T>) {
-    return value.then(callback);
-  } else {
-    return callback(value as T);
-  }
-}
-
-/// Converts [value] to a [Future] if it is not already.
-Future<T> toFuture<T>(FutureOr<T> value) =>
-    value is Future<T> ? value : Future.value(value);
diff --git a/build_runner_core/lib/src/util/build_dirs.dart b/build_runner_core/lib/src/util/build_dirs.dart
deleted file mode 100644
index 1301186..0000000
--- a/build_runner_core/lib/src/util/build_dirs.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-
-import '../generate/options.dart';
-import '../generate/phase.dart';
-
-/// Returns whether or not [id] should be built based upon [buildDirs],
-/// [phase], and optional [buildFilters].
-///
-/// The logic for this is as follows:
-///
-/// - If any [buildFilters] are supplied, then this only returns `true` if [id]
-///   explicitly matches one of the filters.
-/// - If no [buildFilters] are supplied, then the old behavior applies - all
-///   build to source builders and all files under `lib` of all packages are
-///   always built.
-/// - Regardless of the [buildFilters] setting, if [buildDirs] is supplied then
-///   `id.path` must start with one of the specified directory names.
-bool shouldBuildForDirs(AssetId id, Set<String> buildDirs,
-    Set<BuildFilter> buildFilters, BuildPhase phase) {
-  buildFilters ??= {};
-  if (buildFilters.isEmpty) {
-    if (!phase.hideOutput) return true;
-
-    if (id.path.startsWith('lib/')) return true;
-  } else {
-    if (!buildFilters.any((f) => f.matches(id))) {
-      return false;
-    }
-  }
-
-  if (buildDirs.isEmpty) return true;
-
-  return id.path.startsWith('lib/') || buildDirs.any(id.path.startsWith);
-}
diff --git a/build_runner_core/lib/src/util/clock.dart b/build_runner_core/lib/src/util/clock.dart
deleted file mode 100644
index 5b2db75..0000000
--- a/build_runner_core/lib/src/util/clock.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-/// A function that returns the current [DateTime].
-typedef _Clock = DateTime Function();
-DateTime _defaultClock() => DateTime.now();
-
-/// Returns the current [DateTime].
-///
-/// May be overridden for tests using [scopeClock].
-DateTime now() => (Zone.current[_Clock] as _Clock ?? _defaultClock)();
-
-/// Runs [f], with [clock] scoped whenever [now] is called.
-T scopeClock<T>(DateTime Function() clock, T Function() f) =>
-    runZoned(f, zoneValues: {_Clock: clock});
diff --git a/build_runner_core/lib/src/util/constants.dart b/build_runner_core/lib/src/util/constants.dart
deleted file mode 100644
index eb1d073..0000000
--- a/build_runner_core/lib/src/util/constants.dart
+++ /dev/null
@@ -1,87 +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:convert';
-import 'dart:io';
-
-import 'package:crypto/crypto.dart';
-import 'package:path/path.dart' as p;
-
-/// Relative path to the asset graph from the root package dir.
-final String assetGraphPath = assetGraphPathFor(_scriptPath);
-
-/// Relative path to the asset graph for a build script at [path]
-String assetGraphPathFor(String path) =>
-    '$cacheDir/${_scriptHashFor(path)}/asset_graph.json';
-
-/// Relative path to the directory which holds serialized versions of errors
-/// reported during previous builds.
-final errorCachePath =
-    p.url.join(cacheDir, _scriptHashFor(_scriptPath), 'error_cache');
-
-final String _scriptPath = Platform.script.scheme == 'file'
-    ? p.url.joinAll(
-        p.split(p.relative(Platform.script.toFilePath(), from: p.current)))
-    : Platform.script.path;
-
-/// Directory containing automatically generated build entrypoints.
-///
-/// Files in this directory must be read to do build script invalidation.
-const entryPointDir = '$cacheDir/entrypoint';
-
-/// The directory to which hidden assets will be written.
-String get generatedOutputDirectory => '$cacheDir/$_generatedOutputDirectory';
-
-/// Locks the generated directory name for the duration of this process.
-///
-/// This should be invoked before any builds start.
-void lockGeneratedOutputDirectory() => _generatedOutputDirectoryIsLocked = true;
-
-/// The default generated dir name. Can be modified with
-/// [overrideGeneratedOutputDirectory].
-String _generatedOutputDirectory = 'generated';
-
-/// Whether or not the [generatedOutputDirectory] is locked. This must be `true`
-/// before you can access [generatedOutputDirectory];
-bool _generatedOutputDirectoryIsLocked = false;
-
-/// Overrides the generated directory name.
-///
-/// This is interpreted as a relative path under the [cacheDir].
-void overrideGeneratedOutputDirectory(String path) {
-  if (_generatedOutputDirectory != 'generated') {
-    throw StateError('You can only override the generated dir once.');
-  } else if (_generatedOutputDirectoryIsLocked) {
-    throw StateError(
-        'Attempted to override the generated dir after it was locked.');
-  } else if (!p.isRelative(path)) {
-    throw StateError('Only relative paths are accepted for the generated dir '
-        'but got `$path`.');
-  }
-  _generatedOutputDirectory = path;
-}
-
-/// Relative path to the cache directory from the root package dir.
-const String cacheDir = '.dart_tool/build';
-
-/// Returns a hash for a given Dart script path.
-///
-/// Normalizes between snapshot and Dart source file paths so they give the same
-/// hash.
-String _scriptHashFor(String path) => md5
-    .convert(utf8.encode(
-        path.endsWith('.snapshot') ? path.substring(0, path.length - 9) : path))
-    .toString();
-
-/// The name of the pub binary on the current platform.
-final pubBinary = p.join(sdkBin, Platform.isWindows ? 'pub.bat' : 'pub');
-
-/// The path to the sdk bin directory on the current platform.
-final sdkBin = p.join(sdkPath, 'bin');
-
-/// The path to the sdk on the current platform.
-final sdkPath = p.dirname(p.dirname(Platform.resolvedExecutable));
-
-/// The maximum number of concurrent actions to run per build phase.
-const buildPhasePoolSize = 16;
diff --git a/build_runner_core/lib/src/util/hash.dart b/build_runner_core/lib/src/util/hash.dart
deleted file mode 100644
index d8539e2..0000000
--- a/build_runner_core/lib/src/util/hash.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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 hashCombine(int hash, int value) {
-  hash = 0x1fffffff & (hash + value);
-  hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
-  return hash ^ (hash >> 6);
-}
-
-int hashComplete(int hash) {
-  hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
-  hash = hash ^ (hash >> 11);
-  return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
-}
diff --git a/build_runner_core/lib/src/util/sdk_version_match.dart b/build_runner_core/lib/src/util/sdk_version_match.dart
deleted file mode 100644
index f584862..0000000
--- a/build_runner_core/lib/src/util/sdk_version_match.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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.
-
-/// Checks whether [thisVersion] and [thatVersion] have the same semver
-/// identifier without extra platform specific information.
-bool isSameSdkVersion(String thisVersion, String thatVersion) =>
-    thisVersion?.split(' ')?.first == thatVersion?.split(' ')?.first;
diff --git a/build_runner_core/lib/src/validation/config_validation.dart b/build_runner_core/lib/src/validation/config_validation.dart
deleted file mode 100644
index 2ec9c7e..0000000
--- a/build_runner_core/lib/src/validation/config_validation.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build_config/build_config.dart';
-import 'package:logging/logging.dart';
-
-import '../package_graph/apply_builders.dart';
-
-/// Checks that all configuration is for valid builder keys.
-void validateBuilderConfig(
-    Iterable<BuilderApplication> builders,
-    BuildConfig rootPackageConfig,
-    Map<String, Map<String, dynamic>> builderConfigOverrides,
-    Logger logger) {
-  final builderKeys = builders.map((b) => b.builderKey).toSet();
-  for (final key in builderConfigOverrides.keys) {
-    if (!builderKeys.contains(key)) {
-      logger.warning('Overriding configuration for `$key` but this is not a '
-          'known Builder');
-    }
-  }
-  for (final target in rootPackageConfig.buildTargets.values) {
-    for (final key in target.builders.keys) {
-      if (!builderKeys.contains(key)) {
-        logger.warning('Configuring `$key` in target `${target.key}` but this '
-            'is not a known Builder');
-      }
-    }
-  }
-  for (final key in rootPackageConfig.globalOptions.keys) {
-    if (!builderKeys.contains(key)) {
-      logger.warning('Configuring `$key` in global options but this is not a '
-          'known Builder');
-    }
-  }
-}
diff --git a/build_runner_core/mono_pkg.yaml b/build_runner_core/mono_pkg.yaml
deleted file mode 100644
index 74ca9f7..0000000
--- a/build_runner_core/mono_pkg.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-dart:
-  - 2.6.0
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-      - dartfmt: sdk
-      - dartanalyzer: --fatal-infos --fatal-warnings .
-      dart: dev
-    - dartanalyzer: --fatal-warnings .
-      dart: 2.6.0
-  - unit_test:
-    - test:
-      os:
-        - linux
-        - windows
diff --git a/build_runner_core/pubspec.yaml b/build_runner_core/pubspec.yaml
deleted file mode 100644
index e87a441..0000000
--- a/build_runner_core/pubspec.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: build_runner_core
-version: 4.4.0
-description: Core tools to write binaries that run builders.
-homepage: https://github.com/dart-lang/build/tree/master/build_runner_core
-
-environment:
-  sdk: ">=2.6.0 <3.0.0"
-
-dependencies:
-  async: ">=1.13.3 <3.0.0"
-  build: ">=1.2.0 <1.3.0"
-  build_config: ">=0.4.2 <0.4.3"
-  build_resolvers: ^1.0.0
-  collection: ^1.14.0
-  convert: ^2.0.1
-  crypto: ">=0.9.2 <3.0.0"
-  glob: ^1.1.0
-  graphs: ^0.2.0
-  json_annotation: '>=1.0.0 <4.0.0'
-  logging: ^0.11.2
-  meta: ^1.1.0
-  path: ^1.1.0
-  pedantic: ^1.0.0
-  pool: ^1.0.0
-  timing: ^0.1.1
-  watcher: ^0.9.7
-  yaml: ^2.1.0
-
-dev_dependencies:
-  build_test: ^0.10.0
-  package_resolver: ^1.0.2
-  source_gen: ^0.9.0
-  test: ^1.0.0
-  test_descriptor: ^1.0.0
-  test_process: ^1.0.0
-  _test_common:
-    path: ../_test_common
diff --git a/build_test/BUILD.gn b/build_test/BUILD.gn
deleted file mode 100644
index f490fa0..0000000
--- a/build_test/BUILD.gn
+++ /dev/null
@@ -1,32 +0,0 @@
-# This file is generated by importer.py for build_test-0.10.12+1
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_test") {
-  package_name = "build_test"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/pedantic",
-    "//third_party/dart-pkg/pub/matcher",
-    "//third_party/dart-pkg/pub/glob",
-    "//third_party/dart-pkg/pub/watcher",
-    "//third_party/dart-pkg/pub/test_core",
-    "//third_party/dart-pkg/pub/package_resolver",
-    "//third_party/dart-pkg/pub/path",
-    "//third_party/dart-pkg/pub/logging",
-    "//third_party/dart-pkg/pub/crypto",
-    "//third_party/dart-pkg/pub/stream_transform",
-    "//third_party/dart-pkg/pub/html",
-    "//third_party/dart-pkg/pub/build",
-    "//third_party/dart-pkg/pub/build_resolvers",
-    "//third_party/dart-pkg/pub/test",
-    "//third_party/dart-pkg/pub/async",
-    "//third_party/dart-pkg/pub/build_config",
-  ]
-}
diff --git a/build_test/CHANGELOG.md b/build_test/CHANGELOG.md
deleted file mode 100644
index f0d57ab..0000000
--- a/build_test/CHANGELOG.md
+++ /dev/null
@@ -1,426 +0,0 @@
-## 0.10.12+1
-
-- Allow the latest test_core package (`0.3.x`).
-
-## 0.10.12
-
-- Fix a bug with the `resolve*` apis where they would leak unhandled async
-  errors to client code if the provided action callback threw an error.
-
-## 0.10.11
-
-- Add support for the new `$package$` placeholder.
-
-### Potentially Breaking Change
-
-- Only add the non-lib placeholders when a root package is specified
-  - Infer the root package when there is only one package in the sources
-  - This is being released as a non-breaking change because the only expected
-    use cases already would have been broken - `findAssets` calls already
-    required a root package.
-
-## 0.10.10
-
-- Allow reading of assets written from the same build step.
-  - This mirrors the latest behavior in build_runner_core.
-- Require SDK version `2.6.0` to enable extension methods.
-
-## 0.10.9+1
-
-- Fix the `DebugTestBuilder` on windows.
-- Fix `PackageAssetReader` on windows.
-
-## 0.10.9
-
-- Allow tracking of reported unused assets in `testBuilder` calls with the
-  `reportUnusedAssetsForInput(AssetId input, Iterable<AssetId> unused)`
-  callback.
-
-## 0.10.8
-
-- Allow a custom AssetReader to be passed to `testBuilder`. This will be used
-  as a fallback for any sources that don't exist in the `sourceAssets` map.
-
-## 0.10.7+3
-
-- Handle the case where the root package in a `PackageAssetReader` is a fake
-  package.
-
-## 0.10.7+2
-
-- Avoid throwing for missing files from `PackageAssetReader.canRead`.
-
-## 0.10.7+1
-
-- Allow `build_config` `0.4.x`.
-
-## 0.10.7
-
-- Support the latest version of `package:html`.
-- Only generate bootstrap scripts for supported platforms based on `TestOn`
-  annotations.
-
-## 0.10.6
-
-- Allow build_resolvers version `1.0.0`.
-
-## 0.10.5
-
-- Improve error messages for unresolvable URIs in the PackageAssetReader.
-
-## 0.10.4
-
-- Allow using `PackageAssetReader` when the current working directory is not the
-  root package directory as long as it uses a pub layout.
-
-## 0.10.3+4
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 0.10.3+3
-
-- Increased the upper bound for `package:analyzer` to '<0.34.0'.
-
-## 0.10.3+2
-
-- Declare support for `package:build` version 1.0.0.
-
-## 0.10.3+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.10.3
-
-- Require test version ^0.12.42 and use `TypeMatcher`.
-- Improve performance of test methods which use a `Resolver` by keeping a cached
-  instance of `AnalyzerResolvers`.
-
-## 0.10.2+4
-
-- Allow the latest build_config.
-
-## 0.10.2+3
-
-- Remove package:build_barback dependency, and use public apis from package:test
-  to directly do the bootstrapping instead of wrapping the transformer.
-
-## 0.10.2+2
-
-- Avoid looking for files from `Uri.path` paths.
-
-## 0.10.2+1
-
-- Add back an implementation of `findAssets` in `PackageAssetReader`.
-
-## 0.10.2
-
-- Added a `DebugIndexBuilder`, which by default generates a `test/index.html`
-  with links to debug tests in your `test/**_test.dart` folder, linking to the
-  generated `*_test.debug.html` files. **NOTE**: This only works for web-based
-  tests.
-- Fix `PackageAssetReader` when running with a package map pointing to a
-  "packages" directory structure, as is generated by `build_runner`. Drop
-  support for a broken `findAssets` implementation.
-
-## 0.10.1+1
-
-- Replace `BarbackResolvers` with `AnalyzerResolvers` from `build_resolvers` by
-  default.
-
-## 0.10.1
-
-- Allow overriding the `Resolvers` used for `resolve*` utilities.
-- Bug Fix: Don't call the `action` multiple times when there are multiple
-  sources passed to `resolve*`.
-
-## 0.10.0
-
-- Added automatic generation of `.debug.html` files for all tests, which can
-  be loaded in the browser to directly run tests and debug them without going
-  through the package:test runner.
-- Update to package:build version `0.12.0`.
-- Removed `CopyBuilder` in favor of `TestBuilder` which takes closures to
-  change behavior rather than adding configuration for every possible
-  modification.
-- Added support for the special placeholder `{$lib/$test/$web}` assets
-  supported by the `build_runner` and `bazel_codegen` implementations of
-  `package:build`. For an example see `test/test_builder_test.dart`. Note that
-  this is technically a **BREAKING CHANGE**, as additional inputs will be
-  matched for overzealous builders (like `TestBuilder`).
-- Added `resolverFor` as an optional parameter to `resolveSources`. By default
-  a `Resolver` is returned for the _first_ asset provided; to modify that the
-  name of another asset may be provided. This is a **BREAKING CHANGE**, as
-  previously the last asset was used.
-
-## 0.9.4
-
-- Added `InMemoryAssetReader.shareAssetCache` constructor. This is useful for the
-  case where the reader should be kept up to date as assets are written through
-  a writer.
-- Added `buildInputs` stream to `CopyBuilder` which emits an event for each
-  `BuildStep.inputId` at the top of the `build` method.
-- `CopyBuilder` automatically skips the placeholder files (any file ending in
-  `$`). This is technically breaking but should not affect any real users and is
-  not being released as a breaking change.
-- Changed `TestBootstrapBuilder` to only target `_test.dart` files.
-
-## 0.9.3
-
-- Added `resolveSources`, a way to resolve multiple libraries for testing,
-  including any combination of fake files (in-memory, created in the test) and
-  real ones (from on-disk packages):
-
-```dart
-test('multiple assets, some mock, some on disk', () async {
-  final real = 'build_test|test/_files/example_lib.dart';
-  final mock = 'build_test|test/_files/not_really_here.dart';
-  final library = await resolveSources(
-    {
-      real: useAssetReader,
-      mock: r'''
-        // This is a fake library that we're mocking.
-        library example;
-
-        // This is a real on-disk library we are using.
-        import 'example_lib.dart';
-
-        class ExamplePrime extends Example {}
-      ''',
-    },
-    (resolver) => resolver.findLibraryByName('example'),
-  );
-  final type = library.getType('ExamplePrime');
-  expect(type, isNotNull);
-  expect(type.supertype.name, 'Example');
-});
-```
-
-## 0.9.2
-
-- Add `inputExtension` argument to `CopyBuilder`. When used the builder with
-  throw if any assets are provided that don't match the input extension.
-
-## 0.9.1
-
-- Allow `build_barback` version `0.5.x`. The breaking behavior change should not
-  impact test uses that don't already have a version constraint on that package.
-
-## 0.9.0
-
-- Added the `TestBootstrapBuilder` under the `builder.dart` library. This can
-  be used to bootstrap tests similar to the `test/pub_serve` Transformer.
-  - **Known Issue**: Custom html files are not supported.
-- **Breaking**: All `AssetReader#findAssets` implementations now return a
-  `Stream<AssetId>` to match the latest `build` package.
-- **Breaking**: The `DatedValue`, `DatedString`, and `DatedBytes` apis are now
-  gone, since timestamps are no longer used by package:build. Instead the
-  `InMemoryAssetReader` and other apis take a `Map<AssetId, dynamic>`, and will
-  automatically convert any `String` values into  `List<int>` values.
-- **Breaking**: The `outputs` map of `testBuilder` works a little bit
-  differently due to the removal of `DatedValue` and `DatedString`.
-  * If a value provided is a `String`, then the asset is by default decoded
-    using UTF8, and matched against the string.
-  * If the value is a `matcher`, it will match againt the actual bytes of the
-    asset (in `List<int>` form).
-  * A new matcher was added, `decodedMatches`, which can be combined with other
-    matchers to match against the string contents. For example, to match a
-    string containing a substring, you would do
-    `decodedMatches(contains('some substring'))`.
-
-## 0.8.0
-
-- `InMemoryAssetReader`, `MultiAssetReader`, `StubAssetReader` and
-  `PackageAssetReader` now implement the `MultiPackageAssetReader` interface.
-- `testBuilder` now supports `Builder`s that call `findAssets` in non-root
-  packages.
-- Added a `GlobbingBuilder` which globs files in a package.
-- Added the `RecordingAssetReader` interface, which adds the
-  `Iterable<AssetId> get assetsRead` getter.
-- `InMemoryAssetReader` now implements `RecordingAssetReader`.
-- **Breaking**: The `MultiAssetReader` now requires all its wrapped readers to
-  implement the `MultiPackageAssetReader` interface.
-  - This should not affect most users, since all readers provided by this
-    package now implement that interface.
-
-## 0.7.1
-
-- Add `mapAssetIds` argument to `checkOutputs` for cases where the logical asset
-  location recorded by the builder does not match the written location.
-
-- Add `recordLogs`, a top-level function that invokes `scopeLog` and captures
-  the resulting `Stream<LogRecord>` for testing. Can be used with the provided
-  `anyLogOf`, `infoLogOf`, `warningLogOf`, `severeLogOf` matchers in order to
-  test a build process:
-
-```dart
-test('should log "uh oh!"', () async {
-  final logs = recordLogs(() => runBuilder());
-  expect(logs, emitsInOrder([
-    anyLogOf('uh oh!'),
-  ]);
-});
-```
-
-- Add the constructors `forPackages` and `forPackageRoot` to
-  `PackageAssetReader` - these are convenience constructors for pointing to a
-  small set of packages (fake or real) for testing purposes. For example:
-
-```dart
-test('should resolve multiple libraries', () async {
-  reader = new PackageAssetReader.forPackages({
-    'example_a': '_libs/example_a',
-    'example_b': '_libs/example_b',
-  });
-  expect(await reader.canRead(fileFromExampleLibA), isTrue);
-  expect(await reader.canRead(fileFromExampleLibB), isTrue);
-  expect(await reader.canRead(fileFromExampleLibC), isFalse);
-});
-```
-
-## 0.7.0+1
-
-- Switch to a typedef from function type syntax for compatibility with older
-  SDKs.
-
-## 0.7.0
-
-- **Breaking**: `resolveSource` and `resolveAsset` now take an `action` to
-  perform with the Resolver instance.
-
-## 0.6.4+1
-
-- Allow `package:build_barback` v0.4.x
-
-## 0.6.4
-
-- Allow `package:build` v0.10.x
-- `AssetReader` implementations always return `Future` from `canRead`
-
-## 0.6.3
-
-- Added `resolveAsset`, which is similar to `resolveSource` but specifies a
-  real asset that lives on the file system. For example, to resolve the main
-  library of `package:collection`:
-
-```dart
-var pkgCollection = new AssetId('collection', 'lib/collection.dart');
-var resolver = await resolveAsset(pkgCollection);
-// ...
-```
-
-- Supports `package:build_barback >=0.2.0 <0.4.0`.
-
-## 0.6.2
-
-- Internal version bump.
-
-## 0.6.1
-
-- Declare an output extension in `_ResolveSourceBuilder` so it is not skipped
-
-## 0.6.0
-
-- Support build 0.9.0
-  - Rename `hasInput` to `canRead` in `AssetReader` implementations
-  - Replace `declareOutputs` with `buildExtensions` in `Builder` implementations
-- **Breaking** `CopyBuilder` no longer has an `outputPackage` field since outputs
-  can only ever be in the same package as inputs.
-
-## 0.5.2
-
-- Add `MultiAssetReader` to the public API.
-
-## 0.5.1
-
-- Add `PackageAssetReader`, a standalone asset reader that uses a
-  `PackageResolver` to map an `AssetId` to a location on disk.
-- Add `resolveSource`, a top-level function that can resolve arbitrary Dart
-  source code. This can be useful in testing your own code that uses a
-  `Resolver` to do type checks.
-
-## 0.5.0
-
-- Add `findAssets` implementations to StubAssetReader an InMemoryAssetReader
-- **BREAKING**: InMemoryAssetReader constructor uses named optional parameters
-
-## 0.4.1
-
-- Make `scopeLog` visible so tests can be run with an available `log` without
-  going through runBuilder.
-
-## 0.4.0+1
-
-- Bug Fix: Correctly identify missing outputs in testBuilder
-
-## 0.4.0
-
-Updates to work with `build` version 0.7.0.
-
-### New Features
-- The `testBuilder` method now accepts `List<int>` values for both
-  `sourceAssets` and `outputs`.
-- The `checkOutputs` method is now public.
-
-### Breaking Changes
-- The `testBuilder` method now requires a `RecordingAssetWriter` instead of
-  just an `AssetWriter` for the `writer` parameter.
-- If a `Matcher` is provided as a value in `outputs`, then it will match against
-  the same value that was written. For example if your builder uses
-  `writeAsString` then it will match against that string. If you use
-  `writeAsBytes` then it will match against those bytes. It will not
-  automatically convert to/from bytes and strings.
-- Deleted the `makeAsset` and `makeAssets` methods. There is no more `Asset`
-  class so these don't really have any value any more.
-- The signature of `addAssets` has changed to
-  `void addAssets(Map<AssetId, dynamic> assets, InMemoryAssetWriter writer)`.
-  Values of the map may be either `String` or `List<int>`.
-- `InMemoryAssetReader#assets` and `InMemoryAssetWriter#assets` have changed to
-  a type of `Map<AssetId, DatedValue>` from a type of
-  `Map<AssetId, DatedString>`. `DatedValue` has both a `stringValue` and
-  `bytesValue` getter.
-- `InMemoryAssetReader` and `InMemoryAssetWriter` have been updated to implement
-  the new `AssetReader` and `AssetWriter` interfaces (see the `build` package
-  CHANGELOG for more details).
-- `InMemoryAssetReader#cacheAsset` has been changed to two separate methods,
-  `void cacheStringAsset(AssetId id, String contents)` and
-  `void cacheBytesAsset(AssetId id, List<int> bytes)`.
-- The `equalsAsset` matcher has been removed, since there is no more `Asset`
-  class.
-
-## 0.3.1
-
-- Additional capabilities in testBuilder:
-  - Filter sourceAssets to inputs with `isInput`
-  - Get log records
-  - Ignore output expectations when `outputs` is null
-  - Use a custom `writer`
-
-## 0.3.0
-
-- **BREAKING** removed testPhases utility. Tests should be using testBuilder
-- Drop dependency on build_runner package
-
-## 0.2.1
-
-- Support the package split into build/build_runner/build_barback
-- Expose additional test utilities that used to be internal to build
-
-## 0.2.0
-
-- Upgrade build package to 0.4.0
-- Delete now unnecessary `GenericBuilderTransformer` and use
-  `BuilderTransformer` in the tests.
-
-## 0.1.2
-
-- Add `logLevel` and `onLog` named args to `testPhases`. These can be used
-  to test your log messages, see `test/utils_test.dart` for an example.
-
-## 0.1.1
-
-- Allow String or Matcher for expected output values in `testPhases`.
-
-## 0.1.0
-
-- Initial version, exposes many basic utilities for testing `Builder`s using in
-  memory data structures. Most notably, the `testPhases` method.
diff --git a/build_test/LICENSE b/build_test/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/build_test/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_test/README.md b/build_test/README.md
deleted file mode 100644
index 148cb82..0000000
--- a/build_test/README.md
+++ /dev/null
@@ -1,140 +0,0 @@
-<p align="center">
-  Testing utilities for users of <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
-  <br>
-  <a href="https://travis-ci.org/dart-lang/build">
-    <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
-  </a>
-  <a href="https://github.com/dart-lang/build/labels/package%3A%20build_test">
-    <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_test.svg" alt="Issues related to build_test" />
-  </a>
-  <a href="https://pub.dev/packages/build_test">
-    <img src="https://img.shields.io/pub/v/build_test.svg" alt="Pub Package Version" />
-  </a>
-  <a href="https://pub.dev/documentation/build_test/latest">
-    <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
-  </a>
-  <a href="https://gitter.im/dart-lang/build">
-    <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
-  </a>
-</p>
-
-## Installation
-
-This package is intended to only be as a [development dependency][] for users
-of [`package:build`][], and should not be used in any production code. Simply
-add to your `pubspec.yaml`:
-
-```yaml
-dev_dependencies:
-  build_test:
-```
-
-## Running tests
-
-To run tests, you should go through the `pub run build_runner test` command.
-This will compile all your tests to a temp directory and run them using
-`pub run test`. If you would like to see the output directory, you can use the
-`--output=<dir>` option to force the output to go to a specific place.
-
-### Forwarding additional args to `pub run test`
-
-It is very common to need to pass some arguments through to the eventual call
-to `pub run test`. To do this, add all those args after an empty `--` arg.
-
-For example, to run all chrome platform tests you would do
-`pub run build_runner test -- -p chrome`.
-
-## Debugging web tests
-
-This package will automatically create `*.debug.html` files next to all your
-`*_test.dart` files, which can be loaded in a browser from the normal
-development server (`pub run build_runner serve`).
-
-**Note:** In order to run the tests this way, you will need to configure them
-to be compiled (by default we only compile `*.browser_test.dart` files). You
-can do this in your build.yaml file, with something like the following:
-
-```yaml
-targets:
-  $default:
-    builders:
-      build_web_compilers|entrypoint:
-        generate_for:
-        - test/**_test.dart
-        - web/**.dart
-```
-
-You may also view an index of links to every `*.debug.html` file by navigating
-to `http://localhost:8081` (or wherever your `test` folder is being served).
-
-## Writing tests for your custom Builder
-
-In addition to assiting in running normal tests, this package provides some
-utilities for testing your custom `Builder` classes.
-
-_See the `test` folder in the `build` package for more examples_.
-
-### Run a `Builder` within a test environment
-
-Using [`testBuilder`][api:testBuilder], you can run a functional test of a
-`Builder`, including feeding specific assets, and more. It automatically
-creates an in-memory representation of various utility classes.
-
-### Exposing actual package sources to `testBuilder`
-
-You can expose real package sources to the builder in addition to your in
-memory sources, by passing a `PackageAssetReader` to the `reader` parameter:
-
-```dart
-testBuilder(yourBuilder, {}/* test assets here */,
-    reader: await PackageAssetReader.currentIsolate());
-```
-
-You can pass any custom AssetReader here, which will be used as a fallback
-for any source not defined in the source assets map.
-
-### Resolve source code for testing
-
-Using [`resolveAsset`][api:resolveAsset] and
-[`resolveSource`][api:resolveSource], you can resolve Dart source code into a
-static element model, suitable for probing and using within tests of code you
-might have written for a `Builder`:
-
-```dart
-test('should resolve a simple dart file', () async {
-  var resolver = await resolveSource(r'''
-    library example;
-
-    class Foo {}
-  ''');
-  var libExample = resolver.getLibraryByName('example');
-  expect(libExample.getType('Foo'), isNotNull);
-});
-```
-
-### Various test implementations of classes
-
-* [`FakeWatcher`][api:FakeWatcher]
-* [`InMemoryAssetReader`][api:InMemoryAssetReader]
-* [`InMemoryAssetWriter`][api:InMemoryAssetWriter]
-* [`MultiAssetReader`][api:MultiAssetReader]
-* [`PackageAssetReader`][api:PackageAssetReader]
-* [`RecordingAssetWriter`][api:RecordingAssetWriter]
-* [`StubAssetReader`][api:StubAssetReader]
-* [`StubAssetWriter`][api:StubAssetWriter]
-
-[development dependency]: https://dart.dev/tools/pub/dependencies#dev-dependencies
-[`package:build`]: https://pub.dev/packages/build
-
-[api:FakeWatcher]: https://pub.dev/documentation/build_test/latest/build_test/FakeWatcher-class.html
-[api:InMemoryAssetReader]: https://pub.dev/documentation/build_test/latest/build_test/InMemoryAssetReader-class.html
-[api:InMemoryAssetWriter]: https://pub.dev/documentation/build_test/latest/build_test/InMemoryAssetWriter-class.html
-[api:MultiAssetReader]: https://pub.dev/documentation/build_test/latest/build_test/MultiAssetReader-class.html
-[api:PackageAssetReader]: https://pub.dev/documentation/build_test/latest/build_test/PackageAssetReader-class.html
-[api:RecordingAssetWriter]: https://pub.dev/documentation/build_test/latest/build_test/RecordingAssetWriter-class.html
-[api:StubAssetReader]: https://pub.dev/documentation/build_test/latest/build_test/StubAssetReader-class.html
-[api:StubAssetWriter]: https://pub.dev/documentation/build_test/latest/build_test/StubAssetWriter-class.html
-
-[api:resolveAsset]: https://pub.dev/documentation/build_test/latest/build_test/resolveAsset.html
-[api:resolveSource]: https://pub.dev/documentation/build_test/latest/build_test/resolveSource.html
-[api:testBuilder]: https://pub.dev/documentation/build_test/latest/build_test/testBuilder.html
diff --git a/build_test/build.yaml b/build_test/build.yaml
deleted file mode 100644
index 2283e15..0000000
--- a/build_test/build.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-builders:
-  test_bootstrap:
-    target: "build_test"
-    import: "package:build_test/builder.dart"
-    builder_factories:
-        - "debugIndexBuilder"
-        - "debugTestBuilder"
-        - "testBootstrapBuilder"
-    build_extensions:
-      $test$:
-        - index.html
-      _test.dart:
-        - _test.dart.vm_test.dart
-        - _test.dart.browser_test.dart
-        - _test.dart.node_test.dart
-        - _test.html
-        - _test.debug.html
-    is_optional: False
-    build_to: cache
-    auto_apply: root_package
-    defaults:
-      generate_for: ["test/**"]
diff --git a/build_test/lib/build_test.dart b/build_test/lib/build_test.dart
deleted file mode 100644
index e215514..0000000
--- a/build_test/lib/build_test.dart
+++ /dev/null
@@ -1,22 +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.
-
-export 'package:build/src/builder/logging.dart' show scopeLogAsync;
-
-export 'src/assets.dart';
-export 'src/builder.dart';
-export 'src/fake_watcher.dart';
-export 'src/globbing_builder.dart';
-export 'src/in_memory_reader.dart';
-export 'src/in_memory_writer.dart';
-export 'src/matchers.dart';
-export 'src/multi_asset_reader.dart' show MultiAssetReader;
-export 'src/package_reader.dart' show PackageAssetReader;
-export 'src/record_logs.dart';
-export 'src/resolve_source.dart'
-    show useAssetReader, resolveSource, resolveSources, resolveAsset;
-export 'src/stub_reader.dart';
-export 'src/stub_writer.dart';
-export 'src/test_builder.dart';
-export 'src/written_asset_reader.dart';
diff --git a/build_test/lib/builder.dart b/build_test/lib/builder.dart
deleted file mode 100644
index 44d7697..0000000
--- a/build_test/lib/builder.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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 'src/debug_test_builder.dart';
-import 'src/test_bootstrap_builder.dart';
-
-export 'src/debug_test_builder.dart' show DebugTestBuilder;
-export 'src/test_bootstrap_builder.dart' show TestBootstrapBuilder;
-
-DebugTestBuilder debugTestBuilder(_) => const DebugTestBuilder();
-DebugIndexBuilder debugIndexBuilder(_) => const DebugIndexBuilder();
-TestBootstrapBuilder testBootstrapBuilder(_) => TestBootstrapBuilder();
diff --git a/build_test/lib/src/assets.dart b/build_test/lib/src/assets.dart
deleted file mode 100644
index 53597a8..0000000
--- a/build_test/lib/src/assets.dart
+++ /dev/null
@@ -1,32 +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:convert';
-
-import 'package:build/build.dart';
-
-import 'in_memory_writer.dart';
-
-int _nextId = 0;
-AssetId makeAssetId([String assetIdString]) {
-  if (assetIdString == null) {
-    assetIdString = 'a|web/asset_$_nextId.txt';
-    _nextId++;
-  }
-  return AssetId.parse(assetIdString);
-}
-
-void addAssets(Map<AssetId, dynamic> assets, InMemoryAssetWriter writer) {
-  assets.forEach((id, value) {
-    if (value is String) {
-      writer.assets[id] = utf8.encode(value);
-    } else if (value is List<int>) {
-      writer.assets[id] = value;
-    } else {
-      throw ArgumentError(
-          '`assets` values must be of type `String` or `List<int>`, got '
-          '${value.runtimeType}.');
-    }
-  });
-}
diff --git a/build_test/lib/src/builder.dart b/build_test/lib/src/builder.dart
deleted file mode 100644
index f36f6e3..0000000
--- a/build_test/lib/src/builder.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-
-/// Overridable behavior for a [Builder.build] method.
-typedef BuildBehavior = FutureOr Function(
-    BuildStep buildStep, Map<String, List<String>> buildExtensions);
-
-/// Copy the input asset to all possible output assets.
-void _defaultBehavior(
-        BuildStep buildStep, Map<String, List<String>> buildExtensions) =>
-    _copyToAll(buildStep, buildExtensions);
-
-T _identity<T>(T value) => value;
-Future<String> _readAsset(BuildStep buildStep, AssetId assetId) =>
-    buildStep.readAsString(assetId);
-
-/// Pass the input assetId through [readFrom] and duplicate the results of
-/// [read] on that asset into every matching output based on [buildExtensions].
-void _copyToAll(BuildStep buildStep, Map<String, List<String>> buildExtensions,
-    {AssetId Function(AssetId assetId) readFrom = _identity,
-    Future<String> Function(BuildStep buildStep, AssetId assetId) read =
-        _readAsset}) {
-  if (!buildExtensions.keys.any((e) => buildStep.inputId.path.endsWith(e))) {
-    throw ArgumentError('Only expected inputs with extension in '
-        '${buildExtensions.keys.toList()} but got ${buildStep.inputId}');
-  }
-  for (final inputExtension in buildExtensions.keys) {
-    if (!buildStep.inputId.path.endsWith(inputExtension)) continue;
-    for (final outputExtension in buildExtensions[inputExtension]) {
-      final newPath = _replaceSuffix(
-          buildStep.inputId.path, inputExtension, outputExtension);
-      final id = AssetId(buildStep.inputId.package, newPath);
-      buildStep.writeAsString(id, read(buildStep, readFrom(buildStep.inputId)));
-    }
-  }
-}
-
-/// A build behavior which reads [assetId] and copies it's content into every
-/// output.
-BuildBehavior copyFrom(AssetId assetId) => (buildStep, buildExtensions) =>
-    _copyToAll(buildStep, buildExtensions, readFrom: (_) => assetId);
-
-/// A build behavior which writes either 'true' or 'false' depending on whether
-/// [assetId] can be read.
-BuildBehavior writeCanRead(AssetId assetId) =>
-    (BuildStep buildStep, Map<String, List<String>> buildExtensions) =>
-        _copyToAll(buildStep, buildExtensions,
-            readFrom: (_) => assetId,
-            read: (buildStep, assetId) async =>
-                '${await buildStep.canRead(assetId)}');
-
-/// A [Builder.buildExtensions] which operats on assets ending in [from] and
-/// creates outputs with [postFix] appended as the extension.
-///
-/// If [numCopies] is greater than 1 the postFix will also get a `.0`, `.1`...
-Map<String, List<String>> appendExtension(String postFix,
-        {String from = '', int numCopies = 1}) =>
-    {
-      from: numCopies == 1
-          ? ['$from$postFix']
-          : List.generate(numCopies, (i) => '$from$postFix.$i')
-    };
-
-Map<String, List<String>> replaceExtension(String from, String to) => {
-      from: [to]
-    };
-
-/// A [Builder] whose [build] method can be replaced with a closure.
-class TestBuilder implements Builder {
-  @override
-  final Map<String, List<String>> buildExtensions;
-
-  final BuildBehavior _build;
-  final BuildBehavior _extraWork;
-
-  /// A stream of all the [BuildStep.inputId]s that are seen.
-  ///
-  /// Events are added at the start of the [build] method.
-  final _buildInputsController = StreamController<AssetId>.broadcast();
-  Stream<AssetId> get buildInputs => _buildInputsController.stream;
-
-  /// A stream of all the [BuildStep.inputId]s that are completed.
-  ///
-  /// Events are added at the end of the [build] method.
-  final _buildsCompletedController = StreamController<AssetId>.broadcast();
-  Stream<AssetId> get buildsCompleted => _buildsCompletedController.stream;
-
-  TestBuilder({
-    Map<String, List<String>> buildExtensions,
-    BuildBehavior build,
-    BuildBehavior extraWork,
-  })  : buildExtensions = buildExtensions ?? appendExtension('.copy'),
-        _build = build ?? _defaultBehavior,
-        _extraWork = extraWork;
-
-  @override
-  Future build(BuildStep buildStep) async {
-    if (!await buildStep.canRead(buildStep.inputId)) return;
-    _buildInputsController.add(buildStep.inputId);
-    await _build(buildStep, buildExtensions);
-    if (_extraWork != null) await _extraWork(buildStep, buildExtensions);
-    _buildsCompletedController.add(buildStep.inputId);
-  }
-}
-
-String _replaceSuffix(String path, String old, String replacement) =>
-    path.substring(0, path.length - old.length) + replacement;
diff --git a/build_test/lib/src/debug_test_builder.dart b/build_test/lib/src/debug_test_builder.dart
deleted file mode 100644
index 1d97bd9..0000000
--- a/build_test/lib/src/debug_test_builder.dart
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:html/dom.dart';
-import 'package:html/parser.dart';
-import 'package:path/path.dart' as p;
-
-const _inputExtension = '_test.dart';
-const _outputExtension = '_test.debug.html';
-
-/// Returns the (optional) user-provided HTML file to use as an input.
-///
-/// For example, for `test/foo_test.dart`, we look for `test/foo_test.html`.
-AssetId _customHtmlId(AssetId test) => test.changeExtension('.html');
-
-/// Returns the builder-generated HTML file for browsers to navigate to.
-AssetId _debugHtmlId(AssetId test) => test.changeExtension('.debug.html');
-
-/// Returns the JS script path for the browser for [dartTest].
-String _jsScriptPath(AssetId dartTest) => '${p.url.basename(dartTest.path)}.js';
-
-/// Generates a `*.debug.html` for every file in `test/**/*_test.dart`.
-///
-/// This is normally used in order to use Chrome (or another browser's)
-/// debugging tools (such as setting breakpoints) while running a test suite.
-class DebugTestBuilder implements Builder {
-  /// Generates a `.debug.html` for the provided `._test.dart` file.
-  static Future<void> _generateDebugHtml(
-    BuildStep buildStep,
-    AssetId dartTest,
-  ) async {
-    final customHtmlId = _customHtmlId(dartTest);
-    final jsScriptPath = _jsScriptPath(buildStep.inputId);
-    String debugHtml;
-    if (await buildStep.canRead(customHtmlId)) {
-      debugHtml = _replaceCustomHtml(
-        await buildStep.readAsString(customHtmlId),
-        jsScriptPath,
-      );
-    } else {
-      debugHtml = _createDebugHtml(jsScriptPath);
-    }
-    return buildStep.writeAsString(_debugHtmlId(dartTest), debugHtml);
-  }
-
-  /// Returns the content of [customHtml] modified to work with this package.
-  static String _replaceCustomHtml(String customHtml, String jsScriptPath) {
-    final document = parse(customHtml);
-
-    // Replace <link rel="x-dart-test"> with <script src="{jsScriptPath}">.
-    final linkTag = document.querySelector('link[rel="x-dart-test"]');
-    final scriptTag = Element.tag('script');
-    scriptTag.attributes['src'] = jsScriptPath;
-    linkTag.replaceWith(scriptTag);
-
-    // Remove the <script src="packages/test/dart.js"></script> if present.
-    document.querySelector('script[src="packages/test/dart.js"]')?.remove();
-
-    return document.outerHtml;
-  }
-
-  static String _createDebugHtml(String jsScriptPath) => ''
-      '<html>\n'
-      '  <head>\n'
-      '    <script src="$jsScriptPath"></script>\n'
-      '  </head>\n'
-      '</html>\n';
-
-  const DebugTestBuilder();
-
-  @override
-  final buildExtensions = const {
-    _inputExtension: [_outputExtension],
-  };
-
-  @override
-  Future<void> build(BuildStep buildStep) {
-    return _generateDebugHtml(buildStep, buildStep.inputId);
-  }
-}
-
-/// Generates `text/index.html`, useful for navigating and running tests.
-class DebugIndexBuilder implements Builder {
-  static final _allTests = Glob(p.url.join('test', '**$_inputExtension'));
-
-  static AssetId _outputFor(BuildStep buildStep) {
-    return AssetId(buildStep.inputId.package, p.url.join('test', 'index.html'));
-  }
-
-  static String _generateHtml(Iterable<AssetId> tests) {
-    if (tests.isEmpty) {
-      return '<strong>No tests found!</strong>';
-    }
-    final buffer = StringBuffer('    <ul>');
-    for (final test in tests) {
-      final path =
-          p.url.joinAll(p.url.split(_debugHtmlId(test).path)..removeAt(0));
-      buffer.writeln('      <li><a href="/$path">${test.path}</a></li>');
-    }
-    buffer.writeln('    </ul>');
-    return buffer.toString();
-  }
-
-  const DebugIndexBuilder();
-
-  @override
-  final buildExtensions = const {
-    r'$test$': ['index.html'],
-  };
-
-  @override
-  Future<void> build(BuildStep buildStep) async {
-    final files = await buildStep.findAssets(_allTests).toList();
-    final output = _outputFor(buildStep);
-    return buildStep.writeAsString(
-        output,
-        '<html>\n'
-        '  <body>\n'
-        '    ${_generateHtml(files)}\n'
-        '  </body>\n'
-        '</html>');
-  }
-}
diff --git a/build_test/lib/src/fake_watcher.dart b/build_test/lib/src/fake_watcher.dart
deleted file mode 100644
index b41ebaa..0000000
--- a/build_test/lib/src/fake_watcher.dart
+++ /dev/null
@@ -1,45 +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:watcher/watcher.dart';
-
-/// A fake [DirectoryWatcher].
-///
-/// Use the static [notifyWatchers] method to add simulated events.
-class FakeWatcher implements DirectoryWatcher {
-  @override
-  String get directory => path;
-
-  @override
-  final String path;
-
-  FakeWatcher(this.path) {
-    watchers.add(this);
-  }
-
-  final _eventsController = StreamController<WatchEvent>();
-
-  @override
-  Stream<WatchEvent> get events => _eventsController.stream;
-
-  @override
-  Future get ready => Future(() {});
-
-  @override
-  bool get isReady => true;
-
-  /// All watchers.
-  static final List<FakeWatcher> watchers = <FakeWatcher>[];
-
-  /// Notify all active watchers of [event] if their [FakeWatcher#path] matches.
-  /// The path will also be adjusted to remove the path.
-  static void notifyWatchers(WatchEvent event) {
-    for (var watcher in watchers) {
-      if (event.path.startsWith(watcher.path)) {
-        watcher._eventsController.add(WatchEvent(event.type, event.path));
-      }
-    }
-  }
-}
diff --git a/build_test/lib/src/globbing_builder.dart b/build_test/lib/src/globbing_builder.dart
deleted file mode 100644
index 918ec1f..0000000
--- a/build_test/lib/src/globbing_builder.dart
+++ /dev/null
@@ -1,30 +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:build/build.dart';
-import 'package:glob/glob.dart';
-
-/// A simple builder which globs files in a package and outputs a file that
-/// lists each matching file in alphabetical order into another file, one
-/// per line.
-class GlobbingBuilder extends Builder {
-  @override
-  final buildExtensions = {
-    '.globPlaceholder': ['.matchingFiles'],
-  };
-
-  final Glob glob;
-
-  GlobbingBuilder(this.glob);
-
-  @override
-  Future build(BuildStep buildStep) async {
-    var allAssets = await buildStep.findAssets(glob).toList();
-    allAssets.sort((a, b) => a.path.compareTo(b.path));
-    await buildStep.writeAsString(
-        buildStep.inputId.changeExtension('.matchingFiles'),
-        allAssets.map((id) => id.toString()).join('\n'));
-  }
-}
diff --git a/build_test/lib/src/in_memory_reader.dart b/build_test/lib/src/in_memory_reader.dart
deleted file mode 100644
index 9444da1..0000000
--- a/build_test/lib/src/in_memory_reader.dart
+++ /dev/null
@@ -1,93 +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:convert';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-/// An [AssetReader] that records which assets have been read to [assetsRead].
-abstract class RecordingAssetReader implements AssetReader {
-  Iterable<AssetId> get assetsRead;
-}
-
-/// An implementation of [AssetReader] with primed in-memory assets.
-class InMemoryAssetReader extends AssetReader
-    implements MultiPackageAssetReader, RecordingAssetReader {
-  final Map<AssetId, List<int>> assets;
-  final String rootPackage;
-
-  @override
-  final Set<AssetId> assetsRead = <AssetId>{};
-
-  /// Create a new asset reader that contains [sourceAssets].
-  ///
-  /// Any items in [sourceAssets] which are [String]s will be converted into
-  /// a [List<int>] of bytes.
-  ///
-  /// May optionally define a [rootPackage], which is required for some APIs.
-  InMemoryAssetReader({Map<AssetId, dynamic> sourceAssets, this.rootPackage})
-      : assets = _assetsAsBytes(sourceAssets) ?? <AssetId, List<int>>{};
-
-  /// Create a new asset reader backed by [assets].
-  InMemoryAssetReader.shareAssetCache(this.assets, {this.rootPackage});
-
-  static Map<AssetId, List<int>> _assetsAsBytes(Map<AssetId, dynamic> assets) {
-    if (assets == null || assets.isEmpty) {
-      return {};
-    }
-    final output = <AssetId, List<int>>{};
-    assets.forEach((id, stringOrBytes) {
-      if (stringOrBytes is List<int>) {
-        output[id] = stringOrBytes;
-      } else if (stringOrBytes is String) {
-        output[id] = utf8.encode(stringOrBytes);
-      } else {
-        throw UnsupportedError('Invalid asset contents: $stringOrBytes.');
-      }
-    });
-    return output;
-  }
-
-  @override
-  Future<bool> canRead(AssetId id) async {
-    assetsRead.add(id);
-    return assets.containsKey(id);
-  }
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) async {
-    if (!await canRead(id)) throw AssetNotFoundException(id);
-    assetsRead.add(id);
-    return assets[id];
-  }
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) async {
-    if (!await canRead(id)) throw AssetNotFoundException(id);
-    assetsRead.add(id);
-    return utf8.decode(assets[id]);
-  }
-
-  @override
-  Stream<AssetId> findAssets(Glob glob, {String package}) {
-    package ??= rootPackage;
-    if (package == null) {
-      throw UnsupportedError(
-          'Root package is required to use findAssets without providing an '
-          'explicit package.');
-    }
-    return Stream.fromIterable(assets.keys
-        .where((id) => id.package == package && glob.matches(id.path)));
-  }
-
-  void cacheBytesAsset(AssetId id, List<int> bytes) {
-    assets[id] = bytes;
-  }
-
-  void cacheStringAsset(AssetId id, String contents, {Encoding encoding}) {
-    encoding ??= utf8;
-    assets[id] = encoding.encode(contents);
-  }
-}
diff --git a/build_test/lib/src/in_memory_writer.dart b/build_test/lib/src/in_memory_writer.dart
deleted file mode 100644
index 8bb35cc..0000000
--- a/build_test/lib/src/in_memory_writer.dart
+++ /dev/null
@@ -1,31 +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:convert';
-
-import 'package:build/build.dart';
-
-/// An implementation of [AssetWriter] that records outputs to [assets].
-abstract class RecordingAssetWriter implements AssetWriter {
-  Map<AssetId, List<int>> get assets;
-}
-
-/// An implementation of [AssetWriter] that writes outputs to memory.
-class InMemoryAssetWriter implements RecordingAssetWriter {
-  @override
-  final Map<AssetId, List<int>> assets = {};
-
-  InMemoryAssetWriter();
-
-  @override
-  Future writeAsBytes(AssetId id, List<int> bytes) async {
-    assets[id] = bytes;
-  }
-
-  @override
-  Future writeAsString(AssetId id, String contents,
-      {Encoding encoding = utf8}) async {
-    assets[id] = encoding.encode(contents);
-  }
-}
diff --git a/build_test/lib/src/matchers.dart b/build_test/lib/src/matchers.dart
deleted file mode 100644
index 92f3c16..0000000
--- a/build_test/lib/src/matchers.dart
+++ /dev/null
@@ -1,28 +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:convert';
-
-import 'package:test/test.dart';
-
-import 'package:build/build.dart';
-
-/// Matches instance of [AssetNotFoundException].
-final assetNotFoundException = const TypeMatcher<AssetNotFoundException>();
-
-/// Matches instance of [InvalidInputException].
-final invalidInputException = const TypeMatcher<InvalidInputException>();
-
-/// Matches instance of [InvalidOutputException].
-final invalidOutputException = const TypeMatcher<InvalidOutputException>();
-
-/// Matches instance of [PackageNotFoundException].
-final packageNotFoundException = const TypeMatcher<PackageNotFoundException>();
-
-/// Decodes the value using [encoding] and matches it against [expected].
-TypeMatcher<List<int>> decodedMatches(dynamic expected, {Encoding encoding}) {
-  encoding ??= utf8;
-  return TypeMatcher<List<int>>().having(
-      (e) => encoding.decode(e), '${encoding.name} decoded bytes', expected);
-}
diff --git a/build_test/lib/src/multi_asset_reader.dart b/build_test/lib/src/multi_asset_reader.dart
deleted file mode 100644
index a487263..0000000
--- a/build_test/lib/src/multi_asset_reader.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-/// A [MultiPackageAssetReader] that delegates to multiple other asset
-/// readers.
-///
-/// [MultiAssetReader] attempts to check every provided
-/// [MultiPackageAssetReader] to see if they are capable of reading an
-/// [AssetId], otherwise checks the next reader.
-class MultiAssetReader extends AssetReader implements MultiPackageAssetReader {
-  final List<MultiPackageAssetReader> _readers;
-
-  MultiAssetReader(this._readers);
-
-  @override
-  Future<bool> canRead(AssetId id) async {
-    for (var reader in _readers) {
-      if (await reader.canRead(id)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) async =>
-      (await _readerWith(id)).readAsBytes(id);
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) async =>
-      (await _readerWith(id)).readAsString(id, encoding: encoding);
-
-  /// Returns all readable assets matching [glob] under [package].
-  ///
-  /// **NOTE**: This is a combined view of all provided readers. As such it is
-  /// possible that an [AssetId] will be iterated over more than once, unlike
-  /// other implementations of [AssetReader].
-  @override
-  Stream<AssetId> findAssets(Glob glob, {String package}) => StreamGroup.merge(
-      _readers.map((reader) => reader.findAssets(glob, package: package)));
-
-  /// Returns the first [AssetReader] that contains [id].
-  ///
-  /// Otherwise throws [AssetNotFoundException].
-  Future<AssetReader> _readerWith(AssetId id) async {
-    for (var reader in _readers) {
-      if (await reader.canRead(id)) {
-        return reader;
-      }
-    }
-    throw AssetNotFoundException(id);
-  }
-}
diff --git a/build_test/lib/src/package_reader.dart b/build_test/lib/src/package_reader.dart
deleted file mode 100644
index b8a7809..0000000
--- a/build_test/lib/src/package_reader.dart
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:package_resolver/package_resolver.dart';
-import 'package:path/path.dart' as p;
-import 'package:stream_transform/stream_transform.dart';
-
-/// Resolves using a [SyncPackageResolver] before reading from the file system.
-///
-/// For a simple implementation that uses the current isolate's package
-/// resolution logic (i.e. whatever you have generated in `.packages` in most
-/// cases), use [currentIsolate]:
-/// ```dart
-/// var assetReader = await PackageAssetReader.currentIsolate();
-/// ```
-class PackageAssetReader extends AssetReader
-    implements MultiPackageAssetReader {
-  final SyncPackageResolver _packageResolver;
-
-  /// What package is the originating build occurring in.
-  final String _rootPackage;
-
-  /// Wrap a [SyncPackageResolver] to identify where files are located.
-  ///
-  /// To use a normal [PackageResolver] use `asSync`:
-  /// ```
-  /// new PackageAssetReader(await packageResolver.asSync);
-  /// ```
-  PackageAssetReader(this._packageResolver, [this._rootPackage]);
-
-  /// A [PackageAssetReader] with a single [packageRoot] configured.
-  ///
-  /// It is assumed that every _directory_ in [packageRoot] is a package where
-  /// the name of the package is the name of the directory. This is similar to
-  /// the older "packages" folder paradigm for resolution.
-  factory PackageAssetReader.forPackageRoot(String packageRoot,
-      [String rootPackage]) {
-    // This purposefully doesn't use SyncPackageResolver.root, because that is
-    // assuming a symlink collection and not directories, and this factory is
-    // more useful for a user-created collection of folders for testing.
-    final directory = Directory(packageRoot);
-    final packages = <String, String>{};
-    for (final entity in directory.listSync()) {
-      if (entity is Directory) {
-        final name = p.basename(entity.path);
-        packages[name] = entity.uri.toFilePath(windows: false);
-      }
-    }
-    return PackageAssetReader.forPackages(packages, rootPackage);
-  }
-
-  /// Returns a [PackageAssetReader] with a simple [packageToPath] mapping.
-  factory PackageAssetReader.forPackages(Map<String, String> packageToPath,
-          [String rootPackage]) =>
-      PackageAssetReader(
-          SyncPackageResolver.config(packageToPath
-              .map((k, v) => MapEntry(k, Uri.parse(p.url.absolute(v, 'lib'))))),
-          rootPackage);
-
-  /// A reader that can resolve files known to the current isolate.
-  ///
-  /// A [rootPackage] should be provided for full API compatibility.
-  static Future<PackageAssetReader> currentIsolate({String rootPackage}) async {
-    var resolver = PackageResolver.current;
-    return PackageAssetReader(await resolver.asSync, rootPackage);
-  }
-
-  File _resolve(AssetId id) {
-    final uri = id.uri;
-    if (uri.isScheme('package')) {
-      final uri = _packageResolver.resolveUri(id.uri);
-      if (uri != null) {
-        return File.fromUri(uri);
-      }
-    }
-    if (id.package == _rootPackage) {
-      return File(p.canonicalize(p.join(_rootPackagePath, id.path)));
-    }
-    return null;
-  }
-
-  String get _rootPackagePath {
-    // If the root package has a pub layout, use `packagePath`.
-    final root = _packageResolver.packagePath(_rootPackage);
-    if (root != null && Directory(p.join(root, 'lib')).existsSync()) {
-      return root;
-    }
-    // Assume the cwd is the package root.
-    return p.current;
-  }
-
-  @override
-  Stream<AssetId> findAssets(Glob glob, {String package}) {
-    package ??= _rootPackage;
-    if (package == null) {
-      throw UnsupportedError(
-          'Root package must be provided to use `findAssets` without an '
-          'explicit `package`.');
-    }
-    var packageLibDir = _packageResolver.packageConfigMap[package];
-    if (packageLibDir == null) {
-      throw UnsupportedError('Unable to find package $package');
-    }
-
-    var packageFiles = Directory.fromUri(packageLibDir)
-        .list(recursive: true)
-        .whereType<File>()
-        .map((f) =>
-            p.join('lib', p.relative(f.path, from: p.fromUri(packageLibDir))));
-    if (package == _rootPackage) {
-      packageFiles = packageFiles.merge(Directory(_rootPackagePath)
-          .list(recursive: true)
-          .whereType<File>()
-          .map((f) => p.relative(f.path, from: _rootPackagePath))
-          .where((p) => !(p.startsWith('packages/') || p.startsWith('lib/'))));
-    }
-    return packageFiles.where(glob.matches).map((p) => AssetId(package, p));
-  }
-
-  @override
-  Future<bool> canRead(AssetId id) =>
-      _resolve(id)?.exists() ?? Future.value(false);
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) =>
-      _resolve(id)?.readAsBytes() ?? (throw AssetNotFoundException(id));
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) =>
-      _resolve(id)?.readAsString(encoding: encoding) ??
-      (throw AssetNotFoundException(id));
-}
diff --git a/build_test/lib/src/record_logs.dart b/build_test/lib/src/record_logs.dart
deleted file mode 100644
index b45de5b..0000000
--- a/build_test/lib/src/record_logs.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/src/builder/logging.dart';
-import 'package:matcher/matcher.dart';
-import 'package:logging/logging.dart';
-
-/// Executes [run] with a new [Logger], returning the resulting log records.
-///
-/// The returned [Stream] is _closed_ after the [run] function is executed. If
-/// [run] returns a [Future], that future is awaited _before_ the stream is
-/// closed.
-///
-/// ```dart
-/// test('should log "uh oh!"', () async {
-///   final logs = recordLogs(() => runBuilder());
-///   expect(logs, emitsInOrder([
-///     anyLogOf('uh oh!'),
-///   ]);
-/// });
-/// ```
-Stream<LogRecord> recordLogs(dynamic Function() run, {String name = ''}) {
-  final logger = Logger(name);
-  Timer.run(() async {
-    await scopeLogAsync(() => Future.value(run()), logger);
-    logger.clearListeners();
-  });
-  return logger.onRecord;
-}
-
-/// Matches [LogRecord] of any level whose message is [messageOrMatcher].
-///
-/// ```dart
-/// anyLogOf('Hello World)';     // Exactly match 'Hello World'.
-/// anyLogOf(contains('ERROR')); // Contains the sub-string 'ERROR'.
-/// ```
-Matcher anyLogOf(dynamic messageOrMatcher) =>
-    _LogRecordMatcher(anything, messageOrMatcher);
-
-/// Matches [LogRecord] of [Level.INFO] where message is [messageOrMatcher].
-Matcher infoLogOf(dynamic messageOrMatcher) =>
-    _LogRecordMatcher(Level.INFO, messageOrMatcher);
-
-/// Matches [LogRecord] of [Level.WARNING] where message is [messageOrMatcher].
-Matcher warningLogOf(dynamic messageOrMatcher) =>
-    _LogRecordMatcher(Level.WARNING, messageOrMatcher);
-
-/// Matches [LogRecord] of [Level.SEVERE] where message is [messageOrMatcher].
-Matcher severeLogOf(dynamic messageOrMatcher) =>
-    _LogRecordMatcher(Level.SEVERE, messageOrMatcher);
-
-class _LogRecordMatcher extends Matcher {
-  final Matcher _level;
-  final Matcher _message;
-
-  factory _LogRecordMatcher(dynamic levelOr, dynamic messageOr) =>
-      _LogRecordMatcher._(levelOr is Matcher ? levelOr : equals(levelOr),
-          messageOr is Matcher ? messageOr : equals(messageOr));
-
-  _LogRecordMatcher._(this._level, this._message);
-
-  @override
-  Description describe(Description description) {
-    description.add('level: ');
-    _level.describe(description);
-    description.add(', message: ');
-    _message.describe(description);
-    return description;
-  }
-
-  @override
-  Description describeMismatch(
-      covariant LogRecord item, Description description, _, __) {
-    if (!_level.matches(item.level, {})) {
-      _level.describeMismatch(item.level, description, {}, false);
-    }
-    if (!_message.matches(item.message, {})) {
-      _message.describeMismatch(item.message, description, {}, false);
-    }
-    return description;
-  }
-
-  @override
-  bool matches(item, _) =>
-      item is LogRecord &&
-      _level.matches(item.level, {}) &&
-      _message.matches(item.message, {});
-}
diff --git a/build_test/lib/src/resolve_source.dart b/build_test/lib/src/resolve_source.dart
deleted file mode 100644
index 6782805..0000000
--- a/build_test/lib/src/resolve_source.dart
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:build_resolvers/build_resolvers.dart';
-import 'package:package_resolver/package_resolver.dart';
-import 'package:pedantic/pedantic.dart';
-
-import 'in_memory_reader.dart';
-import 'in_memory_writer.dart';
-import 'multi_asset_reader.dart';
-import 'package_reader.dart';
-
-final defaultResolvers = AnalyzerResolvers();
-
-/// Marker constant that may be used in combination with [resolveSources].
-///
-/// Use of this string means instead of using the contents of the string as the
-/// source of a given asset, instead read the file from the default or provided
-/// [AssetReader].
-const useAssetReader = '__useAssetReader__';
-
-/// A convenience method for using [resolveSources] with a single source file.
-Future<T> resolveSource<T>(
-  String inputSource,
-  FutureOr<T> Function(Resolver resolver) action, {
-  AssetId inputId,
-  PackageResolver resolver,
-  Future<Null> tearDown,
-  Resolvers resolvers,
-}) {
-  inputId ??= AssetId('_resolve_source', 'lib/_resolve_source.dart');
-  return _resolveAssets(
-    {
-      '${inputId.package}|${inputId.path}': inputSource,
-    },
-    inputId.package,
-    action,
-    resolver: resolver,
-    resolverFor: inputId,
-    tearDown: tearDown,
-    resolvers: resolvers,
-  );
-}
-
-/// Resolves and runs [action] using a created resolver for [inputs].
-///
-/// Inputs accepts the pattern of `<package>|<path>.dart`, for example:
-/// ```
-/// {
-///   'test_lib|lib/test_lib.dart': r'''
-///     // Contents of test_lib.dart go here.
-///   ''',
-/// }
-/// ```
-///
-/// You may provide [useAssetReader] as the value of any input in order to read
-/// it from the file system instead of being forced to provide it inline as a
-/// string. This is useful for mixing real and mocked assets.
-///
-/// Example use:
-/// ```
-/// import 'package:build_test/build_test.dart';
-/// import 'package:test/test.dart';
-///
-/// void main() {
-///   test('should find a Foo type', () async {
-///     var library = await resolveSources({
-///       'test_lib|lib/test_lib.dart': r'''
-///         library example;
-///
-///         class Foo {}
-///       ''',
-///     }, (resolver) => resolver.findLibraryByName('example'));
-///     expect(library.getType('Foo'), isNotNull);
-///   });
-/// }
-/// ```
-///
-/// By default the [Resolver] is unusable after [action] completes. To keep the
-/// resolver active across multiple tests (for example, use `setUpAll` and
-/// `tearDownAll`, provide a `tearDown` [Future]:
-/// ```
-/// import 'dart:async';
-/// import 'package:build/build.dart';
-/// import 'package:build_test/build_test.dart';
-/// import 'package:test/test.dart';
-///
-/// void main() {
-///   Resolver resolver;
-///   var resolverDone = new Completer<Null>();
-///
-///   setUpAll(() async {
-///     resolver = await resolveSources(
-///       {...},
-///       (resolver) => resolver,
-///       tearDown: resolverDone.future,
-///     );
-///   });
-///
-///   tearDownAll(() => resolverDone.complete());
-///
-///   test('...', () async {
-///     // Use the resolver here, and in other tests.
-///   });
-/// }
-/// ```
-///
-/// May provide [resolverFor] to return the [Resolver] for the asset provided,
-/// otherwise defaults to the first one in [inputs].
-///
-/// **NOTE**: All `package` dependencies are resolved using [PackageAssetReader]
-/// - by default, [PackageAssetReader.currentIsolate]. A custom [resolver] may
-/// be provided to map files not visible to the current package's runtime.
-Future<T> resolveSources<T>(
-  Map<String, String> inputs,
-  FutureOr<T> Function(Resolver resolver) action, {
-  PackageResolver resolver,
-  String resolverFor,
-  String rootPackage,
-  Future<Null> tearDown,
-  Resolvers resolvers,
-}) {
-  if (inputs == null || inputs.isEmpty) {
-    throw ArgumentError.value(inputs, 'inputs', 'Must be a non-empty Map');
-  }
-  return _resolveAssets(
-    inputs,
-    rootPackage ?? AssetId.parse(inputs.keys.first).package,
-    action,
-    resolver: resolver,
-    resolverFor: AssetId.parse(resolverFor ?? inputs.keys.first),
-    tearDown: tearDown,
-    resolvers: resolvers,
-  );
-}
-
-/// A convenience for using [resolveSources] with a single [inputId] from disk.
-Future<T> resolveAsset<T>(
-  AssetId inputId,
-  FutureOr<T> Function(Resolver resolver) action, {
-  PackageResolver resolver,
-  Future<Null> tearDown,
-  Resolvers resolvers,
-}) {
-  return _resolveAssets(
-    {
-      '${inputId.package}|${inputId.path}': useAssetReader,
-    },
-    inputId.package,
-    action,
-    resolver: resolver,
-    resolverFor: inputId,
-    tearDown: tearDown,
-    resolvers: resolvers,
-  );
-}
-
-/// Internal-only backing implementation of `resolve{Asset|Source(s)}`.
-///
-/// If the value of an entry of [inputs] is [useAssetReader] then the value is
-/// instead read from the file system, otherwise the provided text is used as
-/// the contents of the asset.
-Future<T> _resolveAssets<T>(
-  Map<String, String> inputs,
-  String rootPackage,
-  FutureOr<T> Function(Resolver resolver) action, {
-  PackageResolver resolver,
-  AssetId resolverFor,
-  Future<Null> tearDown,
-  Resolvers resolvers,
-}) async {
-  final syncResolver = await (resolver ?? PackageResolver.current).asSync;
-  final assetReader = PackageAssetReader(syncResolver, rootPackage);
-  final resolveBuilder = _ResolveSourceBuilder(
-    action,
-    resolverFor,
-    tearDown,
-  );
-  final inputAssets = <AssetId, String>{};
-  await Future.wait(inputs.keys.map((String rawAssetId) async {
-    final assetId = AssetId.parse(rawAssetId);
-    var assetValue = inputs[rawAssetId];
-    if (assetValue == useAssetReader) {
-      assetValue = await assetReader.readAsString(assetId);
-    }
-    inputAssets[assetId] = assetValue;
-  }));
-  final inMemory = InMemoryAssetReader(
-    sourceAssets: inputAssets,
-    rootPackage: rootPackage,
-  );
-  // We don't care about the results of this build, but we also can't await
-  // it because that would block on the `tearDown` of the `resolveBuilder`.
-  //
-  // We also dont want to leak errors as unhandled async errors so we swallow
-  // them here.
-  //
-  // Errors will still be reported through the resolver itself as well as the
-  // `onDone` future that we return.
-  unawaited(runBuilder(
-    resolveBuilder,
-    inputAssets.keys,
-    MultiAssetReader([inMemory, assetReader]),
-    InMemoryAssetWriter(),
-    resolvers ?? defaultResolvers,
-  ).catchError((_) {}));
-  return resolveBuilder.onDone.future;
-}
-
-/// A [Builder] that is only used to retrieve a [Resolver] instance.
-///
-/// It simulates what a user builder would do in order to resolve a primary
-/// input given a set of dependencies to also use. See `resolveSource`.
-class _ResolveSourceBuilder<T> implements Builder {
-  final FutureOr<T> Function(Resolver) _action;
-  final Future _tearDown;
-  final AssetId _resolverFor;
-
-  final onDone = Completer<T>();
-
-  _ResolveSourceBuilder(this._action, this._resolverFor, this._tearDown);
-
-  @override
-  Future<void> build(BuildStep buildStep) async {
-    if (_resolverFor != buildStep.inputId) return;
-    try {
-      onDone.complete(await _action(buildStep.resolver));
-    } catch (e, s) {
-      onDone.completeError(e, s);
-    }
-    await _tearDown;
-  }
-
-  @override
-  final buildExtensions = const {
-    '': ['.unused']
-  };
-}
diff --git a/build_test/lib/src/stub_reader.dart b/build_test/lib/src/stub_reader.dart
deleted file mode 100644
index 6c10e90..0000000
--- a/build_test/lib/src/stub_reader.dart
+++ /dev/null
@@ -1,30 +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:convert';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-/// A no-op implementation of [AssetReader].
-class StubAssetReader extends AssetReader implements MultiPackageAssetReader {
-  StubAssetReader();
-
-  @override
-  Future<bool> canRead(AssetId id) => Future.value(null);
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) => Future.value(null);
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) =>
-      Future.value(null);
-
-  @override
-  Stream<AssetId> findAssets(Glob glob, {String package}) => null;
-
-  @override
-  Future<Digest> digest(AssetId id) => Future.value(Digest([1, 2, 3]));
-}
diff --git a/build_test/lib/src/stub_writer.dart b/build_test/lib/src/stub_writer.dart
deleted file mode 100644
index 8c4b5b2..0000000
--- a/build_test/lib/src/stub_writer.dart
+++ /dev/null
@@ -1,18 +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:convert';
-
-import 'package:build/build.dart';
-
-/// A no-op implementation of [AssetWriter].
-class StubAssetWriter implements AssetWriter {
-  const StubAssetWriter();
-
-  @override
-  Future writeAsBytes(_, __) => Future.value(null);
-
-  @override
-  Future writeAsString(_, __, {Encoding encoding = utf8}) => Future.value(null);
-}
diff --git a/build_test/lib/src/test_bootstrap_builder.dart b/build_test/lib/src/test_bootstrap_builder.dart
deleted file mode 100644
index 7c77340..0000000
--- a/build_test/lib/src/test_bootstrap_builder.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-// ignore: deprecated_member_use
-import 'package:test_core/backend.dart';
-
-/// A [Builder] that injects bootstrapping code used by the test runner to run
-/// tests in --precompiled mode.
-///
-/// This doesn't modify existing code at all, it just adds wrapper files that
-/// can be used to load isolates or iframes.
-class TestBootstrapBuilder extends Builder {
-  @override
-  final buildExtensions = const {
-    '_test.dart': [
-      '_test.dart.vm_test.dart',
-      '_test.dart.browser_test.dart',
-      '_test.dart.node_test.dart',
-    ]
-  };
-  TestBootstrapBuilder();
-
-  @override
-  Future<void> build(BuildStep buildStep) async {
-    var id = buildStep.inputId;
-    var contents = await buildStep.readAsString(id);
-    var assetPath = id.pathSegments.first == 'lib'
-        ? p.url.join('packages', id.package, id.path)
-        : id.path;
-    var metadata = parseMetadata(
-        assetPath, contents, Runtime.builtIn.map((r) => r.name).toSet());
-
-    if (metadata.testOn.evaluate(SuitePlatform(Runtime.vm))) {
-      await buildStep.writeAsString(id.addExtension('.vm_test.dart'), '''
-          import "dart:isolate";
-
-          import "package:test/bootstrap/vm.dart";
-
-          import "${p.url.basename(id.path)}" as test;
-
-          void main(_, SendPort message) {
-            internalBootstrapVmTest(() => test.main, message);
-          }
-        ''');
-    }
-
-    var browserRuntimes = Runtime.builtIn.where((r) => r.isBrowser == true);
-    if (browserRuntimes
-        .any((r) => metadata.testOn.evaluate(SuitePlatform(r)))) {
-      await buildStep.writeAsString(id.addExtension('.browser_test.dart'), '''
-          import "package:test/bootstrap/browser.dart";
-
-          import "${p.url.basename(id.path)}" as test;
-
-          void main() {
-            internalBootstrapBrowserTest(() => test.main);
-          }
-        ''');
-    }
-
-    if (metadata.testOn.evaluate(SuitePlatform(Runtime.nodeJS))) {
-      await buildStep.writeAsString(id.addExtension('.node_test.dart'), '''
-          import "package:test/bootstrap/node.dart";
-
-          import "${p.url.basename(id.path)}" as test;
-
-          void main() {
-            internalBootstrapNodeTest(() => test.main);
-          }
-        ''');
-    }
-  }
-}
diff --git a/build_test/lib/src/test_builder.dart b/build_test/lib/src/test_builder.dart
deleted file mode 100644
index 31ee456..0000000
--- a/build_test/lib/src/test_builder.dart
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:test/test.dart';
-
-import 'assets.dart';
-import 'in_memory_reader.dart';
-import 'in_memory_writer.dart';
-import 'multi_asset_reader.dart';
-import 'resolve_source.dart';
-import 'written_asset_reader.dart';
-
-AssetId _passThrough(AssetId id) => id;
-
-/// Validates that [actualAssets] matches the expected [outputs].
-///
-/// The keys in [outputs] should be serialized [AssetId]s in the form
-/// `'package|path'`. The values should match the expected content for the
-/// written asset and may be a String (for `writeAsString`), a `List<int>` (for
-/// `writeAsBytes`) or a [Matcher] for a String or bytes.
-///
-/// [actualAssets] are the IDs that were recorded as written during the build.
-///
-/// Assets are checked against those that were written to [writer]. If other
-/// assets were written through the writer, but not as part of the build
-/// process, they will be ignored. Only the IDs in [actualAssets] are checked.
-///
-/// If assets are written to a location that does not match their logical
-/// association to a package pass [mapAssetIds] to translate from the logical
-/// location to the actual written location.
-void checkOutputs(
-    Map<String, /*List<int>|String|Matcher<String|List<int>>*/ dynamic> outputs,
-    Iterable<AssetId> actualAssets,
-    RecordingAssetWriter writer,
-    {AssetId Function(AssetId id) mapAssetIds = _passThrough}) {
-  var modifiableActualAssets = Set.from(actualAssets);
-  if (outputs != null) {
-    outputs.forEach((serializedId, contentsMatcher) {
-      assert(contentsMatcher is String ||
-          contentsMatcher is List<int> ||
-          contentsMatcher is Matcher);
-
-      var assetId = makeAssetId(serializedId);
-
-      // Check that the asset was produced.
-      expect(modifiableActualAssets, contains(assetId),
-          reason: 'Builder failed to write asset $assetId');
-      modifiableActualAssets.remove(assetId);
-      var actual = writer.assets[mapAssetIds(assetId)];
-      Object expected;
-      if (contentsMatcher is String) {
-        expected = utf8.decode(actual);
-      } else if (contentsMatcher is List<int>) {
-        expected = actual;
-      } else if (contentsMatcher is Matcher) {
-        expected = actual;
-      } else {
-        throw ArgumentError('Expected values for `outputs` to be of type '
-            '`String`, `List<int>`, or `Matcher`, but got `$contentsMatcher`.');
-      }
-      expect(expected, contentsMatcher,
-          reason: 'Unexpected content for $assetId in result.outputs.');
-    });
-    // Check that no extra assets were produced.
-    expect(modifiableActualAssets, isEmpty,
-        reason:
-            'Unexpected outputs found `$actualAssets`. Only expected $outputs');
-  }
-}
-
-/// Runs [builder] in a test environment.
-///
-/// The test environment supplies in-memory build [sourceAssets] to the builders
-/// under test. [outputs] may be optionally provided to verify that the builders
-/// produce the expected output. If [outputs] is omitted the only validation
-/// this method provides is that the build did not `throw`.
-///
-/// Either [generateFor] or the [isInput] callback can specify which assets
-/// should be given as inputs to the builder. These can be omitted if every
-/// asset in [sourceAssets] should be considered an input. [generateFor] is
-/// ignored if both [isInput] and [generateFor] are provided.
-///
-/// The keys in [sourceAssets] and [outputs] are paths to file assets and the
-/// values are file contents. The paths must use the following format:
-///
-///     PACKAGE_NAME|PATH_WITHIN_PACKAGE
-///
-/// Where `PACKAGE_NAME` is the name of the package, and `PATH_WITHIN_PACKAGE`
-/// is the path to a file relative to the package. `PATH_WITHIN_PACKAGE` must
-/// include `lib`, `web`, `bin` or `test`. Example: "myapp|lib/utils.dart".
-///
-/// If a [reader] is provided, then any asset not in [sourceAssets] will be
-/// read from the provided reader. This allows you to more easily provide
-/// sources of entire packages to the test, instead of mocking them out, for
-/// example, this exposes all assets available to the test itself:
-///
-///
-/// ```dart
-/// testBuilder(yourBuilder, {}/* test assets here */,
-///     reader: await PackageAssetReader.currentIsolate());
-/// ```
-///
-/// Callers may optionally provide a [writer] to stub different behavior or do
-/// more complex validation than what is possible with [outputs].
-///
-/// Callers may optionally provide an [onLog] callback to do validaiton on the
-/// logging output of the builder.
-Future testBuilder(
-    Builder builder, Map<String, /*String|List<int>*/ dynamic> sourceAssets,
-    {Set<String> generateFor,
-    bool Function(String assetId) isInput,
-    String rootPackage,
-    MultiPackageAssetReader reader,
-    RecordingAssetWriter writer,
-    Map<String, /*String|List<int>|Matcher<String|List<int>>*/ dynamic> outputs,
-    void Function(LogRecord log) onLog,
-    void Function(AssetId, Iterable<AssetId>)
-        reportUnusedAssetsForInput}) async {
-  writer ??= InMemoryAssetWriter();
-
-  var inputIds = {
-    for (var descriptor in sourceAssets.keys) makeAssetId(descriptor)
-  };
-  var allPackages = {for (var id in inputIds) id.package};
-  if (allPackages.length == 1) rootPackage ??= allPackages.first;
-
-  inputIds.addAll([
-    for (var package in allPackages) AssetId(package, r'lib/$lib$'),
-    if (rootPackage != null) ...[
-      AssetId(rootPackage, r'$package$'),
-      AssetId(rootPackage, r'test/$test$'),
-      AssetId(rootPackage, r'web/$web$'),
-    ]
-  ]);
-
-  final inMemoryReader = InMemoryAssetReader(rootPackage: rootPackage);
-
-  sourceAssets.forEach((serializedId, contents) {
-    var id = makeAssetId(serializedId);
-    if (contents is String) {
-      inMemoryReader.cacheStringAsset(id, contents);
-    } else if (contents is List<int>) {
-      inMemoryReader.cacheBytesAsset(id, contents);
-    }
-  });
-
-  isInput ??= generateFor?.contains ?? (_) => true;
-  inputIds.retainWhere((id) => isInput('$id'));
-
-  var writerSpy = AssetWriterSpy(writer);
-  var logger = Logger('testBuilder');
-  var logSubscription = logger.onRecord.listen(onLog);
-
-  for (var input in inputIds) {
-    // create another writer spy and reader for each input. This prevents writes
-    // from a previous input being readable when processing the current input.
-    final spyForStep = AssetWriterSpy(writerSpy);
-    final readerForStep = MultiAssetReader([
-      inMemoryReader,
-      if (reader != null) reader,
-      WrittenAssetReader(writer, spyForStep),
-    ]);
-
-    await runBuilder(
-        builder, {input}, readerForStep, spyForStep, defaultResolvers,
-        logger: logger, reportUnusedAssetsForInput: reportUnusedAssetsForInput);
-  }
-
-  await logSubscription.cancel();
-  var actualOutputs = writerSpy.assetsWritten;
-  checkOutputs(outputs, actualOutputs, writer);
-}
diff --git a/build_test/lib/src/written_asset_reader.dart b/build_test/lib/src/written_asset_reader.dart
deleted file mode 100644
index d24dbcb..0000000
--- a/build_test/lib/src/written_asset_reader.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-import 'in_memory_writer.dart';
-
-/// A [MultiPackageAssetReader] which supports reads from previous outputs.
-class WrittenAssetReader extends MultiPackageAssetReader {
-  final RecordingAssetWriter source;
-
-  /// An optional [AssetWriterSpy] to limit what's readable through this reader.
-  ///
-  /// Only assets reported as written trough this [AssetWriterSpy] can be read
-  /// from this reader. When null, all assets from [source] are available.
-  final AssetWriterSpy filterSpy;
-
-  WrittenAssetReader(this.source, [this.filterSpy]);
-
-  @override
-  Future<bool> canRead(AssetId id) {
-    var canRead = source.assets.containsKey(id);
-    if (filterSpy != null) {
-      canRead = canRead && filterSpy.assetsWritten.contains(id);
-    }
-
-    return Future.value(canRead);
-  }
-
-  @override
-  Stream<AssetId> findAssets(Glob glob, {String package}) async* {
-    var available = source.assets.keys.toSet();
-    if (filterSpy != null) {
-      available = available.intersection(filterSpy.assetsWritten.toSet());
-    }
-
-    for (var asset in available) {
-      if (!glob.matches(asset.path)) continue;
-      if (package != null && asset.package != package) continue;
-
-      yield asset;
-    }
-  }
-
-  @override
-  Future<List<int>> readAsBytes(AssetId id) {
-    if (!source.assets.containsKey(id)) {
-      throw AssetNotFoundException(id);
-    }
-    return Future.value(source.assets[id]);
-  }
-
-  @override
-  Future<String> readAsString(AssetId id, {Encoding encoding}) async {
-    encoding ??= utf8;
-    return encoding.decode(await readAsBytes(id));
-  }
-}
diff --git a/build_test/mono_pkg.yaml b/build_test/mono_pkg.yaml
deleted file mode 100644
index 912fda7..0000000
--- a/build_test/mono_pkg.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-        - dartfmt: sdk
-        - dartanalyzer: --fatal-infos --fatal-warnings .
-    - dartanalyzer: --fatal-warnings .
-      dart:
-        - 2.6.0
-  - unit_test:
-    - command: pub run build_runner test
-      os:
-        - linux
-        - windows
-
-cache:
-  directories:
-    - .dart_tool/build
diff --git a/build_test/pubspec.yaml b/build_test/pubspec.yaml
deleted file mode 100644
index 5f71f2f..0000000
--- a/build_test/pubspec.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: build_test
-description: Utilities for writing unit tests of Builders.
-version: 0.10.12+1
-homepage: https://github.com/dart-lang/build/tree/master/build_test
-
-environment:
-  sdk: ">=2.6.0 <3.0.0"
-
-dependencies:
-  async: ">=1.2.0 <3.0.0"
-  build: ">=1.2.0 <2.0.0"
-  build_config: ">=0.2.0 <0.5.0"
-  build_resolvers: ">=0.2.0 <2.0.0"
-  crypto: ">=0.9.2 <3.0.0"
-  glob: ^1.1.0
-  html: ">=0.9.0 <0.15.0"
-  logging: ^0.11.2
-  matcher: ^0.12.0
-  package_resolver: ^1.0.2
-  path: ^1.4.1
-  pedantic: ^1.0.0
-  stream_transform: ">=0.0.20 <2.0.0"
-  test: '>=0.12.42 <2.0.0'
-  test_core: '>=0.2.4 <0.4.0'
-  watcher: ^0.9.7
-
-dev_dependencies:
-  analyzer: ">=0.35.4 <0.40.0"
-  build_runner: ^1.3.3
-  build_vm_compilers: '>=0.1.2 <2.0.0'
-  collection: ^1.14.0
diff --git a/build_vm_compilers/BUILD.gn b/build_vm_compilers/BUILD.gn
deleted file mode 100644
index 7861884..0000000
--- a/build_vm_compilers/BUILD.gn
+++ /dev/null
@@ -1,22 +0,0 @@
-# This file is generated by importer.py for build_vm_compilers-1.0.4
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_vm_compilers") {
-  package_name = "build_vm_compilers"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/build",
-    "//third_party/dart-pkg/pub/build_config",
-    "//third_party/dart-pkg/pub/pool",
-    "//third_party/dart-pkg/pub/path",
-    "//third_party/dart-pkg/pub/build_modules",
-    "//third_party/dart-pkg/pub/analyzer",
-  ]
-}
diff --git a/build_vm_compilers/CHANGELOG.md b/build_vm_compilers/CHANGELOG.md
deleted file mode 100644
index cccd852..0000000
--- a/build_vm_compilers/CHANGELOG.md
+++ /dev/null
@@ -1,56 +0,0 @@
-## 1.0.4
-
-- Allow analyzer version `0.39.0`.
-
-## 1.0.3
-
-- Allow analyzer version `0.38.0`.
-
-## 1.0.2
-
-- Fix kernel concat ordering to be topological instead of reverse
-  topological.
-
-## 1.0.1
-
-- Allow analyzer version 0.37.0.
-
-## 1.0.0
-
-- Support build_modules 2.0.0
-  - Define our own `vm` platform and builders explicitly.
-- Skip trying to compile apps that import known incompatible libraries.
-
-## 0.1.2
-
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-- Require Dart SDK `>=2.1.0`.
-
-## 0.1.1+5
-
-- Increased the upper bound for `package:analyzer` to `<0.36.0`.
-
-## 0.1.1+4
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 0.1.1+3
-
-- Increased the upper bound for `package:analyzer` to `<0.34.0`.
-
-## 0.1.1+2
-
-Support `package:build_modules` version `1.x.x`.
-
-## 0.1.1+1
-
-Support `package:build` version `1.x.x`.
-
-## 0.1.1
-
-Support the latest build_modules.
-
-## 0.1.0
-
-Initial release, adds the modular kernel compiler for the vm platform, and the
-entrypoint builder which concatenates all the modules into a single kernel file.
diff --git a/build_vm_compilers/LICENSE b/build_vm_compilers/LICENSE
deleted file mode 100644
index c4dc9ba..0000000
--- a/build_vm_compilers/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_vm_compilers/README.md b/build_vm_compilers/README.md
deleted file mode 100644
index 971d656..0000000
--- a/build_vm_compilers/README.md
+++ /dev/null
@@ -1,70 +0,0 @@
-<p align="center">
-  Vm compilers for users of <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
-  <br>
-  <a href="https://travis-ci.org/dart-lang/build">
-    <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
-  </a>
-  <a href="https://github.com/dart-lang/build/labels/package%3A%20build_vm_compilers">
-    <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_vm_compilers.svg" alt="Issues related to build_vm_compilers" />
-  </a>
-  <a href="https://pub.dev/packages/build_vm_compilers">
-    <img src="https://img.shields.io/pub/v/build_vm_compilers.svg" alt="Pub Package Version" />
-  </a>
-  <a href="https://pub.dev/documentation/build_vm_compilers/latest">
-    <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
-  </a>
-  <a href="https://gitter.im/dart-lang/build">
-    <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
-  </a>
-</p>
-
-* [Installation](#installation)
-* [Usage](#usage)
-* [Configuration](#configuration)
-* [Manual Usage](#manual-usage)
-
-## Installation
-
-This package is intended to be used as a [development dependency][] for users
-of [`package:build`][] who want to run code in the Dart vm with precompiled
-kernel files. This allows you to share compilation of dependencies between
-multiple entrypoints, instead of doing a monolithic compile of each entrypoint
-like the Dart VM would normally do on each run.
-
-**Note**: If you want to use this package for running tests with
-`pub run build_runner test` you will also need a `build_test` dev dependency.
-
-## Usage
-
-This package creates a `.vm.app.dill` file corresponding to each `.dart` file
-that contains a `main` function.
-
-These files can be passed directly to the vm, instead of the dart script, and
-the vm will skip its initial parse and compile step.
-
-You can find the output either by using the `-o <dir>` option for build_runner,
-or by finding it in the generated cache directory, which is located at
-`.dart_tool/build/generated/<your-package>`.
-
-## Configuration
-
-There are no configuration options available at this time.
-
-## Custom Build Script Integration
-
-If you are using a custom build script, you will need to add the following
-builder applications to what you already have, sometime after the
-`build_modules` builder applications:
-
-```dart
-    apply('build_vm_compilers|entrypoint',
-        [vmKernelEntrypointBuilder], toRoot(),
-        hideOutput: true,
-        // These globs should match your entrypoints only.
-        defaultGenerateFor: const InputSet(
-            include: const ['bin/**', 'tool/**', 'test/**.vm_test.dart'])),
-]
-```
-
-[development dependency]: https://dart.dev/tools/pub/dependencies#dev-dependencies
-[`package:build`]: https://pub.dev/packages/build
diff --git a/build_vm_compilers/build.yaml b/build_vm_compilers/build.yaml
deleted file mode 100644
index 4b13b98..0000000
--- a/build_vm_compilers/build.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-builders:
-  modules:
-    import: "package:build_vm_compilers/builders.dart"
-    builder_factories:
-      - metaModuleBuilder
-      - metaModuleCleanBuilder
-      - moduleBuilder
-    build_extensions:
-      $lib$:
-        - .vm.meta_module.raw
-        - .vm.meta_module.clean
-      .dart:
-        - .vm.module
-    is_optional: True
-    auto_apply: none
-    required_inputs: [".dart", ".module.library"]
-    applies_builders: ["build_modules|module_cleanup"]
-  vm:
-    import: "package:build_vm_compilers/builders.dart"
-    builder_factories:
-      - vmKernelModuleBuilder
-    build_extensions:
-      .vm.module:
-        - .vm.dill
-    is_optional: True
-    auto_apply: all_packages
-    required_inputs:
-      - .dart
-      - .vm.module
-    applies_builders:
-      - build_vm_compilers|modules
-  entrypoint:
-    import: "package:build_vm_compilers/builders.dart"
-    builder_factories:
-      - vmKernelEntrypointBuilder
-    build_extensions:
-      .dart:
-        - .vm.app.dill
-    required_inputs:
-      - .dart
-      - .vm.dill
-      - .vm.module
-    build_to: cache
-    auto_apply: root_package
-    defaults:
-      generate_for:
-        include:
-          - bin/**
-          - tool/**
-          - test/**.dart.vm_test.dart
-          - example/**
-          - benchmark/**
diff --git a/build_vm_compilers/lib/build_vm_compilers.dart b/build_vm_compilers/lib/build_vm_compilers.dart
deleted file mode 100644
index e0ea675..0000000
--- a/build_vm_compilers/lib/build_vm_compilers.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-export 'src/platform.dart' show vmPlatform;
-export 'src/vm_entrypoint_builder.dart' show VmEntrypointBuilder;
diff --git a/build_vm_compilers/lib/builders.dart b/build_vm_compilers/lib/builders.dart
deleted file mode 100644
index 6848a54..0000000
--- a/build_vm_compilers/lib/builders.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:path/path.dart' as p;
-
-import 'src/platform.dart';
-import 'src/vm_entrypoint_builder.dart';
-
-const vmKernelModuleExtension = '.vm.dill';
-const vmKernelEntrypointExtension = '.vm.app.dill';
-
-Builder metaModuleBuilder(BuilderOptions options) =>
-    MetaModuleBuilder.forOptions(vmPlatform, options);
-Builder metaModuleCleanBuilder([_]) => MetaModuleCleanBuilder(vmPlatform);
-Builder moduleBuilder([_]) => ModuleBuilder(vmPlatform);
-
-Builder vmKernelModuleBuilder(_) => KernelBuilder(
-      summaryOnly: false,
-      sdkKernelPath: p.join('lib', '_internal', 'vm_platform_strong.dill'),
-      outputExtension: vmKernelModuleExtension,
-      platform: vmPlatform,
-    );
-
-Builder vmKernelEntrypointBuilder(_) => VmEntrypointBuilder();
diff --git a/build_vm_compilers/lib/src/platform.dart b/build_vm_compilers/lib/src/platform.dart
deleted file mode 100644
index 85bdf5c..0000000
--- a/build_vm_compilers/lib/src/platform.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build_modules/build_modules.dart';
-
-final vmPlatform = DartPlatform.register('vm', [
-  'async',
-  'cli',
-  'collection',
-  'convert',
-  'core',
-  'developer',
-  'io',
-  'isolate',
-  'math',
-  'mirrors',
-  'nativewrappers',
-  'profiler',
-  'typed_data',
-  'vmservice_io',
-  '_internal',
-]);
diff --git a/build_vm_compilers/lib/src/vm_entrypoint_builder.dart b/build_vm_compilers/lib/src/vm_entrypoint_builder.dart
deleted file mode 100644
index 03b520a..0000000
--- a/build_vm_compilers/lib/src/vm_entrypoint_builder.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// 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';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart';
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:pool/pool.dart';
-
-import '../builders.dart';
-import 'platform.dart';
-
-/// Because we hold bytes in memory we don't want to compile to many app entry
-/// points at once.
-final _buildPool = Pool(16);
-
-/// A builder which combines several [vmKernelModuleExtension] modules into a
-/// single [vmKernelEntrypointExtension] file, which represents an entire
-/// application.
-class VmEntrypointBuilder implements Builder {
-  const VmEntrypointBuilder();
-
-  @override
-  final buildExtensions = const {
-    '.dart': [vmKernelEntrypointExtension],
-  };
-
-  @override
-  Future<void> build(BuildStep buildStep) async {
-    await _buildPool.withResource(() async {
-      var dartEntrypointId = buildStep.inputId;
-      var isAppEntrypoint = await _isAppEntryPoint(dartEntrypointId, buildStep);
-      if (!isAppEntrypoint) return;
-
-      var moduleId =
-          buildStep.inputId.changeExtension(moduleExtension(vmPlatform));
-      var module = Module.fromJson(
-          json.decode(await buildStep.readAsString(moduleId))
-              as Map<String, dynamic>);
-
-      List<Module> transitiveModules;
-      try {
-        transitiveModules = await module
-            .computeTransitiveDependencies(buildStep, throwIfUnsupported: true);
-      } on UnsupportedModules catch (e) {
-        var librariesString = (await e.exactLibraries(buildStep).toList())
-            .map((lib) => AssetId(lib.id.package,
-                lib.id.path.replaceFirst(moduleLibraryExtension, '.dart')))
-            .join('\n');
-        log.warning('''
-Skipping compiling ${buildStep.inputId} for the vm because some of its
-transitive libraries have sdk dependencies that not supported on this platform:
-
-$librariesString
-
-https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-resolve-skipped-compiling-warnings
-''');
-        return;
-      }
-
-      var transitiveKernelModules = [
-        module.primarySource.changeExtension(vmKernelModuleExtension)
-      ].followedBy(transitiveModules.reversed.map(
-          (m) => m.primarySource.changeExtension(vmKernelModuleExtension)));
-      var appContents = <int>[];
-      for (var dependencyId in transitiveKernelModules) {
-        appContents.addAll(await buildStep.readAsBytes(dependencyId));
-      }
-      await buildStep.writeAsBytes(
-          buildStep.inputId.changeExtension(vmKernelEntrypointExtension),
-          appContents);
-    });
-  }
-}
-
-/// Returns whether or not [dartId] is an app entrypoint (basically, whether
-/// or not it has a `main` function).
-Future<bool> _isAppEntryPoint(AssetId dartId, AssetReader reader) async {
-  assert(dartId.extension == '.dart');
-  // Skip reporting errors here, dartdevc will report them later with nicer
-  // formatting.
-  // ignore: deprecated_member_use
-  var parsed = parseCompilationUnit(await reader.readAsString(dartId),
-      suppressErrors: true);
-  // Allow two or fewer arguments so that entrypoints intended for use with
-  // [spawnUri] get counted.
-  //
-  // TODO: This misses the case where a Dart file doesn't contain main(),
-  // but has a part that does, or it exports a `main` from another library.
-  return parsed.declarations.any((node) {
-    return node is FunctionDeclaration &&
-        node.name.name == 'main' &&
-        node.functionExpression.parameters.parameters.length <= 2;
-  });
-}
diff --git a/build_vm_compilers/mono_pkg.yaml b/build_vm_compilers/mono_pkg.yaml
deleted file mode 100644
index c79ba5d..0000000
--- a/build_vm_compilers/mono_pkg.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-        - dartfmt: sdk
-        - dartanalyzer: --fatal-infos --fatal-warnings .
-    - dartanalyzer: --fatal-warnings .
-      dart:
-        - 2.5.0
-  - unit_test:
-    - test:
-      os:
-        - linux
-        - windows
diff --git a/build_vm_compilers/pubspec.yaml b/build_vm_compilers/pubspec.yaml
deleted file mode 100644
index f9257d2..0000000
--- a/build_vm_compilers/pubspec.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: build_vm_compilers
-version: 1.0.4
-description: Builder implementations wrapping Dart VM compilers.
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/build/tree/master/build_vm_compilers
-
-environment:
-  sdk: ">=2.5.0 <3.0.0"
-
-dependencies:
-  analyzer: ">=0.35.0 <0.40.0"
-  build: ^1.0.0
-  build_config: ">=0.3.0 <0.5.0"
-  build_modules: ^2.0.0
-  path: ^1.6.0
-  pool: ^1.3.0
-
-dev_dependencies:
-  build_runner: ^1.0.0
-  test: ^1.0.0
-  test_descriptor: ^1.1.0
-  _test_common:
-    path: ../_test_common
diff --git a/build_web_compilers/BUILD.gn b/build_web_compilers/BUILD.gn
deleted file mode 100644
index d5652c7..0000000
--- a/build_web_compilers/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is generated by importer.py for build_web_compilers-2.9.0
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_web_compilers") {
-  package_name = "build_web_compilers"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/stack_trace",
-    "//third_party/dart-pkg/pub/glob",
-    "//third_party/dart-pkg/pub/analyzer",
-    "//third_party/dart-pkg/pub/js",
-    "//third_party/dart-pkg/pub/meta",
-    "//third_party/dart-pkg/pub/scratch_space",
-    "//third_party/dart-pkg/pub/collection",
-    "//third_party/dart-pkg/pub/path",
-    "//third_party/dart-pkg/pub/source_span",
-    "//third_party/dart-pkg/pub/build_modules",
-    "//third_party/dart-pkg/pub/bazel_worker",
-    "//third_party/dart-pkg/pub/pool",
-    "//third_party/dart-pkg/pub/source_maps",
-    "//third_party/dart-pkg/pub/logging",
-    "//third_party/dart-pkg/pub/crypto",
-    "//third_party/dart-pkg/pub/archive",
-    "//third_party/dart-pkg/pub/build",
-    "//third_party/dart-pkg/pub/build_config",
-  ]
-}
diff --git a/build_web_compilers/CHANGELOG.md b/build_web_compilers/CHANGELOG.md
deleted file mode 100644
index 774e4a0..0000000
--- a/build_web_compilers/CHANGELOG.md
+++ /dev/null
@@ -1,544 +0,0 @@
-## 2.9.0
-
-- Add support for enabling experiments through the `experiments` option on the
-  `build_web_compilers|ddc` builder. This must be configured globally.
-  - This is a list of experiment names, which translates into
-    `--enable-experiment=<name>` arguments.
-
-## 2.8.0
-
-- Enable asserts in dev mode with dart2js by default.
-
-## 2.7.2
-
-- Fix a bug with hot restart,
-  [#2586](https://github.com/dart-lang/build/issues/2586).
-
-## 2.7.1
-
-- Allow analyzer version `0.39.x`.
-
-## 2.7.0
-
-- Added an `environment` option to the `DevCompilerBuilder`.
-  - This can be configured using the `environment` option of the
-    `build_web_compilers|ddc` builder.
-  - The expected value is a `Map<String, String>` and is equivalent to
-    providing `-D<key>=<value>` command line arguments.
-  - This option should only be set globally, and will throw if it ever recieves
-    two different values. This is to ensure all modules are compiled with the
-    same environment.
-
-## 2.6.4
-
-- Deobfuscate DDC extension method stack traces.
-
-## 2.6.3
-
-- Enforce builder application ordering between the SDK JS copy builder and the
-  DDC entrypoint builder.
-
-## 2.6.2
-
-Fix the skipPlatformCheck option which was accidentally doing the opposite
-of what it claimed.
-
-## 2.6.1
-
-- Use the kernel version of `dart_sdk.js` rather than the analyzer version.
-
-## 2.6.0
-
-Add an option to globally skip the platform checks instead of only skipping
-them for a set of whitelisted packages.
-
-## 2.5.2
-
-Republish of `2.5.0` with the proper min sdk contraint.
-
-## 2.5.1
-
-### Bug fix for issue #2464
-
-Ignore the `trackUnusedInputs` option that was added in `2.5.0`.
-
-This option will be respected again in the next release which will have the
-proper minimum sdk constraint.
-
-## 2.5.0
-
-Add support for dependency pruning to the `DevCompilerBuilder`. This should
-greatly improve the invalidation semantics for builds, meaning that less code
-will be recompiled for each edit you make.
-
-This is enabled by default when using build_runner, and can be disabled using
-the `track-unused-inputs: false` option if you run into issues, so in your
-`build.yaml` it would look like this:
-
-```yaml
-targets:
-  $default:
-    build_web_compilers:ddc:
-      options:
-        track-unused-inputs: false
-```
-
-When using the builder programatically it is disabled by default and can be
-enabled by passing `trackUnusedInputs: true` to the `DevCompilerBuilder`
-constructor.
-
-## 2.4.1
-
-Make the required assets for DDC applications configurable in the
-`bootstrapDdc` method instead of hard coded. This allows custom integrations
-like flutter web to not require the same assets, or require additional custom
-assets.
-
-## 2.4.0
-
-### New Feature: Better --build-filter support for building a single test.
-
-You can now build a basic app or test in isolation by only requesting the
-`*.dart.js` file using a build filter, for example adding this argument to any
-build_runner command would build the `web/main.dart` app only:
-`--build-filter=web/main.dart.js`.
-
-For tests you will need to specify the bootstrapped test file, so:
-`--build-filter=test/hello_world.dart.browser_test.dart.js`.
-
-Previously you also had to explicitly require the SDK resources like:
-`--build-filter="package:build_web_compilers/**.js"` or similar.
-
-**Note**: If your app relies on any non-Dart generated files you will likely
-have to ask for those explicitly as well with additinal filters.
-
-## 2.3.0
-
-- Add an option to the DDC bootstrap to skip the checks around modules that have
-  imports to unsupported SDK libraries like `dart:io` when the module is from a
-  specified package. This is not used in the default build, but is available for
-  custom DDC integrations.
-
-## 2.2.3
-
-- Allow analyzer version 0.38.0.
-
-## 2.2.2
-
-- Re-publish 2.2.0 with proper minimum sdk constraint of >=2.4.0.
-
-## 2.2.1
-
-- Revert of bad 2.2.0 release (had a bad min sdk).
-
-## 2.2.0
-
-- Make `librariesPath` configurable in `DevCompilerBuilder`.
-
-## 2.1.5
-
-- Add pre-emptive support for an upcoming breaking change in ddc
-  around entrypoint naming.
-
-## 2.1.4
-
-- Allow analyzer version 0.37.0.
-
-## 2.1.3
-
-- Improve error message when `dart2js_args` is configured improperly.
-
-## 2.1.2
-
-- Fix hot restart bootstrapping logic for dart scripts that live in a
-  different directory than the html file.
-
-## 2.1.1
-
-- Prepare for source map change from dartdevc, don't modify relative paths in
-  source maps.
-- Fix hot reload bootstrap logic for app entrypoints under lib.
-
-## 2.1.0
-
-- Make `platformSdk`, `sdkKernelPath`, and `platform` configurable in
-  `DevCompilerBuilder`.
-
-## 2.0.2
-
-- Prepare for the next sdk release, which changes what the uris look like for
-  non-package sources, and breaks our existing hot restart logic.
-
-## 2.0.1
-
-- Fix issue #2269, which could cause applications to fail to properly bootstrap.
-- Skip compiling modules with ddc when the primary source isn't the primary
-  input (only shows up in non-lazy builds - essentially just tests).
-
-## 2.0.0
-
-### Major Update - Switch to use the common front end.
-
-In this release, the Dart front end for the `dev_compiler` is changing from the
-[analyzer] to the common [front end][front_end]. This should unify error
-messages and general consistency across platforms, as this was one of the last
-compilers left still using the analyzer as a front end.
-
-While this is intended to be a transparent change, it is likely that there will
-be unintended differences. Please [file issues][issue tracker] if you experience
-something that seems broken or not working as intended.
-
-### Major Update - Auto-detection of web support for applications
-
-Previously, all files with a `main` that were matched by the input globs would
-attempt to compile for the web. This caused an issue when there were non-web
-applications in the default directories, which specifically happens a lot in the
-`test` directory. Resolving this required custom globs in `build.yaml` files.
-
-Two changes were made to help handle this issue more gracefully, in a way that
-often doesn't require custom `build.yaml` files any more.
-
-- Before compiling any app, build_web_compilers will check that all its
-  transitive modules are compatible with the web (based on their `dart:`
-  imports).
-  - Today we will log a warning message for any app that isn't compatible, as
-    ultimately it is most efficient to exclude these using globs in your
-    `build.yaml` than waiting for us to detect it. This may change based on
-    feedback.
-- Changed the default glob for the `test` directory to only include the
-  `test/**.dart.browser_test.dart` files (other dirs remain unchanged).
-  - Note that as a result of this, serving the `test` dir and running tests that
-    way no longer works, as those entrypoints won't be compiled. You would need
-    to configure the `generate_for` to explicitly include `test/**_test.dart`
-    to restore that functionality (we will continue pushing on this in the
-    future though to restore similar functionality).
-  - Also note that the `build_test` package will now output
-    `<platform>_test.dart` files based on your [TestOn] annotations, so using
-    those where possible will help reduce build platform support warnings as
-    well.
-
-### Additional Notes
-
-- Update to run DDC in kernel mode, and consume kernel outlines instead of
-  analyzer summaries.
-- Skip trying to compile apps that import known incompatible libraries.
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-- Removed support for `build_root_app_summary` configuration option.
-- Combine the `ddc_kernel` and `ddc` workers under a single name (`ddc`).
-- By default only `.dart.browser_test.dart` files will be compiled under the
-  `test` directory, instead of all `_test.dart` files.
-  - If you used the previous test debugging workflow in the browser you can
-    restore the old behavior with something like the following in your
-    build.yaml:
-
-```yaml
-targets:
-  $default:
-    builders:
-      build_web_compilers|entrypoint:
-        generate_for:
-        - test/**_test.dart
-        - web/**.dart
-```
-
-- Added the `use-incremental-compiler` option for the `build_web_compilers:ddc`
-  builder. This is enabled by default but can be disabled if running into build
-  issues by setting it to `false` globally:
-
-```yaml
-global_options:
-  build_web_compilers:ddc:
-    options:
-      use-incremental-compiler: false
-```
-
-- This package now makes its own copy of the `dart_sdk.js` and `require.js`
-  files, which it deletes during production builds.
-  - In a future build_runner release we will be deleting the entire `$sdk`
-    package to resolve some issues with build output bloat.
-  - If you are using `dartdevc` as your production compiler, you will need to
-    disable the cleanup builder in `build.yaml` (globally) like this:
-
-```yaml
-global_options:
-  build_web_compilers|sdk_js_cleanup:
-    release_options:
-      enabled: false
-```
-
-[analyzer]: https://pub.dev/packages/analyzer
-[front_end]: https://pub.dev/packages/front_end
-[issue tracker]: https://github.com/dart-lang/build/issues/new
-[TestOn]: https://pub.dev/documentation/test/latest/#restricting-tests-to-certain-platforms
-
-## 1.2.2
-
-- Allow build_config 0.4.x.
-
-## 1.2.1
-
-- Allow analyzer version 0.36.x.
-
-## 1.2.0
-
-- Add a marker to inject code before the application main method is called.
-- During a hot restart we will now clear all statics before re-invoking main.
-
-## 1.1.0
-
-- Output a `.digests` file which contains transitive digests for an entrypoint.
-
-## 1.0.2
-
-- Improved the time tracking for ddc actions by not reporting time spent waiting
-  for a worker to be available.
-
-## 1.0.1
-
-- Increased the upper bound for `package:analyzer` to `<0.36.0`.
-
-## 1.0.0
-
-- Removed the `enable_sync_async` and `ignore_cast_failures` options for the
-  `build_web_compilers|entrypoint` builder. These will no longer have any effect
-  and will give a build time warning if you try to use them.
-
-## 0.4.4+3
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 0.4.4+2
-
-- Support `package:analyzer` version `0.33.x`.
-
-## 0.4.4+1
-
-- Support `package:build_modules` version `1.x.x`.
-
-## 0.4.4
-
-- Track performance of different builder stages.
-
-## 0.4.3+1
-
-- Removed dependency on cli_util.
-- Fix error in require.js error handling code
-
-## 0.4.3
-
-- Only call `window.postMessage` during initialization if the current context
-  is a `Window`.
-- Fixed an error while showing stack traces for DDC generated scripts
-  when `<base>` tag is used.
-- Value of `<base href="/.../">` tag should start and end with a `/` to be
-  used as the base url for require js.
-- Added more javascript code to dev bootstrap for hot-reloading support
-- Support the latest build_modules.
-
-## 0.4.2+2
-
-- Add magic comment marker for build_runner to know where to inject
-  live-reloading client code. This is only present when using the `dartdevc`
-  compiler. (reapplied)
-
-## 0.4.2+1
-
-- Restore `new` keyword for a working release on Dart 1 VM.
-
-## 0.4.2
-
-- Add magic comment marker for build_runner to know where to inject
-  live-reloading client code. This is only present when using the `dartdevc`
-  compiler.
-- Release broken on Dart 1 VM.
-
-## 0.4.1
-
-- Support the latest build_modules, with updated dart2js support so that it can
-  do multiple builds concurrently and will restart workers periodically to
-  mitigate the effects of dart-lang/sdk#33708.
-- Improvements to reduce the memory usage of the dart2js builder, so that
-  transitive dependency information can be garbage collected before the dart2js
-  compile is completed.
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.4.0+5
-
-- Fixed an issue where subdirectories with hyphens in the name weren't
-  bootstrapped properly in dartdevc.
-
-## 0.4.0+4
-
-- Expand support for `package:build_config` to include version `0.3.x`.
-
-## 0.4.0+3
-
-- Expand support for `package:archive` to include version `2.x.x`.
-
-## 0.4.0+2
-
-- Fix a dart2 error.
-
-## 0.4.0+1
-
-- Support `package:analyzer` `0.32.0`.
-
-## 0.4.0
-
-- Changed the default for `enable_sync_async` to `true` for the
-  `build_web_compilers|entrypoint` builder.
-- Changed the default for `ignore_cast_failures` to `false` for the
-  `build_web_compilers|entrypoint` builder.
-
-## 0.3.8
-
-- Remove `.dart` sources and `.js.map` files from the output directory in
-  release mode.
-- Clean up `.tar.gz` outputs produced by `Dart2Js.`
-- Don't output extra `Dart2Js` outputs other than deferred part files.
-- Fixed a logical error in `dartdevc` compiler to detect correct base url for
-  require js.
-- Added a `enable_sync_async` option to the `build_web_compilers|entrypoint`
-  builder, which defaults to `false`.
-
-## 0.3.7+3
-
-- The `dartdevc` compiler now respects the `<base href="/....">` tags and will
-  set them as the base url for require js.
-
-## 0.3.7+2
-
-- Fix sdk stack trace folding in the browser console and package:test.
-
-## 0.3.7+1
-
-- Add missing dependency on the `pool` package.
-
-## 0.3.7
-
-- Reduce memory usage by requesting (and lazily building) lower level modules
-  first when building for an entrypoint.
-
-## 0.3.6
-
-- Add support for compiling with `dart2js` by default in release mode.
-
-## 0.3.5
-
-- Don't ignore cast failures by default. We expect most code to be clean with
-  cast failures, and the option can be manually enabled with config.
-
-## 0.3.4+2
-
-- Create `.packages` file and use the new frontend with `dart2js`.
-
-## 0.3.4+1
-
-- Use `--use-old-frontend` with `dart2js` as a stopgap until we can add support
-  for `.packages` files.
-
-## 0.3.4
-
-- Added support for dart2js deferred loading.
-- Added support for bootstrapping code in web workers with `dartdevc`.
-
-## 0.3.3
-
-- Added support for `--dump-info` and the `dart2js` compiler. If you pass that
-  argument with `dart2js_args` the `.info.json` file will be copied the output.
-
-## 0.3.2
-
-- Dart2JS now has minification (`--minify`) enabled by default, similar to how
-  it worked in `pub build`. If you are adding custom `dart2js` options, make
-  sure you still keep the `--minify` flag. Here is an example:
-
-```yaml
-targets:
-  $default:
-    builders:
-      build_web_compilers|entrypoint:
-        generate_for:
-        - web/**.dart
-        options:
-          compiler: dart2js
-          dart2js_args:
-          - --fast-startup
-          - --minify
-          - --trust-type-annotations
-          - --trust-primitives
-```
-
-## 0.3.1
-
-- Cast failures will now be ignored in dartdevc by default (these were enabled
-  in the latest sdk), and added an `ignore_cast_failures` option to the
-  `build_web_compilers|entrypoint` builder which you can set to `true` to enable
-  them.
-  - At some point in the future it is expected that the default for this will
-    flip.
-
-## 0.3.0+1
-
-- Fixed an issue with `dart2js` and the `--no-source-maps` flag.
-
-## 0.3.0
-
-### Breaking changes
-
-- Split `ModuleBuilder`, `UnlinkedSummaryBuilder` and `LinkedSummaryBuilder`
-  into a separate `build_modules` package.
-
-## 0.2.1+1
-
-- Support the latest `analyzer` package.
-
-## 0.2.1
-
-- All dart files under `test` are now compiled by default instead of only the
-  `_browser_test.dart` files (minus vm/node test bootstrap files). This means
-  the original tests can be debugged directly (prior to package:test
-  bootstrapping).
-- Updated to `package:build` version `0.12.0`.
-
-## 0.2.0
-
-### New Features
-
-- Added support for `dart2js`. This can be configured using the top level
-  `compiler` option for the `build_web_compilers|entrypoint` builder. The
-  supported options are `dartdevc` (the default) and `dart2js`. Args can be
-  passed to `dart2js` using the `dart2js_args` option. For example:
-
-```yaml
-targets:
-  <my_package>:
-    builders:
-      build_web_compilers|entrypoint:
-        options:
-          compiler: dart2js
-          dart2js_args:
-          - --minify
-```
-
-### Breaking Changes
-
-- Renamed `ddc_bootstrap` builder to `entrypoint`, the exposed class also
-  changed from `DevCompilerBootstrapBuilder` to `WebEntrypointBuilder`.
-- Renamed `jsBootstrapExtension` to `ddcBootstrapExtension` since it is only
-  required when using the dev compiler.
-
-## 0.1.1
-
-- Mark `ddc_bootstrap` builder with `build_to: cache`.
-- Publish as `build_web_compilers`
-
-## 0.1.0
-
-- Add builder factories.
-- Fixed temp dir cleanup bug on windows.
-- Enabled support for running tests in --precompiled mode.
-
-## 0.0.1
-
-- Initial release with support for building analyzer summaries and DDC modules.
diff --git a/build_web_compilers/LICENSE b/build_web_compilers/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/build_web_compilers/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_web_compilers/README.md b/build_web_compilers/README.md
deleted file mode 100644
index 4667d45..0000000
--- a/build_web_compilers/README.md
+++ /dev/null
@@ -1,101 +0,0 @@
-<p align="center">
-  Web compilers for users of <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
-  <br>
-  <a href="https://travis-ci.org/dart-lang/build">
-    <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
-  </a>
-  <a href="https://github.com/dart-lang/build/labels/package%3A%20build_web_compilers">
-    <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_web_compilers.svg" alt="Issues related to build_web_compilers" />
-  </a>
-  <a href="https://pub.dev/packages/build_web_compilers">
-    <img src="https://img.shields.io/pub/v/build_web_compilers.svg" alt="Pub Package Version" />
-  </a>
-  <a href="https://pub.dev/documentation/build_web_compilers/latest">
-    <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
-  </a>
-  <a href="https://gitter.im/dart-lang/build">
-    <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
-  </a>
-</p>
-
-* [Installation](#installation)
-* [Usage](#usage)
-* [Configuration](#configuration)
-* [Manual Usage](#manual-usage)
-
-## Installation
-
-This package is intended to be used as a [development dependency][] for users
-of [`package:build`][] who want to run code in a browser. Simply add the
-following to your `pubspec.yaml`:
-
-```yaml
-dev_dependencies:
-  build_web_compilers:
-```
-
-## Usage
-
-If you are using the autogenerated build script (going through
-`pub run build_runner <command>` instead of handwriting a `build.dart` file),
-then all you need is the `dev_dependency` listed above.
-
-## Configuration
-
-By default, the `dartdevc` compiler will be used, which is the Dart Development
-Compiler.
-
-If you would like to opt into `dart2js` you will need to add a `build.yaml`
-file, which should look roughly like the following:
-
-```yaml
-targets:
-  $default:
-    builders:
-      build_web_compilers|entrypoint:
-        # These are globs for the entrypoints you want to compile.
-        generate_for:
-        - test/**.browser_test.dart
-        - web/**.dart
-        options:
-          compiler: dart2js
-          # List any dart2js specific args here, or omit it.
-          dart2js_args:
-          - -O2
-```
-
-## Manual Usage
-
-If you are using a custom build script, you will need to add the following
-builder applications to what you already have, almost certainly at the end of
-the list (unless you need to post-process the js files).
-
-```dart
-[
-    apply(
-        'build_web_compilers|ddc',
-        [
-        (_) => new ModuleBuilder(),
-        (_) => new UnlinkedSummaryBuilder(),
-        (_) => new LinkedSummaryBuilder(),
-        (_) => new DevCompilerBuilder()
-        ],
-        toAllPackages(),
-        // Recommended, but not required. This makes it so only modules that are
-        // imported by entrypoints get compiled.
-        isOptional: true,
-        hideOutput: true),
-    apply('build_web_compilers|entrypoint',
-        // You can also use `WebCompiler.Dart2Js`. If you don't care about
-        // dartdevc at all you may also omit the previous builder application
-        // entirely.
-        [(_) => new WebEntrypointBuilder(WebCompiler.DartDevc)], toRoot(),
-        hideOutput: true,
-        // These globs should match your entrypoints only.
-        defaultGenerateFor: const InputSet(
-            include: const ['web/**', 'test/**.browser_test.dart'])),
-]
-```
-
-[development dependency]: https://dart.dev/tools/pub/dependencies#dev-dependencies
-[`package:build`]: https://pub.dev/packages/build
diff --git a/build_web_compilers/build.yaml b/build_web_compilers/build.yaml
deleted file mode 100644
index c858018..0000000
--- a/build_web_compilers/build.yaml
+++ /dev/null
@@ -1,149 +0,0 @@
-targets:
-  $default:
-    builders:
-      build_web_compilers|entrypoint:
-        options:
-          compiler: dart2js
-          dart2js_args:
-            - -O4
-        enabled: true
-        generate_for:
-          - web/stack_trace_mapper.dart
-      build_web_compilers|_stack_trace_mapper_copy:
-        enabled: true
-      build_web_compilers|sdk_js_copy:
-        enabled: true
-      build_web_compilers|sdk_js_cleanup:
-        enabled: true
-builders:
-  sdk_js_copy:
-    import: "package:build_web_compilers/builders.dart"
-    builder_factories:
-      - sdkJsCopyBuilder
-    build_extensions:
-      $lib$:
-        - src/dev_compiler/dart_sdk.js
-        - src/dev_compiler/require.js
-    is_optional: False
-    auto_apply: none
-    applies_builders: ["build_web_compilers|sdk_js_cleanup"]
-    runs_before: ["build_web_compilers|entrypoint"]
-  dart2js_modules:
-    import: "package:build_web_compilers/builders.dart"
-    builder_factories:
-      - dart2jsMetaModuleBuilder
-      - dart2jsMetaModuleCleanBuilder
-      - dart2jsModuleBuilder
-    build_extensions:
-      $lib$:
-        - .dart2js.meta_module.raw
-        - .dart2js.meta_module.clean
-      .dart:
-        - .dart2js.module
-    is_optional: True
-    auto_apply: none
-    required_inputs: [".dart", ".module.library"]
-    applies_builders: ["build_modules|module_cleanup"]
-  ddc_modules:
-    import: "package:build_web_compilers/builders.dart"
-    builder_factories:
-      - ddcMetaModuleBuilder
-      - ddcMetaModuleCleanBuilder
-      - ddcModuleBuilder
-    build_extensions:
-      $lib$:
-        - .ddc.meta_module.raw
-        - .ddc.meta_module.clean
-      .dart:
-        - .ddc.module
-    is_optional: True
-    auto_apply: none
-    required_inputs: [".dart", ".module.library"]
-    applies_builders: ["build_modules|module_cleanup"]
-  ddc:
-    import: "package:build_web_compilers/builders.dart"
-    builder_factories:
-      - ddcKernelBuilder
-      - ddcBuilder
-    build_extensions:
-      .ddc.module:
-        - .ddc.dill
-        - .ddc.js.errors
-        - .ddc.js
-        - .ddc.js.map
-    is_optional: True
-    auto_apply: all_packages
-    required_inputs:
-      - .ddc.module
-    applies_builders:
-      - build_web_compilers|ddc_modules
-      # This isn't really the best place to apply these, but it is the only
-      # place we can (its the only builder which runs on all packages).
-      - build_web_compilers|dart2js_modules
-      - build_web_compilers|dart_source_cleanup
-  entrypoint:
-    import: "package:build_web_compilers/builders.dart"
-    builder_factories:
-      - webEntrypointBuilder
-    build_extensions:
-      .dart:
-        - .dart.bootstrap.js
-        - .dart.js
-        - .dart.js.map
-        - .dart.js.tar.gz
-        - .digests
-    required_inputs:
-      - .dart
-      - .ddc.js
-      - .ddc.module
-      - .dart2js.module
-    build_to: cache
-    auto_apply: root_package
-    defaults:
-      generate_for:
-        include:
-          - web/**
-          - test/**.dart.browser_test.dart
-          - example/**
-          - benchmark/**
-        exclude:
-          - test/**.node_test.dart
-          - test/**.vm_test.dart
-      options:
-        dart2js_args:
-          - --minify
-      dev_options:
-        dart2js_args:
-          - --enable-asserts
-      release_options:
-        compiler: dart2js
-    applies_builders:
-      - build_web_compilers|dart2js_archive_extractor
-  _stack_trace_mapper_copy:
-    import: "tool/copy_builder.dart"
-    builder_factories:
-        - copyBuilder
-    build_extensions:
-      web/stack_trace_mapper.dart.js:
-        - lib/src/dev_compiler_stack_trace/stack_trace_mapper.dart.js
-    auto_apply: none
-    build_to: source
-post_process_builders:
-  dart2js_archive_extractor:
-    import: "package:build_web_compilers/builders.dart"
-    builder_factory: dart2jsArchiveExtractor
-    defaults:
-      release_options:
-        filter_outputs: true
-  dart_source_cleanup:
-    import: "package:build_web_compilers/builders.dart"
-    builder_factory: dartSourceCleanup
-    defaults:
-      release_options:
-        enabled: true
-  sdk_js_cleanup:
-    import: "package:build_web_compilers/builders.dart"
-    builder_factory: sdkJsCleanupBuilder
-    defaults:
-      release_options:
-        enabled: true
diff --git a/build_web_compilers/dart_test.yaml b/build_web_compilers/dart_test.yaml
deleted file mode 100644
index f2869e5..0000000
--- a/build_web_compilers/dart_test.yaml
+++ /dev/null
@@ -1 +0,0 @@
-timeout: 2x
diff --git a/build_web_compilers/lib/build_web_compilers.dart b/build_web_compilers/lib/build_web_compilers.dart
deleted file mode 100644
index 95e26a5..0000000
--- a/build_web_compilers/lib/build_web_compilers.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.
-
-export 'src/archive_extractor.dart' show Dart2JsArchiveExtractor;
-export 'src/dev_compiler_builder.dart'
-    show
-        DevCompilerBuilder,
-        jsModuleErrorsExtension,
-        jsModuleExtension,
-        jsSourceMapExtension;
-export 'src/platforms.dart' show dart2jsPlatform, ddcPlatform;
-export 'src/web_entrypoint_builder.dart'
-    show WebCompiler, WebEntrypointBuilder, ddcBootstrapExtension;
diff --git a/build_web_compilers/lib/builders.dart b/build_web_compilers/lib/builders.dart
deleted file mode 100644
index 255fa5d..0000000
--- a/build_web_compilers/lib/builders.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:collection/collection.dart';
-import 'package:path/path.dart' as p;
-
-import 'build_web_compilers.dart';
-import 'src/common.dart';
-import 'src/platforms.dart';
-import 'src/sdk_js_copy_builder.dart';
-
-// Shared entrypoint builder
-Builder webEntrypointBuilder(BuilderOptions options) =>
-    WebEntrypointBuilder.fromOptions(options);
-
-// Ddc related builders
-Builder ddcMetaModuleBuilder(BuilderOptions options) =>
-    MetaModuleBuilder.forOptions(ddcPlatform, options);
-Builder ddcMetaModuleCleanBuilder(_) => MetaModuleCleanBuilder(ddcPlatform);
-Builder ddcModuleBuilder([_]) => ModuleBuilder(ddcPlatform);
-Builder ddcBuilder(BuilderOptions options) {
-  validateOptions(options.config, _supportedOptions, 'build_web_compilers:ddc');
-  _ensureSameDdcOptions(options);
-
-  return DevCompilerBuilder(
-    useIncrementalCompiler: _readUseIncrementalCompilerOption(options),
-    trackUnusedInputs: _readTrackInputsCompilerOption(options),
-    platform: ddcPlatform,
-    environment: _readEnvironmentOption(options),
-    experiments: _readExperimentOption(options),
-  );
-}
-
-const ddcKernelExtension = '.ddc.dill';
-Builder ddcKernelBuilder(BuilderOptions options) {
-  validateOptions(options.config, _supportedOptions, 'build_web_compilers:ddc');
-  _ensureSameDdcOptions(options);
-
-  return KernelBuilder(
-      summaryOnly: true,
-      sdkKernelPath: p.url.join('lib', '_internal', 'ddc_sdk.dill'),
-      outputExtension: ddcKernelExtension,
-      platform: ddcPlatform,
-      useIncrementalCompiler: _readUseIncrementalCompilerOption(options),
-      trackUnusedInputs: _readTrackInputsCompilerOption(options),
-      experiments: _readExperimentOption(options));
-}
-
-Builder sdkJsCopyBuilder(_) => SdkJsCopyBuilder();
-PostProcessBuilder sdkJsCleanupBuilder(BuilderOptions options) =>
-    FileDeletingBuilder(
-        ['lib/src/dev_compiler/dart_sdk.js', 'lib/src/dev_compiler/require.js'],
-        isEnabled: options.config['enabled'] as bool ?? false);
-
-// Dart2js related builders
-Builder dart2jsMetaModuleBuilder(BuilderOptions options) =>
-    MetaModuleBuilder.forOptions(dart2jsPlatform, options);
-Builder dart2jsMetaModuleCleanBuilder(_) =>
-    MetaModuleCleanBuilder(dart2jsPlatform);
-Builder dart2jsModuleBuilder([_]) => ModuleBuilder(dart2jsPlatform);
-PostProcessBuilder dart2jsArchiveExtractor(BuilderOptions options) =>
-    Dart2JsArchiveExtractor.fromOptions(options);
-
-// General purpose builders
-PostProcessBuilder dartSourceCleanup(BuilderOptions options) =>
-    (options.config['enabled'] as bool ?? false)
-        ? const FileDeletingBuilder(['.dart', '.js.map'])
-        : const FileDeletingBuilder(['.dart', '.js.map'], isEnabled: false);
-
-/// Throws if it is ever given different options.
-void _ensureSameDdcOptions(BuilderOptions options) {
-  if (_previousDdcConfig != null) {
-    if (!const MapEquality().equals(_previousDdcConfig, options.config)) {
-      throw ArgumentError(
-          'The build_web_compilers:ddc builder must have the same '
-          'configuration in all packages. Saw $_previousDdcConfig and '
-          '${options.config} which are not equal.\n\n '
-          'Please use the `global_options` section in '
-          '`build.yaml` or the `--define` flag to set global options.');
-    }
-  } else {
-    _previousDdcConfig = options.config;
-  }
-}
-
-bool _readUseIncrementalCompilerOption(BuilderOptions options) {
-  return options.config[_useIncrementalCompilerOption] as bool ?? true;
-}
-
-bool _readTrackInputsCompilerOption(BuilderOptions options) {
-  return options.config[_trackUnusedInputsCompilerOption] as bool ?? true;
-}
-
-Map<String, String> _readEnvironmentOption(BuilderOptions options) {
-  return Map.from((options.config[_environmentOption] as Map) ?? {});
-}
-
-List<String> _readExperimentOption(BuilderOptions options) {
-  return List.from((options.config[_experimentOption] as List) ?? []);
-}
-
-Map<String, dynamic> _previousDdcConfig;
-const _useIncrementalCompilerOption = 'use-incremental-compiler';
-const _trackUnusedInputsCompilerOption = 'track-unused-inputs';
-const _environmentOption = 'environment';
-const _experimentOption = 'experiments';
-const _supportedOptions = [
-  _environmentOption,
-  _experimentOption,
-  _useIncrementalCompilerOption,
-  _trackUnusedInputsCompilerOption
-];
diff --git a/build_web_compilers/lib/src/archive_extractor.dart b/build_web_compilers/lib/src/archive_extractor.dart
deleted file mode 100644
index 1506710..0000000
--- a/build_web_compilers/lib/src/archive_extractor.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:archive/archive.dart';
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-
-import 'web_entrypoint_builder.dart';
-
-class Dart2JsArchiveExtractor implements PostProcessBuilder {
-  /// Whether to only output .js files.
-  ///
-  /// The default in release mode.
-  bool filterOutputs;
-
-  Dart2JsArchiveExtractor() : filterOutputs = false;
-
-  Dart2JsArchiveExtractor.fromOptions(BuilderOptions options)
-      : filterOutputs = options.config['filter_outputs'] as bool ?? false;
-
-  @override
-  final inputExtensions = const [jsEntrypointArchiveExtension];
-
-  @override
-  Future<void> build(PostProcessBuildStep buildStep) async {
-    var bytes = await buildStep.readInputAsBytes();
-    var archive = TarDecoder().decodeBytes(bytes);
-    for (var file in archive.files) {
-      if (filterOutputs && !file.name.endsWith('.js')) continue;
-      var inputId = buildStep.inputId;
-      var id = AssetId(
-          inputId.package, p.url.join(p.url.dirname(inputId.path), file.name));
-      await buildStep.writeAsBytes(id, file.content as List<int>);
-    }
-    buildStep.deletePrimaryInput();
-  }
-}
diff --git a/build_web_compilers/lib/src/common.dart b/build_web_compilers/lib/src/common.dart
deleted file mode 100644
index 1916bff..0000000
--- a/build_web_compilers/lib/src/common.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-import 'package:build_modules/build_modules.dart';
-
-final defaultAnalysisOptionsId =
-    AssetId('build_modules', 'lib/src/analysis_options.default.yaml');
-
-final sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));
-
-String defaultAnalysisOptionsArg(ScratchSpace scratchSpace) =>
-    '--options=${scratchSpace.fileFor(defaultAnalysisOptionsId).path}';
-
-// TODO: better solution for a .packages file, today we just create a new one
-// for every kernel build action.
-Future<File> createPackagesFile(Iterable<AssetId> allAssets) async {
-  var allPackages = allAssets.map((id) => id.package).toSet();
-  var packagesFileDir =
-      await Directory.systemTemp.createTemp('kernel_builder_');
-  var packagesFile = File(p.join(packagesFileDir.path, '.packages'));
-  await packagesFile.create();
-  await packagesFile.writeAsString(allPackages
-      .map((pkg) => '$pkg:$multiRootScheme:///packages/$pkg')
-      .join('\r\n'));
-  return packagesFile;
-}
-
-/// Validates that [config] only has the top level keys [supportedOptions].
-///
-/// Throws an [ArgumentError] if not.
-void validateOptions(Map<String, dynamic> config, List<String> supportedOptions,
-    String builderKey,
-    {List<String> deprecatedOptions}) {
-  deprecatedOptions ??= [];
-  var unsupported = config.keys.where(
-      (o) => !supportedOptions.contains(o) && !deprecatedOptions.contains(o));
-  if (unsupported.isNotEmpty) {
-    throw ArgumentError.value(unsupported.join(', '), builderKey,
-        'only $supportedOptions are supported options, but got');
-  }
-  var deprecated = config.keys.where(deprecatedOptions.contains);
-  if (deprecated.isNotEmpty) {
-    log.warning('Found deprecated options ${deprecated.join(', ')}. These no '
-        'longer have any effect and should be removed.');
-  }
-}
diff --git a/build_web_compilers/lib/src/dart2js_bootstrap.dart b/build_web_compilers/lib/src/dart2js_bootstrap.dart
deleted file mode 100644
index 11ba92c..0000000
--- a/build_web_compilers/lib/src/dart2js_bootstrap.dart
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:archive/archive.dart';
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-
-import 'platforms.dart';
-import 'web_entrypoint_builder.dart';
-
-/// Compiles an the primary input of [buildStep] with dart2js.
-///
-/// If [skipPlatformCheck] is `true` then all `dart:` imports will be
-/// allowed in all packages.
-Future<void> bootstrapDart2Js(BuildStep buildStep, List<String> dart2JsArgs,
-    {bool skipPlatformCheck}) async {
-  skipPlatformCheck ??= false;
-  var dartEntrypointId = buildStep.inputId;
-  var moduleId =
-      dartEntrypointId.changeExtension(moduleExtension(dart2jsPlatform));
-  var args = <String>[];
-  {
-    var module = Module.fromJson(
-        json.decode(await buildStep.readAsString(moduleId))
-            as Map<String, dynamic>);
-    List<Module> allDeps;
-    try {
-      allDeps = (await module.computeTransitiveDependencies(buildStep,
-          throwIfUnsupported: !skipPlatformCheck))
-        ..add(module);
-    } on UnsupportedModules catch (e) {
-      var librariesString = (await e.exactLibraries(buildStep).toList())
-          .map((lib) => AssetId(lib.id.package,
-              lib.id.path.replaceFirst(moduleLibraryExtension, '.dart')))
-          .join('\n');
-      log.warning('''
-Skipping compiling ${buildStep.inputId} with dart2js because some of its
-transitive libraries have sdk dependencies that not supported on this platform:
-
-$librariesString
-
-https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-resolve-skipped-compiling-warnings
-''');
-      return;
-    }
-
-    var scratchSpace = await buildStep.fetchResource(scratchSpaceResource);
-    var allSrcs = allDeps.expand((module) => module.sources);
-    await scratchSpace.ensureAssets(allSrcs, buildStep);
-    var packageFile =
-        await _createPackageFile(allSrcs, buildStep, scratchSpace);
-
-    var dartPath = dartEntrypointId.path.startsWith('lib/')
-        ? 'package:${dartEntrypointId.package}/'
-            '${dartEntrypointId.path.substring('lib/'.length)}'
-        : dartEntrypointId.path;
-    var jsOutputPath =
-        '${p.withoutExtension(dartPath.replaceFirst('package:', 'packages/'))}'
-        '$jsEntrypointExtension';
-    args = dart2JsArgs.toList()
-      ..addAll([
-        '--packages=$packageFile',
-        '-o$jsOutputPath',
-        dartPath,
-      ]);
-  }
-
-  var dart2js = await buildStep.fetchResource(dart2JsWorkerResource);
-  var result = await dart2js.compile(args);
-  var jsOutputId = dartEntrypointId.changeExtension(jsEntrypointExtension);
-  var jsOutputFile = scratchSpace.fileFor(jsOutputId);
-  if (result.succeeded && await jsOutputFile.exists()) {
-    log.info(result.output);
-    var rootDir = p.dirname(jsOutputFile.path);
-    var dartFile = p.basename(dartEntrypointId.path);
-    var fileGlob = Glob('$dartFile.js*');
-    var archive = Archive();
-    await for (var jsFile in fileGlob.list(root: rootDir)) {
-      if (jsFile.path.endsWith(jsEntrypointExtension) ||
-          jsFile.path.endsWith(jsEntrypointSourceMapExtension)) {
-        // These are explicitly output, and are not part of the archive.
-        continue;
-      }
-      if (jsFile is File) {
-        var fileName = p.relative(jsFile.path, from: rootDir);
-        var fileStats = await jsFile.stat();
-        archive.addFile(
-            ArchiveFile(fileName, fileStats.size, await jsFile.readAsBytes())
-              ..mode = fileStats.mode
-              ..lastModTime = fileStats.modified.millisecondsSinceEpoch);
-      }
-    }
-    if (archive.isNotEmpty) {
-      var archiveId =
-          dartEntrypointId.changeExtension(jsEntrypointArchiveExtension);
-      await buildStep.writeAsBytes(archiveId, TarEncoder().encode(archive));
-    }
-
-    // Explicitly write out the original js file and sourcemap - we can't output
-    // these as part of the archive because they already have asset nodes.
-    await scratchSpace.copyOutput(jsOutputId, buildStep);
-    var jsSourceMapId =
-        dartEntrypointId.changeExtension(jsEntrypointSourceMapExtension);
-    await _copyIfExists(jsSourceMapId, scratchSpace, buildStep);
-  } else {
-    log.severe(result.output);
-  }
-}
-
-Future<void> _copyIfExists(
-    AssetId id, ScratchSpace scratchSpace, AssetWriter writer) async {
-  var file = scratchSpace.fileFor(id);
-  if (await file.exists()) {
-    await scratchSpace.copyOutput(id, writer);
-  }
-}
-
-/// Creates a `.packages` file unique to this entrypoint at the root of the
-/// scratch space and returns it's filename.
-///
-/// Since mulitple invocations of Dart2Js will share a scratch space and we only
-/// know the set of packages involved the current entrypoint we can't construct
-/// a `.packages` file that will work for all invocations of Dart2Js so a unique
-/// file is created for every entrypoint that is run.
-///
-/// The filename is based off the MD5 hash of the asset path so that files are
-/// unique regarless of situations like `web/foo/bar.dart` vs
-/// `web/foo-bar.dart`.
-Future<String> _createPackageFile(Iterable<AssetId> inputSources,
-    BuildStep buildStep, ScratchSpace scratchSpace) async {
-  var inputUri = buildStep.inputId.uri;
-  var packageFileName =
-      '.package-${md5.convert(inputUri.toString().codeUnits)}';
-  var packagesFile =
-      scratchSpace.fileFor(AssetId(buildStep.inputId.package, packageFileName));
-  var packageNames = inputSources.map((s) => s.package).toSet();
-  var packagesFileContent =
-      packageNames.map((n) => '$n:packages/$n/').join('\n');
-  await packagesFile
-      .writeAsString('# Generated for $inputUri\n$packagesFileContent');
-  return packageFileName;
-}
diff --git a/build_web_compilers/lib/src/ddc_names.dart b/build_web_compilers/lib/src/ddc_names.dart
deleted file mode 100644
index 6a4e987..0000000
--- a/build_web_compilers/lib/src/ddc_names.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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:path/path.dart' as p;
-
-/// Transforms a path to a valid JS identifier.
-///
-/// This logic must be synchronized with [pathToJSIdentifier] in DDC at:
-/// pkg/dev_compiler/lib/src/compiler/module_builder.dart
-///
-/// For backwards compatibility, if this pattern is changed,
-/// dev_compiler_bootstrap.dart must be updated to accept both old and new
-/// patterns.
-String pathToJSIdentifier(String path) {
-  path = p.normalize(path);
-  if (path.startsWith('/') || path.startsWith('\\')) {
-    path = path.substring(1, path.length);
-  }
-  return toJSIdentifier(path
-      .replaceAll('\\', '__')
-      .replaceAll('/', '__')
-      .replaceAll('..', '__')
-      .replaceAll('-', '_'));
-}
-
-/// Escape [name] to make it into a valid identifier.
-String toJSIdentifier(String name) {
-  if (name.isEmpty) return r'$';
-
-  // Escape any invalid characters
-  StringBuffer buffer;
-  for (var i = 0; i < name.length; i++) {
-    var ch = name[i];
-    var needsEscape = ch == r'$' || _invalidCharInIdentifier.hasMatch(ch);
-    if (needsEscape && buffer == null) {
-      buffer = StringBuffer(name.substring(0, i));
-    }
-    if (buffer != null) {
-      buffer.write(needsEscape ? '\$${ch.codeUnits.join("")}' : ch);
-    }
-  }
-
-  var result = buffer != null ? '$buffer' : name;
-  // Ensure the identifier first character is not numeric and that the whole
-  // identifier is not a keyword.
-  if (result.startsWith(RegExp('[0-9]')) || invalidVariableName(result)) {
-    return '\$$result';
-  }
-  return result;
-}
-
-/// Returns true for invalid JS variable names, such as keywords.
-/// Also handles invalid variable names in strict mode, like "arguments".
-bool invalidVariableName(String keyword, {bool strictMode = true}) {
-  switch (keyword) {
-    // http://www.ecma-international.org/ecma-262/6.0/#sec-future-reserved-words
-    case 'await':
-    case 'break':
-    case 'case':
-    case 'catch':
-    case 'class':
-    case 'const':
-    case 'continue':
-    case 'debugger':
-    case 'default':
-    case 'delete':
-    case 'do':
-    case 'else':
-    case 'enum':
-    case 'export':
-    case 'extends':
-    case 'finally':
-    case 'for':
-    case 'function':
-    case 'if':
-    case 'import':
-    case 'in':
-    case 'instanceof':
-    case 'let':
-    case 'new':
-    case 'return':
-    case 'super':
-    case 'switch':
-    case 'this':
-    case 'throw':
-    case 'try':
-    case 'typeof':
-    case 'var':
-    case 'void':
-    case 'while':
-    case 'with':
-      return true;
-    case 'arguments':
-    case 'eval':
-    // http://www.ecma-international.org/ecma-262/6.0/#sec-future-reserved-words
-    // http://www.ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
-    case 'implements':
-    case 'interface':
-    case 'package':
-    case 'private':
-    case 'protected':
-    case 'public':
-    case 'static':
-    case 'yield':
-      return strictMode;
-  }
-  return false;
-}
-
-// Invalid characters for identifiers, which would need to be escaped.
-final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_$0-9]');
diff --git a/build_web_compilers/lib/src/dev_compiler_bootstrap.dart b/build_web_compilers/lib/src/dev_compiler_bootstrap.dart
deleted file mode 100644
index 2845d45..0000000
--- a/build_web_compilers/lib/src/dev_compiler_bootstrap.dart
+++ /dev/null
@@ -1,530 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as _p; // ignore: library_prefixes
-import 'package:pool/pool.dart';
-
-import 'ddc_names.dart';
-import 'dev_compiler_builder.dart';
-import 'platforms.dart';
-import 'web_entrypoint_builder.dart';
-
-/// Alias `_p.url` to `p`.
-_p.Context get _context => _p.url;
-
-var _modulePartialExtension = _context.withoutExtension(jsModuleExtension);
-
-/// Bootstraps a ddc application, creating the main entrypoint as well as the
-/// bootstrap and digest entrypoints.
-///
-/// If [skipPlatformCheck] is `true` then all `dart:` imports will be
-/// allowed in all packages.
-///
-/// Deprecated: If [skipPlatformCheckPackages] is provided then any dart:
-/// imports will be allowed in the specified packages.
-///
-/// If [requiredAssets] is provided then this will ensure those assets are
-/// available to the app by making them inputs of this build action.
-Future<void> bootstrapDdc(
-  BuildStep buildStep, {
-  DartPlatform platform,
-  bool skipPlatformCheck = false,
-  @deprecated Set<String> skipPlatformCheckPackages = const {},
-  Iterable<AssetId> requiredAssets,
-}) async {
-  requiredAssets ??= [];
-  skipPlatformCheck ??= false;
-  // Ensures that the sdk resources are built and available.
-  await _ensureResources(buildStep, requiredAssets);
-
-  var dartEntrypointId = buildStep.inputId;
-  var moduleId = buildStep.inputId
-      .changeExtension(moduleExtension(platform ?? ddcPlatform));
-  var module = Module.fromJson(json
-      .decode(await buildStep.readAsString(moduleId)) as Map<String, dynamic>);
-
-  // First, ensure all transitive modules are built.
-  List<AssetId> transitiveJsModules;
-  try {
-    transitiveJsModules = await _ensureTransitiveJsModules(module, buildStep,
-        skipPlatformCheck: skipPlatformCheck,
-        skipPlatformCheckPackages: skipPlatformCheckPackages);
-  } on UnsupportedModules catch (e) {
-    var librariesString = (await e.exactLibraries(buildStep).toList())
-        .map((lib) => AssetId(lib.id.package,
-            lib.id.path.replaceFirst(moduleLibraryExtension, '.dart')))
-        .join('\n');
-    log.warning('''
-Skipping compiling ${buildStep.inputId} with ddc because some of its
-transitive libraries have sdk dependencies that not supported on this platform:
-
-$librariesString
-
-https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-resolve-skipped-compiling-warnings
-''');
-    return;
-  }
-  var jsId = module.primarySource.changeExtension(jsModuleExtension);
-  var appModuleName = ddcModuleName(jsId);
-  var appDigestsOutput =
-      dartEntrypointId.changeExtension(digestsEntrypointExtension);
-
-  // The name of the entrypoint dart library within the entrypoint JS module.
-  //
-  // This is used to invoke `main()` from within the bootstrap script.
-  //
-  // TODO(jakemac53): Sane module name creation, this only works in the most
-  // basic of cases.
-  //
-  // See https://github.com/dart-lang/sdk/issues/27262 for the root issue
-  // which will allow us to not rely on the naming schemes that dartdevc uses
-  // internally, but instead specify our own.
-  var oldAppModuleScope = toJSIdentifier(
-      _context.withoutExtension(_context.basename(buildStep.inputId.path)));
-
-  // Like above but with a package-relative entrypoint.
-  var appModuleScope =
-      pathToJSIdentifier(_context.withoutExtension(buildStep.inputId.path));
-
-  // Map from module name to module path for custom modules.
-  var modulePaths = SplayTreeMap.of(
-      {'dart_sdk': r'packages/build_web_compilers/src/dev_compiler/dart_sdk'});
-  for (var jsId in transitiveJsModules) {
-    // Strip out the top level dir from the path for any module, and set it to
-    // `packages/` for lib modules. We set baseUrl to `/` to simplify things,
-    // and we only allow you to serve top level directories.
-    var moduleName = ddcModuleName(jsId);
-    modulePaths[moduleName] = _context.withoutExtension(
-        jsId.path.startsWith('lib')
-            ? '$moduleName$jsModuleExtension'
-            : _context.joinAll(_context.split(jsId.path).skip(1)));
-  }
-
-  var bootstrapId = dartEntrypointId.changeExtension(ddcBootstrapExtension);
-  var bootstrapModuleName = _context.withoutExtension(_context.relative(
-      bootstrapId.path,
-      from: _context.dirname(dartEntrypointId.path)));
-
-  var dartEntrypointParts = _context.split(dartEntrypointId.path);
-  var entrypointLibraryName = _context.joinAll([
-    // Convert to a package: uri for files under lib.
-    if (dartEntrypointParts.first == 'lib')
-      'package:${module.primarySource.package}',
-    // Strip top-level directory from the path.
-    ...dartEntrypointParts.skip(1),
-  ]);
-
-  var bootstrapContent =
-      StringBuffer('$_entrypointExtensionMarker\n(function() {\n')
-        ..write(_dartLoaderSetup(
-            modulePaths,
-            _p.url.relative(appDigestsOutput.path,
-                from: _p.url.dirname(bootstrapId.path))))
-        ..write(_requireJsConfig)
-        ..write(_appBootstrap(bootstrapModuleName, appModuleName,
-            appModuleScope, entrypointLibraryName,
-            oldModuleScope: oldAppModuleScope));
-
-  await buildStep.writeAsString(bootstrapId, bootstrapContent.toString());
-
-  var entrypointJsContent = _entryPointJs(bootstrapModuleName);
-  await buildStep.writeAsString(
-      dartEntrypointId.changeExtension(jsEntrypointExtension),
-      entrypointJsContent);
-
-  // Output the digests for transitive modules.
-  // These can be consumed for hot reloads.
-  var moduleDigests = <String, String>{
-    for (var jsId in transitiveJsModules)
-      _moduleDigestKey(jsId): '${await buildStep.digest(jsId)}',
-  };
-  await buildStep.writeAsString(appDigestsOutput, jsonEncode(moduleDigests));
-}
-
-String _moduleDigestKey(AssetId jsId) =>
-    '${ddcModuleName(jsId)}$jsModuleExtension';
-
-final _lazyBuildPool = Pool(16);
-
-/// Ensures that all transitive js modules for [module] are available and built.
-///
-/// Throws an [UnsupportedModules] exception if there are any
-/// unsupported modules.
-Future<List<AssetId>> _ensureTransitiveJsModules(
-    Module module, BuildStep buildStep,
-    {@required bool skipPlatformCheck,
-    @required Set<String> skipPlatformCheckPackages}) async {
-  // Collect all the modules this module depends on, plus this module.
-  var transitiveDeps = await module.computeTransitiveDependencies(buildStep,
-      throwIfUnsupported: !skipPlatformCheck,
-      // ignore: deprecated_member_use
-      skipPlatformCheckPackages: skipPlatformCheckPackages);
-
-  var jsModules = [
-    module.primarySource.changeExtension(jsModuleExtension),
-    for (var dep in transitiveDeps)
-      dep.primarySource.changeExtension(jsModuleExtension),
-  ];
-  // Check that each module is readable, and warn otherwise.
-  await Future.wait(jsModules.map((jsId) async {
-    if (await _lazyBuildPool.withResource(() => buildStep.canRead(jsId))) {
-      return;
-    }
-    var errorsId = jsId.addExtension('.errors');
-    await buildStep.canRead(errorsId);
-    log.warning('Unable to read $jsId, check your console or the '
-        '`.dart_tool/build/generated/${errorsId.package}/${errorsId.path}` '
-        'log file.');
-  }));
-  return jsModules;
-}
-
-/// Code that actually imports the [moduleName] module, and calls the
-/// `[moduleScope].main()` function on it.
-///
-/// Also performs other necessary initialization.
-String _appBootstrap(String bootstrapModuleName, String moduleName,
-        String moduleScope, String entrypointLibraryName,
-        {String oldModuleScope}) =>
-    '''
-define("$bootstrapModuleName", ["$moduleName", "dart_sdk"], function(app, dart_sdk) {
-  dart_sdk.dart.setStartAsyncSynchronously(true);
-  dart_sdk._isolate_helper.startRootIsolate(() => {}, []);
-  $_initializeTools
-  $_mainExtensionMarker
-  (app.$moduleScope || app.$oldModuleScope).main();
-  var bootstrap = {
-      hot\$onChildUpdate: function(childName, child) {
-        // Special handling for the multi-root scheme uris. We need to strip
-        // out the scheme and the top level directory, to match the source path
-        // that chrome sees.
-        if (childName.startsWith('$multiRootScheme:///')) {
-          childName = childName.substring('$multiRootScheme:///'.length);
-          var firstSlash = childName.indexOf('/');
-          if (firstSlash == -1) return false;
-          childName = childName.substring(firstSlash + 1);
-        }
-        if (childName === "$entrypointLibraryName") {
-          // Clear static caches.
-          dart_sdk.dart.hotRestart();
-          child.main();
-          return true;
-        }
-      }
-    }
-  dart_sdk.dart.trackLibraries("$bootstrapModuleName", {
-    "$bootstrapModuleName": bootstrap
-  }, '');
-  return {
-    bootstrap: bootstrap
-  };
-});
-})();
-''';
-
-/// The actual entrypoint JS file which injects all the necessary scripts to
-/// run the app.
-String _entryPointJs(String bootstrapModuleName) => '''
-(function() {
-  $_currentDirectoryScript
-  $_baseUrlScript
-
-  var mapperUri = baseUrl + "packages/build_web_compilers/src/" +
-      "dev_compiler_stack_trace/stack_trace_mapper.dart.js";
-  var requireUri = baseUrl +
-      "packages/build_web_compilers/src/dev_compiler/require.js";
-  var mainUri = _currentDirectory + "$bootstrapModuleName";
-
-  if (typeof document != 'undefined') {
-    var el = document.createElement("script");
-    el.defer = true;
-    el.async = false;
-    el.src = mapperUri;
-    document.head.appendChild(el);
-
-    el = document.createElement("script");
-    el.defer = true;
-    el.async = false;
-    el.src = requireUri;
-    el.setAttribute("data-main", mainUri);
-    document.head.appendChild(el);
-  } else {
-    importScripts(mapperUri, requireUri);
-    require.config({
-      baseUrl: baseUrl,
-    });
-    // TODO: update bootstrap code to take argument - dart-lang/build#1115
-    window = self;
-    require([mainUri + '.js']);
-  }
-})();
-''';
-
-/// JavaScript snippet to determine the directory a script was run from.
-final _currentDirectoryScript = r'''
-var _currentDirectory = (function () {
-  var _url;
-  var lines = new Error().stack.split('\n');
-  function lookupUrl() {
-    if (lines.length > 2) {
-      var match = lines[1].match(/^\s+at (.+):\d+:\d+$/);
-      // Chrome.
-      if (match) return match[1];
-      // Chrome nested eval case.
-      match = lines[1].match(/^\s+at eval [(](.+):\d+:\d+[)]$/);
-      if (match) return match[1];
-      // Edge.
-      match = lines[1].match(/^\s+at.+\((.+):\d+:\d+\)$/);
-      if (match) return match[1];
-      // Firefox.
-      match = lines[0].match(/[<][@](.+):\d+:\d+$/)
-      if (match) return match[1];
-    }
-    // Safari.
-    return lines[0].match(/(.+):\d+:\d+$/)[1];
-  }
-  _url = lookupUrl();
-  var lastSlash = _url.lastIndexOf('/');
-  if (lastSlash == -1) return _url;
-  var currentDirectory = _url.substring(0, lastSlash + 1);
-  return currentDirectory;
-})();
-''';
-
-/// Sets up `window.$dartLoader` based on [modulePaths].
-String _dartLoaderSetup(Map<String, String> modulePaths, String appDigests) =>
-    '''
-$_currentDirectoryScript
-$_baseUrlScript
-let modulePaths = ${const JsonEncoder.withIndent(" ").convert(modulePaths)};
-if(!window.\$dartLoader) {
-   window.\$dartLoader = {
-     appDigests: _currentDirectory + '$appDigests',
-     moduleIdToUrl: new Map(),
-     urlToModuleId: new Map(),
-     rootDirectories: new Array(),
-     // Used in package:build_runner/src/server/build_updates_client/hot_reload_client.dart
-     moduleParentsGraph: new Map(),
-     moduleLoadingErrorCallbacks: new Map(),
-     forceLoadModule: function (moduleName, callback, onError) {
-       // dartdevc only strips the final extension when adding modules to source
-       // maps, so we need to do the same.
-       if (moduleName.endsWith('$_modulePartialExtension')) {
-         moduleName = moduleName.substring(0, moduleName.length - ${_modulePartialExtension.length});
-       }
-       if (typeof onError != 'undefined') {
-         var errorCallbacks = \$dartLoader.moduleLoadingErrorCallbacks;
-         if (!errorCallbacks.has(moduleName)) {
-           errorCallbacks.set(moduleName, new Set());
-         }
-         errorCallbacks.get(moduleName).add(onError);
-       }
-       requirejs.undef(moduleName);
-       requirejs([moduleName], function() {
-         if (typeof onError != 'undefined') {
-           errorCallbacks.get(moduleName).delete(onError);
-         }
-         if (typeof callback != 'undefined') {
-           callback();
-         }
-       });
-     },
-     getModuleLibraries: null, // set up by _initializeTools
-   };
-}
-let customModulePaths = {};
-window.\$dartLoader.rootDirectories.push(window.location.origin + baseUrl);
-for (let moduleName of Object.getOwnPropertyNames(modulePaths)) {
-  let modulePath = modulePaths[moduleName];
-  if (modulePath != moduleName) {
-    customModulePaths[moduleName] = modulePath;
-  }
-  var src = window.location.origin + '/' + modulePath + '.js';
-  if (window.\$dartLoader.moduleIdToUrl.has(moduleName)) {
-    continue;
-  }
-  \$dartLoader.moduleIdToUrl.set(moduleName, src);
-  \$dartLoader.urlToModuleId.set(src, moduleName);
-}
-''';
-
-/// Code to initialize the dev tools formatter, stack trace mapper, and any
-/// other tools.
-///
-/// Posts a message to the window when done.
-final _initializeTools = '''
-$_baseUrlScript
-  dart_sdk._debugger.registerDevtoolsFormatter();
-  \$dartLoader.getModuleLibraries = dart_sdk.dart.getModuleLibraries;
-  if (window.\$dartStackTraceUtility && !window.\$dartStackTraceUtility.ready) {
-    window.\$dartStackTraceUtility.ready = true;
-    let dart = dart_sdk.dart;
-    window.\$dartStackTraceUtility.setSourceMapProvider(
-      function(url) {
-        url = url.replace(baseUrl, '/');
-        var module = window.\$dartLoader.urlToModuleId.get(url);
-        if (!module) return null;
-        return dart.getSourceMap(module);
-      });
-  }
-  if (typeof document != 'undefined') {
-    window.postMessage({ type: "DDC_STATE_CHANGE", state: "start" }, "*");
-  }
-''';
-
-/// Require JS config for ddc.
-///
-/// Sets the base url to `/` so that all modules can be loaded using absolute
-/// paths which simplifies a lot of scenarios.
-///
-/// Sets the timeout for loading modules to infinity (0).
-///
-/// Sets up the custom module paths.
-///
-/// Adds error handler code for require.js which requests a `.errors` file for
-/// any failed module, and logs it to the console.
-final _requireJsConfig = '''
-// Whenever we fail to load a JS module, try to request the corresponding
-// `.errors` file, and log it to the console.
-(function() {
-  var oldOnError = requirejs.onError;
-  requirejs.onError = function(e) {
-    if (e.requireModules) {
-      if (e.message) {
-        // If error occurred on loading dependencies, we need to invalidate ancessor too.
-        var ancesor = e.message.match(/needed by: (.*)/);
-        if (ancesor) {
-          e.requireModules.push(ancesor[1]);
-        }
-      }
-      for (const module of e.requireModules) {
-        var errorCallbacks = \$dartLoader.moduleLoadingErrorCallbacks.get(module);
-        if (errorCallbacks) {
-          for (const callback of errorCallbacks) callback(e);
-          errorCallbacks.clear();
-        }
-      }
-    }
-    if (e.originalError && e.originalError.srcElement) {
-      var xhr = new XMLHttpRequest();
-      xhr.onreadystatechange = function() {
-        if (this.readyState == 4) {
-          var message;
-          if (this.status == 200) {
-            message = this.responseText;
-          } else {
-            message = "Unknown error loading " + e.originalError.srcElement.src;
-          }
-          console.error(message);
-          var errorEvent = new CustomEvent(
-            'dartLoadException', { detail: message });
-          window.dispatchEvent(errorEvent);
-        }
-      };
-      xhr.open("GET", e.originalError.srcElement.src + ".errors", true);
-      xhr.send();
-    }
-    // Also handle errors the normal way.
-    if (oldOnError) oldOnError(e);
-  };
-}());
-
-$_baseUrlScript;
-
-require.config({
-    baseUrl: baseUrl,
-    waitSeconds: 0,
-    paths: customModulePaths
-});
-
-const modulesGraph = new Map();
-function getRegisteredModuleName(moduleMap) {
-  if (\$dartLoader.moduleIdToUrl.has(moduleMap.name + '$_modulePartialExtension')) {
-    return moduleMap.name + '$_modulePartialExtension';
-  }
-  return moduleMap.name;
-}
-requirejs.onResourceLoad = function (context, map, depArray) {
-  const name = getRegisteredModuleName(map);
-  const depNameArray = depArray.map(getRegisteredModuleName);
-  if (modulesGraph.has(name)) {
-    // TODO Move this logic to better place
-    var previousDeps = modulesGraph.get(name);
-    var changed = previousDeps.length != depNameArray.length;
-    changed = changed || depNameArray.some(function(depName) {
-      return !previousDeps.includes(depName);
-    });
-    if (changed) {
-      console.warn("Dependencies graph change for module '" + name + "' detected. " +
-        "Dependencies was [" + previousDeps + "], now [" +  depNameArray.map((depName) => depName) +"]. " +
-        "Page can't be hot-reloaded, firing full page reload.");
-      window.location.reload();
-    }
-  } else {
-    modulesGraph.set(name, []);
-    for (const depName of depNameArray) {
-      if (!\$dartLoader.moduleParentsGraph.has(depName)) {
-        \$dartLoader.moduleParentsGraph.set(depName, []);
-      }
-      \$dartLoader.moduleParentsGraph.get(depName).push(name);
-      modulesGraph.get(name).push(depName);
-    }
-  }
-};
-''';
-
-/// Marker comment used by tools to identify the entrypoint file,
-/// to inject custom code.
-final _entrypointExtensionMarker = '/* ENTRYPOINT_EXTENTION_MARKER */';
-
-/// Marker comment used by tools to identify the main function
-/// to inject custom code.
-final _mainExtensionMarker = '/* MAIN_EXTENSION_MARKER */';
-
-final _baseUrlScript = '''
-var baseUrl = (function () {
-  // Attempt to detect --precompiled mode for tests, and set the base url
-  // appropriately, otherwise set it to '/'.
-  var pathParts = location.pathname.split("/");
-  if (pathParts[0] == "") {
-    pathParts.shift();
-  }
-  if (pathParts.length > 1 && pathParts[1] == "test") {
-    return "/" + pathParts.slice(0, 2).join("/") + "/";
-  }
-  // Attempt to detect base url using <base href> html tag
-  // base href should start and end with "/"
-  if (typeof document !== 'undefined') {
-    var el = document.getElementsByTagName('base');
-    if (el && el[0] && el[0].getAttribute("href") && el[0].getAttribute
-    ("href").startsWith("/") && el[0].getAttribute("href").endsWith("/")){
-      return el[0].getAttribute("href");
-    }
-  }
-  // return default value
-  return "/";
-}());
-''';
-
-/// Ensures that all of [resources] are built successfully, and adds them as
-/// an input dependency to this action.
-///
-/// This also has the effect of ensuring these resources are present whenever
-/// a DDC app is built - reducing the need to explicitly list these files as
-/// build filters.
-Future<void> _ensureResources(
-    BuildStep buildStep, Iterable<AssetId> resources) async {
-  for (var resource in resources) {
-    if (!await buildStep.canRead(resource)) {
-      throw StateError('Unable to locate required sdk resource $resource');
-    }
-  }
-}
diff --git a/build_web_compilers/lib/src/dev_compiler_builder.dart b/build_web_compilers/lib/src/dev_compiler_builder.dart
deleted file mode 100644
index b2809ee..0000000
--- a/build_web_compilers/lib/src/dev_compiler_builder.dart
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-
-import '../builders.dart';
-import 'common.dart';
-import 'errors.dart';
-
-const jsModuleErrorsExtension = '.ddc.js.errors';
-const jsModuleExtension = '.ddc.js';
-const jsSourceMapExtension = '.ddc.js.map';
-
-/// A builder which can output ddc modules!
-class DevCompilerBuilder implements Builder {
-  final bool useIncrementalCompiler;
-
-  final bool trackUnusedInputs;
-
-  final DartPlatform platform;
-
-  /// The sdk kernel file for the current platform.
-  final String sdkKernelPath;
-
-  /// The root directory of the platform's dart SDK.
-  ///
-  /// If not provided, defaults to the directory of
-  /// [Platform.resolvedExecutable].
-  ///
-  /// On flutter this is the path to the root of the flutter_patched_sdk
-  /// directory, which contains the platform kernel files.
-  final String platformSdk;
-
-  /// The absolute path to the libraries file for the current platform.
-  ///
-  /// If not provided, defaults to "lib/libraries.json" in the sdk directory.
-  final String librariesPath;
-
-  /// Environment defines to pass to ddc (as -D variables).
-  final Map<String, String> environment;
-
-  /// Experiments to pass to ddc (as --enable-experiment=<experiment> args).
-  final Iterable<String> experiments;
-
-  DevCompilerBuilder(
-      {bool useIncrementalCompiler,
-      bool trackUnusedInputs,
-      @required this.platform,
-      this.sdkKernelPath,
-      String librariesPath,
-      String platformSdk,
-      Map<String, String> environment,
-      Iterable<String> experiments})
-      : useIncrementalCompiler = useIncrementalCompiler ?? true,
-        platformSdk = platformSdk ?? sdkDir,
-        librariesPath = librariesPath ??
-            p.join(platformSdk ?? sdkDir, 'lib', 'libraries.json'),
-        trackUnusedInputs = trackUnusedInputs ?? false,
-        buildExtensions = {
-          moduleExtension(platform): [
-            jsModuleExtension,
-            jsModuleErrorsExtension,
-            jsSourceMapExtension
-          ],
-        },
-        environment = environment ?? {},
-        experiments = experiments ?? {};
-
-  @override
-  final Map<String, List<String>> buildExtensions;
-
-  @override
-  Future build(BuildStep buildStep) async {
-    var module = Module.fromJson(
-        json.decode(await buildStep.readAsString(buildStep.inputId))
-            as Map<String, dynamic>);
-    // Entrypoints always have a `.module` file for ease of looking them up,
-    // but they might not be the primary source.
-    if (module.primarySource.changeExtension(moduleExtension(platform)) !=
-        buildStep.inputId) {
-      return;
-    }
-
-    Future<void> handleError(e) async {
-      await buildStep.writeAsString(
-          module.primarySource.changeExtension(jsModuleErrorsExtension), '$e');
-      log.severe('$e');
-    }
-
-    try {
-      await _createDevCompilerModule(
-          module,
-          buildStep,
-          useIncrementalCompiler,
-          trackUnusedInputs,
-          platformSdk,
-          sdkKernelPath,
-          librariesPath,
-          environment,
-          experiments);
-    } on DartDevcCompilationException catch (e) {
-      await handleError(e);
-    } on MissingModulesException catch (e) {
-      await handleError(e);
-    }
-  }
-}
-
-/// Compile [module] with the dev compiler.
-Future<void> _createDevCompilerModule(
-    Module module,
-    BuildStep buildStep,
-    bool useIncrementalCompiler,
-    bool trackUnusedInputs,
-    String dartSdk,
-    String sdkKernelPath,
-    String librariesPath,
-    Map<String, String> environment,
-    Iterable<String> experiments,
-    {bool debugMode = true}) async {
-  var transitiveDeps = await buildStep.trackStage('CollectTransitiveDeps',
-      () => module.computeTransitiveDependencies(buildStep));
-  var transitiveKernelDeps = [
-    for (var dep in transitiveDeps)
-      dep.primarySource.changeExtension(ddcKernelExtension)
-  ];
-  var scratchSpace = await buildStep.fetchResource(scratchSpaceResource);
-
-  var allAssetIds = <AssetId>{...module.sources, ...transitiveKernelDeps};
-  await buildStep.trackStage(
-      'EnsureAssets', () => scratchSpace.ensureAssets(allAssetIds, buildStep));
-  var jsId = module.primarySource.changeExtension(jsModuleExtension);
-  var jsOutputFile = scratchSpace.fileFor(jsId);
-  var sdkSummary =
-      p.url.join(dartSdk, sdkKernelPath ?? 'lib/_internal/ddc_sdk.dill');
-
-  // Maps the inputs paths we provide to the ddc worker to asset ids, if
-  // `trackUnusedInputs` is `true`.
-  Map<String, AssetId> kernelInputPathToId;
-  // If `trackUnusedInputs` is `true`, this is the file we will use to
-  // communicate the used inputs with the ddc worker.
-  File usedInputsFile;
-
-  if (trackUnusedInputs) {
-    usedInputsFile = await File(p.join(
-            (await Directory.systemTemp.createTemp('ddk_builder_')).path,
-            'used_inputs.txt'))
-        .create();
-    kernelInputPathToId = {};
-  }
-
-  var packagesFile = await createPackagesFile(allAssetIds);
-  var request = WorkRequest()
-    ..arguments.addAll([
-      '--dart-sdk-summary=$sdkSummary',
-      '--modules=amd',
-      '--no-summarize',
-      '-o',
-      jsOutputFile.path,
-      debugMode ? '--source-map' : '--no-source-map',
-      for (var dep in transitiveDeps) _summaryArg(dep),
-      '--packages=${packagesFile.absolute.uri}',
-      '--module-name=${ddcModuleName(jsId)}',
-      '--multi-root-scheme=$multiRootScheme',
-      '--multi-root=.',
-      '--track-widget-creation',
-      '--inline-source-map',
-      '--libraries-file=${p.toUri(librariesPath)}',
-      if (useIncrementalCompiler) ...[
-        '--reuse-compiler-result',
-        '--use-incremental-compiler',
-      ],
-      if (usedInputsFile != null)
-        '--used-inputs-file=${usedInputsFile.uri.toFilePath()}',
-      for (var source in module.sources) _sourceArg(source),
-      for (var define in environment.entries) '-D${define.key}=${define.value}',
-      for (var experiment in experiments) '--enable-experiment=$experiment',
-    ])
-    ..inputs.add(Input()
-      ..path = sdkSummary
-      ..digest = [0])
-    ..inputs.addAll(await Future.wait(transitiveKernelDeps.map((dep) async {
-      var file = scratchSpace.fileFor(dep);
-      if (kernelInputPathToId != null) {
-        kernelInputPathToId[file.uri.toString()] = dep;
-      }
-      return Input()
-        ..path = file.path
-        ..digest = (await buildStep.digest(dep)).bytes;
-    })));
-
-  try {
-    var driverResource = dartdevkDriverResource;
-    var driver = await buildStep.fetchResource(driverResource);
-    var response = await driver.doWork(request,
-        trackWork: (response) =>
-            buildStep.trackStage('Compile', () => response, isExternal: true));
-
-    // TODO(jakemac53): Fix the ddc worker mode so it always sends back a bad
-    // status code if something failed. Today we just make sure there is an output
-    // JS file to verify it was successful.
-    var message = response.output
-        .replaceAll('${scratchSpace.tempDir.path}/', '')
-        .replaceAll('$multiRootScheme:///', '');
-    if (response.exitCode != EXIT_CODE_OK ||
-        !jsOutputFile.existsSync() ||
-        message.contains('Error:')) {
-      throw DartDevcCompilationException(jsId, message);
-    }
-
-    if (message.isNotEmpty) {
-      log.info('\n$message');
-    }
-
-    // Copy the output back using the buildStep.
-    await scratchSpace.copyOutput(jsId, buildStep);
-    if (debugMode) {
-      // We need to modify the sources in the sourcemap to remove the custom
-      // `multiRootScheme` that we use.
-      var sourceMapId =
-          module.primarySource.changeExtension(jsSourceMapExtension);
-      var file = scratchSpace.fileFor(sourceMapId);
-      var content = await file.readAsString();
-      var json = jsonDecode(content);
-      json['sources'] = fixSourceMapSources((json['sources'] as List).cast());
-      await buildStep.writeAsString(sourceMapId, jsonEncode(json));
-    }
-
-    // Note that we only want to do this on success, we can't trust the unused
-    // inputs if there is a failure.
-    if (usedInputsFile != null) {
-      await reportUnusedKernelInputs(
-          usedInputsFile, transitiveKernelDeps, kernelInputPathToId, buildStep);
-    }
-  } finally {
-    await packagesFile.parent.delete(recursive: true);
-    await usedInputsFile?.parent?.delete(recursive: true);
-  }
-}
-
-/// Returns the `--summary=` argument for a dependency.
-String _summaryArg(Module module) {
-  final kernelAsset = module.primarySource.changeExtension(ddcKernelExtension);
-  final moduleName =
-      ddcModuleName(module.primarySource.changeExtension(jsModuleExtension));
-  return '--summary=${scratchSpace.fileFor(kernelAsset).path}=$moduleName';
-}
-
-/// The url to compile for a source.
-///
-/// Use the package: path for files under lib and the full absolute path for
-/// other files.
-String _sourceArg(AssetId id) {
-  var uri = canonicalUriFor(id);
-  return uri.startsWith('package:') ? uri : '$multiRootScheme:///${id.path}';
-}
-
-/// Copied to `web/stack_trace_mapper.dart`, these need to be kept in sync.
-///
-/// Given a list of [uris] as [String]s from a sourcemap, fixes them up so that
-/// they make sense in a browser context.
-///
-/// - Strips the scheme from the uri
-/// - Strips the top level directory if its not `packages`
-List<String> fixSourceMapSources(List<String> uris) {
-  return uris.map((source) {
-    var uri = Uri.parse(source);
-    // We only want to rewrite multi-root scheme uris.
-    if (uri.scheme.isEmpty) return source;
-    var newSegments = uri.pathSegments.first == 'packages'
-        ? uri.pathSegments
-        : uri.pathSegments.skip(1);
-    return Uri(path: p.url.joinAll(['/'].followedBy(newSegments))).toString();
-  }).toList();
-}
-
-/// The module name according to ddc for [jsId] which represents the real js
-/// module file.
-String ddcModuleName(AssetId jsId) {
-  var jsPath = jsId.path.startsWith('lib/')
-      ? jsId.path.replaceFirst('lib/', 'packages/${jsId.package}/')
-      : jsId.path;
-  return jsPath.substring(0, jsPath.length - jsModuleExtension.length);
-}
diff --git a/build_web_compilers/lib/src/errors.dart b/build_web_compilers/lib/src/errors.dart
deleted file mode 100644
index 9c63746..0000000
--- a/build_web_compilers/lib/src/errors.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-
-/// An [Exception] that is thrown when a worker returns an error.
-abstract class _WorkerException implements Exception {
-  final AssetId failedAsset;
-
-  final String error;
-
-  /// A message to prepend to [toString] output.
-  String get message;
-
-  _WorkerException(this.failedAsset, this.error);
-
-  @override
-  String toString() => '$message:$failedAsset\n\n$error';
-}
-
-/// An [Exception] that is thrown when dartdevc compilation fails.
-class DartDevcCompilationException extends _WorkerException {
-  @override
-  final String message = 'Error compiling dartdevc module';
-
-  DartDevcCompilationException(AssetId jsId, String error) : super(jsId, error);
-}
diff --git a/build_web_compilers/lib/src/platforms.dart b/build_web_compilers/lib/src/platforms.dart
deleted file mode 100644
index 4722b46..0000000
--- a/build_web_compilers/lib/src/platforms.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build_modules/build_modules.dart';
-
-final ddcPlatform = DartPlatform.register('ddc', [
-  'async',
-  'collection',
-  'convert',
-  'core',
-  'developer',
-  'html',
-  'html_common',
-  'indexed_db',
-  'js',
-  'js_util',
-  'math',
-  'svg',
-  'typed_data',
-  'web_audio',
-  'web_gl',
-  'web_sql',
-  '_internal',
-]);
-
-final dart2jsPlatform = DartPlatform.register('dart2js', [
-  'async',
-  'collection',
-  'convert',
-  'core',
-  'developer',
-  'html',
-  'html_common',
-  'indexed_db',
-  'js',
-  'js_util',
-  'math',
-  'svg',
-  'typed_data',
-  'web_audio',
-  'web_gl',
-  'web_sql',
-  '_internal',
-]);
diff --git a/build_web_compilers/lib/src/sdk_js_copy_builder.dart b/build_web_compilers/lib/src/sdk_js_copy_builder.dart
deleted file mode 100644
index a2579b1..0000000
--- a/build_web_compilers/lib/src/sdk_js_copy_builder.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for 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:build/build.dart';
-import 'package:path/path.dart' as p;
-
-import 'common.dart';
-
-/// Copies the dart_sdk.js and require.js files from the sdk itself, into the
-/// build_web_compilers package at `lib/dart_sdk.js` and `lib/require.js`.
-class SdkJsCopyBuilder implements Builder {
-  @override
-  final buildExtensions = {
-    r'$lib$': ['src/dev_compiler/dart_sdk.js', 'src/dev_compiler/require.js']
-  };
-
-  /// Path to the dart_sdk.js file that should be used for all ddc web apps.
-  final _sdkJsLocation =
-      p.join(sdkDir, 'lib', 'dev_compiler', 'kernel', 'amd', 'dart_sdk.js');
-
-  /// Path to the require.js file that should be used for all ddc web apps.
-  final _sdkRequireJsLocation =
-      p.join(sdkDir, 'lib', 'dev_compiler', 'kernel', 'amd', 'require.js');
-
-  @override
-  FutureOr<void> build(BuildStep buildStep) async {
-    if (buildStep.inputId.package != 'build_web_compilers') {
-      throw StateError('This builder should only be applied to the '
-          'build_web_compilers package');
-    }
-    await buildStep.writeAsBytes(
-        AssetId('build_web_compilers', 'lib/src/dev_compiler/dart_sdk.js'),
-        await File(_sdkJsLocation).readAsBytes());
-    await buildStep.writeAsBytes(
-        AssetId('build_web_compilers', 'lib/src/dev_compiler/require.js'),
-        await File(_sdkRequireJsLocation).readAsBytes());
-  }
-}
diff --git a/build_web_compilers/lib/src/web_entrypoint_builder.dart b/build_web_compilers/lib/src/web_entrypoint_builder.dart
deleted file mode 100644
index 5c1c2a3..0000000
--- a/build_web_compilers/lib/src/web_entrypoint_builder.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart';
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-
-import 'common.dart';
-import 'dart2js_bootstrap.dart';
-import 'dev_compiler_bootstrap.dart';
-
-const ddcBootstrapExtension = '.dart.bootstrap.js';
-const jsEntrypointExtension = '.dart.js';
-const jsEntrypointSourceMapExtension = '.dart.js.map';
-const jsEntrypointArchiveExtension = '.dart.js.tar.gz';
-const digestsEntrypointExtension = '.digests';
-
-/// Which compiler to use when compiling web entrypoints.
-enum WebCompiler {
-  Dart2Js,
-  DartDevc,
-}
-
-/// The top level keys supported for the `options` config for the
-/// [WebEntrypointBuilder].
-const _supportedOptions = [
-  _compiler,
-  _dart2jsArgs,
-];
-
-const _compiler = 'compiler';
-const _dart2jsArgs = 'dart2js_args';
-
-/// The deprecated keys for the `options` config for the [WebEntrypointBuilder].
-const _deprecatedOptions = [
-  'enable_sync_async',
-  'ignore_cast_failures',
-];
-
-/// A builder which compiles entrypoints for the web.
-///
-/// Supports `dart2js` and `dartdevc`.
-class WebEntrypointBuilder implements Builder {
-  final WebCompiler webCompiler;
-  final List<String> dart2JsArgs;
-
-  const WebEntrypointBuilder(this.webCompiler, {this.dart2JsArgs = const []});
-
-  factory WebEntrypointBuilder.fromOptions(BuilderOptions options) {
-    validateOptions(
-        options.config, _supportedOptions, 'build_web_compilers|entrypoint',
-        deprecatedOptions: _deprecatedOptions);
-    var compilerOption = options.config[_compiler] as String ?? 'dartdevc';
-    WebCompiler compiler;
-    switch (compilerOption) {
-      case 'dartdevc':
-        compiler = WebCompiler.DartDevc;
-        break;
-      case 'dart2js':
-        compiler = WebCompiler.Dart2Js;
-        break;
-      default:
-        throw ArgumentError.value(compilerOption, _compiler,
-            'Only `dartdevc` and `dart2js` are supported.');
-    }
-
-    if (options.config[_dart2jsArgs] is! List) {
-      throw ArgumentError.value(options.config[_dart2jsArgs], _dart2jsArgs,
-          'Expected a list for $_dart2jsArgs.');
-    }
-    var dart2JsArgs = (options.config[_dart2jsArgs] as List)
-            ?.map((arg) => '$arg')
-            ?.toList() ??
-        const <String>[];
-
-    return WebEntrypointBuilder(compiler, dart2JsArgs: dart2JsArgs);
-  }
-
-  @override
-  final buildExtensions = const {
-    '.dart': [
-      ddcBootstrapExtension,
-      jsEntrypointExtension,
-      jsEntrypointSourceMapExtension,
-      jsEntrypointArchiveExtension,
-      digestsEntrypointExtension,
-    ],
-  };
-
-  @override
-  Future<void> build(BuildStep buildStep) async {
-    var dartEntrypointId = buildStep.inputId;
-    var isAppEntrypoint = await _isAppEntryPoint(dartEntrypointId, buildStep);
-    if (!isAppEntrypoint) return;
-    if (webCompiler == WebCompiler.DartDevc) {
-      try {
-        await bootstrapDdc(buildStep, requiredAssets: _ddcSdkResources);
-      } on MissingModulesException catch (e) {
-        log.severe('$e');
-      }
-    } else if (webCompiler == WebCompiler.Dart2Js) {
-      await bootstrapDart2Js(buildStep, dart2JsArgs);
-    }
-  }
-}
-
-/// Returns whether or not [dartId] is an app entrypoint (basically, whether
-/// or not it has a `main` function).
-Future<bool> _isAppEntryPoint(AssetId dartId, AssetReader reader) async {
-  assert(dartId.extension == '.dart');
-  // Skip reporting errors here, dartdevc will report them later with nicer
-  // formatting.
-  // ignore: deprecated_member_use
-  var parsed = parseCompilationUnit(await reader.readAsString(dartId),
-      suppressErrors: true);
-  // Allow two or fewer arguments so that entrypoints intended for use with
-  // [spawnUri] get counted.
-  //
-  // TODO: This misses the case where a Dart file doesn't contain main(),
-  // but has a part that does, or it exports a `main` from another library.
-  return parsed.declarations.any((node) {
-    return node is FunctionDeclaration &&
-        node.name.name == 'main' &&
-        node.functionExpression.parameters.parameters.length <= 2;
-  });
-}
-
-/// Files copied from the SDK that are required at runtime to run a DDC
-/// application.
-final _ddcSdkResources = [
-  AssetId('build_web_compilers', 'lib/src/dev_compiler/dart_sdk.js'),
-  AssetId('build_web_compilers', 'lib/src/dev_compiler/require.js'),
-];
diff --git a/build_web_compilers/mono_pkg.yaml b/build_web_compilers/mono_pkg.yaml
deleted file mode 100644
index bae55f2..0000000
--- a/build_web_compilers/mono_pkg.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-      - dartfmt: sdk
-      - dartanalyzer: --fatal-infos --fatal-warnings .
-    - dartanalyzer: --fatal-warnings .
-      dart:
-        - 2.5.0
-  - unit_test:
-    - group:
-      - test:
-      os:
-        - linux
-        - windows
\ No newline at end of file
diff --git a/build_web_compilers/pubspec.yaml b/build_web_compilers/pubspec.yaml
deleted file mode 100644
index 40aa3d6..0000000
--- a/build_web_compilers/pubspec.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-name: build_web_compilers
-version: 2.9.0
-description: Builder implementations wrapping Dart compilers.
-homepage: https://github.com/dart-lang/build/tree/master/build_web_compilers
-
-environment:
-  sdk: ">=2.5.0 <3.0.0"
-
-dependencies:
-  analyzer: ">=0.30.0 <0.40.0"
-  archive: ^2.0.0
-  bazel_worker: ^0.1.18
-  build: ">=1.2.0 <2.0.0"
-  build_config: ">=0.3.0 <0.5.0"
-  build_modules: ^2.8.0
-  collection: ^1.0.0
-  crypto: ^2.0.0
-  glob: ^1.1.0
-  js: ^0.6.1
-  logging: ^0.11.2
-  meta: ^1.1.0
-  path: ^1.4.2
-  pool: ^1.3.0
-  scratch_space: ^0.0.2
-  source_maps: ^0.10.4
-  source_span: ^1.4.0
-  stack_trace: ^1.9.2
-
-dev_dependencies:
-  build_runner: ^1.0.0
-  build_test: ^0.10.9
-  test: ^1.0.0
-  a:
-    path: test/fixtures/a
-  b:
-    path: test/fixtures/b
diff --git a/build_web_compilers/tool/copy_builder.dart b/build_web_compilers/tool/copy_builder.dart
deleted file mode 100644
index 1191a9d..0000000
--- a/build_web_compilers/tool/copy_builder.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-
-/// Factory for the build script.
-Builder copyBuilder(_) => _CopyBuilder();
-
-/// Copies the [_stackTraceMapperJs] file to [_stackTraceMapperCopyJs].
-class _CopyBuilder extends Builder {
-  @override
-  final Map<String, List<String>> buildExtensions = {
-    _stackTraceMapperJs.path: [_stackTraceMapperCopyJs.path]
-  };
-
-  @override
-  void build(BuildStep buildStep) {
-    if (buildStep.inputId != _stackTraceMapperJs) {
-      throw StateError(
-          'Unexpected input for `CopyBuilder` expected only $_stackTraceMapperJs');
-    }
-    buildStep.writeAsString(
-        _stackTraceMapperCopyJs, buildStep.readAsString(_stackTraceMapperJs));
-  }
-}
-
-final _stackTraceMapperJs =
-    AssetId('build_web_compilers', 'web/stack_trace_mapper.dart.js');
-final _stackTraceMapperCopyJs = AssetId('build_web_compilers',
-    'lib/src/dev_compiler_stack_trace/stack_trace_mapper.dart.js');
diff --git a/build_web_compilers/web/source_map_stack_trace.dart b/build_web_compilers/web/source_map_stack_trace.dart
deleted file mode 100644
index b231ef4..0000000
--- a/build_web_compilers/web/source_map_stack_trace.dart
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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.
-
-/// Standalone utility that manages loading source maps for all Dart scripts
-/// on the page compiled with DDC.
-///
-/// This is forked from the equivalent file that ships with the SDK which is
-/// intended for use within bazel only.
-
-import 'package:path/path.dart' as p;
-import 'package:source_maps/source_maps.dart';
-import 'package:stack_trace/stack_trace.dart';
-
-/// TODO(jakemac): Remove after https://github.com/dart-lang/build/issues/2219
-void main() {}
-
-/// Convert [stackTrace], a stack trace generated by DDC-compiled
-/// JavaScript, to a native-looking stack trace using [sourceMap].
-///
-/// [roots] are the paths (usually `http:` URI strings) that DDC applications
-/// are served from.  This is used to identify sdk and package URIs.
-StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
-    {List<String> roots}) {
-  if (stackTrace is Chain) {
-    return Chain(stackTrace.traces.map(
-        (trace) => Trace.from(mapStackTrace(sourceMap, trace, roots: roots))));
-  }
-
-  var trace = Trace.from(stackTrace);
-  return Trace(trace.frames.map((frame) {
-    // If there's no line information, there's no way to translate this frame.
-    // We could return it as-is, but these lines are usually not useful anyways.
-    if (frame.line == null) return null;
-
-    // If there's no column, try using the first column of the line.
-    var column = frame.column ?? 0;
-
-    // Subtract 1 because stack traces use 1-indexed lines and columns and
-    // source maps uses 0-indexed.
-    var span = sourceMap.spanFor(frame.line - 1, column - 1,
-        uri: frame.uri?.toString());
-
-    // If we can't find a source span, ignore the frame. It's probably something
-    // internal that the user doesn't care about.
-    if (span == null) return null;
-
-    var sourceUrl = span.sourceUrl.toString();
-    for (var root in roots) {
-      if (root != null && p.url.isWithin(root, sourceUrl)) {
-        var relative = p.url.relative(sourceUrl, from: root);
-        if (relative.contains('dart:')) {
-          sourceUrl = relative.substring(relative.indexOf('dart:'));
-          break;
-        }
-        var packageRoot = '$root/packages';
-        if (p.url.isWithin(packageRoot, sourceUrl)) {
-          sourceUrl = 'package:' + p.url.relative(sourceUrl, from: packageRoot);
-          break;
-        }
-      }
-    }
-
-    if (!sourceUrl.startsWith('dart:') &&
-        sourceUrl ==
-            'package:build_web_compilers/src/dev_compiler/dart_sdk.js') {
-      // This compresses the long dart_sdk URLs if SDK source maps are missing.
-      // It's no longer linkable, but neither are the properly mapped ones
-      // above.
-      sourceUrl = 'dart:sdk_internal';
-    }
-
-    return Frame(Uri.parse(sourceUrl), span.start.line + 1,
-        span.start.column + 1, _prettifyMember(frame.member));
-  }).where((frame) => frame != null))
-      .foldFrames((Frame frame) => frame.uri.scheme.contains('dart'));
-}
-
-final escapedPipe = '\$124';
-final escapedPound = '\$35';
-
-/// Reformats a JS member name to make it look more Dart-like.
-///
-/// TODO(https://github.com/dart-lang/sdk/issues/38869): Remove this logic when
-/// DDC stack trace deobfuscation is overhauled.
-String _prettifyMember(String member) {
-  var last = member.lastIndexOf('.');
-  if (last < 0) return member;
-  var suffix = member.substring(last + 1);
-  member = suffix == 'fn' ? member : suffix;
-  // We avoid unescaping the entire member here due to DDC's deduping mechanism
-  // introducing trailing $N.
-  member = member.replaceAll(escapedPipe, '|');
-  return member.contains('|') ? _prettifyExtension(member) : member;
-}
-
-/// Reformats a JS member name as an extension method invocation.
-String _prettifyExtension(String member) {
-  var isSetter = false;
-  var pipeIndex = member.indexOf('|');
-  var spaceIndex = member.indexOf(' ');
-  var poundIndex = member.indexOf('escapedPound');
-  if (spaceIndex >= 0) {
-    // Here member is a static field or static getter/setter.
-    isSetter = member.substring(0, spaceIndex) == 'set';
-    member = member.substring(spaceIndex + 1, member.length);
-  } else if (poundIndex >= 0) {
-    // Here member is a tearoff or local property getter/setter.
-    isSetter = member.substring(pipeIndex + 1, poundIndex) == 'set';
-    member = member.replaceRange(pipeIndex + 1, poundIndex + 3, '');
-  } else {
-    var body = member.substring(pipeIndex + 1, member.length);
-    if (body.startsWith('unary') || body.startsWith('\$')) {
-      // Here member's an operator, so it's safe to unescape everything lazily.
-      member = _unescape(member);
-    }
-  }
-  member = member.replaceAll('|', '.');
-  return isSetter ? '$member=' : member;
-}
-
-/// Unescapes a DDC-escaped JS identifier name.
-///
-/// Identifier names that contain illegal JS characters are escaped by DDC to a
-/// decimal representation of the symbol's UTF-16 value.
-/// Warning: this greedily escapes characters, so it can be unsafe in the event
-/// that an escaped sequence precedes a number literal in the JS name.
-String _unescape(String name) {
-  return name.replaceAllMapped(
-      RegExp(r'\$[0-9]+'),
-      (m) =>
-          String.fromCharCode(int.parse(name.substring(m.start + 1, m.end))));
-}
diff --git a/build_web_compilers/web/stack_trace_mapper.dart b/build_web_compilers/web/stack_trace_mapper.dart
deleted file mode 100644
index 383fef2..0000000
--- a/build_web_compilers/web/stack_trace_mapper.dart
+++ /dev/null
@@ -1,141 +0,0 @@
-// 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.
-
-/// Standalone utility that manages loading source maps for all Dart scripts
-/// on the page compiled with DDC.
-///
-/// Example JavaScript usage:
-/// $dartStackTraceUtility.addLoadedListener(function() {
-///   // All Dart source maps are now loaded. It is now safe to start your
-///   // Dart application compiled with DDC.
-///   dart_library.start('your_dart_application');
-/// })
-///
-/// If $dartStackTraceUtility is set, the dart:core StackTrace class calls
-/// $dartStackTraceUtility.mapper(someJSStackTrace)
-/// to apply source maps.
-///
-/// This utility can be compiled to JavaScript using Dart2JS while the rest
-/// of the application is compiled with DDC or could be compiled with DDC.
-
-@JS()
-library stack_trace_mapper;
-
-import 'dart:convert';
-
-import 'package:js/js.dart';
-import 'package:path/path.dart' as p;
-import 'package:source_maps/source_maps.dart';
-import 'package:source_span/source_span.dart';
-import 'package:stack_trace/stack_trace.dart';
-
-import 'source_map_stack_trace.dart';
-
-/// Copied from `lib/src/dev_compiler_builder.dart`, these need to be kept in
-/// sync.
-///
-/// Given a list of [uris] as [String]s from a sourcemap, fixes them up so that
-/// they make sense in a browser context.
-///
-/// - Strips the scheme from the uri
-/// - Strips the top level directory if its not `packages`
-List<String> fixSourceMapSources(List<String> uris) {
-  return uris.map((source) {
-    var uri = Uri.parse(source);
-    // We only want to rewrite multi-root scheme uris.
-    if (uri.scheme.isEmpty) return source;
-    var newSegments = uri.pathSegments.first == 'packages'
-        ? uri.pathSegments
-        : uri.pathSegments.skip(1);
-    return Uri(path: p.url.joinAll(['/'].followedBy(newSegments))).toString();
-  }).toList();
-}
-
-typedef ReadyCallback = void Function();
-
-/// Global object DDC uses to see if a stack trace utility has been registered.
-@JS(r'$dartStackTraceUtility')
-external set dartStackTraceUtility(DartStackTraceUtility value);
-
-@JS(r'$dartLoader.rootDirectories')
-external List get rootDirectories;
-
-typedef StackTraceMapper = String Function(String stackTrace);
-typedef SourceMapProvider = dynamic Function(String modulePath);
-typedef SetSourceMapProvider = void Function(SourceMapProvider provider);
-
-@JS()
-@anonymous
-class DartStackTraceUtility {
-  external factory DartStackTraceUtility(
-      {StackTraceMapper mapper, SetSourceMapProvider setSourceMapProvider});
-}
-
-/// Source mapping that waits to parse source maps until they match the uri
-/// of a requested source map.
-///
-/// This improves startup performance compared to using MappingBundle directly.
-/// The unparsed data for the source maps must still be loaded before
-/// LazyMapping is used.
-class LazyMapping extends Mapping {
-  final _bundle = MappingBundle();
-  final SourceMapProvider _provider;
-
-  LazyMapping(this._provider);
-
-  List toJson() => _bundle.toJson();
-
-  @override
-  SourceMapSpan spanFor(int line, int column,
-      {Map<String, SourceFile> files, String uri}) {
-    if (uri == null) {
-      throw ArgumentError.notNull('uri');
-    }
-
-    if (!_bundle.containsMapping(uri)) {
-      var rawMap = _provider(uri);
-      var parsedMap = (rawMap is String ? jsonDecode(rawMap) : rawMap) as Map;
-      if (parsedMap != null) {
-        parsedMap['sources'] =
-            fixSourceMapSources((parsedMap['sources'] as List).cast());
-        var mapping = parse(jsonEncode(parsedMap)) as SingleMapping
-          ..targetUrl = uri
-          ..sourceRoot = '${p.dirname(uri)}/';
-        _bundle.addMapping(mapping);
-      }
-    }
-    var span = _bundle.spanFor(line, column, files: files, uri: uri);
-    // TODO(jacobr): we shouldn't have to filter out invalid sourceUrl entries
-    // here.
-    if (span == null || span.start.sourceUrl == null) return null;
-    var pathSegments = span.start.sourceUrl.pathSegments;
-    if (pathSegments.isNotEmpty && pathSegments.last == 'null') return null;
-    return span;
-  }
-}
-
-LazyMapping _mapping;
-
-List<String> roots = rootDirectories.map((s) => '$s').toList();
-
-String mapper(String rawStackTrace) {
-  if (_mapping == null) {
-    // This should not happen if the user has waited for the ReadyCallback
-    // to start the application.
-    throw StateError('Source maps are not done loading.');
-  }
-  var trace = Trace.parse(rawStackTrace);
-  return mapStackTrace(_mapping, trace, roots: roots).toString();
-}
-
-void setSourceMapProvider(SourceMapProvider provider) {
-  _mapping = LazyMapping(provider);
-}
-
-void main() {
-  // Register with DDC.
-  dartStackTraceUtility = DartStackTraceUtility(
-      mapper: allowInterop(mapper),
-      setSourceMapProvider: allowInterop(setSourceMapProvider));
-}
diff --git a/code_builder/.gitignore b/code_builder/.gitignore
deleted file mode 100644
index feb089d..0000000
--- a/code_builder/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Files and directories created by pub
-.dart_tool
-.packages
-.pub
-pubspec.lock
diff --git a/code_builder/.travis.yml b/code_builder/.travis.yml
deleted file mode 100644
index e415dd4..0000000
--- a/code_builder/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: dart
-dart:
-  - dev
-  - 2.1.0
-
-cache:
-  directories:
-    - $HOME/.pub-cache
-
-dist: trusty
-addons:
-  chrome: stable
-
-branches:
-  only: [master]
-
-# TODO: Give up the dream of running with dartdevc until...
-# https://github.com/dart-lang/sdk/issues/31280
-
-dart_task:
-  - test: --platform vm
-  - dartanalyzer
-  - dartfmt
diff --git a/code_builder/AUTHORS b/code_builder/AUTHORS
deleted file mode 100644
index 609e0dc..0000000
--- a/code_builder/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Below is a list of people and organizations that have contributed
-# to the project. Names should be added to the list like so:
-#
-#   Name/Organization <email address>
-
-Google Inc.
\ No newline at end of file
diff --git a/code_builder/BUILD.gn b/code_builder/BUILD.gn
deleted file mode 100644
index a5f2e0b..0000000
--- a/code_builder/BUILD.gn
+++ /dev/null
@@ -1,21 +0,0 @@
-# This file is generated by importer.py for code_builder-3.2.1
-
-import("//build/dart/dart_library.gni")
-
-dart_library("code_builder") {
-  package_name = "code_builder"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/matcher",
-    "//third_party/dart-pkg/pub/built_collection",
-    "//third_party/dart-pkg/pub/meta",
-    "//third_party/dart-pkg/pub/built_value",
-    "//third_party/dart-pkg/pub/collection",
-  ]
-}
diff --git a/code_builder/CHANGELOG.md b/code_builder/CHANGELOG.md
deleted file mode 100644
index 6f2abf0..0000000
--- a/code_builder/CHANGELOG.md
+++ /dev/null
@@ -1,684 +0,0 @@
-## 3.2.1
-
-* Escape newlines in String literals.
-* Introduce `Expression.or` for boolean OR.
-* Introduce `Expression.negate` for boolean NOT.
-* No longer emits redundant `,`s in `FunctionType`s.
-* Added support for `literalSet` and `literalConstSet`.
-* Depend on the latest `package:built_value`.
-
-## 3.2.0
-
-* Emit `=` instead of `:` for named parameter default values.
-* The `new` keyword will not be used in generated code.
-* The `const` keyword will be omitted when it can be inferred.
-* Add an option in `DartEmitter` to order directives.
-* `DartEmitter` added a `startConstCode` function to track the creation of
-  constant expression trees.
-* `BinaryExpression` added the `final bool isConst` field.
-
-## 3.1.3
-
-* Bump dependency on built_collection to include v4.0.0.
-
-## 3.1.2
-
-* Set max SDK version to `<3.0.0`.
-
-## 3.1.1
-
-* `Expression.asA` is now wrapped with parenthesis so that further calls may be
-  made on it as an expression.
-
-
-## 3.1.0
-
-* Added `Expression.asA` for creating explicit casts:
-
-```dart
-void main() {
-  test('should emit an explicit cast', () {
-    expect(
-      refer('foo').asA(refer('String')),
-      equalsDart('foo as String'),
-    );
-  });
-}
-```
-
-## 3.0.3
-
-* Fix a bug that caused all downstream users of `code_builder` to crash due to
-  `build_runner` trying to import our private builder (in `tool/`). Sorry for
-  the inconvenience.
-
-## 3.0.2
-
-* Require `source_gen: ^0.7.5`.
-
-## 3.0.1
-
-* Upgrade to `built_value` 5.1.0.
-* Export the `literalNum` function.
-* **BUG FIX**: `literal` supports a `Map`.
-
-## 3.0.0
-
-* Also infer `Constructor.lambda` for `factory` constructors.
-
-## 3.0.0-alpha
-
-* Using `equalsDart` no longer formats automatically with `dartfmt`.
-
-* Removed deprecated `Annotation` and `File` classes.
-
-* `Method.lambda` is inferred based on `Method.body` where possible and now
-  defaults to `null`.
-
-## 2.4.0
-
-* Add `equalTo`, `notEqualTo`, `greaterThan`, `lessThan`, `greateOrEqualTo`, and
-  `lessOrEqualTo` to `Expression`.
-
-## 2.3.0
-
-* Using `equalsDart` and expecting `dartfmt` by default is *deprecated*. This
-  requires this package to have a direct dependency on specific versions of
-  `dart_style` (and transitively `analyzer`), which is problematic just for
-  testing infrastructure. To future proof, we've exposed the `EqualsDart` class
-  with a `format` override:
-
-```dart
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-final DartFormatter _dartfmt = new DartFormatter();
-String _format(String source) {
-  try {
-    return _dartfmt.format(source);
-  } on FormatException catch (_) {
-    return _dartfmt.formatStatement(source);
-  }
-}
-
-/// Should be invoked in `main()` of every test in `test/**_test.dart`.
-void useDartfmt() => EqualsDart.format = _format;
-```
-
-* Added `Expression.isA` and `Expression.isNotA`:
-
-```dart
-void main() {
-  test('should emit an is check', () {
-    expect(
-      refer('foo').isA(refer('String')),
-      equalsDart('foo is String'),
-    );
-  });
-}
-```
-
-* Deprecated `Annotation`. It is now legal to simply pass any `Expression` as
-  a metadata annotation to `Class`, `Method`, `Field,` and `Parameter`. In
-  `3.0.0`, the `Annotation` class will be completely removed:
-
-```dart
-void main() {
-  test('should create a class with a annotated constructor', () {
-    expect(
-      new Class((b) => b
-        ..name = 'Foo'
-        ..constructors.add(
-          new Constructor((b) => b..annotations.add(refer('deprecated'))))),
-      equalsDart(r'''
-        class Foo {
-          @deprecated
-          Foo();
-        }
-      '''),
-    );
-  });
-}
-```
-
-* Added inference support for `Method.lambda` and `Constructor.lambda`. If not
-  explicitly provided and the body of the function originated from an
-  `Expression` then `lambda` is inferred to be true. This is not a breaking
-  change yet, as it requires an explicit `null` value. In `3.0.0` this will be
-  the default:
-
-```dart
-void main() {
-  final animal = new Class((b) => b
-    ..name = 'Animal'
-    ..extend = refer('Organism')
-    ..methods.add(new Method.returnsVoid((b) => b
-      ..name = 'eat'
-      // In 3.0.0, this may be omitted and still is inferred.
-      ..lambda = null
-      ..body = refer('print').call([literalString('Yum!')]).code)));
-  final emitter = new DartEmitter();
-  print(new DartFormatter().format('${animal.accept(emitter)}'));
-}
-```
-
-* Added `nullSafeProperty` to `Expression` to access properties with `?.`
-* Added `conditional` to `Expression` to use the ternary operator `? : `
-* Methods taking `positionalArguments` accept `Iterable<Expression>`
-* **BUG FIX**: Parameters can take a `FunctionType` as a `type`.
-  `Reference.type` now returns a `Reference`. Note that this change is
-  technically breaking but should not impacts most clients.
-
-## 2.2.0
-
-* Imports are prefixed with `_i1` rather than `_1` which satisfies the lint
-  `lowercase_with_underscores`. While not a strictly breaking change you may
-  have to fix/regenerate golden file-like tests. We added documentation that
-  the specific prefix is not considered stable.
-
-* Added `Expression.index` for accessing the `[]` operator:
-
-```dart
-void main() {
-  test('should emit an index operator', () {
-    expect(
-      refer('bar').index(literalTrue).assignVar('foo').statement,
-      equalsDart('var foo = bar[true];'),
-    );
-  });
-
-  test('should emit an index operator set', () {
-    expect(
-      refer('bar')
-        .index(literalTrue)
-        .assign(literalFalse)
-        .assignVar('foo')
-        .statement,
-      equalsDart('var foo = bar[true] = false;'),
-    );
-  });
-}
-```
-
-* `literalList` accepts an `Iterable` argument.
-
-* Fixed an NPE when a method had a return type of a `FunctionType`:
-
-```dart
-void main() {
-  test('should create a method with a function type return type', () {
-    expect(
-      new Method((b) => b
-        ..name = 'foo'
-        ..returns = new FunctionType((b) => b
-          ..returnType = refer('String')
-          ..requiredParameters.addAll([
-            refer('int'),
-          ]))),
-      equalsDart(r'''
-        String Function(int) foo();
-      '''),
-    );
-  });
-}
-```
-
-## 2.1.0
-
-We now require the Dart 2.0-dev branch SDK (`>= 2.0.0-dev`).
-
-* Added support for raw `String` literals.
-* Automatically escapes single quotes in now-raw `String` literals.
-* Deprecated `File`, which is now a redirect to the preferred class, `Library`.
-
-This helps avoid symbol clashes when used with `dart:io`, a popular library. It
-is now safe to do the following and get full access to the `code_builder` API:
-
-```dart
-import 'dart:io';
-
-import 'package:code_builder/code_builder.dart' hide File;
-```
-
-We will remove `File` in `3.0.0`, so use `Library` instead.
-
-## 2.0.0
-
-Re-released without a direct dependency on `package:analyzer`!
-
-For users of the `1.x` branch of `code_builder`, this is a pretty big breaking
-change but ultimately is for the better - it's easier to evolve this library
-now and even add your own builders on top of the library.
-
-```dart
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-void main() {
-  final animal = new Class((b) => b
-    ..name = 'Animal'
-    ..extend = refer('Organism')
-    ..methods.add(new Method.returnsVoid((b) => b
-      ..name = 'eat'
-      ..lambda = true
-      ..body = const Code('print(\'Yum\')'))));
-  final emitter = new DartEmitter();
-  print(new DartFormatter().format('${animal.accept(emitter)}'));
-}
-```
-
-...outputs...
-
-```dart
-class Animal extends Organism {
-  void eat() => print('Yum!');
-}
-```
-
-**Major changes**:
-
-* Builders now use `built_value`, and have a more consistent, friendly API.
-* Builders are now consistent - they don't any work until code is emitted.
-* It's possible to overwrite the built-in code emitting, formatting, etc by
-  providing your own visitors. See `DartEmitter` as an example of the built-in
-  visitor/emitter.
-* Most of the expression and statement level helpers were removed; in practice
-  they were difficult to write and maintain, and many users commonly asked for
-  opt-out type APIs. See the `Code` example below:
-
-```dart
-void main() {
-  var code = new Code('x + y = z');
-  code.expression;
-  code.statement;
-}
-```
-
-See the commit log, examples, and tests for full details. While we want to try
-and avoid breaking changes, suggestions, new features, and incremental updates
-are welcome!
-
-## 2.0.0-beta
-
-* Added `lazySpec` and `lazyCode` to lazily create code on visit [#145](https://github.com/dart-lang/code_builder/issues/145).
-
-* **BUG FIX**: `equalsDart` emits the failing source code [#147](https://github.com/dart-lang/code_builder/issues/147).
-* **BUG FIX**: Top-level `lambda` `Method`s no longer emit invalid code [#146](https://github.com/dart-lang/code_builder/issues/146).
-
-## 2.0.0-alpha+3
-
-* Added `Expression.annotation` and `Expression.annotationNamed`.
-* Added `Method.closure` to create an `Expression`.
-* Added `FunctionType`.
-* Added `{new|const}InstanceNamed` to `Expression` [#135](https://github.com/dart-lang/code_builder/issues/135).
-  * Also added a `typeArguments` option to all invocations.
-* Added `assign{...}` variants to `Expression` [#137](https://github.com/dart-lang/code_builder/issues/137).
-* Added `.awaited` and `.returned` to `Expression` [#138](https://github.com/dart-lang/code_builder/issues/138).
-
-* **BUG FIX**: `Block` now implements `Code` [#136](https://github.com/dart-lang/code_builder/issues/136).
-* **BUG FIX**: `new DartEmitter.scoped()` applies prefixing [#139](https://github.com/dart-lang/code_builder/issues/139).
-
-* Renamed many of the `.asFoo(...)` and `.toFoo(...)` methods to single getter:
-  * `asCode()` to `code`
-  * `asStatement()` to `statement`
-  * `toExpression()` to `expression`
-
-* Moved `{new|const}Instance{[Named]}` from `Expression` to `Reference`.
-
-## 2.0.0-alpha+2
-
-* Upgraded `build_runner` from `^0.3.0` to `>=0.4.0 <0.6.0`.
-* Upgraded `build_value{_generator}` from `^1.0.0` to `>=2.0.0 <5.0.0`.
-* Upgraded `source_gen` from `>=0.5.0 <0.7.0` to `^0.7.0`.
-
-* Added `MethodModifier` to allow emit a `Method` with `async|async*|sync*`.
-* Added `show|hide` to `Directive`.
-* Added `Directive.importDeferredAs`.
-* Added a new line character after emitting some types (class, method, etc).
-* Added `refer` as a short-hand for `new Reference(...)`.
-  * `Reference` now implements `Expression`.
-
-* Added many classes/methods for writing bodies of `Code` fluently:
-  * `Expression`
-  * `LiteralExpression`
-    * `literal`
-    * `literalNull`
-    * `literalBool`
-    * `literalTrue`
-    * `literalFalse`
-    * `literalNum`
-    * `literalString`
-    * `literalList` and `literalConstList`
-    * `literalMap` and `literalConstMap`
-  * `const Code(staticString)`
-  * `const Code.scope((allocate) => '')`
-
-* Removed `SimpleSpecVisitor` (it was unused).
-* Removed `implements Reference` from `Method` and `Field`; not a lot of value.
-
-* `SpecVisitor<T>`'s methods all have an optional `[T context]` parameter now.
-  * This makes it much easier to avoid allocating extra `StringBuffer`s.
-* `equalsDart` removes insignificant white space before comparing results.
-
-## 2.0.0-alpha+1
-
-* Removed `Reference.localScope`. Just use `Reference(symbol)` now.
-* Allow `Reference` instead of an explicit `TypeReference` in most APIs.
-  * `toType()` is performed for you as part the emitter process
-
-```dart
-final animal = new Class((b) => b
-  ..name = 'Animal'
-  // Used to need a suffix of .toType().
-  ..extend = const Reference('Organism')
-  ..methods.add(new Method.returnsVoid((b) => b
-    ..name = 'eat'
-    ..lambda = true
-    ..body = new Code((b) => b..code = 'print(\'Yum\')'))));
-```
-
-* We now support the Dart 2.0 pre-release SDKs (`<2.0.0-dev.infinity`)
-* Removed the ability to treat `Class` as a `TypeReference`.
-  * Was required for compilation to `dart2js`, which is now tested on travis.
-
-## 2.0.0-alpha
-
-* Complete re-write to not use `package:analyzer`.
-* Code generation now properly uses the _builder_ pattern (via `built_value`).
-* See examples and tests for details.
-
-## 1.0.4
-
-* Added `isInstanceOf` to `ExpressionBuilder`, which performs an `is` check:
-
-```dart
-expect(
-  reference('foo').isInstanceOf(_barType),
-  equalsSource('foo is Bar'),
-);
-```
-
-## 1.0.3
-
-* Support latest `pkg/analyzer` and `pkg/func`.
-
-## 1.0.2
-
-* Update internals to use newer analyzer API
-
-## 1.0.1
-
-* Support the latest version of `package:dart_style`.
-
-## 1.0.0
-
-First full release. At this point all changes until `2.0.0` will be backwards
-compatible (new features) or bug fixes that are not breaking. This doesn't mean
-that the entire Dart language is buildable with our API, though.
-
-**Contributions are welcome.**
-
-- Exposed `uri` in `ImportBuilder`, `ExportBuilder`, and `Part[Of]Builder`.
-
-## 1.0.0-beta+7
-
-- Added `ExpressionBuilder#ternary`.
-
-## 1.0.0-beta+6
-
-- Added `TypeDefBuilder`.
-- Added `FunctionParameterBuilder`.
-- Added `asAbstract` to various `MethodBuilder` constructors.
-
-## 1.0.0-beta+5
-
-- Re-published the package without merge conflicts.
-
-## 1.0.0-beta+4
-
-- Renamed `PartBuilder` to `PartOfBuilder`.
-- Added a new class, `PartBuilder`, to represent `part '...dart'` directives.
-- Added the `HasAnnotations` interface to all library/part/directive builders.
-- Added `asFactory` and `asConst` to `ConstructorBuilder`.
-- Added `ConstructorBuilder.redirectTo` for a redirecting factory constructor.
-- Added a `name` getter to `ReferenceBuilder`.
-- Supplying an empty constructor name (`''`) is equivalent to `null` (default).
-- Automatically encodes string literals with multiple lines as `'''`.
-- Added `asThrow` to `ExpressionBuilder`.
-- Fixed a bug that prevented `FieldBuilder` from being used at the top-level.
-
-## 1.0.0-beta+3
-
-- Added support for `genericTypes` parameter for `ExpressionBuilder#invoke`:
-
-```dart
-expect(
-  explicitThis.invoke('doThing', [literal(true)], genericTypes: [
-    lib$core.bool,
-  ]),
-  equalsSource(r'''
-    this.doThing<bool>(true)
-  '''),
-);
-```
-
-- Added a `castAs` method to `ExpressionBuilder`:
-
-```dart
-expect(
-  literal(1.0).castAs(lib$core.num),
-  equalsSource(r'''
-    1.0 as num
-  '''),
-);
-```
-
-### BREAKING CHANGES
-
-- Removed `namedNewInstance` and `namedConstInstance`, replaced with `constructor: `:
-
-```dart
-expect(
-  reference('Foo').newInstance([], constructor: 'other'),
-  equalsSource(r'''
-    new Foo.other()
-  '''),
-);
-```
-
-- Renamed `named` parameter to `namedArguments`:
-
-```dart
-expect(
-  reference('doThing').call(
-    [literal(true)],
-    namedArguments: {
-      'otherFlag': literal(false),
-    },
-  ),
-  equalsSource(r'''
-    doThing(true, otherFlag: false)
-  '''),
-);
-```
-
-## 1.0.0-beta+2
-
-### BREAKING CHANGES
-
-Avoid creating symbols that can collide with the Dart language:
-
-- `MethodModifier.async` -> `MethodModifier.asAsync`
-- `MethodModifier.asyncStar` -> `MethodModifier.asAsyncStar`
-- `MethodModifier.syncStar` -> `MethodModifier.asSyncStar`
-
-## 1.0.0-beta+1
-
-- Add support for `switch` statements
-- Add support for a raw expression and statement
-  - `new ExpressionBuilder.raw(...)`
-  - `new StatemnetBuilder.raw(...)`
-
-This should help cover any cases not covered with builders today.
-
-- Allow referring to a `ClassBuilder` and `TypeBuilder` as an expression
-- Add support for accessing the index `[]` operator on an expression
-
-### BREAKING CHANGES
-
-- Changed `ExpressionBuilder.asAssign` to always take an `ExpressionBuilder` as
-  target and removed the `value` property. Most changes are pretty simple, and
-  involve just using `reference(...)`. For example:
-
-```dart
-literal(true).asAssign(reference('flag'))
-```
-
-... emits `flag = true`.
-
-## 1.0.0-beta
-
-- Add support for `async`, `sync`, `sync*` functions
-- Add support for expression `asAwait`, `asYield`, `asYieldStar`
-- Add `toExportBuilder` and `toImportBuilder` to types and references
-- Fix an import scoping bug in `return` statements and named constructor invocations.
-- Added constructor initializer support
-- Add `while` and `do {} while` loop support
-- Add `for` and `for-in` support
-- Added a `name` getter for `ParameterBuilder`
-
-## 1.0.0-alpha+7
-
-- Make use of new analyzer API in preparation for analyzer version 0.30.
-
-## 1.0.0-alpha+6
-
-- `MethodBuilder.closure` emits properly as a top-level function
-
-## 1.0.0-alpha+5
-
-- MethodBuilder with no statements will create an empty block instead of
-  a semicolon.
-
-```dart
-// main() {}
-method('main')
-```
-
-- Fix lambdas and closures to not include a trailing semicolon when used
-  as an expression.
-
-```dart
- // () => false
- new MethodBuilder.closure(returns: literal(false));
-```
-
-## 1.0.0-alpha+4
-
-- Add support for latest `pkg/analyzer`.
-
-## 1.0.0-alpha+3
-
-- BREAKING CHANGE: Added generics support to `TypeBuilder`:
-
-`importFrom` becomes a _named_, not positional argument, and the named
-argument `genericTypes` is added (`Iterable<TypeBuilder>`).
-
-```dart
-// List<String>
-new TypeBuilder('List', genericTypes: [reference('String')])
-```
-
-- Added generic support to `ReferenceBuilder`:
-
-```dart
-// List<String>
-reference('List').toTyped([reference('String')])
-```
-
-- Fixed a bug where `ReferenceBuilder.buildAst` was not implemented
-- Added `and` and `or` methods to `ExpressionBuilder`:
-
-```dart
-// true || false
-literal(true).or(literal(false));
-
-// true && false
-literal(true).and(literal(false));
-```
-
-- Added support for creating closures - `MethodBuilder.closure`:
-
-```dart
-// () => true
-new MethodBuilder.closure(
-  returns: literal(true),
-  returnType: lib$core.bool,
-)
-```
-
-## 1.0.0-alpha+2
-
-- Added `returnVoid` to well, `return;`
-- Added support for top-level field assignments:
-
-```dart
-new LibraryBuilder()..addMember(literal(false).asConst('foo'))
-```
-
-- Added support for specifying a `target` when using `asAssign`:
-
-```dart
-// Outputs bank.bar = goldBar
-reference('goldBar').asAssign('bar', target: reference('bank'))
-```
-
-- Added support for the cascade operator:
-
-```dart
-// Outputs foo..doThis()..doThat()
-reference('foo').cascade((c) => <ExpressionBuilder> [
-  c.invoke('doThis', []),
-  c.invoke('doThat', []),
-]);
-```
-
-- Added support for accessing a property
-
-```dart
-// foo.bar
-reference('foo').property('bar');
-```
-
-## 1.0.0-alpha+1
-
-- Slight updates to confusing documentation.
-- Added support for null-aware assignments.
-- Added `show` and `hide` support to `ImportBuilder`
-- Added `deferred` support to `ImportBuilder`
-- Added `ExportBuilder`
-- Added `list` and `map` literals that support generic types
-
-## 1.0.0-alpha
-
-- Large refactor that makes the library more feature complete.
-
-## 0.1.1
-
-- Add concept of `Scope` and change `toAst` to support it
-
-Now your entire AST tree can be scoped and import directives
-automatically added to a `LibraryBuilder` for you if you use
-`LibraryBuilder.scope`.
-
-## 0.1.0
-
-- Initial version
diff --git a/code_builder/CONTRIBUTING.md b/code_builder/CONTRIBUTING.md
deleted file mode 100644
index 0dfd0f7..0000000
--- a/code_builder/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-### Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-All submissions, including submissions by project members, require review.
-
-### File headers
-All files in the project must start with the following header.
-
-    // 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.
-
-### The small print
-Contributions made by corporations are covered by a different agreement than the
-one above, the
-[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
\ No newline at end of file
diff --git a/code_builder/LICENSE b/code_builder/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/code_builder/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/code_builder/README.md b/code_builder/README.md
deleted file mode 100644
index 9d9f394..0000000
--- a/code_builder/README.md
+++ /dev/null
@@ -1,107 +0,0 @@
-[![Pub package](https://img.shields.io/pub/v/code_builder.svg)](https://pub.dartlang.org/packages/code_builder)
-[![Build status](https://travis-ci.org/dart-lang/code_builder.svg)](https://travis-ci.org/dart-lang/code_builder)
-[![Latest docs](https://img.shields.io/badge/dartdocs-latest-blue.svg)](https://www.dartdocs.org/documentation/code_builder/latest)
-[![Gitter chat](https://badges.gitter.im/dart-lang/build.svg)](https://gitter.im/dart-lang/build)
-
-A fluent, builder-based library for generating valid Dart code.
-
-## Usage
-
-`code_builder` has a narrow and user-friendly API.
-
-See the `example` and `test` folders for additional examples.
-
-For example creating a class with a method:
-
-```dart
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-void main() {
-  final animal = Class((b) => b
-    ..name = 'Animal'
-    ..extend = refer('Organism')
-    ..methods.add(Method.returnsVoid((b) => b
-      ..name = 'eat'
-      ..body = const Code("print('Yum');"))));
-  final emitter = DartEmitter();
-  print(DartFormatter().format('${animal.accept(emitter)}'));
-}
-```
-
-Outputs:
-```dart
-class Animal extends Organism {
-  void eat() => print('Yum!');
-}
-```
-
-Have a complicated set of dependencies for your generated code?
-`code_builder` supports automatic scoping of your ASTs to automatically
-use prefixes to avoid symbol conflicts:
-
-```dart
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-void main() {
-  final library = Library((b) => b.body.addAll([
-        Method((b) => b
-          ..body = const Code('')
-          ..name = 'doThing'
-          ..returns = refer('Thing', 'package:a/a.dart')),
-        Method((b) => b
-          ..body = const Code('')
-          ..name = 'doOther'
-          ..returns = refer('Other', 'package:b/b.dart')),
-      ]));
-  final emitter = DartEmitter(Allocator.simplePrefixing());
-  print(DartFormatter().format('${library.accept(emitter)}'));
-}
-```
-
-Outputs:
-```dart
-import 'package:a/a.dart' as _i1;
-import 'package:b/b.dart' as _i2;
-
-_i1.Thing doThing() {}
-_i2.Other doOther() {}
-```
-
-## Contributing
-
-* Read and help us document common patterns over [at the wiki][wiki].
-* Is there a *bug* in the code? [File an issue][issue].
-
-If a feature is missing (the Dart language is always evolving) or you'd like an
-easier or better way to do something, consider [opening a pull request][pull].
-You can always [file an issue][issue], but generally speaking feature requests
-will be on a best-effort basis.
-
-> **NOTE**: Due to the evolving Dart SDK the local `dartfmt` must be used to
-> format this repository. You can run it simply from the command-line:
->
-> ```sh
-> $ pub run dart_style:format -w .
-> ```
-
-[wiki]: https://github.com/dart-lang/code_builder/wiki
-[issue]: https://github.com/dart-lang/code_builder/issues
-[pull]: https://github.com/dart-lang/code_builder/pulls
-
-### Updating generated (`.g.dart`) files
-
-> **NOTE**: There is currently a limitation in `build_runner` that requires
-> a workaround for developing this package. We expect this to be unnecessary
-> in the future.
-
-Use [`build_runner`][build_runner]:
-
-```bash
-$ mv build.disabled.yaml build.yaml
-$ pub run build_runner build --delete-conflicting-outputs
-$ mv build.yaml build.disabled.yaml
-```
-
-[build_runner]: https://pub.dartlang.org/packages/build_runner
diff --git a/code_builder/analysis_options.yaml b/code_builder/analysis_options.yaml
deleted file mode 100644
index b4b37b4..0000000
--- a/code_builder/analysis_options.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-analyzer:
-  strong-mode:
-    implicit-casts: false
-    implicit-dynamic: false
-
-linter:
-  rules:
-    # Error Rules
-    - avoid_empty_else
-    - comment_references
-    - control_flow_in_finally
-    - empty_statements
-    - hash_and_equals
-    - invariant_booleans
-    - iterable_contains_unrelated_type
-    - list_remove_unrelated_type
-    - no_adjacent_strings_in_list
-    - no_duplicate_case_values
-    - test_types_in_equals
-    - throw_in_finally
-    - unrelated_type_equality_checks
-    - valid_regexps
-
-    # Style Rules
-    - annotate_overrides
-    - avoid_init_to_null
-    - avoid_return_types_on_setters
-    - camel_case_types
-    - cascade_invocations
-    - constant_identifier_names
-    - directives_ordering
-    - empty_catches
-    - empty_constructor_bodies
-    - implementation_imports
-    - library_names
-    - library_prefixes
-    - non_constant_identifier_names
-    - omit_local_variable_types
-    - only_throw_errors
-    - prefer_adjacent_string_concatenation
-    - prefer_collection_literals
-    - prefer_const_constructors
-    - prefer_contains
-    - prefer_equal_for_default_values
-    - prefer_final_fields
-    - prefer_final_locals
-    - prefer_initializing_formals
-    - prefer_interpolation_to_compose_strings
-    - prefer_is_empty
-    - prefer_is_not_empty
-    - recursive_getters
-    - slash_for_doc_comments
-    - type_init_formals
-    - unnecessary_brace_in_string_interps
-    - unnecessary_this
diff --git a/code_builder/build.disabled.yaml b/code_builder/build.disabled.yaml
deleted file mode 100644
index 2eed503..0000000
--- a/code_builder/build.disabled.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-targets:
-  $default:
-    builders:
-      "|_built_value":
-
-builders:
-  _built_value:
-    target: ":code_builder"
-    import: "../../../tool/src/builder.dart"
-    builder_factories:
-      - "builtValueBuilder"
-    build_extensions:
-      ".dart": [".g.dart"]
-    build_to: "source"
diff --git a/code_builder/example/example.dart b/code_builder/example/example.dart
deleted file mode 100644
index 577752b..0000000
--- a/code_builder/example/example.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-final _dartfmt = DartFormatter();
-
-void main() {
-  print('animalClass():\n${'=' * 40}\n${animalClass()}');
-  print('scopedLibrary():\n${'=' * 40}\n${scopedLibrary()}');
-}
-
-/// Outputs:
-///
-/// ```dart
-/// class Animal extends Organism {
-///   void eat() => print('Yum!');
-/// }
-/// ```
-String animalClass() {
-  final animal = Class((b) => b
-    ..name = 'Animal'
-    ..extend = refer('Organism')
-    ..methods.add(Method.returnsVoid((b) => b
-      ..name = 'eat'
-      ..body = refer('print').call([literalString('Yum!')]).code)));
-  return _dartfmt.format('${animal.accept(DartEmitter())}');
-}
-
-/// Outputs:
-///
-/// ```dart
-/// import 'package:a/a.dart' as _i1;
-/// import 'package:b/b.dart' as _i2;
-///
-/// _i1.Thing doThing() {}
-/// _i2.Other doOther() {}
-/// ```
-String scopedLibrary() {
-  final methods = [
-    Method((b) => b
-      ..body = const Code('')
-      ..name = 'doThing'
-      ..returns = refer('Thing', 'package:a/a.dart')),
-    Method((b) => b
-      ..body = const Code('')
-      ..name = 'doOther'
-      ..returns = refer('Other', 'package:b/b.dart')),
-  ];
-  final library = Library((b) => b.body.addAll(methods));
-  return _dartfmt.format('${library.accept(DartEmitter.scoped())}');
-}
diff --git a/code_builder/lib/code_builder.dart b/code_builder/lib/code_builder.dart
deleted file mode 100644
index 2be4733..0000000
--- a/code_builder/lib/code_builder.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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.
-
-export 'src/allocator.dart' show Allocator;
-export 'src/base.dart' show lazySpec, Spec;
-export 'src/emitter.dart' show DartEmitter;
-export 'src/matchers.dart' show equalsDart, EqualsDart;
-export 'src/specs/class.dart' show Class, ClassBuilder;
-export 'src/specs/code.dart'
-    show lazyCode, Block, BlockBuilder, Code, StaticCode, ScopedCode;
-export 'src/specs/constructor.dart' show Constructor, ConstructorBuilder;
-export 'src/specs/directive.dart'
-    show Directive, DirectiveType, DirectiveBuilder;
-export 'src/specs/expression.dart'
-    show
-        ToCodeExpression,
-        BinaryExpression,
-        CodeExpression,
-        Expression,
-        ExpressionEmitter,
-        ExpressionVisitor,
-        InvokeExpression,
-        InvokeExpressionType,
-        LiteralExpression,
-        LiteralListExpression,
-        literal,
-        literalNull,
-        literalNum,
-        literalBool,
-        literalList,
-        literalConstList,
-        literalSet,
-        literalConstSet,
-        literalMap,
-        literalConstMap,
-        literalString,
-        literalTrue,
-        literalFalse;
-export 'src/specs/field.dart' show Field, FieldBuilder, FieldModifier;
-export 'src/specs/library.dart' show Library, LibraryBuilder;
-export 'src/specs/method.dart'
-    show
-        Method,
-        MethodBuilder,
-        MethodModifier,
-        MethodType,
-        Parameter,
-        ParameterBuilder;
-export 'src/specs/reference.dart' show refer, Reference;
-export 'src/specs/type_function.dart' show FunctionType, FunctionTypeBuilder;
-export 'src/specs/type_reference.dart' show TypeReference, TypeReferenceBuilder;
diff --git a/code_builder/lib/src/allocator.dart b/code_builder/lib/src/allocator.dart
deleted file mode 100644
index 87315d5..0000000
--- a/code_builder/lib/src/allocator.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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 'specs/directive.dart';
-import 'specs/reference.dart';
-
-/// Collects references and automatically allocates prefixes and imports.
-///
-/// `Allocator` takes out the manual work of deciding whether a symbol will
-/// clash with other imports in your generated code, or what imports are needed
-/// to resolve all symbols in your generated code.
-abstract class Allocator {
-  /// An allocator that does not prefix symbols nor collects imports.
-  static const Allocator none = _NullAllocator();
-
-  /// Creates a new default allocator that applies no prefixing.
-  factory Allocator() = _Allocator;
-
-  /// Creates a new allocator that applies naive prefixing to avoid conflicts.
-  ///
-  /// This implementation is not optimized for any particular code generation
-  /// style and instead takes a conservative approach of prefixing _every_
-  /// import except references to `dart:core` (which are considered always
-  /// imported).
-  ///
-  /// The prefixes are not guaranteed to be stable and cannot be expected to
-  /// have any particular value.
-  factory Allocator.simplePrefixing() = _PrefixedAllocator;
-
-  /// Returns a reference string given a [reference] object.
-  ///
-  /// For example, a no-op implementation:
-  /// ```dart
-  /// allocate(const Reference('List', 'dart:core')); // Returns 'List'.
-  /// ```
-  ///
-  /// Where-as an implementation that prefixes imports might output:
-  /// ```dart
-  /// allocate(const Reference('Foo', 'package:foo')); // Returns '_i1.Foo'.
-  /// ```
-  String allocate(Reference reference);
-
-  /// All imports that have so far been added implicitly via [allocate].
-  Iterable<Directive> get imports;
-}
-
-class _Allocator implements Allocator {
-  final _imports = Set<String>();
-
-  @override
-  String allocate(Reference reference) {
-    if (reference.url != null) {
-      _imports.add(reference.url);
-    }
-    return reference.symbol;
-  }
-
-  @override
-  Iterable<Directive> get imports {
-    return _imports.map((u) => Directive.import(u));
-  }
-}
-
-class _NullAllocator implements Allocator {
-  const _NullAllocator();
-
-  @override
-  String allocate(Reference reference) => reference.symbol;
-
-  @override
-  Iterable<Directive> get imports => const [];
-}
-
-class _PrefixedAllocator implements Allocator {
-  static const _doNotPrefix = ['dart:core'];
-
-  final _imports = <String, int>{};
-  var _keys = 1;
-
-  @override
-  String allocate(Reference reference) {
-    final symbol = reference.symbol;
-    if (reference.url == null || _doNotPrefix.contains(reference.url)) {
-      return symbol;
-    }
-    return '_i${_imports.putIfAbsent(reference.url, _nextKey)}.$symbol';
-  }
-
-  int _nextKey() => _keys++;
-
-  @override
-  Iterable<Directive> get imports {
-    return _imports.keys.map(
-      (u) => Directive.import(u, as: '_i${_imports[u]}'),
-    );
-  }
-}
diff --git a/code_builder/lib/src/base.dart b/code_builder/lib/src/base.dart
deleted file mode 100644
index 529dd5b..0000000
--- a/code_builder/lib/src/base.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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 'visitors.dart';
-
-abstract class Spec {
-  R accept<R>(SpecVisitor<R> visitor, [R context]);
-}
-
-/// Returns a generic [Spec] that is lazily generated when visited.
-Spec lazySpec(Spec Function() generate) => _LazySpec(generate);
-
-class _LazySpec implements Spec {
-  final Spec Function() generate;
-
-  const _LazySpec(this.generate);
-
-  @override
-  R accept<R>(SpecVisitor<R> visitor, [R context]) {
-    return generate().accept(visitor, context);
-  }
-}
diff --git a/code_builder/lib/src/emitter.dart b/code_builder/lib/src/emitter.dart
deleted file mode 100644
index d7a688f..0000000
--- a/code_builder/lib/src/emitter.dart
+++ /dev/null
@@ -1,531 +0,0 @@
-// 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 'allocator.dart';
-import 'base.dart';
-import 'specs/class.dart';
-import 'specs/code.dart';
-import 'specs/constructor.dart';
-import 'specs/directive.dart';
-import 'specs/expression.dart';
-import 'specs/field.dart';
-import 'specs/library.dart';
-import 'specs/method.dart';
-import 'specs/reference.dart';
-import 'specs/type_function.dart';
-import 'specs/type_reference.dart';
-import 'visitors.dart';
-
-/// Helper method improving on [StringSink.writeAll].
-///
-/// For every `Spec` in [elements], executing [visit].
-///
-/// If [elements] is at least 2 elements, inserts [separator] delimiting them.
-StringSink visitAll<T>(
-  Iterable<T> elements,
-  StringSink output,
-  void visit(T element), [
-  String separator = ', ',
-]) {
-  // Basically, this whole method is an improvement on
-  //   output.writeAll(specs.map((s) => s.accept(visitor));
-  //
-  // ... which would allocate more StringBuffer(s) for a one-time use.
-  if (elements.isEmpty) {
-    return output;
-  }
-  final iterator = elements.iterator..moveNext();
-  visit(iterator.current);
-  while (iterator.moveNext()) {
-    output.write(separator);
-    visit(iterator.current);
-  }
-  return output;
-}
-
-class DartEmitter extends Object
-    with CodeEmitter, ExpressionEmitter
-    implements SpecVisitor<StringSink> {
-  @override
-  final Allocator allocator;
-
-  /// If directives should be ordered while emitting.
-  ///
-  /// Ordering rules follow the guidance in
-  /// [Effective Dart](https://www.dartlang.org/guides/language/effective-dart/style#ordering)
-  /// and the
-  /// [directives_ordering](http://dart-lang.github.io/linter/lints/directives_ordering.html)
-  /// lint.
-  final bool orderDirectives;
-
-  /// Creates a new instance of [DartEmitter].
-  ///
-  /// May specify an [Allocator] to use for symbols, otherwise uses a no-op.
-  DartEmitter([this.allocator = Allocator.none, bool orderDirectives = false])
-      : orderDirectives = orderDirectives ?? false;
-
-  /// Creates a new instance of [DartEmitter] with simple automatic imports.
-  factory DartEmitter.scoped({bool orderDirectives = false}) {
-    return DartEmitter(Allocator.simplePrefixing(), orderDirectives);
-  }
-
-  static bool _isLambdaBody(Code code) =>
-      code is ToCodeExpression && !code.isStatement;
-
-  /// Whether the provided [method] is considered a lambda method.
-  static bool _isLambdaMethod(Method method) =>
-      method.lambda ?? _isLambdaBody(method.body);
-
-  /// Whether the provided [constructor] is considered a lambda method.
-  static bool _isLambdaConstructor(Constructor constructor) =>
-      constructor.lambda ??
-      constructor.factory && _isLambdaBody(constructor.body);
-
-  @override
-  visitAnnotation(Expression spec, [StringSink output]) {
-    (output ??= StringBuffer()).write('@');
-    spec.accept(this, output);
-    output.write(' ');
-    return output;
-  }
-
-  @override
-  visitClass(Class spec, [StringSink output]) {
-    output ??= StringBuffer();
-    spec.docs.forEach(output.writeln);
-    spec.annotations.forEach((a) => visitAnnotation(a, output));
-    if (spec.abstract) {
-      output.write('abstract ');
-    }
-    output.write('class ${spec.name}');
-    visitTypeParameters(spec.types.map((r) => r.type), output);
-    if (spec.extend != null) {
-      output.write(' extends ');
-      spec.extend.type.accept(this, output);
-    }
-    if (spec.mixins.isNotEmpty) {
-      output
-        ..write(' with ')
-        ..writeAll(
-            spec.mixins.map<StringSink>((m) => m.type.accept(this)), ',');
-    }
-    if (spec.implements.isNotEmpty) {
-      output
-        ..write(' implements ')
-        ..writeAll(
-            spec.implements.map<StringSink>((m) => m.type.accept(this)), ',');
-    }
-    output.write(' {');
-    spec.constructors.forEach((c) {
-      visitConstructor(c, spec.name, output);
-      output.writeln();
-    });
-    spec.fields.forEach((f) {
-      visitField(f, output);
-      output.writeln();
-    });
-    spec.methods.forEach((m) {
-      visitMethod(m, output);
-      if (_isLambdaMethod(m)) {
-        output.write(';');
-      }
-      output.writeln();
-    });
-    output.writeln(' }');
-    return output;
-  }
-
-  @override
-  visitConstructor(Constructor spec, String clazz, [StringSink output]) {
-    output ??= StringBuffer();
-    spec.docs.forEach(output.writeln);
-    spec.annotations.forEach((a) => visitAnnotation(a, output));
-    if (spec.external) {
-      output.write('external ');
-    }
-    if (spec.factory) {
-      output.write('factory ');
-    }
-    if (spec.constant) {
-      output.write('const ');
-    }
-    output.write(clazz);
-    if (spec.name != null) {
-      output..write('.')..write(spec.name);
-    }
-    output.write('(');
-    if (spec.requiredParameters.isNotEmpty) {
-      var count = 0;
-      for (final p in spec.requiredParameters) {
-        count++;
-        _visitParameter(p, output);
-        if (spec.requiredParameters.length != count ||
-            spec.optionalParameters.isNotEmpty) {
-          output.write(', ');
-        }
-      }
-    }
-    if (spec.optionalParameters.isNotEmpty) {
-      final named = spec.optionalParameters.any((p) => p.named);
-      if (named) {
-        output.write('{');
-      } else {
-        output.write('[');
-      }
-      var count = 0;
-      for (final p in spec.optionalParameters) {
-        count++;
-        _visitParameter(p, output, optional: true, named: named);
-        if (spec.optionalParameters.length != count) {
-          output.write(', ');
-        }
-      }
-      if (named) {
-        output.write('}');
-      } else {
-        output.write(']');
-      }
-    }
-    output.write(')');
-    if (spec.initializers.isNotEmpty) {
-      output.write(' : ');
-      var count = 0;
-      for (final initializer in spec.initializers) {
-        count++;
-        initializer.accept(this, output);
-        if (count != spec.initializers.length) {
-          output.write(', ');
-        }
-      }
-    }
-    if (spec.redirect != null) {
-      output.write(' = ');
-      spec.redirect.type.accept(this, output);
-      output.write(';');
-    } else if (spec.body != null) {
-      if (_isLambdaConstructor(spec)) {
-        output.write(' => ');
-        spec.body.accept(this, output);
-        output.write(';');
-      } else {
-        output.write(' { ');
-        spec.body.accept(this, output);
-        output.write(' }');
-      }
-    } else {
-      output.write(';');
-    }
-    output.writeln();
-    return output;
-  }
-
-  @override
-  visitDirective(Directive spec, [StringSink output]) {
-    output ??= StringBuffer();
-    if (spec.type == DirectiveType.import) {
-      output.write('import ');
-    } else {
-      output.write('export ');
-    }
-    output.write("'${spec.url}'");
-    if (spec.as != null) {
-      if (spec.deferred) {
-        output.write(' deferred ');
-      }
-      output.write(' as ${spec.as}');
-    }
-    if (spec.show.isNotEmpty) {
-      output
-        ..write(' show ')
-        ..writeAll(spec.show, ', ');
-    } else if (spec.hide.isNotEmpty) {
-      output
-        ..write(' hide ')
-        ..writeAll(spec.hide, ', ');
-    }
-    output.write(';');
-    return output;
-  }
-
-  @override
-  visitField(Field spec, [StringSink output]) {
-    output ??= StringBuffer();
-    spec.docs.forEach(output.writeln);
-    spec.annotations.forEach((a) => visitAnnotation(a, output));
-    if (spec.static) {
-      output.write('static ');
-    }
-    switch (spec.modifier) {
-      case FieldModifier.var$:
-        if (spec.type == null) {
-          output.write('var ');
-        }
-        break;
-      case FieldModifier.final$:
-        output.write('final ');
-        break;
-      case FieldModifier.constant:
-        output.write('const ');
-        break;
-    }
-    if (spec.type != null) {
-      spec.type.type.accept(this, output);
-      output.write(' ');
-    }
-    output.write(spec.name);
-    if (spec.assignment != null) {
-      output.write(' = ');
-      startConstCode(spec.modifier == FieldModifier.constant, () {
-        spec.assignment.accept(this, output);
-      });
-    }
-    output.writeln(';');
-    return output;
-  }
-
-  @override
-  visitLibrary(Library spec, [StringSink output]) {
-    output ??= StringBuffer();
-    // Process the body first in order to prime the allocators.
-    final body = StringBuffer();
-    for (final spec in spec.body) {
-      spec.accept(this, body);
-      if (spec is Method && _isLambdaMethod(spec)) {
-        body.write(';');
-      }
-    }
-
-    final directives = <Directive>[]
-      ..addAll(spec.directives)
-      ..addAll(allocator.imports);
-
-    if (orderDirectives) {
-      directives.sort();
-    }
-
-    Directive previous;
-    for (final directive in directives) {
-      if (_newLineBetween(orderDirectives, previous, directive)) {
-        // Note: dartfmt handles creating new lines between directives.
-        // 2 lines are written here. The first one comes after the previous
-        // directive `;`, the second is the empty line.
-        output..writeln()..writeln();
-      }
-      directive.accept(this, output);
-      previous = directive;
-    }
-    output.write(body);
-    return output;
-  }
-
-  @override
-  visitFunctionType(FunctionType spec, [StringSink output]) {
-    output ??= StringBuffer();
-    if (spec.returnType != null) {
-      spec.returnType.accept(this, output);
-      output.write(' ');
-    }
-    output.write('Function');
-    if (spec.types.isNotEmpty) {
-      output.write('<');
-      visitAll<Reference>(spec.types, output, (spec) {
-        spec.accept(this, output);
-      });
-      output.write('>');
-    }
-    output.write('(');
-    visitAll<Reference>(spec.requiredParameters, output, (spec) {
-      spec.accept(this, output);
-    });
-    if (spec.requiredParameters.isNotEmpty &&
-        (spec.optionalParameters.isNotEmpty ||
-            spec.namedParameters.isNotEmpty)) {
-      output.write(', ');
-    }
-    if (spec.optionalParameters.isNotEmpty) {
-      output.write('[');
-      visitAll<Reference>(spec.optionalParameters, output, (spec) {
-        spec.accept(this, output);
-      });
-      output.write(']');
-    } else if (spec.namedParameters.isNotEmpty) {
-      output.write('{');
-      visitAll<String>(spec.namedParameters.keys, output, (name) {
-        spec.namedParameters[name].accept(this, output);
-        output..write(' ')..write(name);
-      });
-      output.write('}');
-    }
-    return output..write(')');
-  }
-
-  @override
-  visitMethod(Method spec, [StringSink output]) {
-    output ??= StringBuffer();
-    spec.docs.forEach(output.writeln);
-    spec.annotations.forEach((a) => visitAnnotation(a, output));
-    if (spec.external) {
-      output.write('external ');
-    }
-    if (spec.static) {
-      output.write('static ');
-    }
-    if (spec.returns != null) {
-      spec.returns.accept(this, output);
-      output.write(' ');
-    }
-    if (spec.type == MethodType.getter) {
-      output..write('get ')..write(spec.name);
-    } else {
-      if (spec.type == MethodType.setter) {
-        output.write('set ');
-      }
-      if (spec.name != null) {
-        output.write(spec.name);
-      }
-      visitTypeParameters(spec.types.map((r) => r.type), output);
-      output.write('(');
-      if (spec.requiredParameters.isNotEmpty) {
-        var count = 0;
-        for (final p in spec.requiredParameters) {
-          count++;
-          _visitParameter(p, output);
-          if (spec.requiredParameters.length != count ||
-              spec.optionalParameters.isNotEmpty) {
-            output.write(', ');
-          }
-        }
-      }
-      if (spec.optionalParameters.isNotEmpty) {
-        final named = spec.optionalParameters.any((p) => p.named);
-        if (named) {
-          output.write('{');
-        } else {
-          output.write('[');
-        }
-        var count = 0;
-        for (final p in spec.optionalParameters) {
-          count++;
-          _visitParameter(p, output, optional: true, named: named);
-          if (spec.optionalParameters.length != count) {
-            output.write(', ');
-          }
-        }
-        if (named) {
-          output.write('}');
-        } else {
-          output.write(']');
-        }
-      }
-      output.write(')');
-    }
-    if (spec.body != null) {
-      if (spec.modifier != null) {
-        switch (spec.modifier) {
-          case MethodModifier.async:
-            output.write(' async ');
-            break;
-          case MethodModifier.asyncStar:
-            output.write(' async* ');
-            break;
-          case MethodModifier.syncStar:
-            output.write(' sync* ');
-            break;
-        }
-      }
-      if (_isLambdaMethod(spec)) {
-        output.write(' => ');
-      } else {
-        output.write(' { ');
-      }
-      spec.body.accept(this, output);
-      if (!_isLambdaMethod(spec)) {
-        output.write(' } ');
-      }
-    } else {
-      output.write(';');
-    }
-    return output;
-  }
-
-  // Expose as a first-class visit function only if needed.
-  void _visitParameter(
-    Parameter spec,
-    StringSink output, {
-    bool optional = false,
-    bool named = false,
-  }) {
-    spec.docs.forEach(output.writeln);
-    spec.annotations.forEach((a) => visitAnnotation(a, output));
-    if (spec.type != null) {
-      spec.type.type.accept(this, output);
-      output.write(' ');
-    }
-    if (spec.toThis) {
-      output.write('this.');
-    }
-    output.write(spec.name);
-    if (optional && spec.defaultTo != null) {
-      output.write(' = ');
-      spec.defaultTo.accept(this, output);
-    }
-  }
-
-  @override
-  visitReference(Reference spec, [StringSink output]) {
-    return (output ??= StringBuffer())..write(allocator.allocate(spec));
-  }
-
-  @override
-  visitSpec(Spec spec, [StringSink output]) => spec.accept(this, output);
-
-  @override
-  visitType(TypeReference spec, [StringSink output]) {
-    output ??= StringBuffer();
-    // Intentionally not .accept to avoid stack overflow.
-    visitReference(spec, output);
-    if (spec.bound != null) {
-      output.write(' extends ');
-      spec.bound.type.accept(this, output);
-    }
-    visitTypeParameters(spec.types.map((r) => r.type), output);
-    return output;
-  }
-
-  @override
-  visitTypeParameters(Iterable<Reference> specs, [StringSink output]) {
-    output ??= StringBuffer();
-    if (specs.isNotEmpty) {
-      output
-        ..write('<')
-        ..writeAll(specs.map<StringSink>((s) => s.accept(this)), ',')
-        ..write('>');
-    }
-    return output;
-  }
-}
-
-/// Returns `true` if:
-///
-/// * [ordered] is `true`
-/// * [a] is non-`null`
-/// * If there should be an empty line before [b] if it's emitted after [a].
-bool _newLineBetween(bool ordered, Directive a, Directive b) {
-  if (!ordered) return false;
-  if (a == null) return false;
-
-  assert(b != null);
-
-  // Put a line between imports and exports
-  if (a.type != b.type) return true;
-
-  // Within exports, don't put in extra blank lines
-  if (a.type == DirectiveType.export) {
-    assert(b.type == DirectiveType.export);
-    return false;
-  }
-
-  // Return `true` if the schemes for [a] and [b] are different
-  return !Uri.parse(a.url).isScheme(Uri.parse(b.url).scheme);
-}
diff --git a/code_builder/lib/src/matchers.dart b/code_builder/lib/src/matchers.dart
deleted file mode 100644
index dda8ac8..0000000
--- a/code_builder/lib/src/matchers.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:matcher/matcher.dart';
-
-import 'base.dart';
-import 'emitter.dart';
-
-/// Encodes [spec] as Dart source code.
-String _dart(Spec spec, DartEmitter emitter) =>
-    EqualsDart._format(spec.accept<StringSink>(emitter).toString());
-
-/// Returns a matcher for Dart source code.
-Matcher equalsDart(
-  String source, [
-  DartEmitter emitter,
-]) =>
-    EqualsDart._(EqualsDart._format(source), emitter ?? DartEmitter());
-
-/// Implementation detail of using the [equalsDart] matcher.
-///
-/// See [EqualsDart.format] to specify the default source code formatter.
-class EqualsDart extends Matcher {
-  /// May override to provide a function to format Dart on [equalsDart].
-  ///
-  /// By default, uses [collapseWhitespace], but it is recommended to instead
-  /// use `dart_style` (dartfmt) where possible. See `test/common.dart` for an
-  /// example.
-  static String Function(String) format = (String source) {
-    return collapseWhitespace(source);
-  };
-
-  static String _format(String source) {
-    try {
-      return format(source).trim();
-    } catch (_) {
-      // Ignored on purpose, probably not exactly valid Dart code.
-      return collapseWhitespace(source).trim();
-    }
-  }
-
-  final DartEmitter _emitter;
-  final String _source;
-
-  const EqualsDart._(this._source, this._emitter);
-
-  @override
-  Description describe(Description description) => description.add(_source);
-
-  @override
-  Description describeMismatch(
-    covariant Spec item,
-    Description mismatchDescription,
-    state,
-    verbose,
-  ) {
-    final result = _dart(item, _emitter);
-    return equals(result).describeMismatch(
-      _source,
-      mismatchDescription.add(result),
-      state,
-      verbose,
-    );
-  }
-
-  @override
-  bool matches(covariant Spec item, _) => _dart(item, _emitter) == _source;
-}
diff --git a/code_builder/lib/src/mixins/annotations.dart b/code_builder/lib/src/mixins/annotations.dart
deleted file mode 100644
index f8bc948..0000000
--- a/code_builder/lib/src/mixins/annotations.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_collection/built_collection.dart';
-
-import '../specs/expression.dart';
-
-/// A type of AST node that can have metadata [annotations].
-abstract class HasAnnotations {
-  /// Annotations as metadata on the node.
-  BuiltList<Expression> get annotations;
-}
-
-/// Compliment to the [HasAnnotations] mixin for metadata [annotations].
-abstract class HasAnnotationsBuilder {
-  /// Annotations as metadata on the node.
-  ListBuilder<Expression> annotations;
-}
diff --git a/code_builder/lib/src/mixins/dartdoc.dart b/code_builder/lib/src/mixins/dartdoc.dart
deleted file mode 100644
index ae44bd1..0000000
--- a/code_builder/lib/src/mixins/dartdoc.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_collection/built_collection.dart';
-
-abstract class HasDartDocs {
-  /// Dart docs.
-  BuiltList<String> get docs;
-}
-
-abstract class HasDartDocsBuilder {
-  /// Dart docs.
-  ListBuilder<String> docs;
-}
diff --git a/code_builder/lib/src/mixins/generics.dart b/code_builder/lib/src/mixins/generics.dart
deleted file mode 100644
index 04a049e..0000000
--- a/code_builder/lib/src/mixins/generics.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_collection/built_collection.dart';
-
-import '../specs/reference.dart';
-
-abstract class HasGenerics {
-  /// Generic type parameters.
-  BuiltList<Reference> get types;
-}
-
-abstract class HasGenericsBuilder {
-  /// Generic type parameters.
-  ListBuilder<Reference> types;
-}
diff --git a/code_builder/lib/src/specs/class.dart b/code_builder/lib/src/specs/class.dart
deleted file mode 100644
index 3e596a6..0000000
--- a/code_builder/lib/src/specs/class.dart
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/annotations.dart';
-import '../mixins/dartdoc.dart';
-import '../mixins/generics.dart';
-import '../visitors.dart';
-import 'constructor.dart';
-import 'expression.dart';
-import 'field.dart';
-import 'method.dart';
-import 'reference.dart';
-
-part 'class.g.dart';
-
-@immutable
-abstract class Class extends Object
-    with HasAnnotations, HasDartDocs, HasGenerics
-    implements Built<Class, ClassBuilder>, Spec {
-  factory Class([void updates(ClassBuilder b)]) = _$Class;
-
-  Class._();
-
-  /// Whether the class is `abstract`.
-  bool get abstract;
-
-  @override
-  BuiltList<Expression> get annotations;
-
-  @override
-  BuiltList<String> get docs;
-
-  @nullable
-  Reference get extend;
-
-  BuiltList<Reference> get implements;
-
-  BuiltList<Reference> get mixins;
-
-  @override
-  BuiltList<Reference> get types;
-
-  BuiltList<Constructor> get constructors;
-  BuiltList<Method> get methods;
-  BuiltList<Field> get fields;
-
-  /// Name of the class.
-  String get name;
-
-  @override
-  R accept<R>(
-    SpecVisitor<R> visitor, [
-    R context,
-  ]) =>
-      visitor.visitClass(this, context);
-}
-
-abstract class ClassBuilder extends Object
-    with HasAnnotationsBuilder, HasDartDocsBuilder, HasGenericsBuilder
-    implements Builder<Class, ClassBuilder> {
-  factory ClassBuilder() = _$ClassBuilder;
-
-  ClassBuilder._();
-
-  /// Whether the class is `abstract`.
-  bool abstract = false;
-
-  @override
-  ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
-  @override
-  ListBuilder<String> docs = ListBuilder<String>();
-
-  Reference extend;
-
-  ListBuilder<Reference> implements = ListBuilder<Reference>();
-  ListBuilder<Reference> mixins = ListBuilder<Reference>();
-
-  @override
-  ListBuilder<Reference> types = ListBuilder<Reference>();
-
-  ListBuilder<Constructor> constructors = ListBuilder<Constructor>();
-  ListBuilder<Method> methods = ListBuilder<Method>();
-  ListBuilder<Field> fields = ListBuilder<Field>();
-
-  /// Name of the class.
-  String name;
-}
diff --git a/code_builder/lib/src/specs/class.g.dart b/code_builder/lib/src/specs/class.g.dart
deleted file mode 100644
index 68cff19..0000000
--- a/code_builder/lib/src/specs/class.g.dart
+++ /dev/null
@@ -1,353 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'class.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Class extends Class {
-  @override
-  final bool abstract;
-  @override
-  final BuiltList<Expression> annotations;
-  @override
-  final BuiltList<String> docs;
-  @override
-  final Reference extend;
-  @override
-  final BuiltList<Reference> implements;
-  @override
-  final BuiltList<Reference> mixins;
-  @override
-  final BuiltList<Reference> types;
-  @override
-  final BuiltList<Constructor> constructors;
-  @override
-  final BuiltList<Method> methods;
-  @override
-  final BuiltList<Field> fields;
-  @override
-  final String name;
-
-  factory _$Class([void updates(ClassBuilder b)]) =>
-      (new ClassBuilder()..update(updates)).build() as _$Class;
-
-  _$Class._(
-      {this.abstract,
-      this.annotations,
-      this.docs,
-      this.extend,
-      this.implements,
-      this.mixins,
-      this.types,
-      this.constructors,
-      this.methods,
-      this.fields,
-      this.name})
-      : super._() {
-    if (abstract == null)
-      throw new BuiltValueNullFieldError('Class', 'abstract');
-    if (annotations == null)
-      throw new BuiltValueNullFieldError('Class', 'annotations');
-    if (docs == null) throw new BuiltValueNullFieldError('Class', 'docs');
-    if (implements == null)
-      throw new BuiltValueNullFieldError('Class', 'implements');
-    if (mixins == null) throw new BuiltValueNullFieldError('Class', 'mixins');
-    if (types == null) throw new BuiltValueNullFieldError('Class', 'types');
-    if (constructors == null)
-      throw new BuiltValueNullFieldError('Class', 'constructors');
-    if (methods == null) throw new BuiltValueNullFieldError('Class', 'methods');
-    if (fields == null) throw new BuiltValueNullFieldError('Class', 'fields');
-    if (name == null) throw new BuiltValueNullFieldError('Class', 'name');
-  }
-
-  @override
-  Class rebuild(void updates(ClassBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$ClassBuilder toBuilder() => new _$ClassBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! Class) return false;
-    return abstract == other.abstract &&
-        annotations == other.annotations &&
-        docs == other.docs &&
-        extend == other.extend &&
-        implements == other.implements &&
-        mixins == other.mixins &&
-        types == other.types &&
-        constructors == other.constructors &&
-        methods == other.methods &&
-        fields == other.fields &&
-        name == other.name;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(
-        $jc(
-            $jc(
-                $jc(
-                    $jc(
-                        $jc(
-                            $jc(
-                                $jc(
-                                    $jc(
-                                        $jc($jc(0, abstract.hashCode),
-                                            annotations.hashCode),
-                                        docs.hashCode),
-                                    extend.hashCode),
-                                implements.hashCode),
-                            mixins.hashCode),
-                        types.hashCode),
-                    constructors.hashCode),
-                methods.hashCode),
-            fields.hashCode),
-        name.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('Class')
-          ..add('abstract', abstract)
-          ..add('annotations', annotations)
-          ..add('docs', docs)
-          ..add('extend', extend)
-          ..add('implements', implements)
-          ..add('mixins', mixins)
-          ..add('types', types)
-          ..add('constructors', constructors)
-          ..add('methods', methods)
-          ..add('fields', fields)
-          ..add('name', name))
-        .toString();
-  }
-}
-
-class _$ClassBuilder extends ClassBuilder {
-  _$Class _$v;
-
-  @override
-  bool get abstract {
-    _$this;
-    return super.abstract;
-  }
-
-  @override
-  set abstract(bool abstract) {
-    _$this;
-    super.abstract = abstract;
-  }
-
-  @override
-  ListBuilder<Expression> get annotations {
-    _$this;
-    return super.annotations ??= new ListBuilder<Expression>();
-  }
-
-  @override
-  set annotations(ListBuilder<Expression> annotations) {
-    _$this;
-    super.annotations = annotations;
-  }
-
-  @override
-  ListBuilder<String> get docs {
-    _$this;
-    return super.docs ??= new ListBuilder<String>();
-  }
-
-  @override
-  set docs(ListBuilder<String> docs) {
-    _$this;
-    super.docs = docs;
-  }
-
-  @override
-  Reference get extend {
-    _$this;
-    return super.extend;
-  }
-
-  @override
-  set extend(Reference extend) {
-    _$this;
-    super.extend = extend;
-  }
-
-  @override
-  ListBuilder<Reference> get implements {
-    _$this;
-    return super.implements ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set implements(ListBuilder<Reference> implements) {
-    _$this;
-    super.implements = implements;
-  }
-
-  @override
-  ListBuilder<Reference> get mixins {
-    _$this;
-    return super.mixins ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set mixins(ListBuilder<Reference> mixins) {
-    _$this;
-    super.mixins = mixins;
-  }
-
-  @override
-  ListBuilder<Reference> get types {
-    _$this;
-    return super.types ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set types(ListBuilder<Reference> types) {
-    _$this;
-    super.types = types;
-  }
-
-  @override
-  ListBuilder<Constructor> get constructors {
-    _$this;
-    return super.constructors ??= new ListBuilder<Constructor>();
-  }
-
-  @override
-  set constructors(ListBuilder<Constructor> constructors) {
-    _$this;
-    super.constructors = constructors;
-  }
-
-  @override
-  ListBuilder<Method> get methods {
-    _$this;
-    return super.methods ??= new ListBuilder<Method>();
-  }
-
-  @override
-  set methods(ListBuilder<Method> methods) {
-    _$this;
-    super.methods = methods;
-  }
-
-  @override
-  ListBuilder<Field> get fields {
-    _$this;
-    return super.fields ??= new ListBuilder<Field>();
-  }
-
-  @override
-  set fields(ListBuilder<Field> fields) {
-    _$this;
-    super.fields = fields;
-  }
-
-  @override
-  String get name {
-    _$this;
-    return super.name;
-  }
-
-  @override
-  set name(String name) {
-    _$this;
-    super.name = name;
-  }
-
-  _$ClassBuilder() : super._();
-
-  ClassBuilder get _$this {
-    if (_$v != null) {
-      super.abstract = _$v.abstract;
-      super.annotations = _$v.annotations?.toBuilder();
-      super.docs = _$v.docs?.toBuilder();
-      super.extend = _$v.extend;
-      super.implements = _$v.implements?.toBuilder();
-      super.mixins = _$v.mixins?.toBuilder();
-      super.types = _$v.types?.toBuilder();
-      super.constructors = _$v.constructors?.toBuilder();
-      super.methods = _$v.methods?.toBuilder();
-      super.fields = _$v.fields?.toBuilder();
-      super.name = _$v.name;
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(Class other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$Class;
-  }
-
-  @override
-  void update(void updates(ClassBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$Class build() {
-    _$Class _$result;
-    try {
-      _$result = _$v ??
-          new _$Class._(
-              abstract: abstract,
-              annotations: annotations.build(),
-              docs: docs.build(),
-              extend: extend,
-              implements: implements.build(),
-              mixins: mixins.build(),
-              types: types.build(),
-              constructors: constructors.build(),
-              methods: methods.build(),
-              fields: fields.build(),
-              name: name);
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'annotations';
-        annotations.build();
-        _$failedField = 'docs';
-        docs.build();
-
-        _$failedField = 'implements';
-        implements.build();
-        _$failedField = 'mixins';
-        mixins.build();
-        _$failedField = 'types';
-        types.build();
-        _$failedField = 'constructors';
-        constructors.build();
-        _$failedField = 'methods';
-        methods.build();
-        _$failedField = 'fields';
-        fields.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'Class', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/specs/code.dart b/code_builder/lib/src/specs/code.dart
deleted file mode 100644
index e14c102..0000000
--- a/code_builder/lib/src/specs/code.dart
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../allocator.dart';
-import '../base.dart';
-import '../emitter.dart';
-import '../visitors.dart';
-
-import 'expression.dart';
-import 'reference.dart';
-
-part 'code.g.dart';
-
-/// Returns a scoped symbol to [Reference], with an import prefix if needed.
-///
-/// This is short-hand for [Allocator.allocate] in most implementations.
-typedef String Allocate(Reference reference);
-
-/// Represents arbitrary Dart code (either expressions or statements).
-///
-/// See the various constructors for details.
-abstract class Code implements Spec {
-  /// Create a simple code body based on a static string.
-  const factory Code(String code) = StaticCode._;
-
-  /// Create a code based that may use a provided [Allocator] for scoping:
-  ///
-  /// ```dart
-  /// // Emits `_i123.FooType()`, where `_i123` is the import prefix.
-  ///
-  /// Code.scope((a) {
-  ///   return '${a.allocate(fooType)}()'
-  /// });
-  /// ```
-  const factory Code.scope(
-    String Function(Allocate allocate) scope,
-  ) = ScopedCode._;
-
-  @override
-  R accept<R>(covariant CodeVisitor<R> visitor, [R context]);
-}
-
-/// Represents blocks of statements of Dart code.
-abstract class Block implements Built<Block, BlockBuilder>, Code, Spec {
-  factory Block([void updates(BlockBuilder b)]) = _$Block;
-
-  factory Block.of(Iterable<Code> statements) {
-    return Block((b) => b..statements.addAll(statements));
-  }
-
-  Block._();
-
-  @override
-  R accept<R>(covariant CodeVisitor<R> visitor, [R context]) {
-    return visitor.visitBlock(this, context);
-  }
-
-  BuiltList<Code> get statements;
-}
-
-abstract class BlockBuilder implements Builder<Block, BlockBuilder> {
-  factory BlockBuilder() = _$BlockBuilder;
-
-  BlockBuilder._();
-
-  /// Adds an [expression] to [statements].
-  ///
-  /// **NOTE**: Not all expressions are _useful_ statements.
-  void addExpression(Expression expression) {
-    statements.add(expression.statement);
-  }
-
-  ListBuilder<Code> statements = ListBuilder<Code>();
-}
-
-/// Knowledge of different types of blocks of code in Dart.
-///
-/// **INTERNAL ONLY**.
-abstract class CodeVisitor<T> implements SpecVisitor<T> {
-  T visitBlock(Block code, [T context]);
-  T visitStaticCode(StaticCode code, [T context]);
-  T visitScopedCode(ScopedCode code, [T context]);
-}
-
-/// Knowledge of how to write valid Dart code from [CodeVisitor].
-abstract class CodeEmitter implements CodeVisitor<StringSink> {
-  @protected
-  Allocator get allocator;
-
-  @override
-  visitBlock(Block block, [StringSink output]) {
-    output ??= StringBuffer();
-    return visitAll<Code>(block.statements, output, (statement) {
-      statement.accept(this, output);
-    }, '\n');
-  }
-
-  @override
-  visitStaticCode(StaticCode code, [StringSink output]) {
-    output ??= StringBuffer();
-    return output..write(code.code);
-  }
-
-  @override
-  visitScopedCode(ScopedCode code, [StringSink output]) {
-    output ??= StringBuffer();
-    return output..write(code.code(allocator.allocate));
-  }
-}
-
-/// Represents a code block that requires lazy visiting.
-class LazyCode implements Code {
-  final Spec Function(SpecVisitor) generate;
-
-  const LazyCode._(this.generate);
-
-  @override
-  R accept<R>(CodeVisitor<R> visitor, [R context]) {
-    return generate(visitor).accept(visitor, context);
-  }
-}
-
-/// Returns a generic [Code] that is lazily generated when visited.
-Code lazyCode(Code Function() generate) => _LazyCode(generate);
-
-class _LazyCode implements Code {
-  final Code Function() generate;
-
-  const _LazyCode(this.generate);
-
-  @override
-  R accept<R>(CodeVisitor<R> visitor, [R context]) {
-    return generate().accept(visitor, context);
-  }
-}
-
-/// Represents a simple, literal code block to be inserted as-is.
-class StaticCode implements Code {
-  final String code;
-
-  const StaticCode._(this.code);
-
-  @override
-  R accept<R>(CodeVisitor<R> visitor, [R context]) {
-    return visitor.visitStaticCode(this, context);
-  }
-
-  @override
-  String toString() => code;
-}
-
-/// Represents a code block that may require scoping.
-class ScopedCode implements Code {
-  final String Function(Allocate) code;
-
-  const ScopedCode._(this.code);
-
-  @override
-  R accept<R>(CodeVisitor<R> visitor, [R context]) {
-    return visitor.visitScopedCode(this, context);
-  }
-
-  @override
-  String toString() => code((ref) => ref.symbol);
-}
diff --git a/code_builder/lib/src/specs/code.g.dart b/code_builder/lib/src/specs/code.g.dart
deleted file mode 100644
index 5243ec8..0000000
--- a/code_builder/lib/src/specs/code.g.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'code.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Block extends Block {
-  @override
-  final BuiltList<Code> statements;
-
-  factory _$Block([void updates(BlockBuilder b)]) =>
-      (new BlockBuilder()..update(updates)).build() as _$Block;
-
-  _$Block._({this.statements}) : super._() {
-    if (statements == null)
-      throw new BuiltValueNullFieldError('Block', 'statements');
-  }
-
-  @override
-  Block rebuild(void updates(BlockBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$BlockBuilder toBuilder() => new _$BlockBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! Block) return false;
-    return statements == other.statements;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(0, statements.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('Block')..add('statements', statements))
-        .toString();
-  }
-}
-
-class _$BlockBuilder extends BlockBuilder {
-  _$Block _$v;
-
-  @override
-  ListBuilder<Code> get statements {
-    _$this;
-    return super.statements ??= new ListBuilder<Code>();
-  }
-
-  @override
-  set statements(ListBuilder<Code> statements) {
-    _$this;
-    super.statements = statements;
-  }
-
-  _$BlockBuilder() : super._();
-
-  BlockBuilder get _$this {
-    if (_$v != null) {
-      super.statements = _$v.statements?.toBuilder();
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(Block other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$Block;
-  }
-
-  @override
-  void update(void updates(BlockBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$Block build() {
-    _$Block _$result;
-    try {
-      _$result = _$v ?? new _$Block._(statements: statements.build());
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'statements';
-        statements.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'Block', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/specs/constructor.dart b/code_builder/lib/src/specs/constructor.dart
deleted file mode 100644
index 04fcc70..0000000
--- a/code_builder/lib/src/specs/constructor.dart
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../mixins/annotations.dart';
-import '../mixins/dartdoc.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'method.dart';
-import 'reference.dart';
-
-part 'constructor.g.dart';
-
-@immutable
-abstract class Constructor extends Object
-    with HasAnnotations, HasDartDocs
-    implements Built<Constructor, ConstructorBuilder> {
-  factory Constructor([void updates(ConstructorBuilder b)]) = _$Constructor;
-
-  Constructor._();
-
-  @override
-  BuiltList<Expression> get annotations;
-
-  @override
-  BuiltList<String> get docs;
-
-  /// Optional parameters.
-  BuiltList<Parameter> get optionalParameters;
-
-  /// Required parameters.
-  BuiltList<Parameter> get requiredParameters;
-
-  /// Constructor initializer statements.
-  BuiltList<Code> get initializers;
-
-  /// Body of the method.
-  @nullable
-  Code get body;
-
-  /// Whether the constructor should be prefixed with `external`.
-  bool get external;
-
-  /// Whether the constructor should be prefixed with `const`.
-  bool get constant;
-
-  /// Whether this constructor should be prefixed with `factory`.
-  bool get factory;
-
-  /// Whether this constructor is a simple lambda expression.
-  @nullable
-  bool get lambda;
-
-  /// Name of the constructor - optional.
-  @nullable
-  String get name;
-
-  /// If non-null, redirect to this constructor.
-  @nullable
-  Reference get redirect;
-}
-
-abstract class ConstructorBuilder extends Object
-    with HasAnnotationsBuilder, HasDartDocsBuilder
-    implements Builder<Constructor, ConstructorBuilder> {
-  factory ConstructorBuilder() = _$ConstructorBuilder;
-
-  ConstructorBuilder._();
-
-  @override
-  ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
-  @override
-  ListBuilder<String> docs = ListBuilder<String>();
-
-  /// Optional parameters.
-  ListBuilder<Parameter> optionalParameters = ListBuilder<Parameter>();
-
-  /// Required parameters.
-  ListBuilder<Parameter> requiredParameters = ListBuilder<Parameter>();
-
-  /// Constructor initializer statements.
-  ListBuilder<Code> initializers = ListBuilder<Code>();
-
-  /// Body of the constructor.
-  Code body;
-
-  /// Whether the constructor should be prefixed with `const`.
-  bool constant = false;
-
-  /// Whether the constructor should be prefixed with `external`.
-  bool external = false;
-
-  /// Whether this constructor should be prefixed with `factory`.
-  bool factory = false;
-
-  /// Whether this constructor is a simple lambda expression.
-  bool lambda;
-
-  /// Name of the constructor - optional.
-  String name;
-
-  /// If non-null, redirect to this constructor.
-  @nullable
-  Reference redirect;
-}
diff --git a/code_builder/lib/src/specs/constructor.g.dart b/code_builder/lib/src/specs/constructor.g.dart
deleted file mode 100644
index efc08f2..0000000
--- a/code_builder/lib/src/specs/constructor.g.dart
+++ /dev/null
@@ -1,368 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'constructor.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Constructor extends Constructor {
-  @override
-  final BuiltList<Expression> annotations;
-  @override
-  final BuiltList<String> docs;
-  @override
-  final BuiltList<Parameter> optionalParameters;
-  @override
-  final BuiltList<Parameter> requiredParameters;
-  @override
-  final BuiltList<Code> initializers;
-  @override
-  final Code body;
-  @override
-  final bool external;
-  @override
-  final bool constant;
-  @override
-  final bool factory;
-  @override
-  final bool lambda;
-  @override
-  final String name;
-  @override
-  final Reference redirect;
-
-  factory _$Constructor([void updates(ConstructorBuilder b)]) =>
-      (new ConstructorBuilder()..update(updates)).build() as _$Constructor;
-
-  _$Constructor._(
-      {this.annotations,
-      this.docs,
-      this.optionalParameters,
-      this.requiredParameters,
-      this.initializers,
-      this.body,
-      this.external,
-      this.constant,
-      this.factory,
-      this.lambda,
-      this.name,
-      this.redirect})
-      : super._() {
-    if (annotations == null)
-      throw new BuiltValueNullFieldError('Constructor', 'annotations');
-    if (docs == null) throw new BuiltValueNullFieldError('Constructor', 'docs');
-    if (optionalParameters == null)
-      throw new BuiltValueNullFieldError('Constructor', 'optionalParameters');
-    if (requiredParameters == null)
-      throw new BuiltValueNullFieldError('Constructor', 'requiredParameters');
-    if (initializers == null)
-      throw new BuiltValueNullFieldError('Constructor', 'initializers');
-    if (external == null)
-      throw new BuiltValueNullFieldError('Constructor', 'external');
-    if (constant == null)
-      throw new BuiltValueNullFieldError('Constructor', 'constant');
-    if (factory == null)
-      throw new BuiltValueNullFieldError('Constructor', 'factory');
-  }
-
-  @override
-  Constructor rebuild(void updates(ConstructorBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$ConstructorBuilder toBuilder() => new _$ConstructorBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! Constructor) return false;
-    return annotations == other.annotations &&
-        docs == other.docs &&
-        optionalParameters == other.optionalParameters &&
-        requiredParameters == other.requiredParameters &&
-        initializers == other.initializers &&
-        body == other.body &&
-        external == other.external &&
-        constant == other.constant &&
-        factory == other.factory &&
-        lambda == other.lambda &&
-        name == other.name &&
-        redirect == other.redirect;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(
-        $jc(
-            $jc(
-                $jc(
-                    $jc(
-                        $jc(
-                            $jc(
-                                $jc(
-                                    $jc(
-                                        $jc(
-                                            $jc($jc(0, annotations.hashCode),
-                                                docs.hashCode),
-                                            optionalParameters.hashCode),
-                                        requiredParameters.hashCode),
-                                    initializers.hashCode),
-                                body.hashCode),
-                            external.hashCode),
-                        constant.hashCode),
-                    factory.hashCode),
-                lambda.hashCode),
-            name.hashCode),
-        redirect.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('Constructor')
-          ..add('annotations', annotations)
-          ..add('docs', docs)
-          ..add('optionalParameters', optionalParameters)
-          ..add('requiredParameters', requiredParameters)
-          ..add('initializers', initializers)
-          ..add('body', body)
-          ..add('external', external)
-          ..add('constant', constant)
-          ..add('factory', factory)
-          ..add('lambda', lambda)
-          ..add('name', name)
-          ..add('redirect', redirect))
-        .toString();
-  }
-}
-
-class _$ConstructorBuilder extends ConstructorBuilder {
-  _$Constructor _$v;
-
-  @override
-  ListBuilder<Expression> get annotations {
-    _$this;
-    return super.annotations ??= new ListBuilder<Expression>();
-  }
-
-  @override
-  set annotations(ListBuilder<Expression> annotations) {
-    _$this;
-    super.annotations = annotations;
-  }
-
-  @override
-  ListBuilder<String> get docs {
-    _$this;
-    return super.docs ??= new ListBuilder<String>();
-  }
-
-  @override
-  set docs(ListBuilder<String> docs) {
-    _$this;
-    super.docs = docs;
-  }
-
-  @override
-  ListBuilder<Parameter> get optionalParameters {
-    _$this;
-    return super.optionalParameters ??= new ListBuilder<Parameter>();
-  }
-
-  @override
-  set optionalParameters(ListBuilder<Parameter> optionalParameters) {
-    _$this;
-    super.optionalParameters = optionalParameters;
-  }
-
-  @override
-  ListBuilder<Parameter> get requiredParameters {
-    _$this;
-    return super.requiredParameters ??= new ListBuilder<Parameter>();
-  }
-
-  @override
-  set requiredParameters(ListBuilder<Parameter> requiredParameters) {
-    _$this;
-    super.requiredParameters = requiredParameters;
-  }
-
-  @override
-  ListBuilder<Code> get initializers {
-    _$this;
-    return super.initializers ??= new ListBuilder<Code>();
-  }
-
-  @override
-  set initializers(ListBuilder<Code> initializers) {
-    _$this;
-    super.initializers = initializers;
-  }
-
-  @override
-  Code get body {
-    _$this;
-    return super.body;
-  }
-
-  @override
-  set body(Code body) {
-    _$this;
-    super.body = body;
-  }
-
-  @override
-  bool get external {
-    _$this;
-    return super.external;
-  }
-
-  @override
-  set external(bool external) {
-    _$this;
-    super.external = external;
-  }
-
-  @override
-  bool get constant {
-    _$this;
-    return super.constant;
-  }
-
-  @override
-  set constant(bool constant) {
-    _$this;
-    super.constant = constant;
-  }
-
-  @override
-  bool get factory {
-    _$this;
-    return super.factory;
-  }
-
-  @override
-  set factory(bool factory) {
-    _$this;
-    super.factory = factory;
-  }
-
-  @override
-  bool get lambda {
-    _$this;
-    return super.lambda;
-  }
-
-  @override
-  set lambda(bool lambda) {
-    _$this;
-    super.lambda = lambda;
-  }
-
-  @override
-  String get name {
-    _$this;
-    return super.name;
-  }
-
-  @override
-  set name(String name) {
-    _$this;
-    super.name = name;
-  }
-
-  @override
-  Reference get redirect {
-    _$this;
-    return super.redirect;
-  }
-
-  @override
-  set redirect(Reference redirect) {
-    _$this;
-    super.redirect = redirect;
-  }
-
-  _$ConstructorBuilder() : super._();
-
-  ConstructorBuilder get _$this {
-    if (_$v != null) {
-      super.annotations = _$v.annotations?.toBuilder();
-      super.docs = _$v.docs?.toBuilder();
-      super.optionalParameters = _$v.optionalParameters?.toBuilder();
-      super.requiredParameters = _$v.requiredParameters?.toBuilder();
-      super.initializers = _$v.initializers?.toBuilder();
-      super.body = _$v.body;
-      super.external = _$v.external;
-      super.constant = _$v.constant;
-      super.factory = _$v.factory;
-      super.lambda = _$v.lambda;
-      super.name = _$v.name;
-      super.redirect = _$v.redirect;
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(Constructor other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$Constructor;
-  }
-
-  @override
-  void update(void updates(ConstructorBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$Constructor build() {
-    _$Constructor _$result;
-    try {
-      _$result = _$v ??
-          new _$Constructor._(
-              annotations: annotations.build(),
-              docs: docs.build(),
-              optionalParameters: optionalParameters.build(),
-              requiredParameters: requiredParameters.build(),
-              initializers: initializers.build(),
-              body: body,
-              external: external,
-              constant: constant,
-              factory: factory,
-              lambda: lambda,
-              name: name,
-              redirect: redirect);
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'annotations';
-        annotations.build();
-        _$failedField = 'docs';
-        docs.build();
-        _$failedField = 'optionalParameters';
-        optionalParameters.build();
-        _$failedField = 'requiredParameters';
-        requiredParameters.build();
-        _$failedField = 'initializers';
-        initializers.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'Constructor', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/specs/directive.dart b/code_builder/lib/src/specs/directive.dart
deleted file mode 100644
index 69e93ff..0000000
--- a/code_builder/lib/src/specs/directive.dart
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_value/built_value.dart';
-import 'package:collection/collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../visitors.dart';
-
-part 'directive.g.dart';
-
-@immutable
-abstract class Directive
-    implements Built<Directive, DirectiveBuilder>, Spec, Comparable<Directive> {
-  factory Directive([void updates(DirectiveBuilder b)]) = _$Directive;
-
-  factory Directive.import(
-    String url, {
-    String as,
-    List<String> show = const [],
-    List<String> hide = const [],
-  }) =>
-      Directive((builder) => builder
-        ..as = as
-        ..type = DirectiveType.import
-        ..url = url
-        ..show.addAll(show)
-        ..hide.addAll(hide));
-
-  factory Directive.importDeferredAs(
-    String url,
-    String as, {
-    List<String> show = const [],
-    List<String> hide = const [],
-  }) =>
-      Directive((builder) => builder
-        ..as = as
-        ..type = DirectiveType.import
-        ..url = url
-        ..deferred = true
-        ..show.addAll(show)
-        ..hide.addAll(hide));
-
-  factory Directive.export(
-    String url, {
-    List<String> show = const [],
-    List<String> hide = const [],
-  }) =>
-      Directive((builder) => builder
-        ..type = DirectiveType.export
-        ..url = url
-        ..show.addAll(show)
-        ..hide.addAll(hide));
-
-  Directive._();
-
-  @nullable
-  String get as;
-
-  String get url;
-
-  DirectiveType get type;
-
-  List<String> get show;
-
-  List<String> get hide;
-
-  bool get deferred;
-
-  @override
-  R accept<R>(
-    SpecVisitor<R> visitor, [
-    R context,
-  ]) =>
-      visitor.visitDirective(this, context);
-
-  @override
-  int compareTo(Directive other) => _compareDirectives(this, other);
-}
-
-abstract class DirectiveBuilder
-    implements Builder<Directive, DirectiveBuilder> {
-  factory DirectiveBuilder() = _$DirectiveBuilder;
-
-  DirectiveBuilder._();
-
-  bool deferred = false;
-
-  String as;
-
-  String url;
-
-  List<String> show = <String>[];
-
-  List<String> hide = <String>[];
-
-  DirectiveType type;
-}
-
-enum DirectiveType {
-  import,
-  export,
-}
-
-/// Sort import URIs represented by [a] and [b] to honor the
-/// "Effective Dart" ordering rules which are enforced by the
-/// `directives_ordering` lint.
-///
-/// 1. `import`s before `export`s
-/// 2. `dart:`
-/// 3. `package:`
-/// 4. relative
-int _compareDirectives(Directive a, Directive b) {
-  // NOTE: using the fact that `import` is before `export` in the
-  // `DirectiveType` enum – which allows us to compare using `indexOf`.
-  var value = DirectiveType.values
-      .indexOf(a.type)
-      .compareTo(DirectiveType.values.indexOf(b.type));
-
-  if (value == 0) {
-    final uriA = Uri.parse(a.url);
-    final uriB = Uri.parse(b.url);
-
-    if (uriA.hasScheme) {
-      if (uriB.hasScheme) {
-        // If both import URIs have schemes, compare them based on scheme
-        // `dart` will sort before `package` which is what we want
-        // schemes are case-insensitive, so compare accordingly
-        value = compareAsciiLowerCase(uriA.scheme, uriB.scheme);
-      } else {
-        value = -1;
-      }
-    } else if (uriB.hasScheme) {
-      value = 1;
-    }
-
-    // If both schemes are the same, compare based on path
-    if (value == 0) {
-      value = compareAsciiLowerCase(uriA.path, uriB.path);
-    }
-
-    assert((value == 0) == (a.url == b.url));
-  }
-
-  return value;
-}
diff --git a/code_builder/lib/src/specs/directive.g.dart b/code_builder/lib/src/specs/directive.g.dart
deleted file mode 100644
index a1717b2..0000000
--- a/code_builder/lib/src/specs/directive.g.dart
+++ /dev/null
@@ -1,203 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'directive.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Directive extends Directive {
-  @override
-  final String as;
-  @override
-  final String url;
-  @override
-  final DirectiveType type;
-  @override
-  final List<String> show;
-  @override
-  final List<String> hide;
-  @override
-  final bool deferred;
-
-  factory _$Directive([void updates(DirectiveBuilder b)]) =>
-      (new DirectiveBuilder()..update(updates)).build() as _$Directive;
-
-  _$Directive._(
-      {this.as, this.url, this.type, this.show, this.hide, this.deferred})
-      : super._() {
-    if (url == null) throw new BuiltValueNullFieldError('Directive', 'url');
-    if (type == null) throw new BuiltValueNullFieldError('Directive', 'type');
-    if (show == null) throw new BuiltValueNullFieldError('Directive', 'show');
-    if (hide == null) throw new BuiltValueNullFieldError('Directive', 'hide');
-    if (deferred == null)
-      throw new BuiltValueNullFieldError('Directive', 'deferred');
-  }
-
-  @override
-  Directive rebuild(void updates(DirectiveBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$DirectiveBuilder toBuilder() => new _$DirectiveBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! Directive) return false;
-    return as == other.as &&
-        url == other.url &&
-        type == other.type &&
-        show == other.show &&
-        hide == other.hide &&
-        deferred == other.deferred;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(
-        $jc(
-            $jc($jc($jc($jc(0, as.hashCode), url.hashCode), type.hashCode),
-                show.hashCode),
-            hide.hashCode),
-        deferred.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('Directive')
-          ..add('as', as)
-          ..add('url', url)
-          ..add('type', type)
-          ..add('show', show)
-          ..add('hide', hide)
-          ..add('deferred', deferred))
-        .toString();
-  }
-}
-
-class _$DirectiveBuilder extends DirectiveBuilder {
-  _$Directive _$v;
-
-  @override
-  String get as {
-    _$this;
-    return super.as;
-  }
-
-  @override
-  set as(String as) {
-    _$this;
-    super.as = as;
-  }
-
-  @override
-  String get url {
-    _$this;
-    return super.url;
-  }
-
-  @override
-  set url(String url) {
-    _$this;
-    super.url = url;
-  }
-
-  @override
-  DirectiveType get type {
-    _$this;
-    return super.type;
-  }
-
-  @override
-  set type(DirectiveType type) {
-    _$this;
-    super.type = type;
-  }
-
-  @override
-  List<String> get show {
-    _$this;
-    return super.show;
-  }
-
-  @override
-  set show(List<String> show) {
-    _$this;
-    super.show = show;
-  }
-
-  @override
-  List<String> get hide {
-    _$this;
-    return super.hide;
-  }
-
-  @override
-  set hide(List<String> hide) {
-    _$this;
-    super.hide = hide;
-  }
-
-  @override
-  bool get deferred {
-    _$this;
-    return super.deferred;
-  }
-
-  @override
-  set deferred(bool deferred) {
-    _$this;
-    super.deferred = deferred;
-  }
-
-  _$DirectiveBuilder() : super._();
-
-  DirectiveBuilder get _$this {
-    if (_$v != null) {
-      super.as = _$v.as;
-      super.url = _$v.url;
-      super.type = _$v.type;
-      super.show = _$v.show;
-      super.hide = _$v.hide;
-      super.deferred = _$v.deferred;
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(Directive other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$Directive;
-  }
-
-  @override
-  void update(void updates(DirectiveBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$Directive build() {
-    final _$result = _$v ??
-        new _$Directive._(
-            as: as,
-            url: url,
-            type: type,
-            show: show,
-            hide: hide,
-            deferred: deferred);
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/specs/expression.dart b/code_builder/lib/src/specs/expression.dart
deleted file mode 100644
index cbbf6d4..0000000
--- a/code_builder/lib/src/specs/expression.dart
+++ /dev/null
@@ -1,573 +0,0 @@
-// 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.
-
-library code_builder.src.specs.expression;
-
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../emitter.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'method.dart';
-import 'reference.dart';
-import 'type_function.dart';
-
-part 'expression/binary.dart';
-part 'expression/closure.dart';
-part 'expression/code.dart';
-part 'expression/invoke.dart';
-part 'expression/literal.dart';
-
-/// Represents a [code] block that wraps an [Expression].
-
-/// Represents a Dart expression.
-///
-/// See various concrete implementations for details.
-abstract class Expression implements Spec {
-  const Expression();
-
-  /// An empty expression.
-  static const _empty = CodeExpression(Code(''));
-
-  @override
-  R accept<R>(covariant ExpressionVisitor<R> visitor, [R context]);
-
-  /// The expression as a valid [Code] block.
-  ///
-  /// Also see [statement].
-  Code get code => ToCodeExpression(this, false);
-
-  /// The expression as a valid [Code] block with a trailing `;`.
-  Code get statement => ToCodeExpression(this, true);
-
-  /// Returns the result of `this` `&&` [other].
-  Expression and(Expression other) {
-    return BinaryExpression._(expression, other, '&&');
-  }
-
-  /// Returns the result of `this` `||` [other].
-  Expression or(Expression other) {
-    return BinaryExpression._(expression, other, '||');
-  }
-
-  /// Returns the result of `!this`.
-  Expression negate() {
-    return BinaryExpression._(_empty, expression, '!', addSpace: false);
-  }
-
-  /// Returns the result of `this` `as` [other].
-  Expression asA(Expression other) {
-    return CodeExpression(Block.of([
-      const Code('('),
-      BinaryExpression._(
-        expression,
-        other,
-        'as',
-      ).code,
-      const Code(')')
-    ]));
-  }
-
-  /// Returns accessing the index operator (`[]`) on `this`.
-  Expression index(Expression index) {
-    return BinaryExpression._(
-      expression,
-      CodeExpression(Block.of([
-        const Code('['),
-        index.code,
-        const Code(']'),
-      ])),
-      '',
-    );
-  }
-
-  /// Returns the result of `this` `is` [other].
-  Expression isA(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      'is',
-    );
-  }
-
-  /// Returns the result of `this` `is!` [other].
-  Expression isNotA(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      'is!',
-    );
-  }
-
-  /// Returns the result of `this` `==` [other].
-  Expression equalTo(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '==',
-    );
-  }
-
-  /// Returns the result of `this` `!=` [other].
-  Expression notEqualTo(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '!=',
-    );
-  }
-
-  /// Returns the result of `this` `>` [other].
-  Expression greaterThan(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '>',
-    );
-  }
-
-  /// Returns the result of `this` `<` [other].
-  Expression lessThan(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '<',
-    );
-  }
-
-  /// Returns the result of `this` `>=` [other].
-  Expression greaterOrEqualTo(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '>=',
-    );
-  }
-
-  /// Returns the result of `this` `<=` [other].
-  Expression lessOrEqualTo(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '<=',
-    );
-  }
-
-  /// Returns the result of `this` `+` [other].
-  Expression operatorAdd(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '+',
-    );
-  }
-
-  /// Returns the result of `this` `-` [other].
-  Expression operatorSubstract(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '-',
-    );
-  }
-
-  /// Returns the result of `this` `/` [other].
-  Expression operatorDivide(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '/',
-    );
-  }
-
-  /// Returns the result of `this` `*` [other].
-  Expression operatorMultiply(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '*',
-    );
-  }
-
-  /// Returns the result of `this` `%` [other].
-  Expression operatorEuclideanModulo(Expression other) {
-    return BinaryExpression._(
-      expression,
-      other,
-      '%',
-    );
-  }
-
-  Expression conditional(Expression whenTrue, Expression whenFalse) {
-    return BinaryExpression._(
-      expression,
-      BinaryExpression._(whenTrue, whenFalse, ':'),
-      '?',
-    );
-  }
-
-  /// This expression preceded by `await`.
-  Expression get awaited {
-    return BinaryExpression._(
-      _empty,
-      this,
-      'await',
-    );
-  }
-
-  /// Return `{other} = {this}`.
-  Expression assign(Expression other) {
-    return BinaryExpression._(
-      this,
-      other,
-      '=',
-    );
-  }
-
-  /// Return `{other} ??= {this}`.
-  Expression assignNullAware(Expression other) {
-    return BinaryExpression._(
-      this,
-      other,
-      '??=',
-    );
-  }
-
-  /// Return `var {name} = {this}`.
-  Expression assignVar(String name, [Reference type]) {
-    return BinaryExpression._(
-      type == null
-          ? LiteralExpression._('var $name')
-          : BinaryExpression._(
-              type.expression,
-              LiteralExpression._(name),
-              '',
-            ),
-      this,
-      '=',
-    );
-  }
-
-  /// Return `final {name} = {this}`.
-  Expression assignFinal(String name, [Reference type]) {
-    return BinaryExpression._(
-      type == null
-          ? const LiteralExpression._('final')
-          : BinaryExpression._(
-              const LiteralExpression._('final'),
-              type.expression,
-              '',
-            ),
-      this,
-      '$name =',
-    );
-  }
-
-  /// Return `const {name} = {this}`.
-  Expression assignConst(String name, [Reference type]) {
-    return BinaryExpression._(
-      type == null
-          ? const LiteralExpression._('const')
-          : BinaryExpression._(
-              const LiteralExpression._('const'),
-              type.expression,
-              '',
-            ),
-      this,
-      '$name =',
-      isConst: true,
-    );
-  }
-
-  /// Call this expression as a method.
-  Expression call(
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression._(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-    );
-  }
-
-  /// Returns an expression accessing `.<name>` on this expression.
-  Expression property(String name) {
-    return BinaryExpression._(
-      this,
-      LiteralExpression._(name),
-      '.',
-      addSpace: false,
-    );
-  }
-
-  /// Returns an expression accessing `?.<name>` on this expression.
-  Expression nullSafeProperty(String name) {
-    return BinaryExpression._(
-      this,
-      LiteralExpression._(name),
-      '?.',
-      addSpace: false,
-    );
-  }
-
-  /// This expression preceded by `return`.
-  Expression get returned {
-    return BinaryExpression._(
-      const LiteralExpression._('return'),
-      this,
-      '',
-    );
-  }
-
-  /// May be overridden to support other types implementing [Expression].
-  @visibleForOverriding
-  Expression get expression => this;
-}
-
-/// Creates `typedef {name} =`.
-Code createTypeDef(String name, FunctionType type) => BinaryExpression._(
-        LiteralExpression._('typedef $name'), type.expression, '=')
-    .statement;
-
-class ToCodeExpression implements Code {
-  final Expression code;
-
-  /// Whether this code should be considered a _statement_.
-  final bool isStatement;
-
-  @visibleForTesting
-  const ToCodeExpression(this.code, [this.isStatement = false]);
-
-  @override
-  R accept<R>(CodeVisitor<R> visitor, [R context]) {
-    return (visitor as ExpressionVisitor<R>)
-        .visitToCodeExpression(this, context);
-  }
-
-  @override
-  String toString() => code.toString();
-}
-
-/// Knowledge of different types of expressions in Dart.
-///
-/// **INTERNAL ONLY**.
-abstract class ExpressionVisitor<T> implements SpecVisitor<T> {
-  T visitToCodeExpression(ToCodeExpression code, [T context]);
-  T visitBinaryExpression(BinaryExpression expression, [T context]);
-  T visitClosureExpression(ClosureExpression expression, [T context]);
-  T visitCodeExpression(CodeExpression expression, [T context]);
-  T visitInvokeExpression(InvokeExpression expression, [T context]);
-  T visitLiteralExpression(LiteralExpression expression, [T context]);
-  T visitLiteralListExpression(LiteralListExpression expression, [T context]);
-  T visitLiteralSetExpression(LiteralSetExpression expression, [T context]);
-  T visitLiteralMapExpression(LiteralMapExpression expression, [T context]);
-}
-
-/// Knowledge of how to write valid Dart code from [ExpressionVisitor].
-///
-/// **INTERNAL ONLY**.
-abstract class ExpressionEmitter implements ExpressionVisitor<StringSink> {
-  @override
-  visitToCodeExpression(ToCodeExpression expression, [StringSink output]) {
-    output ??= StringBuffer();
-    expression.code.accept(this, output);
-    if (expression.isStatement) {
-      output.write(';');
-    }
-    return output;
-  }
-
-  @override
-  visitBinaryExpression(BinaryExpression expression, [StringSink output]) {
-    output ??= StringBuffer();
-    expression.left.accept(this, output);
-    if (expression.addSpace) {
-      output.write(' ');
-    }
-    output.write(expression.operator);
-    if (expression.addSpace) {
-      output.write(' ');
-    }
-    startConstCode(expression.isConst, () {
-      expression.right.accept(this, output);
-    });
-    return output;
-  }
-
-  @override
-  visitClosureExpression(ClosureExpression expression, [StringSink output]) {
-    output ??= StringBuffer();
-    return expression.method.accept(this, output);
-  }
-
-  @override
-  visitCodeExpression(CodeExpression expression, [StringSink output]) {
-    output ??= StringBuffer();
-    final visitor = this as CodeVisitor<StringSink>;
-    return expression.code.accept(visitor, output);
-  }
-
-  @override
-  visitInvokeExpression(InvokeExpression expression, [StringSink output]) {
-    output ??= StringBuffer();
-    return _writeConstExpression(
-        output, expression.type == InvokeExpressionType.constInstance, () {
-      expression.target.accept(this, output);
-      if (expression.name != null) {
-        output..write('.')..write(expression.name);
-      }
-      if (expression.typeArguments.isNotEmpty) {
-        output.write('<');
-        visitAll<Reference>(expression.typeArguments, output, (type) {
-          type.accept(this, output);
-        });
-        output.write('>');
-      }
-      output.write('(');
-      visitAll<Spec>(expression.positionalArguments, output, (spec) {
-        spec.accept(this, output);
-      });
-      if (expression.positionalArguments.isNotEmpty &&
-          expression.namedArguments.isNotEmpty) {
-        output.write(', ');
-      }
-      visitAll<String>(expression.namedArguments.keys, output, (name) {
-        output..write(name)..write(': ');
-        expression.namedArguments[name].accept(this, output);
-      });
-      return output..write(')');
-    });
-  }
-
-  @override
-  visitLiteralExpression(LiteralExpression expression, [StringSink output]) {
-    output ??= StringBuffer();
-    return output..write(expression.literal);
-  }
-
-  void _acceptLiteral(Object literalOrSpec, StringSink output) {
-    if (literalOrSpec is Spec) {
-      literalOrSpec.accept(this, output);
-      return;
-    }
-    literal(literalOrSpec).accept(this, output);
-  }
-
-  bool _withInConstExpression = false;
-
-  @override
-  visitLiteralListExpression(
-    LiteralListExpression expression, [
-    StringSink output,
-  ]) {
-    output ??= StringBuffer();
-
-    return _writeConstExpression(output, expression.isConst, () {
-      if (expression.type != null) {
-        output.write('<');
-        expression.type.accept(this, output);
-        output.write('>');
-      }
-      output.write('[');
-      visitAll<Object>(expression.values, output, (value) {
-        _acceptLiteral(value, output);
-      });
-      return output..write(']');
-    });
-  }
-
-  @override
-  visitLiteralSetExpression(
-    LiteralSetExpression expression, [
-    StringSink output,
-  ]) {
-    output ??= StringBuffer();
-
-    return _writeConstExpression(output, expression.isConst, () {
-      if (expression.type != null) {
-        output.write('<');
-        expression.type.accept(this, output);
-        output.write('>');
-      }
-      output.write('{');
-      visitAll<Object>(expression.values, output, (value) {
-        _acceptLiteral(value, output);
-      });
-      return output..write('}');
-    });
-  }
-
-  @override
-  visitLiteralMapExpression(
-    LiteralMapExpression expression, [
-    StringSink output,
-  ]) {
-    output ??= StringBuffer();
-    return _writeConstExpression(output, expression.isConst, () {
-      if (expression.keyType != null) {
-        output.write('<');
-        expression.keyType.accept(this, output);
-        output.write(', ');
-        if (expression.valueType == null) {
-          const Reference('dynamic', 'dart:core').accept(this, output);
-        } else {
-          expression.valueType.accept(this, output);
-        }
-        output.write('>');
-      }
-      output.write('{');
-      visitAll<Object>(expression.values.keys, output, (key) {
-        final value = expression.values[key];
-        _acceptLiteral(key, output);
-        output.write(': ');
-        _acceptLiteral(value, output);
-      });
-      return output..write('}');
-    });
-  }
-
-  /// Executes [visit] within a context which may alter the output if [isConst]
-  /// is `true`.
-  ///
-  /// This allows constant expressions to omit the `const` keyword if they
-  /// are already within a constant expression.
-  void startConstCode(
-    bool isConst,
-    Null Function() visit,
-  ) {
-    final previousConstContext = _withInConstExpression;
-    if (isConst) {
-      _withInConstExpression = true;
-    }
-
-    visit();
-    _withInConstExpression = previousConstContext;
-  }
-
-  /// Similar to [startConstCode], but handles writing `"const "` if [isConst]
-  /// is `true` and the invocation is not nested under other invocations where
-  /// [isConst] is true.
-  StringSink _writeConstExpression(
-    StringSink sink,
-    bool isConst,
-    StringSink Function() visitExpression,
-  ) {
-    final previousConstContext = _withInConstExpression;
-    if (isConst) {
-      if (!_withInConstExpression) {
-        sink.write('const ');
-      }
-      _withInConstExpression = true;
-    }
-
-    final returnedSink = visitExpression();
-    assert(identical(returnedSink, sink));
-    _withInConstExpression = previousConstContext;
-    return sink;
-  }
-}
diff --git a/code_builder/lib/src/specs/expression/binary.dart b/code_builder/lib/src/specs/expression/binary.dart
deleted file mode 100644
index 1f7e76e..0000000
--- a/code_builder/lib/src/specs/expression/binary.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.
-
-part of code_builder.src.specs.expression;
-
-/// Represents two expressions ([left] and [right]) and an [operator].
-class BinaryExpression extends Expression {
-  final Expression left;
-  final Expression right;
-  final String operator;
-  final bool addSpace;
-  final bool isConst;
-
-  const BinaryExpression._(
-    this.left,
-    this.right,
-    this.operator, {
-    this.addSpace = true,
-    this.isConst = false,
-  });
-
-  @override
-  R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
-    return visitor.visitBinaryExpression(this, context);
-  }
-}
diff --git a/code_builder/lib/src/specs/expression/closure.dart b/code_builder/lib/src/specs/expression/closure.dart
deleted file mode 100644
index 1af2760..0000000
--- a/code_builder/lib/src/specs/expression/closure.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.
-
-part of code_builder.src.specs.expression;
-
-Expression toClosure(Method method) {
-  final withoutTypes = method.rebuild((b) {
-    b.returns = null;
-    b.types.clear();
-  });
-  return ClosureExpression._(withoutTypes);
-}
-
-class ClosureExpression extends Expression {
-  final Method method;
-
-  const ClosureExpression._(this.method);
-
-  @override
-  R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
-    return visitor.visitClosureExpression(this, context);
-  }
-}
diff --git a/code_builder/lib/src/specs/expression/code.dart b/code_builder/lib/src/specs/expression/code.dart
deleted file mode 100644
index 7465448..0000000
--- a/code_builder/lib/src/specs/expression/code.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.
-
-part of code_builder.src.specs.expression;
-
-/// Represents a [Code] block as an [Expression].
-class CodeExpression extends Expression {
-  @override
-  final Code code;
-
-  /// **INTERNAL ONLY**: Used to wrap [Code] as an [Expression].
-  const CodeExpression(this.code);
-
-  @override
-  R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
-    return visitor.visitCodeExpression(this, context);
-  }
-}
diff --git a/code_builder/lib/src/specs/expression/invoke.dart b/code_builder/lib/src/specs/expression/invoke.dart
deleted file mode 100644
index 3ac586f..0000000
--- a/code_builder/lib/src/specs/expression/invoke.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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.
-
-part of code_builder.src.specs.expression;
-
-/// Represents invoking [target] as a method with arguments.
-class InvokeExpression extends Expression {
-  /// Target of the method invocation.
-  final Expression target;
-
-  /// Optional; type of invocation.
-  final InvokeExpressionType type;
-
-  final List<Expression> positionalArguments;
-  final Map<String, Expression> namedArguments;
-  final List<Reference> typeArguments;
-  final String name;
-
-  const InvokeExpression._(
-    this.target,
-    this.positionalArguments, [
-    this.namedArguments = const {},
-    this.typeArguments,
-    this.name,
-  ]) : type = null;
-
-  const InvokeExpression.newOf(
-    this.target,
-    this.positionalArguments, [
-    this.namedArguments = const {},
-    this.typeArguments,
-    this.name,
-  ]) : type = InvokeExpressionType.newInstance;
-
-  const InvokeExpression.constOf(
-    this.target,
-    this.positionalArguments, [
-    this.namedArguments = const {},
-    this.typeArguments,
-    this.name,
-  ]) : type = InvokeExpressionType.constInstance;
-
-  @override
-  R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
-    return visitor.visitInvokeExpression(this, context);
-  }
-
-  @override
-  String toString() =>
-      '${type ?? ''} $target($positionalArguments, $namedArguments)';
-}
-
-enum InvokeExpressionType {
-  newInstance,
-  constInstance,
-}
diff --git a/code_builder/lib/src/specs/expression/literal.dart b/code_builder/lib/src/specs/expression/literal.dart
deleted file mode 100644
index 3021fa1..0000000
--- a/code_builder/lib/src/specs/expression/literal.dart
+++ /dev/null
@@ -1,182 +0,0 @@
-// 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.
-
-part of code_builder.src.specs.expression;
-
-/// Converts a runtime Dart [literal] value into an [Expression].
-///
-/// Unsupported inputs invoke the [onError] callback.
-Expression literal(Object literal, {Expression onError(Object value)}) {
-  if (literal is bool) {
-    return literalBool(literal);
-  }
-  if (literal is num) {
-    return literalNum(literal);
-  }
-  if (literal is String) {
-    return literalString(literal);
-  }
-  if (literal is List) {
-    return literalList(literal);
-  }
-  if (literal is Set) {
-    return literalSet(literal);
-  }
-  if (literal is Map) {
-    return literalMap(literal);
-  }
-  if (literal == null) {
-    return literalNull;
-  }
-  if (onError != null) {
-    return onError(literal);
-  }
-  throw UnsupportedError('Not a supported literal type: $literal.');
-}
-
-/// Represents the literal value `true`.
-const Expression literalTrue = LiteralExpression._('true');
-
-/// Represents the literal value `false`.
-const Expression literalFalse = LiteralExpression._('false');
-
-/// Create a literal expression from a boolean [value].
-Expression literalBool(bool value) => value ? literalTrue : literalFalse;
-
-/// Represents the literal value `null`.
-const Expression literalNull = LiteralExpression._('null');
-
-/// Create a literal expression from a number [value].
-Expression literalNum(num value) => LiteralExpression._('$value');
-
-/// Create a literal expression from a string [value].
-///
-/// **NOTE**: The string is always formatted `'<value>'`.
-///
-/// If [raw] is `true`, creates a raw String formatted `r'<value>'` and the
-/// value may not contain a single quote.
-/// Escapes single quotes and newlines in the value.
-Expression literalString(String value, {bool raw = false}) {
-  if (raw && value.contains('\'')) {
-    throw ArgumentError('Cannot include a single quote in a raw string');
-  }
-  final escaped = value.replaceAll('\'', '\\\'').replaceAll('\n', '\\n');
-  return LiteralExpression._("${raw ? 'r' : ''}'$escaped'");
-}
-
-/// Creates a literal list expression from [values].
-LiteralListExpression literalList(Iterable<Object> values, [Reference type]) {
-  return LiteralListExpression._(false, values.toList(), type);
-}
-
-/// Creates a literal `const` list expression from [values].
-LiteralListExpression literalConstList(List<Object> values, [Reference type]) {
-  return LiteralListExpression._(true, values, type);
-}
-
-/// Creates a literal set expression from [values].
-LiteralSetExpression literalSet(Iterable<Object> values, [Reference type]) {
-  return LiteralSetExpression._(false, values.toSet(), type);
-}
-
-/// Creates a literal `const` set expression from [values].
-LiteralSetExpression literalConstSet(Set<Object> values, [Reference type]) {
-  return LiteralSetExpression._(true, values, type);
-}
-
-/// Create a literal map expression from [values].
-LiteralMapExpression literalMap(
-  Map<Object, Object> values, [
-  Reference keyType,
-  Reference valueType,
-]) {
-  return LiteralMapExpression._(false, values, keyType, valueType);
-}
-
-/// Create a literal `const` map expression from [values].
-LiteralMapExpression literalConstMap(
-  Map<Object, Object> values, [
-  Reference keyType,
-  Reference valueType,
-]) {
-  return LiteralMapExpression._(true, values, keyType, valueType);
-}
-
-/// Represents a literal value in Dart source code.
-///
-/// For example, `LiteralExpression('null')` should emit `null`.
-///
-/// Some common literals and helpers are available as methods/fields:
-/// * [literal]
-/// * [literalBool] and [literalTrue], [literalFalse]
-/// * [literalNull]
-/// * [literalList] and [literalConstList]
-/// * [literalSet] and [literalConstSet]
-class LiteralExpression extends Expression {
-  final String literal;
-
-  const LiteralExpression._(this.literal);
-
-  @override
-  R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
-    return visitor.visitLiteralExpression(this, context);
-  }
-
-  @override
-  String toString() => literal;
-}
-
-class LiteralListExpression extends Expression {
-  final bool isConst;
-  final List<Object> values;
-  final Reference type;
-
-  const LiteralListExpression._(this.isConst, this.values, this.type);
-
-  @override
-  R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
-    return visitor.visitLiteralListExpression(this, context);
-  }
-
-  @override
-  String toString() => '[${values.map(literal).join(', ')}]';
-}
-
-class LiteralSetExpression extends Expression {
-  final bool isConst;
-  final Set<Object> values;
-  final Reference type;
-
-  const LiteralSetExpression._(this.isConst, this.values, this.type);
-
-  @override
-  R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
-    return visitor.visitLiteralSetExpression(this, context);
-  }
-
-  @override
-  String toString() => '{${values.map(literal).join(', ')}}';
-}
-
-class LiteralMapExpression extends Expression {
-  final bool isConst;
-  final Map<Object, Object> values;
-  final Reference keyType;
-  final Reference valueType;
-
-  const LiteralMapExpression._(
-    this.isConst,
-    this.values,
-    this.keyType,
-    this.valueType,
-  );
-
-  @override
-  R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
-    return visitor.visitLiteralMapExpression(this, context);
-  }
-
-  @override
-  String toString() => '{$values}';
-}
diff --git a/code_builder/lib/src/specs/field.dart b/code_builder/lib/src/specs/field.dart
deleted file mode 100644
index 81c5640..0000000
--- a/code_builder/lib/src/specs/field.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_collection/built_collection.dart';
-import 'package:built_value/built_value.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/annotations.dart';
-import '../mixins/dartdoc.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'reference.dart';
-
-part 'field.g.dart';
-
-@immutable
-abstract class Field extends Object
-    with HasAnnotations, HasDartDocs
-    implements Built<Field, FieldBuilder>, Spec {
-  factory Field([void updates(FieldBuilder b)]) = _$Field;
-
-  Field._();
-
-  @override
-  BuiltList<Expression> get annotations;
-
-  @override
-  BuiltList<String> get docs;
-
-  /// Field assignment, if any.
-  @nullable
-  Code get assignment;
-
-  /// Whether this field should be prefixed with `static`.
-  ///
-  /// This is only valid within classes.
-  bool get static;
-
-  /// Name of the field.
-  String get name;
-
-  @nullable
-  Reference get type;
-
-  FieldModifier get modifier;
-
-  @override
-  R accept<R>(
-    SpecVisitor<R> visitor, [
-    R context,
-  ]) =>
-      visitor.visitField(this, context);
-}
-
-enum FieldModifier {
-  var$,
-  final$,
-  constant,
-}
-
-abstract class FieldBuilder extends Object
-    with HasAnnotationsBuilder, HasDartDocsBuilder
-    implements Builder<Field, FieldBuilder> {
-  factory FieldBuilder() = _$FieldBuilder;
-
-  FieldBuilder._();
-
-  @override
-  ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
-  @override
-  ListBuilder<String> docs = ListBuilder<String>();
-
-  /// Field assignment, if any.
-  Code assignment;
-
-  /// Whether this field should be prefixed with `static`.
-  ///
-  /// This is only valid within classes.
-  bool static = false;
-
-  /// Name of the field.
-  String name;
-
-  Reference type;
-
-  FieldModifier modifier = FieldModifier.var$;
-}
diff --git a/code_builder/lib/src/specs/field.g.dart b/code_builder/lib/src/specs/field.g.dart
deleted file mode 100644
index 3bef453..0000000
--- a/code_builder/lib/src/specs/field.g.dart
+++ /dev/null
@@ -1,247 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'field.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Field extends Field {
-  @override
-  final BuiltList<Expression> annotations;
-  @override
-  final BuiltList<String> docs;
-  @override
-  final Code assignment;
-  @override
-  final bool static;
-  @override
-  final String name;
-  @override
-  final Reference type;
-  @override
-  final FieldModifier modifier;
-
-  factory _$Field([void updates(FieldBuilder b)]) =>
-      (new FieldBuilder()..update(updates)).build() as _$Field;
-
-  _$Field._(
-      {this.annotations,
-      this.docs,
-      this.assignment,
-      this.static,
-      this.name,
-      this.type,
-      this.modifier})
-      : super._() {
-    if (annotations == null)
-      throw new BuiltValueNullFieldError('Field', 'annotations');
-    if (docs == null) throw new BuiltValueNullFieldError('Field', 'docs');
-    if (static == null) throw new BuiltValueNullFieldError('Field', 'static');
-    if (name == null) throw new BuiltValueNullFieldError('Field', 'name');
-    if (modifier == null)
-      throw new BuiltValueNullFieldError('Field', 'modifier');
-  }
-
-  @override
-  Field rebuild(void updates(FieldBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$FieldBuilder toBuilder() => new _$FieldBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! Field) return false;
-    return annotations == other.annotations &&
-        docs == other.docs &&
-        assignment == other.assignment &&
-        static == other.static &&
-        name == other.name &&
-        type == other.type &&
-        modifier == other.modifier;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(
-        $jc(
-            $jc(
-                $jc(
-                    $jc($jc($jc(0, annotations.hashCode), docs.hashCode),
-                        assignment.hashCode),
-                    static.hashCode),
-                name.hashCode),
-            type.hashCode),
-        modifier.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('Field')
-          ..add('annotations', annotations)
-          ..add('docs', docs)
-          ..add('assignment', assignment)
-          ..add('static', static)
-          ..add('name', name)
-          ..add('type', type)
-          ..add('modifier', modifier))
-        .toString();
-  }
-}
-
-class _$FieldBuilder extends FieldBuilder {
-  _$Field _$v;
-
-  @override
-  ListBuilder<Expression> get annotations {
-    _$this;
-    return super.annotations ??= new ListBuilder<Expression>();
-  }
-
-  @override
-  set annotations(ListBuilder<Expression> annotations) {
-    _$this;
-    super.annotations = annotations;
-  }
-
-  @override
-  ListBuilder<String> get docs {
-    _$this;
-    return super.docs ??= new ListBuilder<String>();
-  }
-
-  @override
-  set docs(ListBuilder<String> docs) {
-    _$this;
-    super.docs = docs;
-  }
-
-  @override
-  Code get assignment {
-    _$this;
-    return super.assignment;
-  }
-
-  @override
-  set assignment(Code assignment) {
-    _$this;
-    super.assignment = assignment;
-  }
-
-  @override
-  bool get static {
-    _$this;
-    return super.static;
-  }
-
-  @override
-  set static(bool static) {
-    _$this;
-    super.static = static;
-  }
-
-  @override
-  String get name {
-    _$this;
-    return super.name;
-  }
-
-  @override
-  set name(String name) {
-    _$this;
-    super.name = name;
-  }
-
-  @override
-  Reference get type {
-    _$this;
-    return super.type;
-  }
-
-  @override
-  set type(Reference type) {
-    _$this;
-    super.type = type;
-  }
-
-  @override
-  FieldModifier get modifier {
-    _$this;
-    return super.modifier;
-  }
-
-  @override
-  set modifier(FieldModifier modifier) {
-    _$this;
-    super.modifier = modifier;
-  }
-
-  _$FieldBuilder() : super._();
-
-  FieldBuilder get _$this {
-    if (_$v != null) {
-      super.annotations = _$v.annotations?.toBuilder();
-      super.docs = _$v.docs?.toBuilder();
-      super.assignment = _$v.assignment;
-      super.static = _$v.static;
-      super.name = _$v.name;
-      super.type = _$v.type;
-      super.modifier = _$v.modifier;
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(Field other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$Field;
-  }
-
-  @override
-  void update(void updates(FieldBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$Field build() {
-    _$Field _$result;
-    try {
-      _$result = _$v ??
-          new _$Field._(
-              annotations: annotations.build(),
-              docs: docs.build(),
-              assignment: assignment,
-              static: static,
-              name: name,
-              type: type,
-              modifier: modifier);
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'annotations';
-        annotations.build();
-        _$failedField = 'docs';
-        docs.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'Field', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/specs/library.dart b/code_builder/lib/src/specs/library.dart
deleted file mode 100644
index f476828..0000000
--- a/code_builder/lib/src/specs/library.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_collection/built_collection.dart';
-import 'package:built_value/built_value.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../visitors.dart';
-import 'directive.dart';
-
-part 'library.g.dart';
-
-@immutable
-abstract class Library implements Built<Library, LibraryBuilder>, Spec {
-  factory Library([void updates(LibraryBuilder b)]) = _$Library;
-  Library._();
-
-  BuiltList<Directive> get directives;
-  BuiltList<Spec> get body;
-
-  @override
-  R accept<R>(
-    SpecVisitor<R> visitor, [
-    R context,
-  ]) =>
-      visitor.visitLibrary(this, context);
-}
-
-abstract class LibraryBuilder implements Builder<Library, LibraryBuilder> {
-  factory LibraryBuilder() = _$LibraryBuilder;
-  LibraryBuilder._();
-
-  ListBuilder<Spec> body = ListBuilder<Spec>();
-  ListBuilder<Directive> directives = ListBuilder<Directive>();
-}
diff --git a/code_builder/lib/src/specs/library.g.dart b/code_builder/lib/src/specs/library.g.dart
deleted file mode 100644
index 9935040..0000000
--- a/code_builder/lib/src/specs/library.g.dart
+++ /dev/null
@@ -1,133 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'library.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Library extends Library {
-  @override
-  final BuiltList<Directive> directives;
-  @override
-  final BuiltList<Spec> body;
-
-  factory _$Library([void updates(LibraryBuilder b)]) =>
-      (new LibraryBuilder()..update(updates)).build() as _$Library;
-
-  _$Library._({this.directives, this.body}) : super._() {
-    if (directives == null)
-      throw new BuiltValueNullFieldError('Library', 'directives');
-    if (body == null) throw new BuiltValueNullFieldError('Library', 'body');
-  }
-
-  @override
-  Library rebuild(void updates(LibraryBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$LibraryBuilder toBuilder() => new _$LibraryBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! Library) return false;
-    return directives == other.directives && body == other.body;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc($jc(0, directives.hashCode), body.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('Library')
-          ..add('directives', directives)
-          ..add('body', body))
-        .toString();
-  }
-}
-
-class _$LibraryBuilder extends LibraryBuilder {
-  _$Library _$v;
-
-  @override
-  ListBuilder<Directive> get directives {
-    _$this;
-    return super.directives ??= new ListBuilder<Directive>();
-  }
-
-  @override
-  set directives(ListBuilder<Directive> directives) {
-    _$this;
-    super.directives = directives;
-  }
-
-  @override
-  ListBuilder<Spec> get body {
-    _$this;
-    return super.body ??= new ListBuilder<Spec>();
-  }
-
-  @override
-  set body(ListBuilder<Spec> body) {
-    _$this;
-    super.body = body;
-  }
-
-  _$LibraryBuilder() : super._();
-
-  LibraryBuilder get _$this {
-    if (_$v != null) {
-      super.directives = _$v.directives?.toBuilder();
-      super.body = _$v.body?.toBuilder();
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(Library other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$Library;
-  }
-
-  @override
-  void update(void updates(LibraryBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$Library build() {
-    _$Library _$result;
-    try {
-      _$result = _$v ??
-          new _$Library._(directives: directives.build(), body: body.build());
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'directives';
-        directives.build();
-        _$failedField = 'body';
-        body.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'Library', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/specs/method.dart b/code_builder/lib/src/specs/method.dart
deleted file mode 100644
index 5fecfe3..0000000
--- a/code_builder/lib/src/specs/method.dart
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/annotations.dart';
-import '../mixins/dartdoc.dart';
-import '../mixins/generics.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'reference.dart';
-
-part 'method.g.dart';
-
-final Reference _$void = const Reference('void');
-
-@immutable
-abstract class Method extends Object
-    with HasAnnotations, HasGenerics, HasDartDocs
-    implements Built<Method, MethodBuilder>, Spec {
-  factory Method([void updates(MethodBuilder b)]) = _$Method;
-
-  factory Method.returnsVoid([void updates(MethodBuilder b)]) {
-    return Method((b) {
-      if (updates != null) {
-        updates(b);
-      }
-      b.returns = _$void;
-    });
-  }
-
-  Method._();
-
-  @override
-  BuiltList<Expression> get annotations;
-
-  @override
-  BuiltList<String> get docs;
-
-  @override
-  BuiltList<Reference> get types;
-
-  /// Optional parameters.
-  BuiltList<Parameter> get optionalParameters;
-
-  /// Required parameters.
-  BuiltList<Parameter> get requiredParameters;
-
-  /// Body of the method.
-  @nullable
-  Code get body;
-
-  /// Whether the method should be prefixed with `external`.
-  bool get external;
-
-  /// Whether this method is a simple lambda expression.
-  ///
-  /// May be `null` to be inferred based on the value of [body].
-  @nullable
-  bool get lambda;
-
-  /// Whether this method should be prefixed with `static`.
-  ///
-  /// This is only valid within classes.
-  bool get static;
-
-  /// Name of the method or function.
-  ///
-  /// May be `null` when being used as a [closure].
-  @nullable
-  String get name;
-
-  /// Whether this is a getter or setter.
-  @nullable
-  MethodType get type;
-
-  /// Whether this method is `async`, `async*`, or `sync*`.
-  @nullable
-  MethodModifier get modifier;
-
-  @nullable
-  Reference get returns;
-
-  @override
-  R accept<R>(
-    SpecVisitor<R> visitor, [
-    R context,
-  ]) =>
-      visitor.visitMethod(this, context);
-
-  /// This method as a closure.
-  Expression get closure => toClosure(this);
-}
-
-abstract class MethodBuilder extends Object
-    with HasAnnotationsBuilder, HasGenericsBuilder, HasDartDocsBuilder
-    implements Builder<Method, MethodBuilder> {
-  factory MethodBuilder() = _$MethodBuilder;
-
-  MethodBuilder._();
-
-  @override
-  ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
-  @override
-  ListBuilder<String> docs = ListBuilder<String>();
-
-  @override
-  ListBuilder<Reference> types = ListBuilder<Reference>();
-
-  /// Optional parameters.
-  ListBuilder<Parameter> optionalParameters = ListBuilder<Parameter>();
-
-  /// Required parameters.
-  ListBuilder<Parameter> requiredParameters = ListBuilder<Parameter>();
-
-  /// Body of the method.
-  Code body;
-
-  /// Whether the method should be prefixed with `external`.
-  bool external = false;
-
-  /// Whether this method is a simple lambda expression.
-  ///
-  /// If not specified this is inferred from the [body].
-  bool lambda;
-
-  /// Whether this method should be prefixed with `static`.
-  ///
-  /// This is only valid within classes.
-  bool static = false;
-
-  /// Name of the method or function.
-  String name;
-
-  /// Whether this is a getter or setter.
-  MethodType type;
-
-  /// Whether this method is `async`, `async*`, or `sync*`.
-  MethodModifier modifier;
-
-  Reference returns;
-}
-
-enum MethodType {
-  getter,
-  setter,
-}
-
-enum MethodModifier {
-  async,
-  asyncStar,
-  syncStar,
-}
-
-abstract class Parameter extends Object
-    with HasAnnotations, HasGenerics, HasDartDocs
-    implements Built<Parameter, ParameterBuilder> {
-  factory Parameter([void updates(ParameterBuilder b)]) = _$Parameter;
-
-  Parameter._();
-
-  /// If not `null`, a default assignment if the parameter is optional.
-  @nullable
-  Code get defaultTo;
-
-  /// Name of the parameter.
-  String get name;
-
-  /// Whether this parameter should be named, if optional.
-  bool get named;
-
-  /// Whether this parameter should be field formal (i.e. `this.`).
-  ///
-  /// This is only valid on constructors;
-  bool get toThis;
-
-  @override
-  BuiltList<Expression> get annotations;
-
-  @override
-  BuiltList<String> get docs;
-
-  @override
-  BuiltList<Reference> get types;
-
-  /// Type of the parameter;
-  @nullable
-  Reference get type;
-}
-
-abstract class ParameterBuilder extends Object
-    with HasAnnotationsBuilder, HasGenericsBuilder, HasDartDocsBuilder
-    implements Builder<Parameter, ParameterBuilder> {
-  factory ParameterBuilder() = _$ParameterBuilder;
-
-  ParameterBuilder._();
-
-  /// If not `null`, a default assignment if the parameter is optional.
-  Code defaultTo;
-
-  /// Name of the parameter.
-  String name;
-
-  /// Whether this parameter should be named, if optional.
-  bool named = false;
-
-  /// Whether this parameter should be field formal (i.e. `this.`).
-  ///
-  /// This is only valid on constructors;
-  bool toThis = false;
-
-  @override
-  ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
-  @override
-  ListBuilder<String> docs = ListBuilder<String>();
-
-  @override
-  ListBuilder<Reference> types = ListBuilder<Reference>();
-
-  /// Type of the parameter;
-  Reference type;
-}
diff --git a/code_builder/lib/src/specs/method.g.dart b/code_builder/lib/src/specs/method.g.dart
deleted file mode 100644
index b6b862a..0000000
--- a/code_builder/lib/src/specs/method.g.dart
+++ /dev/null
@@ -1,641 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'method.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Method extends Method {
-  @override
-  final BuiltList<Expression> annotations;
-  @override
-  final BuiltList<String> docs;
-  @override
-  final BuiltList<Reference> types;
-  @override
-  final BuiltList<Parameter> optionalParameters;
-  @override
-  final BuiltList<Parameter> requiredParameters;
-  @override
-  final Code body;
-  @override
-  final bool external;
-  @override
-  final bool lambda;
-  @override
-  final bool static;
-  @override
-  final String name;
-  @override
-  final MethodType type;
-  @override
-  final MethodModifier modifier;
-  @override
-  final Reference returns;
-
-  factory _$Method([void updates(MethodBuilder b)]) =>
-      (new MethodBuilder()..update(updates)).build() as _$Method;
-
-  _$Method._(
-      {this.annotations,
-      this.docs,
-      this.types,
-      this.optionalParameters,
-      this.requiredParameters,
-      this.body,
-      this.external,
-      this.lambda,
-      this.static,
-      this.name,
-      this.type,
-      this.modifier,
-      this.returns})
-      : super._() {
-    if (annotations == null)
-      throw new BuiltValueNullFieldError('Method', 'annotations');
-    if (docs == null) throw new BuiltValueNullFieldError('Method', 'docs');
-    if (types == null) throw new BuiltValueNullFieldError('Method', 'types');
-    if (optionalParameters == null)
-      throw new BuiltValueNullFieldError('Method', 'optionalParameters');
-    if (requiredParameters == null)
-      throw new BuiltValueNullFieldError('Method', 'requiredParameters');
-    if (external == null)
-      throw new BuiltValueNullFieldError('Method', 'external');
-    if (static == null) throw new BuiltValueNullFieldError('Method', 'static');
-  }
-
-  @override
-  Method rebuild(void updates(MethodBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$MethodBuilder toBuilder() => new _$MethodBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! Method) return false;
-    return annotations == other.annotations &&
-        docs == other.docs &&
-        types == other.types &&
-        optionalParameters == other.optionalParameters &&
-        requiredParameters == other.requiredParameters &&
-        body == other.body &&
-        external == other.external &&
-        lambda == other.lambda &&
-        static == other.static &&
-        name == other.name &&
-        type == other.type &&
-        modifier == other.modifier &&
-        returns == other.returns;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(
-        $jc(
-            $jc(
-                $jc(
-                    $jc(
-                        $jc(
-                            $jc(
-                                $jc(
-                                    $jc(
-                                        $jc(
-                                            $jc(
-                                                $jc(
-                                                    $jc(0,
-                                                        annotations.hashCode),
-                                                    docs.hashCode),
-                                                types.hashCode),
-                                            optionalParameters.hashCode),
-                                        requiredParameters.hashCode),
-                                    body.hashCode),
-                                external.hashCode),
-                            lambda.hashCode),
-                        static.hashCode),
-                    name.hashCode),
-                type.hashCode),
-            modifier.hashCode),
-        returns.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('Method')
-          ..add('annotations', annotations)
-          ..add('docs', docs)
-          ..add('types', types)
-          ..add('optionalParameters', optionalParameters)
-          ..add('requiredParameters', requiredParameters)
-          ..add('body', body)
-          ..add('external', external)
-          ..add('lambda', lambda)
-          ..add('static', static)
-          ..add('name', name)
-          ..add('type', type)
-          ..add('modifier', modifier)
-          ..add('returns', returns))
-        .toString();
-  }
-}
-
-class _$MethodBuilder extends MethodBuilder {
-  _$Method _$v;
-
-  @override
-  ListBuilder<Expression> get annotations {
-    _$this;
-    return super.annotations ??= new ListBuilder<Expression>();
-  }
-
-  @override
-  set annotations(ListBuilder<Expression> annotations) {
-    _$this;
-    super.annotations = annotations;
-  }
-
-  @override
-  ListBuilder<String> get docs {
-    _$this;
-    return super.docs ??= new ListBuilder<String>();
-  }
-
-  @override
-  set docs(ListBuilder<String> docs) {
-    _$this;
-    super.docs = docs;
-  }
-
-  @override
-  ListBuilder<Reference> get types {
-    _$this;
-    return super.types ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set types(ListBuilder<Reference> types) {
-    _$this;
-    super.types = types;
-  }
-
-  @override
-  ListBuilder<Parameter> get optionalParameters {
-    _$this;
-    return super.optionalParameters ??= new ListBuilder<Parameter>();
-  }
-
-  @override
-  set optionalParameters(ListBuilder<Parameter> optionalParameters) {
-    _$this;
-    super.optionalParameters = optionalParameters;
-  }
-
-  @override
-  ListBuilder<Parameter> get requiredParameters {
-    _$this;
-    return super.requiredParameters ??= new ListBuilder<Parameter>();
-  }
-
-  @override
-  set requiredParameters(ListBuilder<Parameter> requiredParameters) {
-    _$this;
-    super.requiredParameters = requiredParameters;
-  }
-
-  @override
-  Code get body {
-    _$this;
-    return super.body;
-  }
-
-  @override
-  set body(Code body) {
-    _$this;
-    super.body = body;
-  }
-
-  @override
-  bool get external {
-    _$this;
-    return super.external;
-  }
-
-  @override
-  set external(bool external) {
-    _$this;
-    super.external = external;
-  }
-
-  @override
-  bool get lambda {
-    _$this;
-    return super.lambda;
-  }
-
-  @override
-  set lambda(bool lambda) {
-    _$this;
-    super.lambda = lambda;
-  }
-
-  @override
-  bool get static {
-    _$this;
-    return super.static;
-  }
-
-  @override
-  set static(bool static) {
-    _$this;
-    super.static = static;
-  }
-
-  @override
-  String get name {
-    _$this;
-    return super.name;
-  }
-
-  @override
-  set name(String name) {
-    _$this;
-    super.name = name;
-  }
-
-  @override
-  MethodType get type {
-    _$this;
-    return super.type;
-  }
-
-  @override
-  set type(MethodType type) {
-    _$this;
-    super.type = type;
-  }
-
-  @override
-  MethodModifier get modifier {
-    _$this;
-    return super.modifier;
-  }
-
-  @override
-  set modifier(MethodModifier modifier) {
-    _$this;
-    super.modifier = modifier;
-  }
-
-  @override
-  Reference get returns {
-    _$this;
-    return super.returns;
-  }
-
-  @override
-  set returns(Reference returns) {
-    _$this;
-    super.returns = returns;
-  }
-
-  _$MethodBuilder() : super._();
-
-  MethodBuilder get _$this {
-    if (_$v != null) {
-      super.annotations = _$v.annotations?.toBuilder();
-      super.docs = _$v.docs?.toBuilder();
-      super.types = _$v.types?.toBuilder();
-      super.optionalParameters = _$v.optionalParameters?.toBuilder();
-      super.requiredParameters = _$v.requiredParameters?.toBuilder();
-      super.body = _$v.body;
-      super.external = _$v.external;
-      super.lambda = _$v.lambda;
-      super.static = _$v.static;
-      super.name = _$v.name;
-      super.type = _$v.type;
-      super.modifier = _$v.modifier;
-      super.returns = _$v.returns;
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(Method other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$Method;
-  }
-
-  @override
-  void update(void updates(MethodBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$Method build() {
-    _$Method _$result;
-    try {
-      _$result = _$v ??
-          new _$Method._(
-              annotations: annotations.build(),
-              docs: docs.build(),
-              types: types.build(),
-              optionalParameters: optionalParameters.build(),
-              requiredParameters: requiredParameters.build(),
-              body: body,
-              external: external,
-              lambda: lambda,
-              static: static,
-              name: name,
-              type: type,
-              modifier: modifier,
-              returns: returns);
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'annotations';
-        annotations.build();
-        _$failedField = 'docs';
-        docs.build();
-        _$failedField = 'types';
-        types.build();
-        _$failedField = 'optionalParameters';
-        optionalParameters.build();
-        _$failedField = 'requiredParameters';
-        requiredParameters.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'Method', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
-
-class _$Parameter extends Parameter {
-  @override
-  final Code defaultTo;
-  @override
-  final String name;
-  @override
-  final bool named;
-  @override
-  final bool toThis;
-  @override
-  final BuiltList<Expression> annotations;
-  @override
-  final BuiltList<String> docs;
-  @override
-  final BuiltList<Reference> types;
-  @override
-  final Reference type;
-
-  factory _$Parameter([void updates(ParameterBuilder b)]) =>
-      (new ParameterBuilder()..update(updates)).build() as _$Parameter;
-
-  _$Parameter._(
-      {this.defaultTo,
-      this.name,
-      this.named,
-      this.toThis,
-      this.annotations,
-      this.docs,
-      this.types,
-      this.type})
-      : super._() {
-    if (name == null) throw new BuiltValueNullFieldError('Parameter', 'name');
-    if (named == null) throw new BuiltValueNullFieldError('Parameter', 'named');
-    if (toThis == null)
-      throw new BuiltValueNullFieldError('Parameter', 'toThis');
-    if (annotations == null)
-      throw new BuiltValueNullFieldError('Parameter', 'annotations');
-    if (docs == null) throw new BuiltValueNullFieldError('Parameter', 'docs');
-    if (types == null) throw new BuiltValueNullFieldError('Parameter', 'types');
-  }
-
-  @override
-  Parameter rebuild(void updates(ParameterBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$ParameterBuilder toBuilder() => new _$ParameterBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! Parameter) return false;
-    return defaultTo == other.defaultTo &&
-        name == other.name &&
-        named == other.named &&
-        toThis == other.toThis &&
-        annotations == other.annotations &&
-        docs == other.docs &&
-        types == other.types &&
-        type == other.type;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(
-        $jc(
-            $jc(
-                $jc(
-                    $jc(
-                        $jc($jc($jc(0, defaultTo.hashCode), name.hashCode),
-                            named.hashCode),
-                        toThis.hashCode),
-                    annotations.hashCode),
-                docs.hashCode),
-            types.hashCode),
-        type.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('Parameter')
-          ..add('defaultTo', defaultTo)
-          ..add('name', name)
-          ..add('named', named)
-          ..add('toThis', toThis)
-          ..add('annotations', annotations)
-          ..add('docs', docs)
-          ..add('types', types)
-          ..add('type', type))
-        .toString();
-  }
-}
-
-class _$ParameterBuilder extends ParameterBuilder {
-  _$Parameter _$v;
-
-  @override
-  Code get defaultTo {
-    _$this;
-    return super.defaultTo;
-  }
-
-  @override
-  set defaultTo(Code defaultTo) {
-    _$this;
-    super.defaultTo = defaultTo;
-  }
-
-  @override
-  String get name {
-    _$this;
-    return super.name;
-  }
-
-  @override
-  set name(String name) {
-    _$this;
-    super.name = name;
-  }
-
-  @override
-  bool get named {
-    _$this;
-    return super.named;
-  }
-
-  @override
-  set named(bool named) {
-    _$this;
-    super.named = named;
-  }
-
-  @override
-  bool get toThis {
-    _$this;
-    return super.toThis;
-  }
-
-  @override
-  set toThis(bool toThis) {
-    _$this;
-    super.toThis = toThis;
-  }
-
-  @override
-  ListBuilder<Expression> get annotations {
-    _$this;
-    return super.annotations ??= new ListBuilder<Expression>();
-  }
-
-  @override
-  set annotations(ListBuilder<Expression> annotations) {
-    _$this;
-    super.annotations = annotations;
-  }
-
-  @override
-  ListBuilder<String> get docs {
-    _$this;
-    return super.docs ??= new ListBuilder<String>();
-  }
-
-  @override
-  set docs(ListBuilder<String> docs) {
-    _$this;
-    super.docs = docs;
-  }
-
-  @override
-  ListBuilder<Reference> get types {
-    _$this;
-    return super.types ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set types(ListBuilder<Reference> types) {
-    _$this;
-    super.types = types;
-  }
-
-  @override
-  Reference get type {
-    _$this;
-    return super.type;
-  }
-
-  @override
-  set type(Reference type) {
-    _$this;
-    super.type = type;
-  }
-
-  _$ParameterBuilder() : super._();
-
-  ParameterBuilder get _$this {
-    if (_$v != null) {
-      super.defaultTo = _$v.defaultTo;
-      super.name = _$v.name;
-      super.named = _$v.named;
-      super.toThis = _$v.toThis;
-      super.annotations = _$v.annotations?.toBuilder();
-      super.docs = _$v.docs?.toBuilder();
-      super.types = _$v.types?.toBuilder();
-      super.type = _$v.type;
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(Parameter other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$Parameter;
-  }
-
-  @override
-  void update(void updates(ParameterBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$Parameter build() {
-    _$Parameter _$result;
-    try {
-      _$result = _$v ??
-          new _$Parameter._(
-              defaultTo: defaultTo,
-              name: name,
-              named: named,
-              toThis: toThis,
-              annotations: annotations.build(),
-              docs: docs.build(),
-              types: types.build(),
-              type: type);
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'annotations';
-        annotations.build();
-        _$failedField = 'docs';
-        docs.build();
-        _$failedField = 'types';
-        types.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'Parameter', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/specs/reference.dart b/code_builder/lib/src/specs/reference.dart
deleted file mode 100644
index 102d330..0000000
--- a/code_builder/lib/src/specs/reference.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// 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.
-
-library code_builder.src.specs.reference;
-
-import 'package:built_value/built_value.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'type_reference.dart';
-
-/// Short-hand for `Reference(symbol, url)`.
-Reference refer(String symbol, [String url]) {
-  return Reference(symbol, url);
-}
-
-/// A reference to [symbol], such as a class, or top-level method or field.
-///
-/// References can be collected and collated in order to automatically generate
-/// `import` statements for all used symbols.
-@immutable
-class Reference extends Expression implements Spec {
-  /// Relative, `package:` or `dart:` URL of the library.
-  ///
-  /// May be omitted (`null`) in order to express "same library".
-  final String url;
-
-  /// Name of the class, method, or field.
-  final String symbol;
-
-  /// Create a reference to [symbol] in [url].
-  const Reference(this.symbol, [this.url]);
-
-  @override
-  R accept<R>(
-    SpecVisitor<R> visitor, [
-    R context,
-  ]) =>
-      visitor.visitReference(this, context);
-
-  @override
-  int get hashCode => '$url#$symbol'.hashCode;
-
-  @override
-  bool operator ==(Object o) =>
-      o is Reference && o.url == url && o.symbol == symbol;
-
-  /// Returns a new instance of this expression.
-  Expression newInstance(
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression.newOf(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-      null,
-    );
-  }
-
-  /// Returns a new instance of this expression with a named constructor.
-  Expression newInstanceNamed(
-    String name,
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression.newOf(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-      name,
-    );
-  }
-
-  /// Returns a const instance of this expression.
-  Expression constInstance(
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression.constOf(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-      null,
-    );
-  }
-
-  /// Returns a const instance of this expression with a named constructor.
-  Expression constInstanceNamed(
-    String name,
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression.constOf(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-      name,
-    );
-  }
-
-  @override
-  Expression get expression {
-    return CodeExpression(Code.scope((a) => a(this)));
-  }
-
-  @override
-  String toString() => (newBuiltValueToStringHelper('Reference')
-        ..add('url', url)
-        ..add('symbol', symbol))
-      .toString();
-
-  /// Returns as a [TypeReference], which allows adding generic type parameters.
-  Reference get type => TypeReference((b) => b
-    ..url = url
-    ..symbol = symbol);
-}
diff --git a/code_builder/lib/src/specs/type_function.dart b/code_builder/lib/src/specs/type_function.dart
deleted file mode 100644
index b7b9014..0000000
--- a/code_builder/lib/src/specs/type_function.dart
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/generics.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'reference.dart';
-
-part 'type_function.g.dart';
-
-@immutable
-abstract class FunctionType extends Expression
-    with HasGenerics
-    implements Built<FunctionType, FunctionTypeBuilder>, Reference, Spec {
-  factory FunctionType([
-    void updates(FunctionTypeBuilder b),
-  ]) = _$FunctionType;
-
-  FunctionType._();
-
-  @override
-  R accept<R>(
-    SpecVisitor<R> visitor, [
-    R context,
-  ]) =>
-      visitor.visitFunctionType(this, context);
-
-  /// Return type.
-  @nullable
-  Reference get returnType;
-
-  @override
-  BuiltList<Reference> get types;
-
-  /// Required positional arguments to this function type.
-  BuiltList<Reference> get requiredParameters;
-
-  /// Optional positional arguments to this function type.
-  BuiltList<Reference> get optionalParameters;
-
-  /// Named optional arguments to this function type.
-  BuiltMap<String, Reference> get namedParameters;
-
-  @override
-  String get url => null;
-
-  @override
-  String get symbol => null;
-
-  @override
-  Reference get type => this;
-
-  @override
-  Expression newInstance(
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) =>
-      throw UnsupportedError('Cannot instantiate a function type.');
-
-  @override
-  Expression newInstanceNamed(
-    String name,
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) =>
-      throw UnsupportedError('Cannot instantiate a function type.');
-
-  @override
-  Expression constInstance(
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) =>
-      throw UnsupportedError('Cannot "const" a function type.');
-
-  @override
-  Expression constInstanceNamed(
-    String name,
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) =>
-      throw UnsupportedError('Cannot "const" a function type.');
-
-  /// A typedef assignment to this type.
-  Code toTypeDef(String name) => createTypeDef(name, this);
-}
-
-abstract class FunctionTypeBuilder extends Object
-    with HasGenericsBuilder
-    implements Builder<FunctionType, FunctionTypeBuilder> {
-  factory FunctionTypeBuilder() = _$FunctionTypeBuilder;
-
-  FunctionTypeBuilder._();
-
-  Reference returnType;
-
-  @override
-  ListBuilder<Reference> types = ListBuilder<Reference>();
-
-  ListBuilder<Reference> requiredParameters = ListBuilder<Reference>();
-
-  ListBuilder<Reference> optionalParameters = ListBuilder<Reference>();
-
-  MapBuilder<String, Reference> namedParameters =
-      MapBuilder<String, Reference>();
-}
diff --git a/code_builder/lib/src/specs/type_function.g.dart b/code_builder/lib/src/specs/type_function.g.dart
deleted file mode 100644
index b89237f..0000000
--- a/code_builder/lib/src/specs/type_function.g.dart
+++ /dev/null
@@ -1,211 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'type_function.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$FunctionType extends FunctionType {
-  @override
-  final Reference returnType;
-  @override
-  final BuiltList<Reference> types;
-  @override
-  final BuiltList<Reference> requiredParameters;
-  @override
-  final BuiltList<Reference> optionalParameters;
-  @override
-  final BuiltMap<String, Reference> namedParameters;
-
-  factory _$FunctionType([void updates(FunctionTypeBuilder b)]) =>
-      (new FunctionTypeBuilder()..update(updates)).build() as _$FunctionType;
-
-  _$FunctionType._(
-      {this.returnType,
-      this.types,
-      this.requiredParameters,
-      this.optionalParameters,
-      this.namedParameters})
-      : super._() {
-    if (types == null)
-      throw new BuiltValueNullFieldError('FunctionType', 'types');
-    if (requiredParameters == null)
-      throw new BuiltValueNullFieldError('FunctionType', 'requiredParameters');
-    if (optionalParameters == null)
-      throw new BuiltValueNullFieldError('FunctionType', 'optionalParameters');
-    if (namedParameters == null)
-      throw new BuiltValueNullFieldError('FunctionType', 'namedParameters');
-  }
-
-  @override
-  FunctionType rebuild(void updates(FunctionTypeBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$FunctionTypeBuilder toBuilder() =>
-      new _$FunctionTypeBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! FunctionType) return false;
-    return returnType == other.returnType &&
-        types == other.types &&
-        requiredParameters == other.requiredParameters &&
-        optionalParameters == other.optionalParameters &&
-        namedParameters == other.namedParameters;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(
-        $jc(
-            $jc($jc($jc(0, returnType.hashCode), types.hashCode),
-                requiredParameters.hashCode),
-            optionalParameters.hashCode),
-        namedParameters.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('FunctionType')
-          ..add('returnType', returnType)
-          ..add('types', types)
-          ..add('requiredParameters', requiredParameters)
-          ..add('optionalParameters', optionalParameters)
-          ..add('namedParameters', namedParameters))
-        .toString();
-  }
-}
-
-class _$FunctionTypeBuilder extends FunctionTypeBuilder {
-  _$FunctionType _$v;
-
-  @override
-  Reference get returnType {
-    _$this;
-    return super.returnType;
-  }
-
-  @override
-  set returnType(Reference returnType) {
-    _$this;
-    super.returnType = returnType;
-  }
-
-  @override
-  ListBuilder<Reference> get types {
-    _$this;
-    return super.types ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set types(ListBuilder<Reference> types) {
-    _$this;
-    super.types = types;
-  }
-
-  @override
-  ListBuilder<Reference> get requiredParameters {
-    _$this;
-    return super.requiredParameters ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set requiredParameters(ListBuilder<Reference> requiredParameters) {
-    _$this;
-    super.requiredParameters = requiredParameters;
-  }
-
-  @override
-  ListBuilder<Reference> get optionalParameters {
-    _$this;
-    return super.optionalParameters ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set optionalParameters(ListBuilder<Reference> optionalParameters) {
-    _$this;
-    super.optionalParameters = optionalParameters;
-  }
-
-  @override
-  MapBuilder<String, Reference> get namedParameters {
-    _$this;
-    return super.namedParameters ??= new MapBuilder<String, Reference>();
-  }
-
-  @override
-  set namedParameters(MapBuilder<String, Reference> namedParameters) {
-    _$this;
-    super.namedParameters = namedParameters;
-  }
-
-  _$FunctionTypeBuilder() : super._();
-
-  FunctionTypeBuilder get _$this {
-    if (_$v != null) {
-      super.returnType = _$v.returnType;
-      super.types = _$v.types?.toBuilder();
-      super.requiredParameters = _$v.requiredParameters?.toBuilder();
-      super.optionalParameters = _$v.optionalParameters?.toBuilder();
-      super.namedParameters = _$v.namedParameters?.toBuilder();
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(FunctionType other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$FunctionType;
-  }
-
-  @override
-  void update(void updates(FunctionTypeBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$FunctionType build() {
-    _$FunctionType _$result;
-    try {
-      _$result = _$v ??
-          new _$FunctionType._(
-              returnType: returnType,
-              types: types.build(),
-              requiredParameters: requiredParameters.build(),
-              optionalParameters: optionalParameters.build(),
-              namedParameters: namedParameters.build());
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'types';
-        types.build();
-        _$failedField = 'requiredParameters';
-        requiredParameters.build();
-        _$failedField = 'optionalParameters';
-        optionalParameters.build();
-        _$failedField = 'namedParameters';
-        namedParameters.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'FunctionType', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/specs/type_reference.dart b/code_builder/lib/src/specs/type_reference.dart
deleted file mode 100644
index 1f864f9..0000000
--- a/code_builder/lib/src/specs/type_reference.dart
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/generics.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'reference.dart';
-
-part 'type_reference.g.dart';
-
-@immutable
-abstract class TypeReference extends Expression
-    with HasGenerics
-    implements Built<TypeReference, TypeReferenceBuilder>, Reference, Spec {
-  factory TypeReference([
-    void updates(TypeReferenceBuilder b),
-  ]) = _$TypeReference;
-
-  TypeReference._();
-
-  @override
-  String get symbol;
-
-  @override
-  @nullable
-  String get url;
-
-  /// Optional bound generic.
-  @nullable
-  Reference get bound;
-
-  @override
-  BuiltList<Reference> get types;
-
-  @override
-  R accept<R>(
-    SpecVisitor<R> visitor, [
-    R context,
-  ]) =>
-      visitor.visitType(this, context);
-
-  @override
-  Expression get expression {
-    return CodeExpression(Code.scope((a) => a(this)));
-  }
-
-  @override
-  TypeReference get type => this;
-
-  @override
-  Expression newInstance(
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression.newOf(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-      null,
-    );
-  }
-
-  @override
-  Expression newInstanceNamed(
-    String name,
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression.newOf(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-      name,
-    );
-  }
-
-  @override
-  Expression constInstance(
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression.constOf(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-      null,
-    );
-  }
-
-  @override
-  Expression constInstanceNamed(
-    String name,
-    Iterable<Expression> positionalArguments, [
-    Map<String, Expression> namedArguments = const {},
-    List<Reference> typeArguments = const [],
-  ]) {
-    return InvokeExpression.constOf(
-      this,
-      positionalArguments.toList(),
-      namedArguments,
-      typeArguments,
-      name,
-    );
-  }
-}
-
-abstract class TypeReferenceBuilder extends Object
-    with HasGenericsBuilder
-    implements Builder<TypeReference, TypeReferenceBuilder> {
-  factory TypeReferenceBuilder() = _$TypeReferenceBuilder;
-
-  TypeReferenceBuilder._();
-
-  String symbol;
-
-  String url;
-
-  /// Optional bound generic.
-  Reference bound;
-
-  @override
-  ListBuilder<Reference> types = ListBuilder<Reference>();
-}
diff --git a/code_builder/lib/src/specs/type_reference.g.dart b/code_builder/lib/src/specs/type_reference.g.dart
deleted file mode 100644
index bcd362f..0000000
--- a/code_builder/lib/src/specs/type_reference.g.dart
+++ /dev/null
@@ -1,172 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'type_reference.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$TypeReference extends TypeReference {
-  @override
-  final String symbol;
-  @override
-  final String url;
-  @override
-  final Reference bound;
-  @override
-  final BuiltList<Reference> types;
-
-  factory _$TypeReference([void updates(TypeReferenceBuilder b)]) =>
-      (new TypeReferenceBuilder()..update(updates)).build() as _$TypeReference;
-
-  _$TypeReference._({this.symbol, this.url, this.bound, this.types})
-      : super._() {
-    if (symbol == null)
-      throw new BuiltValueNullFieldError('TypeReference', 'symbol');
-    if (types == null)
-      throw new BuiltValueNullFieldError('TypeReference', 'types');
-  }
-
-  @override
-  TypeReference rebuild(void updates(TypeReferenceBuilder b)) =>
-      (toBuilder()..update(updates)).build();
-
-  @override
-  _$TypeReferenceBuilder toBuilder() =>
-      new _$TypeReferenceBuilder()..replace(this);
-
-  @override
-  bool operator ==(dynamic other) {
-    if (identical(other, this)) return true;
-    if (other is! TypeReference) return false;
-    return symbol == other.symbol &&
-        url == other.url &&
-        bound == other.bound &&
-        types == other.types;
-  }
-
-  @override
-  int get hashCode {
-    return $jf($jc(
-        $jc($jc($jc(0, symbol.hashCode), url.hashCode), bound.hashCode),
-        types.hashCode));
-  }
-
-  @override
-  String toString() {
-    return (newBuiltValueToStringHelper('TypeReference')
-          ..add('symbol', symbol)
-          ..add('url', url)
-          ..add('bound', bound)
-          ..add('types', types))
-        .toString();
-  }
-}
-
-class _$TypeReferenceBuilder extends TypeReferenceBuilder {
-  _$TypeReference _$v;
-
-  @override
-  String get symbol {
-    _$this;
-    return super.symbol;
-  }
-
-  @override
-  set symbol(String symbol) {
-    _$this;
-    super.symbol = symbol;
-  }
-
-  @override
-  String get url {
-    _$this;
-    return super.url;
-  }
-
-  @override
-  set url(String url) {
-    _$this;
-    super.url = url;
-  }
-
-  @override
-  Reference get bound {
-    _$this;
-    return super.bound;
-  }
-
-  @override
-  set bound(Reference bound) {
-    _$this;
-    super.bound = bound;
-  }
-
-  @override
-  ListBuilder<Reference> get types {
-    _$this;
-    return super.types ??= new ListBuilder<Reference>();
-  }
-
-  @override
-  set types(ListBuilder<Reference> types) {
-    _$this;
-    super.types = types;
-  }
-
-  _$TypeReferenceBuilder() : super._();
-
-  TypeReferenceBuilder get _$this {
-    if (_$v != null) {
-      super.symbol = _$v.symbol;
-      super.url = _$v.url;
-      super.bound = _$v.bound;
-      super.types = _$v.types?.toBuilder();
-      _$v = null;
-    }
-    return this;
-  }
-
-  @override
-  void replace(TypeReference other) {
-    if (other == null) throw new ArgumentError.notNull('other');
-    _$v = other as _$TypeReference;
-  }
-
-  @override
-  void update(void updates(TypeReferenceBuilder b)) {
-    if (updates != null) updates(this);
-  }
-
-  @override
-  _$TypeReference build() {
-    _$TypeReference _$result;
-    try {
-      _$result = _$v ??
-          new _$TypeReference._(
-              symbol: symbol, url: url, bound: bound, types: types.build());
-    } catch (_) {
-      String _$failedField;
-      try {
-        _$failedField = 'types';
-        types.build();
-      } catch (e) {
-        throw new BuiltValueNestedFieldError(
-            'TypeReference', _$failedField, e.toString());
-      }
-      rethrow;
-    }
-    replace(_$result);
-    return _$result;
-  }
-}
diff --git a/code_builder/lib/src/visitors.dart b/code_builder/lib/src/visitors.dart
deleted file mode 100644
index 62b47bc..0000000
--- a/code_builder/lib/src/visitors.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:meta/meta.dart';
-
-import 'base.dart';
-import 'specs/class.dart';
-import 'specs/constructor.dart';
-import 'specs/directive.dart';
-import 'specs/expression.dart';
-import 'specs/field.dart';
-import 'specs/library.dart';
-import 'specs/method.dart';
-import 'specs/reference.dart';
-import 'specs/type_function.dart';
-import 'specs/type_reference.dart';
-
-@optionalTypeArgs
-abstract class SpecVisitor<T> {
-  const SpecVisitor._();
-
-  T visitAnnotation(Expression spec, [T context]);
-
-  T visitClass(Class spec, [T context]);
-
-  T visitConstructor(Constructor spec, String clazz, [T context]);
-
-  T visitDirective(Directive spec, [T context]);
-
-  T visitField(Field spec, [T context]);
-
-  T visitLibrary(Library spec, [T context]);
-
-  T visitFunctionType(FunctionType spec, [T context]);
-
-  T visitMethod(Method spec, [T context]);
-
-  T visitReference(Reference spec, [T context]);
-
-  T visitSpec(Spec spec, [T context]);
-
-  T visitType(TypeReference spec, [T context]);
-
-  T visitTypeParameters(Iterable<Reference> specs, [T context]);
-}
diff --git a/code_builder/pubspec.yaml b/code_builder/pubspec.yaml
deleted file mode 100644
index 60bcd09..0000000
--- a/code_builder/pubspec.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-name: code_builder
-version: 3.2.1
-
-description: >-
-  A fluent, builder-based library for generating valid Dart code
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/code_builder
-
-environment:
-  sdk: '>=2.1.0 <3.0.0'
-
-dependencies:
-  built_collection: '>=3.0.0 <5.0.0'
-  built_value: ^7.0.0
-  collection: ^1.14.0
-  matcher: ^0.12.0
-  meta: ^1.0.5
-
-dev_dependencies:
-  build: ^1.0.0
-  build_runner: ^1.1.0
-  built_value_generator: ^7.0.0
-  dart_style: ^1.0.0
-  source_gen: ^0.9.0
-  test: ^1.3.0
-
-#dependency_overrides:
-#  built_value: ^7.0.0
diff --git a/code_builder/tool/src/builder.dart b/code_builder/tool/src/builder.dart
deleted file mode 100644
index ff95814..0000000
--- a/code_builder/tool/src/builder.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:build/build.dart';
-import 'package:built_value_generator/built_value_generator.dart';
-import 'package:source_gen/source_gen.dart';
-
-/// Returns a [Builder] to generate `.g.dart` files for `built_value`.
-Builder builtValueBuilder(BuilderOptions _) {
-  return PartBuilder([
-    const BuiltValueGenerator(),
-  ], '.g.dart');
-}
diff --git a/completion/.travis.yml b/completion/.travis.yml
index 7e4cc44..f8a21dd 100644
--- a/completion/.travis.yml
+++ b/completion/.travis.yml
@@ -2,11 +2,17 @@
 
 dart:
   - dev
+  - 2.3.0
 
 dart_task:
   - test
-  - dartfmt
-  - dartanalyzer
+  - dartanalyzer: --fatal-infos --fatal-warnings .
+
+matrix:
+  include:
+  # Only validate formatting using the dev release
+  - dart: dev
+    dart_task: dartfmt
 
 # Only building master means that we don't run two builds for each pull request.
 branches:
diff --git a/completion/BUILD.gn b/completion/BUILD.gn
index f1d8965..c6d945e 100644
--- a/completion/BUILD.gn
+++ b/completion/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for completion-0.2.1+1
+# This file is generated by importer.py for completion-0.2.2
 
 import("//build/dart/dart_library.gni")
 
diff --git a/completion/CHANGELOG.md b/completion/CHANGELOG.md
index 7fa074d..0f8ca1c 100644
--- a/completion/CHANGELOG.md
+++ b/completion/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.2.2
+
+* Increase minimum Dart SDK to `2.3.0`.
+
 ## 0.2.1+1
 
 * Small fix to error handler.
diff --git a/completion/analysis_options.yaml b/completion/analysis_options.yaml
index 47f9b74..c1d96c4 100644
--- a/completion/analysis_options.yaml
+++ b/completion/analysis_options.yaml
@@ -1,63 +1,70 @@
+include: package:pedantic/analysis_options.yaml
+
 analyzer:
   strong-mode:
     implicit-casts: false
-  errors:
-    unused_element: error
-    unused_import: error
-    unused_local_variable: error
-    dead_code: error
-    override_on_non_overriding_method: error
+
 linter:
   rules:
-    - annotate_overrides
-    - avoid_empty_else
+    - avoid_catching_errors
     - avoid_function_literals_in_foreach_calls
-    - avoid_init_to_null
-    - avoid_null_checks_in_equality_operators
-    - avoid_return_types_on_setters
+    - avoid_private_typedef_functions
+    - avoid_redundant_argument_values
+    - avoid_renaming_method_parameters
     - avoid_returning_null
+    - avoid_returning_null_for_void
     - avoid_unused_constructor_parameters
+    - avoid_void_async
     - await_only_futures
     - camel_case_types
     - cancel_subscriptions
+    - cascade_invocations
     - comment_references
     - constant_identifier_names
     - control_flow_in_finally
     - directives_ordering
-    - empty_catches
-    - empty_constructor_bodies
     - empty_statements
+    - file_names
     - hash_and_equals
     - implementation_imports
+    - invariant_booleans
     - iterable_contains_unrelated_type
-    - library_names
-    - library_prefixes
+    - join_return_with_assignment
+    - lines_longer_than_80_chars
     - list_remove_unrelated_type
-    - no_duplicate_case_values
+    - literal_only_boolean_expressions
+    - missing_whitespace_between_adjacent_strings
+    - no_adjacent_strings_in_list
+    - no_runtimeType_toString
     - non_constant_identifier_names
     - only_throw_errors
     - overridden_fields
     - package_api_docs
     - package_names
     - package_prefixed_library_names
-    - prefer_conditional_assignment
-    - prefer_final_fields
-    - prefer_is_empty
-    - prefer_is_not_empty
-    - prefer_single_quotes
+    - prefer_asserts_in_initializer_lists
+    - prefer_const_constructors
+    - prefer_const_declarations
+    - prefer_expression_function_bodies
+    - prefer_final_locals
+    - prefer_function_declarations_over_variables
+    - prefer_initializing_formals
+    - prefer_inlined_adds
+    - prefer_interpolation_to_compose_strings
+    - prefer_is_not_operator
+    - prefer_null_aware_operators
+    - prefer_relative_imports
     - prefer_typing_uninitialized_variables
-    - recursive_getters
-    - slash_for_doc_comments
-    - super_goes_last
+    - prefer_void_to_null
+    - sort_pub_dependencies
     - test_types_in_equals
     - throw_in_finally
-    - type_init_formals
-    - unawaited_futures
     - unnecessary_brace_in_string_interps
     - unnecessary_getters_setters
     - unnecessary_lambdas
     - unnecessary_null_aware_assignments
+    - unnecessary_overrides
+    - unnecessary_parenthesis
     - unnecessary_statements
-    - unused_catch_clause
-    - unrelated_type_equality_checks
-    - valid_regexps
+    - unnecessary_string_interpolations
+    - void_checks
diff --git a/completion/example/hello-completion.sh b/completion/example/example-completion.sh
similarity index 69%
rename from completion/example/hello-completion.sh
rename to completion/example/example-completion.sh
index 91e272f..3dee89a 100644
--- a/completion/example/hello-completion.sh
+++ b/completion/example/example-completion.sh
@@ -11,32 +11,32 @@
 #
 #    /usr/local/etc/bash_completion.d/
 
-###-begin-hello.dart-completion-###
+###-begin-example.dart-completion-###
 
 if type complete &>/dev/null; then
-  __hello_dart_completion() {
+  __example_dart_completion() {
     local si="$IFS"
     IFS=$'\n' COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \
                            COMP_LINE="$COMP_LINE" \
                            COMP_POINT="$COMP_POINT" \
-                           hello.dart completion -- "${COMP_WORDS[@]}" \
+                           example.dart completion -- "${COMP_WORDS[@]}" \
                            2>/dev/null)) || return $?
     IFS="$si"
   }
-  complete -F __hello_dart_completion hello.dart
+  complete -F __example_dart_completion example.dart
 elif type compdef &>/dev/null; then
-  __hello_dart_completion() {
+  __example_dart_completion() {
     si=$IFS
     compadd -- $(COMP_CWORD=$((CURRENT-1)) \
                  COMP_LINE=$BUFFER \
                  COMP_POINT=0 \
-                 hello.dart completion -- "${words[@]}" \
+                 example.dart completion -- "${words[@]}" \
                  2>/dev/null)
     IFS=$si
   }
-  compdef __hello_dart_completion hello.dart
+  compdef __example_dart_completion example.dart
 elif type compctl &>/dev/null; then
-  __hello_dart_completion() {
+  __example_dart_completion() {
     local cword line point words si
     read -Ac words
     read -cn cword
@@ -47,14 +47,14 @@
     IFS=$'\n' reply=($(COMP_CWORD="$cword" \
                        COMP_LINE="$line" \
                        COMP_POINT="$point" \
-                       hello.dart completion -- "${words[@]}" \
+                       example.dart completion -- "${words[@]}" \
                        2>/dev/null)) || return $?
     IFS="$si"
   }
-  compctl -K __hello_dart_completion hello.dart
+  compctl -K __example_dart_completion example.dart
 fi
 
-###-end-hello.dart-completion-###
+###-end-example.dart-completion-###
 
-## Generated 2018-04-24 15:45:52.542816Z
+## Generated 2018-12-06 13:41:53.261614Z
 ## By /Users/kevmoo/source/github/completion.dart/bin/shell_completion_generator.dart
diff --git a/completion/example/hello.dart b/completion/example/example.dart
similarity index 94%
rename from completion/example/hello.dart
rename to completion/example/example.dart
index 81ce1de..c20909a 100755
--- a/completion/example/hello.dart
+++ b/completion/example/example.dart
@@ -1,11 +1,12 @@
 #!/usr/bin/env dart
 import 'dart:io';
+
 import 'package:args/args.dart';
 import 'package:completion/completion.dart';
 
 import '../test/completion_tests_args.dart';
 
-main(List<String> args) {
+void main(List<String> args) {
   final argParser = getHelloSampleParser();
 
   ArgResults argResult;
@@ -45,7 +46,7 @@
           print(subCommandParser.usage);
           return;
         } else {
-          throw new StateError(
+          throw StateError(
               'no clue what that subCammand is: ${subSubCommand.name}');
         }
       }
@@ -67,7 +68,7 @@
 
   final greeting = argResult['friendly'] as bool ? 'Hiya' : 'Hello';
 
-  final String salutationVal = argResult['salutation'];
+  final salutationVal = argResult['salutation'] as String;
   final salutation = salutationVal == null ? '' : '$salutationVal ';
 
   var message = '$greeting, $salutation$name';
diff --git a/completion/example/hello_completion_init.sh b/completion/example/example_completion_init.sh
similarity index 73%
rename from completion/example/hello_completion_init.sh
rename to completion/example/example_completion_init.sh
index 1bb2642..873f19c 100644
--- a/completion/example/hello_completion_init.sh
+++ b/completion/example/example_completion_init.sh
@@ -5,8 +5,8 @@
 #  source hello_completion_init.sh
 #
 
-APP_NAME=hello.dart
-COMPETION_NAME=hello-completion.sh
+APP_NAME=example.dart
+COMPLETION_NAME=example-completion.sh
 
 APP_DIR=$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd )
 
@@ -18,15 +18,15 @@
 
 if [ ! -f $APP_DIR/$COMPETION_NAME ]
 then
-  echo $COMPETION_NAME does not exist in the expected directory
+  echo $COMPLETION_NAME does not exist in the expected directory
   exit 1
 fi
 
 echo Initializing your environment to run the $APP_NAME completion sample
 echo
 
-echo 'sourcing' $COMPETION_NAME to enable command completion
-source $APP_DIR/$COMPETION_NAME
+echo 'sourcing' $COMPLETION_NAME to enable command completion
+source $APP_DIR/$COMPLETION_NAME
 
 echo
 echo Adding $APP_NAME directory \($APP_DIR\) to PATH environment
diff --git a/completion/lib/completion.dart b/completion/lib/completion.dart
index 55c627a..4ebc244 100644
--- a/completion/lib/completion.dart
+++ b/completion/lib/completion.dart
@@ -13,10 +13,9 @@
         logFile}) {
   tryCompletion(
     mainArgs,
-    (List<String> args, String compLine, int compPoint) {
-      return getArgsCompletions(parser, args, compLine, compPoint);
-    },
-    // ignore: deprecated_member_use
+    (List<String> args, String compLine, int compPoint) =>
+        getArgsCompletions(parser, args, compLine, compPoint),
+    // ignore: deprecated_member_use_from_same_package,deprecated_member_use
     logFile: logFile,
   );
   return parser.parse(mainArgs);
diff --git a/completion/lib/src/bot.dart b/completion/lib/src/bot.dart
deleted file mode 100644
index c77a072..0000000
--- a/completion/lib/src/bot.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-class Tuple<T1, T2> {
-  final T1 item1;
-  final T2 item2;
-
-  const Tuple(this.item1, this.item2);
-
-  @override
-  bool operator ==(other) {
-    return other is Tuple && item1 == other.item1 && item2 == other.item2;
-  }
-
-  @override
-  String toString() => '{item1: $item1, item2: $item2}';
-
-  @override
-  int get hashCode => Util.getHashCode([item1, item2]);
-
-  dynamic toJson() => {'item1': item1, 'item2': item2};
-}
-
-class Util {
-  static int getHashCode(Iterable source) {
-    requireArgumentNotNull(source, 'source');
-
-    int hash = 0;
-    for (final h in source) {
-      int next = h == null ? 0 : h.hashCode;
-      hash = 0x1fffffff & (hash + next);
-      hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
-      hash ^= hash >> 6;
-    }
-    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
-    hash ^= hash >> 11;
-    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
-  }
-}
-
-void require(bool truth, [String message]) {
-  if (!truth) {
-    throw new Exception(message);
-  }
-}
-
-void requireArgumentNotNull(argument, String argName) {
-  _metaRequireArgumentNotNullOrEmpty(argName);
-  if (argument == null) {
-    throw new ArgumentError.notNull(argName);
-  }
-}
-
-void _metaRequireArgumentNotNullOrEmpty(String argName) {
-  if (argName == null || argName.isEmpty) {
-    throw new UnsupportedError("That's just sad. Give me a good argName");
-  }
-}
diff --git a/completion/lib/src/generate.dart b/completion/lib/src/generate.dart
index e371b2b..7fb0304 100644
--- a/completion/lib/src/generate.dart
+++ b/completion/lib/src/generate.dart
@@ -12,7 +12,7 @@
  * Can contain letters, numbers, '_', '-', '.'
  * Must end with letter or number
  */
-final _binNameMatch = new RegExp(r'^[a-zA-Z0-9]((\w|-|\.)*[a-zA-Z0-9])?$');
+final _binNameMatch = RegExp(r'^[a-zA-Z0-9]((\w|-|\.)*[a-zA-Z0-9])?$');
 
 /*
  * Format for unified bash and zsh completion script:
@@ -26,32 +26,32 @@
 
 String generateCompletionScript(List<String> binaryNames) {
   if (binaryNames.isEmpty) {
-    throw new ArgumentError('Provide the name of at least of one command');
+    throw ArgumentError('Provide the name of at least of one command');
   }
 
   for (final binName in binaryNames) {
     if (!_binNameMatch.hasMatch(binName)) {
       final msg = 'The provided name - "$binName" - is invalid\n'
           'It must match regex: ${_binNameMatch.pattern}';
-      throw new StateError(msg);
+      throw StateError(msg);
     }
   }
 
-  var buffer = new StringBuffer();
+  final buffer = StringBuffer();
 
   final prefix =
       LineSplitter.split(_prefix).map((l) => '# $l'.trim()).join('\n');
-  buffer.writeln(prefix);
-
-  // empty line
-  buffer.writeln('');
+  buffer
+    ..writeln(prefix)
+    // empty line
+    ..writeln('');
 
   for (final binName in binaryNames) {
     buffer.writeln(_printBinName(binName));
   }
 
   final detailLines = [
-    'Generated ${new DateTime.now().toUtc()}',
+    'Generated ${DateTime.now().toUtc()}',
   ];
 
   if (Platform.script.scheme == 'file') {
@@ -68,14 +68,11 @@
 }
 
 String _printBinName(String binName) {
-  var templateContents = _template.replaceAll(_binNameReplacement, binName);
+  final templateContents = _template.replaceAll(_binNameReplacement, binName);
 
   var funcName = binName.replaceAll('.', '_');
   funcName = '__${funcName}_completion';
-  templateContents =
-      templateContents.replaceAll(_funcNameReplacement, funcName);
-
-  return templateContents;
+  return templateContents.replaceAll(_funcNameReplacement, funcName);
 }
 
 const _prefix = '''
diff --git a/completion/lib/src/get_args_completions.dart b/completion/lib/src/get_args_completions.dart
index d593e88..4f00923 100644
--- a/completion/lib/src/get_args_completions.dart
+++ b/completion/lib/src/get_args_completions.dart
@@ -1,6 +1,5 @@
 import 'package:args/args.dart';
 
-import 'bot.dart';
 import 'util.dart';
 
 /*
@@ -8,20 +7,24 @@
  *       then tabbing into an app just completes to that one command. Weird?
  */
 
-List<String> getArgsCompletions(ArgParser parser, List<String> providedArgs,
-    String compLine, int compPoint) {
+List<String> getArgsCompletions(
+  ArgParser parser,
+  List<String> providedArgs,
+  String compLine,
+  int compPoint,
+) {
   assert(parser != null);
   assert(providedArgs != null);
   // all arg entries: no empty items, no null items, all pre-trimmed
-  for (int i = 0; i < providedArgs.length; i++) {
+  for (var i = 0; i < providedArgs.length; i++) {
     final arg = providedArgs[i];
     final msg = 'Arg at index $i with value "$arg" ';
-    requireArgumentNotNull(arg, '$msg is null');
-    require(arg.trim() == arg, '$msg has whitespace');
+    if (arg.trim() != arg) throw StateError('$msg has whitespace');
 
     if (i < (providedArgs.length - 1)) {
-      require(
-          arg.isNotEmpty, '$msg – Only the last arg can be an empty string');
+      if (arg.isEmpty) {
+        throw StateError('$msg – Only the last arg can be an empty string');
+      }
     }
   }
 
@@ -60,14 +63,14 @@
 
   // a set of options in use (minus, potentially, the last one)
   // all non-null, all unique
-  var optionsDefinedInArgs = alignedArgsOptions
+  final optionsDefinedInArgs = alignedArgsOptions
       .take(alignedArgsOptions.length - 1)
       .where((o) => o != null)
       .toSet();
   sublog('defined options: ${optionsDefinedInArgs.map((o) => o.name).toSet()}');
 
-  var parserOptionCompletions = new List<String>.unmodifiable(
-      _getParserOptionCompletions(parser, optionsDefinedInArgs));
+  final parserOptionCompletions = List<String>.unmodifiable(
+      _parserOptionCompletions(parser, optionsDefinedInArgs));
 
   /*
    * KNOWN: at least one item in providedArgs last and first are now safe
@@ -79,9 +82,9 @@
    * If it does, we can use the result to determine what we should do next
    */
 
-  final subsetTuple = _getValidSubset(parser, providedArgs);
-  final validSubSet = subsetTuple.item1;
-  final subsetResult = subsetTuple.item2;
+  final subsetTuple = _validSubset(parser, providedArgs);
+  final validSubSet = subsetTuple.subset;
+  final subsetResult = subsetTuple.result;
 
   sublog('valid subset: ${helpfulToString(validSubSet)}');
 
@@ -160,7 +163,7 @@
         assert(!option.isFlag);
         sublog('completing option "${option.name}"');
 
-        final String optionValue = providedArgs[providedArgs.length - 1];
+        final optionValue = providedArgs[providedArgs.length - 1];
 
         return option.allowed
             .where((String v) => v.startsWith(optionValue))
@@ -248,7 +251,7 @@
   return null;
 }
 
-Iterable<String> _getParserOptionCompletions(
+Iterable<String> _parserOptionCompletions(
     ArgParser parser, Set<Option> existingOptions) {
   assert(
       existingOptions.every((option) => parser.options.containsValue(option)));
@@ -256,11 +259,10 @@
   return parser.options.values
       .where((opt) =>
           !existingOptions.contains(opt) || opt.type == OptionType.multiple)
-      .expand(_getArgsOptionCompletions);
+      .expand(_argsOptionCompletions);
 }
 
-Tuple<List<String>, ArgResults> _getValidSubset(
-    ArgParser parser, List<String> providedArgs) {
+_Tuple _validSubset(ArgParser parser, List<String> providedArgs) {
   /* start with all of the args, loop through parsing them,
    * removing one every time
    *
@@ -285,19 +287,17 @@
     validSubSet.removeLast();
   }
 
-  return new Tuple(validSubSet, subsetResult);
+  return _Tuple(validSubSet, subsetResult);
 }
 
-List<String> _getArgsOptionCompletions(Option option) {
-  final items = new List<String>();
+List<String> _argsOptionCompletions(Option option) => <String>[
+      '--${option.name}',
+      if (option.negatable) '--no-${option.name}',
+    ]..sort();
 
-  items.add('--${option.name}');
+class _Tuple {
+  final List<String> subset;
+  final ArgResults result;
 
-  if (option.negatable) {
-    items.add('--no-${option.name}');
-  }
-
-  items.sort();
-
-  return items;
+  const _Tuple(this.subset, this.result);
 }
diff --git a/completion/lib/src/try_completion.dart b/completion/lib/src/try_completion.dart
index 0c3449c..8db4cca 100644
--- a/completion/lib/src/try_completion.dart
+++ b/completion/lib/src/try_completion.dart
@@ -3,7 +3,6 @@
 import 'package:logging/logging.dart';
 import 'package:path/path.dart' as p;
 
-import 'bot.dart';
 import 'util.dart';
 
 /// The string 'completion' used to denote that arguments provided to an app are
@@ -17,11 +16,12 @@
 
 void tryCompletion(
     List<String> args,
-    List<String> completer(List<String> args, String compLine, int compPoint),
+    List<String> Function(List<String> args, String compLine, int compPoint)
+        completer,
     {@Deprecated('Useful for testing, but do not release with this set.')
         logFile}) {
   if (logFile != null) {
-    var logFile = new File('_completion.log');
+    final logFile = File('_completion.log');
 
     void logLine(String content) {
       logFile.writeAsStringSync('$content\n', mode: FileMode.writeOnlyAppend);
@@ -30,12 +30,14 @@
     logLine(' *' * 50);
 
     Logger.root.onRecord.listen((e) {
-      var loggerName = e.loggerName.split('.');
+      final loggerName = e.loggerName.split('.');
       if (loggerName.isNotEmpty && loggerName.first == 'completion') {
         loggerName.removeAt(0);
         assert(e.level == Level.INFO);
         logLine(
-            '${loggerName.join('.').padLeft(Tag.longestTagLength)}  ${e.message}');
+          '${loggerName.join('.').padLeft(Tag.longestTagLength)}  '
+          '${e.message}',
+        );
       }
     });
   }
@@ -43,7 +45,8 @@
   String scriptName;
   try {
     scriptName = p.basename(Platform.script.toFilePath());
-  } on UnsupportedError {
+  } on UnsupportedError // ignore: avoid_catching_errors
+  {
     scriptName = '<unknown>';
   }
 
@@ -56,20 +59,24 @@
 
       final env = Platform.environment;
 
-      // There are 3 interesting env paramaters passed by the completion logic
+      // There are 3 interesting env parameters passed by the completion logic
       // COMP_LINE:  the full contents of the completion
       final compLine = env['COMP_LINE'];
-      require(compLine != null, 'Environment variable COMP_LINE must be set');
+      if (compLine == null) {
+        throw StateError('Environment variable COMP_LINE must be set');
+      }
 
       // COMP_CWORD: number of words. Also might be nice
       // COMP_POINT: where the cursor is on the completion line
       final compPointValue = env[_compPointVar];
-      require(compPointValue != null && compPointValue.isNotEmpty,
-          'Environment variable $_compPointVar must be set and non-empty');
+      if (compPointValue == null || compPointValue.isEmpty) {
+        throw StateError(
+            'Environment variable $_compPointVar must be set and non-empty');
+      }
       final compPoint = int.tryParse(compPointValue);
 
       if (compPoint == null) {
-        throw new FormatException('Could not parse $_compPointVar value '
+        throw FormatException('Could not parse $_compPointVar value '
             '"$compPointValue" into an integer');
       }
 
diff --git a/completion/lib/src/util.dart b/completion/lib/src/util.dart
index 4512df1..98b5209 100644
--- a/completion/lib/src/util.dart
+++ b/completion/lib/src/util.dart
@@ -1,7 +1,7 @@
 import 'package:logging/logging.dart' as logging;
 
 class Tag {
-  static const getArgsCompletions = const Tag._('getArgsCompletions');
+  static const getArgsCompletions = Tag._('getArgsCompletions');
 
   final String name;
 
@@ -27,9 +27,7 @@
 
   final loggerName = startArgs.join('.');
 
-  final logger = new logging.Logger(loggerName);
-
-  logger.info(safe);
+  logging.Logger(loggerName)..info(safe);
 }
 
 String helpfulToString(Object input) {
diff --git a/completion/pubspec.yaml b/completion/pubspec.yaml
index f70ef9e..3599f7b 100644
--- a/completion/pubspec.yaml
+++ b/completion/pubspec.yaml
@@ -1,11 +1,10 @@
 name: completion
-version: 0.2.1+1
-author: Kevin Moore <github@j832.com>
+version: 0.2.2
 description: A packaged to add shell command completion to your Dart application
 homepage: https://github.com/kevmoo/completion.dart
 
 environment:
-  sdk: '>=2.0.0-dev.54.0 <3.0.0'
+  sdk: '>=2.3.0 <3.0.0'
 
 dependencies:
   args: ^1.4.0
@@ -13,6 +12,7 @@
   path: ^1.0.0
 
 dev_dependencies:
+  pedantic: ^1.0.0
   test: ^1.2.0
   test_process: ^1.0.1
 
diff --git a/connectivity/BUILD.gn b/connectivity/BUILD.gn
index 567cd56..559c427 100644
--- a/connectivity/BUILD.gn
+++ b/connectivity/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for connectivity-0.4.6+2
+# This file is generated by importer.py for connectivity-0.4.8+1
 
 import("//build/dart/dart_library.gni")
 
@@ -12,7 +12,9 @@
   disable_analysis = true
 
   deps = [
+    "//third_party/dart-pkg/pub/connectivity_platform_interface",
     "//third_party/dart-pkg/pub/meta",
     "//third_party/dart-pkg/git/flutter/packages/flutter",
+    "//third_party/dart-pkg/pub/connectivity_macos",
   ]
 }
diff --git a/connectivity/CHANGELOG.md b/connectivity/CHANGELOG.md
index 57741ee..b297f38 100644
--- a/connectivity/CHANGELOG.md
+++ b/connectivity/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 0.4.8+1
+
+* Make the pedantic dev_dependency explicit.
+
+## 0.4.8
+
+* Adds macOS as an endorsed platform.
+
+## 0.4.7
+
+* Migrate the plugin to use the ConnectivityPlatform.instance defined in the connectivity_platform_interface package.
+
 ## 0.4.6+2
 
 * Migrate deprecated BinaryMessages to ServicesBinding.instance.defaultBinaryMessenger.
diff --git a/connectivity/connectivity_macos/CHANGELOG.md b/connectivity/connectivity_macos/CHANGELOG.md
deleted file mode 100644
index c34dc60..0000000
--- a/connectivity/connectivity_macos/CHANGELOG.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## 0.0.2+1
-
-* Add CHANGELOG.
-
-## 0.0.1
-
-* Initial open source release.
\ No newline at end of file
diff --git a/connectivity/connectivity_macos/README.md b/connectivity/connectivity_macos/README.md
deleted file mode 100644
index ee34d1d..0000000
--- a/connectivity/connectivity_macos/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# connectivity_macos
-
-The macos implementation of [`connectivity`].
-
-## Usage
-
-### Import the package
-
-To use this plugin in your Flutter Web app, simply add it as a dependency in
-your `pubspec.yaml` alongside the base `connectivity` plugin.
-
-_(This is only temporary: in the future we hope to make this package an
-"endorsed" implementation of `connectivity`, so that it is automatically
-included in your Flutter macos app when you depend on `package:connectivity_macos`.)_
-
-This is what the above means to your `pubspec.yaml`:
-
-```yaml
-...
-dependencies:
-  ...
-  connectivity: ^0.4.6
-  connectivity_macos: ^0.0.1
-  ...
-```
-
-### Use the plugin
-
-Once you have the `connectivity_macos` dependency in your pubspec, you should
-be able to use `package:connectivity` as normal.
diff --git a/connectivity/example/lib/main.dart b/connectivity/example/lib/main.dart
index 0d9c282..4ad3097 100644
--- a/connectivity/example/lib/main.dart
+++ b/connectivity/example/lib/main.dart
@@ -15,7 +15,7 @@
 // Sets a platform override for desktop to avoid exceptions. See
 // https://flutter.dev/desktop#target-platform-override for more info.
 void _enablePlatformOverrideForDesktop() {
-  if (!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux)) {
+  if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) {
     debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
   }
 }
diff --git a/connectivity/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/connectivity/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..21a3cc1
--- /dev/null
+++ b/connectivity/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/connectivity/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/connectivity/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/connectivity/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>
diff --git a/connectivity/example/pubspec.yaml b/connectivity/example/pubspec.yaml
index c4c58a1..a16e604 100644
--- a/connectivity/example/pubspec.yaml
+++ b/connectivity/example/pubspec.yaml
@@ -6,14 +6,13 @@
     sdk: flutter
   connectivity:
     path: ../
-  connectivity_macos:
-    path: ../connectivity_macos
 
 dev_dependencies:
   flutter_driver:
     sdk: flutter
   test: any
   e2e: ^0.2.0
+  pedantic: ^1.8.0
 
 flutter:
   uses-material-design: true
diff --git a/connectivity/example/test_driver/test/connectivity_e2e.dart b/connectivity/example/test_driver/test/connectivity_e2e.dart
new file mode 100644
index 0000000..10c4bda
--- /dev/null
+++ b/connectivity/example/test_driver/test/connectivity_e2e.dart
@@ -0,0 +1,41 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+import 'package:e2e/e2e.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:connectivity/connectivity.dart';
+
+void main() {
+  E2EWidgetsFlutterBinding.ensureInitialized();
+
+  group('Connectivity test driver', () {
+    Connectivity _connectivity;
+
+    setUpAll(() async {
+      _connectivity = Connectivity();
+    });
+
+    testWidgets('test connectivity result', (WidgetTester tester) async {
+      final ConnectivityResult result = await _connectivity.checkConnectivity();
+      expect(result, isNotNull);
+      switch (result) {
+        case ConnectivityResult.wifi:
+          expect(_connectivity.getWifiName(), completes);
+          expect(_connectivity.getWifiBSSID(), completes);
+          expect((await _connectivity.getWifiIP()), isNotNull);
+          break;
+        default:
+          break;
+      }
+    });
+
+    testWidgets('test location methods, iOS only', (WidgetTester tester) async {
+      if (Platform.isIOS) {
+        expect((await _connectivity.getLocationServiceAuthorization()),
+            LocationAuthorizationStatus.notDetermined);
+      }
+    });
+  });
+}
diff --git a/connectivity/lib/connectivity.dart b/connectivity/lib/connectivity.dart
index ad9fae3..a5d9f25 100644
--- a/connectivity/lib/connectivity.dart
+++ b/connectivity/lib/connectivity.dart
@@ -3,22 +3,13 @@
 // found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:io';
 
 import 'package:flutter/services.dart';
-import 'package:meta/meta.dart';
+import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
 
-/// Connection status check result.
-enum ConnectivityResult {
-  /// WiFi: Device connected via Wi-Fi
-  wifi,
-
-  /// Mobile: Device connected to cellular network
-  mobile,
-
-  /// None: Device not connected to any network
-  none
-}
+// Export enums from the platform_interface so plugin users can use them directly.
+export 'package:connectivity_platform_interface/connectivity_platform_interface.dart'
+    show ConnectivityResult, LocationAuthorizationStatus;
 
 /// Discover network connectivity configurations: Distinguish between WI-FI and cellular, check WI-FI status and more.
 class Connectivity {
@@ -27,7 +18,7 @@
   /// [Connectivity] is designed to work as a singleton.
   // When a second instance is created, the first instance will not be able to listen to the
   // EventChannel because it is overridden. Forcing the class to be a singleton class can prevent
-  // misusage of creating a second instance from a programmer.
+  // misuse of creating a second instance from a programmer.
   factory Connectivity() {
     if (_singleton == null) {
       _singleton = Connectivity._();
@@ -39,28 +30,11 @@
 
   static Connectivity _singleton;
 
-  Stream<ConnectivityResult> _onConnectivityChanged;
-
-  /// Exposed for testing purposes and should not be used by users of the plugin.
-  @visibleForTesting
-  static const MethodChannel methodChannel = MethodChannel(
-    'plugins.flutter.io/connectivity',
-  );
-
-  /// Exposed for testing purposes and should not be used by users of the plugin.
-  @visibleForTesting
-  static const EventChannel eventChannel = EventChannel(
-    'plugins.flutter.io/connectivity_status',
-  );
+  static ConnectivityPlatform get _platform => ConnectivityPlatform.instance;
 
   /// Fires whenever the connectivity state changes.
   Stream<ConnectivityResult> get onConnectivityChanged {
-    if (_onConnectivityChanged == null) {
-      _onConnectivityChanged = eventChannel
-          .receiveBroadcastStream()
-          .map((dynamic event) => _parseConnectivityResult(event));
-    }
-    return _onConnectivityChanged;
+    return _platform.onConnectivityChanged;
   }
 
   /// Checks the connection status of the device.
@@ -69,9 +43,8 @@
   /// make a network request. It only gives you the radio status.
   ///
   /// Instead listen for connectivity changes via [onConnectivityChanged] stream.
-  Future<ConnectivityResult> checkConnectivity() async {
-    final String result = await methodChannel.invokeMethod<String>('check');
-    return _parseConnectivityResult(result);
+  Future<ConnectivityResult> checkConnectivity() {
+    return _platform.checkConnectivity();
   }
 
   /// Obtains the wifi name (SSID) of the connected network
@@ -80,12 +53,8 @@
   ///
   /// From android 8.0 onwards the GPS must be ON (high accuracy)
   /// in order to be able to obtain the SSID.
-  Future<String> getWifiName() async {
-    String wifiName = await methodChannel.invokeMethod<String>('wifiName');
-    // as Android might return <unknown ssid>, uniforming result
-    // our iOS implementation will return null
-    if (wifiName == '<unknown ssid>') wifiName = null;
-    return wifiName;
+  Future<String> getWifiName() {
+    return _platform.getWifiName();
   }
 
   /// Obtains the wifi BSSID of the connected network.
@@ -94,13 +63,13 @@
   ///
   /// From Android 8.0 onwards the GPS must be ON (high accuracy)
   /// in order to be able to obtain the BSSID.
-  Future<String> getWifiBSSID() async {
-    return await methodChannel.invokeMethod<String>('wifiBSSID');
+  Future<String> getWifiBSSID() {
+    return _platform.getWifiBSSID();
   }
 
   /// Obtains the IP address of the connected wifi network
-  Future<String> getWifiIP() async {
-    return await methodChannel.invokeMethod<String>('wifiIPAddress');
+  Future<String> getWifiIP() {
+    return _platform.getWifiIP();
   }
 
   /// Request to authorize the location service (Only on iOS).
@@ -151,14 +120,12 @@
   /// Ideally, a location service authorization should only be requested if the current authorization status is not determined.
   ///
   /// See also [getLocationServiceAuthorization] to obtain current location service status.
-  Future<LocationAuthorizationStatus> requestLocationServiceAuthorization(
-      {bool requestAlwaysLocationUsage = false}) async {
-    //Just `assert(Platform.isIOS)` will prevent us from doing dart side unit testing.
-    assert(!Platform.isAndroid);
-    final String result = await methodChannel.invokeMethod<String>(
-        'requestLocationServiceAuthorization',
-        <bool>[requestAlwaysLocationUsage]);
-    return _convertLocationStatusString(result);
+  Future<LocationAuthorizationStatus> requestLocationServiceAuthorization({
+    bool requestAlwaysLocationUsage = false,
+  }) {
+    return _platform.requestLocationServiceAuthorization(
+      requestAlwaysLocationUsage: requestAlwaysLocationUsage,
+    );
   }
 
   /// Get the current location service authorization (Only on iOS).
@@ -197,61 +164,7 @@
   /// ```
   ///
   /// See also [requestLocationServiceAuthorization] for requesting a location service authorization.
-  Future<LocationAuthorizationStatus> getLocationServiceAuthorization() async {
-    //Just `assert(Platform.isIOS)` will prevent us from doing dart side unit testing.
-    assert(!Platform.isAndroid);
-    final String result = await methodChannel
-        .invokeMethod<String>('getLocationServiceAuthorization');
-    return _convertLocationStatusString(result);
+  Future<LocationAuthorizationStatus> getLocationServiceAuthorization() {
+    return _platform.getLocationServiceAuthorization();
   }
-
-  LocationAuthorizationStatus _convertLocationStatusString(String result) {
-    switch (result) {
-      case 'notDetermined':
-        return LocationAuthorizationStatus.notDetermined;
-      case 'restricted':
-        return LocationAuthorizationStatus.restricted;
-      case 'denied':
-        return LocationAuthorizationStatus.denied;
-      case 'authorizedAlways':
-        return LocationAuthorizationStatus.authorizedAlways;
-      case 'authorizedWhenInUse':
-        return LocationAuthorizationStatus.authorizedWhenInUse;
-      default:
-        return LocationAuthorizationStatus.unknown;
-    }
-  }
-}
-
-ConnectivityResult _parseConnectivityResult(String state) {
-  switch (state) {
-    case 'wifi':
-      return ConnectivityResult.wifi;
-    case 'mobile':
-      return ConnectivityResult.mobile;
-    case 'none':
-    default:
-      return ConnectivityResult.none;
-  }
-}
-
-/// The status of the location service authorization.
-enum LocationAuthorizationStatus {
-  /// The authorization of the location service is not determined.
-  notDetermined,
-
-  /// This app is not authorized to use location.
-  restricted,
-
-  /// User explicitly denied the location service.
-  denied,
-
-  /// User authorized the app to access the location at any time.
-  authorizedAlways,
-
-  /// User authorized the app to access the location when the app is visible to them.
-  authorizedWhenInUse,
-
-  /// Status unknown.
-  unknown
 }
diff --git a/connectivity/macos/connectivity.podspec b/connectivity/macos/connectivity.podspec
new file mode 100644
index 0000000..ea544df
--- /dev/null
+++ b/connectivity/macos/connectivity.podspec
@@ -0,0 +1,22 @@
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
+#
+Pod::Spec.new do |s|
+  s.name             = 'connectivity'
+  s.version          = '0.0.1'
+  s.summary          = 'No-op implementation of the macos connectivity to avoid build issues on macos'
+  s.description      = <<-DESC
+  No-op implementation of the connectivity plugin to avoid build issues on macos.
+  https://github.com/flutter/flutter/issues/46618
+                       DESC
+  s.homepage         = 'https://github.com/flutter/plugins/tree/master/packages/connectivity'
+  s.license          = { :file => '../LICENSE' }
+  s.author           = { 'Flutter Team' => 'flutter-dev@googlegroups.com' }
+  s.source           = { :path => '.' }
+  s.source_files = 'Classes/**/*'
+  s.public_header_files = 'Classes/**/*.h'
+
+  s.platform = :osx
+  s.osx.deployment_target = '10.11'
+end
+
diff --git a/connectivity/pubspec.yaml b/connectivity/pubspec.yaml
index 91ba068..ce90f75 100644
--- a/connectivity/pubspec.yaml
+++ b/connectivity/pubspec.yaml
@@ -1,8 +1,8 @@
 name: connectivity
 description: Flutter plugin for discovering the state of the network (WiFi &
   mobile/cellular) connectivity on Android and iOS.
-homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity
-version: 0.4.6+2
+homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity
+version: 0.4.8+1
 
 flutter:
   plugin:
@@ -12,11 +12,15 @@
         pluginClass: ConnectivityPlugin
       ios:
         pluginClass: FLTConnectivityPlugin
+      macos:
+        default_package: connectivity_macos
 
 dependencies:
   flutter:
     sdk: flutter
   meta: "^1.0.5"
+  connectivity_platform_interface: ^1.0.2
+  connectivity_macos: ^0.1.0
 
 dev_dependencies:
   flutter_test:
@@ -25,6 +29,9 @@
     sdk: flutter
   test: any
   e2e: ^0.2.0
+  mockito: ^4.1.1
+  plugin_platform_interface: ^1.0.0
+  pedantic: ^1.8.0
 
 environment:
   sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/connectivity_macos/BUILD.gn b/connectivity_macos/BUILD.gn
new file mode 100644
index 0000000..07cb715
--- /dev/null
+++ b/connectivity_macos/BUILD.gn
@@ -0,0 +1,17 @@
+# This file is generated by importer.py for connectivity_macos-0.1.0+1
+
+import("//build/dart/dart_library.gni")
+
+dart_library("connectivity_macos") {
+  package_name = "connectivity_macos"
+
+  # This parameter is left empty as we don't care about analysis or exporting
+  # these sources outside of the tree.
+  sources = []
+
+  disable_analysis = true
+
+  deps = [
+    "//third_party/dart-pkg/git/flutter/packages/flutter",
+  ]
+}
diff --git a/connectivity_macos/CHANGELOG.md b/connectivity_macos/CHANGELOG.md
new file mode 100644
index 0000000..43db2ff
--- /dev/null
+++ b/connectivity_macos/CHANGELOG.md
@@ -0,0 +1,16 @@
+## 0.1.0+1
+
+* Make the pedantic dev_dependency explicit.
+
+## 0.1.0
+
+* Adds an example app to trigger CI tests. Bumped the MINOR version to
+avoid compatibility issues once this packages is endorsed.
+
+## 0.0.2+1
+
+* Add CHANGELOG.
+
+## 0.0.1
+
+* Initial open source release.
\ No newline at end of file
diff --git a/connectivity/connectivity_macos/LICENSE b/connectivity_macos/LICENSE
similarity index 100%
rename from connectivity/connectivity_macos/LICENSE
rename to connectivity_macos/LICENSE
diff --git a/connectivity_macos/README.md b/connectivity_macos/README.md
new file mode 100644
index 0000000..d63803a
--- /dev/null
+++ b/connectivity_macos/README.md
@@ -0,0 +1,25 @@
+# connectivity_macos
+
+The macos implementation of [`connectivity`].
+
+## Usage
+
+### Import the package
+
+
+This package has been endorsed, meaning that you only need to add `connectivity`
+as a dependency in your `pubspec.yaml`. It will be automatically included in your app
+when you depend on `package:connectivity`.
+
+This is what the above means to your `pubspec.yaml`:
+
+```yaml
+...
+dependencies:
+  ...
+  connectivity: ^0.4.8
+  ...
+```
+
+Refer to the `connectivity` [documentation](https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity) for more details.
+
diff --git a/connectivity/connectivity_macos/android/README.md b/connectivity_macos/android/README.md
similarity index 100%
rename from connectivity/connectivity_macos/android/README.md
rename to connectivity_macos/android/README.md
diff --git a/connectivity/connectivity_macos/android/build.gradle b/connectivity_macos/android/build.gradle
similarity index 100%
rename from connectivity/connectivity_macos/android/build.gradle
rename to connectivity_macos/android/build.gradle
diff --git a/connectivity/connectivity_macos/android/gradle.properties b/connectivity_macos/android/gradle.properties
similarity index 100%
rename from connectivity/connectivity_macos/android/gradle.properties
rename to connectivity_macos/android/gradle.properties
diff --git a/connectivity/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties b/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
rename from connectivity/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties
rename to connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties
diff --git a/connectivity/connectivity_macos/android/settings.gradle b/connectivity_macos/android/settings.gradle
similarity index 100%
rename from connectivity/connectivity_macos/android/settings.gradle
rename to connectivity_macos/android/settings.gradle
diff --git a/connectivity/connectivity_macos/android/src/main/AndroidManifest.xml b/connectivity_macos/android/src/main/AndroidManifest.xml
similarity index 100%
rename from connectivity/connectivity_macos/android/src/main/AndroidManifest.xml
rename to connectivity_macos/android/src/main/AndroidManifest.xml
diff --git a/connectivity/connectivity_macos/android/src/main/java/com/example/connectivity/ConnectivityPlugin.java b/connectivity_macos/android/src/main/java/com/example/connectivity/ConnectivityPlugin.java
similarity index 100%
rename from connectivity/connectivity_macos/android/src/main/java/com/example/connectivity/ConnectivityPlugin.java
rename to connectivity_macos/android/src/main/java/com/example/connectivity/ConnectivityPlugin.java
diff --git a/connectivity_macos/example/android/app/build.gradle b/connectivity_macos/example/android/app/build.gradle
new file mode 100644
index 0000000..5d1f138
--- /dev/null
+++ b/connectivity_macos/example/android/app/build.gradle
@@ -0,0 +1,58 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+    localPropertiesFile.withReader('UTF-8') { reader ->
+        localProperties.load(reader)
+    }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+    flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+    flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+    compileSdkVersion 28
+
+    lintOptions {
+        disable 'InvalidPackage'
+    }
+
+    defaultConfig {
+        applicationId "io.flutter.plugins.connectivityexample"
+        minSdkVersion 16
+        targetSdkVersion 28
+        versionCode flutterVersionCode.toInteger()
+        versionName flutterVersionName
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+    }
+
+    buildTypes {
+        release {
+            signingConfig signingConfigs.debug
+        }
+    }
+}
+
+flutter {
+    source '../..'
+}
+
+dependencies {
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'androidx.test:runner:1.1.1'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+}
diff --git a/connectivity_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties b/connectivity_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..9a4163a
--- /dev/null
+++ b/connectivity_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/connectivity_macos/example/android/app/src/main/AndroidManifest.xml b/connectivity_macos/example/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..3bf2ca0
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="io.flutter.plugins.connectivityexample">
+
+    <uses-permission android:name="android.permission.INTERNET"/>
+
+    <application android:name="io.flutter.app.FlutterApplication" android:label="connectivity_example" android:icon="@mipmap/ic_launcher">
+        <activity android:name=".EmbeddingV1Activity"
+            android:launchMode="singleTop"
+            android:theme="@android:style/Theme.Black.NoTitleBar"
+            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
+            android:hardwareAccelerated="true"
+            android:exported="true"
+            android:windowSoftInputMode="adjustResize">
+        </activity>
+        <activity android:name=".MainActivity"
+            android:theme="@android:style/Theme.Black.NoTitleBar"
+            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
+            android:hardwareAccelerated="true"
+            android:windowSoftInputMode="adjustResize">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java
new file mode 100644
index 0000000..587b623
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.connectivityexample;
+
+import android.os.Bundle;
+import io.flutter.app.FlutterActivity;
+import io.flutter.plugins.GeneratedPluginRegistrant;
+
+public class EmbeddingV1Activity extends FlutterActivity {
+  @Override
+  protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    GeneratedPluginRegistrant.registerWith(this);
+  }
+}
diff --git a/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java
new file mode 100644
index 0000000..a347553
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java
@@ -0,0 +1,17 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.connectivityexample;
+
+import androidx.test.rule.ActivityTestRule;
+import dev.flutter.plugins.e2e.FlutterRunner;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+
+@RunWith(FlutterRunner.class)
+public class EmbeddingV1ActivityTest {
+  @Rule
+  public ActivityTestRule<EmbeddingV1Activity> rule =
+      new ActivityTestRule<>(EmbeddingV1Activity.class);
+}
diff --git a/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivity.java b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivity.java
new file mode 100644
index 0000000..b0deb61
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivity.java
@@ -0,0 +1,18 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.connectivityexample;
+
+import io.flutter.embedding.android.FlutterActivity;
+import io.flutter.embedding.engine.FlutterEngine;
+import io.flutter.plugins.connectivity.ConnectivityPlugin;
+
+public class MainActivity extends FlutterActivity {
+
+  @Override
+  public void configureFlutterEngine(FlutterEngine flutterEngine) {
+    super.configureFlutterEngine(flutterEngine);
+    flutterEngine.getPlugins().add(new ConnectivityPlugin());
+  }
+}
diff --git a/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivityTest.java b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivityTest.java
new file mode 100644
index 0000000..0c33d6a
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivityTest.java
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.connectivityexample;
+
+import androidx.test.rule.ActivityTestRule;
+import dev.flutter.plugins.e2e.FlutterRunner;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+
+@RunWith(FlutterRunner.class)
+public class MainActivityTest {
+  @Rule public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class);
+}
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..db77bb4
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..17987b7
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..09d4391
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d5f1c8d
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4d6372e
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/build.gradle b/connectivity_macos/example/android/build.gradle
new file mode 100644
index 0000000..541636c
--- /dev/null
+++ b/connectivity_macos/example/android/build.gradle
@@ -0,0 +1,29 @@
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.3.0'
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+    project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+    project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}
diff --git a/connectivity_macos/example/android/gradle.properties b/connectivity_macos/example/android/gradle.properties
new file mode 100644
index 0000000..a673820
--- /dev/null
+++ b/connectivity_macos/example/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
+android.enableR8=true
diff --git a/connectivity/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties b/connectivity_macos/example/android/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
copy from connectivity/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties
copy to connectivity_macos/example/android/gradle/wrapper/gradle-wrapper.properties
diff --git a/connectivity_macos/example/android/settings.gradle b/connectivity_macos/example/android/settings.gradle
new file mode 100644
index 0000000..a159ea7
--- /dev/null
+++ b/connectivity_macos/example/android/settings.gradle
@@ -0,0 +1,15 @@
+include ':app'
+
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+
+def plugins = new Properties()
+def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
+if (pluginsFile.exists()) {
+    pluginsFile.withInputStream { stream -> plugins.load(stream) }
+}
+
+plugins.each { name, path ->
+    def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
+        include ":$name"
+        project(":$name").projectDir = pluginDirectory
+}
diff --git a/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist b/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 0000000..6c2de80
--- /dev/null
+++ b/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>en</string>
+  <key>CFBundleExecutable</key>
+  <string>App</string>
+  <key>CFBundleIdentifier</key>
+  <string>io.flutter.flutter.app</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>App</string>
+  <key>CFBundlePackageType</key>
+  <string>FMWK</string>
+  <key>CFBundleShortVersionString</key>
+  <string>1.0</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>CFBundleVersion</key>
+  <string>1.0</string>
+  <key>UIRequiredDeviceCapabilities</key>
+  <array>
+    <string>arm64</string>
+  </array>
+  <key>MinimumOSVersion</key>
+  <string>8.0</string>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/ios/Flutter/Debug.xcconfig b/connectivity_macos/example/ios/Flutter/Debug.xcconfig
new file mode 100644
index 0000000..e8efba1
--- /dev/null
+++ b/connectivity_macos/example/ios/Flutter/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"
diff --git a/connectivity_macos/example/ios/Flutter/Release.xcconfig b/connectivity_macos/example/ios/Flutter/Release.xcconfig
new file mode 100644
index 0000000..399e934
--- /dev/null
+++ b/connectivity_macos/example/ios/Flutter/Release.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"
diff --git a/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj b/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..e497d09
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,490 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+		3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
+		3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
+		9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
+		97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
+		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+		97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+		97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+		EB0BA966000B5C35B13186D7 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C80D49AFD183103034E444C2 /* libPods-Runner.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+				3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
+				9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
+			);
+			name = "Embed Frameworks";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
+		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
+		3173C764DD180BE02EB51E47 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
+		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
+		3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
+		69D903F0A9A7C636EE803AF8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
+		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
+		7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+		7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
+		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
+		9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
+		97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		C80D49AFD183103034E444C2 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		97C146EB1CF9000F007C117D /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
+				3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
+				EB0BA966000B5C35B13186D7 /* libPods-Runner.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		89F516DEFCBF79E39D2885C2 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				C80D49AFD183103034E444C2 /* libPods-Runner.a */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		8ECC1C323F60D5498EEC2315 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				69D903F0A9A7C636EE803AF8 /* Pods-Runner.debug.xcconfig */,
+				3173C764DD180BE02EB51E47 /* Pods-Runner.release.xcconfig */,
+			);
+			name = Pods;
+			sourceTree = "<group>";
+		};
+		9740EEB11CF90186004384FC /* Flutter */ = {
+			isa = PBXGroup;
+			children = (
+				3B80C3931E831B6300D905FE /* App.framework */,
+				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+				9740EEBA1CF902C7004384FC /* Flutter.framework */,
+				9740EEB21CF90195004384FC /* Debug.xcconfig */,
+				7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+				9740EEB31CF90195004384FC /* Generated.xcconfig */,
+			);
+			name = Flutter;
+			sourceTree = "<group>";
+		};
+		97C146E51CF9000F007C117D = {
+			isa = PBXGroup;
+			children = (
+				9740EEB11CF90186004384FC /* Flutter */,
+				97C146F01CF9000F007C117D /* Runner */,
+				97C146EF1CF9000F007C117D /* Products */,
+				8ECC1C323F60D5498EEC2315 /* Pods */,
+				89F516DEFCBF79E39D2885C2 /* Frameworks */,
+			);
+			sourceTree = "<group>";
+		};
+		97C146EF1CF9000F007C117D /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				97C146EE1CF9000F007C117D /* Runner.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		97C146F01CF9000F007C117D /* Runner */ = {
+			isa = PBXGroup;
+			children = (
+				7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
+				7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
+				97C146FA1CF9000F007C117D /* Main.storyboard */,
+				97C146FD1CF9000F007C117D /* Assets.xcassets */,
+				97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+				97C147021CF9000F007C117D /* Info.plist */,
+				97C146F11CF9000F007C117D /* Supporting Files */,
+				1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+				1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+			);
+			path = Runner;
+			sourceTree = "<group>";
+		};
+		97C146F11CF9000F007C117D /* Supporting Files */ = {
+			isa = PBXGroup;
+			children = (
+				97C146F21CF9000F007C117D /* main.m */,
+			);
+			name = "Supporting Files";
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		97C146ED1CF9000F007C117D /* Runner */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+			buildPhases = (
+				3BAF367E8BACBC7576CEE653 /* [CP] Check Pods Manifest.lock */,
+				9740EEB61CF901F6004384FC /* Run Script */,
+				97C146EA1CF9000F007C117D /* Sources */,
+				97C146EB1CF9000F007C117D /* Frameworks */,
+				97C146EC1CF9000F007C117D /* Resources */,
+				9705A1C41CF9048500538489 /* Embed Frameworks */,
+				3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+				6A2F146AD353BE7A0C3E797E /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Runner;
+			productName = Runner;
+			productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		97C146E61CF9000F007C117D /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 1100;
+				ORGANIZATIONNAME = "The Chromium Authors";
+				TargetAttributes = {
+					97C146ED1CF9000F007C117D = {
+						CreatedOnToolsVersion = 7.3.1;
+					};
+				};
+			};
+			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 97C146E51CF9000F007C117D;
+			productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				97C146ED1CF9000F007C117D /* Runner */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		97C146EC1CF9000F007C117D /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+				3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+				97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+				97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Thin Binary";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
+		};
+		3BAF367E8BACBC7576CEE653 /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		6A2F146AD353BE7A0C3E797E /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		9740EEB61CF901F6004384FC /* Run Script */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Run Script";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		97C146EA1CF9000F007C117D /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
+				97C146F31CF9000F007C117D /* main.m in Sources */,
+				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				97C146FB1CF9000F007C117D /* Base */,
+			);
+			name = Main.storyboard;
+			sourceTree = "<group>";
+		};
+		97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				97C147001CF9000F007C117D /* Base */,
+			);
+			name = LaunchScreen.storyboard;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		97C147031CF9000F007C117D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		97C147041CF9000F007C117D /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		97C147061CF9000F007C117D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				ENABLE_BITCODE = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Flutter",
+				);
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Flutter",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		97C147071CF9000F007C117D /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				ENABLE_BITCODE = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Flutter",
+				);
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Flutter",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				97C147031CF9000F007C117D /* Debug */,
+				97C147041CF9000F007C117D /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				97C147061CF9000F007C117D /* Debug */,
+				97C147071CF9000F007C117D /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..3bb3697
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1100"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+               BuildableName = "Runner.app"
+               BlueprintName = "Runner"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..21a3cc1
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..949b678
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildSystemType</key>
+	<string>Original</string>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/ios/Runner/AppDelegate.h b/connectivity_macos/example/ios/Runner/AppDelegate.h
new file mode 100644
index 0000000..d9e18e9
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/AppDelegate.h
@@ -0,0 +1,10 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Flutter/Flutter.h>
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : FlutterAppDelegate
+
+@end
diff --git a/connectivity_macos/example/ios/Runner/AppDelegate.m b/connectivity_macos/example/ios/Runner/AppDelegate.m
new file mode 100644
index 0000000..f086757
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/AppDelegate.m
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "AppDelegate.h"
+#include "GeneratedPluginRegistrant.h"
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application
+    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+  [GeneratedPluginRegistrant registerWithRegistry:self];
+  // Override point for customization after application launch.
+  return [super application:application didFinishLaunchingWithOptions:launchOptions];
+}
+
+@end
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d22f10b
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,116 @@
+{
+  "images" : [
+    {
+      "size" : "20x20",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-20x20@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-20x20@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-40x40@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-40x40@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-60x60@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-60x60@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-20x20@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-20x20@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-29x29@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-29x29@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-40x40@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-40x40@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "76x76",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-76x76@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "76x76",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-76x76@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "83.5x83.5",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-83.5x83.5@2x.png",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 0000000..28c6bf0
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 0000000..2ccbfd9
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 0000000..f091b6b
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 0000000..4cde121
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 0000000..d0ef06e
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 0000000..dcdc230
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 0000000..2ccbfd9
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 0000000..c8f9ed8
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 0000000..a6d6b86
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 0000000..a6d6b86
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 0000000..75b2d16
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 0000000..c4df70d
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 0000000..6a84f41
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 0000000..d0e1f58
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/connectivity_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..ebf48f6
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="EHf-IW-A2E">
+            <objects>
+                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
+                        <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="53" y="375"/>
+        </scene>
+    </scenes>
+</document>
diff --git a/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard b/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..f3c2851
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+    </dependencies>
+    <scenes>
+        <!--Flutter View Controller-->
+        <scene sceneID="tne-QT-ifu">
+            <objects>
+                <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+    </scenes>
+</document>
diff --git a/connectivity_macos/example/ios/Runner/Info.plist b/connectivity_macos/example/ios/Runner/Info.plist
new file mode 100644
index 0000000..babbd80
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Info.plist
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>connectivity_example</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+	<string>This app requires accessing your location information all the time to get wi-fi information.</string>
+	<key>NSLocationWhenInUseUsageDescription</key>
+	<string>This app requires accessing your location information when the app is in foreground to get wi-fi information.</string>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIMainStoryboardFile</key>
+	<string>Main</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>arm64</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<false/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/ios/Runner/Runner.entitlements b/connectivity_macos/example/ios/Runner/Runner.entitlements
new file mode 100644
index 0000000..ba21fbd
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Runner.entitlements
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.developer.networking.wifi-info</key>
+	<true/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/ios/Runner/main.m b/connectivity_macos/example/ios/Runner/main.m
new file mode 100644
index 0000000..bec320c
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/main.m
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Flutter/Flutter.h>
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char* argv[]) {
+  @autoreleasepool {
+    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+  }
+}
diff --git a/connectivity_macos/example/lib/main.dart b/connectivity_macos/example/lib/main.dart
new file mode 100644
index 0000000..4ad3097
--- /dev/null
+++ b/connectivity_macos/example/lib/main.dart
@@ -0,0 +1,172 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ignore_for_file: public_member_api_docs
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:connectivity/connectivity.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+// Sets a platform override for desktop to avoid exceptions. See
+// https://flutter.dev/desktop#target-platform-override for more info.
+void _enablePlatformOverrideForDesktop() {
+  if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) {
+    debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
+  }
+}
+
+void main() {
+  _enablePlatformOverrideForDesktop();
+  runApp(MyApp());
+}
+
+class MyApp extends StatelessWidget {
+  // This widget is the root of your application.
+  @override
+  Widget build(BuildContext context) {
+    return MaterialApp(
+      title: 'Flutter Demo',
+      theme: ThemeData(
+        primarySwatch: Colors.blue,
+      ),
+      home: MyHomePage(title: 'Flutter Demo Home Page'),
+    );
+  }
+}
+
+class MyHomePage extends StatefulWidget {
+  MyHomePage({Key key, this.title}) : super(key: key);
+
+  final String title;
+
+  @override
+  _MyHomePageState createState() => _MyHomePageState();
+}
+
+class _MyHomePageState extends State<MyHomePage> {
+  String _connectionStatus = 'Unknown';
+  final Connectivity _connectivity = Connectivity();
+  StreamSubscription<ConnectivityResult> _connectivitySubscription;
+
+  @override
+  void initState() {
+    super.initState();
+    initConnectivity();
+    _connectivitySubscription =
+        _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
+  }
+
+  @override
+  void dispose() {
+    _connectivitySubscription.cancel();
+    super.dispose();
+  }
+
+  // Platform messages are asynchronous, so we initialize in an async method.
+  Future<void> initConnectivity() async {
+    ConnectivityResult result;
+    // Platform messages may fail, so we use a try/catch PlatformException.
+    try {
+      result = await _connectivity.checkConnectivity();
+    } on PlatformException catch (e) {
+      print(e.toString());
+    }
+
+    // If the widget was removed from the tree while the asynchronous platform
+    // message was in flight, we want to discard the reply rather than calling
+    // setState to update our non-existent appearance.
+    if (!mounted) {
+      return Future.value(null);
+    }
+
+    return _updateConnectionStatus(result);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Plugin example app'),
+      ),
+      body: Center(child: Text('Connection Status: $_connectionStatus')),
+    );
+  }
+
+  Future<void> _updateConnectionStatus(ConnectivityResult result) async {
+    switch (result) {
+      case ConnectivityResult.wifi:
+        String wifiName, wifiBSSID, wifiIP;
+
+        try {
+          if (Platform.isIOS) {
+            LocationAuthorizationStatus status =
+                await _connectivity.getLocationServiceAuthorization();
+            if (status == LocationAuthorizationStatus.notDetermined) {
+              status =
+                  await _connectivity.requestLocationServiceAuthorization();
+            }
+            if (status == LocationAuthorizationStatus.authorizedAlways ||
+                status == LocationAuthorizationStatus.authorizedWhenInUse) {
+              wifiName = await _connectivity.getWifiName();
+            } else {
+              wifiName = await _connectivity.getWifiName();
+            }
+          } else {
+            wifiName = await _connectivity.getWifiName();
+          }
+        } on PlatformException catch (e) {
+          print(e.toString());
+          wifiName = "Failed to get Wifi Name";
+        }
+
+        try {
+          if (Platform.isIOS) {
+            LocationAuthorizationStatus status =
+                await _connectivity.getLocationServiceAuthorization();
+            if (status == LocationAuthorizationStatus.notDetermined) {
+              status =
+                  await _connectivity.requestLocationServiceAuthorization();
+            }
+            if (status == LocationAuthorizationStatus.authorizedAlways ||
+                status == LocationAuthorizationStatus.authorizedWhenInUse) {
+              wifiBSSID = await _connectivity.getWifiBSSID();
+            } else {
+              wifiBSSID = await _connectivity.getWifiBSSID();
+            }
+          } else {
+            wifiBSSID = await _connectivity.getWifiBSSID();
+          }
+        } on PlatformException catch (e) {
+          print(e.toString());
+          wifiBSSID = "Failed to get Wifi BSSID";
+        }
+
+        try {
+          wifiIP = await _connectivity.getWifiIP();
+        } on PlatformException catch (e) {
+          print(e.toString());
+          wifiIP = "Failed to get Wifi IP";
+        }
+
+        setState(() {
+          _connectionStatus = '$result\n'
+              'Wifi Name: $wifiName\n'
+              'Wifi BSSID: $wifiBSSID\n'
+              'Wifi IP: $wifiIP\n';
+        });
+        break;
+      case ConnectivityResult.mobile:
+      case ConnectivityResult.none:
+        setState(() => _connectionStatus = result.toString());
+        break;
+      default:
+        setState(() => _connectionStatus = 'Failed to get connectivity.');
+        break;
+    }
+  }
+}
diff --git a/connectivity_macos/example/macos/Flutter/Flutter-Debug.xcconfig b/connectivity_macos/example/macos/Flutter/Flutter-Debug.xcconfig
new file mode 100644
index 0000000..785633d
--- /dev/null
+++ b/connectivity_macos/example/macos/Flutter/Flutter-Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/connectivity_macos/example/macos/Flutter/Flutter-Release.xcconfig b/connectivity_macos/example/macos/Flutter/Flutter-Release.xcconfig
new file mode 100644
index 0000000..5fba960
--- /dev/null
+++ b/connectivity_macos/example/macos/Flutter/Flutter-Release.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/connectivity_macos/example/macos/Runner.xcodeproj/project.pbxproj b/connectivity_macos/example/macos/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..0e24134
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,654 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 51;
+	objects = {
+
+/* Begin PBXAggregateTarget section */
+		33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
+			buildPhases = (
+				33CC111E2044C6BF0003C045 /* ShellScript */,
+			);
+			dependencies = (
+			);
+			name = "Flutter Assemble";
+			productName = FLX;
+		};
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+		335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
+		33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
+		33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
+		33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
+		33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
+		33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; };
+		33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; };
+		D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		EA473EC5F2038B17A2FE4D78 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 748ADDF1719804343BB18004 /* Pods_Runner.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 33CC111A2044C6BA0003C045;
+			remoteInfo = FLX;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		33CC110E2044A8840003C045 /* Bundle Framework */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+				D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */,
+				33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */,
+			);
+			name = "Bundle Framework";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
+		335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
+		33CC10ED2044A3C60003C045 /* connectivity_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = connectivity_example.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+		33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
+		33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
+		33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
+		33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
+		33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
+		33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
+		33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
+		33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; };
+		33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
+		33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
+		33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
+		748ADDF1719804343BB18004 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
+		80418F0A2F74D683C63A4D0A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
+		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
+		AA19B00394637215A825CF5E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
+		D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; };
+		E960ED3977AF6DF197F74FFA /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		33CC10EA2044A3C60003C045 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D73912F022F37F9E000D13A0 /* App.framework in Frameworks */,
+				33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */,
+				EA473EC5F2038B17A2FE4D78 /* Pods_Runner.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		33BA886A226E78AF003329D5 /* Configs */ = {
+			isa = PBXGroup;
+			children = (
+				33E5194F232828860026EE4D /* AppInfo.xcconfig */,
+				9740EEB21CF90195004384FC /* Debug.xcconfig */,
+				7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+				333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
+			);
+			path = Configs;
+			sourceTree = "<group>";
+		};
+		33CC10E42044A3C60003C045 = {
+			isa = PBXGroup;
+			children = (
+				33FAB671232836740065AC1E /* Runner */,
+				33CEB47122A05771004F2AC0 /* Flutter */,
+				33CC10EE2044A3C60003C045 /* Products */,
+				D73912EC22F37F3D000D13A0 /* Frameworks */,
+				D42EAEE5849744148CC78D83 /* Pods */,
+			);
+			sourceTree = "<group>";
+		};
+		33CC10EE2044A3C60003C045 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				33CC10ED2044A3C60003C045 /* connectivity_example.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		33CC11242044D66E0003C045 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				33CC10F22044A3C60003C045 /* Assets.xcassets */,
+				33CC10F42044A3C60003C045 /* MainMenu.xib */,
+				33CC10F72044A3C60003C045 /* Info.plist */,
+			);
+			name = Resources;
+			path = ..;
+			sourceTree = "<group>";
+		};
+		33CEB47122A05771004F2AC0 /* Flutter */ = {
+			isa = PBXGroup;
+			children = (
+				335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
+				33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
+				33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
+				33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
+				D73912EF22F37F9E000D13A0 /* App.framework */,
+				33D1A10322148B71006C7A3E /* FlutterMacOS.framework */,
+			);
+			path = Flutter;
+			sourceTree = "<group>";
+		};
+		33FAB671232836740065AC1E /* Runner */ = {
+			isa = PBXGroup;
+			children = (
+				33CC10F02044A3C60003C045 /* AppDelegate.swift */,
+				33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
+				33E51913231747F40026EE4D /* DebugProfile.entitlements */,
+				33E51914231749380026EE4D /* Release.entitlements */,
+				33CC11242044D66E0003C045 /* Resources */,
+				33BA886A226E78AF003329D5 /* Configs */,
+			);
+			path = Runner;
+			sourceTree = "<group>";
+		};
+		D42EAEE5849744148CC78D83 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				80418F0A2F74D683C63A4D0A /* Pods-Runner.debug.xcconfig */,
+				E960ED3977AF6DF197F74FFA /* Pods-Runner.release.xcconfig */,
+				AA19B00394637215A825CF5E /* Pods-Runner.profile.xcconfig */,
+			);
+			name = Pods;
+			path = Pods;
+			sourceTree = "<group>";
+		};
+		D73912EC22F37F3D000D13A0 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				748ADDF1719804343BB18004 /* Pods_Runner.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		33CC10EC2044A3C60003C045 /* Runner */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
+			buildPhases = (
+				B24477CAB9D5BDFC8F3553DA /* [CP] Check Pods Manifest.lock */,
+				33CC10E92044A3C60003C045 /* Sources */,
+				33CC10EA2044A3C60003C045 /* Frameworks */,
+				33CC10EB2044A3C60003C045 /* Resources */,
+				33CC110E2044A8840003C045 /* Bundle Framework */,
+				3399D490228B24CF009A79C7 /* ShellScript */,
+				84A8D21305B2F01D093A8F9C /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				33CC11202044C79F0003C045 /* PBXTargetDependency */,
+			);
+			name = Runner;
+			productName = Runner;
+			productReference = 33CC10ED2044A3C60003C045 /* connectivity_example.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		33CC10E52044A3C60003C045 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastSwiftUpdateCheck = 0920;
+				LastUpgradeCheck = 0930;
+				ORGANIZATIONNAME = "Google LLC";
+				TargetAttributes = {
+					33CC10EC2044A3C60003C045 = {
+						CreatedOnToolsVersion = 9.2;
+						LastSwiftMigration = 1100;
+						ProvisioningStyle = Automatic;
+						SystemCapabilities = {
+							com.apple.Sandbox = {
+								enabled = 1;
+							};
+						};
+					};
+					33CC111A2044C6BA0003C045 = {
+						CreatedOnToolsVersion = 9.2;
+						ProvisioningStyle = Manual;
+					};
+				};
+			};
+			buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
+			compatibilityVersion = "Xcode 8.0";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 33CC10E42044A3C60003C045;
+			productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				33CC10EC2044A3C60003C045 /* Runner */,
+				33CC111A2044C6BA0003C045 /* Flutter Assemble */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		33CC10EB2044A3C60003C045 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
+				33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		3399D490228B24CF009A79C7 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+			);
+			outputFileListPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n";
+		};
+		33CC111E2044C6BF0003C045 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+				Flutter/ephemeral/FlutterInputs.xcfilelist,
+			);
+			inputPaths = (
+				Flutter/ephemeral/tripwire,
+			);
+			outputFileListPaths = (
+				Flutter/ephemeral/FlutterOutputs.xcfilelist,
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n";
+		};
+		84A8D21305B2F01D093A8F9C /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputFileListPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		B24477CAB9D5BDFC8F3553DA /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		33CC10E92044A3C60003C045 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
+				33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
+				335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
+			targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				33CC10F52044A3C60003C045 /* Base */,
+			);
+			name = MainMenu.xib;
+			path = Runner;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		338D0CE9231458BD00FA5F75 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.11;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = macosx;
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
+			};
+			name = Profile;
+		};
+		338D0CEA231458BD00FA5F75 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+				CODE_SIGN_STYLE = Automatic;
+				COMBINE_HIDPI_IMAGES = YES;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Flutter/ephemeral",
+				);
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+				);
+				PROVISIONING_PROFILE_SPECIFIER = "";
+				SWIFT_VERSION = 5.0;
+			};
+			name = Profile;
+		};
+		338D0CEB231458BD00FA5F75 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_STYLE = Manual;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Profile;
+		};
+		33CC10F92044A3C60003C045 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.11;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+			};
+			name = Debug;
+		};
+		33CC10FA2044A3C60003C045 /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.11;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = macosx;
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
+			};
+			name = Release;
+		};
+		33CC10FC2044A3C60003C045 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+				CODE_SIGN_STYLE = Automatic;
+				COMBINE_HIDPI_IMAGES = YES;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Flutter/ephemeral",
+				);
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+				);
+				PROVISIONING_PROFILE_SPECIFIER = "";
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 5.0;
+			};
+			name = Debug;
+		};
+		33CC10FD2044A3C60003C045 /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
+				CODE_SIGN_STYLE = Automatic;
+				COMBINE_HIDPI_IMAGES = YES;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Flutter/ephemeral",
+				);
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+				);
+				PROVISIONING_PROFILE_SPECIFIER = "";
+				SWIFT_VERSION = 5.0;
+			};
+			name = Release;
+		};
+		33CC111C2044C6BA0003C045 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_STYLE = Manual;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		33CC111D2044C6BA0003C045 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_STYLE = Automatic;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				33CC10F92044A3C60003C045 /* Debug */,
+				33CC10FA2044A3C60003C045 /* Release */,
+				338D0CE9231458BD00FA5F75 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				33CC10FC2044A3C60003C045 /* Debug */,
+				33CC10FD2044A3C60003C045 /* Release */,
+				338D0CEA231458BD00FA5F75 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				33CC111C2044C6BA0003C045 /* Debug */,
+				33CC111D2044C6BA0003C045 /* Release */,
+				338D0CEB231458BD00FA5F75 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 33CC10E52044A3C60003C045 /* Project object */;
+}
diff --git a/connectivity_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/connectivity_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..2a7d3e7
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1000"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+               BuildableName = "connectivity_example.app"
+               BlueprintName = "Runner"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "00380F9121DF178D00097171"
+               BuildableName = "RunnerUITests.xctest"
+               BlueprintName = "RunnerUITests"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+            BuildableName = "connectivity_example.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+            BuildableName = "connectivity_example.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+            BuildableName = "connectivity_example.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/connectivity_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/connectivity_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..21a3cc1
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/connectivity_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/connectivity_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/macos/Runner/AppDelegate.swift b/connectivity_macos/example/macos/Runner/AppDelegate.swift
new file mode 100644
index 0000000..d53ef64
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/AppDelegate.swift
@@ -0,0 +1,9 @@
+import Cocoa
+import FlutterMacOS
+
+@NSApplicationMain
+class AppDelegate: FlutterAppDelegate {
+  override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
+    return true
+  }
+}
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..a2ec33f
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+  "images" : [
+    {
+      "size" : "16x16",
+      "idiom" : "mac",
+      "filename" : "app_icon_16.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "16x16",
+      "idiom" : "mac",
+      "filename" : "app_icon_32.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "32x32",
+      "idiom" : "mac",
+      "filename" : "app_icon_32.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "32x32",
+      "idiom" : "mac",
+      "filename" : "app_icon_64.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "128x128",
+      "idiom" : "mac",
+      "filename" : "app_icon_128.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "128x128",
+      "idiom" : "mac",
+      "filename" : "app_icon_256.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "256x256",
+      "idiom" : "mac",
+      "filename" : "app_icon_256.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "256x256",
+      "idiom" : "mac",
+      "filename" : "app_icon_512.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "512x512",
+      "idiom" : "mac",
+      "filename" : "app_icon_512.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "512x512",
+      "idiom" : "mac",
+      "filename" : "app_icon_1024.png",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
new file mode 100644
index 0000000..3c4935a
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
new file mode 100644
index 0000000..ed4cc16
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
new file mode 100644
index 0000000..483be61
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
new file mode 100644
index 0000000..bcbf36d
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
new file mode 100644
index 0000000..9c0a652
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
new file mode 100644
index 0000000..e71a726
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
new file mode 100644
index 0000000..8a31fe2
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Base.lproj/MainMenu.xib b/connectivity_macos/example/macos/Runner/Base.lproj/MainMenu.xib
new file mode 100644
index 0000000..537341a
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Base.lproj/MainMenu.xib
@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
+            <connections>
+                <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Runner" customModuleProvider="target">
+            <connections>
+                <outlet property="applicationMenu" destination="uQy-DD-JDr" id="XBo-yE-nKs"/>
+                <outlet property="mainFlutterWindow" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
+            </connections>
+        </customObject>
+        <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
+        <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
+            <items>
+                <menuItem title="APP_NAME" id="1Xt-HY-uBw">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="APP_NAME" systemMenu="apple" id="uQy-DD-JDr">
+                        <items>
+                            <menuItem title="About APP_NAME" id="5kV-Vb-QxS">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
+                            <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
+                            <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
+                            <menuItem title="Services" id="NMo-om-nkz">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
+                            <menuItem title="Hide APP_NAME" keyEquivalent="h" id="Olw-nP-bQN">
+                                <connections>
+                                    <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
+                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+                                <connections>
+                                    <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Show All" id="Kd2-mp-pUS">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
+                            <menuItem title="Quit APP_NAME" keyEquivalent="q" id="4sb-4s-VLi">
+                                <connections>
+                                    <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Edit" id="5QF-Oa-p0T">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Edit" id="W48-6f-4Dl">
+                        <items>
+                            <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
+                                <connections>
+                                    <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
+                                <connections>
+                                    <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
+                            <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
+                                <connections>
+                                    <action selector="cut:" target="-1" id="YJe-68-I9s"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
+                                <connections>
+                                    <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
+                                <connections>
+                                    <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
+                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+                                <connections>
+                                    <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Delete" id="pa3-QI-u2k">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
+                                <connections>
+                                    <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
+                            <menuItem title="Find" id="4EN-yA-p0u">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Find" id="1b7-l0-nxx">
+                                    <items>
+                                        <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
+                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
+                                            <connections>
+                                                <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                            <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
+                                    <items>
+                                        <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
+                                            <connections>
+                                                <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
+                                            <connections>
+                                                <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
+                                        <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                            <menuItem title="Substitutions" id="9ic-FL-obx">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
+                                    <items>
+                                        <menuItem title="Show Substitutions" id="z6F-FW-3nz">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
+                                        <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Smart Quotes" id="hQb-2v-fYv">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Smart Dashes" id="rgM-f4-ycn">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Smart Links" id="cwL-P1-jid">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Data Detectors" id="tRr-pd-1PS">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Text Replacement" id="HFQ-gK-NFA">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                            <menuItem title="Transformations" id="2oI-Rn-ZJC">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
+                                    <items>
+                                        <menuItem title="Make Upper Case" id="vmV-6d-7jI">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Make Lower Case" id="d9M-CD-aMd">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Capitalize" id="UEZ-Bs-lqG">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                            <menuItem title="Speech" id="xrE-MZ-jX0">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
+                                    <items>
+                                        <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="View" id="H8h-7b-M4v">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="View" id="HyV-fh-RgO">
+                        <items>
+                            <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
+                                <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+                                <connections>
+                                    <action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Window" id="aUF-d1-5bR">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
+                        <items>
+                            <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
+                                <connections>
+                                    <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Zoom" id="R4o-n2-Eq4">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
+                            <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+            </items>
+            <point key="canvasLocation" x="142" y="-258"/>
+        </menu>
+        <window title="APP_NAME" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MainFlutterWindow" customModule="Runner" customModuleProvider="target">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+            <rect key="contentRect" x="335" y="390" width="800" height="600"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
+            <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
+                <rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
+                <autoresizingMask key="autoresizingMask"/>
+            </view>
+        </window>
+    </objects>
+</document>
diff --git a/connectivity_macos/example/macos/Runner/Configs/AppInfo.xcconfig b/connectivity_macos/example/macos/Runner/Configs/AppInfo.xcconfig
new file mode 100644
index 0000000..a951488
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Configs/AppInfo.xcconfig
@@ -0,0 +1,14 @@
+// Application-level settings for the Runner target.
+//
+// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
+// future. If not, the values below would default to using the project name when this becomes a
+// 'flutter create' template.
+
+// The application's name. By default this is also the title of the Flutter window.
+PRODUCT_NAME = connectivity_example
+
+// The application's bundle identifier
+PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample
+
+// The copyright displayed in application information
+PRODUCT_COPYRIGHT = Copyright © 2019 io.flutter.plugins. All rights reserved.
diff --git a/connectivity_macos/example/macos/Runner/Configs/Debug.xcconfig b/connectivity_macos/example/macos/Runner/Configs/Debug.xcconfig
new file mode 100644
index 0000000..36b0fd9
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Configs/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Debug.xcconfig"
+#include "Warnings.xcconfig"
diff --git a/connectivity_macos/example/macos/Runner/Configs/Release.xcconfig b/connectivity_macos/example/macos/Runner/Configs/Release.xcconfig
new file mode 100644
index 0000000..dff4f49
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Configs/Release.xcconfig
@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Release.xcconfig"
+#include "Warnings.xcconfig"
diff --git a/connectivity_macos/example/macos/Runner/Configs/Warnings.xcconfig b/connectivity_macos/example/macos/Runner/Configs/Warnings.xcconfig
new file mode 100644
index 0000000..42bcbf4
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Configs/Warnings.xcconfig
@@ -0,0 +1,13 @@
+WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
+GCC_WARN_UNDECLARED_SELECTOR = YES
+CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
+CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
+CLANG_WARN_PRAGMA_PACK = YES
+CLANG_WARN_STRICT_PROTOTYPES = YES
+CLANG_WARN_COMMA = YES
+GCC_WARN_STRICT_SELECTOR_MATCH = YES
+CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
+CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
+GCC_WARN_SHADOW = YES
+CLANG_WARN_UNREACHABLE_CODE = YES
diff --git a/connectivity_macos/example/macos/Runner/DebugProfile.entitlements b/connectivity_macos/example/macos/Runner/DebugProfile.entitlements
new file mode 100644
index 0000000..dddb8a3
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/DebugProfile.entitlements
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.app-sandbox</key>
+	<true/>
+	<key>com.apple.security.cs.allow-jit</key>
+	<true/>
+	<key>com.apple.security.network.server</key>
+	<true/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/macos/Runner/Info.plist b/connectivity_macos/example/macos/Runner/Info.plist
new file mode 100644
index 0000000..4789daa
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>$(FLUTTER_BUILD_NAME)</string>
+	<key>CFBundleVersion</key>
+	<string>$(FLUTTER_BUILD_NUMBER)</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>$(PRODUCT_COPYRIGHT)</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift b/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift
new file mode 100644
index 0000000..2722837
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift
@@ -0,0 +1,15 @@
+import Cocoa
+import FlutterMacOS
+
+class MainFlutterWindow: NSWindow {
+  override func awakeFromNib() {
+    let flutterViewController = FlutterViewController.init()
+    let windowFrame = self.frame
+    self.contentViewController = flutterViewController
+    self.setFrame(windowFrame, display: true)
+
+    RegisterGeneratedPlugins(registry: flutterViewController)
+
+    super.awakeFromNib()
+  }
+}
diff --git a/connectivity_macos/example/macos/Runner/Release.entitlements b/connectivity_macos/example/macos/Runner/Release.entitlements
new file mode 100644
index 0000000..852fa1a
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Release.entitlements
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.app-sandbox</key>
+	<true/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/pubspec.yaml b/connectivity_macos/example/pubspec.yaml
new file mode 100644
index 0000000..8772500
--- /dev/null
+++ b/connectivity_macos/example/pubspec.yaml
@@ -0,0 +1,19 @@
+name: connectivity_example
+description: Demonstrates how to use the connectivity plugin.
+
+dependencies:
+  flutter:
+    sdk: flutter
+  connectivity: any
+  connectivity_macos:
+    path: ../
+
+dev_dependencies:
+  flutter_driver:
+    sdk: flutter
+  test: any
+  e2e: ^0.2.0
+  pedantic: ^1.8.0
+
+flutter:
+  uses-material-design: true
diff --git a/connectivity_macos/example/test_driver/test/connectivity_e2e.dart b/connectivity_macos/example/test_driver/test/connectivity_e2e.dart
new file mode 100644
index 0000000..10c4bda
--- /dev/null
+++ b/connectivity_macos/example/test_driver/test/connectivity_e2e.dart
@@ -0,0 +1,41 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+import 'package:e2e/e2e.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:connectivity/connectivity.dart';
+
+void main() {
+  E2EWidgetsFlutterBinding.ensureInitialized();
+
+  group('Connectivity test driver', () {
+    Connectivity _connectivity;
+
+    setUpAll(() async {
+      _connectivity = Connectivity();
+    });
+
+    testWidgets('test connectivity result', (WidgetTester tester) async {
+      final ConnectivityResult result = await _connectivity.checkConnectivity();
+      expect(result, isNotNull);
+      switch (result) {
+        case ConnectivityResult.wifi:
+          expect(_connectivity.getWifiName(), completes);
+          expect(_connectivity.getWifiBSSID(), completes);
+          expect((await _connectivity.getWifiIP()), isNotNull);
+          break;
+        default:
+          break;
+      }
+    });
+
+    testWidgets('test location methods, iOS only', (WidgetTester tester) async {
+      if (Platform.isIOS) {
+        expect((await _connectivity.getLocationServiceAuthorization()),
+            LocationAuthorizationStatus.notDetermined);
+      }
+    });
+  });
+}
diff --git a/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart b/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart
new file mode 100644
index 0000000..84b7ae6
--- /dev/null
+++ b/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart
@@ -0,0 +1,14 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+import 'package:flutter_driver/flutter_driver.dart';
+
+Future<void> main() async {
+  final FlutterDriver driver = await FlutterDriver.connect();
+  final String result =
+      await driver.requestData(null, timeout: const Duration(minutes: 1));
+  await driver.close();
+  exit(result == 'pass' ? 0 : 1);
+}
diff --git a/connectivity/connectivity_macos/ios/connectivity_macos.podspec b/connectivity_macos/ios/connectivity_macos.podspec
similarity index 100%
rename from connectivity/connectivity_macos/ios/connectivity_macos.podspec
rename to connectivity_macos/ios/connectivity_macos.podspec
diff --git a/connectivity_macos/lib/connectivity_macos.dart b/connectivity_macos/lib/connectivity_macos.dart
new file mode 100644
index 0000000..7be7b14
--- /dev/null
+++ b/connectivity_macos/lib/connectivity_macos.dart
@@ -0,0 +1,3 @@
+// Analyze will fail if there is no main.dart file. This file should
+// be removed once an example app has been added to connectivity_macos.
+// https://github.com/flutter/flutter/issues/51007
diff --git a/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift b/connectivity_macos/macos/Classes/ConnectivityPlugin.swift
similarity index 100%
rename from connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift
rename to connectivity_macos/macos/Classes/ConnectivityPlugin.swift
diff --git a/connectivity/connectivity_macos/macos/Classes/IPHelper.h b/connectivity_macos/macos/Classes/IPHelper.h
similarity index 100%
rename from connectivity/connectivity_macos/macos/Classes/IPHelper.h
rename to connectivity_macos/macos/Classes/IPHelper.h
diff --git a/connectivity/connectivity_macos/macos/connectivity_macos.podspec b/connectivity_macos/macos/connectivity_macos.podspec
similarity index 100%
rename from connectivity/connectivity_macos/macos/connectivity_macos.podspec
rename to connectivity_macos/macos/connectivity_macos.podspec
diff --git a/connectivity/connectivity_macos/pubspec.yaml b/connectivity_macos/pubspec.yaml
similarity index 87%
rename from connectivity/connectivity_macos/pubspec.yaml
rename to connectivity_macos/pubspec.yaml
index f82189f..70ba247 100644
--- a/connectivity/connectivity_macos/pubspec.yaml
+++ b/connectivity_macos/pubspec.yaml
@@ -1,6 +1,6 @@
 name: connectivity_macos
 description: macOS implementation of the connectivity plugin.
-version: 0.0.2+1
+version: 0.1.0+1
 homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_macos
 
 flutter:
@@ -16,3 +16,6 @@
 dependencies:
   flutter:
     sdk: flutter
+
+dev_dependencies:
+  pedantic: ^1.8.0
diff --git a/connectivity_platform_interface/BUILD.gn b/connectivity_platform_interface/BUILD.gn
new file mode 100644
index 0000000..5541f94
--- /dev/null
+++ b/connectivity_platform_interface/BUILD.gn
@@ -0,0 +1,19 @@
+# This file is generated by importer.py for connectivity_platform_interface-1.0.3
+
+import("//build/dart/dart_library.gni")
+
+dart_library("connectivity_platform_interface") {
+  package_name = "connectivity_platform_interface"
+
+  # This parameter is left empty as we don't care about analysis or exporting
+  # these sources outside of the tree.
+  sources = []
+
+  disable_analysis = true
+
+  deps = [
+    "//third_party/dart-pkg/pub/plugin_platform_interface",
+    "//third_party/dart-pkg/pub/meta",
+    "//third_party/dart-pkg/git/flutter/packages/flutter",
+  ]
+}
diff --git a/connectivity_platform_interface/CHANGELOG.md b/connectivity_platform_interface/CHANGELOG.md
new file mode 100644
index 0000000..d249985
--- /dev/null
+++ b/connectivity_platform_interface/CHANGELOG.md
@@ -0,0 +1,19 @@
+## 1.0.3
+
+* Make the pedantic dev_dependency explicit.
+
+## 1.0.2
+
+* Bring ConnectivityResult and LocationAuthorizationStatus enums from the core package.
+* Use the above Enums as return values for ConnectivityPlatformInterface methods.
+* Modify the MethodChannel implementation so it returns the right types.
+* Bring all utility methods, asserts and other logic that is only needed on the MethodChannel implementation from the core package.
+* Bring MethodChannel unit tests from core package.
+
+## 1.0.1
+
+* Fix README.md link.
+
+## 1.0.0
+
+* Initial release.
diff --git a/connectivity_platform_interface/LICENSE b/connectivity_platform_interface/LICENSE
new file mode 100644
index 0000000..0c91662
--- /dev/null
+++ b/connectivity_platform_interface/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/connectivity_platform_interface/README.md b/connectivity_platform_interface/README.md
new file mode 100644
index 0000000..76b3931
--- /dev/null
+++ b/connectivity_platform_interface/README.md
@@ -0,0 +1,26 @@
+# connectivity_platform_interface
+
+A common platform interface for the [`connectivity`][1] plugin.
+
+This interface allows platform-specific implementations of the `connectivity`
+plugin, as well as the plugin itself, to ensure they are supporting the
+same interface.
+
+# Usage
+
+To implement a new platform-specific implementation of `connectivity`, extend
+[`ConnectivityPlatform`][2] with an implementation that performs the
+platform-specific behavior, and when you register your plugin, set the default
+`ConnectivityPlatform` by calling
+`ConnectivityPlatform.instance = MyPlatformConnectivity()`.
+
+# Note on breaking changes
+
+Strongly prefer non-breaking changes (such as adding a method to the interface)
+over breaking changes for this package.
+
+See https://flutter.dev/go/platform-interface-breaking-changes for a discussion
+on why a less-clean interface is preferable to a breaking change.
+
+[1]: ../
+[2]: lib/connectivity_platform_interface.dart
diff --git a/connectivity_platform_interface/lib/connectivity_platform_interface.dart b/connectivity_platform_interface/lib/connectivity_platform_interface.dart
new file mode 100644
index 0000000..cfd9cf6
--- /dev/null
+++ b/connectivity_platform_interface/lib/connectivity_platform_interface.dart
@@ -0,0 +1,79 @@
+// Copyright 2020 The Chromium Authors. 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:plugin_platform_interface/plugin_platform_interface.dart';
+
+import 'src/enums.dart';
+import 'src/method_channel_connectivity.dart';
+
+export 'src/enums.dart';
+
+/// The interface that implementations of connectivity must implement.
+///
+/// Platform implementations should extend this class rather than implement it as `Connectivity`
+/// does not consider newly added methods to be breaking changes. Extending this class
+/// (using `extends`) ensures that the subclass will get the default implementation, while
+/// platform implementations that `implements` this interface will be broken by newly added
+/// [ConnectivityPlatform] methods.
+abstract class ConnectivityPlatform extends PlatformInterface {
+  /// Constructs a ConnectivityPlatform.
+  ConnectivityPlatform() : super(token: _token);
+
+  static final Object _token = Object();
+
+  static ConnectivityPlatform _instance = MethodChannelConnectivity();
+
+  /// The default instance of [ConnectivityPlatform] to use.
+  ///
+  /// Defaults to [MethodChannelConnectivity].
+  static ConnectivityPlatform get instance => _instance;
+
+  /// Platform-specific plugins should set this with their own platform-specific
+  /// class that extends [ConnectivityPlatform] when they register themselves.
+  static set instance(ConnectivityPlatform instance) {
+    PlatformInterface.verifyToken(instance, _token);
+    _instance = instance;
+  }
+
+  /// Checks the connection status of the device.
+  Future<ConnectivityResult> checkConnectivity() {
+    throw UnimplementedError('checkConnectivity() has not been implemented.');
+  }
+
+  /// Returns a Stream of ConnectivityResults changes.
+  Stream<ConnectivityResult> get onConnectivityChanged {
+    throw UnimplementedError(
+        'get onConnectivityChanged has not been implemented.');
+  }
+
+  /// Obtains the wifi name (SSID) of the connected network
+  Future<String> getWifiName() {
+    throw UnimplementedError('getWifiName() has not been implemented.');
+  }
+
+  /// Obtains the wifi BSSID of the connected network.
+  Future<String> getWifiBSSID() {
+    throw UnimplementedError('getWifiBSSID() has not been implemented.');
+  }
+
+  /// Obtains the IP address of the connected wifi network
+  Future<String> getWifiIP() {
+    throw UnimplementedError('getWifiIP() has not been implemented.');
+  }
+
+  /// Request to authorize the location service (Only on iOS).
+  Future<LocationAuthorizationStatus> requestLocationServiceAuthorization(
+      {bool requestAlwaysLocationUsage = false}) {
+    throw UnimplementedError(
+        'requestLocationServiceAuthorization() has not been implemented.');
+  }
+
+  /// Get the current location service authorization (Only on iOS).
+  Future<LocationAuthorizationStatus> getLocationServiceAuthorization() {
+    throw UnimplementedError(
+        'getLocationServiceAuthorization() has not been implemented.');
+  }
+}
diff --git a/connectivity_platform_interface/lib/src/enums.dart b/connectivity_platform_interface/lib/src/enums.dart
new file mode 100644
index 0000000..9d8cef9
--- /dev/null
+++ b/connectivity_platform_interface/lib/src/enums.dart
@@ -0,0 +1,32 @@
+/// Connection status check result.
+enum ConnectivityResult {
+  /// WiFi: Device connected via Wi-Fi
+  wifi,
+
+  /// Mobile: Device connected to cellular network
+  mobile,
+
+  /// None: Device not connected to any network
+  none
+}
+
+/// The status of the location service authorization.
+enum LocationAuthorizationStatus {
+  /// The authorization of the location service is not determined.
+  notDetermined,
+
+  /// This app is not authorized to use location.
+  restricted,
+
+  /// User explicitly denied the location service.
+  denied,
+
+  /// User authorized the app to access the location at any time.
+  authorizedAlways,
+
+  /// User authorized the app to access the location when the app is visible to them.
+  authorizedWhenInUse,
+
+  /// Status unknown.
+  unknown
+}
diff --git a/connectivity_platform_interface/lib/src/method_channel_connectivity.dart b/connectivity_platform_interface/lib/src/method_channel_connectivity.dart
new file mode 100644
index 0000000..7a64115
--- /dev/null
+++ b/connectivity_platform_interface/lib/src/method_channel_connectivity.dart
@@ -0,0 +1,88 @@
+// Copyright 2020 The Chromium Authors. 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' show Platform;
+
+import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
+import 'package:flutter/services.dart';
+import 'package:meta/meta.dart';
+
+import 'utils.dart';
+
+/// An implementation of [ConnectivityPlatform] that uses method channels.
+class MethodChannelConnectivity extends ConnectivityPlatform {
+  /// The method channel used to interact with the native platform.
+  @visibleForTesting
+  MethodChannel methodChannel =
+      MethodChannel('plugins.flutter.io/connectivity');
+
+  /// The event channel used to receive ConnectivityResult changes from the native platform.
+  @visibleForTesting
+  EventChannel eventChannel =
+      EventChannel('plugins.flutter.io/connectivity_status');
+
+  Stream<ConnectivityResult> _onConnectivityChanged;
+
+  /// Fires whenever the connectivity state changes.
+  Stream<ConnectivityResult> get onConnectivityChanged {
+    if (_onConnectivityChanged == null) {
+      _onConnectivityChanged = eventChannel
+          .receiveBroadcastStream()
+          .map((dynamic result) => result.toString())
+          .map(parseConnectivityResult);
+    }
+    return _onConnectivityChanged;
+  }
+
+  @override
+  Future<ConnectivityResult> checkConnectivity() {
+    return methodChannel
+        .invokeMethod<String>('check')
+        .then(parseConnectivityResult);
+  }
+
+  @override
+  Future<String> getWifiName() async {
+    String wifiName = await methodChannel.invokeMethod<String>('wifiName');
+    // as Android might return <unknown ssid>, uniforming result
+    // our iOS implementation will return null
+    if (wifiName == '<unknown ssid>') {
+      wifiName = null;
+    }
+    return wifiName;
+  }
+
+  @override
+  Future<String> getWifiBSSID() {
+    return methodChannel.invokeMethod<String>('wifiBSSID');
+  }
+
+  @override
+  Future<String> getWifiIP() {
+    return methodChannel.invokeMethod<String>('wifiIPAddress');
+  }
+
+  @override
+  Future<LocationAuthorizationStatus> requestLocationServiceAuthorization({
+    bool requestAlwaysLocationUsage = false,
+  }) {
+    // `assert(Platform.isIOS)` will prevent us from doing dart side unit testing.
+    // TODO: These should noop for non-Android, instead of throwing, so people don't need to rely on dart:io for this.
+    assert(!Platform.isAndroid);
+    return methodChannel.invokeMethod<String>(
+        'requestLocationServiceAuthorization', <bool>[
+      requestAlwaysLocationUsage
+    ]).then(parseLocationAuthorizationStatus);
+  }
+
+  @override
+  Future<LocationAuthorizationStatus> getLocationServiceAuthorization() {
+    // `assert(Platform.isIOS)` will prevent us from doing dart side unit testing.
+    assert(!Platform.isAndroid);
+    return methodChannel
+        .invokeMethod<String>('getLocationServiceAuthorization')
+        .then(parseLocationAuthorizationStatus);
+  }
+}
diff --git a/connectivity_platform_interface/lib/src/utils.dart b/connectivity_platform_interface/lib/src/utils.dart
new file mode 100644
index 0000000..2ae22e1
--- /dev/null
+++ b/connectivity_platform_interface/lib/src/utils.dart
@@ -0,0 +1,32 @@
+import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
+
+/// Convert a String to a ConnectivityResult value.
+ConnectivityResult parseConnectivityResult(String state) {
+  switch (state) {
+    case 'wifi':
+      return ConnectivityResult.wifi;
+    case 'mobile':
+      return ConnectivityResult.mobile;
+    case 'none':
+    default:
+      return ConnectivityResult.none;
+  }
+}
+
+/// Convert a String to a LocationAuthorizationStatus value.
+LocationAuthorizationStatus parseLocationAuthorizationStatus(String result) {
+  switch (result) {
+    case 'notDetermined':
+      return LocationAuthorizationStatus.notDetermined;
+    case 'restricted':
+      return LocationAuthorizationStatus.restricted;
+    case 'denied':
+      return LocationAuthorizationStatus.denied;
+    case 'authorizedAlways':
+      return LocationAuthorizationStatus.authorizedAlways;
+    case 'authorizedWhenInUse':
+      return LocationAuthorizationStatus.authorizedWhenInUse;
+    default:
+      return LocationAuthorizationStatus.unknown;
+  }
+}
diff --git a/connectivity_platform_interface/pubspec.yaml b/connectivity_platform_interface/pubspec.yaml
new file mode 100644
index 0000000..78f9473
--- /dev/null
+++ b/connectivity_platform_interface/pubspec.yaml
@@ -0,0 +1,21 @@
+name: connectivity_platform_interface
+description: A common platform interface for the connectivity plugin.
+homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_platform_interface
+# NOTE: We strongly prefer non-breaking changes, even at the expense of a
+# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
+version: 1.0.3
+
+dependencies:
+  flutter:
+    sdk: flutter
+  meta: ^1.0.5
+  plugin_platform_interface: ^1.0.1
+
+dev_dependencies:
+  flutter_test:
+    sdk: flutter
+  pedantic: ^1.8.0
+
+environment:
+  sdk: ">=2.0.0-dev.28.0 <3.0.0"
+  flutter: ">=1.10.0 <2.0.0"
diff --git a/coverage/.travis.yml b/coverage/.travis.yml
index 9ce0790..5cccfe5 100644
--- a/coverage/.travis.yml
+++ b/coverage/.travis.yml
@@ -1,7 +1,7 @@
 language: dart
 
 dart:
-  - 2.6.0
+  - 2.7.0
   - dev
 
 install:
diff --git a/coverage/BUILD.gn b/coverage/BUILD.gn
index e7f6d83..9b05ac8 100644
--- a/coverage/BUILD.gn
+++ b/coverage/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for coverage-0.13.6
+# This file is generated by importer.py for coverage-0.13.8
 
 import("//build/dart/dart_library.gni")
 
diff --git a/coverage/CHANGELOG.md b/coverage/CHANGELOG.md
index b97c52b..c3d28d2 100644
--- a/coverage/CHANGELOG.md
+++ b/coverage/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 0.13.8 - 2020-03-02
+
+* Update to package_config `1.9.0` which supports package_config.json
+  files and should be forwards compatible with `2.0.0`.
+* Deprecate the `packageRoot` argument on `Resolver`.
+
+## 0.13.7 - 2020-02-28
+
+* Loosen the dependency on the `vm_service` package from `>=1.0.0 <3.0.0` to
+`>=1.0.0 <4.0.0`.
+
 ## 0.13.6 - 2020-02-10
 
 * Now consider all `.json` files for the `format_coverage` command.
diff --git a/coverage/bin/format_coverage.dart b/coverage/bin/format_coverage.dart
index 0b15899..3e2b659 100644
--- a/coverage/bin/format_coverage.dart
+++ b/coverage/bin/format_coverage.dart
@@ -54,6 +54,7 @@
       ? BazelResolver(workspacePath: env.bazelWorkspace)
       : Resolver(
           packagesPath: env.packagesPath,
+          // ignore_for_file: deprecated_member_use_from_same_package
           packageRoot: env.pkgRoot,
           sdkRoot: env.sdkRoot);
   final loader = Loader();
diff --git a/coverage/lib/src/collect.dart b/coverage/lib/src/collect.dart
index f44b030..768e2f8 100644
--- a/coverage/lib/src/collect.dart
+++ b/coverage/lib/src/collect.dart
@@ -51,7 +51,10 @@
       final options = const CompressionOptions(enabled: false);
       final socket = await WebSocket.connect('$uri', compression: options);
       final controller = StreamController<String>();
-      socket.listen((data) => controller.add(data as String));
+      socket.listen((data) => controller.add(data as String), onDone: () {
+        controller.close();
+        service.dispose();
+      });
       service = VmService(
           controller.stream, (String message) => socket.add(message),
           log: StdoutLog(), disposeHandler: () => socket.close());
@@ -86,7 +89,7 @@
     if (isolateIds != null && !isolateIds.contains(isolateRef.id)) continue;
     if (scopedOutput.isNotEmpty) {
       final scripts = await service.getScripts(isolateRef.id);
-      for (var script in scripts.scripts) {
+      for (ScriptRef script in scripts.scripts) {
         final uri = Uri.parse(script.uri);
         if (uri.scheme != 'package') continue;
         final scope = uri.path.split('/').first;
@@ -94,7 +97,7 @@
         if (!scopedOutput.contains(scope)) continue;
         final scriptReport = await service.getSourceReport(
             isolateRef.id, <String>[SourceReportKind.kCoverage],
-            forceCompile: true, scriptId: script.id);
+            forceCompile: true, scriptId: script.id) as SourceReport;
         final coverage = await _getCoverageJson(
             service, isolateRef, scriptReport, includeDart);
         allCoverage.addAll(coverage);
@@ -104,7 +107,7 @@
         isolateRef.id,
         <String>[SourceReportKind.kCoverage],
         forceCompile: true,
-      );
+      ) as SourceReport;
       final coverage = await _getCoverageJson(
           service, isolateRef, isolateReport, includeDart);
       allCoverage.addAll(coverage);
@@ -115,11 +118,22 @@
 
 Future _resumeIsolates(VmService service) async {
   final vm = await service.getVM();
+  final futures = <Future>[];
   for (var isolateRef in vm.isolates) {
-    final isolate = await service.getIsolate(isolateRef.id) as Isolate;
-    if (isolate.pauseEvent.kind != EventKind.kResume) {
-      await service.resume(isolateRef.id);
-    }
+    // Guard against sync as well as async errors: sync - when we are writing
+    // message to the socket, the socket might be closed; async - when we are
+    // waiting for the response, the socket again closes.
+    futures.add(Future.sync(() async {
+      final isolate = await service.getIsolate(isolateRef.id) as Isolate;
+      if (isolate.pauseEvent.kind != EventKind.kResume) {
+        await service.resume(isolateRef.id);
+      }
+    }));
+  }
+  try {
+    await Future.wait(futures);
+  } catch (_) {
+    // Ignore resume isolate failures
   }
 }
 
diff --git a/coverage/lib/src/resolver.dart b/coverage/lib/src/resolver.dart
index 316c66d..03ae6ef 100644
--- a/coverage/lib/src/resolver.dart
+++ b/coverage/lib/src/resolver.dart
@@ -3,14 +3,16 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 
-import 'package:package_config/packages_file.dart' as packages_file;
+import 'package:package_config/package_config.dart';
 import 'package:path/path.dart' as p;
 
 /// [Resolver] resolves imports with respect to a given environment.
 class Resolver {
-  Resolver({String packagesPath, this.packageRoot, this.sdkRoot})
+  // ignore_for_file: deprecated_member_use_from_same_package
+  Resolver({String packagesPath, @deprecated this.packageRoot, this.sdkRoot})
       : packagesPath = packagesPath,
         _packages = packagesPath != null ? _parsePackages(packagesPath) : null;
 
@@ -89,8 +91,32 @@
   }
 
   static Map<String, Uri> _parsePackages(String packagesPath) {
-    final source = File(packagesPath).readAsBytesSync();
-    return packages_file.parse(source, Uri.file(packagesPath));
+    final content = File(packagesPath).readAsStringSync();
+    try {
+      final parsed =
+          PackageConfig.parseString(content, Uri.base.resolve(packagesPath));
+      return {
+        for (var package in parsed.packages)
+          package.name: package.packageUriRoot
+      };
+    } on FormatException catch (_) {
+      // It was probably an old style .packages file
+      final lines = LineSplitter.split(content);
+      final packageMap = <String, Uri>{};
+      for (var line in lines) {
+        if (line.startsWith('#')) continue;
+        final firstColon = line.indexOf(':');
+        if (firstColon == -1) {
+          throw FormatException(
+              'Unexpected package config format, expected an old style '
+              '.packages file or new style package_config.json file.',
+              content);
+        }
+        packageMap[line.substring(0, firstColon)] =
+            Uri.parse(line.substring(firstColon + 1, line.length));
+      }
+      return packageMap;
+    }
   }
 }
 
diff --git a/coverage/pubspec.yaml b/coverage/pubspec.yaml
index 6757599..5401403 100644
--- a/coverage/pubspec.yaml
+++ b/coverage/pubspec.yaml
@@ -1,23 +1,24 @@
 name: coverage
-version: 0.13.6
+version: 0.13.8
 description: Coverage data manipulation and formatting
 homepage: https://github.com/dart-lang/coverage
 
 environment:
-  sdk: '>=2.6.0 <3.0.0'
+  sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
-  args: '>=1.4.0 <2.0.0'
+  args: ^1.4.0
   logging: '>=0.9.0 <0.12.0'
-  package_config: '>=0.1.5 <2.0.0'
+  package_config: ^1.9.0
   path: '>=0.9.0 <2.0.0'
   source_maps: ^0.10.8
   stack_trace: ^1.3.0
-  vm_service: '>=1.0.0 <3.0.0'
+  vm_service: '>=1.0.0 <4.0.0'
 
 dev_dependencies:
   pedantic: ^1.0.0
   test: ^1.0.0
+  test_descriptor: ^1.2.0
 
 executables:
   collect_coverage:
diff --git a/device_info/BUILD.gn b/device_info/BUILD.gn
index f5a595b..ff67c9a 100644
--- a/device_info/BUILD.gn
+++ b/device_info/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for device_info-0.4.1+4
+# This file is generated by importer.py for device_info-0.4.1+5
 
 import("//build/dart/dart_library.gni")
 
diff --git a/device_info/CHANGELOG.md b/device_info/CHANGELOG.md
index 13e0bae..00dcd29 100644
--- a/device_info/CHANGELOG.md
+++ b/device_info/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.4.1+5
+
+* Make the pedantic dev_dependency explicit.
+
 ## 0.4.1+4
 
 * Remove the deprecated `author:` field from pubspec.yaml
diff --git a/device_info/example/pubspec.yaml b/device_info/example/pubspec.yaml
index 148b7b9..89bf430 100644
--- a/device_info/example/pubspec.yaml
+++ b/device_info/example/pubspec.yaml
@@ -11,6 +11,7 @@
   flutter_driver:
     sdk: flutter
   e2e: ^0.2.0
+  pedantic: ^1.8.0
 
 flutter:
   uses-material-design: true
diff --git a/device_info/pubspec.yaml b/device_info/pubspec.yaml
index 452d690..b862a7d 100644
--- a/device_info/pubspec.yaml
+++ b/device_info/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Flutter plugin providing detailed information about the device
   (make, model, etc.), and Android or iOS version the app is running on.
 homepage: https://github.com/flutter/plugins/tree/master/packages/device_info
-version: 0.4.1+4
+version: 0.4.1+5
 
 flutter:
   plugin:
@@ -22,6 +22,7 @@
   flutter_test:
     sdk: flutter
   e2e: ^0.2.0
+  pedantic: ^1.8.0
 
 environment:
   sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/graphs/.gitignore b/graphs/.gitignore
deleted file mode 100644
index ddfdca1..0000000
--- a/graphs/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.dart_tool/
-.packages
-.pub/
-build/
-pubspec.lock
diff --git a/graphs/.travis.yml b/graphs/.travis.yml
deleted file mode 100644
index 3c0743f..0000000
--- a/graphs/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: dart
-
-dart:
-  - dev
-  - stable
-
-dart_task:
-  - test
-  - test -p chrome,firefox
-  - dartfmt
-  - dartanalyzer: --fatal-infos --fatal-warnings .
-
-matrix:
-  exclude:
-    - dart: stable
-      dart_task: dartfmt
-
-branches:
-  only: [master]
-
-cache:
-  directories:
-    - $HOME/.pub-cache
diff --git a/graphs/CHANGELOG.md b/graphs/CHANGELOG.md
deleted file mode 100644
index 78722c4..0000000
--- a/graphs/CHANGELOG.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# 0.2.0-dev
-
-- **BREAKING** `shortestPath`, `shortestPaths` and `stronglyConnectedComponents`
-  now have one generic parameter and have replaced the `key` parameter with
-  optional params: `{bool equals(T key1, T key2), int hashCode(T key)}`.
-  This follows the pattern used in `dart:collection` classes `HashMap` and 
-  `LinkedHashMap`. It improves the usability and performance of the case where
-  the source values are directly usable in a hash data structure.
-
-# 0.1.3+1
-
-- Fixed a bug with non-identity `key` in `shortestPath` and `shortestPaths`.
-
-# 0.1.3
-
-- Added `shortestPath` and `shortestPaths` functions.
-- Use `HashMap` and `HashSet` from `dart:collection` for
-  `stronglyConnectedComponents`. Improves runtime performance.
-
-# 0.1.2+1
-
-- Allow using non-dev Dart 2 SDK.
-
-# 0.1.2
-
-- `crawlAsync` surfaces exceptions while crawling through the result stream
-  rather than as uncaught asynchronous errors.
-
-# 0.1.1
-
-- `crawlAsync` will now ignore nodes that are resolved to `null`.
-
-# 0.1.0
-
-- Initial release with an implementation of `stronglyConnectedComponents` and
-  `crawlAsync`.
diff --git a/graphs/CONTRIBUTING.md b/graphs/CONTRIBUTING.md
deleted file mode 100644
index 286d61c..0000000
--- a/graphs/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-### Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-All submissions, including submissions by project members, require review.
-
-### File headers
-All files in the project must start with the following header.
-
-    // 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.
-
-### The small print
-Contributions made by corporations are covered by a different agreement than the
-one above, the
-[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
diff --git a/graphs/LICENSE b/graphs/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/graphs/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/graphs/README.md b/graphs/README.md
deleted file mode 100644
index 0edaf92..0000000
--- a/graphs/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# [![Build Status](https://travis-ci.org/dart-lang/graphs.svg?branch=master)](https://travis-ci.org/dart-lang/graphs)
-
-Graph algorithms which do not specify a particular approach for representing a
-Graph.
-
-Functions in this package will take arguments that provide the mechanism for
-traversing the graph. For example two common approaches for representing a
-graph:
-
-```dart
-class Graph {
-  Map<Node, List<Node>> nodes;
-}
-class Node {
-  // Interesting data
-}
-```
-
-```dart
-class Graph {
-  Node root;
-}
-class Node {
-  List<Node> edges;
-  // Interesting data
-}
-```
-
-Any representation can be adapted to the needs of the algorithm:
-
-- Some algorithms need to associate data with each node in the graph. If the
-  node type `T` does not correctly or efficiently implement `hashCode` or `==`,
-  you may provide optional `equals` and/or `hashCode` functions are parameters.
-- Algorithms which need to traverse the graph take a `edges` function which
-  provides the reachable nodes.
-  - `(node) => graph[node]`
-  - `(node) => node.edges`
-
-
-Graphs which are resolved asynchronously will have similar functions which
-return `FutureOr`.
diff --git a/graphs/analysis_options.yaml b/graphs/analysis_options.yaml
deleted file mode 100644
index 6e159f3..0000000
--- a/graphs/analysis_options.yaml
+++ /dev/null
@@ -1,66 +0,0 @@
-include: package:pedantic/analysis_options.yaml
-analyzer:
-  strong-mode:
-    implicit-casts: false
-  errors:
-    unused_element: error
-    unused_import: error
-    unused_local_variable: error
-    dead_code: error
-linter:
-  rules:
-    - annotate_overrides
-    - avoid_function_literals_in_foreach_calls
-    - avoid_init_to_null
-    - avoid_null_checks_in_equality_operators
-    - avoid_relative_lib_imports
-    - avoid_returning_null
-    - avoid_unused_constructor_parameters
-    - await_only_futures
-    - camel_case_types
-    - cancel_subscriptions
-    - comment_references
-    - constant_identifier_names
-    - control_flow_in_finally
-    - directives_ordering
-    - empty_catches
-    - empty_constructor_bodies
-    - empty_statements
-    - hash_and_equals
-    - implementation_imports
-    - invariant_booleans
-    - iterable_contains_unrelated_type
-    - library_names
-    - library_prefixes
-    - list_remove_unrelated_type
-    - no_adjacent_strings_in_list
-    - non_constant_identifier_names
-    - omit_local_variable_types
-    - only_throw_errors
-    - overridden_fields
-    - package_api_docs
-    - package_names
-    - package_prefixed_library_names
-    - prefer_adjacent_string_concatenation
-    - prefer_collection_literals
-    - prefer_conditional_assignment
-    - prefer_const_constructors
-    - prefer_final_fields
-    - prefer_initializing_formals
-    - prefer_interpolation_to_compose_strings
-    - prefer_single_quotes
-    - prefer_typing_uninitialized_variables
-    - slash_for_doc_comments
-    - test_types_in_equals
-    - super_goes_last
-    - test_types_in_equals
-    - throw_in_finally
-    - type_init_formals
-    - unnecessary_brace_in_string_interps
-    - unnecessary_const
-    - unnecessary_getters_setters
-    - unnecessary_lambdas
-    - unnecessary_new
-    - unnecessary_null_aware_assignments
-    - unnecessary_statements
-    - unnecessary_this
diff --git a/graphs/benchmark/connected_components_benchmark.dart b/graphs/benchmark/connected_components_benchmark.dart
deleted file mode 100644
index c1c83d7..0000000
--- a/graphs/benchmark/connected_components_benchmark.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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:collection';
-import 'dart:math' show Random;
-
-import 'package:graphs/graphs.dart';
-
-void main() {
-  final _rnd = Random(0);
-  final size = 2000;
-  final graph = HashMap<int, List<int>>();
-
-  for (var i = 0; i < size * 3; i++) {
-    final toList = graph.putIfAbsent(_rnd.nextInt(size), () => <int>[]);
-
-    final toValue = _rnd.nextInt(size);
-    if (!toList.contains(toValue)) {
-      toList.add(toValue);
-    }
-  }
-
-  var maxCount = 0;
-  var maxIteration = 0;
-
-  final duration = const Duration(milliseconds: 100);
-
-  for (var i = 1;; i++) {
-    var count = 0;
-    final watch = Stopwatch()..start();
-    while (watch.elapsed < duration) {
-      count++;
-      final length =
-          stronglyConnectedComponents(graph.keys, (e) => graph[e] ?? []).length;
-      assert(length == 244, '$length');
-    }
-
-    if (count > maxCount) {
-      maxCount = count;
-      maxIteration = i;
-    }
-
-    if (maxIteration == i || (i - maxIteration) % 20 == 0) {
-      print('max iterations in ${duration.inMilliseconds}ms: $maxCount\t'
-          'after $maxIteration of $i iterations');
-    }
-  }
-}
diff --git a/graphs/benchmark/shortest_path_benchmark.dart b/graphs/benchmark/shortest_path_benchmark.dart
deleted file mode 100644
index 813c18b..0000000
--- a/graphs/benchmark/shortest_path_benchmark.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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:collection';
-import 'dart:math' show Random;
-
-import 'package:graphs/graphs.dart';
-
-void main() {
-  final _rnd = Random(1);
-  final size = 1000;
-  final graph = HashMap<int, List<int>>();
-
-  for (var i = 0; i < size * 5; i++) {
-    final toList = graph.putIfAbsent(_rnd.nextInt(size), () => <int>[]);
-
-    final toValue = _rnd.nextInt(size);
-    if (!toList.contains(toValue)) {
-      toList.add(toValue);
-    }
-  }
-
-  int minTicks;
-  var maxIteration = 0;
-
-  final testOutput =
-      shortestPath(0, size - 1, (e) => graph[e] ?? []).toString();
-  print(testOutput);
-  assert(testOutput == '[258, 252, 819, 999]');
-
-  final watch = Stopwatch();
-  for (var i = 1;; i++) {
-    watch
-      ..reset()
-      ..start();
-    final length = shortestPath(0, size - 1, (e) => graph[e] ?? []).length;
-    watch.stop();
-    assert(length == 4, '$length');
-
-    if (minTicks == null || watch.elapsedTicks < minTicks) {
-      minTicks = watch.elapsedTicks;
-      maxIteration = i;
-    }
-
-    if (maxIteration == i || (i - maxIteration) % 100000 == 0) {
-      print('min ticks for one run: $minTicks\t'
-          'after $maxIteration of $i iterations');
-    }
-  }
-}
diff --git a/graphs/example/crawl_async_example.dart b/graphs/example/crawl_async_example.dart
deleted file mode 100644
index 959b894..0000000
--- a/graphs/example/crawl_async_example.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:isolate';
-
-import 'package:analyzer/dart/analysis/analysis_context.dart';
-import 'package:analyzer/dart/analysis/context_builder.dart';
-import 'package:analyzer/dart/analysis/context_locator.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:graphs/graphs.dart';
-import 'package:path/path.dart' as p;
-
-/// Print a transitive set of imported URIs where libraries are read
-/// asynchronously.
-Future<Null> main() async {
-  var allImports = await crawlAsync(
-          [Uri.parse('package:graphs/graphs.dart')], read, findImports)
-      .toList();
-  print(allImports.map((s) => s.uri).toList());
-}
-
-AnalysisContext _analysisContext;
-
-Future<AnalysisContext> get analysisContext async {
-  if (_analysisContext == null) {
-    var libUri = Uri.parse('package:graphs/');
-    var libPath = await pathForUri(libUri);
-    var packagePath = p.dirname(libPath);
-
-    var roots = ContextLocator().locateRoots(includedPaths: [packagePath]);
-    if (roots.length != 1) {
-      throw StateError('Expected to find exactly one context root, got $roots');
-    }
-
-    _analysisContext = ContextBuilder().createContext(contextRoot: roots[0]);
-  }
-
-  return _analysisContext;
-}
-
-Future<Iterable<Uri>> findImports(Uri from, Source source) async {
-  return source.unit.directives
-      .whereType<UriBasedDirective>()
-      .map((d) => d.uri.stringValue)
-      .where((uri) => !uri.startsWith('dart:'))
-      .map((import) => resolveImport(import, from));
-}
-
-Future<CompilationUnit> parseUri(Uri uri) async {
-  var path = await pathForUri(uri);
-  var analysisSession = (await analysisContext).currentSession;
-  var parseResult = analysisSession.getParsedUnit(path);
-  return parseResult.unit;
-}
-
-Future<String> pathForUri(Uri uri) async {
-  var fileUri = await Isolate.resolvePackageUri(uri);
-  if (fileUri == null || !fileUri.isScheme('file')) {
-    throw StateError('Expected to resolve $uri to a file URI, got $fileUri');
-  }
-  return p.fromUri(fileUri);
-}
-
-Future<Source> read(Uri uri) async => Source(uri, await parseUri(uri));
-
-Uri resolveImport(String import, Uri from) {
-  if (import.startsWith('package:')) return Uri.parse(import);
-  assert(from.scheme == 'package');
-  final package = from.pathSegments.first;
-  final fromPath = p.joinAll(from.pathSegments.skip(1));
-  final path = p.normalize(p.join(p.dirname(fromPath), import));
-  return Uri.parse('package:${p.join(package, path)}');
-}
-
-class Source {
-  final Uri uri;
-  final CompilationUnit unit;
-
-  Source(this.uri, this.unit);
-}
diff --git a/graphs/example/example.dart b/graphs/example/example.dart
deleted file mode 100644
index 47aca61..0000000
--- a/graphs/example/example.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:graphs/graphs.dart';
-
-/// A representation of a directed graph.
-///
-/// Data is stored on the [Node] class.
-class Graph {
-  final Map<Node, List<Node>> nodes;
-
-  Graph(this.nodes);
-}
-
-class Node {
-  final String id;
-  final int data;
-
-  Node(this.id, this.data);
-
-  @override
-  bool operator ==(Object other) => other is Node && other.id == id;
-
-  @override
-  int get hashCode => id.hashCode;
-
-  @override
-  String toString() => '<$id -> $data>';
-}
-
-void main() {
-  var nodeA = Node('A', 1);
-  var nodeB = Node('B', 2);
-  var nodeC = Node('C', 3);
-  var nodeD = Node('D', 4);
-  var graph = Graph({
-    nodeA: [nodeB, nodeC],
-    nodeB: [nodeC, nodeD],
-    nodeC: [nodeB, nodeD]
-  });
-
-  var components = stronglyConnectedComponents<Node>(
-      graph.nodes.keys, (node) => graph.nodes[node]);
-
-  print(components);
-}
diff --git a/graphs/lib/graphs.dart b/graphs/lib/graphs.dart
deleted file mode 100644
index a5de89c..0000000
--- a/graphs/lib/graphs.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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.
-
-export 'src/crawl_async.dart' show crawlAsync;
-export 'src/shortest_path.dart' show shortestPath, shortestPaths;
-export 'src/strongly_connected_components.dart'
-    show stronglyConnectedComponents;
diff --git a/graphs/lib/src/crawl_async.dart b/graphs/lib/src/crawl_async.dart
deleted file mode 100644
index 319a61e..0000000
--- a/graphs/lib/src/crawl_async.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-
-final _empty = Future<Null>.value(null);
-
-/// Finds and returns every node in a graph who's nodes and edges are
-/// asynchronously resolved.
-///
-/// Cycles are allowed. If this is an undirected graph the [edges] function
-/// may be symmetric. In this case the [roots] may be any node in each connected
-/// graph.
-///
-/// [V] is the type of values in the graph nodes. [K] must be a type suitable
-/// for using as a Map or Set key. [edges] should return the next reachable
-/// nodes.
-///
-/// There are no ordering guarantees. This is useful for ensuring some work is
-/// performed at every node in an asynchronous graph, but does not give
-/// guarantees that the work is done in topological order.
-///
-/// If [readNode] returns null for any key it will be ignored from the rest of
-/// the graph. If missing nodes are important they should be tracked within the
-/// [readNode] callback.
-///
-/// If either [readNode] or [edges] throws the error will be forwarded
-/// through the result stream and no further nodes will be crawled, though some
-/// work may have already been started.
-Stream<V> crawlAsync<K, V>(Iterable<K> roots, FutureOr<V> Function(K) readNode,
-    FutureOr<Iterable<K>> Function(K, V) edges) {
-  final crawl = _CrawlAsync(roots, readNode, edges)..run();
-  return crawl.result.stream;
-}
-
-class _CrawlAsync<K, V> {
-  final result = StreamController<V>();
-
-  final FutureOr<V> Function(K) readNode;
-  final FutureOr<Iterable<K>> Function(K, V) edges;
-  final Iterable<K> roots;
-
-  final _seen = HashSet<K>();
-
-  _CrawlAsync(this.roots, this.readNode, this.edges);
-
-  /// Add all nodes in the graph to [result] and return a Future which fires
-  /// after all nodes have been seen.
-  Future<Null> run() async {
-    try {
-      await Future.wait(roots.map(_visit), eagerError: true);
-      await result.close();
-    } catch (e, st) {
-      result.addError(e, st);
-      await result.close();
-    }
-  }
-
-  /// Resolve the node at [key] and output it, then start crawling all of it's
-  /// edges.
-  Future<Null> _crawlFrom(K key) async {
-    var value = await readNode(key);
-    if (value == null) return;
-    if (result.isClosed) return;
-    result.add(value);
-    var next = await edges(key, value) ?? const [];
-    await Future.wait(next.map(_visit), eagerError: true);
-  }
-
-  /// Synchronously record that [key] is being handled then start work on the
-  /// node for [key].
-  ///
-  /// The returned Future will complete only after the work for [key] and all
-  /// transitively reachable nodes has either been finished, or will be finished
-  /// by some other Future in [_seen].
-  Future<Null> _visit(K key) {
-    if (_seen.contains(key)) return _empty;
-    _seen.add(key);
-    return _crawlFrom(key);
-  }
-}
diff --git a/graphs/lib/src/shortest_path.dart b/graphs/lib/src/shortest_path.dart
deleted file mode 100644
index f295e5d..0000000
--- a/graphs/lib/src/shortest_path.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// 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:collection';
-
-/// Returns the shortest path from [start] to [target] given the directed
-/// edges of a graph provided by [edges].
-///
-/// If [start] `==` [target], an empty [List] is returned and [edges] is never
-/// called.
-///
-/// [start], [target] and all values returned by [edges] must not be `null`.
-/// If asserts are enabled, an [AssertionError] is raised if these conditions
-/// are not met. If asserts are not enabled, violations result in undefined
-/// behavior.
-///
-/// If [equals] is provided, it is used to compare nodes in the graph. If
-/// [equals] is omitted, the node's own [Object.==] is used instead.
-///
-/// Similarly, if [hashCode] is provided, it is used to produce a hash value
-/// for nodes to efficiently calculate the return value. If it is omitted, the
-/// key's own [Object.hashCode] is used.
-///
-/// If you supply one of [equals] or [hashCode], you should generally also to
-/// supply the other.
-List<T> shortestPath<T>(
-  T start,
-  T target,
-  Iterable<T> Function(T) edges, {
-  bool equals(T key1, T key2),
-  int hashCode(T key),
-}) =>
-    _shortestPaths<T>(
-      start,
-      edges,
-      target: target,
-      equals: equals,
-      hashCode: hashCode,
-    )[target];
-
-/// Returns a [Map] of the shortest paths from [start] to all of the nodes in
-/// the directed graph defined by [edges].
-///
-/// All return values will contain the key [start] with an empty [List] value.
-///
-/// [start] and all values returned by [edges] must not be `null`.
-/// If asserts are enabled, an [AssertionError] is raised if these conditions
-/// are not met. If asserts are not enabled, violations result in undefined
-/// behavior.
-///
-/// If [equals] is provided, it is used to compare nodes in the graph. If
-/// [equals] is omitted, the node's own [Object.==] is used instead.
-///
-/// Similarly, if [hashCode] is provided, it is used to produce a hash value
-/// for nodes to efficiently calculate the return value. If it is omitted, the
-/// key's own [Object.hashCode] is used.
-///
-/// If you supply one of [equals] or [hashCode], you should generally also to
-/// supply the other.
-Map<T, List<T>> shortestPaths<T>(
-  T start,
-  Iterable<T> Function(T) edges, {
-  bool equals(T key1, T key2),
-  int hashCode(T key),
-}) =>
-    _shortestPaths<T>(
-      start,
-      edges,
-      equals: equals,
-      hashCode: hashCode,
-    );
-
-Map<T, List<T>> _shortestPaths<T>(
-  T start,
-  Iterable<T> Function(T) edges, {
-  T target,
-  bool equals(T key1, T key2),
-  int hashCode(T key),
-}) {
-  assert(start != null, '`start` cannot be null');
-  assert(edges != null, '`edges` cannot be null');
-
-  final distances = HashMap<T, List<T>>(equals: equals, hashCode: hashCode);
-  distances[start] = List(0);
-
-  equals ??= _defaultEquals;
-  if (equals(start, target)) {
-    return distances;
-  }
-
-  final toVisit = ListQueue<T>()..add(start);
-
-  List<T> bestOption;
-
-  while (toVisit.isNotEmpty) {
-    final current = toVisit.removeFirst();
-    final currentPath = distances[current];
-    final currentPathLength = currentPath.length;
-
-    if (bestOption != null && (currentPathLength + 1) >= bestOption.length) {
-      // Skip any existing `toVisit` items that have no chance of being
-      // better than bestOption (if it exists)
-      continue;
-    }
-
-    for (var edge in edges(current)) {
-      assert(edge != null, '`edges` cannot return null values.');
-      final existingPath = distances[edge];
-
-      assert(existingPath == null ||
-          existingPath.length <= (currentPathLength + 1));
-
-      if (existingPath == null) {
-        final newOption = List<T>(currentPathLength + 1)
-          ..setRange(0, currentPathLength, currentPath)
-          ..[currentPathLength] = edge;
-
-        if (equals(edge, target)) {
-          assert(bestOption == null || bestOption.length > newOption.length);
-          bestOption = newOption;
-        }
-
-        distances[edge] = newOption;
-        if (bestOption == null || bestOption.length > newOption.length) {
-          // Only add a node to visit if it might be a better path to the
-          // target node
-          toVisit.add(edge);
-        }
-      }
-    }
-  }
-
-  return distances;
-}
-
-bool _defaultEquals(a, b) => a == b;
diff --git a/graphs/lib/src/strongly_connected_components.dart b/graphs/lib/src/strongly_connected_components.dart
deleted file mode 100644
index 19519a8..0000000
--- a/graphs/lib/src/strongly_connected_components.dart
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-import 'dart:math' show min;
-
-/// Finds the strongly connected components of a directed graph using Tarjan's
-/// algorithm.
-///
-/// The result will be a valid reverse topological order ordering of the
-/// strongly connected components. Components further from a root will appear in
-/// the result before the components which they are connected to.
-///
-/// Nodes within a strongly connected component have no ordering guarantees,
-/// except that if the first value in [nodes] is a valid root, and is contained
-/// in a cycle, it will be the last element of that cycle.
-///
-/// [nodes] must contain at least a root of every tree in the graph if there are
-/// disjoint subgraphs but it may contain all nodes in the graph if the roots
-/// are not known.
-///
-/// If [equals] is provided, it is used to compare nodes in the graph. If
-/// [equals] is omitted, the node's own [Object.==] is used instead.
-///
-/// Similarly, if [hashCode] is provided, it is used to produce a hash value
-/// for nodes to efficiently calculate the return value. If it is omitted, the
-/// key's own [Object.hashCode] is used.
-///
-/// If you supply one of [equals] or [hashCode], you should generally also to
-/// supply the other.
-List<List<T>> stronglyConnectedComponents<T>(
-  Iterable<T> nodes,
-  Iterable<T> Function(T) edges, {
-  bool equals(T key1, T key2),
-  int hashCode(T key),
-}) {
-  final result = <List<T>>[];
-  final lowLinks = HashMap<T, int>(equals: equals, hashCode: hashCode);
-  final indexes = HashMap<T, int>(equals: equals, hashCode: hashCode);
-  final onStack = HashSet<T>(equals: equals, hashCode: hashCode);
-
-  equals ??= _defaultEquals;
-
-  var index = 0;
-  var lastVisited = Queue<T>();
-
-  void strongConnect(T node) {
-    indexes[node] = index;
-    lowLinks[node] = index;
-    index++;
-    lastVisited.addLast(node);
-    onStack.add(node);
-    // ignore: omit_local_variable_types
-    for (final T next in edges(node) ?? const []) {
-      if (!indexes.containsKey(next)) {
-        strongConnect(next);
-        lowLinks[node] = min(lowLinks[node], lowLinks[next]);
-      } else if (onStack.contains(next)) {
-        lowLinks[node] = min(lowLinks[node], indexes[next]);
-      }
-    }
-    if (lowLinks[node] == indexes[node]) {
-      final component = <T>[];
-      T next;
-      do {
-        next = lastVisited.removeLast();
-        onStack.remove(next);
-        component.add(next);
-      } while (!equals(next, node));
-      result.add(component);
-    }
-  }
-
-  for (final node in nodes) {
-    if (!indexes.containsKey(node)) strongConnect(node);
-  }
-  return result;
-}
-
-bool _defaultEquals(a, b) => a == b;
diff --git a/graphs/pubspec.yaml b/graphs/pubspec.yaml
deleted file mode 100644
index 12c5ff4..0000000
--- a/graphs/pubspec.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: graphs
-version: 0.2.0
-description: Graph algorithms that operate on graphs in any representation
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/graphs
-
-environment:
-  sdk: '>=2.0.0 <3.0.0'
-
-dev_dependencies:
-  pedantic: ^1.3.0
-  test: ^1.5.1
-
-  # For examples
-  analyzer: ^0.34.0
-  path: ^1.1.0
diff --git a/mustache/BUILD.gn b/mustache/BUILD.gn
deleted file mode 100644
index 2e8c791..0000000
--- a/mustache/BUILD.gn
+++ /dev/null
@@ -1,16 +0,0 @@
-# This file is generated by importer.py for mustache-1.1.1
-
-import("//build/dart/dart_library.gni")
-
-dart_library("mustache") {
-  package_name = "mustache"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-  ]
-}
diff --git a/mustache/example/basic.dart b/mustache/example/basic.dart
deleted file mode 100644
index 89a293c..0000000
--- a/mustache/example/basic.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-import 'package:mustache/mustache.dart';
-
-main() {
-  var source = '''
-    {{# names }}
-          <div>{{ lastname }}, {{ firstname }}</div>
-    {{/ names }}
-    {{^ names }}
-      <div>No names.</div>
-    {{/ names }}
-    {{! I am a comment. }}
-  ''';
-
-  var template = new Template(source, name: 'template-filename.html');
-
-  var output = template.renderString({'names': [
-      {'firstname': 'Greg', 'lastname': 'Lowe'},
-      {'firstname': 'Bob', 'lastname': 'Johnson'}
-  ]});
-
-  print(output);
-}
\ No newline at end of file
diff --git a/mustache/example/lambdas.dart b/mustache/example/lambdas.dart
deleted file mode 100644
index b7a9ff2..0000000
--- a/mustache/example/lambdas.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-import 'package:mustache/mustache.dart';
-
-main() {
-  var t = new Template('{{ foo }}');
-  Function lambda = (_) => 'bar';
-  var output = t.renderString({'foo': lambda}); // bar
-  print(output);
-
-  t = new Template('{{# foo }}hidden{{/ foo }}');
-  lambda = (_) => 'shown';
-  output = t.renderString({'foo': lambda}); // shown
-  print(output);
-
-  t = new Template('{{# foo }}oi{{/ foo }}');
-  lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
-  output = t.renderString({'foo': lambda}); // <b>OI</b>
-  print(output);
-
-  t = new Template('{{# foo }}{{bar}}{{/ foo }}');
-  lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
-  output = t.renderString({'foo': lambda, 'bar': 'pub'}); // <b>PUB</b>
-  print(output);
-
-  t = new Template('{{# foo }}{{bar}}{{/ foo }}');
-  lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
-  output = t.renderString({'foo': lambda, 'bar': 'pub'}); // <b>PUB</b>
-  print(output);
-
-  t = new Template('{{# foo }}{{bar}}{{/ foo }}');
-  lambda = (LambdaContext ctx) => ctx.renderSource(ctx.source + '{{cmd}}');
-  output = t.renderString({'foo': lambda, 'bar': 'pub', 'cmd': 'build'}); // pub build
-  print(output);
-}
diff --git a/mustache/example/nested_paths.dart b/mustache/example/nested_paths.dart
deleted file mode 100644
index 5472ce7..0000000
--- a/mustache/example/nested_paths.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-import 'package:mustache/mustache.dart';
-
-main() {
-  var template = new Template('{{ author.name }}');
-  var output = template.renderString({'author': {'name': 'Greg Lowe'}});
-  print(output);
-}
diff --git a/mustache/example/partials.dart b/mustache/example/partials.dart
deleted file mode 100644
index a0c105f..0000000
--- a/mustache/example/partials.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'package:mustache/mustache.dart';
-
-main() {
-  var partial = new Template('{{ foo }}', name: 'partial');
-
-  var resolver = (String name) {
-     if (name == 'partial-name') { // Name of partial tag.
-       return partial;
-     }
-  };
-
-  var t = new Template('{{> partial-name }}', partialResolver: resolver);
-
-  var output = t.renderString({'foo': 'bar'}); // bar
-  print(output);
-}
diff --git a/mustache/lib/src/token.dart b/mustache/lib/src/token.dart
deleted file mode 100644
index e4d7b59..0000000
--- a/mustache/lib/src/token.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-library mustache.token;
-
-class TokenType {
-  const TokenType(this.name);
-
-  final String name;
-
-  String toString() => '(TokenType $name)';
-
-  static const TokenType text = const TokenType('text');
-  static const TokenType openDelimiter = const TokenType('openDelimiter');
-  static const TokenType closeDelimiter = const TokenType('closeDelimiter');
-
-  // A sigil is the word commonly used to describe the special character at the
-  // start of mustache tag i.e. #, ^ or /.
-  static const TokenType sigil = const TokenType('sigil');
-  static const TokenType identifier = const TokenType('identifier');
-  static const TokenType dot = const TokenType('dot');
-
-  static const TokenType changeDelimiter = const TokenType('changeDelimiter');
-  static const TokenType whitespace = const TokenType('whitespace');
-  static const TokenType lineEnd = const TokenType('lineEnd');
-}
-
-class Token {
-  Token(this.type, this.value, this.start, this.end);
-
-  final TokenType type;
-  final String value;
-
-  final int start;
-  final int end;
-
-  String toString() => "(Token ${type.name} \"$value\" $start $end)";
-}
diff --git a/mustache/pubspec.yaml b/mustache/pubspec.yaml
deleted file mode 100644
index ed01ed6..0000000
--- a/mustache/pubspec.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-name: mustache
-version: 1.1.1
-author: Greg Lowe <greg@vis.net.nz>
-description: Mustache template library
-homepage: https://github.com/xxgreg/mustache
-environment:
-  sdk: '>=2.0.0 <3.0.0'
-dev_dependencies:
-  test: '>=0.12.0 <2.0.0'
-analyzer:
-  strong-mode: true
diff --git a/mustache/.gitignore b/mustache_template/.gitignore
similarity index 100%
rename from mustache/.gitignore
rename to mustache_template/.gitignore
diff --git a/mustache/.travis.yml b/mustache_template/.travis.yml
similarity index 100%
rename from mustache/.travis.yml
rename to mustache_template/.travis.yml
diff --git a/graphs/BUILD.gn b/mustache_template/BUILD.gn
similarity index 60%
rename from graphs/BUILD.gn
rename to mustache_template/BUILD.gn
index 1258e65..0f80569 100644
--- a/graphs/BUILD.gn
+++ b/mustache_template/BUILD.gn
@@ -1,9 +1,9 @@
-# This file is generated by importer.py for graphs-0.2.0
+# This file is generated by importer.py for mustache_template-1.0.0+1
 
 import("//build/dart/dart_library.gni")
 
-dart_library("graphs") {
-  package_name = "graphs"
+dart_library("mustache_template") {
+  package_name = "mustache_template"
 
   # This parameter is left empty as we don't care about analysis or exporting
   # these sources outside of the tree.
diff --git a/mustache/CHANGELOG.md b/mustache_template/CHANGELOG.md
similarity index 87%
rename from mustache/CHANGELOG.md
rename to mustache_template/CHANGELOG.md
index 3a8f600..28d3573 100644
--- a/mustache/CHANGELOG.md
+++ b/mustache_template/CHANGELOG.md
@@ -1,5 +1,16 @@
 # CHANGELOG
 
+## 1.0.0+1
+
+* Fixed regression where lookups from list did not work. Removed failing tests
+  that depend on reflection.
+
+## 1.0.0
+
+ * Forked from original repo. Support for mirrors removed.
+
+## Fork
+
 ## 1.1.1
 
  * Fixed error "boolean expression must not be null". Thanks Nico.
diff --git a/mustache/LICENSE b/mustache_template/LICENSE
similarity index 100%
rename from mustache/LICENSE
rename to mustache_template/LICENSE
diff --git a/mustache/README.md b/mustache_template/README.md
similarity index 88%
rename from mustache/README.md
rename to mustache_template/README.md
index c2223d7..37a3a14 100644
--- a/mustache/README.md
+++ b/mustache_template/README.md
@@ -2,8 +2,6 @@
 
 A Dart library to parse and render [mustache templates](https://mustache.github.io/).
 
-[![Build Status](https://api.travis-ci.org/xxgreg/mustache.svg?branch=master)](https://travis-ci.org/xxgreg/mustache) [![Coverage Status](https://coveralls.io/repos/xxgreg/mustache/badge.svg)](https://coveralls.io/r/xxgreg/mustache)
-
 See the [mustache manual](http://mustache.github.com/mustache.5.html) for detailed usage information.
 
 This library passes all [mustache specification](https://github.com/mustache/spec/tree/master/specs) tests.
@@ -40,10 +38,6 @@
 
 By default all output from `{{variable}}` tags is html escaped, this behaviour can be changed by passing htmlEscapeValues : false to the Template constructor. You can also use a `{{{triple mustache}}}` tag, or a unescaped variable tag `{{&unescaped}}`, the output from these tags is not escaped.
 
-## Dart2js
-
-This library uses mirrors. When compiling with dart2js you will need to pass the experimental mirrors flag. You also need to mark any objects which will be rendered with the @mustache annotation. There is also another version of this library available which doesn't use mirrors.
-
 ## Differences between strict mode and lenient mode.
 
 ### Strict mode (default)
diff --git a/mustache_template/analysis_options.yaml b/mustache_template/analysis_options.yaml
new file mode 100644
index 0000000..108d105
--- /dev/null
+++ b/mustache_template/analysis_options.yaml
@@ -0,0 +1 @@
+include: package:pedantic/analysis_options.yaml
diff --git a/mustache/lib/mustache.dart b/mustache_template/lib/mustache.dart
similarity index 84%
rename from mustache/lib/mustache.dart
rename to mustache_template/lib/mustache.dart
index 945c9d2..687459c 100644
--- a/mustache/lib/mustache.dart
+++ b/mustache_template/lib/mustache.dart
@@ -1,14 +1,5 @@
-/// [Mustache template documentation](http://mustache.github.com/mustache.5.html)
-
-library mustache;
-
 import 'src/template.dart' as t;
 
-/// Use new Template(source) instead.
-@deprecated
-Template parse(String source, {bool lenient: false}) =>
-    new Template(source, lenient: lenient);
-
 /// A Template can be efficiently rendered multiple times with different
 /// values.
 abstract class Template {
@@ -37,9 +28,9 @@
   void render(values, StringSink sink);
 }
 
-typedef Template PartialResolver(String templateName);
+typedef PartialResolver = Template Function(String);
 
-typedef Object LambdaFunction(LambdaContext context);
+typedef LambdaFunction = Object Function(LambdaContext context);
 
 /// Passed as an argument to a mustache lambda function. The methods on
 /// this object may only be called before the lambda function returns. If a
@@ -69,13 +60,6 @@
   Object lookup(String variableName);
 }
 
-const MustacheMirrorsUsedAnnotation mustache =
-    const MustacheMirrorsUsedAnnotation();
-
-class MustacheMirrorsUsedAnnotation {
-  const MustacheMirrorsUsedAnnotation();
-}
-
 /// [TemplateException] is used to obtain the line and column numbers
 /// of the token which caused parse or render to fail.
 abstract class TemplateException implements Exception {
@@ -101,6 +85,4 @@
   /// A short source substring of the source at the point the problem occurred
   /// with parsing or rendering.
   String get context;
-
-  String toString();
 }
diff --git a/mustache_template/lib/mustache_template.dart b/mustache_template/lib/mustache_template.dart
new file mode 100644
index 0000000..299de3a
--- /dev/null
+++ b/mustache_template/lib/mustache_template.dart
@@ -0,0 +1 @@
+export 'mustache.dart';
diff --git a/mustache/lib/src/lambda_context.dart b/mustache_template/lib/src/lambda_context.dart
similarity index 70%
rename from mustache/lib/src/lambda_context.dart
rename to mustache_template/lib/src/lambda_context.dart
index e233248..31d0a96 100644
--- a/mustache/lib/src/lambda_context.dart
+++ b/mustache_template/lib/src/lambda_context.dart
@@ -1,6 +1,4 @@
-library mustache.lambda_context;
-
-import 'package:mustache/mustache.dart' as m;
+import 'package:mustache_template/mustache.dart' as m;
 
 import 'node.dart';
 import 'parser.dart' as parser;
@@ -24,41 +22,45 @@
   }
 
   TemplateException _error(String msg) {
-    return new TemplateException(
+    return TemplateException(
         msg, _renderer.templateName, _renderer.source, _node.start);
   }
 
-  /// Render the current section tag in the current context and return the
-  /// result as a string.
+  @override
   String renderString({Object value}) {
     _checkClosed();
-    if (_node is! SectionNode) _error(
-        'LambdaContext.renderString() can only be called on section tags.');
-    var sink = new StringBuffer();
+    if (_node is! SectionNode) {
+      _error(
+          'LambdaContext.renderString() can only be called on section tags.');
+    }
+    var sink = StringBuffer();
     _renderSubtree(sink, value);
     return sink.toString();
   }
 
   void _renderSubtree(StringSink sink, Object value) {
-    var renderer = new Renderer.subtree(_renderer, sink);
+    var renderer = Renderer.subtree(_renderer, sink);
     SectionNode section = _node;
     if (value != null) renderer.push(value);
     renderer.render(section.children);
   }
 
+  @override
   void render({Object value}) {
     _checkClosed();
-    if (_node is! SectionNode) _error(
-        'LambdaContext.render() can only be called on section tags.');
+    if (_node is! SectionNode) {
+      _error('LambdaContext.render() can only be called on section tags.');
+    }
     _renderSubtree(_renderer.sink, value);
   }
 
+  @override
   void write(Object object) {
     _checkClosed();
     _renderer.write(object);
   }
 
-  /// Get the unevaluated template source for the current section tag.
+  @override
   String get source {
     _checkClosed();
 
@@ -77,10 +79,10 @@
     return _renderer.source.substring(node.contentStart, node.contentEnd);
   }
 
-  /// Evaluate the string as a mustache template using the current context.
+  @override
   String renderSource(String source, {Object value}) {
     _checkClosed();
-    var sink = new StringBuffer();
+    var sink = StringBuffer();
 
     // Lambdas used for sections should parse with the current delimiters.
     var delimiters = '{{ }}';
@@ -92,8 +94,8 @@
     var nodes = parser.parse(
         source, _renderer.lenient, _renderer.templateName, delimiters);
 
-    var renderer = new Renderer.lambda(
-        _renderer, source, _renderer.indent, sink, delimiters);
+    var renderer =
+        Renderer.lambda(_renderer, source, _renderer.indent, sink, delimiters);
 
     if (value != null) renderer.push(value);
     renderer.render(nodes);
@@ -101,7 +103,7 @@
     return sink.toString();
   }
 
-  /// Lookup the value of a variable in the current context.
+  @override
   Object lookup(String variableName) {
     _checkClosed();
     return _renderer.resolveValue(variableName);
diff --git a/mustache/lib/src/node.dart b/mustache_template/lib/src/node.dart
similarity index 84%
rename from mustache/lib/src/node.dart
rename to mustache_template/lib/src/node.dart
index 046baff..0c52012 100644
--- a/mustache/lib/src/node.dart
+++ b/mustache_template/lib/src/node.dart
@@ -1,5 +1,3 @@
-library mustache.node;
-
 abstract class Node {
   Node(this.start, this.end);
 
@@ -25,6 +23,7 @@
 
   final String text;
 
+  @override
   String toString() => '(TextNode "$_debugText" $start $end)';
 
   String get _debugText {
@@ -32,24 +31,27 @@
     return t.length < 50 ? t : t.substring(0, 48) + '...';
   }
 
+  @override
   void accept(Visitor visitor) => visitor.visitText(this);
 }
 
 class VariableNode extends Node {
-  VariableNode(this.name, int start, int end, {this.escape: true})
+  VariableNode(this.name, int start, int end, {this.escape = true})
       : super(start, end);
 
   final String name;
   final bool escape;
 
+  @override
   void accept(Visitor visitor) => visitor.visitVariable(this);
 
+  @override
   String toString() => '(VariableNode "$name" escape: $escape $start $end)';
 }
 
 class SectionNode extends Node {
   SectionNode(this.name, int start, int end, this.delimiters,
-      {this.inverse: false})
+      {this.inverse = false})
       : contentStart = end,
         super(start, end);
 
@@ -60,13 +62,16 @@
   int contentEnd; // Set in parser when close tag is parsed.
   final List<Node> children = <Node>[];
 
+  @override
   void accept(Visitor visitor) => visitor.visitSection(this);
 
+  @override
   void visitChildren(Visitor visitor) {
     children.forEach((node) => node.accept(visitor));
   }
 
-  toString() => '(SectionNode $name inverse: $inverse $start $end)';
+  @override
+  String toString() => '(SectionNode $name inverse: $inverse $start $end)';
 }
 
 class PartialNode extends Node {
@@ -78,7 +83,9 @@
   // it's content can be correctly indented.
   final String indent;
 
+  @override
   void accept(Visitor visitor) => visitor.visitPartial(this);
 
-  toString() => '(PartialNode $name $start $end "$indent")';
+  @override
+  String toString() => '(PartialNode $name $start $end "$indent")';
 }
diff --git a/mustache/lib/src/parser.dart b/mustache_template/lib/src/parser.dart
similarity index 80%
rename from mustache/lib/src/parser.dart
rename to mustache_template/lib/src/parser.dart
index 5ebb0c0..867cce6 100644
--- a/mustache/lib/src/parser.dart
+++ b/mustache_template/lib/src/parser.dart
@@ -1,5 +1,3 @@
-library mustache.parser;
-
 import 'node.dart';
 import 'scanner.dart';
 import 'template_exception.dart';
@@ -7,7 +5,7 @@
 
 List<Node> parse(
     String source, bool lenient, String templateName, String delimiters) {
-  var parser = new Parser(source, templateName, delimiters, lenient: lenient);
+  var parser = Parser(source, templateName, delimiters, lenient: lenient);
   return parser.parse();
 }
 
@@ -23,26 +21,25 @@
   const TagType(this.name);
   final String name;
 
-  static const TagType openSection = const TagType('openSection');
-  static const TagType openInverseSection = const TagType('openInverseSection');
-  static const TagType closeSection = const TagType('closeSection');
-  static const TagType variable = const TagType('variable');
-  static const TagType tripleMustache = const TagType('tripleMustache');
-  static const TagType unescapedVariable = const TagType('unescapedVariable');
-  static const TagType partial = const TagType('partial');
-  static const TagType comment = const TagType('comment');
-  static const TagType changeDelimiter = const TagType('changeDelimiter');
+  static const TagType openSection = TagType('openSection');
+  static const TagType openInverseSection = TagType('openInverseSection');
+  static const TagType closeSection = TagType('closeSection');
+  static const TagType variable = TagType('variable');
+  static const TagType tripleMustache = TagType('tripleMustache');
+  static const TagType unescapedVariable = TagType('unescapedVariable');
+  static const TagType partial = TagType('partial');
+  static const TagType comment = TagType('comment');
+  static const TagType changeDelimiter = TagType('changeDelimiter');
 }
 
 class Parser {
   Parser(String source, String templateName, String delimiters,
-      {lenient: false})
+      {lenient = false})
       : _source = source,
         _templateName = templateName,
         _delimiters = delimiters,
         _lenient = lenient,
-        _scanner =
-            new Scanner(source, templateName, delimiters);
+        _scanner = Scanner(source, templateName, delimiters);
 
   final String _source;
   final bool _lenient;
@@ -58,7 +55,7 @@
     _tokens = _scanner.scan();
     _currentDelimiters = _delimiters;
     _stack.clear();
-    _stack.add(new SectionNode('root', 0, 0, _delimiters));
+    _stack.add(SectionNode('root', 0, 0, _delimiters));
 
     // Handle a standalone tag on first line, including special case where the
     // first line is empty.
@@ -91,12 +88,12 @@
           break;
 
         default:
-          throw new Exception('Unreachable code.');
+          throw Exception('Unreachable code.');
       }
     }
 
     if (_stack.length != 1) {
-      throw new TemplateException("Unclosed tag: '${_stack.last.name}'.",
+      throw TemplateException("Unclosed tag: '${_stack.last.name}'.",
           _templateName, _source, _stack.last.start);
     }
 
@@ -108,7 +105,7 @@
 
   // Returns null on EOF.
   Token _read() {
-    var t = null;
+    Token t;
     if (_offset < _tokens.length) {
       t = _tokens[_offset];
       _offset++;
@@ -125,7 +122,7 @@
     return token;
   }
 
-  Token _readIf(TokenType type, {eofOk: false}) {
+  Token _readIf(TokenType type, {eofOk = false}) {
     var token = _peek();
     if (!eofOk && token == null) throw _errorEof();
     return token != null && token.type == type ? _read() : null;
@@ -135,7 +132,7 @@
       _error('Unexpected end of input.', _source.length - 1);
 
   TemplateException _error(String msg, int offset) =>
-      new TemplateException(msg, _templateName, _source, offset);
+      TemplateException(msg, _templateName, _source, offset);
 
   // Add a text node to top most section on the stack and merge consecutive
   // text nodes together.
@@ -144,10 +141,10 @@
         .contains(token.type));
     var children = _stack.last.children;
     if (children.isEmpty || children.last is! TextNode) {
-      children.add(new TextNode(token.value, token.start, token.end));
+      children.add(TextNode(token.value, token.start, token.end));
     } else {
       var last = children.removeLast() as TextNode;
-      var node = new TextNode(last.text + token.value, last.start, token.end);
+      var node = TextNode(last.text + token.value, last.start, token.end);
       children.add(node);
     }
   }
@@ -167,8 +164,8 @@
       // {{/...}}
       case TagType.closeSection:
         if (tag.name != _stack.last.name) {
-          throw new TemplateException(
-              "Mismatched tag, expected: "
+          throw TemplateException(
+              'Mismatched tag, expected: '
               "'${_stack.last.name}', was: '${tag.name}'",
               _templateName,
               _source,
@@ -192,7 +189,7 @@
         break;
 
       default:
-        throw new Exception('Unreachable code.');
+        throw Exception('Unreachable code.');
     }
   }
 
@@ -222,7 +219,7 @@
       var tagNode = _createNodeFromTag(tag, partialIndent: indent);
       var followingWhitespace = _readIf(TokenType.whitespace, eofOk: true);
 
-      const standaloneTypes = const [
+      const standaloneTypes = [
         TagType.openSection,
         TagType.closeSection,
         TagType.openInverseSection,
@@ -249,9 +246,9 @@
     }
   }
 
-  final RegExp _validIdentifier = new RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
+  final RegExp _validIdentifier = RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
 
-  static const _tagTypeMap = const {
+  static const _tagTypeMap = {
     '#': TagType.openSection,
     '^': TagType.openInverseSection,
     '/': TagType.closeSection,
@@ -275,7 +272,7 @@
 
       // Change delimiter tags are already parsed by the scanner.
       // So just create a tag and return it.
-      return new Tag(TagType.changeDelimiter, t.value, t.start, t.end);
+      return Tag(TagType.changeDelimiter, t.value, t.start, t.end);
     }
 
     // Start parsing a typical tag.
@@ -331,31 +328,33 @@
 
     var close = _expect(TokenType.closeDelimiter);
 
-    return new Tag(tagType, name, open.start, close.end);
+    return Tag(tagType, name, open.start, close.end);
   }
 
-  Node _createNodeFromTag(Tag tag, {String partialIndent: ''}) {
+  Node _createNodeFromTag(Tag tag, {String partialIndent = ''}) {
     // Handle EOF case.
-    if (tag == null) return null;
+    if (tag == null) {
+      return null;
+    }
 
-    Node node = null;
+    Node node;
     switch (tag.type) {
       case TagType.openSection:
       case TagType.openInverseSection:
-        bool inverse = tag.type == TagType.openInverseSection;
-        node = new SectionNode(tag.name, tag.start, tag.end, _currentDelimiters,
+        var inverse = tag.type == TagType.openInverseSection;
+        node = SectionNode(tag.name, tag.start, tag.end, _currentDelimiters,
             inverse: inverse);
         break;
 
       case TagType.variable:
       case TagType.unescapedVariable:
       case TagType.tripleMustache:
-        bool escape = tag.type == TagType.variable;
-        node = new VariableNode(tag.name, tag.start, tag.end, escape: escape);
+        var escape = tag.type == TagType.variable;
+        node = VariableNode(tag.name, tag.start, tag.end, escape: escape);
         break;
 
       case TagType.partial:
-        node = new PartialNode(tag.name, tag.start, tag.end, partialIndent);
+        node = PartialNode(tag.name, tag.start, tag.end, partialIndent);
         break;
 
       case TagType.closeSection:
@@ -365,7 +364,7 @@
         break;
 
       default:
-        throw new Exception('Unreachable code');
+        throw Exception('Unreachable code');
     }
     return node;
   }
diff --git a/mustache/lib/src/renderer.dart b/mustache_template/lib/src/renderer.dart
similarity index 80%
rename from mustache/lib/src/renderer.dart
rename to mustache_template/lib/src/renderer.dart
index bccd7e4..74ca3cf 100644
--- a/mustache/lib/src/renderer.dart
+++ b/mustache_template/lib/src/renderer.dart
@@ -1,22 +1,16 @@
-library mustache.renderer;
-
-@MirrorsUsed(metaTargets: const [m.MustacheMirrorsUsedAnnotation])
-import 'dart:mirrors';
-import 'package:mustache/mustache.dart' as m;
+import 'package:mustache_template/mustache.dart' as m;
 import 'lambda_context.dart';
 import 'node.dart';
 import 'template.dart';
 import 'template_exception.dart';
 
-final RegExp _validTag = new RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
-final RegExp _integerTag = new RegExp(r'^[0-9]+$');
-
-const Object noSuchProperty = const Object();
+const Object noSuchProperty = Object();
+final RegExp _integerTag = RegExp(r'^[0-9]+$');
 
 class Renderer extends Visitor {
   Renderer(this.sink, List stack, this.lenient, this.htmlEscapeValues,
       this.partialResolver, this.templateName, this.indent, this.source)
-      : _stack = new List.from(stack);
+      : _stack = List.from(stack);
 
   Renderer.partial(Renderer ctx, Template partial, String indent)
       : this(
@@ -72,7 +66,8 @@
     }
   }
 
-  void visitText(TextNode node, {bool lastNode: false}) {
+  @override
+  void visitText(TextNode node, {bool lastNode = false}) {
     if (node.text == '') return;
     if (indent == null || indent == '') {
       write(node.text);
@@ -86,19 +81,21 @@
     }
   }
 
+  @override
   void visitVariable(VariableNode node) {
     var value = resolveValue(node.name);
 
     if (value is Function) {
-      var context = new LambdaContext(node, this);
+      var context = LambdaContext(node, this);
       Function valueFunction = value;
       value = valueFunction(context);
       context.close();
     }
 
     if (value == noSuchProperty) {
-      if (!lenient)
+      if (!lenient) {
         throw error('Value was missing for variable tag: ${node.name}.', node);
+      }
     } else {
       var valueString = (value == null) ? '' : value.toString();
       var output = !node.escape || !htmlEscapeValues
@@ -108,11 +105,13 @@
     }
   }
 
+  @override
   void visitSection(SectionNode node) {
-    if (node.inverse)
+    if (node.inverse) {
       _renderInvSection(node);
-    else
+    } else {
       _renderSection(node);
+    }
   }
 
   //TODO can probably combine Inv and Normal to shorten.
@@ -132,10 +131,11 @@
       // Do nothing.
 
     } else if (value == noSuchProperty) {
-      if (!lenient)
+      if (!lenient) {
         throw error('Value was missing for section tag: ${node.name}.', node);
+      }
     } else if (value is Function) {
-      var context = new LambdaContext(node, this);
+      var context = LambdaContext(node, this);
       var output = value(context);
       context.close();
       if (output != null) write(output);
@@ -185,12 +185,13 @@
     pop();
   }
 
+  @override
   void visitPartial(PartialNode node) {
     var partialName = node.name;
     Template template =
         partialResolver == null ? null : partialResolver(partialName);
     if (template != null) {
-      var renderer = new Renderer.partial(this, template, node.indent);
+      var renderer = Renderer.partial(this, template, node.indent);
       var nodes = getTemplateNodes(template);
       renderer.render(nodes);
     } else if (lenient) {
@@ -214,7 +215,7 @@
         break;
       }
     }
-    for (int i = 1; i < parts.length; i++) {
+    for (var i = 1; i < parts.length; i++) {
       if (object == null || object == noSuchProperty) {
         return noSuchProperty;
       }
@@ -227,35 +228,20 @@
   // which contains the key name, this is object[name]. For other
   // objects, this is object.name or object.name(). If no property
   // by the given name exists, this method returns noSuchProperty.
-  _getNamedProperty(object, name) {
+  Object _getNamedProperty(dynamic object, dynamic name) {
     if (object is Map && object.containsKey(name)) return object[name];
 
-    if (object is List && _integerTag.hasMatch(name))
+    if (object is List && _integerTag.hasMatch(name)) {
       return object[int.parse(name)];
-
-    if (lenient && !_validTag.hasMatch(name)) return noSuchProperty;
-
-    var instance = reflect(object);
-    var field = instance.type.instanceMembers[new Symbol(name)];
-    if (field == null) return noSuchProperty;
-
-    var invocation = null;
-    if ((field is VariableMirror) ||
-        ((field is MethodMirror) && (field.isGetter))) {
-      invocation = instance.getField(field.simpleName);
-    } else if ((field is MethodMirror) && (field.parameters.where((p) => !p.isOptional).length == 0)) {
-      invocation = instance.invoke(field.simpleName, []);
     }
-    if (invocation == null) {
-      return noSuchProperty;
-    }
-    return invocation.reflectee;
+
+    return noSuchProperty;
   }
 
   m.TemplateException error(String message, Node node) =>
-      new TemplateException(message, templateName, source, node.start);
+      TemplateException(message, templateName, source, node.start);
 
-  static const Map<int, String> _htmlEscapeMap = const {
+  static const Map<int, String> _htmlEscapeMap = {
     _AMP: '&amp;',
     _LT: '&lt;',
     _GT: '&gt;',
@@ -265,10 +251,10 @@
   };
 
   String _htmlEscape(String s) {
-    var buffer = new StringBuffer();
-    int startIndex = 0;
-    int i = 0;
-    for (int c in s.runes) {
+    var buffer = StringBuffer();
+    var startIndex = 0;
+    var i = 0;
+    for (var c in s.runes) {
       if (c == _AMP ||
           c == _LT ||
           c == _GT ||
diff --git a/mustache/lib/src/scanner.dart b/mustache_template/lib/src/scanner.dart
similarity index 84%
rename from mustache/lib/src/scanner.dart
rename to mustache_template/lib/src/scanner.dart
index 2a668b5..992566a 100644
--- a/mustache/lib/src/scanner.dart
+++ b/mustache_template/lib/src/scanner.dart
@@ -1,5 +1,3 @@
-library mustache.scanner;
-
 import 'token.dart';
 import 'template_exception.dart';
 
@@ -26,7 +24,7 @@
       _closeDelimiterInner = delimiters.codeUnits[3];
       _closeDelimiter = delimiters.codeUnits[4];
     } else {
-      throw new TemplateException(
+      throw TemplateException(
           'Invalid delimiter string $delimiters', null, null, null);
     }
   }
@@ -38,7 +36,7 @@
   int _offset = 0;
   int _c = 0;
 
-  final List<Token> _tokens = new List<Token>();
+  final List<Token> _tokens = <Token>[];
 
   // These can be changed by the change delimiter tag.
   int _openDelimiter;
@@ -47,21 +45,21 @@
   int _closeDelimiter;
 
   List<Token> scan() {
-    for (int c = _peek(); c != _EOF; c = _peek()) {
+    for (var c = _peek(); c != _EOF; c = _peek()) {
       // Scan text tokens.
       if (c != _openDelimiter) {
         _scanText();
         continue;
       }
 
-      int start = _offset;
+      var start = _offset;
 
       // Read first open delimiter character.
       _read();
 
       // If only a single delimiter character then create a text token.
       if (_openDelimiterInner != null && _peek() != _openDelimiterInner) {
-        var value = new String.fromCharCode(_openDelimiter);
+        var value = String.fromCharCode(_openDelimiter);
         _append(TokenType.text, value, start, _offset);
         continue;
       }
@@ -79,14 +77,14 @@
       } else {
         // Check to see if this is a change delimiter tag. {{= | | =}}
         // Need to skip whitespace and check for "=".
-        int wsStart = _offset;
+        var wsStart = _offset;
         var ws = _readWhile(_isWhitespace);
 
         if (_peek() == _EQUAL) {
           _parseChangeDelimiterTag(start);
         } else {
           // Scan standard mustache tag.
-          var value = new String.fromCharCodes(_openDelimiterInner == null
+          var value = String.fromCharCodes(_openDelimiterInner == null
               ? [_openDelimiter]
               : [_openDelimiter, _openDelimiterInner]);
 
@@ -105,33 +103,34 @@
   int _peek() => _c;
 
   int _read() {
-    int c = _c;
+    var c = _c;
     _offset++;
     _c = _itr.moveNext() ? _itr.current : _EOF;
     return c;
   }
 
-  String _readWhile(bool test(int charCode)) {
+  String _readWhile(bool Function(int charCode) test) {
     if (_c == _EOF) return '';
-    int start = _offset;
+    var start = _offset;
     while (_peek() != _EOF && test(_peek())) {
       _read();
     }
-    int end = _peek() == _EOF ? _source.length : _offset;
+    var end = _peek() == _EOF ? _source.length : _offset;
     return _source.substring(start, end);
   }
 
-  _expect(int expectedCharCode) {
-    int c = _read();
+  void _expect(int expectedCharCode) {
+    var c = _read();
 
     if (c == _EOF) {
-      throw new TemplateException(
+      throw TemplateException(
           'Unexpected end of input', _templateName, _source, _offset - 1);
-    } else if (c != expectedCharCode) {
-      throw new TemplateException(
+    }
+    if (c != expectedCharCode) {
+      throw TemplateException(
           'Unexpected character, '
-          'expected: ${new String.fromCharCode(expectedCharCode)}, '
-          'was: ${new String.fromCharCode(c)}',
+          'expected: ${String.fromCharCode(expectedCharCode)}, '
+          'was: ${String.fromCharCode(c)}',
           _templateName,
           _source,
           _offset - 1);
@@ -139,7 +138,7 @@
   }
 
   void _append(TokenType type, String value, int start, int end) =>
-      _tokens.add(new Token(type, value, start, end));
+      _tokens.add(Token(type, value, start, end));
 
   bool _isWhitespace(int c) =>
       const [_SPACE, _TAB, _NEWLINE, _RETURN].contains(c);
@@ -148,11 +147,11 @@
   // tokens for whitespace at the begining of a line. This is because the
   // mustache spec requires special handing of whitespace.
   void _scanText() {
-    int start = 0;
+    var start = 0;
     TokenType token;
     String value;
 
-    for (int c = _peek(); c != _EOF && c != _openDelimiter; c = _peek()) {
+    for (var c = _peek(); c != _EOF && c != _openDelimiter; c = _peek()) {
       start = _offset;
 
       switch (c) {
@@ -199,7 +198,7 @@
         (_closeDelimiterInner == null && c == _closeDelimiter) ||
         (_closeDelimiterInner != null && c == _closeDelimiterInner);
 
-    for (int c = _peek(); c != _EOF && !isCloseDelimiter(c); c = _peek()) {
+    for (var c = _peek(); c != _EOF && !isCloseDelimiter(c); c = _peek()) {
       start = _offset;
 
       switch (c) {
@@ -211,7 +210,7 @@
         case _EXCLAIM:
           _read();
           token = TokenType.sigil;
-          value = new String.fromCharCode(c);
+          value = String.fromCharCode(c);
           break;
 
         case _SPACE:
@@ -255,12 +254,12 @@
   // Scan close delimiter token.
   void _scanCloseDelimiter() {
     if (_peek() != _EOF) {
-      int start = _offset;
+      var start = _offset;
 
       if (_closeDelimiterInner != null) _expect(_closeDelimiterInner);
       _expect(_closeDelimiter);
 
-      String value = new String.fromCharCodes(_closeDelimiterInner == null
+      var value = String.fromCharCodes(_closeDelimiterInner == null
           ? [_closeDelimiter]
           : [_closeDelimiterInner, _closeDelimiter]);
 
@@ -271,7 +270,7 @@
   // Scan close triple mustache delimiter token.
   void _scanCloseTripleMustache() {
     if (_peek() != _EOF) {
-      int start = _offset;
+      var start = _offset;
 
       _expect(_CLOSE_MUSTACHE);
       _expect(_CLOSE_MUSTACHE);
@@ -307,8 +306,9 @@
 
     c = _read();
 
-    if (_isWhitespace(c) || c == _EQUAL)
+    if (_isWhitespace(c) || c == _EQUAL) {
       throw _error('Incorrect change delimiter tag.');
+    }
 
     if (_isWhitespace(_peek()) || _peek() == _EQUAL) {
       _closeDelimiterInner = null;
@@ -328,7 +328,7 @@
     _expect(delimiter);
 
     // Create delimiter string.
-    var buffer = new StringBuffer();
+    var buffer = StringBuffer();
     buffer.writeCharCode(_openDelimiter);
     if (_openDelimiterInner != null) buffer.writeCharCode(_openDelimiterInner);
     buffer.write(' ');
@@ -342,7 +342,7 @@
   }
 
   TemplateException _error(String message) {
-    return new TemplateException(message, _templateName, _source, _offset);
+    return TemplateException(message, _templateName, _source, _offset);
   }
 }
 
@@ -352,26 +352,13 @@
 const int _RETURN = 13;
 const int _SPACE = 32;
 const int _EXCLAIM = 33;
-const int _QUOTE = 34;
-const int _APOS = 39;
 const int _HASH = 35;
 const int _AMP = 38;
 const int _PERIOD = 46;
 const int _FORWARD_SLASH = 47;
-const int _LT = 60;
 const int _EQUAL = 61;
 const int _GT = 62;
 const int _CARET = 94;
 
 const int _OPEN_MUSTACHE = 123;
 const int _CLOSE_MUSTACHE = 125;
-
-const int _A = 65;
-const int _Z = 90;
-const int _a = 97;
-const int _z = 122;
-const int _0 = 48;
-const int _9 = 57;
-
-const int _UNDERSCORE = 95;
-const int _MINUS = 45;
diff --git a/mustache/lib/src/template.dart b/mustache_template/lib/src/template.dart
similarity index 70%
rename from mustache/lib/src/template.dart
rename to mustache_template/lib/src/template.dart
index 2a33b28..a38cc97 100644
--- a/mustache/lib/src/template.dart
+++ b/mustache_template/lib/src/template.dart
@@ -1,17 +1,15 @@
-library mustache.template;

-

-import 'package:mustache/mustache.dart' as m;

+import 'package:mustache_template/mustache.dart' as m;

 import 'node.dart';

 import 'parser.dart' as parser;

 import 'renderer.dart';

 

 class Template implements m.Template {

   Template.fromSource(String source,

-      {bool lenient: false,

-      bool htmlEscapeValues: true,

+      {bool lenient = false,

+      bool htmlEscapeValues = true,

       String name,

       m.PartialResolver partialResolver,

-      String delimiters: "{{ }}"})

+      String delimiters = '{{ }}'})

       : source = source,

         _nodes = parser.parse(source, lenient, name, delimiters),

         _lenient = lenient,

@@ -19,6 +17,7 @@
         _name = name,

         _partialResolver = partialResolver;

 

+  @override

   final String source;

   final List<Node> _nodes;

   final bool _lenient;

@@ -26,20 +25,23 @@
   final String _name;

   final m.PartialResolver _partialResolver;

 

+  @override

   String get name => _name;

 

+  @override

   String renderString(values) {

-    var buf = new StringBuffer();

+    var buf = StringBuffer();

     render(values, buf);

     return buf.toString();

   }

 

+  @override

   void render(values, StringSink sink) {

-    var renderer = new Renderer(sink, [values], _lenient, _htmlEscapeValues,

+    var renderer = Renderer(sink, [values], _lenient, _htmlEscapeValues,

         _partialResolver, _name, '', source);

     renderer.render(_nodes);

   }

 }

 

 // Expose getter for nodes internally within this package.

-getTemplateNodes(Template template) => template._nodes;

+List<Node> getTemplateNodes(Template template) => template._nodes;

diff --git a/mustache/lib/src/template_exception.dart b/mustache_template/lib/src/template_exception.dart
similarity index 70%
rename from mustache/lib/src/template_exception.dart
rename to mustache_template/lib/src/template_exception.dart
index c1b24ce..d067bdd 100644
--- a/mustache/lib/src/template_exception.dart
+++ b/mustache_template/lib/src/template_exception.dart
@@ -1,13 +1,15 @@
-library mustache.template_exception;
-
-import 'package:mustache/mustache.dart' as m;
+import 'package:mustache_template/mustache.dart' as m;
 
 class TemplateException implements m.TemplateException {
   TemplateException(this.message, this.templateName, this.source, this.offset);
 
+  @override
   final String message;
+  @override
   final String templateName;
+  @override
   final String source;
+  @override
   final int offset;
 
   bool _isUpdated = false;
@@ -15,21 +17,25 @@
   int _column;
   String _context;
 
+  @override
   int get line {
     _update();
     return _line;
   }
 
+  @override
   int get column {
     _update();
     return _column;
   }
 
+  @override
   String get context {
     _update();
     return _context;
   }
 
+  @override
   String toString() {
     var list = [];
     if (templateName != null) list.add(templateName);
@@ -49,14 +55,14 @@
         (offset < 0 || offset > source.length)) return;
 
     // Find line and character column.
-    int lineNum = 1;
-    int lineStart = 0;
-    bool lastWasCR = false;
-    for (int i = 0; i < offset; i++) {
-      int char = source.codeUnitAt(i);
+    var lineNum = 1;
+    var lineStart = 0;
+    var lastWasCR = false;
+    for (var i = 0; i < offset; i++) {
+      var char = source.codeUnitAt(i);
       if (char == 0x0a) {
         if (lineStart != i || !lastWasCR) {
-          lineNum++;
+          lineNum += 1;
         }
         lineStart = i + 1;
         lastWasCR = false;
@@ -71,38 +77,38 @@
     _column = offset - lineStart + 1;
 
     // Find context.
-    int lineEnd = source.length;
-    for (int i = offset; i < source.length; i++) {
-      int char = source.codeUnitAt(i);
+    var lineEnd = source.length;
+    for (var i = offset; i < source.length; i++) {
+      var char = source.codeUnitAt(i);
       if (char == 0x0a || char == 0x0d) {
         lineEnd = i;
         break;
       }
     }
-    int length = lineEnd - lineStart;
-    int start = lineStart;
-    int end = lineEnd;
-    String prefix = "";
-    String postfix = "";
+    var length = lineEnd - lineStart;
+    var start = lineStart;
+    var end = lineEnd;
+    var prefix = '';
+    var postfix = '';
     if (length > 78) {
       // Can't show entire line. Try to anchor at the nearest end, if
       // one is within reach.
-      int index = offset - lineStart;
+      var index = offset - lineStart;
       if (index < 75) {
         end = start + 75;
-        postfix = "...";
+        postfix = '...';
       } else if (end - offset < 75) {
         start = end - 75;
-        prefix = "...";
+        prefix = '...';
       } else {
         // Neither end is near, just pick an area around the offset.
         start = offset - 36;
         end = offset + 36;
-        prefix = postfix = "...";
+        prefix = postfix = '...';
       }
     }
-    String slice = source.substring(start, end);
-    int markOffset = offset - start + prefix.length;
+    var slice = source.substring(start, end);
+    var markOffset = offset - start + prefix.length;
 
     _context = "$prefix$slice$postfix\n${" " * markOffset}^\n";
   }
diff --git a/mustache_template/lib/src/token.dart b/mustache_template/lib/src/token.dart
new file mode 100644
index 0000000..d31361e
--- /dev/null
+++ b/mustache_template/lib/src/token.dart
@@ -0,0 +1,35 @@
+class TokenType {
+  const TokenType(this.name);
+
+  final String name;
+
+  @override
+  String toString() => '(TokenType $name)';
+
+  static const TokenType text = TokenType('text');
+  static const TokenType openDelimiter = TokenType('openDelimiter');
+  static const TokenType closeDelimiter = TokenType('closeDelimiter');
+
+  // A sigil is the word commonly used to describe the special character at the
+  // start of mustache tag i.e. #, ^ or /.
+  static const TokenType sigil = TokenType('sigil');
+  static const TokenType identifier = TokenType('identifier');
+  static const TokenType dot = TokenType('dot');
+
+  static const TokenType changeDelimiter = TokenType('changeDelimiter');
+  static const TokenType whitespace = TokenType('whitespace');
+  static const TokenType lineEnd = TokenType('lineEnd');
+}
+
+class Token {
+  Token(this.type, this.value, this.start, this.end);
+
+  final TokenType type;
+  final String value;
+
+  final int start;
+  final int end;
+
+  @override
+  String toString() => '(Token ${type.name} \"$value\" $start $end)';
+}
diff --git a/mustache_template/pubspec.yaml b/mustache_template/pubspec.yaml
new file mode 100644
index 0000000..216a1e4
--- /dev/null
+++ b/mustache_template/pubspec.yaml
@@ -0,0 +1,11 @@
+name: mustache_template
+version: 1.0.0+1
+description: A mustache template library that supports dart2js and dart2native
+homepage: https://github.com/jonahwilliams/mustache
+
+environment:
+  sdk: '>=2.0.0 <3.0.0'
+
+dev_dependencies:
+  test: '>=0.12.0 <2.0.0'
+  pedantic: 1.9.0
diff --git a/mustache/tool/travis.sh b/mustache_template/tool/travis.sh
similarity index 100%
rename from mustache/tool/travis.sh
rename to mustache_template/tool/travis.sh
diff --git a/package_config/.travis.yml b/package_config/.travis.yml
index 655bf3d..09fc296 100644
--- a/package_config/.travis.yml
+++ b/package_config/.travis.yml
@@ -7,6 +7,11 @@
   - dartfmt
   - dartanalyzer: --fatal-warnings .
 
+matrix:
+  include:
+  - dart: dev
+    script: pub run build_runner test -- -p chrome
+
 # Only building master means that we don't run two builds for each pull request.
 branches:
   only: [master]
diff --git a/package_config/BUILD.gn b/package_config/BUILD.gn
index d100e3f..75d009c 100644
--- a/package_config/BUILD.gn
+++ b/package_config/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for package_config-1.1.0
+# This file is generated by importer.py for package_config-1.9.1
 
 import("//build/dart/dart_library.gni")
 
diff --git a/package_config/CHANGELOG.md b/package_config/CHANGELOG.md
index db4bb00..1cd45d0 100644
--- a/package_config/CHANGELOG.md
+++ b/package_config/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 1.9.1
+
+- Remove accidental transitive import of `dart:io` from entrypoints that are
+  supposed to be cross-platform compatible.
+
+## 1.9.0
+
+- Based on new JSON file format with more content.
+- This version includes all the new functionality intended for a 2.0.0
+  version, as well as the, now deprecated, version 1 functionality.
+  When we release 2.0.0, the deprectated functionality will be removed.
+
 ## 1.1.0
 
 - Allow parsing files with default-package entries and metadata.
diff --git a/package_config/CONTRIBUTING.md b/package_config/CONTRIBUTING.md
index 6f5e0ea..8423ff9 100644
--- a/package_config/CONTRIBUTING.md
+++ b/package_config/CONTRIBUTING.md
@@ -23,7 +23,7 @@
 ### File headers
 All files in the project must start with the following header.
 
-    // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+    // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
     // for details. All rights reserved. Use of this source code is governed by a
     // BSD-style license that can be found in the LICENSE file.
 
diff --git a/package_config/LICENSE b/package_config/LICENSE
index de31e1a..f75d7c2 100644
--- a/package_config/LICENSE
+++ b/package_config/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2015, the Dart project authors. All rights reserved.
+Copyright 2019, the Dart project authors. All rights reserved.
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
diff --git a/package_config/README.md b/package_config/README.md
index 9428220..b47a682 100644
--- a/package_config/README.md
+++ b/package_config/README.md
@@ -1,13 +1,18 @@
-# package_config
+[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config)
+[![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dev/packages/package_config)
 
-Support for working with **Package Resolution Configuration** files as described 
-in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), 
-under review [here](https://github.com/dart-lang/dart_enhancement_proposals/issues/5).
+Support for working with **Package Configuration** files as described
+in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md).
 
-[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) 
+The primary libraries are
+* `package_config.dart`:
+    Defines the `PackageConfig` class and other types needed to use
+    package configurations.
 
-## Features and bugs
+* `package_config_discovery.dart`:
+    Provides functions for reading configurations from files,
+    and writing them back out.
 
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/package_config/issues
+The package includes deprecated backwards compatible functionality to
+work with the `.packages` file. This functionality will not be maintained,
+and will be removed in a future version of this package.
diff --git a/package_config/analysis_options.yaml b/package_config/analysis_options.yaml
new file mode 100644
index 0000000..66639ec
--- /dev/null
+++ b/package_config/analysis_options.yaml
@@ -0,0 +1,11 @@
+# Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+# for 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: package:pedantic/analysis_options.1.9.0.yaml
+analyzer:
+  errors:
+    annotate_overrides: ignore
+    curly_braces_in_flow_control_structures: ignore
+    prefer_single_quotes: ignore
+    use_function_type_syntax_for_parameters: ignore
diff --git a/package_config/lib/discovery.dart b/package_config/lib/discovery.dart
index 57584b6..a2f53c0 100644
--- a/package_config/lib/discovery.dart
+++ b/package_config/lib/discovery.dart
@@ -2,6 +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("Use the package_config.json based API")
 library package_config.discovery;
 
 import "dart:async";
@@ -30,13 +31,11 @@
 Future<Packages> loadPackagesFile(Uri packagesFile,
     {Future<List<int>> loader(Uri uri)}) async {
   Packages parseBytes(List<int> bytes) {
-    Map<String, Uri> packageMap = pkgfile.parse(bytes, packagesFile);
-    return new MapPackages(packageMap);
+    return MapPackages(pkgfile.parse(bytes, packagesFile));
   }
 
   if (packagesFile.scheme == "file") {
-    File file = new File.fromUri(packagesFile);
-    return parseBytes(await file.readAsBytes());
+    return parseBytes(await File.fromUri(packagesFile).readAsBytes());
   }
   if (loader == null) {
     return parseBytes(await _httpGet(packagesFile));
@@ -54,13 +53,12 @@
 /// for example one specified using a `--package-root` comand-line parameter.
 Packages getPackagesDirectory(Uri packagesDir) {
   if (packagesDir.scheme == "file") {
-    Directory directory = new Directory.fromUri(packagesDir);
-    return new FilePackagesDirectoryPackages(directory);
+    return FilePackagesDirectoryPackages(Directory.fromUri(packagesDir));
   }
   if (!packagesDir.path.endsWith('/')) {
     packagesDir = packagesDir.replace(path: packagesDir.path + '/');
   }
-  return new NonFilePackagesDirectoryPackages(packagesDir);
+  return NonFilePackagesDirectoryPackages(packagesDir);
 }
 
 /// Discover the package configuration for a Dart script.
@@ -94,13 +92,13 @@
 Future<Packages> findPackages(Uri baseUri,
     {Future<List<int>> loader(Uri unsupportedUri)}) {
   if (baseUri.scheme == "file") {
-    return new Future<Packages>.sync(() => findPackagesFromFile(baseUri));
+    return Future<Packages>.sync(() => findPackagesFromFile(baseUri));
   } else if (loader != null) {
     return findPackagesFromNonFile(baseUri, loader: loader);
   } else if (baseUri.scheme == "http" || baseUri.scheme == "https") {
     return findPackagesFromNonFile(baseUri, loader: _httpGet);
   } else {
-    return new Future<Packages>.value(Packages.noPackages);
+    return Future<Packages>.value(Packages.noPackages);
   }
 }
 
@@ -114,15 +112,15 @@
 /// Returns a [File] object of a `.packages` file if one is found, or a
 /// [Directory] object for the `packages/` directory if that is found.
 FileSystemEntity _findPackagesFile(String workingDirectory) {
-  var dir = new Directory(workingDirectory);
+  var dir = Directory(workingDirectory);
   if (!dir.isAbsolute) dir = dir.absolute;
   if (!dir.existsSync()) {
-    throw new ArgumentError.value(
+    throw ArgumentError.value(
         workingDirectory, "workingDirectory", "Directory does not exist.");
   }
   File checkForConfigFile(Directory directory) {
     assert(directory.isAbsolute);
-    var file = new File(path.join(directory.path, ".packages"));
+    var file = File(path.join(directory.path, ".packages"));
     if (file.existsSync()) return file;
     return null;
   }
@@ -131,7 +129,7 @@
   var packagesCfgFile = checkForConfigFile(dir);
   if (packagesCfgFile != null) return packagesCfgFile;
   // Check for $cwd/packages/
-  var packagesDir = new Directory(path.join(dir.path, "packages"));
+  var packagesDir = Directory(path.join(dir.path, "packages"));
   if (packagesDir.existsSync()) return packagesDir;
   // Check for cwd(/..)+/.packages
   var parentDir = dir.parent;
@@ -156,21 +154,20 @@
 /// file, and stops if it finds it.
 /// Otherwise it gives up and returns [Packages.noPackages].
 Packages findPackagesFromFile(Uri fileBaseUri) {
-  Uri baseDirectoryUri = fileBaseUri;
+  var baseDirectoryUri = fileBaseUri;
   if (!fileBaseUri.path.endsWith('/')) {
     baseDirectoryUri = baseDirectoryUri.resolve(".");
   }
-  String baseDirectoryPath = baseDirectoryUri.toFilePath();
-  FileSystemEntity location = _findPackagesFile(baseDirectoryPath);
+  var baseDirectoryPath = baseDirectoryUri.toFilePath();
+  var location = _findPackagesFile(baseDirectoryPath);
   if (location == null) return Packages.noPackages;
   if (location is File) {
-    List<int> fileBytes = location.readAsBytesSync();
-    Map<String, Uri> map =
-        pkgfile.parse(fileBytes, new Uri.file(location.path));
-    return new MapPackages(map);
+    var fileBytes = location.readAsBytesSync();
+    var map = pkgfile.parse(fileBytes, Uri.file(location.path));
+    return MapPackages(map);
   }
   assert(location is Directory);
-  return new FilePackagesDirectoryPackages(location);
+  return FilePackagesDirectoryPackages(location);
 }
 
 /// Finds a package resolution strategy for a Dart script.
@@ -192,37 +189,37 @@
 /// UTF-8 encoded.
 Future<Packages> findPackagesFromNonFile(Uri nonFileUri,
     {Future<List<int>> loader(Uri name)}) async {
-  if (loader == null) loader = _httpGet;
-  Uri packagesFileUri = nonFileUri.resolve(".packages");
+  loader ??= _httpGet;
+  var packagesFileUri = nonFileUri.resolve(".packages");
 
   try {
-    List<int> fileBytes = await loader(packagesFileUri);
-    Map<String, Uri> map = pkgfile.parse(fileBytes, packagesFileUri);
-    return new MapPackages(map);
+    var fileBytes = await loader(packagesFileUri);
+    var map = pkgfile.parse(fileBytes, packagesFileUri);
+    return MapPackages(map);
   } catch (_) {
     // Didn't manage to load ".packages". Assume a "packages/" directory.
-    Uri packagesDirectoryUri = nonFileUri.resolve("packages/");
-    return new NonFilePackagesDirectoryPackages(packagesDirectoryUri);
+    var packagesDirectoryUri = nonFileUri.resolve("packages/");
+    return NonFilePackagesDirectoryPackages(packagesDirectoryUri);
   }
 }
 
 /// Fetches a file over http.
 Future<List<int>> _httpGet(Uri uri) async {
-  HttpClient client = new HttpClient();
-  HttpClientRequest request = await client.getUrl(uri);
-  HttpClientResponse response = await request.close();
+  var client = HttpClient();
+  var request = await client.getUrl(uri);
+  var response = await request.close();
   if (response.statusCode != HttpStatus.ok) {
-    throw new HttpException('${response.statusCode} ${response.reasonPhrase}',
+    throw HttpException('${response.statusCode} ${response.reasonPhrase}',
         uri: uri);
   }
-  List<List<int>> splitContent = await response.toList();
-  int totalLength = 0;
+  var splitContent = await response.toList();
+  var totalLength = 0;
   for (var list in splitContent) {
     totalLength += list.length;
   }
-  Uint8List result = new Uint8List(totalLength);
-  int offset = 0;
-  for (List<int> contentPart in splitContent) {
+  var result = Uint8List(totalLength);
+  var offset = 0;
+  for (var contentPart in splitContent) {
     result.setRange(offset, offset + contentPart.length, contentPart);
     offset += contentPart.length;
   }
diff --git a/package_config/lib/discovery_analysis.dart b/package_config/lib/discovery_analysis.dart
index d623303..2af0729 100644
--- a/package_config/lib/discovery_analysis.dart
+++ b/package_config/lib/discovery_analysis.dart
@@ -10,6 +10,7 @@
 /// but more efficiently and with some heuristics for directories that
 /// wouldn't otherwise have a package resolution strategy, or that are
 /// determined to be "package directories" themselves.
+@Deprecated("Use the package_config.json based API")
 library package_config.discovery_analysis;
 
 import "dart:collection" show HashMap;
@@ -57,7 +58,7 @@
   /// directory of `directory`. If there is, its corresponding `Packages` object
   /// should be provided as `root`.
   static PackageContext findAll(Directory directory,
-      {Packages root: Packages.noPackages}) {
+      {Packages root = Packages.noPackages}) {
     if (!directory.existsSync()) {
       throw ArgumentError("Directory not found: $directory");
     }
@@ -65,14 +66,13 @@
     void findRoots(Directory directory) {
       Packages packages;
       List<PackageContext> oldContexts;
-      File packagesFile = File(path.join(directory.path, ".packages"));
+      var packagesFile = File(path.join(directory.path, ".packages"));
       if (packagesFile.existsSync()) {
         packages = _loadPackagesFile(packagesFile);
         oldContexts = contexts;
         contexts = [];
       } else {
-        Directory packagesDir =
-            Directory(path.join(directory.path, "packages"));
+        var packagesDir = Directory(path.join(directory.path, "packages"));
         if (packagesDir.existsSync()) {
           packages = FilePackagesDirectoryPackages(packagesDir);
           oldContexts = contexts;
@@ -110,7 +110,7 @@
 
   Map<Directory, Packages> asMap() {
     var result = HashMap<Directory, Packages>();
-    recurse(_PackageContext current) {
+    void recurse(_PackageContext current) {
       result[current.directory] = current.packages;
       for (var child in current.children) {
         recurse(child);
@@ -122,19 +122,19 @@
   }
 
   PackageContext operator [](Directory directory) {
-    String path = directory.path;
+    var path = directory.path;
     if (!path.startsWith(this.directory.path)) {
       throw ArgumentError("Not inside $path: $directory");
     }
-    _PackageContext current = this;
+    var current = this;
     // The current path is know to agree with directory until deltaIndex.
-    int deltaIndex = current.directory.path.length;
+    var deltaIndex = current.directory.path.length;
     List children = current.children;
-    int i = 0;
+    var i = 0;
     while (i < children.length) {
       // TODO(lrn): Sort children and use binary search.
       _PackageContext child = children[i];
-      String childPath = child.directory.path;
+      var childPath = child.directory.path;
       if (_stringsAgree(path, childPath, deltaIndex, childPath.length)) {
         deltaIndex = childPath.length;
         if (deltaIndex == path.length) {
@@ -152,7 +152,7 @@
 
   static bool _stringsAgree(String a, String b, int start, int end) {
     if (a.length < end || b.length < end) return false;
-    for (int i = start; i < end; i++) {
+    for (var i = start; i < end; i++) {
       if (a.codeUnitAt(i) != b.codeUnitAt(i)) return false;
     }
     return true;
diff --git a/package_config/lib/package_config.dart b/package_config/lib/package_config.dart
new file mode 100644
index 0000000..bca865d
--- /dev/null
+++ b/package_config/lib/package_config.dart
@@ -0,0 +1,174 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A package configuration is a way to assign file paths to package URIs,
+/// and vice-versa,
+library package_config.package_config_discovery;
+
+import "dart:io" show File, Directory;
+import "dart:typed_data" show Uint8List;
+
+import "src/discovery.dart" as discover;
+import "src/errors.dart" show throwError;
+import "src/package_config.dart";
+import "src/package_config_io.dart";
+
+export "package_config_types.dart";
+
+/// Reads a specific package configuration file.
+///
+/// The file must exist and be readable.
+/// It must be either a valid `package_config.json` file
+/// or a valid `.packages` file.
+/// It is considered a `package_config.json` file if its first character
+/// is a `{`.
+///
+/// If the file is a `.packages` file and [preferNewest] is true, the default,
+/// also checks if there is a `.dart_tool/package_config.json` file next to the original file,
+/// and if so, loads that instead.
+/// If [preferNewest] is set to false, a directly specified `.packages` file
+/// is loaded even if there is an available `package_config.json` file.
+/// The caller can determine this from the [PackageConfig.version]
+/// being 1 and look for a `package_config.json` file themselves.
+///
+/// If [onError] is provided, the configuration file parsing will report errors
+/// by calling that function, and then try to recover.
+/// The returned package configuration is a *best effort* attempt to create
+/// a valid configuration from the invalid configuration file.
+/// If no [onError] is provided, errors are thrown immediately.
+Future<PackageConfig> loadPackageConfig(File file,
+        {bool preferNewest = true, void onError(Object error)}) =>
+    readAnyConfigFile(file, preferNewest, onError ?? throwError);
+
+/// Reads a specific package configuration URI.
+///
+/// The file of the URI must exist and be readable.
+/// It must be either a valid `package_config.json` file
+/// or a valid `.packages` file.
+/// It is considered a `package_config.json` file if its first
+/// non-whitespace character is a `{`.
+///
+/// If [preferNewest] is true, the default, and the file is a `.packages` file,
+/// first checks if there is a `.dart_tool/package_config.json` file
+/// next to the original file, and if so, loads that instead.
+/// The [file] *must not* be a `package:` URI.
+/// If [preferNewest] is set to false, a directly specified `.packages` file
+/// is loaded even if there is an available `package_config.json` file.
+/// The caller can determine this from the [PackageConfig.version]
+/// being 1 and look for a `package_config.json` file themselves.
+///
+/// If [loader] is provided, URIs are loaded using that function.
+/// The future returned by the loader must complete with a [Uint8List]
+/// containing the entire file content encoded as UTF-8,
+/// or with `null` if the file does not exist.
+/// The loader may throw at its own discretion, for situations where
+/// it determines that an error might be need user attention,
+/// but it is always allowed to return `null`.
+/// This function makes no attempt to catch such errors.
+/// As such, it may throw any error that [loader] throws.
+///
+/// If no [loader] is supplied, a default loader is used which
+/// only accepts `file:`,  `http:` and `https:` URIs,
+/// and which uses the platform file system and HTTP requests to
+/// fetch file content. The default loader never throws because
+/// of an I/O issue, as long as the location URIs are valid.
+/// As such, it does not distinguish between a file not existing,
+/// and it being temporarily locked or unreachable.
+///
+/// If [onError] is provided, the configuration file parsing will report errors
+/// by calling that function, and then try to recover.
+/// The returned package configuration is a *best effort* attempt to create
+/// a valid configuration from the invalid configuration file.
+/// If no [onError] is provided, errors are thrown immediately.
+Future<PackageConfig> loadPackageConfigUri(Uri file,
+        {Future<Uint8List /*?*/ > loader(Uri uri) /*?*/,
+        bool preferNewest = true,
+        void onError(Object error)}) =>
+    readAnyConfigFileUri(file, loader, onError ?? throwError, preferNewest);
+
+/// Finds a package configuration relative to [directory].
+///
+/// If [directory] contains a package configuration,
+/// either a `.dart_tool/package_config.json` file or,
+/// if not, a `.packages`, then that file is loaded.
+///
+/// If no file is found in the current directory,
+/// then the parent directories are checked recursively,
+/// all the way to the root directory, to check if those contains
+/// a package configuration.
+/// If [recurse] is set to [false], this parent directory check is not
+/// performed.
+///
+/// If [onError] is provided, the configuration file parsing will report errors
+/// by calling that function, and then try to recover.
+/// The returned package configuration is a *best effort* attempt to create
+/// a valid configuration from the invalid configuration file.
+/// If no [onError] is provided, errors are thrown immediately.
+///
+/// Returns `null` if no configuration file is found.
+Future<PackageConfig> findPackageConfig(Directory directory,
+        {bool recurse = true, void onError(Object error)}) =>
+    discover.findPackageConfig(directory, recurse, onError ?? throwError);
+
+/// Finds a package configuration relative to [location].
+///
+/// If [location] contains a package configuration,
+/// either a `.dart_tool/package_config.json` file or,
+/// if not, a `.packages`, then that file is loaded.
+/// The [location] URI *must not* be a `package:` URI.
+/// It should be a hierarchical URI which is supported
+/// by [loader].
+///
+/// If no file is found in the current directory,
+/// then the parent directories are checked recursively,
+/// all the way to the root directory, to check if those contains
+/// a package configuration.
+/// If [recurse] is set to [false], this parent directory check is not
+/// performed.
+///
+/// If [loader] is provided, URIs are loaded using that function.
+/// The future returned by the loader must complete with a [Uint8List]
+/// containing the entire file content,
+/// or with `null` if the file does not exist.
+/// The loader may throw at its own discretion, for situations where
+/// it determines that an error might be need user attention,
+/// but it is always allowed to return `null`.
+/// This function makes no attempt to catch such errors.
+///
+/// If no [loader] is supplied, a default loader is used which
+/// only accepts `file:`,  `http:` and `https:` URIs,
+/// and which uses the platform file system and HTTP requests to
+/// fetch file content. The default loader never throws because
+/// of an I/O issue, as long as the location URIs are valid.
+/// As such, it does not distinguish between a file not existing,
+/// and it being temporarily locked or unreachable.
+///
+/// If [onError] is provided, the configuration file parsing will report errors
+/// by calling that function, and then try to recover.
+/// The returned package configuration is a *best effort* attempt to create
+/// a valid configuration from the invalid configuration file.
+/// If no [onError] is provided, errors are thrown immediately.
+///
+/// Returns `null` if no configuration file is found.
+Future<PackageConfig> findPackageConfigUri(Uri location,
+        {bool recurse = true,
+        Future<Uint8List /*?*/ > loader(Uri uri),
+        void onError(Object error)}) =>
+    discover.findPackageConfigUri(
+        location, loader, onError ?? throwError, recurse);
+
+/// Writes a package configuration to the provided directory.
+///
+/// Writes `.dart_tool/package_config.json` relative to [directory].
+/// If the `.dart_tool/` directory does not exist, it is created.
+/// If it cannot be created, this operation fails.
+///
+/// Also writes a `.packages` file in [directory].
+/// This will stop happening eventually as the `.packages` file becomes
+/// discontinued.
+/// A comment is generated if `[PackageConfig.extraData]` contains a
+/// `"generator"` entry.
+Future<void> savePackageConfig(
+        PackageConfig configuration, Directory directory) =>
+    writePackageConfigJsonFile(configuration, directory);
diff --git a/package_config/lib/package_config_types.dart b/package_config/lib/package_config_types.dart
new file mode 100644
index 0000000..f0637b1
--- /dev/null
+++ b/package_config/lib/package_config_types.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A package configuration is a way to assign file paths to package URIs,
+/// and vice-versa,
+library package_config.package_config;
+
+export "src/package_config.dart"
+    show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion;
+export "src/errors.dart" show PackageConfigError;
diff --git a/package_config/lib/packages.dart b/package_config/lib/packages.dart
index 886fbc8..203f32f 100644
--- a/package_config/lib/packages.dart
+++ b/package_config/lib/packages.dart
@@ -2,6 +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("Use the package_config.json based API")
 library package_config.packages;
 
 import "src/packages_impl.dart";
@@ -16,12 +17,13 @@
 /// in which case [packages] and [asMap] will throw if used.
 /// One such case is if the packages are resolved relative to a
 /// `packages/` directory available over HTTP.
+@Deprecated("Use the package_config.json based API")
 abstract class Packages {
   /// A [Packages] resolver containing no packages.
   ///
   /// This constant object is returned by [find] above if no
   /// package resolution strategy is found.
-  static const Packages noPackages = const NoPackages();
+  static const Packages noPackages = NoPackages();
 
   /// Resolve a package URI into a non-package URI.
   ///
diff --git a/package_config/lib/packages_file.dart b/package_config/lib/packages_file.dart
index 284d8e9..ef0b0b3 100644
--- a/package_config/lib/packages_file.dart
+++ b/package_config/lib/packages_file.dart
@@ -2,6 +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("Use the package_config.json based API")
 library package_config.packages_file;
 
 import "package:charcode/ascii.dart";
@@ -31,14 +32,14 @@
 /// If default package is allowed, the map maps the empty string to the default package's name.
 Map<String, Uri> parse(List<int> source, Uri baseLocation,
     {bool allowDefaultPackage = false}) {
-  int index = 0;
-  Map<String, Uri> result = <String, Uri>{};
+  var index = 0;
+  var result = <String, Uri>{};
   while (index < source.length) {
-    bool isComment = false;
-    int start = index;
-    int separatorIndex = -1;
-    int end = source.length;
-    int char = source[index++];
+    var isComment = false;
+    var start = index;
+    var separatorIndex = -1;
+    var end = source.length;
+    var char = source[index++];
     if (char == $cr || char == $lf) {
       continue;
     }
@@ -62,14 +63,13 @@
     if (separatorIndex < 0) {
       throw FormatException("No ':' on line", source, index - 1);
     }
-    var packageName = new String.fromCharCodes(source, start, separatorIndex);
+    var packageName = String.fromCharCodes(source, start, separatorIndex);
     if (packageName.isEmpty
         ? !allowDefaultPackage
         : !isValidPackageName(packageName)) {
       throw FormatException("Not a valid package name", packageName, 0);
     }
-    var packageValue =
-        new String.fromCharCodes(source, separatorIndex + 1, end);
+    var packageValue = String.fromCharCodes(source, separatorIndex + 1, end);
     Uri packageLocation;
     if (packageName.isEmpty) {
       if (!isValidPackageName(packageValue)) {
@@ -106,12 +106,17 @@
 /// If [baseUri] is provided, package locations will be made relative
 /// to the base URI, if possible, before writing.
 ///
+/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an
+/// empty string mapping to the _default package name_.
+///
 /// All the keys of [packageMapping] must be valid package names,
 /// and the values must be URIs that do not have the `package:` scheme.
 void write(StringSink output, Map<String, Uri> packageMapping,
-    {Uri baseUri, String comment}) {
+    {Uri baseUri, String comment, bool allowDefaultPackage = false}) {
+  ArgumentError.checkNotNull(allowDefaultPackage, 'allowDefaultPackage');
+
   if (baseUri != null && !baseUri.isAbsolute) {
-    throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute");
+    throw ArgumentError.value(baseUri, "baseUri", "Must be absolute");
   }
 
   if (comment != null) {
@@ -123,17 +128,32 @@
     }
   } else {
     output.write("# generated by package:package_config at ");
-    output.write(new DateTime.now());
+    output.write(DateTime.now());
     output.writeln();
   }
 
   packageMapping.forEach((String packageName, Uri uri) {
+    // If [packageName] is empty then [uri] is the _default package name_.
+    if (allowDefaultPackage && packageName.isEmpty) {
+      final defaultPackageName = uri.toString();
+      if (!isValidPackageName(defaultPackageName)) {
+        throw ArgumentError.value(
+          defaultPackageName,
+          'defaultPackageName',
+          '"$defaultPackageName" is not a valid package name',
+        );
+      }
+      output.write(':');
+      output.write(defaultPackageName);
+      output.writeln();
+      return;
+    }
     // Validate packageName.
     if (!isValidPackageName(packageName)) {
-      throw new ArgumentError('"$packageName" is not a valid package name');
+      throw ArgumentError('"$packageName" is not a valid package name');
     }
     if (uri.scheme == "package") {
-      throw new ArgumentError.value(
+      throw ArgumentError.value(
           "Package location must not be a package: URI", uri.toString());
     }
     output.write(packageName);
@@ -142,10 +162,10 @@
     if (baseUri != null) {
       uri = _relativize(uri, baseUri);
     }
-    output.write(uri);
     if (!uri.path.endsWith('/')) {
-      output.write('/');
+      uri = uri.replace(path: uri.path + '/');
     }
+    output.write(uri);
     output.writeln();
   });
 }
@@ -158,7 +178,7 @@
 Uri _relativize(Uri uri, Uri baseUri) {
   assert(baseUri.isAbsolute);
   if (uri.hasQuery || uri.hasFragment) {
-    uri = new Uri(
+    uri = Uri(
         scheme: uri.scheme,
         userInfo: uri.hasAuthority ? uri.userInfo : null,
         host: uri.hasAuthority ? uri.host : null,
@@ -184,14 +204,14 @@
   }
 
   baseUri = baseUri.normalizePath();
-  List<String> base = baseUri.pathSegments.toList();
+  var base = baseUri.pathSegments.toList();
   if (base.isNotEmpty) {
-    base = new List<String>.from(base)..removeLast();
+    base = List<String>.from(base)..removeLast();
   }
   uri = uri.normalizePath();
-  List<String> target = uri.pathSegments.toList();
+  var target = uri.pathSegments.toList();
   if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
-  int index = 0;
+  var index = 0;
   while (index < base.length && index < target.length) {
     if (base[index] != target[index]) {
       break;
@@ -200,11 +220,11 @@
   }
   if (index == base.length) {
     if (index == target.length) {
-      return new Uri(path: "./");
+      return Uri(path: "./");
     }
-    return new Uri(path: target.skip(index).join('/'));
+    return Uri(path: target.skip(index).join('/'));
   } else if (index > 0) {
-    return new Uri(
+    return Uri(
         path: '../' * (base.length - index) + target.skip(index).join('/'));
   } else {
     return uri;
diff --git a/package_config/lib/src/discovery.dart b/package_config/lib/src/discovery.dart
new file mode 100644
index 0000000..8ac6a01
--- /dev/null
+++ b/package_config/lib/src/discovery.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import 'dart:typed_data';
+
+import 'package_config_io.dart';
+
+import "errors.dart";
+import "package_config_impl.dart";
+import "package_config_json.dart";
+import "packages_file.dart" as packages_file;
+import "util_io.dart" show defaultLoader, pathJoin;
+
+final Uri packageConfigJsonPath = Uri(path: ".dart_tool/package_config.json");
+final Uri dotPackagesPath = Uri(path: ".packages");
+final Uri currentPath = Uri(path: ".");
+final Uri parentPath = Uri(path: "..");
+
+/// Discover the package configuration for a Dart script.
+///
+/// The [baseDirectory] points to the directory of the Dart script.
+/// A package resolution strategy is found by going through the following steps,
+/// and stopping when something is found.
+///
+/// * Check if a `.dart_tool/package_config.json` file exists in the directory.
+/// * Check if a `.packages` file exists in the directory.
+/// * Repeat these checks for the parent directories until reaching the
+///   root directory if [recursive] is true.
+///
+/// If any of these tests succeed, a `PackageConfig` class is returned.
+/// Returns `null` if no configuration was found. If a configuration
+/// is needed, then the caller can supply [PackageConfig.empty].
+Future<PackageConfig /*?*/ > findPackageConfig(
+    Directory baseDirectory, bool recursive, void onError(Object error)) async {
+  var directory = baseDirectory;
+  if (!directory.isAbsolute) directory = directory.absolute;
+  if (!await directory.exists()) {
+    return null;
+  }
+  do {
+    // Check for $cwd/.packages
+    var packageConfig = await findPackagConfigInDirectory(directory, onError);
+    if (packageConfig != null) return packageConfig;
+    if (!recursive) break;
+    // Check in parent directories.
+    var parentDirectory = directory.parent;
+    if (parentDirectory.path == directory.path) break;
+    directory = parentDirectory;
+  } while (true);
+  return null;
+}
+
+/// Similar to [findPackageConfig] but based on a URI.
+Future<PackageConfig /*?*/ > findPackageConfigUri(
+    Uri location,
+    Future<Uint8List /*?*/ > loader(Uri uri) /*?*/,
+    void onError(Object error) /*?*/,
+    bool recursive) async {
+  if (location.isScheme("package")) {
+    onError(PackageConfigArgumentError(
+        location, "location", "Must not be a package: URI"));
+    return null;
+  }
+  if (loader == null) {
+    if (location.isScheme("file")) {
+      return findPackageConfig(
+          Directory.fromUri(location.resolveUri(currentPath)),
+          recursive,
+          onError);
+    }
+    loader = defaultLoader;
+  }
+  if (!location.path.endsWith("/")) location = location.resolveUri(currentPath);
+  while (true) {
+    var file = location.resolveUri(packageConfigJsonPath);
+    var bytes = await loader(file);
+    if (bytes != null) {
+      return parsePackageConfigBytes(bytes, file, onError);
+    }
+    file = location.resolveUri(dotPackagesPath);
+    bytes = await loader(file);
+    if (bytes != null) {
+      return packages_file.parse(bytes, file, onError);
+    }
+    if (!recursive) break;
+    var parent = location.resolveUri(parentPath);
+    if (parent == location) break;
+    location = parent;
+  }
+  return null;
+}
+
+/// Finds a `.packages` or `.dart_tool/package_config.json` file in [directory].
+///
+/// Loads the file, if it is there, and returns the resulting [PackageConfig].
+/// Returns `null` if the file isn't there.
+/// Reports a [FormatException] if a file is there but the content is not valid.
+/// If the file exists, but fails to be read, the file system error is reported.
+///
+/// If [onError] is supplied, parsing errors are reported using that, and
+/// a best-effort attempt is made to return a package configuration.
+/// This may be the empty package configuration.
+Future<PackageConfig /*?*/ > findPackagConfigInDirectory(
+    Directory directory, void onError(Object error)) async {
+  var packageConfigFile = await checkForPackageConfigJsonFile(directory);
+  if (packageConfigFile != null) {
+    return await readPackageConfigJsonFile(packageConfigFile, onError);
+  }
+  packageConfigFile = await checkForDotPackagesFile(directory);
+  if (packageConfigFile != null) {
+    return await readDotPackagesFile(packageConfigFile, onError);
+  }
+  return null;
+}
+
+Future<File> /*?*/ checkForPackageConfigJsonFile(Directory directory) async {
+  assert(directory.isAbsolute);
+  var file =
+      File(pathJoin(directory.path, ".dart_tool", "package_config.json"));
+  if (await file.exists()) return file;
+  return null;
+}
+
+Future<File /*?*/ > checkForDotPackagesFile(Directory directory) async {
+  var file = File(pathJoin(directory.path, ".packages"));
+  if (await file.exists()) return file;
+  return null;
+}
diff --git a/package_config/lib/src/errors.dart b/package_config/lib/src/errors.dart
new file mode 100644
index 0000000..c973617
--- /dev/null
+++ b/package_config/lib/src/errors.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// General superclass of most errors and exceptions thrown by this package.
+///
+/// Only covers errors thrown while parsing package configuration files.
+/// Programming errors and I/O exceptions are not covered.
+abstract class PackageConfigError {
+  PackageConfigError._();
+}
+
+class PackageConfigArgumentError extends ArgumentError
+    implements PackageConfigError {
+  PackageConfigArgumentError(Object /*?*/ value, String name, String message)
+      : super.value(value, name, message);
+
+  PackageConfigArgumentError.from(ArgumentError error)
+      : super.value(error.invalidValue, error.name, error.message);
+}
+
+class PackageConfigFormatException extends FormatException
+    implements PackageConfigError {
+  PackageConfigFormatException(String message, Object /*?*/ source,
+      [int /*?*/ offset])
+      : super(message, source, offset);
+
+  PackageConfigFormatException.from(FormatException exception)
+      : super(exception.message, exception.source, exception.offset);
+}
+
+/// The default `onError` handler.
+void /*Never*/ throwError(Object error) => throw error;
diff --git a/package_config/lib/src/package_config.dart b/package_config/lib/src/package_config.dart
new file mode 100644
index 0000000..364df75
--- /dev/null
+++ b/package_config/lib/src/package_config.dart
@@ -0,0 +1,375 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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:typed_data';
+
+import 'errors.dart';
+import "package_config_impl.dart";
+import 'package_config_json.dart';
+
+/// A package configuration.
+///
+/// Associates configuration data to packages and files in packages.
+///
+/// More members may be added to this class in the future,
+/// so classes outside of this package must not implement [PackageConfig]
+/// or any subclass of it.
+abstract class PackageConfig {
+  /// The largest configuration version currently recognized.
+  static const int maxVersion = 2;
+
+  /// An empty package configuration.
+  ///
+  /// A package configuration with no available packages.
+  /// Is used as a default value where a package configuration
+  /// is expected, but none have been specified or found.
+  static const PackageConfig empty = SimplePackageConfig.empty();
+
+  /// Creats a package configuration with the provided available [packages].
+  ///
+  /// The packages must be valid packages (valid package name, valid
+  /// absolute directory URIs, valid language version, if any),
+  /// and there must not be two packages with the same name.
+  ///
+  /// The package's root ([Package.rootUri]) and package-root
+  /// ([Package.packageUriRoot]) paths must satisfy a number of constraints
+  /// We say that one path (which we know ends with a `/` charater)
+  /// is inside another path, if the latter path is a prefix of the former path,
+  /// including the two paths being the same.
+  ///
+  /// * No package's root must be the same as another package's root.
+  /// * The package-root of a package must be inside the pacakge's root.
+  /// * If one package's package-root is inside another package's root,
+  ///   then the latter package's package root must not be inside the former
+  ///   package's root. (No getting between a package and its package root!)
+  ///   This also disallows a package's root being the same as another
+  ///   package's package root.
+  ///
+  /// If supplied, the [extraData] will be available as the
+  /// [PackageConfig.extraData] of the created configuration.
+  ///
+  /// The version of the resulting configuration is always [maxVersion].
+  factory PackageConfig(Iterable<Package> packages, {dynamic extraData}) =>
+      SimplePackageConfig(maxVersion, packages, extraData);
+
+  /// Parses a package configuration file.
+  ///
+  /// The [bytes] must be an UTF-8 encoded JSON object
+  /// containing a valid package configuration.
+  ///
+  /// The [baseUri] is used as the base for resolving relative
+  /// URI references in the configuration file. If the configuration
+  /// has been read from a file, the [baseUri] can be the URI of that
+  /// file, or of the directory it occurs in.
+  ///
+  /// If [onError] is provided, errors found during parsing or building
+  /// the configuration are reported by calling [onError] instead of
+  /// throwing, and parser makes a *best effort* attempt to continue
+  /// despite the error. The input must still be valid JSON.
+  /// The result may be a [PackageConfig.empty] if there is no way to
+  /// extract useful information from the bytes.
+  static PackageConfig parseBytes(Uint8List bytes, Uri baseUri,
+          {void onError(Object error)}) =>
+      parsePackageConfigBytes(bytes, baseUri, onError ?? throwError);
+
+  /// Parses a package configuration file.
+  ///
+  /// The [configuration] must be a JSON object
+  /// containing a valid package configuration.
+  ///
+  /// The [baseUri] is used as the base for resolving relative
+  /// URI references in the configuration file. If the configuration
+  /// has been read from a file, the [baseUri] can be the URI of that
+  /// file, or of the directory it occurs in.
+  ///
+  /// If [onError] is provided, errors found during parsing or building
+  /// the configuration are reported by calling [onError] instead of
+  /// throwing, and parser makes a *best effort* attempt to continue
+  /// despite the error. The input must still be valid JSON.
+  /// The result may be a [PackageConfig.empty] if there is no way to
+  /// extract useful information from the bytes.
+  static PackageConfig parseString(String configuration, Uri baseUri,
+          {void onError(Object error)}) =>
+      parsePackageConfigString(configuration, baseUri, onError ?? throwError);
+
+  /// Parses the JSON data of a package configuration file.
+  ///
+  /// The [configuration] must be a JSON-like Dart data structure,
+  /// like the one provided by parsing JSON text using `dart:convert`,
+  /// containing a valid package configuration.
+  ///
+  /// The [baseUri] is used as the base for resolving relative
+  /// URI references in the configuration file. If the configuration
+  /// has been read from a file, the [baseUri] can be the URI of that
+  /// file, or of the directory it occurs in.
+  ///
+  /// If [onError] is provided, errors found during parsing or building
+  /// the configuration are reported by calling [onError] instead of
+  /// throwing, and parser makes a *best effort* attempt to continue
+  /// despite the error. The input must still be valid JSON.
+  /// The result may be a [PackageConfig.empty] if there is no way to
+  /// extract useful information from the bytes.
+  static PackageConfig parseJson(dynamic jsonData, Uri baseUri,
+          {void onError(Object error)}) =>
+      parsePackageConfigJson(jsonData, baseUri, onError ?? throwError);
+
+  /// Writes a configuration file for this configuration on [output].
+  ///
+  /// If [baseUri] is provided, URI references in the generated file
+  /// will be made relative to [baseUri] where possible.
+  static void writeBytes(PackageConfig configuration, Sink<Uint8List> output,
+      [Uri /*?*/ baseUri]) {
+    writePackageConfigJsonUtf8(configuration, baseUri, output);
+  }
+
+  /// Writes a configuration JSON text for this configuration on [output].
+  ///
+  /// If [baseUri] is provided, URI references in the generated file
+  /// will be made relative to [baseUri] where possible.
+  static void writeString(PackageConfig configuration, StringSink output,
+      [Uri /*?*/ baseUri]) {
+    writePackageConfigJsonString(configuration, baseUri, output);
+  }
+
+  /// Converts a configuration to a JSON-like data structure.
+  ///
+  /// If [baseUri] is provided, URI references in the generated data
+  /// will be made relative to [baseUri] where possible.
+  static Map<String, dynamic> toJson(PackageConfig configuration,
+          [Uri /*?*/ baseUri]) =>
+      packageConfigToJson(configuration, baseUri);
+
+  /// The configuration version number.
+  ///
+  /// Currently this is 1 or 2, where
+  /// * Version one is the `.packages` file format and
+  /// * Version two is the first `package_config.json` format.
+  ///
+  /// Instances of this class supports both, and the version
+  /// is only useful for detecting which kind of file the configuration
+  /// was read from.
+  int get version;
+
+  /// All the available packages of this configuration.
+  ///
+  /// No two of these packages have the same name,
+  /// and no two [Package.root] directories overlap.
+  Iterable<Package> get packages;
+
+  /// Look up a package by name.
+  ///
+  /// Returns the [Package] fron [packages] with [packageName] as
+  /// [Package.name]. Returns `null` if the package is not available in the
+  /// current configuration.
+  Package /*?*/ operator [](String packageName);
+
+  /// Provides the associated package for a specific [file] (or directory).
+  ///
+  /// Returns a [Package] which contains the [file]'s path, if any.
+  /// That is, the [Package.rootUri] directory is a parent directory
+  /// of the [file]'s location.
+  ///
+  /// Returns `null` if the file does not belong to any package.
+  Package /*?*/ packageOf(Uri file);
+
+  /// Resolves a `package:` URI to a non-package URI
+  ///
+  /// The [packageUri] must be a valid package URI. That means:
+  /// * A URI with `package` as scheme,
+  /// * with no authority part (`package://...`),
+  /// * with a path starting with a valid package name followed by a slash, and
+  /// * with no query or fragment part.
+  ///
+  /// Throws an [ArgumentError] (which also implements [PackageConfigError])
+  /// if the package URI is not valid.
+  ///
+  /// Returns `null` if the package name of [packageUri] is not available
+  /// in this package configuration.
+  /// Returns the remaining path of the package URI resolved relative to the
+  /// [Package.packageUriRoot] of the corresponding package.
+  Uri /*?*/ resolve(Uri packageUri);
+
+  /// The package URI which resolves to [nonPackageUri].
+  ///
+  /// The [nonPackageUri] must not have any query or fragment part,
+  /// and it must not have `package` as scheme.
+  /// Throws an [ArgumentError] (which also implements [PackageConfigError])
+  /// if the non-package URI is not valid.
+  ///
+  /// Returns a package URI which [resolve] will convert to [nonPackageUri],
+  /// if any such URI exists. Returns `null` if no such package URI exists.
+  Uri /*?*/ toPackageUri(Uri nonPackageUri);
+
+  /// Extra data associated with the package configuration.
+  ///
+  /// The data may be in any format, depending on who introduced it.
+  /// The standard `packjage_config.json` file storage will only store
+  /// JSON-like list/map data structures.
+  dynamic get extraData;
+}
+
+/// Configuration data for a single package.
+abstract class Package {
+  /// Creates a package with the provided properties.
+  ///
+  /// The [name] must be a valid package name.
+  /// The [root] must be an absolute directory URI, meaning an absolute URI
+  /// with no query or fragment path and a path starting and ending with `/`.
+  /// The [packageUriRoot], if provided, must be either an absolute
+  /// directory URI or a relative URI reference which is then resolved
+  /// relative to [root]. It must then also be a subdirectory of [root],
+  /// or the same directory.
+  /// If [languageVersion] is supplied, it must be a valid Dart language
+  /// version, which means two decimal integer literals separated by a `.`,
+  /// where the integer literals have no leading zeros unless they are
+  /// a single zero digit.
+  /// If [extraData] is supplied, it will be available as the
+  /// [Package.extraData] of the created package.
+  factory Package(String name, Uri root,
+          {Uri /*?*/ packageUriRoot,
+          LanguageVersion /*?*/ languageVersion,
+          dynamic extraData}) =>
+      SimplePackage.validate(
+          name, root, packageUriRoot, languageVersion, extraData, throwError);
+
+  /// The package-name of the package.
+  String get name;
+
+  /// The location of the root of the package.
+  ///
+  /// Is always an absolute URI with no query or fragment parts,
+  /// and with a path ending in `/`.
+  ///
+  /// All files in the [rootUri] directory are considered
+  /// part of the package for purposes where that that matters.
+  Uri get root;
+
+  /// The root of the files available through `package:` URIs.
+  ///
+  /// A `package:` URI with [name] as the package name is
+  /// resolved relative to this location.
+  ///
+  /// Is always an absolute URI with no query or fragment part
+  /// with a path ending in `/`,
+  /// and with a location which is a subdirectory
+  /// of the [root], or the same as the [root].
+  Uri get packageUriRoot;
+
+  /// The default language version associated with this package.
+  ///
+  /// Each package may have a default language version associated,
+  /// which is the language version used to parse and compile
+  /// Dart files in the package.
+  /// A package version is defined by two non-negative numbers,
+  /// the *major* and *minor* version numbers.
+  LanguageVersion /*?*/ get languageVersion;
+
+  /// Extra data associated with the specific package.
+  ///
+  /// The data may be in any format, depending on who introduced it.
+  /// The standard `packjage_config.json` file storage will only store
+  /// JSON-like list/map data structures.
+  dynamic get extraData;
+}
+
+/// A language version.
+///
+/// A language version is represented by two non-negative integers,
+/// the [major] and [minor] version numbers.
+///
+/// If errors during parsing are handled using an `onError` handler,
+/// then an *invalid* language version may be represented by an
+/// [InvalidLanguageVersion] object.
+abstract class LanguageVersion implements Comparable<LanguageVersion> {
+  /// The maximal value allowed by [major] and [minor] values;
+  static const int maxValue = 0x7FFFFFFF;
+  factory LanguageVersion(int major, int minor) {
+    RangeError.checkValueInInterval(major, 0, maxValue, "major");
+    RangeError.checkValueInInterval(minor, 0, maxValue, "major");
+    return SimpleLanguageVersion(major, minor, null);
+  }
+
+  /// Parses a language version string.
+  ///
+  /// A valid language version string has the form
+  ///
+  /// > *decimalNumber* `.` *decimalNumber*
+  ///
+  /// where a *decimalNumber* is a non-empty sequence of decimal digits
+  /// with no unnecessary leading zeros (the decimal number only starts
+  /// with a zero digit if that digit is the entire number).
+  /// No spaces are allowed in the string.
+  ///
+  /// If the [source] is valid then it is parsed into a valid
+  /// [LanguageVersion] object.
+  /// If not, then the [onError] is called with a [FormatException].
+  /// If [onError] is not supplied, it defaults to throwing the exception.
+  /// If the call does not throw, then an [InvalidLanguageVersion] is returned
+  /// containing the original [source].
+  static LanguageVersion parse(String source, {void onError(Object error)}) =>
+      parseLanguageVersion(source, onError ?? throwError);
+
+  /// The major language version.
+  ///
+  /// A non-negative integer less than 2<sup>31</sup>.
+  ///
+  /// The value is negative for objects representing *invalid* language
+  /// versions ([InvalidLanguageVersion]).
+  int get major;
+
+  /// The minor language version.
+  ///
+  /// A non-negative integer less than 2<sup>31</sup>.
+  ///
+  /// The value is negative for objects representing *invalid* language
+  /// versions ([InvalidLanguageVersion]).
+  int get minor;
+
+  /// Compares language versions.
+  ///
+  /// Two language versions are considered equal if they have the
+  /// same major and minor version numbers.
+  ///
+  /// A language version is greater then another if the former's major version
+  /// is greater than the latter's major version, or if they have
+  /// the same major version and the former's minor version is greater than
+  /// the latter's.
+  int compareTo(LanguageVersion other);
+
+  /// Valid language versions with the same [major] and [minor] values are
+  /// equal.
+  ///
+  /// Invalid language versions ([InvalidLanguageVersion]) are not equal to
+  /// any other object.
+  bool operator ==(Object other);
+
+  int get hashCode;
+
+  /// A string representation of the language version.
+  ///
+  /// A valid language version is represented as
+  /// `"${version.major}.${version.minor}"`.
+  String toString();
+}
+
+/// An *invalid* language version.
+///
+/// Stored in a [Package] when the orginal language version string
+/// was invalid and a `onError` handler was passed to the parser
+/// which did not throw on an error.
+abstract class InvalidLanguageVersion implements LanguageVersion {
+  /// The value -1 for an invalid language version.
+  int get major;
+
+  /// The value -1 for an invalid language version.
+  int get minor;
+
+  /// An invalid language version is only equal to itself.
+  bool operator ==(Object other);
+
+  int get hashCode;
+
+  /// The original invalid version string.
+  String toString();
+}
diff --git a/package_config/lib/src/package_config_impl.dart b/package_config/lib/src/package_config_impl.dart
new file mode 100644
index 0000000..f68a9ea
--- /dev/null
+++ b/package_config/lib/src/package_config_impl.dart
@@ -0,0 +1,519 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 'errors.dart';
+import "package_config.dart";
+import "util.dart";
+
+export "package_config.dart";
+
+// Implementations of the main data types exposed by the API of this package.
+
+class SimplePackageConfig implements PackageConfig {
+  final int version;
+  final Map<String, Package> _packages;
+  final PackageTree _packageTree;
+  final dynamic extraData;
+
+  factory SimplePackageConfig(int version, Iterable<Package> packages,
+      [dynamic extraData, void onError(Object error)]) {
+    onError ??= throwError;
+    var validVersion = _validateVersion(version, onError);
+    var sortedPackages = [...packages]..sort(_compareRoot);
+    var packageTree = _validatePackages(packages, sortedPackages, onError);
+    return SimplePackageConfig._(validVersion, packageTree,
+        {for (var p in packageTree.allPackages) p.name: p}, extraData);
+  }
+
+  SimplePackageConfig._(
+      this.version, this._packageTree, this._packages, this.extraData);
+
+  /// Creates empty configuration.
+  ///
+  /// The empty configuration can be used in cases where no configuration is
+  /// found, but code expects a non-null configuration.
+  const SimplePackageConfig.empty()
+      : version = 1,
+        _packageTree = const EmptyPackageTree(),
+        _packages = const <String, Package>{},
+        extraData = null;
+
+  static int _validateVersion(int version, void onError(Object error)) {
+    if (version < 0 || version > PackageConfig.maxVersion) {
+      onError(PackageConfigArgumentError(version, "version",
+          "Must be in the range 1 to ${PackageConfig.maxVersion}"));
+      return 2; // The minimal version supporting a SimplePackageConfig.
+    }
+    return version;
+  }
+
+  static PackageTree _validatePackages(Iterable<Package> originalPackages,
+      List<Package> packages, void onError(Object error)) {
+    var packageNames = <String>{};
+    var tree = MutablePackageTree();
+    for (var originalPackage in packages) {
+      if (originalPackage == null) {
+        onError(ArgumentError.notNull("element of packages"));
+        continue;
+      }
+      SimplePackage package;
+      if (originalPackage is! SimplePackage) {
+        // SimplePackage validates these properties.
+        package = SimplePackage.validate(
+            originalPackage.name,
+            originalPackage.root,
+            originalPackage.packageUriRoot,
+            originalPackage.languageVersion,
+            originalPackage.extraData, (error) {
+          if (error is PackageConfigArgumentError) {
+            onError(PackageConfigArgumentError(packages, "packages",
+                "Package ${package.name}: ${error.message}"));
+          } else {
+            onError(error);
+          }
+        });
+        if (package == null) continue;
+      } else {
+        package = originalPackage;
+      }
+      var name = package.name;
+      if (packageNames.contains(name)) {
+        onError(PackageConfigArgumentError(
+            name, "packages", "Duplicate package name"));
+        continue;
+      }
+      packageNames.add(name);
+      tree.add(0, package, (error) {
+        if (error is ConflictException) {
+          // There is a conflict with an existing package.
+          var existingPackage = error.existingPackage;
+          if (error.isRootConflict) {
+            onError(PackageConfigArgumentError(
+                originalPackages,
+                "packages",
+                "Packages ${package.name} and ${existingPackage.name} "
+                    "have the same root directory: ${package.root}.\n"));
+          } else {
+            assert(error.isPackageRootConflict);
+            // Package is inside the package URI root of the existing package.
+            onError(PackageConfigArgumentError(
+                originalPackages,
+                "packages",
+                "Package ${package.name} is inside the package URI root of "
+                    "package ${existingPackage.name}.\n"
+                    "${existingPackage.name} URI root: "
+                    "${existingPackage.packageUriRoot}\n"
+                    "${package.name} root: ${package.root}\n"));
+          }
+        } else {
+          // Any other error.
+          onError(error);
+        }
+      });
+    }
+    return tree;
+  }
+
+  Iterable<Package> get packages => _packages.values;
+
+  Package /*?*/ operator [](String packageName) => _packages[packageName];
+
+  /// Provides the associated package for a specific [file] (or directory).
+  ///
+  /// Returns a [Package] which contains the [file]'s path.
+  /// That is, the [Package.rootUri] directory is a parent directory
+  /// of the [file]'s location.
+  /// Returns `null` if the file does not belong to any package.
+  Package /*?*/ packageOf(Uri file) => _packageTree.packageOf(file);
+
+  Uri /*?*/ resolve(Uri packageUri) {
+    var packageName = checkValidPackageUri(packageUri, "packageUri");
+    return _packages[packageName]?.packageUriRoot?.resolveUri(
+        Uri(path: packageUri.path.substring(packageName.length + 1)));
+  }
+
+  Uri /*?*/ toPackageUri(Uri nonPackageUri) {
+    if (nonPackageUri.isScheme("package")) {
+      throw PackageConfigArgumentError(
+          nonPackageUri, "nonPackageUri", "Must not be a package URI");
+    }
+    if (nonPackageUri.hasQuery || nonPackageUri.hasFragment) {
+      throw PackageConfigArgumentError(nonPackageUri, "nonPackageUri",
+          "Must not have query or fragment part");
+    }
+    // Find package that file belongs to.
+    var package = _packageTree.packageOf(nonPackageUri);
+    if (package == null) return null;
+    // Check if it is inside the package URI root.
+    var path = nonPackageUri.toString();
+    var root = package.packageUriRoot.toString();
+    if (_beginsWith(package.root.toString().length, root, path)) {
+      var rest = path.substring(root.length);
+      return Uri(scheme: "package", path: "${package.name}/$rest");
+    }
+    return null;
+  }
+}
+
+/// Configuration data for a single package.
+class SimplePackage implements Package {
+  final String name;
+  final Uri root;
+  final Uri packageUriRoot;
+  final LanguageVersion /*?*/ languageVersion;
+  final dynamic extraData;
+
+  SimplePackage._(this.name, this.root, this.packageUriRoot,
+      this.languageVersion, this.extraData);
+
+  /// Creates a [SimplePackage] with the provided content.
+  ///
+  /// The provided arguments must be valid.
+  ///
+  /// If the arguments are invalid then the error is reported by
+  /// calling [onError], then the erroneous entry is ignored.
+  ///
+  /// If [onError] is provided, the user is expected to be able to handle
+  /// errors themselves. An invalid [languageVersion] string
+  /// will be replaced with the string `"invalid"`. This allows
+  /// users to detect the difference between an absent version and
+  /// an invalid one.
+  ///
+  /// Returns `null` if the input is invalid and an approximately valid package
+  /// cannot be salvaged from the input.
+  static SimplePackage /*?*/ validate(
+      String name,
+      Uri root,
+      Uri packageUriRoot,
+      LanguageVersion /*?*/ languageVersion,
+      dynamic extraData,
+      void onError(Object error)) {
+    var fatalError = false;
+    var invalidIndex = checkPackageName(name);
+    if (invalidIndex >= 0) {
+      onError(PackageConfigFormatException(
+          "Not a valid package name", name, invalidIndex));
+      fatalError = true;
+    }
+    if (root.isScheme("package")) {
+      onError(PackageConfigArgumentError(
+          "$root", "root", "Must not be a package URI"));
+      fatalError = true;
+    } else if (!isAbsoluteDirectoryUri(root)) {
+      onError(PackageConfigArgumentError(
+          "$root",
+          "root",
+          "In package $name: Not an absolute URI with no query or fragment "
+              "with a path ending in /"));
+      // Try to recover. If the URI has a scheme,
+      // then ensure that the path ends with `/`.
+      if (!root.hasScheme) {
+        fatalError = true;
+      } else if (!root.path.endsWith("/")) {
+        root = root.replace(path: root.path + "/");
+      }
+    }
+    if (!fatalError) {
+      if (!isAbsoluteDirectoryUri(packageUriRoot)) {
+        onError(PackageConfigArgumentError(
+            packageUriRoot,
+            "packageUriRoot",
+            "In package $name: Not an absolute URI with no query or fragment "
+                "with a path ending in /"));
+        packageUriRoot = root;
+      } else if (!isUriPrefix(root, packageUriRoot)) {
+        onError(PackageConfigArgumentError(packageUriRoot, "packageUriRoot",
+            "The package URI root is not below the package root"));
+        packageUriRoot = root;
+      }
+    }
+    if (fatalError) return null;
+    return SimplePackage._(
+        name, root, packageUriRoot, languageVersion, extraData);
+  }
+}
+
+/// Checks whether [version] is a valid Dart language version string.
+///
+/// The format is (as RegExp) `^(0|[1-9]\d+)\.(0|[1-9]\d+)$`.
+///
+/// Reports a format exception on [onError] if not, or if the numbers
+/// are too large (at most 32-bit signed integers).
+LanguageVersion parseLanguageVersion(
+    String source, void onError(Object error)) {
+  var index = 0;
+  // Reads a positive decimal numeral. Returns the value of the numeral,
+  // or a negative number in case of an error.
+  // Starts at [index] and increments the index to the position after
+  // the numeral.
+  // It is an error if the numeral value is greater than 0x7FFFFFFFF.
+  // It is a recoverable error if the numeral starts with leading zeros.
+  int readNumeral() {
+    const maxValue = 0x7FFFFFFF;
+    if (index == source.length) {
+      onError(PackageConfigFormatException("Missing number", source, index));
+      return -1;
+    }
+    var start = index;
+
+    var char = source.codeUnitAt(index);
+    var digit = char ^ 0x30;
+    if (digit > 9) {
+      onError(PackageConfigFormatException("Missing number", source, index));
+      return -1;
+    }
+    var firstDigit = digit;
+    var value = 0;
+    do {
+      value = value * 10 + digit;
+      if (value > maxValue) {
+        onError(
+            PackageConfigFormatException("Number too large", source, start));
+        return -1;
+      }
+      index++;
+      if (index == source.length) break;
+      char = source.codeUnitAt(index);
+      digit = char ^ 0x30;
+    } while (digit <= 9);
+    if (firstDigit == 0 && index > start + 1) {
+      onError(PackageConfigFormatException(
+          "Leading zero not allowed", source, start));
+    }
+    return value;
+  }
+
+  var major = readNumeral();
+  if (major < 0) {
+    return SimpleInvalidLanguageVersion(source);
+  }
+  if (index == source.length || source.codeUnitAt(index) != $dot) {
+    onError(PackageConfigFormatException("Missing '.'", source, index));
+    return SimpleInvalidLanguageVersion(source);
+  }
+  index++;
+  var minor = readNumeral();
+  if (minor < 0) {
+    return SimpleInvalidLanguageVersion(source);
+  }
+  if (index != source.length) {
+    onError(PackageConfigFormatException(
+        "Unexpected trailing character", source, index));
+    return SimpleInvalidLanguageVersion(source);
+  }
+  return SimpleLanguageVersion(major, minor, source);
+}
+
+abstract class _SimpleLanguageVersionBase implements LanguageVersion {
+  int compareTo(LanguageVersion other) {
+    var result = major.compareTo(other.major);
+    if (result != 0) return result;
+    return minor.compareTo(other.minor);
+  }
+}
+
+class SimpleLanguageVersion extends _SimpleLanguageVersionBase {
+  final int major;
+  final int minor;
+  String /*?*/ _source;
+  SimpleLanguageVersion(this.major, this.minor, this._source);
+
+  bool operator ==(Object other) =>
+      other is LanguageVersion && major == other.major && minor == other.minor;
+
+  int get hashCode => (major * 17 ^ minor * 37) & 0x3FFFFFFF;
+
+  String toString() => _source ??= "$major.$minor";
+}
+
+class SimpleInvalidLanguageVersion extends _SimpleLanguageVersionBase
+    implements InvalidLanguageVersion {
+  final String _source;
+  SimpleInvalidLanguageVersion(this._source);
+  int get major => -1;
+  int get minor => -1;
+
+  String toString() => _source;
+}
+
+abstract class PackageTree {
+  Iterable<Package> get allPackages;
+  SimplePackage /*?*/ packageOf(Uri file);
+}
+
+/// Packages of a package configuration ordered by root path.
+///
+/// A package has a root path and a package root path, where the latter
+/// contains the files exposed by `package:` URIs.
+///
+/// A package is said to be inside another package if the root path URI of
+/// the latter is a prefix of the root path URI of the former.
+///
+/// No two packages of a package may have the same root path, so this
+/// path prefix ordering defines a tree-like partial ordering on packages
+/// of a configuration.
+///
+/// The package root path of a package must not be inside another package's
+/// root path.
+/// Entire other packages are allowed inside a package's root or
+/// package root path.
+///
+/// The package tree contains an ordered mapping of unrelated packages
+/// (represented by their name) to their immediately nested packages' names.
+class MutablePackageTree implements PackageTree {
+  /// A list of packages that are not nested inside each other.
+  final List<SimplePackage> packages = [];
+
+  /// The tree of the immediately nested packages inside each package.
+  ///
+  /// Indexed by [Package.name].
+  /// If a package has no nested packages (which is most often the case),
+  /// there is no tree object associated with it.
+  Map<String, MutablePackageTree /*?*/ > /*?*/ _packageChildren;
+
+  Iterable<Package> get allPackages sync* {
+    for (var package in packages) yield package;
+    if (_packageChildren != null) {
+      for (var tree in _packageChildren.values) yield* tree.allPackages;
+    }
+  }
+
+  /// Tries to (add) `package` to the tree.
+  ///
+  /// Reports a [ConflictException] if the added package conflicts with an
+  /// existing package.
+  /// It conflicts if its root or package root is the same as another
+  /// package's root or package root, or is between the two.
+  ///
+  /// If a conflict is detected between [package] and a previous package,
+  /// then [onError] is called with a [ConflictException] object
+  /// and the [package] is not added to the tree.
+  ///
+  /// The packages are added in order of their root path.
+  /// It is never necessary to insert a node between two existing levels.
+  void add(int start, SimplePackage package, void onError(Object error)) {
+    var path = package.root.toString();
+    for (var treePackage in packages) {
+      // Check is package is inside treePackage.
+      var treePackagePath = treePackage.root.toString();
+      assert(treePackagePath.length > start);
+      assert(path.startsWith(treePackagePath.substring(0, start)));
+      if (_beginsWith(start, treePackagePath, path)) {
+        // Package *is* inside treePackage.
+        var treePackagePathLength = treePackagePath.length;
+        if (path.length == treePackagePathLength) {
+          // Has same root. Do not add package.
+          onError(ConflictException.root(package, treePackage));
+          return;
+        }
+        var treePackageUriRoot = treePackage.packageUriRoot.toString();
+        if (_beginsWith(treePackagePathLength, path, treePackageUriRoot)) {
+          // The treePackage's package root is inside package, which is inside
+          // the treePackage. This is not allowed.
+          onError(ConflictException.packageRoot(package, treePackage));
+          return;
+        }
+        _treeOf(treePackage).add(treePackagePathLength, package, onError);
+        return;
+      }
+    }
+    packages.add(package);
+  }
+
+  SimplePackage /*?*/ packageOf(Uri file) {
+    return findPackageOf(0, file.toString());
+  }
+
+  /// Finds package containing [path] in this tree.
+  ///
+  /// Returns `null` if no such package is found.
+  ///
+  /// Assumes the first [start] characters of path agrees with all
+  /// the packages at this level of the tree.
+  SimplePackage /*?*/ findPackageOf(int start, String path) {
+    for (var childPackage in packages) {
+      var childPath = childPackage.root.toString();
+      if (_beginsWith(start, childPath, path)) {
+        // The [package] is inside [childPackage].
+        var childPathLength = childPath.length;
+        if (path.length == childPathLength) return childPackage;
+        var uriRoot = childPackage.packageUriRoot.toString();
+        // Is [package] is inside the URI root of [childPackage].
+        if (uriRoot.length == childPathLength ||
+            _beginsWith(childPathLength, uriRoot, path)) {
+          return childPackage;
+        }
+        // Otherwise add [package] as child of [childPackage].
+        // TODO(lrn): When NNBD comes, convert to:
+        // return _packageChildren?[childPackage.name]
+        //     ?.packageOf(childPathLength, path) ?? childPackage;
+        if (_packageChildren == null) return childPackage;
+        var childTree = _packageChildren[childPackage.name];
+        if (childTree == null) return childPackage;
+        return childTree.findPackageOf(childPathLength, path) ?? childPackage;
+      }
+    }
+    return null;
+  }
+
+  /// Returns the [PackageTree] of the children of [package].
+  ///
+  /// Ensures that the object is allocated if necessary.
+  MutablePackageTree _treeOf(SimplePackage package) {
+    var children = _packageChildren ??= {};
+    return children[package.name] ??= MutablePackageTree();
+  }
+}
+
+class EmptyPackageTree implements PackageTree {
+  const EmptyPackageTree();
+
+  Iterable<Package> get allPackages => const Iterable<Package>.empty();
+
+  SimplePackage packageOf(Uri file) => null;
+}
+
+/// Checks whether [longerPath] begins with [parentPath].
+///
+/// Skips checking the [start] first characters which are assumed to
+/// already have been matched.
+bool _beginsWith(int start, String parentPath, String longerPath) {
+  if (longerPath.length < parentPath.length) return false;
+  for (var i = start; i < parentPath.length; i++) {
+    if (longerPath.codeUnitAt(i) != parentPath.codeUnitAt(i)) return false;
+  }
+  return true;
+}
+
+/// Conflict between packages added to the same configuration.
+///
+/// The [package] conflicts with [existingPackage] if it has
+/// the same root path ([isRootConflict]) or the package URI root path
+/// of [existingPackage] is inside the root path of [package]
+/// ([isPackageRootConflict]).
+class ConflictException {
+  /// The existing package that [package] conflicts with.
+  final SimplePackage existingPackage;
+
+  /// The package that could not be added without a conflict.
+  final SimplePackage package;
+
+  /// Whether the conflict is with the package URI root of [existingPackage].
+  final bool isPackageRootConflict;
+
+  /// Creates a root conflict between [package] and [existingPackage].
+  ConflictException.root(this.package, this.existingPackage)
+      : isPackageRootConflict = false;
+
+  /// Creates a package root conflict between [package] and [existingPackage].
+  ConflictException.packageRoot(this.package, this.existingPackage)
+      : isPackageRootConflict = true;
+
+  /// WHether the conflict is with the root URI of [existingPackage].
+  bool get isRootConflict => !isPackageRootConflict;
+}
+
+/// Used for sorting packages by root path.
+int _compareRoot(Package p1, Package p2) =>
+    p1.root.toString().compareTo(p2.root.toString());
diff --git a/package_config/lib/src/package_config_io.dart b/package_config/lib/src/package_config_io.dart
new file mode 100644
index 0000000..954be6b
--- /dev/null
+++ b/package_config/lib/src/package_config_io.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart:io dependent functionality for reading and writing configuration files.
+
+import "dart:convert";
+import "dart:io";
+import "dart:typed_data";
+
+import "discovery.dart" show packageConfigJsonPath;
+import "errors.dart";
+import "package_config_impl.dart";
+import "package_config_json.dart";
+import "packages_file.dart" as packages_file;
+import "util.dart";
+import "util_io.dart";
+
+/// Reads a package configuration file.
+///
+/// Detects whether the [file] is a version one `.packages` file or
+/// a version two `package_config.json` file.
+///
+/// If the [file] is a `.packages` file and [preferNewest] is true,
+/// first checks whether there is an adjacent `.dart_tool/package_config.json`
+/// file, and if so, reads that instead.
+/// If [preferNewset] is false, the specified file is loaded even if it is
+/// a `.packages` file and there is an available `package_config.json` file.
+///
+/// The file must exist and be a normal file.
+Future<PackageConfig> readAnyConfigFile(
+    File file, bool preferNewest, void onError(Object error)) async {
+  Uint8List bytes;
+  try {
+    bytes = await file.readAsBytes();
+  } catch (e) {
+    onError(e);
+    return const SimplePackageConfig.empty();
+  }
+  var firstChar = firstNonWhitespaceChar(bytes);
+  if (firstChar != $lbrace) {
+    // Definitely not a JSON object, probably a .packages.
+    if (preferNewest) {
+      var alternateFile = File(
+          pathJoin(dirName(file.path), ".dart_tool", "package_config.json"));
+      if (alternateFile.existsSync()) {
+        Uint8List /*?*/ bytes;
+        try {
+          bytes = await alternateFile.readAsBytes();
+        } catch (e) {
+          onError(e);
+          return const SimplePackageConfig.empty();
+        }
+        if (bytes != null) {
+          return parsePackageConfigBytes(bytes, alternateFile.uri, onError);
+        }
+      }
+    }
+    return packages_file.parse(bytes, file.uri, onError);
+  }
+  return parsePackageConfigBytes(bytes, file.uri, onError);
+}
+
+/// Like [readAnyConfigFile] but uses a URI and an optional loader.
+Future<PackageConfig> readAnyConfigFileUri(
+    Uri file,
+    Future<Uint8List /*?*/ > loader(Uri uri) /*?*/,
+    void onError(Object error),
+    bool preferNewest) async {
+  if (file.isScheme("package")) {
+    throw PackageConfigArgumentError(
+        file, "file", "Must not be a package: URI");
+  }
+  if (loader == null) {
+    if (file.isScheme("file")) {
+      return readAnyConfigFile(File.fromUri(file), preferNewest, onError);
+    }
+    loader = defaultLoader;
+  }
+  Uint8List bytes;
+  try {
+    bytes = await loader(file);
+  } catch (e) {
+    onError(e);
+    return const SimplePackageConfig.empty();
+  }
+  if (bytes == null) {
+    onError(PackageConfigArgumentError(
+        file.toString(), "file", "File cannot be read"));
+    return const SimplePackageConfig.empty();
+  }
+  var firstChar = firstNonWhitespaceChar(bytes);
+  if (firstChar != $lbrace) {
+    // Definitely not a JSON object, probably a .packages.
+    if (preferNewest) {
+      // Check if there is a package_config.json file.
+      var alternateFile = file.resolveUri(packageConfigJsonPath);
+      Uint8List alternateBytes;
+      try {
+        alternateBytes = await loader(alternateFile);
+      } catch (e) {
+        onError(e);
+        return const SimplePackageConfig.empty();
+      }
+      if (alternateBytes != null) {
+        return parsePackageConfigBytes(alternateBytes, alternateFile, onError);
+      }
+    }
+    return packages_file.parse(bytes, file, onError);
+  }
+  return parsePackageConfigBytes(bytes, file, onError);
+}
+
+Future<PackageConfig> readPackageConfigJsonFile(
+    File file, void onError(Object error)) async {
+  Uint8List bytes;
+  try {
+    bytes = await file.readAsBytes();
+  } catch (error) {
+    onError(error);
+    return const SimplePackageConfig.empty();
+  }
+  return parsePackageConfigBytes(bytes, file.uri, onError);
+}
+
+Future<PackageConfig> readDotPackagesFile(
+    File file, void onError(Object error)) async {
+  Uint8List bytes;
+  try {
+    bytes = await file.readAsBytes();
+  } catch (error) {
+    onError(error);
+    return const SimplePackageConfig.empty();
+  }
+  return packages_file.parse(bytes, file.uri, onError);
+}
+
+Future<void> writePackageConfigJsonFile(
+    PackageConfig config, Directory targetDirectory) async {
+  // Write .dart_tool/package_config.json first.
+  var file =
+      File(pathJoin(targetDirectory.path, ".dart_tool", "package_config.json"));
+  var baseUri = file.uri;
+  var sink = file.openWrite(encoding: utf8);
+  writePackageConfigJsonUtf8(config, baseUri, sink);
+  var doneJson = sink.close();
+
+  // Write .packages too.
+  file = File(pathJoin(targetDirectory.path, ".packages"));
+  baseUri = file.uri;
+  sink = file.openWrite(encoding: utf8);
+  writeDotPackages(config, baseUri, sink);
+  var donePackages = sink.close();
+
+  await Future.wait([doneJson, donePackages]);
+}
diff --git a/package_config/lib/src/package_config_json.dart b/package_config/lib/src/package_config_json.dart
new file mode 100644
index 0000000..b9b3416
--- /dev/null
+++ b/package_config/lib/src/package_config_json.dart
@@ -0,0 +1,315 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Parsing and serialization of package configurations.
+
+import "dart:convert";
+import "dart:typed_data";
+
+import "errors.dart";
+import "package_config_impl.dart";
+import "packages_file.dart" as packages_file;
+import "util.dart";
+
+const String _configVersionKey = "configVersion";
+const String _packagesKey = "packages";
+const List<String> _topNames = [_configVersionKey, _packagesKey];
+const String _nameKey = "name";
+const String _rootUriKey = "rootUri";
+const String _packageUriKey = "packageUri";
+const String _languageVersionKey = "languageVersion";
+const List<String> _packageNames = [
+  _nameKey,
+  _rootUriKey,
+  _packageUriKey,
+  _languageVersionKey
+];
+
+const String _generatedKey = "generated";
+const String _generatorKey = "generator";
+const String _generatorVersionKey = "generatorVersion";
+
+final _jsonUtf8Decoder = json.fuse(utf8).decoder;
+
+PackageConfig parsePackageConfigBytes(
+    Uint8List bytes, Uri file, void onError(Object error)) {
+  // TODO(lrn): Make this simpler. Maybe parse directly from bytes.
+  var jsonObject;
+  try {
+    jsonObject = _jsonUtf8Decoder.convert(bytes);
+  } on FormatException catch (e) {
+    onError(PackageConfigFormatException(e.message, e.source, e.offset));
+    return const SimplePackageConfig.empty();
+  }
+  return parsePackageConfigJson(jsonObject, file, onError);
+}
+
+PackageConfig parsePackageConfigString(
+    String source, Uri file, void onError(Object error)) {
+  var jsonObject;
+  try {
+    jsonObject = jsonDecode(source);
+  } on FormatException catch (e) {
+    onError(PackageConfigFormatException(e.message, e.source, e.offset));
+    return const SimplePackageConfig.empty();
+  }
+  return parsePackageConfigJson(jsonObject, file, onError);
+}
+
+/// Creates a [PackageConfig] from a parsed JSON-like object structure.
+///
+/// The [json] argument must be a JSON object (`Map<String, dynamic>`)
+/// containing a `"configVersion"` entry with an integer value in the range
+/// 1 to [PackageConfig.maxVersion],
+/// and with a `"packages"` entry which is a JSON array (`List<dynamic>`)
+/// containing JSON objects which each has the following properties:
+///
+/// * `"name"`: The package name as a string.
+/// * `"rootUri"`: The root of the package as a URI stored as a string.
+/// * `"packageUri"`: Optionally the root of for `package:` URI resolution
+///     for the package, as a relative URI below the root URI
+///     stored as a string.
+/// * `"languageVersion"`: Optionally a language version string which is a
+///     an integer numeral, a decimal point (`.`) and another integer numeral,
+///     where the integer numeral cannot have a sign, and can only have a
+///     leading zero if the entire numeral is a single zero.
+///
+/// All other properties are stored in [extraData].
+///
+/// The [baseLocation] is used as base URI to resolve the "rootUri"
+/// URI referencestring.
+PackageConfig parsePackageConfigJson(
+    dynamic json, Uri baseLocation, void onError(Object error)) {
+  if (!baseLocation.hasScheme || baseLocation.isScheme("package")) {
+    throw PackageConfigArgumentError(baseLocation.toString(), "baseLocation",
+        "Must be an absolute non-package: URI");
+  }
+
+  if (!baseLocation.path.endsWith("/")) {
+    baseLocation = baseLocation.resolveUri(Uri(path: "."));
+  }
+
+  String typeName<T>() {
+    if (0 is T) return "int";
+    if ("" is T) return "string";
+    if (const [] is T) return "array";
+    return "object";
+  }
+
+  T checkType<T>(dynamic value, String name, [String /*?*/ packageName]) {
+    if (value is T) return value;
+    // The only types we are called with are [int], [String], [List<dynamic>]
+    // and Map<String, dynamic>. Recognize which to give a better error message.
+    var message =
+        "$name${packageName != null ? " of package $packageName" : ""}"
+        " is not a JSON ${typeName<T>()}";
+    onError(PackageConfigFormatException(message, value));
+    return null;
+  }
+
+  Package /*?*/ parsePackage(Map<String, dynamic> entry) {
+    String /*?*/ name;
+    String /*?*/ rootUri;
+    String /*?*/ packageUri;
+    String /*?*/ languageVersion;
+    Map<String, dynamic> /*?*/ extraData;
+    var hasName = false;
+    var hasRoot = false;
+    var hasVersion = false;
+    entry.forEach((key, value) {
+      switch (key) {
+        case _nameKey:
+          hasName = true;
+          name = checkType<String>(value, _nameKey);
+          break;
+        case _rootUriKey:
+          hasRoot = true;
+          rootUri = checkType<String>(value, _rootUriKey, name);
+          break;
+        case _packageUriKey:
+          packageUri = checkType<String>(value, _packageUriKey, name);
+          break;
+        case _languageVersionKey:
+          hasVersion = true;
+          languageVersion = checkType<String>(value, _languageVersionKey, name);
+          break;
+        default:
+          (extraData ??= {})[key] = value;
+          break;
+      }
+    });
+    if (!hasName) {
+      onError(PackageConfigFormatException("Missing name entry", entry));
+    }
+    if (!hasRoot) {
+      onError(PackageConfigFormatException("Missing rootUri entry", entry));
+    }
+    if (name == null || rootUri == null) return null;
+    var root = baseLocation.resolve(rootUri);
+    if (!root.path.endsWith("/")) root = root.replace(path: root.path + "/");
+    var packageRoot = root;
+    if (packageUri != null) packageRoot = root.resolve(packageUri);
+    if (!packageRoot.path.endsWith("/")) {
+      packageRoot = packageRoot.replace(path: packageRoot.path + "/");
+    }
+
+    LanguageVersion /*?*/ version;
+    if (languageVersion != null) {
+      version = parseLanguageVersion(languageVersion, onError);
+    } else if (hasVersion) {
+      version = SimpleInvalidLanguageVersion("invalid");
+    }
+
+    return SimplePackage.validate(name, root, packageRoot, version, extraData,
+        (error) {
+      if (error is ArgumentError) {
+        onError(
+            PackageConfigFormatException(error.message, error.invalidValue));
+      } else {
+        onError(error);
+      }
+    });
+  }
+
+  var map = checkType<Map<String, dynamic>>(json, "value");
+  if (map == null) return const SimplePackageConfig.empty();
+  Map<String, dynamic> /*?*/ extraData;
+  List<Package> /*?*/ packageList;
+  int /*?*/ configVersion;
+  map.forEach((key, value) {
+    switch (key) {
+      case _configVersionKey:
+        configVersion = checkType<int>(value, _configVersionKey) ?? 2;
+        break;
+      case _packagesKey:
+        var packageArray = checkType<List<dynamic>>(value, _packagesKey) ?? [];
+        var packages = <Package>[];
+        for (var package in packageArray) {
+          var packageMap =
+              checkType<Map<String, dynamic>>(package, "package entry");
+          if (packageMap != null) {
+            var entry = parsePackage(packageMap);
+            if (entry != null) {
+              packages.add(entry);
+            }
+          }
+        }
+        packageList = packages;
+        break;
+      default:
+        (extraData ??= {})[key] = value;
+        break;
+    }
+  });
+  if (configVersion == null) {
+    onError(PackageConfigFormatException("Missing configVersion entry", json));
+    configVersion = 2;
+  }
+  if (packageList == null) {
+    onError(PackageConfigFormatException("Missing packages list", json));
+    packageList = [];
+  }
+  return SimplePackageConfig(configVersion, packageList, extraData, (error) {
+    if (error is ArgumentError) {
+      onError(PackageConfigFormatException(error.message, error.invalidValue));
+    } else {
+      onError(error);
+    }
+  });
+}
+
+final _jsonUtf8Encoder = JsonUtf8Encoder("  ");
+
+void writePackageConfigJsonUtf8(
+    PackageConfig config, Uri baseUri, Sink<List<int>> output) {
+  // Can be optimized.
+  var data = packageConfigToJson(config, baseUri);
+  output.add(_jsonUtf8Encoder.convert(data) as Uint8List);
+}
+
+void writePackageConfigJsonString(
+    PackageConfig config, Uri baseUri, StringSink output) {
+  // Can be optimized.
+  var data = packageConfigToJson(config, baseUri);
+  output.write(JsonEncoder.withIndent("  ").convert(data) as Uint8List);
+}
+
+Map<String, dynamic> packageConfigToJson(PackageConfig config, Uri baseUri) =>
+    <String, dynamic>{
+      ...?_extractExtraData(config.extraData, _topNames),
+      _configVersionKey: PackageConfig.maxVersion,
+      _packagesKey: [
+        for (var package in config.packages)
+          <String, dynamic>{
+            _nameKey: package.name,
+            _rootUriKey: relativizeUri(package.root, baseUri).toString(),
+            if (package.root != package.packageUriRoot)
+              _packageUriKey:
+                  relativizeUri(package.packageUriRoot, package.root)
+                      .toString(),
+            if (package.languageVersion != null &&
+                package.languageVersion is! InvalidLanguageVersion)
+              _languageVersionKey: package.languageVersion.toString(),
+            ...?_extractExtraData(package.extraData, _packageNames),
+          }
+      ],
+    };
+
+void writeDotPackages(PackageConfig config, Uri baseUri, StringSink output) {
+  var extraData = config.extraData;
+  // Write .packages too.
+  String /*?*/ comment;
+  if (extraData != null) {
+    String /*?*/ generator = extraData[_generatorKey];
+    if (generator != null) {
+      String /*?*/ generated = extraData[_generatedKey];
+      String /*?*/ generatorVersion = extraData[_generatorVersionKey];
+      comment = "Generated by $generator"
+          "${generatorVersion != null ? " $generatorVersion" : ""}"
+          "${generated != null ? " on $generated" : ""}.";
+    }
+  }
+  packages_file.write(output, config, baseUri: baseUri, comment: comment);
+  return;
+}
+
+/// If "extraData" is a JSON map, then return it, otherwise return null.
+///
+/// If the value contains any of the [reservedNames] for the current context,
+/// entries with that name in the extra data are dropped.
+Map<String, dynamic> /*?*/ _extractExtraData(
+    dynamic data, Iterable<String> reservedNames) {
+  if (data is Map<String, dynamic>) {
+    if (data.isEmpty) return null;
+    for (var name in reservedNames) {
+      if (data.containsKey(name)) {
+        data = {
+          for (var key in data.keys)
+            if (!reservedNames.contains(key)) key: data[key]
+        };
+        if (data.isEmpty) return null;
+        for (var value in data.values) {
+          if (!_validateJson(value)) return null;
+        }
+      }
+    }
+    return data;
+  }
+  return null;
+}
+
+/// Checks that the object is a valid JSON-like data structure.
+bool _validateJson(dynamic object) {
+  if (object == null || true == object || false == object) return true;
+  if (object is num || object is String) return true;
+  if (object is List<dynamic>) {
+    for (var element in object) if (!_validateJson(element)) return false;
+    return true;
+  }
+  if (object is Map<String, dynamic>) {
+    for (var value in object.values) if (!_validateJson(value)) return false;
+    return true;
+  }
+  return false;
+}
diff --git a/package_config/lib/src/packages_file.dart b/package_config/lib/src/packages_file.dart
new file mode 100644
index 0000000..e65e7e8
--- /dev/null
+++ b/package_config/lib/src/packages_file.dart
@@ -0,0 +1,185 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_config_impl.dart";
+
+import "util.dart";
+import "errors.dart";
+
+/// Parses a `.packages` file into a [PackageConfig].
+///
+/// The [source] is the byte content of a `.packages` file, assumed to be
+/// UTF-8 encoded. In practice, all significant parts of the file must be ASCII,
+/// so Latin-1 or Windows-1252 encoding will also work fine.
+///
+/// If the file content is available as a string, its [String.codeUnits] can
+/// be used as the `source` argument of this function.
+///
+/// The [baseLocation] is used as a base URI to resolve all relative
+/// URI references against.
+/// If the content was read from a file, `baseLocation` should be the
+/// location of that file.
+///
+/// Returns a simple package configuration where each package's
+/// [Package.packageUriRoot] is the same as its [Package.root]
+/// and it has no [Package.languageVersion].
+PackageConfig parse(
+    List<int> source, Uri baseLocation, void onError(Object error)) {
+  if (baseLocation.isScheme("package")) {
+    onError(PackageConfigArgumentError(
+        baseLocation, "baseLocation", "Must not be a package: URI"));
+    return PackageConfig.empty;
+  }
+  var index = 0;
+  var packages = <Package>[];
+  var packageNames = <String>{};
+  while (index < source.length) {
+    var ignoreLine = false;
+    var start = index;
+    var separatorIndex = -1;
+    var end = source.length;
+    var char = source[index++];
+    if (char == $cr || char == $lf) {
+      continue;
+    }
+    if (char == $colon) {
+      onError(PackageConfigFormatException(
+          "Missing package name", source, index - 1));
+      ignoreLine = true; // Ignore if package name is invalid.
+    } else {
+      ignoreLine = char == $hash; // Ignore if comment.
+    }
+    var queryStart = -1;
+    var fragmentStart = -1;
+    while (index < source.length) {
+      char = source[index++];
+      if (char == $colon && separatorIndex < 0) {
+        separatorIndex = index - 1;
+      } else if (char == $cr || char == $lf) {
+        end = index - 1;
+        break;
+      } else if (char == $question && queryStart < 0 && fragmentStart < 0) {
+        queryStart = index - 1;
+      } else if (char == $hash && fragmentStart < 0) {
+        fragmentStart = index - 1;
+      }
+    }
+    if (ignoreLine) continue;
+    if (separatorIndex < 0) {
+      onError(
+          PackageConfigFormatException("No ':' on line", source, index - 1));
+      continue;
+    }
+    var packageName = String.fromCharCodes(source, start, separatorIndex);
+    var invalidIndex = checkPackageName(packageName);
+    if (invalidIndex >= 0) {
+      onError(PackageConfigFormatException(
+          "Not a valid package name", source, start + invalidIndex));
+      continue;
+    }
+    if (queryStart >= 0) {
+      onError(PackageConfigFormatException(
+          "Location URI must not have query", source, queryStart));
+      end = queryStart;
+    } else if (fragmentStart >= 0) {
+      onError(PackageConfigFormatException(
+          "Location URI must not have fragment", source, fragmentStart));
+      end = fragmentStart;
+    }
+    var packageValue = String.fromCharCodes(source, separatorIndex + 1, end);
+    Uri packageLocation;
+    try {
+      packageLocation = baseLocation.resolve(packageValue);
+    } on FormatException catch (e) {
+      onError(PackageConfigFormatException.from(e));
+      continue;
+    }
+    if (packageLocation.isScheme("package")) {
+      onError(PackageConfigFormatException(
+          "Package URI as location for package", source, separatorIndex + 1));
+      continue;
+    }
+    if (!packageLocation.path.endsWith('/')) {
+      packageLocation =
+          packageLocation.replace(path: packageLocation.path + "/");
+    }
+    if (packageNames.contains(packageName)) {
+      onError(PackageConfigFormatException(
+          "Same package name occured more than once", source, start));
+      continue;
+    }
+    var package = SimplePackage.validate(
+        packageName, packageLocation, packageLocation, null, null, (error) {
+      if (error is ArgumentError) {
+        onError(PackageConfigFormatException(error.message, source));
+      } else {
+        onError(error);
+      }
+    });
+    if (package != null) {
+      packages.add(package);
+      packageNames.add(packageName);
+    }
+  }
+  return SimplePackageConfig(1, packages, null, onError);
+}
+
+/// Writes the configuration to a [StringSink].
+///
+/// If [comment] is provided, the output will contain this comment
+/// with `# ` in front of each line.
+/// Lines are defined as ending in line feed (`'\n'`). If the final
+/// line of the comment doesn't end in a line feed, one will be added.
+///
+/// If [baseUri] is provided, package locations will be made relative
+/// to the base URI, if possible, before writing.
+///
+/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an
+/// empty string mapping to the _default package name_.
+///
+/// All the keys of [packageMapping] must be valid package names,
+/// and the values must be URIs that do not have the `package:` scheme.
+void write(StringSink output, PackageConfig config,
+    {Uri baseUri, String comment}) {
+  if (baseUri != null && !baseUri.isAbsolute) {
+    throw PackageConfigArgumentError(baseUri, "baseUri", "Must be absolute");
+  }
+
+  if (comment != null) {
+    var lines = comment.split('\n');
+    if (lines.last.isEmpty) lines.removeLast();
+    for (var commentLine in lines) {
+      output.write('# ');
+      output.writeln(commentLine);
+    }
+  } else {
+    output.write("# generated by package:package_config at ");
+    output.write(DateTime.now());
+    output.writeln();
+  }
+  for (var package in config.packages) {
+    var packageName = package.name;
+    var uri = package.packageUriRoot;
+    // Validate packageName.
+    if (!isValidPackageName(packageName)) {
+      throw PackageConfigArgumentError(
+          config, "config", '"$packageName" is not a valid package name');
+    }
+    if (uri.scheme == "package") {
+      throw PackageConfigArgumentError(
+          config, "config", "Package location must not be a package URI: $uri");
+    }
+    output.write(packageName);
+    output.write(':');
+    // If baseUri is provided, make the URI relative to baseUri.
+    if (baseUri != null) {
+      uri = relativizeUri(uri, baseUri);
+    }
+    if (!uri.path.endsWith('/')) {
+      uri = uri.replace(path: uri.path + '/');
+    }
+    output.write(uri);
+    output.writeln();
+  }
+}
diff --git a/package_config/lib/src/packages_impl.dart b/package_config/lib/src/packages_impl.dart
index 817002f..19f1039 100644
--- a/package_config/lib/src/packages_impl.dart
+++ b/package_config/lib/src/packages_impl.dart
@@ -5,6 +5,7 @@
 /// Implementations of [Packages] that may be used in either server or browser
 /// based applications. For implementations that can only run in the browser,
 /// see [package_config.packages_io_impl].
+@Deprecated("Use the package_config.json based API")
 library package_config.packages_impl;
 
 import "dart:collection" show UnmodifiableMapView;
@@ -17,13 +18,13 @@
   const NoPackages();
 
   Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) {
-    String packageName = checkValidPackageUri(packageUri);
+    var packageName = checkValidPackageUri(packageUri, "packageUri");
     if (notFound != null) return notFound(packageUri);
-    throw new ArgumentError.value(
+    throw ArgumentError.value(
         packageUri, "packageUri", 'No package named "$packageName"');
   }
 
-  Iterable<String> get packages => new Iterable<String>.empty();
+  Iterable<String> get packages => Iterable<String>.empty();
 
   Map<String, Uri> asMap() => const <String, Uri>{};
 
@@ -41,14 +42,14 @@
 abstract class PackagesBase implements Packages {
   Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) {
     packageUri = packageUri.normalizePath();
-    String packageName = checkValidPackageUri(packageUri);
-    Uri packageBase = getBase(packageName);
+    var packageName = checkValidPackageUri(packageUri, "packageUri");
+    var packageBase = getBase(packageName);
     if (packageBase == null) {
       if (notFound != null) return notFound(packageUri);
-      throw new ArgumentError.value(
+      throw ArgumentError.value(
           packageUri, "packageUri", 'No package named "$packageName"');
     }
-    String packagePath = packageUri.path.substring(packageName.length + 1);
+    var packagePath = packageUri.path.substring(packageName.length + 1);
     return packageBase.resolve(packagePath);
   }
 
@@ -75,13 +76,13 @@
 
   Iterable<String> get packages => _mapping.keys;
 
-  Map<String, Uri> asMap() => new UnmodifiableMapView<String, Uri>(_mapping);
+  Map<String, Uri> asMap() => UnmodifiableMapView<String, Uri>(_mapping);
 
   String get defaultPackageName => _mapping[""]?.toString();
 
   String packageMetadata(String packageName, String key) {
     if (packageName.isEmpty) return null;
-    Uri uri = _mapping[packageName];
+    var uri = _mapping[packageName];
     if (uri == null || !uri.hasFragment) return null;
     // This can be optimized, either by caching the map or by
     // parsing incrementally instead of parsing the entire fragment.
@@ -112,7 +113,7 @@
   Uri getBase(String packageName) => _packageBase.resolve("$packageName/");
 
   Error _failListingPackages() {
-    return new UnsupportedError(
+    return UnsupportedError(
         "Cannot list packages for a ${_packageBase.scheme}: "
         "based package root");
   }
diff --git a/package_config/lib/src/packages_io_impl.dart b/package_config/lib/src/packages_io_impl.dart
index 9eba9ce..c623f4d 100644
--- a/package_config/lib/src/packages_io_impl.dart
+++ b/package_config/lib/src/packages_io_impl.dart
@@ -4,15 +4,16 @@
 
 /// Implementations of [Packages] that can only be used in server based
 /// applications.
+@Deprecated("Use the package_config.json based API")
 library package_config.packages_io_impl;
 
 import "dart:collection" show UnmodifiableMapView;
 import "dart:io" show Directory;
 
-import "package:path/path.dart" as path;
-
 import "packages_impl.dart";
 
+import "util_io.dart";
+
 /// A [Packages] implementation based on a local directory.
 class FilePackagesDirectoryPackages extends PackagesBase {
   final Directory _packageDir;
@@ -22,15 +23,15 @@
 
   Uri getBase(String packageName) {
     return _packageToBaseUriMap.putIfAbsent(packageName, () {
-      return new Uri.file(path.join(_packageDir.path, packageName, '.'));
+      return Uri.file(pathJoin(_packageDir.path, packageName, '.'));
     });
   }
 
   Iterable<String> _listPackageNames() {
     return _packageDir
         .listSync()
-        .where((e) => e is Directory)
-        .map((e) => path.basename(e.path));
+        .whereType<Directory>()
+        .map((e) => fileName(e.path));
   }
 
   Iterable<String> get packages => _listPackageNames();
@@ -40,6 +41,6 @@
     for (var packageName in _listPackageNames()) {
       result[packageName] = getBase(packageName);
     }
-    return new UnmodifiableMapView<String, Uri>(result);
+    return UnmodifiableMapView<String, Uri>(result);
   }
 }
diff --git a/package_config/lib/src/util.dart b/package_config/lib/src/util.dart
index f1e1afd..50b140f 100644
--- a/package_config/lib/src/util.dart
+++ b/package_config/lib/src/util.dart
@@ -1,11 +1,11 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 /// Utility methods used by more than one library in the package.
 library package_config.util;
 
-import "package:charcode/ascii.dart";
+import "errors.dart";
 
 // All ASCII characters that are valid in a package name, with space
 // for all the invalid ones (including space).
@@ -15,7 +15,7 @@
 
 /// Tests whether something is a valid Dart package name.
 bool isValidPackageName(String string) {
-  return _findInvalidCharacter(string) < 0;
+  return checkPackageName(string) < 0;
 }
 
 /// Check if a string is a valid package name.
@@ -26,10 +26,10 @@
 /// Returns `-1` if the string is valid.
 /// Otherwise returns the index of the first invalid character,
 /// or `string.length` if the string contains no non-'.' character.
-int _findInvalidCharacter(String string) {
+int checkPackageName(String string) {
   // Becomes non-zero if any non-'.' character is encountered.
-  int nonDot = 0;
-  for (int i = 0; i < string.length; i++) {
+  var nonDot = 0;
+  for (var i = 0; i < string.length; i++) {
     var c = string.codeUnitAt(i);
     if (c > 0x7f || _validPackageNameCharacters.codeUnitAt(c) <= $space) {
       return i;
@@ -40,58 +40,199 @@
   return -1;
 }
 
-/// Validate that a Uri is a valid package:URI.
-String checkValidPackageUri(Uri packageUri) {
+/// Validate that a [Uri] is a valid `package:` URI.
+///
+/// Used to validate user input.
+///
+/// Returns the package name extracted from the package URI,
+/// which is the path segment between `package:` and the first `/`.
+String checkValidPackageUri(Uri packageUri, String name) {
   if (packageUri.scheme != "package") {
-    throw new ArgumentError.value(
-        packageUri, "packageUri", "Not a package: URI");
+    throw PackageConfigArgumentError(packageUri, name, "Not a package: URI");
   }
   if (packageUri.hasAuthority) {
-    throw new ArgumentError.value(
-        packageUri, "packageUri", "Package URIs must not have a host part");
+    throw PackageConfigArgumentError(
+        packageUri, name, "Package URIs must not have a host part");
   }
   if (packageUri.hasQuery) {
     // A query makes no sense if resolved to a file: URI.
-    throw new ArgumentError.value(
-        packageUri, "packageUri", "Package URIs must not have a query part");
+    throw PackageConfigArgumentError(
+        packageUri, name, "Package URIs must not have a query part");
   }
   if (packageUri.hasFragment) {
     // We could leave the fragment after the URL when resolving,
     // but it would be odd if "package:foo/foo.dart#1" and
     // "package:foo/foo.dart#2" were considered different libraries.
     // Keep the syntax open in case we ever get multiple libraries in one file.
-    throw new ArgumentError.value(
-        packageUri, "packageUri", "Package URIs must not have a fragment part");
+    throw PackageConfigArgumentError(
+        packageUri, name, "Package URIs must not have a fragment part");
   }
   if (packageUri.path.startsWith('/')) {
-    throw new ArgumentError.value(
-        packageUri, "packageUri", "Package URIs must not start with a '/'");
+    throw PackageConfigArgumentError(
+        packageUri, name, "Package URIs must not start with a '/'");
   }
-  int firstSlash = packageUri.path.indexOf('/');
+  var firstSlash = packageUri.path.indexOf('/');
   if (firstSlash == -1) {
-    throw new ArgumentError.value(packageUri, "packageUri",
+    throw PackageConfigArgumentError(packageUri, name,
         "Package URIs must start with the package name followed by a '/'");
   }
-  String packageName = packageUri.path.substring(0, firstSlash);
-  int badIndex = _findInvalidCharacter(packageName);
+  var packageName = packageUri.path.substring(0, firstSlash);
+  var badIndex = checkPackageName(packageName);
   if (badIndex >= 0) {
     if (packageName.isEmpty) {
-      throw new ArgumentError.value(
-          packageUri, "packageUri", "Package names mus be non-empty");
+      throw PackageConfigArgumentError(
+          packageUri, name, "Package names mus be non-empty");
     }
     if (badIndex == packageName.length) {
-      throw new ArgumentError.value(packageUri, "packageUri",
+      throw PackageConfigArgumentError(packageUri, name,
           "Package names must contain at least one non-'.' character");
     }
     assert(badIndex < packageName.length);
-    int badCharCode = packageName.codeUnitAt(badIndex);
+    var badCharCode = packageName.codeUnitAt(badIndex);
     var badChar = "U+" + badCharCode.toRadixString(16).padLeft(4, '0');
     if (badCharCode >= 0x20 && badCharCode <= 0x7e) {
       // Printable character.
       badChar = "'${packageName[badIndex]}' ($badChar)";
     }
-    throw new ArgumentError.value(
-        packageUri, "packageUri", "Package names must not contain $badChar");
+    throw PackageConfigArgumentError(
+        packageUri, name, "Package names must not contain $badChar");
   }
   return packageName;
 }
+
+/// Checks whether URI is just an absolute directory.
+///
+/// * It must have a scheme.
+/// * It must not have a query or fragment.
+/// * The path must end with `/`.
+bool isAbsoluteDirectoryUri(Uri uri) {
+  if (uri.hasQuery) return false;
+  if (uri.hasFragment) return false;
+  if (!uri.hasScheme) return false;
+  var path = uri.path;
+  if (!path.endsWith("/")) return false;
+  return true;
+}
+
+/// Whether the former URI is a prefix of the latter.
+bool isUriPrefix(Uri prefix, Uri path) {
+  assert(!prefix.hasFragment);
+  assert(!prefix.hasQuery);
+  assert(!path.hasQuery);
+  assert(!path.hasFragment);
+  assert(prefix.path.endsWith('/'));
+  return path.toString().startsWith(prefix.toString());
+}
+
+/// Finds the first non-JSON-whitespace character in a file.
+///
+/// Used to heuristically detect whether a file is a JSON file or an .ini file.
+int firstNonWhitespaceChar(List<int> bytes) {
+  for (var i = 0; i < bytes.length; i++) {
+    var char = bytes[i];
+    if (char != 0x20 && char != 0x09 && char != 0x0a && char != 0x0d) {
+      return char;
+    }
+  }
+  return -1;
+}
+
+/// Attempts to return a relative path-only URI for [uri].
+///
+/// First removes any query or fragment part from [uri].
+///
+/// If [uri] is already relative (has no scheme), it's returned as-is.
+/// If that is not desired, the caller can pass `baseUri.resolveUri(uri)`
+/// as the [uri] instead.
+///
+/// If the [uri] has a scheme or authority part which differs from
+/// the [baseUri], or if there is no overlap in the paths of the
+/// two URIs at all, the [uri] is returned as-is.
+///
+/// Otherwise the result is a path-only URI which satsifies
+/// `baseUri.resolveUri(result) == uri`,
+///
+/// The `baseUri` must be absolute.
+Uri relativizeUri(Uri uri, Uri /*?*/ baseUri) {
+  if (baseUri == null) return uri;
+  assert(baseUri.isAbsolute);
+  if (uri.hasQuery || uri.hasFragment) {
+    uri = Uri(
+        scheme: uri.scheme,
+        userInfo: uri.hasAuthority ? uri.userInfo : null,
+        host: uri.hasAuthority ? uri.host : null,
+        port: uri.hasAuthority ? uri.port : null,
+        path: uri.path);
+  }
+
+  // Already relative. We assume the caller knows what they are doing.
+  if (!uri.isAbsolute) return uri;
+
+  if (baseUri.scheme != uri.scheme) {
+    return uri;
+  }
+
+  // If authority differs, we could remove the scheme, but it's not worth it.
+  if (uri.hasAuthority != baseUri.hasAuthority) return uri;
+  if (uri.hasAuthority) {
+    if (uri.userInfo != baseUri.userInfo ||
+        uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
+        uri.port != baseUri.port) {
+      return uri;
+    }
+  }
+
+  baseUri = baseUri.normalizePath();
+  var base = [...baseUri.pathSegments];
+  if (base.isNotEmpty) base.removeLast();
+  uri = uri.normalizePath();
+  var target = [...uri.pathSegments];
+  if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
+  var index = 0;
+  while (index < base.length && index < target.length) {
+    if (base[index] != target[index]) {
+      break;
+    }
+    index++;
+  }
+  if (index == base.length) {
+    if (index == target.length) {
+      return Uri(path: "./");
+    }
+    return Uri(path: target.skip(index).join('/'));
+  } else if (index > 0) {
+    var buffer = StringBuffer();
+    for (var n = base.length - index; n > 0; --n) {
+      buffer.write("../");
+    }
+    buffer.writeAll(target.skip(index), "/");
+    return Uri(path: buffer.toString());
+  } else {
+    return uri;
+  }
+}
+
+// Character constants used by this package.
+/// "Line feed" control character.
+const int $lf = 0x0a;
+
+/// "Carriage return" control character.
+const int $cr = 0x0d;
+
+/// Space character.
+const int $space = 0x20;
+
+/// Character `#`.
+const int $hash = 0x23;
+
+/// Character `.`.
+const int $dot = 0x2e;
+
+/// Character `:`.
+const int $colon = 0x3a;
+
+/// Character `?`.
+const int $question = 0x3f;
+
+/// Character `{`.
+const int $lbrace = 0x7b;
diff --git a/package_config/lib/src/util_io.dart b/package_config/lib/src/util_io.dart
new file mode 100644
index 0000000..7f21a8d
--- /dev/null
+++ b/package_config/lib/src/util_io.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Utility methods requiring dart:io and used by more than one library in the
+/// package.
+library package_config.util_io;
+
+import 'dart:io';
+import 'dart:typed_data';
+
+Future<Uint8List> defaultLoader(Uri uri) async {
+  if (uri.isScheme("file")) {
+    var file = File.fromUri(uri);
+    try {
+      return file.readAsBytes();
+    } catch (_) {
+      return null;
+    }
+  }
+  if (uri.isScheme("http") || uri.isScheme("https")) {
+    return _httpGet(uri);
+  }
+  throw UnsupportedError("Default URI unsupported scheme: $uri");
+}
+
+Future<Uint8List /*?*/ > _httpGet(Uri uri) async {
+  assert(uri.isScheme("http") || uri.isScheme("https"));
+  var client = HttpClient();
+  var request = await client.getUrl(uri);
+  var response = await request.close();
+  if (response.statusCode != HttpStatus.ok) {
+    return null;
+  }
+  var splitContent = await response.toList();
+  var totalLength = 0;
+  if (splitContent.length == 1) {
+    var part = splitContent[0];
+    if (part is Uint8List) {
+      return part;
+    }
+  }
+  for (var list in splitContent) {
+    totalLength += list.length;
+  }
+  var result = Uint8List(totalLength);
+  var offset = 0;
+  for (Uint8List contentPart in splitContent) {
+    result.setRange(offset, offset + contentPart.length, contentPart);
+    offset += contentPart.length;
+  }
+  return result;
+}
+
+/// The file name of a path.
+///
+/// The file name is everything after the last occurrence of
+/// [Platform.pathSeparator], or the entire string if no
+/// path separator occurs in the string.
+String fileName(String path) {
+  var separator = Platform.pathSeparator;
+  var lastSeparator = path.lastIndexOf(separator);
+  if (lastSeparator < 0) return path;
+  return path.substring(lastSeparator + separator.length);
+}
+
+/// The directory name of a path.
+///
+/// The directory name is everything before the last occurrence of
+/// [Platform.pathSeparator], or the empty string if no
+/// path separator occurs in the string.
+String dirName(String path) {
+  var separator = Platform.pathSeparator;
+  var lastSeparator = path.lastIndexOf(separator);
+  if (lastSeparator < 0) return "";
+  return path.substring(0, lastSeparator);
+}
+
+/// Join path parts with the [Platform.pathSeparator].
+///
+/// If a part ends with a path separator, then no extra separator is
+/// inserted.
+String pathJoin(String part1, String part2, [String part3]) {
+  var separator = Platform.pathSeparator;
+  var separator1 = part1.endsWith(separator) ? "" : separator;
+  if (part3 == null) {
+    return "$part1$separator1$part2";
+  }
+  var separator2 = part2.endsWith(separator) ? "" : separator;
+  return "$part1$separator1$part2$separator2$part3";
+}
+
+/// Join an unknown number of path parts with [Platform.pathSeparator].
+///
+/// If a part ends with a path separator, then no extra separator is
+/// inserted.
+String pathJoinAll(Iterable<String> parts) {
+  var buffer = StringBuffer();
+  var separator = "";
+  for (var part in parts) {
+    buffer..write(separator)..write(part);
+    separator =
+        part.endsWith(Platform.pathSeparator) ? "" : Platform.pathSeparator;
+  }
+  return buffer.toString();
+}
diff --git a/package_config/pubspec.yaml b/package_config/pubspec.yaml
index b51932e..5c05891 100644
--- a/package_config/pubspec.yaml
+++ b/package_config/pubspec.yaml
@@ -1,15 +1,20 @@
 name: package_config
-version: 1.1.0
-description: Support for working with Package Resolution config files.
-author: Dart Team <misc@dartlang.org>
+version: 1.9.1
+description: Support for working with Package Configuration files.
 homepage: https://github.com/dart-lang/package_config
 
 environment:
-  sdk: '>=2.0.0-dev <3.0.0'
+  sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
+  path: ^1.6.4
   charcode: ^1.1.0
-  path: ^1.0.0
 
 dev_dependencies:
-  test: ^1.3.0
+  test: ^1.6.4
+  matcher: ^0.12.5
+  pedantic: ^1.8.0
+
+  build_runner: ^1.0.0
+  build_web_compilers: ^2.0.0
+  build_test: ^0.10.0
diff --git a/pedantic/BUILD.gn b/pedantic/BUILD.gn
index c7ef7f4..0c47148 100644
--- a/pedantic/BUILD.gn
+++ b/pedantic/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for pedantic-1.8.0+1
+# This file is generated by importer.py for pedantic-1.9.0
 
 import("//build/dart/dart_library.gni")
 
diff --git a/pedantic/CHANGELOG.md b/pedantic/CHANGELOG.md
index 05399aa..a15b3d0 100644
--- a/pedantic/CHANGELOG.md
+++ b/pedantic/CHANGELOG.md
@@ -1,4 +1,47 @@
+## 1.9.0
+
+- Enforce 17 new lint rules:
+
+  - [`always_declare_return_types`]
+  - [`always_require_non_null_named_parameters`]
+  - [`annotate_overrides`]
+  - [`avoid_null_checks_in_equality_operators`]
+  - [`camel_case_extensions`]
+  - [`omit_local_variable_types`]
+  - [`prefer_adjacent_string_concatenation`]
+  - [`prefer_collection_literals`]
+  - [`prefer_conditional_assignment`]
+  - [`prefer_final_fields`]
+  - [`prefer_for_elements_to_map_fromIterable`]
+  - [`prefer_generic_function_type_aliases`]
+  - [`prefer_if_null_operators`]
+  - [`prefer_single_quotes`]
+  - [`prefer_spread_collections`]
+  - [`unnecessary_this`]
+  - [`use_function_type_syntax_for_parameters`]
+
+- Mark a number of lints unused, see `README.md` for details.
+
+[`always_declare_return_types`]: https://dart-lang.github.io/linter/lints/always_declare_return_types.html
+[`always_require_non_null_named_parameters`]: https://dart-lang.github.io/linter/lints/always_require_non_null_named_parameters.html
+[`annotate_overrides`]: https://dart-lang.github.io/linter/lints/annotate_overrides.html
+[`avoid_null_checks_in_equality_operators`]: https://dart-lang.github.io/linter/lints/avoid_null_checks_in_equality_operators.html
+[`camel_case_extensions`]: https://dart-lang.github.io/linter/lints/camel_case_extensions.html
+[`omit_local_variable_types`]: https://dart-lang.github.io/linter/lints/omit_local_variable_types.html
+[`prefer_adjacent_string_concatenation`]: https://dart-lang.github.io/linter/lints/prefer_adjacent_string_concatenation.html
+[`prefer_collection_literals`]: https://dart-lang.github.io/linter/lints/prefer_collection_literals.html
+[`prefer_conditional_assignment`]: https://dart-lang.github.io/linter/lints/prefer_conditional_assignment.html
+[`prefer_final_fields`]: https://dart-lang.github.io/linter/lints/prefer_final_fields.html
+[`prefer_for_elements_to_map_fromIterable`]: https://dart-lang.github.io/linter/lints/prefer_for_elements_to_map_fromIterable.html
+[`prefer_generic_function_type_aliases`]: https://dart-lang.github.io/linter/lints/prefer_generic_function_type_aliases.html
+[`prefer_if_null_operators`]: https://dart-lang.github.io/linter/lints/prefer_if_null_operators.html
+[`prefer_single_quotes`]: https://dart-lang.github.io/linter/lints/prefer_single_quotes.html
+[`prefer_spread_collections`]: https://dart-lang.github.io/linter/lints/prefer_spread_collections.html
+[`unnecessary_this`]: https://dart-lang.github.io/linter/lints/unnecessary_this.html
+[`use_function_type_syntax_for_parameters`]: https://dart-lang.github.io/linter/lints/use_function_type_syntax_for_parameters.html
+
 ## 1.8.0
+
 - Enforce three new lint rules:
 
   - [`prefer_iterable_whereType`]
diff --git a/pedantic/README.md b/pedantic/README.md
index 3d97288..df8f6de 100644
--- a/pedantic/README.md
+++ b/pedantic/README.md
@@ -27,8 +27,7 @@
    - The `TODO` hint is a permanent exception.
    - Deprecation hints are a permanent exception. Deprecations are handled
      separately on a case by case basis.
-   - `unnecessary_no_such_method`, `unused_element`, `unused_field` and
-     `unused_local_variable` are allowed.
+   - `unused_element`, `unused_field` and `unused_local_variable` are allowed.
    - When a new SDK version adds new errors, warnings or hints, we either clean
      up everything before switching SDK version or maintain a whitelist of
      allowed violations so it can be gradually cleaned up.
@@ -80,26 +79,174 @@
 violates Effective Dart "DO format your code using dartfmt". See note about
 Flutter SDK style below.
 
+`always_put_required_named_parameters_first`
+does not allow for other logical orderings of parameters, such as matching the
+class field order or alphabetical.
+
 `always_specify_types`
 violates Effective Dart "AVOID type annotating initialized local variables"
 and others. See note about Flutter SDK style below.
 
+`avoid_annotating_with_dynamic`
+violates Effective Dart "PREFER annotating with `dynamic` instead of letting
+inference fail".
+
 `avoid_as`
-does not reflect standard usage. See note about Flutter SDK style below.
+does not reflect common usage. See note about Flutter SDK style below.
+
+`avoid_catches_without_on_clauses`
+is too strict, catching anything is useful and common even if not always the
+most correct thing to do.
+
+`avoid_catching_errors`
+is too strict, the distinction between `Error` and `Exception` is followed
+closely in the SDK but is impractical to follow everywhere.
+
+`avoid_classes_with_only_static_members`
+is too strict, Effective Dart explicitly calls out some cases (constants,
+enum-like types) where it makes sense to violate this lint.
+
+`avoid_double_and_int_checks`
+only applies to web, but there is currently no mechanism for enabling a lint
+on web code only.
+
+`avoid_equals_and_hashcode_on_mutable_classes`
+would require the `@immutable` annotation to be consistently and correctly
+used everywhere.
+
+`avoid_field_initializers_in_const_classes`
+does not offer a clear readability benefit.
+
+`avoid_js_rounded_ints`
+only applies to web, but there is currently no mechanism for enabling a lint
+on web code only.
+
+`avoid_print`
+is too strict, it's okay to `print` in some code.
+
+`avoid_returning_null`
+will be obsoleted by NNBD.
+
+`avoid_returning_this`
+has occasional false positives, and adds little value as the cascade operator
+for fluent interfaces in Dart is already very popular.
+
+`avoid_slow_async_io`
+gives wrong advice if the underlying filesystem has unusual properties, for
+example a network mount.
+
+`avoid_void_async`
+prevents a valid style where an asynchronous method has a `void` return type
+to indicate that nobody should `await` for the result.
+
+`cancel_subscriptions`
+has false positives when you use a utility method or class to call `cancel`.
+
+`close_sinks`
+has false positives when you use a utility method or class to call `close`.
+
+`constant_identifier_names`
+is too strict as it does not support the exceptions allowed in Effective Dart
+for use of ALL_CAPS.
 
 `control_flow_in_finally`
 does not offer enough value: people are unlikely to do this by accident,
 and there are occasional valid uses.
 
+`directives_ordering`
+would enforce a slightly different ordering to that used by IntelliJ and other
+tools using the analyzer.
+
 `empty_statements`
 is superfluous, enforcing use of `dartfmt` is sufficient to make empty
  statements obvious.
 
+`flutter_style_todos`
+is for Flutter SDK internal use, see note about Flutter SDK style below.
+
+`invariant_booleans`
+is experimental.
+
+`join_return_with_assignment`
+does not reflect common usage.
+
+`one_member_abstracts`
+is too strict, classes might implement more than one such abstract class and
+there is no equivalent way to do this using functions.
+
+`parameter_assignments`
+does not reflect common usage, and will cause particular problems with NNBD
+code.
+
+`prefer_asserts_in_initializer_lists`
+does not reflect common usage.
+
+`prefer_asserts_with_message`
+is too strict; some asserts do not benefit from documentation.
+
 `prefer_bool_in_asserts`
  is obsolete in Dart 2; bool is required in asserts.
 
+`prefer_const_constructors`
+would add a lot of noise to code now that `new` is optional.
+
+`prefer_const_constructors_in_immutables`
+does not often apply as `@immutable` is not widely used.
+
+`prefer_const_literals_to_create_immutables`
+is too strict, requiring `const` everywhere adds noise.
+
+`prefer_constructors_over_static_methods`
+is too strict, in some cases static methods are better.
+
+`prefer_double_quotes`
+does not reflect common usage.
+
+`prefer_expression_function_bodies`
+is too strict, braces look better for long expressions.
+
+`prefer_final_in_for_each`
+does not reflect common usage.
+
 `prefer_final_locals`
-does not reflect standard usage.
+does not reflect common usage.
+
+`prefer_foreach`
+is too strict; `forEach` is not always an improvement.
+
+`prefer_int_literals`
+does not reflect common usage.
+
+`prefer_typing_uninitialized_variables`
+will be obsoleted by NNBD, which comes with type inference for uninitialized
+variables.
+
+`literal_only_boolean_expressions`
+does not offer enough value: such expressions are easily spotted and so hard
+to add by accident.
+
+`no_adjacent_strings_in_list`
+does not offer enough value: adjacent strings in lists are easily spotted
+when the code is formatted with `dartfmt`.
+
+`sort_constructors_first`
+does not reflect common usage.
+
+`sort_unnamed_constructors_first`
+is too strict, people are free to choose the best constructor ordering.
+
+`test_types_in_equals`
+does not offer enough value: there are plenty of other mistakes possible in
+`operator ==` implementations. It's better to use codegen.
+
+`unnecessary_null_aware_assignments`
+does not offer enough value: this is hard to do by mistake, and harmless.
+
+`use_setters_to_change_properties`
+is too strict: it can't detect when something is conceptually a property.
+
+`use_to_and_if_as_applicable`
+is too strict: it can't detect when the style rule actually applies.
 
 `throw_in_finally`
 does not offer enough value: people are unlikely to do this by accident,
diff --git a/pedantic/lib/analysis_options.1.9.0.yaml b/pedantic/lib/analysis_options.1.9.0.yaml
new file mode 100644
index 0000000..909283b
--- /dev/null
+++ b/pedantic/lib/analysis_options.1.9.0.yaml
@@ -0,0 +1,54 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Google internally enforced rules. See README.md for more information,
+# including a list of lints that are intentionally _not_ enforced.
+
+linter:
+  rules:
+    - always_declare_return_types
+    - always_require_non_null_named_parameters
+    - annotate_overrides
+    - avoid_empty_else
+    - avoid_init_to_null
+    - avoid_null_checks_in_equality_operators
+    - avoid_relative_lib_imports
+    - avoid_return_types_on_setters
+    - avoid_shadowing_type_parameters
+    - avoid_types_as_parameter_names
+    - camel_case_extensions
+    - curly_braces_in_flow_control_structures
+    - empty_catches
+    - empty_constructor_bodies
+    - library_names
+    - library_prefixes
+    - no_duplicate_case_values
+    - null_closures
+    - omit_local_variable_types
+    - prefer_adjacent_string_concatenation
+    - prefer_collection_literals
+    - prefer_conditional_assignment
+    - prefer_contains
+    - prefer_equal_for_default_values
+    - prefer_final_fields
+    - prefer_for_elements_to_map_fromIterable
+    - prefer_generic_function_type_aliases
+    - prefer_if_null_operators
+    - prefer_is_empty
+    - prefer_is_not_empty
+    - prefer_iterable_whereType
+    - prefer_single_quotes
+    - prefer_spread_collections
+    - recursive_getters
+    - slash_for_doc_comments
+    - type_init_formals
+    - unawaited_futures
+    - unnecessary_const
+    - unnecessary_new
+    - unnecessary_null_in_if_null_operators
+    - unnecessary_this
+    - unrelated_type_equality_checks
+    - use_function_type_syntax_for_parameters
+    - use_rethrow_when_possible
+    - valid_regexps
diff --git a/pedantic/lib/analysis_options.yaml b/pedantic/lib/analysis_options.yaml
index c8cc699..cb7021e 100644
--- a/pedantic/lib/analysis_options.yaml
+++ b/pedantic/lib/analysis_options.yaml
@@ -10,4 +10,4 @@
 # whenever a new version of `package:pedantic` is released. To avoid this,
 # specify a specific version of `analysis_options.yaml` instead.
 
-include: package:pedantic/analysis_options.1.8.0.yaml
+include: package:pedantic/analysis_options.1.9.0.yaml
diff --git a/pedantic/pubspec.yaml b/pedantic/pubspec.yaml
index 278d457..71d8bde 100644
--- a/pedantic/pubspec.yaml
+++ b/pedantic/pubspec.yaml
@@ -1,5 +1,5 @@
 name: pedantic
-version: 1.8.0+1
+version: 1.9.0
 description: How to get the most value from Dart static analysis.
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/pedantic
diff --git a/plugin_platform_interface/BUILD.gn b/plugin_platform_interface/BUILD.gn
index 7bd3695..9ea1fb5 100644
--- a/plugin_platform_interface/BUILD.gn
+++ b/plugin_platform_interface/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for plugin_platform_interface-1.0.1
+# This file is generated by importer.py for plugin_platform_interface-1.0.2
 
 import("//build/dart/dart_library.gni")
 
diff --git a/plugin_platform_interface/CHANGELOG.md b/plugin_platform_interface/CHANGELOG.md
index 9fa28ec..1c240ea 100644
--- a/plugin_platform_interface/CHANGELOG.md
+++ b/plugin_platform_interface/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.2
+
+* Make the pedantic dev_dependency explicit.
+
 ## 1.0.1
 
 * Fixed a bug that made all platform interfaces appear as mocks in release builds (https://github.com/flutter/flutter/issues/46941).
diff --git a/plugin_platform_interface/pubspec.yaml b/plugin_platform_interface/pubspec.yaml
index 4adfe6a..b5f263c 100644
--- a/plugin_platform_interface/pubspec.yaml
+++ b/plugin_platform_interface/pubspec.yaml
@@ -12,7 +12,7 @@
 # be done when absolutely necessary and after the ecosystem has already migrated to 1.X.Y version
 # that is forward compatible with 2.0.0 (ideally the ecosystem have migrated to depend on:
 # `plugin_platform_interface: >=1.X.Y <3.0.0`).
-version: 1.0.1
+version: 1.0.2
 
 homepage: https://github.com/flutter/plugins/plugin_platform_interface
 
@@ -25,3 +25,4 @@
 dev_dependencies:
   mockito: ^4.1.1
   test: ^1.9.4
+  pedantic: ^1.8.0
diff --git a/scratch_space/BUILD.gn b/scratch_space/BUILD.gn
deleted file mode 100644
index 959a1c8..0000000
--- a/scratch_space/BUILD.gn
+++ /dev/null
@@ -1,21 +0,0 @@
-# This file is generated by importer.py for scratch_space-0.0.4+2
-
-import("//build/dart/dart_library.gni")
-
-dart_library("scratch_space") {
-  package_name = "scratch_space"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/path",
-    "//third_party/dart-pkg/pub/pedantic",
-    "//third_party/dart-pkg/pub/build",
-    "//third_party/dart-pkg/pub/pool",
-    "//third_party/dart-pkg/pub/crypto",
-  ]
-}
diff --git a/scratch_space/CHANGELOG.md b/scratch_space/CHANGELOG.md
deleted file mode 100644
index c36f90f..0000000
--- a/scratch_space/CHANGELOG.md
+++ /dev/null
@@ -1,56 +0,0 @@
-## 0.0.4+2
-
-- Fix a race condition bug where `ensureAssets` would complete before all
-  pending writes were completed. If the next build was scheduled before these
-  writes finished then they would get the old result.
-
-## 0.0.4+1
-
-- Fix `ScratchSpace.fileFor` on windows to normalize the paths so they dont
-  contain mixed separators.
-
-## 0.0.4
-
-- Add `requireContent` argument to `copyOutput` to allow asserting that a file
-  produced in a scratch space is not empty.
-
-## 0.0.3+2
-
-- Declare support for `package:build` version `1.x.x`.
-
-## 0.0.3+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.0.3
-
-- Use digests to improve `ensureAssets` performance.
-  - Scratch spaces can now be used across builds without cleaning them up, and
-    will check digests and update assets as needed.
-
-## 0.0.2+1
-
-- Fix a bug where failing to read an asset in serve mode could get the build
-  stuck.
-
-## 0.0.2
-
-- Allow creating files at the root of the scratch space.
-
-## 0.0.1+3
-
-- Allow package:build 0.12.0
-
-## 0.0.1+2
-
-- Allow package:build 0.11.0
-
-## 0.0.1+1
-
-- Fix a deadlock issue around the file descriptor pool, only take control of a
-  resource right before actually touching disk instead of also encapsulating
-  the `readAsBytes` call from the wrapped `AssetReader`.
-
-## 0.0.1
-
-- Initial release, adds the `ScratchSpace` class.
diff --git a/scratch_space/LICENSE b/scratch_space/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/scratch_space/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/scratch_space/README.md b/scratch_space/README.md
deleted file mode 100644
index 341b8ee..0000000
--- a/scratch_space/README.md
+++ /dev/null
@@ -1,78 +0,0 @@
-[![Build Status](https://travis-ci.org/dart-lang/build.svg?branch=master)](https://travis-ci.org/dart-lang/build)
-[![Pub Package](https://img.shields.io/pub/v/scratch_space.svg)](https://pub.dev/packages/scratch_space)
-
-A [`ScratchSpace`][dartdoc:ScratchSpace] is a thin wrapper around a temporary
-directory. The constructor takes zero arguments, so making one is as simple as
-doing `new ScratchSpace()`.
-
-In general, you should wrap a `ScratchSpace` in a `Resource`, so that you can
-re-use the scratch space across build steps in an individual build. This is
-safe to do since you are not allowed to overwrite files within a build.
-
-This should look something like the following:
-
-```
-final myScratchSpaceResource =
-    new Resource(() => new ScratchSpace(), dispose: (old) => old.delete());
-```
-
-And then you can get access to it through the `BuildStep#fetchResource` api:
-
-```
-class MyBuilder extends Builder {
-  Future build(BuildStep buildStep) async {
-    var scratchSpace = await buildStep.fetchResource(myScratchSpaceResource);
-  }
-}
-```
-
-### Adding assets to a `ScratchSpace`
-
-To add assets to the `ScratchSpace`, you use the `ensureAssets` method, which
-takes an `Iterable<AssetId>` and an `AssetReader` (for which you should
-generally pass your `BuildStep` which implements that interface).
-
-You must always call this method with all assets that your external executable
-might need in order to set up the proper dependencies and ensure hermetic
-builds.
-
-**Note:** It is important to note that the `ScratchSpace` does not guarantee
-that the version of a file within it is the most updated version, only that
-some version of it exists. For this reason you should create a new
-`ScratchSpace` for each build using the `Resource` class as recommended above.
-
-### Deleting a `ScratchSpace`
-
-When you are done with a `ScratchSpace` you should call `delete` on it to make
-sure it gets cleaned up, otherwise you can end up filling up the users tmp
-directory.
-
-**Note:** You cannot delete individual assets from a `ScratchSpace` today, you
-can only delete the entire thing. If you have a use case for deleting
-individual files you can [file an issue][tracker].
-
-### Getting the actual File objects for a `ScratchSpace`
-
-When invoking an external binary, you probably need to tell it where to look
-for files. There are a few fields/methods to help you do this:
-
-  * `String get packagesDir`: The `packages` directory in the `ScratchSpace`.
-  * `String get tmpDir`: The root temp directory for the `ScratchSpace`.
-  * `File fileFor(AssetId id)`: The File object for `id`.
-
-### Copying back outputs from the temp directory
-
-After running your executable, you most likely have some outputs that you
-need to notify the build system about. To do this you can use the `copyOutput`
-method, which takes an `AssetId` and `AssetWriter` (for which you should
-generally pass your `BuildStep` which implements that interface).
-
-This will copy the asset referenced by the `AssetId` from the temp directory
-back to your actual output directory.
-
-## Feature requests and bugs
-
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/build/issues
-[dartdoc:ScratchSpace]: https://pub.dev/documentation/scratch_space/latest/scratch_space/ScratchSpace-class.html
diff --git a/scratch_space/lib/scratch_space.dart b/scratch_space/lib/scratch_space.dart
deleted file mode 100644
index 95c4c8e..0000000
--- a/scratch_space/lib/scratch_space.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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.
-
-export 'src/scratch_space.dart'
-    show ScratchSpace, canonicalUriFor, EmptyOutputException;
diff --git a/scratch_space/lib/src/scratch_space.dart b/scratch_space/lib/src/scratch_space.dart
deleted file mode 100644
index d467cb3..0000000
--- a/scratch_space/lib/src/scratch_space.dart
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:path/path.dart' as p;
-import 'package:pedantic/pedantic.dart';
-import 'package:pool/pool.dart';
-
-import 'util.dart';
-
-/// Pool for async file writes, we don't want to use too many file handles.
-final _descriptorPool = Pool(32);
-
-/// An on-disk temporary environment for running executables that don't have
-/// a standard Dart library API.
-class ScratchSpace {
-  /// Whether or not this scratch space still exists.
-  bool exists = true;
-
-  /// The `packages` directory under the temp directory.
-  final Directory packagesDir;
-
-  /// The temp directory at the root of this [ScratchSpace].
-  final Directory tempDir;
-
-  // Assets which have a file created but are still being written to.
-  final _pendingWrites = <AssetId, Future<void>>{};
-
-  final _digests = <AssetId, Digest>{};
-
-  ScratchSpace._(this.tempDir)
-      : packagesDir = Directory(p.join(tempDir.path, 'packages'));
-
-  factory ScratchSpace() {
-    var tempDir = Directory(Directory.systemTemp
-        .createTempSync('scratch_space')
-        .resolveSymbolicLinksSync());
-    return ScratchSpace._(tempDir);
-  }
-
-  /// Copies [id] from the tmp dir and writes it back using the [writer].
-  ///
-  /// Note that [BuildStep] implements [AssetWriter] and that is typically
-  /// what you will want to pass in.
-  ///
-  /// This must be called for all outputs which you want to be included as a
-  /// part of the actual build (any other outputs will be deleted with the
-  /// tmp dir and won't be available to other [Builder]s).
-  ///
-  /// If [requireContent] is true and the file is empty an
-  /// [EmptyOutputException] is thrown.
-  Future copyOutput(AssetId id, AssetWriter writer,
-      {bool requireContent = false}) async {
-    var file = fileFor(id);
-    var bytes = await _descriptorPool.withResource(file.readAsBytes);
-    if (requireContent && bytes.isEmpty) throw EmptyOutputException(id);
-    await writer.writeAsBytes(id, bytes);
-  }
-
-  /// Deletes the temp directory for this environment.
-  ///
-  /// This class is no longer valid once the directory is deleted, you must
-  /// create a new [ScratchSpace].
-  Future delete() async {
-    if (!exists) {
-      throw StateError(
-          'Tried to delete a ScratchSpace which was already deleted');
-    }
-    exists = false;
-    _digests.clear();
-    if (_pendingWrites.isNotEmpty) {
-      try {
-        await Future.wait(_pendingWrites.values);
-      } catch (_) {
-        // Ignore any errors, we are essentially just draining this queue
-        // of pending writes but don't care about the result.
-      }
-    }
-    return tempDir.delete(recursive: true);
-  }
-
-  /// Copies [assetIds] to [tempDir] if they don't exist, using [reader] to
-  /// read assets and mark dependencies.
-  ///
-  /// Note that [BuildStep] implements [AssetReader] and that is typically
-  /// what you will want to pass in.
-  ///
-  /// Any asset that is under a `lib` dir will be output under a `packages`
-  /// directory corresponding to its package, and any other assets are output
-  /// directly under the temp dir using their unmodified path.
-  Future ensureAssets(Iterable<AssetId> assetIds, AssetReader reader) {
-    if (!exists) {
-      throw StateError('Tried to use a deleted ScratchSpace!');
-    }
-
-    var futures = assetIds.map((id) async {
-      var digest = await reader.digest(id);
-      var existing = _digests[id];
-      if (digest == existing) {
-        await _pendingWrites[id];
-        return;
-      }
-      _digests[id] = digest;
-
-      try {
-        await _pendingWrites.putIfAbsent(
-            id,
-            () => _descriptorPool.withResource(() async {
-                  var file = fileFor(id);
-                  if (await file.exists()) {
-                    await file.delete();
-                  }
-                  await file.create(recursive: true);
-                  await file.writeAsBytes(await reader.readAsBytes(id));
-                }));
-      } finally {
-        unawaited(_pendingWrites.remove(id));
-      }
-    }).toList();
-
-    return Future.wait(futures);
-  }
-
-  /// Returns the actual [File] in this environment corresponding to [id].
-  ///
-  /// The returned [File] may or may not already exist. Call [ensureAssets]
-  /// with [id] to make sure it is actually present.
-  File fileFor(AssetId id) =>
-      File(p.join(tempDir.path, p.normalize(_relativePathFor(id))));
-}
-
-/// Returns a canonical uri for [id].
-///
-/// If [id] is under a `lib` directory then this returns a `package:` uri,
-/// otherwise it just returns [id#path].
-String canonicalUriFor(AssetId id) {
-  if (topLevelDir(id.path) == 'lib') {
-    var packagePath =
-        p.url.join(id.package, p.url.joinAll(p.url.split(id.path).skip(1)));
-    return 'package:$packagePath';
-  } else {
-    return id.path;
-  }
-}
-
-/// The path relative to the root of the environment for a given [id].
-String _relativePathFor(AssetId id) =>
-    canonicalUriFor(id).replaceFirst('package:', 'packages/');
-
-/// An indication that an output file which was expect to be non-empty had no
-/// content.
-class EmptyOutputException implements Exception {
-  final AssetId id;
-  EmptyOutputException(this.id);
-}
diff --git a/scratch_space/lib/src/util.dart b/scratch_space/lib/src/util.dart
deleted file mode 100644
index ae8f1b7..0000000
--- a/scratch_space/lib/src/util.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:path/path.dart' as p;
-
-/// Returns the top level directory in [uri].
-///
-/// Throws an [ArgumentError] if [uri] reaches above the top level directory.
-String topLevelDir(String uri) {
-  var parts = p.url.split(p.url.normalize(uri));
-  if (parts.first == '..') {
-    throw ArgumentError('Cannot compute top level dir for path `$uri` '
-        'which reaches outside the root directory.');
-  }
-  return parts.length == 1 ? null : parts.first;
-}
diff --git a/scratch_space/mono_pkg.yaml b/scratch_space/mono_pkg.yaml
deleted file mode 100644
index 0271728..0000000
--- a/scratch_space/mono_pkg.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-dart:
-  - dev
-
-stages:
-  - analyze_and_format:
-    - group:
-        - dartfmt: sdk
-        - dartanalyzer: --fatal-infos --fatal-warnings .
-    - dartanalyzer: --fatal-warnings .
-      dart:
-        - 2.3.0
-  - unit_test:
-    - command: pub run build_runner test
-      os:
-        - linux
-        - windows
-
-cache:
-  directories:
-    - .dart_tool/build
diff --git a/scratch_space/pubspec.yaml b/scratch_space/pubspec.yaml
deleted file mode 100644
index 11326df..0000000
--- a/scratch_space/pubspec.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: scratch_space
-version: 0.0.4+2
-description: A tool to manage running external executables within package:build
-homepage: https://github.com/dart-lang/build/tree/master/scratch_space
-
-environment:
-  sdk: ">=2.3.0 <3.0.0"
-
-dependencies:
-  build: ">=0.10.0 <2.0.0"
-  crypto: ">=2.0.3 <3.0.0"
-  path: ^1.1.0
-  pedantic: ^1.0.0
-  pool: ^1.0.0
-
-dev_dependencies:
-  build_runner: ^1.0.0
-  build_test: ^0.10.0
-  build_vm_compilers: ">=0.1.0 <2.0.0"
-  test: ^1.0.0
diff --git a/source_map_stack_trace/.travis.yml b/source_map_stack_trace/.travis.yml
index 3895dfc..de32a3b 100644
--- a/source_map_stack_trace/.travis.yml
+++ b/source_map_stack_trace/.travis.yml
@@ -5,7 +5,7 @@
 
 dart:
   - dev
-  - stable
+  - 2.7.0
 
 dart_task:
   - test: -p chrome,vm
@@ -16,7 +16,8 @@
     - dart: dev
       dart_task: dartfmt
     - dart: dev
-      dart_task: analyzer
+      dart_task:
+        dartanalizer: --fatal-warnings --fatal-infos .
 
 # Only building master means that we don't run two builds for each pull request.
 branches:
diff --git a/source_map_stack_trace/BUILD.gn b/source_map_stack_trace/BUILD.gn
index 4d50473..d58f4e1 100644
--- a/source_map_stack_trace/BUILD.gn
+++ b/source_map_stack_trace/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for source_map_stack_trace-1.1.5
+# This file is generated by importer.py for source_map_stack_trace-2.0.0
 
 import("//build/dart/dart_library.gni")
 
@@ -13,7 +13,6 @@
 
   deps = [
     "//third_party/dart-pkg/pub/source_maps",
-    "//third_party/dart-pkg/pub/package_resolver",
     "//third_party/dart-pkg/pub/path",
     "//third_party/dart-pkg/pub/stack_trace",
   ]
diff --git a/source_map_stack_trace/CHANGELOG.md b/source_map_stack_trace/CHANGELOG.md
index 4acc71e..5bfef35 100644
--- a/source_map_stack_trace/CHANGELOG.md
+++ b/source_map_stack_trace/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 2.0.0
+
+### Breaking Changes
+
+* Removed dependency on `package_resolver` and changed the apis to accept a
+  `Map<String, Uri>` which maps package names to the base uri to resolve the
+  `package:` uris for those packages.
+* The `sdkRoot` argument must be an `Uri`. Use `Uri.parse` for use
+  cases previously passing a `String`.
+* The deprecated `packageRoot` argument has been removed.
+
 ## 1.1.5
 
 * Set max SDK version to `<3.0.0`.
diff --git a/source_map_stack_trace/analysis_options.yaml b/source_map_stack_trace/analysis_options.yaml
new file mode 100644
index 0000000..76c449a
--- /dev/null
+++ b/source_map_stack_trace/analysis_options.yaml
@@ -0,0 +1,6 @@
+include: package:pedantic/analysis_options.yaml
+analyzer:
+  strong-mode:
+    implicit-casts: false
+  language:
+    strict-raw-types: true
diff --git a/source_map_stack_trace/codereview.settings b/source_map_stack_trace/codereview.settings
deleted file mode 100644
index 78c567f..0000000
--- a/source_map_stack_trace/codereview.settings
+++ /dev/null
@@ -1,3 +0,0 @@
-CODE_REVIEW_SERVER: https://codereview.chromium.org/
-VIEW_VC: https://github.com/dart-lang/source_map_stack_trace/commit/
-CC_LIST: reviews@dartlang.org
\ No newline at end of file
diff --git a/source_map_stack_trace/lib/source_map_stack_trace.dart b/source_map_stack_trace/lib/source_map_stack_trace.dart
index d0252e0..fd1226a 100644
--- a/source_map_stack_trace/lib/source_map_stack_trace.dart
+++ b/source_map_stack_trace/lib/source_map_stack_trace.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:package_resolver/package_resolver.dart';
 import 'package:path/path.dart' as p;
 import 'package:source_maps/source_maps.dart';
 import 'package:stack_trace/stack_trace.dart';
@@ -13,53 +12,31 @@
 /// [minified] indicates whether or not the dart2js code was minified. If it
 /// hasn't, this tries to clean up the stack frame member names.
 ///
-/// If [packageResolver] is passed, it's used to reconstruct `package:` URIs for
-/// stack frames that come from packages.
+/// The [packageMap] maps package names to the base uri used to resolve the
+/// `package:` uris for those packages. It is used to  it's used to reconstruct
+/// `package:` URIs for stack frames that come from packages.
 ///
-/// [sdkRoot] is the URI (usually a `file:` URI) for the SDK containing dart2js.
-/// It can be a [String] or a [Uri]. If it's passed, stack frames from the SDK
-/// will have `dart:` URLs.
-///
-/// [packageRoot] is deprecated and shouldn't be used in new code. This throws
-/// an [ArgumentError] if [packageRoot] and [packageResolver] are both passed.
+/// [sdkRoot] is the URI surfaced in the stack traces for SDK libraries.
+/// If it's passed, stack frames from the SDK will have `dart:` URLs.
 StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
-    {bool minified: false,
-    SyncPackageResolver packageResolver,
-    sdkRoot,
-    @Deprecated("Use the packageResolver parameter instead.") packageRoot}) {
-  if (packageRoot != null) {
-    if (packageResolver != null) {
-      throw new ArgumentError(
-          "packageResolver and packageRoot may not both be passed.");
-    }
-
-    packageResolver = new SyncPackageResolver.root(packageRoot);
-  }
-
+    {bool minified = false, Map<String, Uri> packageMap, Uri sdkRoot}) {
   if (stackTrace is Chain) {
-    return new Chain(stackTrace.traces.map((trace) {
-      return new Trace.from(mapStackTrace(sourceMap, trace,
-          minified: minified,
-          packageResolver: packageResolver,
-          sdkRoot: sdkRoot));
+    return Chain(stackTrace.traces.map((trace) {
+      return Trace.from(mapStackTrace(sourceMap, trace,
+          minified: minified, packageMap: packageMap, sdkRoot: sdkRoot));
     }));
   }
 
-  if (sdkRoot != null && sdkRoot is! String && sdkRoot is! Uri) {
-    throw new ArgumentError(
-        'sdkRoot must be a String or a Uri, was "$sdkRoot".');
-  }
+  var sdkLib = sdkRoot == null ? null : '$sdkRoot/lib';
 
-  var sdkLib = sdkRoot == null ? null : "$sdkRoot/lib";
-
-  var trace = new Trace.from(stackTrace);
-  return new Trace(trace.frames.map((frame) {
+  var trace = Trace.from(stackTrace);
+  return Trace(trace.frames.map((frame) {
     // If there's no line information, there's no way to translate this frame.
     // We could return it as-is, but these lines are usually not useful anyways.
     if (frame.line == null) return null;
 
     // If there's no column, try using the first column of the line.
-    var column = frame.column == null ? 0 : frame.column;
+    var column = frame.column ?? 0;
 
     // Subtract 1 because stack traces use 1-indexed lines and columns and
     // source maps uses 0-indexed.
@@ -72,26 +49,19 @@
 
     var sourceUrl = span.sourceUrl.toString();
     if (sdkRoot != null && p.url.isWithin(sdkLib, sourceUrl)) {
-      sourceUrl = "dart:" + p.url.relative(sourceUrl, from: sdkLib);
-    } else if (packageResolver != null) {
-      if (packageResolver.packageRoot != null &&
-          p.url.isWithin(packageResolver.packageRoot.toString(), sourceUrl)) {
-        sourceUrl = "package:" +
-            p.url.relative(sourceUrl,
-                from: packageResolver.packageRoot.toString());
-      } else if (packageResolver.packageConfigMap != null) {
-        for (var package in packageResolver.packageConfigMap.keys) {
-          var packageUrl = packageResolver.packageConfigMap[package].toString();
-          if (!p.url.isWithin(packageUrl, sourceUrl)) continue;
+      sourceUrl = 'dart:' + p.url.relative(sourceUrl, from: sdkLib);
+    } else if (packageMap != null) {
+      for (var package in packageMap.keys) {
+        var packageUrl = packageMap[package].toString();
+        if (!p.url.isWithin(packageUrl, sourceUrl)) continue;
 
-          sourceUrl =
-              "package:$package/" + p.url.relative(sourceUrl, from: packageUrl);
-          break;
-        }
+        sourceUrl =
+            'package:$package/' + p.url.relative(sourceUrl, from: packageUrl);
+        break;
       }
     }
 
-    return new Frame(
+    return Frame(
         Uri.parse(sourceUrl),
         span.start.line + 1,
         span.start.column + 1,
@@ -108,27 +78,26 @@
 String _prettifyMember(String member) {
   return member
       // Get rid of the noise that Firefox sometimes adds.
-      .replaceAll(new RegExp(r"/?<$"), "")
+      .replaceAll(RegExp(r'/?<$'), '')
       // Get rid of arity indicators and named arguments.
-      .replaceAll(new RegExp(r"\$\d+(\$[a-zA-Z_0-9]+)*$"), "")
+      .replaceAll(RegExp(r'\$\d+(\$[a-zA-Z_0-9]+)*$'), '')
       // Convert closures to <fn>.
       .replaceAllMapped(
-          new RegExp(r"(_+)closure\d*\.call$"),
+          RegExp(r'(_+)closure\d*\.call$'),
           // The number of underscores before "closure" indicates how nested it
           // is.
-          (match) => ".<fn>" * match[1].length)
+          (match) => '.<fn>' * match[1].length)
       // Get rid of explicitly-generated calls.
-      .replaceAll(new RegExp(r"\.call$"), "")
+      .replaceAll(RegExp(r'\.call$'), '')
       // Get rid of the top-level method prefix.
-      .replaceAll(new RegExp(r"^dart\."), "")
+      .replaceAll(RegExp(r'^dart\.'), '')
       // Get rid of library namespaces.
-      .replaceAll(new RegExp(r"[a-zA-Z_0-9]+\$"), "")
+      .replaceAll(RegExp(r'[a-zA-Z_0-9]+\$'), '')
       // Get rid of the static method prefix. The class name also exists in the
       // invocation, so we're not getting rid of any information.
-      .replaceAll(new RegExp(r"^[a-zA-Z_0-9]+.(static|dart)."), "")
+      .replaceAll(RegExp(r'^[a-zA-Z_0-9]+.(static|dart).'), '')
       // Convert underscores after identifiers to dots. This runs the risk of
       // incorrectly converting members that contain underscores, but those are
       // contrary to the style guide anyway.
-      .replaceAllMapped(
-          new RegExp(r"([a-zA-Z0-9]+)_"), (match) => match[1] + ".");
+      .replaceAllMapped(RegExp(r'([a-zA-Z0-9]+)_'), (match) => match[1] + '.');
 }
diff --git a/source_map_stack_trace/pubspec.yaml b/source_map_stack_trace/pubspec.yaml
index 77cf804..b998d38 100644
--- a/source_map_stack_trace/pubspec.yaml
+++ b/source_map_stack_trace/pubspec.yaml
@@ -1,18 +1,30 @@
 name: source_map_stack_trace
-version: 1.1.5
-
+version: 2.0.0
 description: A package for applying source maps to stack traces.
-author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/source_map_stack_trace
 
 environment:
-  sdk: '>=1.8.0 <3.0.0'
+  sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
-  package_resolver: ^1.0.0
   path: ^1.0.0
   stack_trace: ^1.0.0
   source_maps: ^0.10.2
 
 dev_dependencies:
-  test: '>=0.12.0 <2.0.0'
+  source_span: ^1.6.0
+  test: ^1.12.0
+  pedantic: ^1.0.0
+
+dependency_overrides:
+  # Required to get a valid pub solve until package:test updates
+  #test_core:
+  #  git:
+  #    url: https://github.com/dart-lang/test.git
+  #    ref: drop-package-resolver
+  #    path: pkgs/test_core
+  #test:
+  #  git:
+  #    url: https://github.com/dart-lang/test.git
+  #    ref: drop-package-resolver
+  #    path: pkgs/test
diff --git a/sse/BUILD.gn b/sse/BUILD.gn
index a691b9f..d993492 100644
--- a/sse/BUILD.gn
+++ b/sse/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for sse-3.1.2
+# This file is generated by importer.py for sse-3.2.1
 
 import("//build/dart/dart_library.gni")
 
diff --git a/sse/CHANGELOG.md b/sse/CHANGELOG.md
index b5fb859..5135fb4 100644
--- a/sse/CHANGELOG.md
+++ b/sse/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 3.2.1
+
+- Fix an issue where `keepAlive` would only allow a single reconnection.
+
+## 3.2.0
+
+- Re-expose `isInKeepAlivePeriod` flag on `SseConnection`. This flag will be
+  `true` when a connection has been dropped and is in the keep-alive period
+  waiting for a client to reconnect.
+
 ## 3.1.2
 
 - Fix an issue where the `SseClient` would not send a `done` event when there
diff --git a/sse/lib/src/server/sse_handler.dart b/sse/lib/src/server/sse_handler.dart
index 9c3d91e..1749f46 100644
--- a/sse/lib/src/server/sse_handler.dart
+++ b/sse/lib/src/server/sse_handler.dart
@@ -37,7 +37,7 @@
   Timer _keepAliveTimer;
 
   /// Whether this connection is currently in the KeepAlive timeout period.
-  bool get _isInKeepAlivePeriod => _keepAliveTimer?.isActive ?? false;
+  bool get isInKeepAlivePeriod => _keepAliveTimer?.isActive ?? false;
 
   final _closedCompleter = Completer<void>();
 
@@ -60,7 +60,7 @@
     while (await outgoingStreamQueue.hasNext) {
       // If we're in a KeepAlive timeout, there's nowhere to send messages so
       // wait a short period and check again.
-      if (_isInKeepAlivePeriod) {
+      if (isInKeepAlivePeriod) {
         await Future.delayed(const Duration(milliseconds: 200));
         continue;
       }
@@ -105,7 +105,7 @@
     if (_keepAlive == null) {
       // Close immediately if we're not keeping alive.
       _close();
-    } else if (!_isInKeepAlivePeriod) {
+    } else if (!isInKeepAlivePeriod) {
       // Otherwise if we didn't already have an active timer, set a timer to
       // close after the timeout period. If the connection comes back, this will
       // be cancelled and all messages left in the queue tried again.
@@ -155,7 +155,7 @@
       // Check if we already have a connection for this ID that is in the process
       // of timing out (in which case we can reconnect it transparently).
       if (_connections[clientId] != null &&
-          _connections[clientId]._isInKeepAlivePeriod) {
+          _connections[clientId].isInKeepAlivePeriod) {
         _connections[clientId]._acceptReconnection(sink);
       } else {
         var connection = SseConnection(sink, keepAlive: _keepAlive);
@@ -163,16 +163,15 @@
         unawaited(connection._closedCompleter.future.then((_) {
           _connections.remove(clientId);
         }));
-        // Remove connection when it is remotely closed or the stream is
-        // cancelled.
-        channel.stream.listen((_) {
-          // SSE is unidirectional. Responses are handled through POST requests.
-        }, onDone: () {
-          connection._handleDisconnect();
-        });
-
         _connectionController.add(connection);
       }
+      // Remove connection when it is remotely closed or the stream is
+      // cancelled.
+      channel.stream.listen((_) {
+        // SSE is unidirectional. Responses are handled through POST requests.
+      }, onDone: () {
+        _connections[clientId]?._handleDisconnect();
+      });
     });
     return shelf.Response.notFound('');
   }
diff --git a/sse/pubspec.yaml b/sse/pubspec.yaml
index 86d3c13..1381d61 100644
--- a/sse/pubspec.yaml
+++ b/sse/pubspec.yaml
@@ -1,5 +1,5 @@
 name: sse
-version: 3.1.2
+version: 3.2.1
 homepage: https://github.com/dart-lang/sse
 description: >-
   Provides client and server functionality for setting up bi-directional
diff --git a/stream_transform/.travis.yml b/stream_transform/.travis.yml
index d69c3f7..596c0c6 100644
--- a/stream_transform/.travis.yml
+++ b/stream_transform/.travis.yml
@@ -3,12 +3,21 @@
   only: [master]
 dart:
   - dev
-  # 2.2.0
+  - 2.6.0
 cache:
   directories:
     - $HOME/.pub-cache
 dart_task:
-  - test
-  - test -p chrome
-  - dartfmt
-  - dartanalyzer: --fatal-warnings --fatal-infos .
+  - test --test-randomize-ordering-seed=random
+  - test -p chrome --test-randomize-ordering-seed=random
+
+matrix:
+  include:
+    - dart: dev
+      dart_task: dartfmt
+    - dart: dev
+      dart_task:
+        dartanalyzer: --fatal-warnings --fatal-infos .
+    - dart: 2.6.0
+      dart_task:
+        dartanalyzer: --fatal-warnings .
diff --git a/stream_transform/BUILD.gn b/stream_transform/BUILD.gn
index fcf871b..4ad82b3 100644
--- a/stream_transform/BUILD.gn
+++ b/stream_transform/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for stream_transform-1.1.0
+# This file is generated by importer.py for stream_transform-1.2.0
 
 import("//build/dart/dart_library.gni")
 
diff --git a/stream_transform/CHANGELOG.md b/stream_transform/CHANGELOG.md
index 686f919..f4cf395 100644
--- a/stream_transform/CHANGELOG.md
+++ b/stream_transform/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 1.2.0
+
+-  Add support for emitting the "leading" event in `debounce`.
+
+## 1.1.1
+
+-   Fix a bug in `asyncMapSample`, `buffer`, `combineLatest`,
+    `combineLatestAll`, `merge`, and `mergeAll` which would cause an exception
+    when cancelling a subscription after using the transformer if the original
+    stream(s) returned `null` from cancelling their subscriptions.
+
 ## 1.1.0
 
 -   Add `concurrentAsyncExpand` to interleave events emitted by multiple sub
diff --git a/stream_transform/lib/src/aggregate_sample.dart b/stream_transform/lib/src/aggregate_sample.dart
index a069af7..88fc490 100644
--- a/stream_transform/lib/src/aggregate_sample.dart
+++ b/stream_transform/lib/src/aggregate_sample.dart
@@ -32,13 +32,13 @@
     StreamSubscription<S> valueSub;
     StreamSubscription<void> triggerSub;
 
-    emit() {
+    void emit() {
       controller.add(currentResults);
       currentResults = null;
       waitingForTrigger = true;
     }
 
-    onValue(S value) {
+    void onValue(S value) {
       currentResults = _aggregate(value, currentResults);
 
       if (!waitingForTrigger) emit();
@@ -49,7 +49,7 @@
       }
     }
 
-    onValuesDone() {
+    void onValuesDone() {
       isValueDone = true;
       if (currentResults == null) {
         triggerSub?.cancel();
@@ -57,7 +57,7 @@
       }
     }
 
-    onTrigger(_) {
+    void onTrigger(_) {
       waitingForTrigger = false;
 
       if (currentResults != null) emit();
@@ -68,7 +68,7 @@
       }
     }
 
-    onTriggerDone() {
+    void onTriggerDone() {
       isTriggerDone = true;
       if (waitingForTrigger) {
         valueSub?.cancel();
@@ -107,8 +107,10 @@
         } else {
           triggerSub.pause();
         }
-        if (toCancel.isEmpty) return null;
-        return Future.wait(toCancel.map((s) => s.cancel()));
+        var cancels =
+            toCancel.map((s) => s.cancel()).where((f) => f != null).toList();
+        if (cancels.isEmpty) return null;
+        return Future.wait(cancels).then((_) => null);
       };
     };
     return controller.stream;
diff --git a/stream_transform/lib/src/async_map.dart b/stream_transform/lib/src/async_map.dart
index f002667..c5b160b 100644
--- a/stream_transform/lib/src/async_map.dart
+++ b/stream_transform/lib/src/async_map.dart
@@ -89,7 +89,7 @@
   ///
   /// The result stream will not close until the source stream closes and all
   /// pending conversions have finished.
-  Stream<S> concurrentAsyncMap<S>(FutureOr<S> convert(T event)) {
+  Stream<S> concurrentAsyncMap<S>(FutureOr<S> Function(T) convert) {
     var valuesWaiting = 0;
     var sourceDone = false;
     return transform(fromHandlers(handleData: (element, sink) {
@@ -116,7 +116,7 @@
 /// rather than once per listener, and [then] is called after completing the
 /// work.
 StreamTransformer<S, T> _asyncMapThen<S, T>(
-    Future<T> convert(S event), void Function(void) then) {
+    Future<T> Function(S) convert, void Function(void) then) {
   Future<void> pendingEvent;
   return fromHandlers(handleData: (event, sink) {
     pendingEvent =
diff --git a/stream_transform/lib/src/combine_latest.dart b/stream_transform/lib/src/combine_latest.dart
index 7fee05d..303b16a 100644
--- a/stream_transform/lib/src/combine_latest.dart
+++ b/stream_transform/lib/src/combine_latest.dart
@@ -175,11 +175,11 @@
           };
       }
       controller.onCancel = () {
-        var cancelSource = sourceSubscription.cancel();
-        var cancelOther = otherSubscription.cancel();
+        var cancels = [sourceSubscription.cancel(), otherSubscription.cancel()]
+            .where((f) => f != null);
         sourceSubscription = null;
         otherSubscription = null;
-        return Future.wait([cancelSource, cancelOther]);
+        return Future.wait(cancels).then((_) => null);
       };
     };
     return controller.stream;
@@ -249,8 +249,12 @@
           };
       }
       controller.onCancel = () {
-        if (subscriptions.isEmpty) return null;
-        return Future.wait(subscriptions.map((s) => s.cancel()));
+        var cancels = subscriptions
+            .map((s) => s.cancel())
+            .where((f) => f != null)
+            .toList();
+        if (cancels.isEmpty) return null;
+        return Future.wait(cancels).then((_) => null);
       };
     };
     return controller.stream;
diff --git a/stream_transform/lib/src/concatenate.dart b/stream_transform/lib/src/concatenate.dart
index f9ba747..05c977f 100644
--- a/stream_transform/lib/src/concatenate.dart
+++ b/stream_transform/lib/src/concatenate.dart
@@ -75,17 +75,17 @@
 
     Function currentDoneHandler;
 
-    listen() {
+    void listen() {
       subscription = currentStream.listen(controller.add,
           onError: controller.addError, onDone: () => currentDoneHandler());
     }
 
-    onSecondDone() {
+    void onSecondDone() {
       secondDone = true;
       controller.close();
     }
 
-    onFirstDone() {
+    void onFirstDone() {
       firstDone = true;
       currentStream = next;
       currentDoneHandler = onSecondDone;
diff --git a/stream_transform/lib/src/merge.dart b/stream_transform/lib/src/merge.dart
index 99d19c9..f654d35 100644
--- a/stream_transform/lib/src/merge.dart
+++ b/stream_transform/lib/src/merge.dart
@@ -124,8 +124,12 @@
           };
       }
       controller.onCancel = () {
-        if (subscriptions.isEmpty) return null;
-        return Future.wait(subscriptions.map((s) => s.cancel()));
+        var cancels = subscriptions
+            .map((s) => s.cancel())
+            .where((f) => f != null)
+            .toList();
+        if (cancels.isEmpty) return null;
+        return Future.wait(cancels).then((_) => null);
       };
     };
     return controller.stream;
@@ -172,7 +176,12 @@
           };
       }
       controller.onCancel = () {
-        return Future.wait(subscriptions.map((s) => s.cancel()));
+        var cancels = subscriptions
+            .map((s) => s.cancel())
+            .where((f) => f != null)
+            .toList();
+        if (cancels.isEmpty) return null;
+        return Future.wait(cancels).then((_) => null);
       };
     };
     return controller.stream;
diff --git a/stream_transform/lib/src/rate_limit.dart b/stream_transform/lib/src/rate_limit.dart
index db6d7df..6341c3e 100644
--- a/stream_transform/lib/src/rate_limit.dart
+++ b/stream_transform/lib/src/rate_limit.dart
@@ -9,30 +9,55 @@
 
 /// Utilities to rate limit events.
 ///
-/// - [debounce] - emit the _first_ event at the _end_ of the period.
-/// - [debounceBuffer] - emit _all_ events at the _end_ of the period.
+/// - [debounce] - emit the the _first_ or _last_ event of a series of closely
+///   spaced events.
+/// - [debounceBuffer] - emit _all_ events at the _end_ of a series of closely
+///   spaced events.
 /// - [throttle] - emit the _first_ event at the _beginning_ of the period.
 /// - [audit] - emit the _last_ event at the _end_ of the period.
 /// - [buffer] - emit _all_ events on a _trigger_.
 extension RateLimit<T> on Stream<T> {
-  /// Returns a Stream which only emits when the source stream does not emit for
-  /// [duration].
+  /// Returns a Stream which suppresses events with less inter-event spacing
+  /// than [duration].
   ///
-  /// Values will always be delayed by at least [duration], and values which
-  /// come within this time will replace the old values, only the most
-  /// recent value will be emitted.
+  /// Events which are emitted with less than [duration] elapsed between them
+  /// are considered to be part of the same "series". If [leading] is `true`,
+  /// the first event of this series is emitted immediately. If [trailing] is
+  /// `true` the last event of this series is emitted with a delay of at least
+  /// [duration]. By default only trailing events are emitted, both arguments
+  /// must be specified with `leading: true, trailing: false` to emit only
+  /// leading events.
   ///
   /// If the source stream is a broadcast stream, the result will be as well.
   /// Errors are forwarded immediately.
   ///
-  /// If there is an event waiting during the debounce period when the source
-  /// stream closes the returned stream will wait to emit it following the
-  /// debounce period before closing. If there is no pending debounced event
+  /// If there is a trailing event waiting during the debounce period when the
+  /// source stream closes the returned stream will wait to emit it following
+  /// the debounce period before closing. If there is no pending debounced event
   /// when the source stream closes the returned stream will close immediately.
   ///
+  /// For example:
+  ///
+  ///     source.debouce(Duration(seconds: 1));
+  ///
+  ///     source: 1-2-3---4---5-6-|
+  ///     result: ------3---4-----6|
+  ///
+  ///     source.debouce(Duration(seconds: 1), leading: true, trailing: false);
+  ///
+  ///     source: 1-2-3---4---5-6-|
+  ///     result: 1-------4---5---|
+  ///
+  ///     source.debouce(Duration(seconds: 1), leading: true);
+  ///
+  ///     source: 1-2-3---4---5-6-|
+  ///     result: 1-----3-4---5---6|
+  ///
   /// To collect values emitted during the debounce period see [debounceBuffer].
-  Stream<T> debounce(Duration duration) =>
-      transform(_debounceAggregate(duration, _dropPrevious));
+  Stream<T> debounce(Duration duration,
+          {bool leading = false, bool trailing = true}) =>
+      transform(_debounceAggregate(duration, _dropPrevious,
+          leading: leading, trailing: trailing));
 
   /// Returns a Stream which collects values until the source stream does not
   /// emit for [duration] then emits the collected values.
@@ -51,7 +76,8 @@
   /// To keep only the most recent event during the debounce perios see
   /// [debounce].
   Stream<List<T>> debounceBuffer(Duration duration) =>
-      transform(_debounceAggregate(duration, _collectToList));
+      transform(_debounceAggregate(duration, _collectToList,
+          leading: false, trailing: true));
 
   /// Returns a stream which only emits once per [duration], at the beginning of
   /// the period.
@@ -146,25 +172,34 @@
 /// Creates a StreamTransformer which aggregates values until the source stream
 /// does not emit for [duration], then emits the aggregated values.
 StreamTransformer<T, R> _debounceAggregate<T, R>(
-    Duration duration, R collect(T element, R soFar)) {
+    Duration duration, R Function(T element, R soFar) collect,
+    {bool leading, bool trailing}) {
   Timer timer;
   R soFar;
   var shouldClose = false;
+  var emittedLatestAsLeading = false;
   return fromHandlers(handleData: (T value, EventSink<R> sink) {
     timer?.cancel();
-    timer = Timer(duration, () {
+    soFar = collect(value, soFar);
+    if (timer == null && leading) {
+      emittedLatestAsLeading = true;
       sink.add(soFar);
+    } else {
+      emittedLatestAsLeading = false;
+    }
+    timer = Timer(duration, () {
+      if (trailing && !emittedLatestAsLeading) sink.add(soFar);
       if (shouldClose) {
         sink.close();
       }
       soFar = null;
       timer = null;
     });
-    soFar = collect(value, soFar);
   }, handleDone: (EventSink<R> sink) {
-    if (soFar != null) {
+    if (soFar != null && trailing) {
       shouldClose = true;
     } else {
+      timer?.cancel();
       sink.close();
     }
   });
diff --git a/stream_transform/lib/src/scan.dart b/stream_transform/lib/src/scan.dart
index b31b9e7..4e022f5 100644
--- a/stream_transform/lib/src/scan.dart
+++ b/stream_transform/lib/src/scan.dart
@@ -14,7 +14,7 @@
   /// called for elements in order, and the result stream always maintains the
   /// same order as the original.
   Stream<S> scan<S>(
-      S initialValue, FutureOr<S> combine(S previousValue, T element)) {
+      S initialValue, FutureOr<S> Function(S soFar, T element) combine) {
     var accumulated = initialValue;
     return asyncMap((value) {
       var result = combine(accumulated, value);
diff --git a/stream_transform/lib/src/switch.dart b/stream_transform/lib/src/switch.dart
index 2e2aeba..5125d57 100644
--- a/stream_transform/lib/src/switch.dart
+++ b/stream_transform/lib/src/switch.dart
@@ -15,7 +15,7 @@
   ///
   /// If the source stream is a broadcast stream, the result stream will be as
   /// well, regardless of the types of the streams produced by [convert].
-  Stream<S> switchMap<S>(Stream<S> convert(T event)) {
+  Stream<S> switchMap<S>(Stream<S> Function(T) convert) {
     return map(convert).switchLatest();
   }
 }
@@ -41,15 +41,11 @@
         ? StreamController<T>.broadcast(sync: true)
         : StreamController<T>(sync: true);
 
-    StreamSubscription<Stream<T>> outerSubscription;
-
     controller.onListen = () {
-      assert(outerSubscription == null);
-
       StreamSubscription<T> innerSubscription;
       var outerStreamDone = false;
 
-      outerSubscription = outer.listen(
+      final outerSubscription = outer.listen(
           (innerStream) {
             innerSubscription?.cancel();
             innerSubscription = innerStream.listen(controller.add,
@@ -75,15 +71,12 @@
           };
       }
       controller.onCancel = () {
-        var toCancel = <StreamSubscription<void>>[];
-        if (!outerStreamDone) toCancel.add(outerSubscription);
-        if (innerSubscription != null) {
-          toCancel.add(innerSubscription);
-        }
-        outerSubscription = null;
-        innerSubscription = null;
-        if (toCancel.isEmpty) return null;
-        return Future.wait(toCancel.map((s) => s.cancel()));
+        var cancels = [
+          if (!outerStreamDone) outerSubscription.cancel(),
+          if (innerSubscription != null) innerSubscription.cancel(),
+        ].where((f) => f != null);
+        if (cancels.isEmpty) return null;
+        return Future.wait(cancels).then((_) => null);
       };
     };
     return controller.stream;
diff --git a/stream_transform/lib/src/where.dart b/stream_transform/lib/src/where.dart
index 7026923..8917cb4 100644
--- a/stream_transform/lib/src/where.dart
+++ b/stream_transform/lib/src/where.dart
@@ -17,7 +17,7 @@
   /// [S] should be a subtype of the stream's generic type, otherwise nothing of
   /// type [S] could possibly be emitted, however there is no static or runtime
   /// checking that this is the case.
-  Stream<S> whereType<S>() => transform(_WhereType<S>());
+  Stream<S> whereType<S>() => where((e) => e is S).cast<S>();
 
   /// Like [where] but allows the [test] to return a [Future].
   ///
@@ -34,7 +34,7 @@
   ///
   /// The result stream will not close until the source stream closes and all
   /// pending [test] calls have finished.
-  Stream<T> asyncWhere(FutureOr<bool> test(T element)) {
+  Stream<T> asyncWhere(FutureOr<bool> Function(T) test) {
     var valuesWaiting = 0;
     var sourceDone = false;
     return transform(fromHandlers(handleData: (element, sink) {
@@ -54,36 +54,3 @@
     }));
   }
 }
-
-class _WhereType<R> extends StreamTransformerBase<Null, R> {
-  @override
-  Stream<R> bind(Stream<Object> source) {
-    var controller = source.isBroadcast
-        ? StreamController<R>.broadcast(sync: true)
-        : StreamController<R>(sync: true);
-
-    StreamSubscription<Object> subscription;
-    controller.onListen = () {
-      assert(subscription == null);
-      subscription = source.listen(
-          (value) {
-            if (value is R) controller.add(value);
-          },
-          onError: controller.addError,
-          onDone: () {
-            subscription = null;
-            controller.close();
-          });
-      if (!source.isBroadcast) {
-        controller
-          ..onPause = subscription.pause
-          ..onResume = subscription.resume;
-      }
-      controller.onCancel = () {
-        subscription?.cancel();
-        subscription = null;
-      };
-    };
-    return controller.stream;
-  }
-}
diff --git a/stream_transform/pubspec.yaml b/stream_transform/pubspec.yaml
index 9e263e2..c336b81 100644
--- a/stream_transform/pubspec.yaml
+++ b/stream_transform/pubspec.yaml
@@ -1,12 +1,12 @@
 name: stream_transform
 description: A collection of utilities to transform and manipulate streams.
-author: Dart Team <misc@dartlang.org>
 homepage: https://www.github.com/dart-lang/stream_transform
-version: 1.1.0
+version: 1.2.0
 
 environment:
   sdk: ">=2.6.0 <3.0.0"
 
 dev_dependencies:
+  async: ^2.0.0
   pedantic: ^1.5.0
   test: ^1.0.0
diff --git a/sync_http/BUILD.gn b/sync_http/BUILD.gn
index ebe62d4..a0c7317 100644
--- a/sync_http/BUILD.gn
+++ b/sync_http/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for sync_http-0.1.4
+# This file is generated by importer.py for sync_http-0.2.0
 
 import("//build/dart/dart_library.gni")
 
diff --git a/sync_http/CHANGELOG.md b/sync_http/CHANGELOG.md
index 67c7d12..840953a 100644
--- a/sync_http/CHANGELOG.md
+++ b/sync_http/CHANGELOG.md
@@ -1,3 +1,11 @@
+## v0.2.0
+
+* Preparation for [HttpHeaders change]. Update signature of `add()`
+  and `set()` to match new signature of `HttpHeaders`. The
+  parameter is not yet forwarded and will not behave as expected.
+
+  [HttpHeaders change]: https://github.com/dart-lang/sdk/issues/39657
+
 ## v0.1.4
 
 * Fixed issue where query parameters were not being sent as part of requests.
diff --git a/sync_http/codereview.settings b/sync_http/codereview.settings
deleted file mode 100644
index 181f5e6..0000000
--- a/sync_http/codereview.settings
+++ /dev/null
@@ -1,4 +0,0 @@
-# This file is used by gcl to get repository specific information.
-CODE_REVIEW_SERVER: http://codereview.chromium.org
-VIEW_VC: https://github.com/dart-lang/sync_http/commit/
-CC_LIST: reviews@dartlang.org
diff --git a/sync_http/lib/src/sync_http.dart b/sync_http/lib/src/sync_http.dart
index fbc0f10..77464a8 100644
--- a/sync_http/lib/src/sync_http.dart
+++ b/sync_http/lib/src/sync_http.dart
@@ -149,7 +149,7 @@
 
   /// Add [value] to the list of values associated with header [name].
   @override
-  void add(String name, Object value) {
+  void add(String name, Object value, {bool preserveHeaderCase = false}) {
     switch (name) {
       case HttpHeaders.acceptCharsetHeader:
       case HttpHeaders.acceptEncodingHeader:
@@ -222,9 +222,9 @@
 
   /// Replace values associated with key [name] with [value].
   @override
-  void set(String name, Object value) {
+  void set(String name, Object value, {bool preserveHeaderCase = false}) {
     removeAll(name);
-    add(name, value);
+    add(name, value, preserveHeaderCase: preserveHeaderCase);
   }
 
   /// Returns the values associated with key [name], if it exists, otherwise
@@ -449,7 +449,7 @@
   List<String> operator [](String name) => _headers[name];
 
   @override
-  void add(String name, Object value) {
+  void add(String name, Object value, {bool preserveHeaderCase = false}) {
     throw new UnsupportedError('Response headers are immutable');
   }
 
@@ -586,7 +586,7 @@
   }
 
   @override
-  void set(String name, Object value) {
+  void set(String name, Object value, {bool preserveHeaderCase = false}) {
     throw new UnsupportedError('Response headers are immutable');
   }
 
diff --git a/sync_http/pubspec.yaml b/sync_http/pubspec.yaml
index a590f77..52041ff 100644
--- a/sync_http/pubspec.yaml
+++ b/sync_http/pubspec.yaml
@@ -1,5 +1,5 @@
 name: sync_http
-version: 0.1.4
+version: 0.2.0
 author: Dart Team <misc@dartlang.org>
 description: Synchronous HTTP client for Dart.
 homepage: https://github.com/dart-lang/sync_http
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 64a5ad5..bc4297c 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for test-1.9.4
+# This file is generated by importer.py for test-1.14.1
 
 import("//build/dart/dart_library.gni")
 
@@ -14,6 +14,8 @@
   deps = [
     "//third_party/dart-pkg/pub/stack_trace",
     "//third_party/dart-pkg/pub/pedantic",
+    "//third_party/dart-pkg/pub/package_config",
+    "//third_party/dart-pkg/pub/http",
     "//third_party/dart-pkg/pub/shelf_web_socket",
     "//third_party/dart-pkg/pub/typed_data",
     "//third_party/dart-pkg/pub/shelf",
@@ -25,16 +27,17 @@
     "//third_party/dart-pkg/pub/test_api",
     "//third_party/dart-pkg/pub/io",
     "//third_party/dart-pkg/pub/test_core",
-    "//third_party/dart-pkg/pub/path",
+    "//third_party/dart-pkg/pub/coverage",
+    "//third_party/dart-pkg/pub/source_span",
     "//third_party/dart-pkg/pub/stream_channel",
     "//third_party/dart-pkg/pub/js",
+    "//third_party/dart-pkg/pub/webkit_inspection_protocol",
     "//third_party/dart-pkg/pub/pool",
     "//third_party/dart-pkg/pub/shelf_static",
-    "//third_party/dart-pkg/pub/yaml",
-    "//third_party/dart-pkg/pub/source_span",
-    "//third_party/dart-pkg/pub/package_resolver",
     "//third_party/dart-pkg/pub/web_socket_channel",
+    "//third_party/dart-pkg/pub/yaml",
     "//third_party/dart-pkg/pub/boolean_selector",
     "//third_party/dart-pkg/pub/async",
+    "//third_party/dart-pkg/pub/path",
   ]
 }
diff --git a/test/CHANGELOG.md b/test/CHANGELOG.md
index 00a3112..ef24aed 100644
--- a/test/CHANGELOG.md
+++ b/test/CHANGELOG.md
@@ -1,3 +1,49 @@
+## 1.14.1
+
+* Allow the latest shelf_packages_handler.
+
+## 1.14.0
+
+* Drop the `package_resolver` dependency for the `package_config` dependency
+  which is lower level.
+
+## 1.13.0
+
+* Enable asserts in code running through `spawnHybrid` APIs.
+* Exit with a non-zero code if no tests were ran, whether due to skips or having
+  no tests defined.
+* Fix the stack trace labels in SDK code for `dart2js` compiled tests.
+* Cancel any StreamQueue that is created as a part of a stream matcher once it
+  is done matching.
+  * This fixes a bug where using a matcher on a custom stream controller and
+    then awaiting the `close()` method on that controller would hang.
+* Avoid causing the test runner to hang if there is a timeout during a
+  `tearDown` callback following a failing test case.
+
+## 1.12.0
+
+* Bump minimum SDK to `2.4.0` for safer usage of for-loop elements.
+* Deprecate `PhantomJS` and provide warning when used. Support for `PhantomJS`
+  will be removed in version `2.0.0`.
+* Support coverage collection for the Chrome platform. See `README.md` for usage
+  details.
+
+## 1.11.1
+
+* Allow `test_api` `0.2.13` to work around a bug in the SDK version `2.3.0`.
+
+## 1.11.0
+
+* Add `file_reporters` configuration option and `--file-reporter` CLI option to
+  allow specifying a separate reporter that writes to a file instead of stdout.
+
+## 1.10.0
+
+* Add `customHtmlTemplateFile` configuration option to allow sharing an
+  html template between tests
+* Depend on the latest `package:test_core`.
+* Depend on the latest `package:test_api`.
+
 ## 1.9.4
 
 * Extend the timeout for synthetic tests, e.g. `tearDownAll`.
diff --git a/test/README.md b/test/README.md
index 5bd7e1d..63ea8be 100644
--- a/test/README.md
+++ b/test/README.md
@@ -10,6 +10,7 @@
 * [Asynchronous Tests](#asynchronous-tests)
   * [Stream Matchers](#stream-matchers)
 * [Running Tests With Custom HTML](#running-tests-with-custom-html)
+  * [Providing a custom HTML template](#providing-a-custom-html-template)
 * [Configuring Tests](#configuring-tests)
   * [Skipping Tests](#skipping-tests)
   * [Timeouts](#timeouts)
@@ -19,8 +20,8 @@
 * [Debugging](#debugging)
 * [Browser/VM Hybrid Tests](#browservm-hybrid-tests)
 * [Support for Other Packages](#support-for-other-packages)
+  * [`build_runner`](#build_runner)
   * [`term_glyph`](#term_glyph)
-  * [`barback`](#barback)
 * [Further Reading](#further-reading)
 
 ## Writing Tests
@@ -32,17 +33,17 @@
 [`expect()`]: https://pub.dev/documentation/test_api/latest/test_api/expect.html
 
 ```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("String.split() splits the string on the delimiter", () {
-    var string = "foo,bar,baz";
-    expect(string.split(","), equals(["foo", "bar", "baz"]));
+  test('String.split() splits the string on the delimiter', () {
+    var string = 'foo,bar,baz';
+    expect(string.split(','), equals(['foo', 'bar', 'baz']));
   });
 
-  test("String.trim() removes surrounding whitespace", () {
-    var string = "  foo ";
-    expect(string.trim(), equals("foo"));
+  test('String.trim() removes surrounding whitespace', () {
+    var string = '  foo ';
+    expect(string.trim(), equals('foo'));
   });
 }
 ```
@@ -53,28 +54,28 @@
 [`group()`]: https://pub.dev/documentation/test_api/latest/test_api/group.html
 
 ```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  group("String", () {
-    test(".split() splits the string on the delimiter", () {
-      var string = "foo,bar,baz";
-      expect(string.split(","), equals(["foo", "bar", "baz"]));
+  group('String', () {
+    test('.split() splits the string on the delimiter', () {
+      var string = 'foo,bar,baz';
+      expect(string.split(','), equals(['foo', 'bar', 'baz']));
     });
 
-    test(".trim() removes surrounding whitespace", () {
-      var string = "  foo ";
-      expect(string.trim(), equals("foo"));
+    test('.trim() removes surrounding whitespace', () {
+      var string = '  foo ';
+      expect(string.trim(), equals('foo'));
     });
   });
 
-  group("int", () {
-    test(".remainder() returns the remainder of division", () {
+  group('int', () {
+    test('.remainder() returns the remainder of division', () {
       expect(11.remainder(3), equals(2));
     });
 
-    test(".toRadixString() returns a hex string", () {
-      expect(11.toRadixString(16), equals("b"));
+    test('.toRadixString() returns a hex string', () {
+      expect(11.toRadixString(16), equals('b'));
     });
   });
 }
@@ -86,14 +87,14 @@
 [`matcher`]: https://pub.dev/documentation/matcher/latest/matcher/matcher-library.html
 
 ```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test(".split() splits the string on the delimiter", () {
-    expect("foo,bar,baz", allOf([
-      contains("foo"),
-      isNot(startsWith("bar")),
-      endsWith("baz")
+  test('.split() splits the string on the delimiter', () {
+    expect('foo,bar,baz', allOf([
+      contains('foo'),
+      isNot(startsWith('bar')),
+      endsWith('baz')
     ]));
   });
 }
@@ -105,14 +106,14 @@
 fails, to ensure that it has a chance to clean up after itself.
 
 ```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
   HttpServer server;
   Uri url;
   setUp(() async {
     server = await HttpServer.bind('localhost', 0);
-    url = Uri.parse("http://${server.address.host}:${server.port}");
+    url = Uri.parse('http://${server.address.host}:${server.port}');
   });
 
   tearDown(() async {
@@ -170,9 +171,22 @@
 pub run test --total-shards 3 --shard-index 2 path/to/test.dart
 ```
 
+### Shuffling Tests
+Test order can be shuffled with the `--test-randomize-ordering-seed` argument.
+This allows you to shuffle your tests with a specific seed (deterministic) or
+a random seed for each run. For example, consider the following test runs:
+
+```bash
+pub run test --test-randomize-ordering-seed=12345
+pub run test --test-randomize-ordering-seed=random
+```
+
+Setting `--test-randomize-ordering-seed=0` will have the same effect as not
+specifying it at all, meaning the test order will remain as-is.
+
 ### Collecting Code Coverage
 To collect code coverage, you can run tests with the `--coverage <directory>`
-argument. The directory specified can be an absolute or relative path. 
+argument. The directory specified can be an absolute or relative path.
 If a directory does not exist at the path specified, a directory will be
 created. If a directory does exist, files may be overwritten with the latest
 coverage data, if they conflict.
@@ -182,7 +196,8 @@
 The files can then be formatted using the `package:coverage`
 `format_coverage` executable.
 
-Coverage gathering is currently only implemented for tests run in the Dart VM.
+Coverage gathering is currently only implemented for tests run on the Dart VM or
+Chrome.
 
 ### Restricting Tests to Certain Platforms
 
@@ -194,11 +209,11 @@
 `import` declarations:
 
 ```dart
-@TestOn("vm")
+@TestOn('vm')
 
-import "dart:io";
+import 'dart:io';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
   // ...
@@ -273,7 +288,7 @@
   equivalent to `!windows`.
 
 For example, if you wanted to run a test on every browser but Chrome, you would
-write `@TestOn("browser && !chrome")`.
+write `@TestOn('browser && !chrome')`.
 
 ### Running Tests on Node.js
 
@@ -289,7 +304,7 @@
 The test runner looks for an executable named `node` (on Mac OS or Linux) or
 `node.exe` (on Windows) on your system path. When compiling Node.js tests, it
 passes `-Dnode=true`, so tests can determine whether they're running on Node
-using [`const bool.fromEnvironment("node")`][bool.fromEnvironment]. It also sets
+using [`const bool.fromEnvironment('node')`][bool.fromEnvironment]. It also sets
 `--server-mode`, which will tell the compiler that `dart:html` is not available.
 
 [bool.fromEnvironment]: https://api.dart.dev/stable/dart-core/bool/bool.fromEnvironment.html
@@ -303,13 +318,13 @@
 won't consider the test finished until the returned `Future` completes.
 
 ```dart
-import "dart:async";
+import 'dart:async';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("new Future.value() returns the value", () async {
-    var value = await new Future.value(10);
+  test('Future.value() returns the value', () async {
+    var value = await Future.value(10);
     expect(value, equals(10));
   });
 }
@@ -323,13 +338,13 @@
 [`completion()`]: https://pub.dev/documentation/test_api/latest/test_api/completion.html
 
 ```dart
-import "dart:async";
+import 'dart:async';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("new Future.value() returns the value", () {
-    expect(new Future.value(10), completion(equals(10)));
+  test('Future.value() returns the value', () {
+    expect(Future.value(10), completion(equals(10)));
   });
 }
 ```
@@ -341,14 +356,14 @@
 [`throwsA()`]: https://pub.dev/documentation/test_api/latest/test_api/throwsA.html
 
 ```dart
-import "dart:async";
+import 'dart:async';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("new Future.error() throws the error", () {
-    expect(new Future.error("oh no"), throwsA(equals("oh no")));
-    expect(new Future.error(new StateError("bad state")), throwsStateError);
+  test('Future.error() throws the error', () {
+    expect(Future.error('oh no'), throwsA(equals('oh no')));
+    expect(Future.error(StateError('bad state')), throwsStateError);
   });
 }
 ```
@@ -359,13 +374,13 @@
 from finishing until the function is called the requisite number of times.
 
 ```dart
-import "dart:async";
+import 'dart:async';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("Stream.fromIterable() emits the values in the iterable", () {
-    var stream = new Stream.fromIterable([1, 2, 3]);
+  test('Stream.fromIterable() emits the values in the iterable', () {
+    var stream = Stream.fromIterable([1, 2, 3]);
 
     stream.listen(expectAsync1((number) {
       expect(number, inInclusiveRange(1, 3));
@@ -386,29 +401,29 @@
 [Stream]: https://api.dart.dev/stable/dart-async/Stream-class.html
 
 ```dart
-import "dart:async";
+import 'dart:async';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("process emits status messages", () {
+  test('process emits status messages', () {
     // Dummy data to mimic something that might be emitted by a process.
-    var stdoutLines = new Stream.fromIterable([
-      "Ready.",
-      "Loading took 150ms.",
-      "Succeeded!"
+    var stdoutLines = Stream.fromIterable([
+      'Ready.',
+      'Loading took 150ms.',
+      'Succeeded!'
     ]);
 
     expect(stdoutLines, emitsInOrder([
       // Values match individual events.
-      "Ready.",
+      'Ready.',
 
       // Matchers also run against individual events.
-      startsWith("Loading took"),
+      startsWith('Loading took'),
 
       // Stream matchers can be nested. This asserts that one of two events are
       // emitted after the "Loading took" line.
-      emitsAnyOf(["Succeeded!", "Failed!"]),
+      emitsAnyOf(['Succeeded!', 'Failed!']),
 
       // By default, more events are allowed after the matcher finishes
       // matching. This asserts instead that the stream emits a done event and
@@ -429,29 +444,29 @@
 [`StreamQueue`]: https://pub.dev/documentation/async/latest/async/StreamQueue-class.html
 
 ```dart
-import "dart:async";
+import 'dart:async';
 
-import "package:async/async.dart";
-import "package:test/test.dart";
+import 'package:async/async.dart';
+import 'package:test/test.dart';
 
 void main() {
-  test("process emits a WebSocket URL", () async {
+  test('process emits a WebSocket URL', () async {
     // Wrap the Stream in a StreamQueue so that we can request events.
-    var stdout = new StreamQueue(new Stream.fromIterable([
-      "WebSocket URL:",
-      "ws://localhost:1234/",
-      "Waiting for connection..."
+    var stdout = StreamQueue(Stream.fromIterable([
+      'WebSocket URL:',
+      'ws://localhost:1234/',
+      'Waiting for connection...'
     ]));
 
     // Ignore lines from the process until it's about to emit the URL.
-    await expect(stdout, emitsThrough("WebSocket URL:"));
+    await expectLater(stdout, emitsThrough('WebSocket URL:'));
 
     // Parse the next line as a URL.
     var url = Uri.parse(await stdout.next);
     expect(url.host, equals('localhost'));
 
     // You can match against the same StreamQueue multiple times.
-    await expect(stdout, emits("Waiting for connection..."));
+    await expectLater(stdout, emits('Waiting for connection...'));
   });
 }
 ```
@@ -473,8 +488,7 @@
 * [`neverEmits()`] matches a stream that finishes *without* matching an inner
   matcher.
 
-You can also define your own custom stream matchers by calling
-[`new StreamMatcher()`].
+You can also define your own custom stream matchers with [`StreamMatcher()`].
 
 [`emits()`]: https://pub.dev/documentation/test_api/latest/test_api/emits.html
 [`emitsError()`]: https://pub.dev/documentation/test_api/latest/test_api/emitsError.html
@@ -485,7 +499,7 @@
 [`emitsInOrder()`]: https://pub.dev/documentation/test_api/latest/test_api/emitsInOrder.html
 [`emitsInAnyOrder()`]: https://pub.dev/documentation/test_api/latest/test_api/emitsInAnyOrder.html
 [`neverEmits()`]: https://pub.dev/documentation/test_api/latest/test_api/neverEmits.html
-[`new StreamMatcher()`]: https://pub.dev/documentation/test_api/latest/test_api/StreamMatcher-class.html
+[`StreamMatcher()`]: https://pub.dev/documentation/test_api/latest/test_api/StreamMatcher-class.html
 
 ## Running Tests With Custom HTML
 
@@ -493,7 +507,9 @@
 tests. However, tests that need custom HTML can create their own files. These
 files have three requirements:
 
-* They must have the same name as the test, with `.dart` replaced by `.html`.
+* They must have the same name as the test, with `.dart` replaced by `.html`. You can also
+  provide a configuration path to an html file if you want it to be reused across all tests.
+  See [Providing a custom HTML template](#providing-a-custom-html-template) below.
 
 * They must contain a `link` tag with `rel="x-dart-test"` and an `href`
   attribute pointing to the test script.
@@ -518,6 +534,40 @@
 </html>
 ```
 
+### Providing a custom HTML template
+
+If you want to share the same HTML file across all tests, you can provide a
+`custom-html-template-path` configuration option to your configuration file.
+This file should follow the rules above, except that instead of the link tag
+add exactly one `{{testScript}}` in the place where you want the template processor to insert it.
+
+You can also optionally use any number of `{{testName}}` placeholders which will be replaced by the test filename.
+
+The template can't be named like any test file, as that would clash with using the
+custom HTML mechanics. In such a case, an error will be thrown.
+
+For example:
+
+```yaml
+custom-html-template-path: html_template.html.tpl
+```
+
+```html
+<!doctype html>
+<!-- html_template.html.tpl -->
+<html>
+  <head>
+    <title>{{testName}} Test</title>
+    {{testScript}}
+    <script src="packages/test/dart.js"></script>
+  </head>
+  <body>
+    // ...
+  </body>
+</html>
+```
+
+
 ## Configuring Tests
 
 ### Skipping Tests
@@ -534,9 +584,9 @@
 To skip a test suite, put a `@Skip` annotation at the top of the file:
 
 ```dart
-@Skip("currently failing (see issue 1234)")
+@Skip('currently failing (see issue 1234)')
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
   // ...
@@ -550,16 +600,16 @@
 can be either `true` or a String describing why the test is skipped. For example:
 
 ```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  group("complicated algorithm tests", () {
+  group('complicated algorithm tests', () {
     // ...
   }, skip: "the algorithm isn't quite right");
 
-  test("error-checking test", () {
+  test('error-checking test', () {
     // ...
-  }, skip: "TODO: add error-checking.");
+  }, skip: 'TODO: add error-checking.');
 }
 ```
 
@@ -572,7 +622,7 @@
 ```dart
 @Timeout(const Duration(seconds: 45))
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
   // ...
@@ -587,16 +637,16 @@
 parameter takes a `Timeout` object just like the annotation. For example:
 
 ```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  group("slow tests", () {
+  group('slow tests', () {
     // ...
 
-    test("even slower test", () {
+    test('even slower test', () {
       // ...
-    }, timeout: new Timeout.factor(2))
-  }, timeout: new Timeout(new Duration(minutes: 1)));
+    }, timeout: Timeout.factor(2))
+  }, timeout: Timeout(Duration(minutes: 1)));
 }
 ```
 
@@ -615,16 +665,16 @@
 ```dart
 @OnPlatform(const {
   // Give Windows some extra wiggle-room before timing out.
-  "windows": const Timeout.factor(2)
+  'windows': const Timeout.factor(2)
 })
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("do a thing", () {
+  test('do a thing', () {
     // ...
   }, onPlatform: {
-    "safari": new Skip("Safari is currently broken (see #1234)")
+    'safari': Skip('Safari is currently broken (see #1234)')
   });
 }
 ```
@@ -655,18 +705,18 @@
 parameter to `test()` and `group()`. For example:
 
 ```dart
-@Tags(const ["browser"])
+@Tags(const ['browser'])
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("successfully launches Chrome", () {
+  test('successfully launches Chrome', () {
     // ...
-  }, tags: "chrome");
+  }, tags: 'chrome');
 
-  test("launches two browsers at once", () {
+  test('launches two browsers at once', () {
     // ...
-  }, tags: ["chrome", "firefox"]);
+  }, tags: ['chrome', 'firefox']);
 }
 ```
 
@@ -716,7 +766,7 @@
 
 Tests can be debugged interactively using platforms' built-in development tools.
 Tests running on browsers can use those browsers' development consoles to inspect
-the document, set breakpoints, and step through code. Those running on the Dart 
+the document, set breakpoints, and step through code. Those running on the Dart
 VM use [the Dart Observatory][observatory]'s .
 
 [observatory]: https://dart-lang.github.io/observatory/
@@ -763,9 +813,9 @@
 
 // The library loaded by spawnHybridUri() can import any packages that your
 // package depends on, including those that only work on the VM.
-import "package:shelf/shelf_io.dart" as io;
-import "package:shelf_web_socket/shelf_web_socket.dart";
-import "package:stream_channel/stream_channel.dart";
+import 'package:shelf/shelf_io.dart' as io;
+import 'package:shelf_web_socket/shelf_web_socket.dart';
+import 'package:stream_channel/stream_channel.dart';
 
 // Once the hybrid isolate starts, it will call the special function
 // hybridMain() with a StreamChannel that's connected to the channel
@@ -773,7 +823,7 @@
 hybridMain(StreamChannel channel) async {
   // Start a WebSocket server that just sends "hello!" to its clients.
   var server = await io.serve(webSocketHandler((webSocket) {
-    webSocket.sink.add("hello!");
+    webSocket.sink.add('hello!');
   }), 'localhost', 0);
 
   // Send the port number of the WebSocket server to the browser test, so
@@ -784,24 +834,24 @@
 
 // ## test/web_socket_test.dart
 
-@TestOn("browser")
+@TestOn('browser')
 
-import "dart:html";
+import 'dart:html';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 void main() {
-  test("connects to a server-side WebSocket", () async {
+  test('connects to a server-side WebSocket', () async {
     // Each spawnHybrid function returns a StreamChannel that communicates with
     // the hybrid isolate. You can close this channel to kill the isolate.
-    var channel = spawnHybridUri("web_socket_server.dart");
+    var channel = spawnHybridUri('web_socket_server.dart');
 
     // Get the port for the WebSocket server from the hybrid isolate.
     var port = await channel.stream.first;
 
-    var socket = new WebSocket('ws://localhost:$port');
+    var socket = WebSocket('ws://localhost:$port');
     var message = await socket.onMessage.first;
-    expect(message.data, equals("hello!"));
+    expect(message.data, equals('hello!'));
   });
 }
 ```
diff --git a/test/doc/configuration.md b/test/doc/configuration.md
index 25514de..7a7cabb 100644
--- a/test/doc/configuration.md
+++ b/test/doc/configuration.md
@@ -47,6 +47,7 @@
   * [`pub_serve`](#pub_serve)
   * [`reporter`](#reporter)
   * [`fold_stack_frames`](#fold_stack_frames)
+  * [`custom_html_template_path`](#custom_html_template_path)
 * [Configuring Tags](#configuring-tags)
   * [`tags`](#tags)
   * [`add_tags`](#add_tags)
@@ -435,6 +436,19 @@
 This field is not supported in the
 [global configuration file](#global-configuration).
 
+### `file_reporters`
+
+This field specifies additional reporters to use that will write their output to
+a file rather than stdout. It should be a map of reporter names to filepaths.
+
+```yaml
+file_reporters:
+  json: reports/tests.json
+```
+
+This field is not supported in the
+[global configuration file](#global-configuration).
+
 ### `fold_stack_frames`
 
 This field controls which packages' stack frames will be folded away
@@ -463,6 +477,11 @@
 test/sample_test.dart 5:27  main.<fn>
 ```
 
+### `custom_html_template_path`
+
+This field specifies the path of the HTML template file to be used for tests run in an HTML environment.
+Any HTML file that is named the same as the test and in the same directory will take precedence over the template.
+For more information about the usage of this option see [Providing a custom HTML template](https://github.com/dart-lang/test/blob/master/README.md#providing-a-custom-html-template)
 
 ## Configuring Tags
 
diff --git a/test/doc/json_reporter.md b/test/doc/json_reporter.md
index 669eebe..50348e7 100644
--- a/test/doc/json_reporter.md
+++ b/test/doc/json_reporter.md
@@ -19,6 +19,11 @@
 
     pub run test --reporter json <path-to-test-file>
 
+You may also use the `--file-reporter` option to enable the JSON reporter such
+that it writes to a file instead of stdout.
+
+    pub run test --file-reporter json:reports/tests.json <path-to-test-file>
+
 The JSON stream will be emitted via standard output. It will be a stream of JSON
 objects, separated by newlines.
 
diff --git a/test/doc/package_config.md b/test/doc/package_config.md
index 25514de..7a7cabb 100644
--- a/test/doc/package_config.md
+++ b/test/doc/package_config.md
@@ -47,6 +47,7 @@
   * [`pub_serve`](#pub_serve)
   * [`reporter`](#reporter)
   * [`fold_stack_frames`](#fold_stack_frames)
+  * [`custom_html_template_path`](#custom_html_template_path)
 * [Configuring Tags](#configuring-tags)
   * [`tags`](#tags)
   * [`add_tags`](#add_tags)
@@ -435,6 +436,19 @@
 This field is not supported in the
 [global configuration file](#global-configuration).
 
+### `file_reporters`
+
+This field specifies additional reporters to use that will write their output to
+a file rather than stdout. It should be a map of reporter names to filepaths.
+
+```yaml
+file_reporters:
+  json: reports/tests.json
+```
+
+This field is not supported in the
+[global configuration file](#global-configuration).
+
 ### `fold_stack_frames`
 
 This field controls which packages' stack frames will be folded away
@@ -463,6 +477,11 @@
 test/sample_test.dart 5:27  main.<fn>
 ```
 
+### `custom_html_template_path`
+
+This field specifies the path of the HTML template file to be used for tests run in an HTML environment.
+Any HTML file that is named the same as the test and in the same directory will take precedence over the template.
+For more information about the usage of this option see [Providing a custom HTML template](https://github.com/dart-lang/test/blob/master/README.md#providing-a-custom-html-template)
 
 ## Configuring Tags
 
diff --git a/test/lib/src/bootstrap/browser.dart b/test/lib/src/bootstrap/browser.dart
index 2a7e730..171840e 100644
--- a/test/lib/src/bootstrap/browser.dart
+++ b/test/lib/src/bootstrap/browser.dart
@@ -8,11 +8,11 @@
 import '../runner/browser/post_message_channel.dart';
 
 /// Bootstraps a browser test to communicate with the test runner.
-void internalBootstrapBrowserTest(Function getMain()) {
+void internalBootstrapBrowserTest(Function Function() getMain) {
   var channel =
       serializeSuite(getMain, hidePrints: false, beforeLoad: () async {
     var serialized =
-        await suiteChannel("test.browser.mapper").stream.first as Map;
+        await suiteChannel('test.browser.mapper').stream.first as Map;
     if (serialized == null) return;
     setStackTraceMapper(JSStackTraceMapper.deserialize(serialized));
   });
diff --git a/test/lib/src/bootstrap/node.dart b/test/lib/src/bootstrap/node.dart
index e1fe100..ca002ba 100644
--- a/test/lib/src/bootstrap/node.dart
+++ b/test/lib/src/bootstrap/node.dart
@@ -8,9 +8,9 @@
 import 'package:test_core/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports
 
 /// Bootstraps a browser test to communicate with the test runner.
-void internalBootstrapNodeTest(Function getMain()) {
+void internalBootstrapNodeTest(Function Function() getMain) {
   var channel = serializeSuite(getMain, beforeLoad: () async {
-    var serialized = await suiteChannel("test.node.mapper").stream.first;
+    var serialized = await suiteChannel('test.node.mapper').stream.first;
     if (serialized == null || serialized is! Map) return;
     setStackTraceMapper(JSStackTraceMapper.deserialize(serialized as Map));
   });
diff --git a/test/lib/src/executable.dart b/test/lib/src/executable.dart
index e8313f8..75b2d58 100644
--- a/test/lib/src/executable.dart
+++ b/test/lib/src/executable.dart
@@ -9,7 +9,7 @@
 import 'runner/node/platform.dart';
 import 'runner/browser/platform.dart';
 
-main(List<String> args) async {
+void main(List<String> args) async {
   registerPlatformPlugin([Runtime.nodeJS], () => NodePlatform());
   registerPlatformPlugin([
     Runtime.chrome,
diff --git a/test/lib/src/runner/browser/browser.dart b/test/lib/src/runner/browser/browser.dart
index db7e7ec..fa816db 100644
--- a/test/lib/src/runner/browser/browser.dart
+++ b/test/lib/src/runner/browser/browser.dart
@@ -6,7 +6,6 @@
 import 'dart:convert';
 import 'dart:io';
 
-import 'package:pedantic/pedantic.dart';
 import 'package:stack_trace/stack_trace.dart';
 import 'package:typed_data/typed_data.dart';
 
@@ -61,7 +60,7 @@
   /// which asynchronously returns the browser process. Any errors in
   /// [startBrowser] (even those raised asynchronously after it returns) are
   /// piped to [onExit] and will cause the browser to be killed.
-  Browser(Future<Process> startBrowser()) {
+  Browser(Future<Process> Function() startBrowser) {
     // Don't return a Future here because there's no need for the caller to wait
     // for the process to actually start. They should just wait for the HTTP
     // request instead.
@@ -70,7 +69,7 @@
       _processCompleter.complete(process);
 
       var output = Uint8Buffer();
-      drainOutput(Stream<List<int>> stream) {
+      void drainOutput(Stream<List<int>> stream) {
         try {
           _ioSubscriptions
               .add(stream.listen(output.addAll, cancelOnError: true));
@@ -99,9 +98,9 @@
 
       if (!_closed && exitCode != 0) {
         var outputString = utf8.decode(output);
-        var message = "$name failed with exit code $exitCode.";
+        var message = '$name failed with exit code $exitCode.';
         if (outputString.isNotEmpty) {
-          message += "\nStandard output:\n$outputString";
+          message += '\nStandard output:\n$outputString';
         }
 
         throw ApplicationException(message);
@@ -115,11 +114,11 @@
       // Make sure the process dies even if the error wasn't fatal.
       _process.then((process) => process.kill());
 
-      if (stackTrace == null) stackTrace = Trace.current();
+      stackTrace ??= Trace.current();
       if (_onExitCompleter.isCompleted) return;
       _onExitCompleter.completeError(
           ApplicationException(
-              "Failed to run $name: ${getErrorMessage(error)}."),
+              'Failed to run $name: ${getErrorMessage(error)}.'),
           stackTrace);
     });
   }
diff --git a/test/lib/src/runner/browser/browser_manager.dart b/test/lib/src/runner/browser/browser_manager.dart
index 91ed9e6..2339908 100644
--- a/test/lib/src/runner/browser/browser_manager.dart
+++ b/test/lib/src/runner/browser/browser_manager.dart
@@ -8,17 +8,15 @@
 import 'package:async/async.dart';
 import 'package:pool/pool.dart';
 import 'package:stream_channel/stream_channel.dart';
-import 'package:web_socket_channel/web_socket_channel.dart';
-
 import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
 import 'package:test_api/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/environment.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
-
 import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/environment.dart'; // ignore: implementation_imports
 import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
 import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
+import 'package:web_socket_channel/web_socket_channel.dart';
 
 import '../executable_settings.dart';
 import 'browser.dart';
@@ -80,7 +78,7 @@
   ///
   /// These are used to mark suites as debugging or not based on the browser's
   /// pings.
-  final _controllers = Set<RunnerSuiteController>();
+  final _controllers = <RunnerSuiteController>{};
 
   // A timer that's reset whenever we receive a message from the browser.
   //
@@ -109,7 +107,7 @@
     // TODO(nweiz): Gracefully handle the browser being killed before the
     // tests complete.
     browser.onExit.then((_) {
-      throw ApplicationException("${runtime.name} exited before connecting.");
+      throw ApplicationException('${runtime.name} exited before connecting.');
     }).catchError((error, StackTrace stackTrace) {
       if (completer.isCompleted) return;
       completer.completeError(error, stackTrace);
@@ -127,7 +125,7 @@
     return completer.future.timeout(Duration(seconds: 30), onTimeout: () {
       browser.close();
       throw ApplicationException(
-          "Timed out waiting for ${runtime.name} to connect.");
+          'Timed out waiting for ${runtime.name} to connect.');
     });
   }
 
@@ -149,7 +147,7 @@
       case Runtime.internetExplorer:
         return InternetExplorer(url, settings: settings);
       default:
-        throw ArgumentError("$browser is not a browser.");
+        throw ArgumentError('$browser is not a browser.');
     }
   }
 
@@ -207,16 +205,16 @@
       {StackTraceMapper mapper}) async {
     url = url.replace(
         fragment: Uri.encodeFull(jsonEncode({
-      "metadata": suiteConfig.metadata.serialize(),
-      "browser": _runtime.identifier
+      'metadata': suiteConfig.metadata.serialize(),
+      'browser': _runtime.identifier
     })));
 
     var suiteID = _suiteID++;
     RunnerSuiteController controller;
-    closeIframe() {
+    void closeIframe() {
       if (_closed) return;
       _controllers.remove(controller);
-      _channel.sink.add({"command": "closeSuite", "id": suiteID});
+      _channel.sink.add({'command': 'closeSuite', 'id': suiteID});
     }
 
     // The virtual channel will be closed when the suite is closed, in which
@@ -231,17 +229,26 @@
 
     return await _pool.withResource<RunnerSuite>(() async {
       _channel.sink.add({
-        "command": "loadSuite",
-        "url": url.toString(),
-        "id": suiteID,
-        "channel": suiteChannelID
+        'command': 'loadSuite',
+        'url': url.toString(),
+        'id': suiteID,
+        'channel': suiteChannelID
       });
 
       try {
-        controller = deserializeSuite(path, currentPlatform(_runtime),
-            suiteConfig, await _environment, suiteChannel, message);
+        controller = deserializeSuite(
+            path,
+            currentPlatform(_runtime),
+            suiteConfig,
+            await _environment,
+            suiteChannel,
+            message, gatherCoverage: () async {
+          var browser = _browser;
+          if (browser is Chrome) return browser.gatherCoverage();
+          return {};
+        });
 
-        controller.channel("test.browser.mapper").sink.add(mapper?.serialize());
+        controller.channel('test.browser.mapper').sink.add(mapper?.serialize());
 
         _controllers.add(controller);
         return await controller.suite;
@@ -257,7 +264,7 @@
     if (_pauseCompleter != null) return _pauseCompleter.operation;
 
     _pauseCompleter = CancelableCompleter(onCancel: () {
-      _channel.sink.add({"command": "resume"});
+      _channel.sink.add({'command': 'resume'});
       _pauseCompleter = null;
     });
 
@@ -265,22 +272,22 @@
       _pauseCompleter = null;
     });
 
-    _channel.sink.add({"command": "displayPause"});
+    _channel.sink.add({'command': 'displayPause'});
 
     return _pauseCompleter.operation;
   }
 
   /// The callback for handling messages received from the host page.
   void _onMessage(Map message) {
-    switch (message["command"] as String) {
-      case "ping":
+    switch (message['command'] as String) {
+      case 'ping':
         break;
 
-      case "restart":
+      case 'restart':
         _onRestartController.add(null);
         break;
 
-      case "resume":
+      case 'resume':
         if (_pauseCompleter != null) _pauseCompleter.complete();
         break;
 
@@ -310,16 +317,21 @@
 class _BrowserEnvironment implements Environment {
   final BrowserManager _manager;
 
+  @override
   final supportsDebugging = true;
 
+  @override
   final Uri observatoryUrl;
 
+  @override
   final Uri remoteDebuggerUrl;
 
+  @override
   final Stream onRestart;
 
   _BrowserEnvironment(this._manager, this.observatoryUrl,
       this.remoteDebuggerUrl, this.onRestart);
 
+  @override
   CancelableOperation displayPause() => _manager._displayPause();
 }
diff --git a/test/lib/src/runner/browser/chrome.dart b/test/lib/src/runner/browser/chrome.dart
index 81c5861..fbecad2 100644
--- a/test/lib/src/runner/browser/chrome.dart
+++ b/test/lib/src/runner/browser/chrome.dart
@@ -3,17 +3,21 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 
+import 'package:coverage/coverage.dart';
+import 'package:http/http.dart' as http;
+import 'package:path/path.dart' as p;
 import 'package:pedantic/pedantic.dart';
 import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
 import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
+import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
 
 import '../executable_settings.dart';
 import 'browser.dart';
 import 'default_settings.dart';
 
-// TODO(nweiz): move this into its own package?
 /// A class for running an instance of Chrome.
 ///
 /// Most of the communication with the browser is expected to happen via HTTP,
@@ -22,38 +26,45 @@
 ///
 /// Any errors starting or running the process are reported through [onExit].
 class Chrome extends Browser {
-  final name = "Chrome";
+  @override
+  final name = 'Chrome';
 
+  @override
   final Future<Uri> remoteDebuggerUrl;
 
+  final Future<WipConnection> _tabConnection;
+  final Map<String, String> _idToUrl;
+
   /// Starts a new instance of Chrome open to the given [url], which may be a
   /// [Uri] or a [String].
   factory Chrome(Uri url, {ExecutableSettings settings, bool debug = false}) {
     settings ??= defaultSettings[Runtime.chrome];
     var remoteDebuggerCompleter = Completer<Uri>.sync();
+    var connectionCompleter = Completer<WipConnection>();
+    var idToUrl = <String, String>{};
     return Chrome._(() async {
       var tryPort = ([int port]) async {
         var dir = createTempDir();
         var args = [
-          "--user-data-dir=$dir",
+          '--user-data-dir=$dir',
           url.toString(),
-          "--disable-extensions",
-          "--disable-popup-blocking",
-          "--bwsi",
-          "--no-first-run",
-          "--no-default-browser-check",
-          "--disable-default-apps",
-          "--disable-translate",
-          "--disable-dev-shm-usage",
+          '--disable-extensions',
+          '--disable-popup-blocking',
+          '--bwsi',
+          '--no-first-run',
+          '--no-default-browser-check',
+          '--disable-default-apps',
+          '--disable-translate',
+          '--disable-dev-shm-usage',
         ];
 
         if (!debug && settings.headless) {
           args.addAll([
-            "--headless",
-            "--disable-gpu",
+            '--headless',
+            '--disable-gpu',
             // We don't actually connect to the remote debugger, but Chrome will
             // close as soon as the page is loaded if we don't turn it on.
-            "--remote-debugging-port=0"
+            '--remote-debugging-port=0'
           ]);
         }
 
@@ -64,13 +75,15 @@
         // but without a reliable and fast way to tell if it succeeded that
         // doesn't provide us much. It's very unlikely that this port will fail,
         // though.
-        if (port != null) args.add("--remote-debugging-port=$port");
+        if (port != null) args.add('--remote-debugging-port=$port');
 
         var process = await Process.start(settings.executable, args);
 
         if (port != null) {
           remoteDebuggerCompleter.complete(
-              getRemoteDebuggerUrl(Uri.parse("http://localhost:$port")));
+              getRemoteDebuggerUrl(Uri.parse('http://localhost:$port')));
+
+          connectionCompleter.complete(_connect(process, port, idToUrl, url));
         } else {
           remoteDebuggerCompleter.complete(null);
         }
@@ -83,9 +96,96 @@
 
       if (!debug) return tryPort();
       return getUnusedPort<Process>(tryPort);
-    }, remoteDebuggerCompleter.future);
+    }, remoteDebuggerCompleter.future, connectionCompleter.future, idToUrl);
   }
 
-  Chrome._(Future<Process> startBrowser(), this.remoteDebuggerUrl)
+  /// Returns a Dart based hit-map containing coverage report, suitable for use
+  /// with `package:coverage`.
+  Future<Map<String, dynamic>> gatherCoverage() async {
+    var tabConnection = await _tabConnection;
+    var response = await tabConnection.debugger.connection
+        .sendCommand('Profiler.takePreciseCoverage', {});
+    var result = response.result['result'];
+    var coverage = await parseChromeCoverage(
+      (result as List).cast(),
+      _sourceProvider,
+      _sourceMapProvider,
+      _sourceUriProvider,
+    );
+    return coverage;
+  }
+
+  Chrome._(Future<Process> Function() startBrowser, this.remoteDebuggerUrl,
+      this._tabConnection, this._idToUrl)
       : super(startBrowser);
+
+  Future<Uri> _sourceUriProvider(String sourceUrl, String scriptId) async {
+    var script = _idToUrl[scriptId];
+    if (script == null) return null;
+    var uri = Uri.parse(script);
+    var path = p.join(
+        p.joinAll(uri.pathSegments.sublist(1, uri.pathSegments.length - 1)),
+        sourceUrl);
+    return path.contains('/packages/')
+        ? Uri(scheme: 'package', path: path.split('/packages/').last)
+        : Uri.file(p.absolute(path));
+  }
+
+  Future<String> _sourceMapProvider(String scriptId) async {
+    var script = _idToUrl[scriptId];
+    if (script == null) return null;
+    var mapResponse = await http.get('$script.map');
+    if (mapResponse.statusCode != HttpStatus.ok) return null;
+    return mapResponse.body;
+  }
+
+  Future<String> _sourceProvider(String scriptId) async {
+    var script = _idToUrl[scriptId];
+    if (script == null) return null;
+    var scriptResponse = await http.get(script);
+    if (scriptResponse.statusCode != HttpStatus.ok) return null;
+    return scriptResponse.body;
+  }
+}
+
+Future<WipConnection> _connect(
+    Process process, int port, Map<String, String> idToUrl, Uri url) async {
+  // Wait for Chrome to be in a ready state.
+  await process.stderr
+      .transform(utf8.decoder)
+      .transform(LineSplitter())
+      .firstWhere((line) => line.startsWith('DevTools listening'));
+
+  var chromeConnection = ChromeConnection('localhost', port);
+  ChromeTab tab;
+  var attempt = 0;
+  while (tab == null) {
+    attempt++;
+    var tabs = await chromeConnection.getTabs();
+    tab =
+        tabs.firstWhere((tab) => tab.url == url.toString(), orElse: () => null);
+    if (tab == null) {
+      await Future.delayed(Duration(milliseconds: 100));
+      if (attempt > 5) {
+        throw StateError('Could not connect to test tab with url: $url');
+      }
+    }
+  }
+  var tabConnection = await tab.connect();
+
+  // Enable debugging.
+  await tabConnection.debugger.enable();
+
+  // Coverage reports are in terms of scriptIds so keep note of URLs.
+  tabConnection.debugger.onScriptParsed.listen((data) {
+    var script = data.script;
+    if (script.url.isNotEmpty) idToUrl[script.scriptId] = script.url;
+  });
+
+  // Enable coverage collection.
+  await tabConnection.debugger.connection.sendCommand('Profiler.enable', {});
+  await tabConnection.debugger.connection.sendCommand(
+      'Profiler.startPreciseCoverage', {'detailed': true, 'callCount': false});
+
+  return tabConnection;
 }
diff --git a/test/lib/src/runner/browser/firefox.dart b/test/lib/src/runner/browser/firefox.dart
index aa51a88..cf0efe6 100644
--- a/test/lib/src/runner/browser/firefox.dart
+++ b/test/lib/src/runner/browser/firefox.dart
@@ -7,7 +7,6 @@
 
 import 'package:path/path.dart' as p;
 import 'package:pedantic/pedantic.dart';
-
 import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
 import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
 
@@ -29,7 +28,8 @@
 ///
 /// Any errors starting or running the process are reported through [onExit].
 class Firefox extends Browser {
-  final name = "Firefox";
+  @override
+  final name = 'Firefox';
 
   Firefox(url, {ExecutableSettings settings})
       : super(() => _startBrowser(url, settings));
@@ -41,11 +41,15 @@
     var dir = createTempDir();
     File(p.join(dir, 'prefs.js')).writeAsStringSync(_preferences);
 
-    var process = await Process.start(
-        settings.executable,
-        ["--profile", "$dir", url.toString(), "--no-remote"]
-          ..addAll(settings.arguments),
-        environment: {"MOZ_CRASHREPORTER_DISABLE": "1"});
+    var process = await Process.start(settings.executable, [
+      '--profile',
+      '$dir',
+      url.toString(),
+      '--no-remote',
+      ...settings.arguments,
+    ], environment: {
+      'MOZ_CRASHREPORTER_DISABLE': '1'
+    });
 
     unawaited(process.exitCode
         .then((_) => Directory(dir).deleteSync(recursive: true)));
diff --git a/test/lib/src/runner/browser/internet_explorer.dart b/test/lib/src/runner/browser/internet_explorer.dart
index 4ddba9e..d79c9e4 100644
--- a/test/lib/src/runner/browser/internet_explorer.dart
+++ b/test/lib/src/runner/browser/internet_explorer.dart
@@ -14,7 +14,8 @@
 ///
 /// Any errors starting or running the process are reported through [onExit].
 class InternetExplorer extends Browser {
-  final name = "Internet Explorer";
+  @override
+  final name = 'Internet Explorer';
 
   InternetExplorer(url, {ExecutableSettings settings})
       : super(() => _startBrowser(url, settings));
@@ -24,7 +25,10 @@
   static Future<Process> _startBrowser(url, ExecutableSettings settings) {
     settings ??= defaultSettings[Runtime.internetExplorer];
 
-    return Process.start(settings.executable,
-        ['-extoff', url.toString()]..addAll(settings.arguments));
+    return Process.start(settings.executable, [
+      '-extoff',
+      '$url',
+      ...settings.arguments,
+    ]);
   }
 }
diff --git a/test/lib/src/runner/browser/phantom_js.dart b/test/lib/src/runner/browser/phantom_js.dart
index 75e1d48..d2adbcd 100644
--- a/test/lib/src/runner/browser/phantom_js.dart
+++ b/test/lib/src/runner/browser/phantom_js.dart
@@ -7,12 +7,10 @@
 
 import 'package:path/path.dart' as p;
 import 'package:pedantic/pedantic.dart';
-
 import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
-
+import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
 import 'package:test_core/src/util/exit_codes.dart' // ignore: implementation_imports
     as exit_codes;
-import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
 import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
 
 import '../executable_settings.dart';
@@ -20,7 +18,7 @@
 import 'default_settings.dart';
 
 /// The PhantomJS script that opens the host page.
-final _script = """
+final _script = '''
 var system = require('system');
 var page = require('webpage').create();
 
@@ -36,14 +34,16 @@
 page.open(system.args[1], function(status) {
   if (status !== "success") phantom.exit(1);
 });
-""";
+''';
 
 /// A class for running an instance of PhantomJS.
 ///
 /// Any errors starting or running the process are reported through [onExit].
 class PhantomJS extends Browser {
-  final name = "PhantomJS";
+  @override
+  final name = 'PhantomJS';
 
+  @override
   final Future<Uri> remoteDebuggerUrl;
 
   factory PhantomJS(url, {ExecutableSettings settings, bool debug = false}) {
@@ -51,7 +51,7 @@
     var remoteDebuggerCompleter = Completer<Uri>.sync();
     return PhantomJS._(() async {
       var dir = createTempDir();
-      var script = p.join(dir, "script.js");
+      var script = p.join(dir, 'script.js');
       File(script).writeAsStringSync(_script);
 
       var port = debug ? await getUnsafeUnusedPort() : null;
@@ -59,7 +59,7 @@
       var args = settings.arguments.toList();
       if (debug) {
         args.addAll(
-            ["--remote-debugger-port=$port", "--remote-debugger-autorun=yes"]);
+            ['--remote-debugger-port=$port', '--remote-debugger-autorun=yes']);
       }
       args.addAll([script, url.toString()]);
       var process = await Process.start(settings.executable, args);
@@ -73,13 +73,13 @@
 
         if (exitCode == exit_codes.protocol) {
           throw ApplicationException(
-              "Only PhantomJS version 2.0.0 or greater is supported");
+              'Only PhantomJS version 2.0.0 or greater is supported');
         }
       }));
 
       if (port != null) {
         remoteDebuggerCompleter.complete(Uri.parse(
-            "http://localhost:$port/webkit/inspector/inspector.html?page=2"));
+            'http://localhost:$port/webkit/inspector/inspector.html?page=2'));
       } else {
         remoteDebuggerCompleter.complete(null);
       }
@@ -88,6 +88,6 @@
     }, remoteDebuggerCompleter.future);
   }
 
-  PhantomJS._(Future<Process> startBrowser(), this.remoteDebuggerUrl)
+  PhantomJS._(Future<Process> Function() startBrowser, this.remoteDebuggerUrl)
       : super(startBrowser);
 }
diff --git a/test/lib/src/runner/browser/platform.dart b/test/lib/src/runner/browser/platform.dart
index 1b67088..75c8eb0 100644
--- a/test/lib/src/runner/browser/platform.dart
+++ b/test/lib/src/runner/browser/platform.dart
@@ -9,7 +9,6 @@
 
 import 'package:async/async.dart';
 import 'package:http_multi_server/http_multi_server.dart';
-import 'package:package_resolver/package_resolver.dart';
 import 'package:path/path.dart' as p;
 import 'package:pool/pool.dart';
 import 'package:shelf/shelf.dart' as shelf;
@@ -37,6 +36,7 @@
 import 'package:test_core/src/runner/plugin/customizable_platform.dart'; // ignore: implementation_imports
 
 import '../executable_settings.dart';
+import '../../util/package_map.dart';
 import '../../util/path_handler.dart';
 import '../../util/one_off_handler.dart';
 import 'browser_manager.dart';
@@ -55,6 +55,8 @@
         Configuration.current,
         p.fromUri(await Isolate.resolvePackageUri(
             Uri.parse('package:test/src/runner/browser/static/favicon.ico'))),
+        p.fromUri(await Isolate.resolvePackageUri(Uri.parse(
+            'package:test/src/runner/browser/static/default.html.tpl'))),
         root: root);
   }
 
@@ -71,7 +73,7 @@
   final _secret = Uri.encodeComponent(randomBase64(24));
 
   /// The URL for this server.
-  Uri get url => _server.url.resolve(_secret + "/");
+  Uri get url => _server.url.resolve(_secret + '/');
 
   /// A [OneOffHandler] for servicing WebSocket connections for
   /// [BrowserManager]s.
@@ -121,15 +123,19 @@
   ///
   /// This is used to make sure that a given test suite is only compiled once
   /// per run, rather than once per browser per run.
-  final _compileFutures = Map<String, Future>();
+  final _compileFutures = <String, Future>{};
 
   /// Mappers for Dartifying stack traces, indexed by test path.
-  final _mappers = Map<String, StackTraceMapper>();
+  final _mappers = <String, StackTraceMapper>{};
+
+  /// The default template for html tests.
+  final String _defaultTemplatePath;
 
   BrowserPlatform._(this._server, Configuration config, String faviconPath,
+      this._defaultTemplatePath,
       {String root})
       : _config = config,
-        _root = root == null ? p.current : root,
+        _root = root ?? p.current,
         _compiledDir = config.pubServeUrl == null ? createTempDir() : null,
         _http = config.pubServeUrl == null ? null : HttpClient() {
     var cascade = shelf.Cascade().add(_webSocketHandler.handler);
@@ -160,7 +166,7 @@
   shelf.Response _wrapperHandler(shelf.Request request) {
     var path = p.fromUri(request.url);
 
-    if (path.endsWith(".browser_test.dart")) {
+    if (path.endsWith('.browser_test.dart')) {
       var testPath = p.basename(p.withoutExtension(p.withoutExtension(path)));
       return shelf.Response.ok('''
         import "package:stream_channel/stream_channel.dart";
@@ -177,36 +183,34 @@
       ''', headers: {'Content-Type': 'application/dart'});
     }
 
-    if (path.endsWith(".html")) {
-      var test = p.withoutExtension(path) + ".dart";
-
-      // Link to the Dart wrapper on Dartium and the compiled JS version
-      // elsewhere.
+    if (path.endsWith('.html')) {
+      var test = p.withoutExtension(path) + '.dart';
       var scriptBase = htmlEscape.convert(p.basename(test));
       var link = '<link rel="x-dart-test" href="$scriptBase">';
-
-      return shelf.Response.ok('''
-        <!DOCTYPE html>
-        <html>
-        <head>
-          <title>${htmlEscape.convert(test)} Test</title>
-          $link
-          <script src="packages/test/dart.js"></script>
-        </head>
-        </html>
-      ''', headers: {'Content-Type': 'text/html'});
+      var testName = htmlEscape.convert(test);
+      var template = _config.customHtmlTemplatePath ?? _defaultTemplatePath;
+      var contents = File(template).readAsStringSync();
+      var processedContents = contents
+          // Checked during loading phase that there is only one {{testScript}} placeholder.
+          .replaceFirst('{{testScript}}', link)
+          .replaceAll('{{testName}}', testName);
+      return shelf.Response.ok(processedContents,
+          headers: {'Content-Type': 'text/html'});
     }
 
     return shelf.Response.notFound('Not found.');
   }
 
+  @override
   ExecutableSettings parsePlatformSettings(YamlMap settings) =>
       ExecutableSettings.parse(settings);
 
+  @override
   ExecutableSettings mergePlatformSettings(
           ExecutableSettings settings1, ExecutableSettings settings2) =>
       settings1.merge(settings2);
 
+  @override
   void customizePlatform(Runtime runtime, ExecutableSettings settings) {
     var oldSettings =
         _browserSettings[runtime] ?? _browserSettings[runtime.root];
@@ -218,22 +222,40 @@
   ///
   /// This will start a browser to load the suite if one isn't already running.
   /// Throws an [ArgumentError] if `platform.platform` isn't a browser.
+  @override
   Future<RunnerSuite> load(String path, SuitePlatform platform,
       SuiteConfiguration suiteConfig, Object message) async {
     var browser = platform.runtime;
     assert(suiteConfig.runtimes.contains(browser.identifier));
 
     if (!browser.isBrowser) {
-      throw ArgumentError("$browser is not a browser.");
+      throw ArgumentError('$browser is not a browser.');
     }
 
-    var htmlPath = p.withoutExtension(path) + '.html';
-    if (File(htmlPath).existsSync() &&
-        !File(htmlPath).readAsStringSync().contains('packages/test/dart.js')) {
-      throw LoadException(
-          path,
-          '"${htmlPath}" must contain <script src="packages/test/dart.js">'
-          '</script>.');
+    var htmlPathFromTestPath = p.withoutExtension(path) + '.html';
+    if (File(htmlPathFromTestPath).existsSync()) {
+      if (_config.customHtmlTemplatePath != null &&
+          p.basename(htmlPathFromTestPath) ==
+              p.basename(_config.customHtmlTemplatePath)) {
+        throw LoadException(
+            path,
+            'template file "${p.basename(_config.customHtmlTemplatePath)}" cannot be named '
+            'like the test file.');
+      }
+      _checkHtmlCorrectness(htmlPathFromTestPath, path);
+    } else if (_config.customHtmlTemplatePath != null) {
+      var htmlTemplatePath = _config.customHtmlTemplatePath;
+      if (!File(htmlTemplatePath).existsSync()) {
+        throw LoadException(
+            path, '"${htmlTemplatePath}" does not exist or is not readable');
+      }
+
+      final templateFileContents = File(htmlTemplatePath).readAsStringSync();
+      if ('{{testScript}}'.allMatches(templateFileContents).length != 1) {
+        throw LoadException(path,
+            '"${htmlTemplatePath}" must contain exactly one {{testScript}} placeholder');
+      }
+      _checkHtmlCorrectness(htmlTemplatePath, path);
     }
 
     Uri suiteUrl;
@@ -257,7 +279,7 @@
 
       if (_closed) return null;
       suiteUrl = url.resolveUri(
-          p.toUri(p.withoutExtension(p.relative(path, from: _root)) + ".html"));
+          p.toUri(p.withoutExtension(p.relative(path, from: _root)) + '.html'));
     }
 
     if (_closed) return null;
@@ -272,6 +294,16 @@
     return suite;
   }
 
+  void _checkHtmlCorrectness(String htmlPath, String path) {
+    if (!File(htmlPath).readAsStringSync().contains('packages/test/dart.js')) {
+      throw LoadException(
+          path,
+          '"${htmlPath}" must contain <script src="packages/test/dart.js">'
+          '</script>.');
+    }
+  }
+
+  @override
   StreamChannel loadChannel(String path, SuitePlatform platform) =>
       throw UnimplementedError();
 
@@ -308,16 +340,17 @@
 
           throw LoadException(
               path,
-              "Error getting $url: ${response.statusCode} "
-              "${response.reasonPhrase}\n"
+              'Error getting $url: ${response.statusCode} '
+              '${response.reasonPhrase}\n'
               'Make sure "pub serve" is serving the test/ directory.');
         }
 
         if (getSourceMap && !suiteConfig.jsTrace) {
           _mappers[path] = JSStackTraceMapper(await utf8.decodeStream(response),
               mapUrl: url,
-              packageResolver: SyncPackageResolver.root('packages'),
-              sdkRoot: p.toUri('packages/\$sdk'));
+              sdkRoot: p.toUri('packages/\$sdk'),
+              packageMap:
+                  (await currentPackageConfig).toPackagesDirPackageMap());
           return;
         }
 
@@ -326,13 +359,13 @@
       } on IOException catch (error) {
         var message = getErrorMessage(error);
         if (error is SocketException) {
-          message = "${error.osError.message} "
-              "(errno ${error.osError.errorCode})";
+          message = '${error.osError.message} '
+              '(errno ${error.osError.errorCode})';
         }
 
         throw LoadException(
             path,
-            "Error getting $url: $message\n"
+            'Error getting $url: $message\n'
             'Make sure "pub serve" is running.');
       } finally {
         timer.cancel();
@@ -347,7 +380,7 @@
   Future _compileSuite(String dartPath, SuiteConfiguration suiteConfig) {
     return _compileFutures.putIfAbsent(dartPath, () async {
       var dir = Directory(_compiledDir).createTempSync('test_').path;
-      var jsPath = p.join(dir, p.basename(dartPath) + ".browser_test.dart.js");
+      var jsPath = p.join(dir, p.basename(dartPath) + '.browser_test.dart.js');
 
       await _compilers.compile('''
         import "package:test/src/bootstrap/browser.dart";
@@ -378,8 +411,8 @@
       var mapPath = jsPath + '.map';
       _mappers[dartPath] = JSStackTraceMapper(File(mapPath).readAsStringSync(),
           mapUrl: p.toUri(mapPath),
-          packageResolver: await PackageResolver.current.asSync,
-          sdkRoot: p.toUri(sdkDir));
+          sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
+          packageMap: (await currentPackageConfig).toPackageMap());
     });
   }
 
@@ -393,7 +426,7 @@
     var completer = Completer<WebSocketChannel>.sync();
     var path = _webSocketHandler.create(webSocketHandler(completer.complete));
     var webSocketUrl = url.replace(scheme: 'ws').resolve(path);
-    var hostUrl = (_config.pubServeUrl == null ? url : _config.pubServeUrl)
+    var hostUrl = (_config.pubServeUrl ?? url)
         .resolve('packages/test/src/runner/browser/static/index.html')
         .replace(queryParameters: {
       'managerUrl': webSocketUrl.toString(),
@@ -415,6 +448,7 @@
   ///
   /// Note that this doesn't close the server itself. Browser tests can still be
   /// loaded, they'll just spawn new browsers.
+  @override
   Future closeEphemeral() {
     var managers = _browserManagers.values.toList();
     _browserManagers.clear();
@@ -429,6 +463,7 @@
   ///
   /// Returns a [Future] that completes once the server is closed and its
   /// resources have been fully released.
+  @override
   Future close() => _closeMemo.runOnce(() async {
         var futures =
             _browserManagers.values.map<Future<dynamic>>((future) async {
diff --git a/test/lib/src/runner/browser/post_message_channel.dart b/test/lib/src/runner/browser/post_message_channel.dart
index 71e3dfa..595c2ec 100644
--- a/test/lib/src/runner/browser/post_message_channel.dart
+++ b/test/lib/src/runner/browser/post_message_channel.dart
@@ -12,7 +12,7 @@
 import 'package:stream_channel/stream_channel.dart';
 
 // Avoid using this from dart:html to work around dart-lang/sdk#32113.
-@JS("window.parent.postMessage")
+@JS('window.parent.postMessage')
 external void _postParentMessage(Object message, String targetOrigin);
 
 /// Constructs a [StreamChannel] wrapping [MessageChannel] communication with
@@ -29,7 +29,7 @@
     // very unlikely that a malicious site would care about hacking someone's
     // unit tests, let alone be able to find the test server while it's
     // running, but it's good practice to check the origin anyway.
-    return message.origin == window.location.origin && message.data == "port";
+    return message.origin == window.location.origin && message.data == 'port';
   }).then((message) {
     var port = message.ports.first;
     var portSubscription = port.onMessage.listen((message) {
@@ -37,9 +37,9 @@
     });
 
     controller.local.stream.listen((data) {
-      port.postMessage({"data": data});
+      port.postMessage({'data': data});
     }, onDone: () {
-      port.postMessage({"event": "done"});
+      port.postMessage({'event': 'done'});
       portSubscription.cancel();
     });
   });
@@ -47,7 +47,7 @@
   // Send a ready message once we're listening so the host knows it's safe to
   // start sending events.
   // TODO(nweiz): Stop manually adding href here once issue 22554 is fixed.
-  _postParentMessage(jsify({"href": window.location.href, "ready": true}),
+  _postParentMessage(jsify({'href': window.location.href, 'ready': true}),
       window.location.origin);
 
   return controller.foreign;
diff --git a/test/lib/src/runner/browser/safari.dart b/test/lib/src/runner/browser/safari.dart
index 40faa4f..a47bb09 100644
--- a/test/lib/src/runner/browser/safari.dart
+++ b/test/lib/src/runner/browser/safari.dart
@@ -8,19 +8,19 @@
 
 import 'package:path/path.dart' as p;
 import 'package:pedantic/pedantic.dart';
-
 import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
 import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
 
+import '../executable_settings.dart';
 import 'browser.dart';
 import 'default_settings.dart';
-import '../executable_settings.dart';
 
 /// A class for running an instance of Safari.
 ///
 /// Any errors starting or running the process are reported through [onExit].
 class Safari extends Browser {
-  final name = "Safari";
+  @override
+  final name = 'Safari';
 
   Safari(url, {ExecutableSettings settings})
       : super(() => _startBrowser(url, settings));
@@ -36,7 +36,7 @@
     // want it to load.
     var redirect = p.join(dir, 'redirect.html');
     File(redirect).writeAsStringSync(
-        "<script>location = " + jsonEncode(url.toString()) + "</script>");
+        '<script>location = ' + jsonEncode(url.toString()) + '</script>');
 
     var process = await Process.start(
         settings.executable, settings.arguments.toList()..add(redirect));
diff --git a/test/lib/src/runner/browser/static/default.html.tpl b/test/lib/src/runner/browser/static/default.html.tpl
new file mode 100644
index 0000000..a92f529
--- /dev/null
+++ b/test/lib/src/runner/browser/static/default.html.tpl
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>{{testName}} Test</title>
+    {{testScript}}
+    <script src="packages/test/dart.js"></script>
+  </head>
+</html>
diff --git a/test/lib/src/runner/executable_settings.dart b/test/lib/src/runner/executable_settings.dart
index e793d12..5aa9b8d 100644
--- a/test/lib/src/runner/executable_settings.dart
+++ b/test/lib/src/runner/executable_settings.dart
@@ -72,7 +72,7 @@
   /// Parses settings from a user-provided YAML mapping.
   factory ExecutableSettings.parse(YamlMap settings) {
     List<String> arguments;
-    var argumentsNode = settings.nodes["arguments"];
+    var argumentsNode = settings.nodes['arguments'];
     if (argumentsNode != null) {
       var value = argumentsNode.value;
       if (value is String) {
@@ -83,14 +83,14 @@
         }
       } else {
         throw SourceSpanFormatException(
-            "Must be a string.", argumentsNode.span);
+            'Must be a string.', argumentsNode.span);
       }
     }
 
     String linuxExecutable;
     String macOSExecutable;
     String windowsExecutable;
-    var executableNode = settings.nodes["executable"];
+    var executableNode = settings.nodes['executable'];
     if (executableNode != null) {
       var value = executableNode.value;
       if (value is String) {
@@ -104,25 +104,25 @@
         macOSExecutable = value;
         windowsExecutable = value;
       } else if (executableNode is YamlMap) {
-        linuxExecutable = _getExecutable(executableNode.nodes["linux"]);
-        macOSExecutable = _getExecutable(executableNode.nodes["mac_os"]);
-        windowsExecutable = _getExecutable(executableNode.nodes["windows"],
+        linuxExecutable = _getExecutable(executableNode.nodes['linux']);
+        macOSExecutable = _getExecutable(executableNode.nodes['mac_os']);
+        windowsExecutable = _getExecutable(executableNode.nodes['windows'],
             allowRelative: true);
       } else {
         throw SourceSpanFormatException(
-            "Must be a map or a string.", executableNode.span);
+            'Must be a map or a string.', executableNode.span);
       }
     }
 
     var headless = true;
-    var headlessNode = settings.nodes["headless"];
+    var headlessNode = settings.nodes['headless'];
     if (headlessNode != null) {
       var value = headlessNode.value;
       if (value is bool) {
         headless = value;
       } else {
         throw SourceSpanFormatException(
-            "Must be a boolean.", headlessNode.span);
+            'Must be a boolean.', headlessNode.span);
       }
     }
 
@@ -142,7 +142,7 @@
       {bool allowRelative = false}) {
     if (executableNode == null || executableNode.value == null) return null;
     if (executableNode.value is! String) {
-      throw SourceSpanFormatException("Must be a string.", executableNode.span);
+      throw SourceSpanFormatException('Must be a string.', executableNode.span);
     }
     if (!allowRelative) _assertNotRelative(executableNode as YamlScalar);
     return executableNode.value as String;
@@ -159,7 +159,7 @@
     if (p.posix.basename(executable) == executable) return;
 
     throw SourceSpanFormatException(
-        "Linux and Mac OS executables may not be relative paths.",
+        'Linux and Mac OS executables may not be relative paths.',
         executableNode.span);
   }
 
diff --git a/test/lib/src/runner/node/platform.dart b/test/lib/src/runner/node/platform.dart
index 3d5d9ba..bea9aa9 100644
--- a/test/lib/src/runner/node/platform.dart
+++ b/test/lib/src/runner/node/platform.dart
@@ -7,10 +7,9 @@
 import 'dart:convert';
 
 import 'package:async/async.dart';
+import 'package:package_config/package_config.dart';
 import 'package:multi_server_socket/multi_server_socket.dart';
 import 'package:node_preamble/preamble.dart' as preamble;
-import 'package:pedantic/pedantic.dart';
-import 'package:package_resolver/package_resolver.dart';
 import 'package:path/path.dart' as p;
 import 'package:stream_channel/stream_channel.dart';
 import 'package:yaml/yaml.dart';
@@ -33,6 +32,7 @@
 import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
 
 import '../executable_settings.dart';
+import '../../util/package_map.dart';
 
 /// A platform that loads tests in Node.js processes.
 class NodePlatform extends PlatformPlugin
@@ -41,7 +41,7 @@
   final Configuration _config;
 
   /// The [CompilerPool] managing active instances of `dart2js`.
-  final _compilers = CompilerPool(["-Dnode=true", "--server-mode"]);
+  final _compilers = CompilerPool(['-Dnode=true', '--server-mode']);
 
   /// The temporary directory in which compiled JS is emitted.
   final _compiledDir = createTempDir();
@@ -53,38 +53,43 @@
   /// it.
   final _settings = {
     Runtime.nodeJS: ExecutableSettings(
-        linuxExecutable: "node",
-        macOSExecutable: "node",
-        windowsExecutable: "node.exe")
+        linuxExecutable: 'node',
+        macOSExecutable: 'node',
+        windowsExecutable: 'node.exe')
   };
 
   NodePlatform()
       : _config = Configuration.current,
         _http = Configuration.current.pubServeUrl == null ? null : HttpClient();
 
+  @override
   ExecutableSettings parsePlatformSettings(YamlMap settings) =>
       ExecutableSettings.parse(settings);
 
+  @override
   ExecutableSettings mergePlatformSettings(
           ExecutableSettings settings1, ExecutableSettings settings2) =>
       settings1.merge(settings2);
 
+  @override
   void customizePlatform(Runtime runtime, ExecutableSettings settings) {
     var oldSettings = _settings[runtime] ?? _settings[runtime.root];
     if (oldSettings != null) settings = oldSettings.merge(settings);
     _settings[runtime] = settings;
   }
 
+  @override
   StreamChannel loadChannel(String path, SuitePlatform platform) =>
       throw UnimplementedError();
 
+  @override
   Future<RunnerSuite> load(String path, SuitePlatform platform,
       SuiteConfiguration suiteConfig, Object message) async {
     var pair = await _loadChannel(path, platform.runtime, suiteConfig);
     var controller = deserializeSuite(
         path, platform, suiteConfig, PluginEnvironment(), pair.first, message);
 
-    controller.channel("test.node.mapper").sink.add(pair.last?.serialize());
+    controller.channel('test.node.mapper').sink.add(pair.last?.serialize());
 
     return await controller.suite;
   }
@@ -146,7 +151,7 @@
   Future<Pair<Process, StackTraceMapper>> _spawnNormalProcess(String testPath,
       Runtime runtime, SuiteConfiguration suiteConfig, int socketPort) async {
     var dir = Directory(_compiledDir).createTempSync('test_').path;
-    var jsPath = p.join(dir, p.basename(testPath) + ".node_test.dart.js");
+    var jsPath = p.join(dir, p.basename(testPath) + '.node_test.dart.js');
     await _compilers.compile('''
         import "package:test/src/bootstrap/node.dart";
 
@@ -168,8 +173,8 @@
       var mapPath = jsPath + '.map';
       mapper = JSStackTraceMapper(await File(mapPath).readAsString(),
           mapUrl: p.toUri(mapPath),
-          packageResolver: await PackageResolver.current.asSync,
-          sdkRoot: p.toUri(sdkDir));
+          sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
+          packageMap: (await currentPackageConfig).toPackageMap());
     }
 
     return Pair(await _startProcess(runtime, jsPath, socketPort), mapper);
@@ -187,12 +192,11 @@
     var jsPath = p.join(precompiledPath, '$testPath.node_test.dart.js');
     if (!suiteConfig.jsTrace) {
       var mapPath = jsPath + '.map';
-      var resolver = await SyncPackageResolver.loadConfig(
-          p.toUri(p.join(precompiledPath, '.packages')));
       mapper = JSStackTraceMapper(await File(mapPath).readAsString(),
           mapUrl: p.toUri(mapPath),
-          packageResolver: resolver,
-          sdkRoot: p.toUri(sdkDir));
+          sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
+          packageMap: (await findPackageConfig(Directory(precompiledPath)))
+              .toPackageMap());
     }
 
     return Pair(await _startProcess(runtime, jsPath, socketPort), mapper);
@@ -204,7 +208,7 @@
   Future<Pair<Process, StackTraceMapper>> _spawnPubServeProcess(String testPath,
       Runtime runtime, SuiteConfiguration suiteConfig, int socketPort) async {
     var dir = Directory(_compiledDir).createTempSync('test_').path;
-    var jsPath = p.join(dir, p.basename(testPath) + ".node_test.dart.js");
+    var jsPath = p.join(dir, p.basename(testPath) + '.node_test.dart.js');
     var url = _config.pubServeUrl.resolveUri(
         p.toUri(p.relative(testPath, from: 'test') + '.node_test.dart.js'));
 
@@ -216,8 +220,8 @@
       var mapUrl = url.replace(path: url.path + '.map');
       mapper = JSStackTraceMapper(await _get(mapUrl, testPath),
           mapUrl: mapUrl,
-          packageResolver: SyncPackageResolver.root('packages'),
-          sdkRoot: p.toUri('packages/\$sdk'));
+          sdkRoot: p.toUri('packages/\$sdk'),
+          packageMap: (await currentPackageConfig).toPackagesDirPackageMap());
     }
 
     return Pair(await _startProcess(runtime, jsPath, socketPort), mapper);
@@ -229,8 +233,8 @@
     var settings = _settings[runtime];
 
     var nodeModules = p.absolute('node_modules');
-    var nodePath = Platform.environment["NODE_PATH"];
-    nodePath = nodePath == null ? nodeModules : "$nodePath:$nodeModules";
+    var nodePath = Platform.environment['NODE_PATH'];
+    nodePath = nodePath == null ? nodeModules : '$nodePath:$nodeModules';
 
     try {
       return await Process.start(settings.executable,
@@ -239,7 +243,7 @@
     } catch (error, stackTrace) {
       await Future.error(
           ApplicationException(
-              "Failed to run ${runtime.name}: ${getErrorMessage(error)}"),
+              'Failed to run ${runtime.name}: ${getErrorMessage(error)}'),
           stackTrace);
       return null;
     }
@@ -259,8 +263,8 @@
 
         throw LoadException(
             suitePath,
-            "Error getting $url: ${response.statusCode} "
-            "${response.reasonPhrase}\n"
+            'Error getting $url: ${response.statusCode} '
+            '${response.reasonPhrase}\n'
             'Make sure "pub serve" is serving the test/ directory.');
       }
 
@@ -268,17 +272,18 @@
     } on IOException catch (error) {
       var message = getErrorMessage(error);
       if (error is SocketException) {
-        message = "${error.osError.message} "
-            "(errno ${error.osError.errorCode})";
+        message = '${error.osError.message} '
+            '(errno ${error.osError.errorCode})';
       }
 
       throw LoadException(
           suitePath,
-          "Error getting $url: $message\n"
+          'Error getting $url: $message\n'
           'Make sure "pub serve" is running.');
     }
   }
 
+  @override
   Future close() => _closeMemo.runOnce(() async {
         await _compilers.close();
 
diff --git a/test/lib/src/runner/node/socket_channel.dart b/test/lib/src/runner/node/socket_channel.dart
index c00a139..0c2036a 100644
--- a/test/lib/src/runner/node/socket_channel.dart
+++ b/test/lib/src/runner/node/socket_channel.dart
@@ -9,10 +9,10 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
 
-@JS("require")
+@JS('require')
 external _Net _require(String module);
 
-@JS("process.argv")
+@JS('process.argv')
 external List<String> get _args;
 
 @JS()
@@ -22,9 +22,9 @@
 
 @JS()
 class _Socket {
-  external setEncoding(String encoding);
-  external on(String event, void callback(String chunk));
-  external write(String data);
+  external void setEncoding(String encoding);
+  external void on(String event, void Function(String chunk) callback);
+  external void write(String data);
 }
 
 /// Returns a [StreamChannel] of JSON-encodable objects that communicates over a
@@ -32,12 +32,12 @@
 StreamChannel<Object> socketChannel() {
   var controller =
       StreamChannelController<String>(allowForeignErrors: false, sync: true);
-  var net = _require("net");
+  var net = _require('net');
   var socket = net.connect(int.parse(_args[2]));
-  socket.setEncoding("utf8");
+  socket.setEncoding('utf8');
 
   controller.local.stream.listen((chunk) => socket.write(chunk));
-  socket.on("data", allowInterop(controller.local.sink.add));
+  socket.on('data', allowInterop(controller.local.sink.add));
 
   return controller.foreign.transform(chunksToLines).transform(jsonDocument);
 }
diff --git a/test/lib/src/util/one_off_handler.dart b/test/lib/src/util/one_off_handler.dart
index a317072..7667df3 100644
--- a/test/lib/src/util/one_off_handler.dart
+++ b/test/lib/src/util/one_off_handler.dart
@@ -12,7 +12,7 @@
 /// invalid and don't need to have a persistent URL.
 class OneOffHandler {
   /// A map from URL paths to handlers.
-  final _handlers = Map<String, shelf.Handler>();
+  final _handlers = <String, shelf.Handler>{};
 
   /// The counter of handlers that have been activated.
   var _counter = 0;
diff --git a/test/lib/src/util/package_map.dart b/test/lib/src/util/package_map.dart
new file mode 100644
index 0000000..948b6a6
--- /dev/null
+++ b/test/lib/src/util/package_map.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for 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:isolate';
+
+import 'package:package_config/package_config.dart';
+
+/// The [PackageConfig] parsed from the current isolates package config file.
+final Future<PackageConfig> currentPackageConfig = () async {
+  return loadPackageConfigUri(await Isolate.packageConfig);
+}();
+
+/// Adds methods to convert to a package map on [PackageConfig].
+extension PackageMap on PackageConfig {
+  /// A package map exactly matching the current package config
+  Map<String, Uri> toPackageMap() =>
+      {for (var package in packages) package.name: package.packageUriRoot};
+
+  /// A package map with all the current packages but where the uris are all
+  /// of the form 'packages/${package.name}'.
+  Map<String, Uri> toPackagesDirPackageMap() => {
+        for (var package in packages)
+          package.name: Uri.parse('packages/${package.name}')
+      };
+}
diff --git a/test/lib/src/util/path_handler.dart b/test/lib/src/util/path_handler.dart
index b5303d5..2fe31c4 100644
--- a/test/lib/src/util/path_handler.dart
+++ b/test/lib/src/util/path_handler.dart
@@ -48,7 +48,7 @@
       handlerIndex = i;
     }
 
-    if (handler == null) return shelf.Response.notFound("Not found.");
+    if (handler == null) return shelf.Response.notFound('Not found.');
 
     return handler(
         request.change(path: p.url.joinAll(components.take(handlerIndex + 1))));
@@ -58,5 +58,5 @@
 /// A trie node.
 class _Node {
   shelf.Handler handler;
-  final children = Map<String, _Node>();
+  final children = <String, _Node>{};
 }
diff --git a/test/mono_pkg.yaml b/test/mono_pkg.yaml
index e2c26a6..ef401af 100644
--- a/test/mono_pkg.yaml
+++ b/test/mono_pkg.yaml
@@ -9,10 +9,10 @@
         dart: dev
       - group:
         - dartanalyzer: --fatal-warnings .
-        dart: 2.2.0
+        dart: 2.7.0
     - unit_test:
-      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 0
-      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 1
-      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 2
-      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 3
-      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 4
+      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 0
+      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 1
+      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 2
+      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 3
+      - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 4
diff --git a/test/pubspec.yaml b/test/pubspec.yaml
index 3693289..26df200 100644
--- a/test/pubspec.yaml
+++ b/test/pubspec.yaml
@@ -1,43 +1,43 @@
 name: test
-version: 1.9.4
-author: Dart Team <misc@dartlang.org>
+version: 1.14.1
 description: A full featured library for writing and running Dart tests.
 homepage: https://github.com/dart-lang/test/blob/master/pkgs/test
 
 environment:
-  sdk: '>=2.2.0 <3.0.0'
+  sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
-  analyzer: ">=0.36.0 <0.40.0"
+  analyzer: '>=0.36.0 <0.40.0'
   async: ^2.0.0
-  boolean_selector: ^1.0.0
+  boolean_selector: '>=1.0.0 <3.0.0'
+  coverage: ^0.13.4
+  http: ^0.12.0
   http_multi_server: ^2.0.0
   io: ^0.3.0
   js: ^0.6.0
   multi_server_socket: ^1.0.0
   node_preamble: ^1.3.0
-  package_resolver: ^1.0.0
+  package_config: ^1.9.0
   path: ^1.2.0
   pedantic: ^1.1.0
   pool: ^1.3.0
   shelf: ^0.7.0
-  shelf_packages_handler: ^1.0.0
+  shelf_packages_handler: ">=1.0.0 <3.0.0"
   shelf_static: ^0.2.6
   shelf_web_socket: ^0.2.0
   source_span: ^1.4.0
   stack_trace: ^1.9.0
-  stream_channel: ">=1.7.0 <3.0.0"
+  stream_channel: '>=1.7.0 <3.0.0'
   typed_data: ^1.0.0
   web_socket_channel: ^1.0.0
+  webkit_inspection_protocol: ^0.5.0
   yaml: ^2.0.0
   # Use an exact version until the test_api and test_core package are stable.
-  test_api: 0.2.11
-  test_core: 0.2.15
+  test_api: 0.2.15
+  test_core: 0.3.2
 
 dev_dependencies:
   fake_async: ^1.0.0
   shelf_test_handler: ^1.0.0
   test_descriptor: ^1.0.0
   test_process: ^1.0.0
-
-
diff --git a/test/tool/host.dart b/test/tool/host.dart
index fb296c7..c1b229c 100644
--- a/test/tool/host.dart
+++ b/test/tool/host.dart
@@ -38,18 +38,19 @@
   /// running.
   external Function get restartCurrent;
 
-  external factory _JSApi({void resume(), void restartCurrent()});
+  external factory _JSApi(
+      {void Function() resume, void Function() restartCurrent});
 }
 
 /// Sets the top-level `dartTest` object so that it's visible to JS.
-@JS("dartTest")
+@JS('dartTest')
 external set _jsApi(_JSApi api);
 
 /// The iframes created for each loaded test suite, indexed by the suite id.
-final _iframes = Map<int, IFrameElement>();
+final _iframes = <int, IFrameElement>{};
 
 /// Subscriptions created for each loaded test suite, indexed by the suite id.
-final _subscriptions = Map<int, List<StreamSubscription>>();
+final _subscriptions = <int, List<StreamSubscription>>{};
 
 /// The URL for the current page.
 final _currentUrl = Uri.parse(window.location.href);
@@ -140,22 +141,22 @@
     // Send periodic pings to the test runner so it can know when the browser is
     // paused for debugging.
     Timer.periodic(Duration(seconds: 1),
-        (_) => serverChannel.sink.add({"command": "ping"}));
+        (_) => serverChannel.sink.add({'command': 'ping'}));
 
-    var play = document.querySelector("#play");
+    var play = document.querySelector('#play');
     play.onClick.listen((_) {
       if (!document.body.classes.remove('paused')) return;
-      serverChannel.sink.add({"command": "resume"});
+      serverChannel.sink.add({'command': 'resume'});
     });
 
     _jsApi = _JSApi(resume: allowInterop(() {
       if (!document.body.classes.remove('paused')) return;
-      serverChannel.sink.add({"command": "resume"});
+      serverChannel.sink.add({'command': 'resume'});
     }), restartCurrent: allowInterop(() {
-      serverChannel.sink.add({"command": "restart"});
+      serverChannel.sink.add({'command': 'restart'});
     }));
   }, onError: (error, StackTrace stackTrace) {
-    print("$error\n${Trace.from(stackTrace).terse}");
+    print('$error\n${Trace.from(stackTrace).terse}');
   });
 }
 
@@ -207,25 +208,25 @@
 
     // TODO(nweiz): Stop manually checking href here once issue 22554 is
     // fixed.
-    if (message.data["href"] != iframe.src) return;
+    if (message.data['href'] != iframe.src) return;
 
     message.stopPropagation();
 
-    if (message.data["ready"] == true) {
+    if (message.data['ready'] == true) {
       // This message indicates that the iframe is actively listening for
       // events, so the message channel's second port can now be transferred.
       iframe.contentWindow
-          .postMessage("port", window.location.origin, [channel.port2]);
+          .postMessage('port', window.location.origin, [channel.port2]);
       readyCompleter.complete();
-    } else if (message.data["exception"] == true) {
+    } else if (message.data['exception'] == true) {
       // This message from `dart.js` indicates that an exception occurred
       // loading the test.
-      controller.local.sink.add(message.data["data"]);
+      controller.local.sink.add(message.data['data']);
     }
   }));
 
   subscriptions.add(channel.port1.onMessage.listen((message) {
-    controller.local.sink.add(message.data["data"]);
+    controller.local.sink.add(message.data['data']);
   }));
 
   subscriptions.add(controller.local.stream.listen((message) async {
diff --git a/test_api/BUILD.gn b/test_api/BUILD.gn
index b020187..4960a26 100644
--- a/test_api/BUILD.gn
+++ b/test_api/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for test_api-0.2.11
+# This file is generated by importer.py for test_api-0.2.15
 
 import("//build/dart/dart_library.gni")
 
@@ -13,7 +13,6 @@
 
   deps = [
     "//third_party/dart-pkg/pub/stack_trace",
-    "//third_party/dart-pkg/pub/pedantic",
     "//third_party/dart-pkg/pub/async",
     "//third_party/dart-pkg/pub/matcher",
     "//third_party/dart-pkg/pub/collection",
diff --git a/test_api/CHANGELOG.md b/test_api/CHANGELOG.md
index 3a31124..ddbb2db 100644
--- a/test_api/CHANGELOG.md
+++ b/test_api/CHANGELOG.md
@@ -1,3 +1,27 @@
+## 0.2.15
+
+* Cancel any StreamQueue that is created as a part of a stream matcher once it
+  is done matching.
+  * This fixes a bug where using a matcher on a custom stream controller and
+    then awaiting the `close()` method on that controller would hang.
+* Avoid causing the test runner to hang if there is a timeout during a
+  `tearDown` callback following a failing test case.
+
+## 0.2.14
+
+* Bump minimum SDK to `2.4.0` for safer usage of for-loop elements.
+
+## 0.2.13
+
+* Work around a bug in the `2.3.0` SDK by avoiding for-loop elements at the top
+  level.
+
+## 0.2.12
+
+* Link to docs on setting timeout when a test times out with the default
+  duration.
+* No longer directly depend on `package:pedantic`.
+
 ## 0.2.11
 
 * Extend the timeout for synthetic tests, e.g. `tearDownAll`.
diff --git a/test_api/lib/src/backend/closed_exception.dart b/test_api/lib/src/backend/closed_exception.dart
index 4432466..08a45a0 100644
--- a/test_api/lib/src/backend/closed_exception.dart
+++ b/test_api/lib/src/backend/closed_exception.dart
@@ -7,5 +7,6 @@
 class ClosedException implements Exception {
   ClosedException();
 
-  String toString() => "This test has been closed.";
+  @override
+  String toString() => 'This test has been closed.';
 }
diff --git a/test_api/lib/src/backend/declarer.dart b/test_api/lib/src/backend/declarer.dart
index cc4b1fd..f4a41b4 100644
--- a/test_api/lib/src/backend/declarer.dart
+++ b/test_api/lib/src/backend/declarer.dart
@@ -50,13 +50,13 @@
   final bool _noRetry;
 
   /// The set-up functions to run for each test in this group.
-  final _setUps = List<Function()>();
+  final _setUps = <dynamic Function()>[];
 
   /// The tear-down functions to run for each test in this group.
-  final _tearDowns = List<Function()>();
+  final _tearDowns = <dynamic Function()>[];
 
   /// The set-up functions to run once for this group.
-  final _setUpAlls = List<Function()>();
+  final _setUpAlls = <dynamic Function()>[];
 
   /// The default timeout for synthetic tests.
   final _timeout = Timeout(Duration(minutes: 12));
@@ -69,7 +69,7 @@
   Trace _setUpAllTrace;
 
   /// The tear-down functions to run once for this group.
-  final _tearDownAlls = List<Function()>();
+  final _tearDownAlls = <Function()>[];
 
   /// The trace for the first call to [tearDownAll].
   ///
@@ -78,13 +78,13 @@
   Trace _tearDownAllTrace;
 
   /// The children of this group, either tests or sub-groups.
-  final _entries = List<GroupEntry>();
+  final _entries = <GroupEntry>[];
 
   /// Whether [build] has been called for this declarer.
   bool _built = false;
 
   /// The tests and/or groups that have been flagged as solo.
-  final _soloEntries = Set<GroupEntry>();
+  final _soloEntries = <GroupEntry>[];
 
   /// Whether any tests and/or groups have been flagged as solo.
   bool get _solo => _soloEntries.isNotEmpty;
@@ -127,10 +127,11 @@
   /// Runs [body] with this declarer as [Declarer.current].
   ///
   /// Returns the return value of [body].
-  declare(body()) => runZoned(body, zoneValues: {#test.declarer: this});
+  T declare<T>(T Function() body) =>
+      runZoned(body, zoneValues: {#test.declarer: this});
 
   /// Defines a test case with the given name and body.
-  void test(String name, body(),
+  void test(String name, dynamic Function() body,
       {String testOn,
       Timeout timeout,
       skip,
@@ -138,7 +139,7 @@
       tags,
       int retry,
       bool solo = false}) {
-    _checkNotBuilt("test");
+    _checkNotBuilt('test');
 
     var newMetadata = Metadata.parse(
         testOn: testOn,
@@ -181,7 +182,7 @@
   }
 
   /// Creates a group of tests.
-  void group(String name, void body(),
+  void group(String name, void Function() body,
       {String testOn,
       Timeout timeout,
       skip,
@@ -189,7 +190,7 @@
       tags,
       int retry,
       bool solo = false}) {
-    _checkNotBuilt("group");
+    _checkNotBuilt('group');
 
     var newMetadata = Metadata.parse(
         testOn: testOn,
@@ -209,7 +210,7 @@
       // result of a void method.
       var result = (body as dynamic)();
       if (result is! Future) return;
-      throw ArgumentError("Groups may not be async.");
+      throw ArgumentError('Groups may not be async.');
     });
     _entries.add(declarer.build());
 
@@ -219,44 +220,45 @@
   }
 
   /// Returns [name] prefixed with this declarer's group name.
-  String _prefix(String name) => _name == null ? name : "$_name $name";
+  String _prefix(String name) => _name == null ? name : '$_name $name';
 
   /// Registers a function to be run before each test in this group.
-  void setUp(callback()) {
-    _checkNotBuilt("setUp");
+  void setUp(dynamic Function() callback) {
+    _checkNotBuilt('setUp');
     _setUps.add(callback);
   }
 
   /// Registers a function to be run after each test in this group.
-  void tearDown(callback()) {
-    _checkNotBuilt("tearDown");
+  void tearDown(dynamic Function() callback) {
+    _checkNotBuilt('tearDown');
     _tearDowns.add(callback);
   }
 
   /// Registers a function to be run once before all tests.
-  void setUpAll(callback()) {
-    _checkNotBuilt("setUpAll");
+  void setUpAll(dynamic Function() callback) {
+    _checkNotBuilt('setUpAll');
     if (_collectTraces) _setUpAllTrace ??= Trace.current(2);
     _setUpAlls.add(callback);
   }
 
   /// Registers a function to be run once after all tests.
-  void tearDownAll(callback()) {
-    _checkNotBuilt("tearDownAll");
+  void tearDownAll(dynamic Function() callback) {
+    _checkNotBuilt('tearDownAll');
     if (_collectTraces) _tearDownAllTrace ??= Trace.current(2);
     _tearDownAlls.add(callback);
   }
 
   /// Like [tearDownAll], but called from within a running [setUpAll] test to
   /// dynamically add a [tearDownAll].
-  void addTearDownAll(callback()) => _tearDownAlls.add(callback);
+  void addTearDownAll(dynamic Function() callback) =>
+      _tearDownAlls.add(callback);
 
   /// Finalizes and returns the group being declared.
   ///
   /// **Note**: The tests in this group must be run in a [Invoker.guard]
   /// context; otherwise, test errors won't be captured.
   Group build() {
-    _checkNotBuilt("build");
+    _checkNotBuilt('build');
 
     _built = true;
     var entries = _entries.map((entry) {
@@ -298,7 +300,7 @@
   Test get _setUpAll {
     if (_setUpAlls.isEmpty) return null;
 
-    return LocalTest(_prefix("(setUpAll)"), _metadata.change(timeout: _timeout),
+    return LocalTest(_prefix('(setUpAll)'), _metadata.change(timeout: _timeout),
         () {
       return runZoned(() => Future.forEach(_setUpAlls, (setUp) => setUp()),
           // Make the declarer visible to running scaffolds so they can add to
@@ -314,7 +316,7 @@
     if (_setUpAlls.isEmpty && _tearDownAlls.isEmpty) return null;
 
     return LocalTest(
-        _prefix("(tearDownAll)"), _metadata.change(timeout: _timeout), () {
+        _prefix('(tearDownAll)'), _metadata.change(timeout: _timeout), () {
       return runZoned(() {
         return Invoker.current.unclosable(() async {
           while (_tearDownAlls.isNotEmpty) {
diff --git a/test_api/lib/src/backend/group.dart b/test_api/lib/src/backend/group.dart
index 3f831f0..30f5238 100644
--- a/test_api/lib/src/backend/group.dart
+++ b/test_api/lib/src/backend/group.dart
@@ -13,10 +13,13 @@
 ///
 /// It includes metadata that applies to all contained tests.
 class Group implements GroupEntry {
+  @override
   final String name;
 
+  @override
   final Metadata metadata;
 
+  @override
   final Trace trace;
 
   /// The children of this group.
@@ -49,8 +52,9 @@
   Group(this.name, Iterable<GroupEntry> entries,
       {Metadata metadata, this.trace, this.setUpAll, this.tearDownAll})
       : entries = List<GroupEntry>.unmodifiable(entries),
-        metadata = metadata == null ? Metadata() : metadata;
+        metadata = metadata ?? Metadata();
 
+  @override
   Group forPlatform(SuitePlatform platform) {
     if (!metadata.testOn.evaluate(platform)) return null;
     var newMetadata = metadata.forPlatform(platform);
@@ -63,7 +67,8 @@
         tearDownAll: tearDownAll);
   }
 
-  Group filter(bool callback(Test test)) {
+  @override
+  Group filter(bool Function(Test) callback) {
     var filtered = _map((entry) => entry.filter(callback));
     if (filtered.isEmpty && entries.isNotEmpty) return null;
     return Group(name, filtered,
@@ -76,7 +81,7 @@
   /// Returns the entries of this group mapped using [callback].
   ///
   /// Any `null` values returned by [callback] will be removed.
-  List<GroupEntry> _map(GroupEntry callback(GroupEntry entry)) {
+  List<GroupEntry> _map(GroupEntry Function(GroupEntry) callback) {
     return entries
         .map((entry) => callback(entry))
         .where((entry) => entry != null)
diff --git a/test_api/lib/src/backend/group_entry.dart b/test_api/lib/src/backend/group_entry.dart
index 2d2a341..44b3054 100644
--- a/test_api/lib/src/backend/group_entry.dart
+++ b/test_api/lib/src/backend/group_entry.dart
@@ -35,5 +35,5 @@
   ///
   /// Returns `null` if this is a test that doesn't match [callback] or a group
   /// where no child tests match [callback].
-  GroupEntry filter(bool callback(Test test));
+  GroupEntry filter(bool Function(Test) callback);
 }
diff --git a/test_api/lib/src/backend/invoker.dart b/test_api/lib/src/backend/invoker.dart
index 5b44624..2c83b2d 100644
--- a/test_api/lib/src/backend/invoker.dart
+++ b/test_api/lib/src/backend/invoker.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 
-import 'package:pedantic/pedantic.dart';
 import 'package:stack_trace/stack_trace.dart';
 
 import '../frontend/expect.dart';
@@ -24,8 +23,11 @@
 
 /// A test in this isolate.
 class LocalTest extends Test {
+  @override
   final String name;
+  @override
   final Metadata metadata;
+  @override
   final Trace trace;
 
   /// Whether this is a test defined using `setUpAll()` or `tearDownAll()`.
@@ -51,11 +53,13 @@
       this.isScaffoldAll);
 
   /// Loads a single runnable instance of this test.
+  @override
   LiveTest load(Suite suite, {Iterable<Group> groups}) {
     var invoker = Invoker._(suite, this, groups: groups, guarded: _guarded);
     return invoker.liveTest;
   }
 
+  @override
   Test forPlatform(SuitePlatform platform) {
     if (!metadata.testOn.evaluate(platform)) return null;
     return LocalTest._(name, metadata.forPlatform(platform), _body, trace,
@@ -111,7 +115,7 @@
     var counter = Zone.current[_counterKey] as _AsyncCounter;
     if (counter != null) return counter;
     throw StateError("Can't add or remove outstanding callbacks outside "
-        "of a test body.");
+        'of a test body.');
   }
 
   /// All the zones created by [waitForOutstandingCallbacks], in the order they
@@ -140,7 +144,7 @@
 
   /// Runs [callback] in a zone where unhandled errors from [LiveTest]s are
   /// caught and dispatched to the appropriate [Invoker].
-  static T guard<T>(T callback()) =>
+  static T guard<T>(T Function() callback) =>
       runZoned(callback, zoneSpecification: ZoneSpecification(
           // Use [handleUncaughtError] rather than [onError] so we can
           // capture [zone] and with it the outstanding callback counter for
@@ -183,7 +187,7 @@
   ///
   /// The [callback] may return a [Future]. Like all tear-downs, callbacks are
   /// run in the reverse of the order they're declared.
-  void addTearDown(callback()) {
+  void addTearDown(dynamic Function() callback) {
     if (closed) throw ClosedException();
 
     if (_test.isScaffoldAll) {
@@ -267,15 +271,20 @@
     if (liveTest.isComplete) return;
     if (_timeoutTimer != null) _timeoutTimer.cancel();
 
-    var timeout = liveTest.test.metadata.timeout.apply(Duration(seconds: 30));
+    const defaultTimeout = Duration(seconds: 30);
+    var timeout = liveTest.test.metadata.timeout.apply(defaultTimeout);
     if (timeout == null) return;
+    String message() {
+      var message = 'Test timed out after ${niceDuration(timeout)}.';
+      if (timeout == defaultTimeout) {
+        message += ' See https://pub.dev/packages/test#timeouts';
+      }
+      return message;
+    }
+
     _timeoutTimer = _invokerZone.createTimer(timeout, () {
       _outstandingCallbackZones.last.run(() {
-        if (liveTest.isComplete) return;
-        _handleError(
-            Zone.current,
-            TimeoutException(
-                "Test timed out after ${niceDuration(timeout)}.", timeout));
+        _handleError(Zone.current, TimeoutException(message(), timeout));
       });
     });
   }
@@ -291,9 +300,9 @@
       // Set the state explicitly so we don't get an extra error about the test
       // failing after being complete.
       _controller.setState(const State(Status.complete, Result.error));
-      throw "This test was marked as skipped after it had already completed. "
-          "Make sure to use\n"
-          "[expectAsync] or the [completes] matcher when testing async code.";
+      throw 'This test was marked as skipped after it had already completed. '
+          'Make sure to use\n'
+          '[expectAsync] or the [completes] matcher when testing async code.';
     }
 
     if (message != null) _controller.message(Message.skip(message));
@@ -305,7 +314,7 @@
   void printOnFailure(String message) {
     message = message.trim();
     if (liveTest.state.result.isFailing) {
-      print("\n$message");
+      print('\n$message');
     } else {
       _printsOnFailure.add(message);
     }
@@ -340,13 +349,13 @@
     zone.run(() => _outstandingCallbacks.complete());
 
     if (!liveTest.test.metadata.chainStackTraces) {
-      _printsOnFailure.add("Consider enabling the flag chain-stack-traces to "
-          "receive more detailed exceptions.\n"
+      _printsOnFailure.add('Consider enabling the flag chain-stack-traces to '
+          'receive more detailed exceptions.\n'
           "For example, 'pub run test --chain-stack-traces'.");
     }
 
     if (_printsOnFailure.isNotEmpty) {
-      print(_printsOnFailure.join("\n\n"));
+      print(_printsOnFailure.join('\n\n'));
       _printsOnFailure.clear();
     }
 
@@ -360,9 +369,9 @@
 
     _handleError(
         zone,
-        "This test failed after it had already completed. Make sure to use "
-        "[expectAsync]\n"
-        "or the [completes] matcher when testing async code.",
+        'This test failed after it had already completed. Make sure to use '
+        '[expectAsync]\n'
+        'or the [completes] matcher when testing async code.',
         stackTrace);
   }
 
@@ -386,8 +395,7 @@
           // corresponding [onStateChange], which violates the timing
           // guarantees.
           //
-          // Using [new Future] also avoids starving the DOM or other
-          // microtask-level events.
+          // Use the event loop over the microtask queue to avoid starvation.
           unawaited(Future(() async {
             await _test._body();
             await unclosable(_runTearDowns);
@@ -399,7 +407,7 @@
 
           if (liveTest.state.result != Result.success &&
               _runCount < liveTest.test.metadata.retry + 1) {
-            _controller.message(Message.print("Retry: ${liveTest.test.name}"));
+            _controller.message(Message.print('Retry: ${liveTest.test.name}'));
             _onRun();
             return;
           }
diff --git a/test_api/lib/src/backend/live_test.dart b/test_api/lib/src/backend/live_test.dart
index ca5a260..875b4d6 100644
--- a/test_api/lib/src/backend/live_test.dart
+++ b/test_api/lib/src/backend/live_test.dart
@@ -109,7 +109,7 @@
 
     // The test will have the same name as the group for virtual tests created
     // to represent skipping the entire group.
-    if (test.name.length == group.name.length) return "";
+    if (test.name.length == group.name.length) return '';
 
     return test.name.substring(group.name.length + 1);
   }
diff --git a/test_api/lib/src/backend/live_test_controller.dart b/test_api/lib/src/backend/live_test_controller.dart
index c8a6671..0aad846 100644
--- a/test_api/lib/src/backend/live_test_controller.dart
+++ b/test_api/lib/src/backend/live_test_controller.dart
@@ -18,27 +18,38 @@
 class _LiveTest extends LiveTest {
   final LiveTestController _controller;
 
+  @override
   Suite get suite => _controller._suite;
 
+  @override
   List<Group> get groups => _controller._groups;
 
+  @override
   Test get test => _controller._test;
 
+  @override
   State get state => _controller._state;
 
+  @override
   Stream<State> get onStateChange =>
       _controller._onStateChangeController.stream;
 
+  @override
   List<AsyncError> get errors => UnmodifiableListView(_controller._errors);
 
+  @override
   Stream<AsyncError> get onError => _controller._onErrorController.stream;
 
+  @override
   Stream<Message> get onMessage => _controller._onMessageController.stream;
 
+  @override
   Future<void> get onComplete => _controller.onComplete;
 
+  @override
   Future<void> run() => _controller._run();
 
+  @override
   Future<void> close() => _controller._close();
 
   _LiveTest(this._controller);
@@ -76,7 +87,7 @@
   final Function _onClose;
 
   /// The list of errors caught by the test.
-  final _errors = List<AsyncError>();
+  final _errors = <AsyncError>[];
 
   /// The current state of the test.
   var _state = const State(Status.pending, Result.success);
@@ -125,7 +136,8 @@
   ///
   /// If [groups] is passed, it's used to populate the list of groups that
   /// contain this test. Otherwise, `suite.group` is used.
-  LiveTestController(Suite suite, this._test, void onRun(), void onClose(),
+  LiveTestController(
+      Suite suite, this._test, void Function() onRun, void Function() onClose,
       {Iterable<Group> groups})
       : _suite = suite,
         _onRun = onRun,
@@ -175,10 +187,10 @@
   /// [LiveTest.run].
   Future<void> _run() {
     if (_runCalled) {
-      throw StateError("LiveTest.run() may not be called more than once.");
+      throw StateError('LiveTest.run() may not be called more than once.');
     } else if (_isClosed) {
-      throw StateError("LiveTest.run() may not be called for a closed "
-          "test.");
+      throw StateError('LiveTest.run() may not be called for a closed '
+          'test.');
     }
     _runCalled = true;
 
diff --git a/test_api/lib/src/backend/message.dart b/test_api/lib/src/backend/message.dart
index 3c24c52..efe152f 100644
--- a/test_api/lib/src/backend/message.dart
+++ b/test_api/lib/src/backend/message.dart
@@ -20,19 +20,19 @@
 
 class MessageType {
   /// A message explicitly printed by the user's test.
-  static const print = MessageType._("print");
+  static const print = MessageType._('print');
 
   /// A message indicating that a test, or some portion of one, was skipped.
-  static const skip = MessageType._("skip");
+  static const skip = MessageType._('skip');
 
   /// The name of the message type.
   final String name;
 
   factory MessageType.parse(String name) {
     switch (name) {
-      case "print":
+      case 'print':
         return MessageType.print;
-      case "skip":
+      case 'skip':
         return MessageType.skip;
       default:
         throw ArgumentError('Invalid message type "$name".');
@@ -41,5 +41,6 @@
 
   const MessageType._(this.name);
 
+  @override
   String toString() => name;
 }
diff --git a/test_api/lib/src/backend/metadata.dart b/test_api/lib/src/backend/metadata.dart
index fc4dbba..a020abc 100644
--- a/test_api/lib/src/backend/metadata.dart
+++ b/test_api/lib/src/backend/metadata.dart
@@ -100,7 +100,7 @@
                 '"$platform".');
           }
 
-          skip = metadatum.reason == null ? true : metadatum.reason;
+          skip = metadatum.reason ?? true;
         } else {
           throw ArgumentError('Metadata for platform "$platform" must be a '
               'Timeout, Skip, or List of those; was "$metadata".');
@@ -116,15 +116,15 @@
   ///
   /// Throws an [ArgumentError] if [tags] is not a [String] or an [Iterable].
   static Set<String> _parseTags(tags) {
-    if (tags == null) return Set();
-    if (tags is String) return Set.from([tags]);
+    if (tags == null) return {};
+    if (tags is String) return {tags};
     if (tags is! Iterable) {
       throw ArgumentError.value(
-          tags, "tags", "must be either a String or an Iterable.");
+          tags, 'tags', 'must be either a String or an Iterable.');
     }
 
     if ((tags as Iterable).any((tag) => tag is! String)) {
-      throw ArgumentError.value(tags, "tags", "must contain only Strings.");
+      throw ArgumentError.value(tags, 'tags', 'must contain only Strings.');
     }
 
     return Set.from(tags as Iterable);
@@ -149,7 +149,7 @@
       Map<PlatformSelector, Metadata> onPlatform,
       Map<BooleanSelector, Metadata> forTag}) {
     // Returns metadata without forTag resolved at all.
-    _unresolved() => Metadata._(
+    Metadata _unresolved() => Metadata._(
         testOn: testOn,
         timeout: timeout,
         skip: skip,
@@ -172,7 +172,7 @@
     // doing it for every test individually.
     var empty = Metadata._();
     var merged = forTag.keys.toList().fold(empty, (Metadata merged, selector) {
-      if (!selector.evaluate(tags)) return merged;
+      if (!selector.evaluate(tags.contains)) return merged;
       return merged.merge(forTag.remove(selector));
     });
 
@@ -194,17 +194,17 @@
       Iterable<String> tags,
       Map<PlatformSelector, Metadata> onPlatform,
       Map<BooleanSelector, Metadata> forTag})
-      : testOn = testOn == null ? PlatformSelector.all : testOn,
-        timeout = timeout == null ? const Timeout.factor(1) : timeout,
+      : testOn = testOn ?? PlatformSelector.all,
+        timeout = timeout ?? const Timeout.factor(1),
         _skip = skip,
         _verboseTrace = verboseTrace,
         _chainStackTraces = chainStackTraces,
         _retry = retry,
-        tags = UnmodifiableSetView(tags == null ? Set() : tags.toSet()),
+        tags = UnmodifiableSetView(tags == null ? {} : tags.toSet()),
         onPlatform =
             onPlatform == null ? const {} : UnmodifiableMapView(onPlatform),
         forTag = forTag == null ? const {} : UnmodifiableMapView(forTag) {
-    if (retry != null) RangeError.checkNotNegative(retry, "retry");
+    if (retry != null) RangeError.checkNotNegative(retry, 'retry');
     _validateTags();
   }
 
@@ -224,7 +224,7 @@
       : testOn = testOn == null
             ? PlatformSelector.all
             : PlatformSelector.parse(testOn),
-        timeout = timeout == null ? const Timeout.factor(1) : timeout,
+        timeout = timeout ?? const Timeout.factor(1),
         _skip = skip == null ? null : skip != false,
         _verboseTrace = verboseTrace,
         _chainStackTraces = chainStackTraces,
@@ -237,7 +237,7 @@
       throw ArgumentError('"skip" must be a String or a bool, was "$skip".');
     }
 
-    if (retry != null) RangeError.checkNotNegative(retry, "retry");
+    if (retry != null) RangeError.checkNotNegative(retry, 'retry');
 
     _validateTags();
   }
@@ -254,9 +254,11 @@
         _chainStackTraces = serialized['chainStackTraces'] as bool,
         _retry = serialized['retry'] as int,
         tags = Set.from(serialized['tags'] as Iterable),
-        onPlatform = Map.fromIterable(serialized['onPlatform'] as Iterable,
-            key: (pair) => PlatformSelector.parse(pair.first as String),
-            value: (pair) => Metadata.deserialize(pair.last)),
+        onPlatform = {
+          for (var pair in serialized['onPlatform'])
+            PlatformSelector.parse(pair.first as String):
+                Metadata.deserialize(pair.last)
+        },
         forTag = (serialized['forTag'] as Map).map((key, nested) => MapEntry(
             BooleanSelector.parse(key as String),
             Metadata.deserialize(nested)));
@@ -280,8 +282,8 @@
     if (invalidTags.isEmpty) return;
 
     throw ArgumentError("Invalid ${pluralize('tag', invalidTags.length)} "
-        "${toSentence(invalidTags)}. Tags must be (optionally hyphenated) "
-        "Dart identifiers.");
+        '${toSentence(invalidTags)}. Tags must be (optionally hyphenated) '
+        'Dart identifiers.');
   }
 
   /// Throws a [FormatException] if any [PlatformSelector]s use any variables
@@ -328,10 +330,10 @@
       Map<BooleanSelector, Metadata> forTag}) {
     testOn ??= this.testOn;
     timeout ??= this.timeout;
-    skip ??= this._skip;
-    verboseTrace ??= this._verboseTrace;
-    chainStackTraces ??= this._chainStackTraces;
-    retry ??= this._retry;
+    skip ??= _skip;
+    verboseTrace ??= _verboseTrace;
+    chainStackTraces ??= _chainStackTraces;
+    retry ??= _retry;
     skipReason ??= this.skipReason;
     onPlatform ??= this.onPlatform;
     tags ??= this.tags;
@@ -363,8 +365,8 @@
   }
 
   /// Serializes [this] into a JSON-safe object that can be deserialized using
-  /// [new Metadata.deserialize].
-  serialize() {
+  /// [Metadata.deserialize].
+  Map<String, dynamic> serialize() {
     // Make this a list to guarantee that the order is preserved.
     var serializedOnPlatform = [];
     onPlatform.forEach((key, value) {
@@ -387,7 +389,7 @@
   }
 
   /// Serializes timeout into a JSON-safe object.
-  _serializeTimeout(Timeout timeout) {
+  dynamic _serializeTimeout(Timeout timeout) {
     if (timeout == Timeout.none) return 'none';
     return {
       'duration':
diff --git a/test_api/lib/src/backend/operating_system.dart b/test_api/lib/src/backend/operating_system.dart
index b914e64..f2b7639 100644
--- a/test_api/lib/src/backend/operating_system.dart
+++ b/test_api/lib/src/backend/operating_system.dart
@@ -9,31 +9,31 @@
 /// running the test runner.
 class OperatingSystem {
   /// Microsoft Windows.
-  static const windows = OperatingSystem._("Windows", "windows");
+  static const windows = OperatingSystem._('Windows', 'windows');
 
   /// Mac OS X.
-  static const macOS = OperatingSystem._("OS X", "mac-os");
+  static const macOS = OperatingSystem._('OS X', 'mac-os');
 
   /// GNU/Linux.
-  static const linux = OperatingSystem._("Linux", "linux");
+  static const linux = OperatingSystem._('Linux', 'linux');
 
   /// Android.
   ///
   /// Since this is the operating system the test runner is running on, this
   /// won't be true when testing remotely on an Android browser.
-  static const android = OperatingSystem._("Android", "android");
+  static const android = OperatingSystem._('Android', 'android');
 
   /// iOS.
   ///
   /// Since this is the operating system the test runner is running on, this
   /// won't be true when testing remotely on an iOS browser.
-  static const iOS = OperatingSystem._("iOS", "ios");
+  static const iOS = OperatingSystem._('iOS', 'ios');
 
   /// No operating system.
   ///
   /// This is used when running in the browser, or if an unrecognized operating
   /// system is used. It can't be referenced by name in platform selectors.
-  static const none = OperatingSystem._("none", "none");
+  static const none = OperatingSystem._('none', 'none');
 
   /// A list of all instances of [OperatingSystem] other than [none].
   static const all = [windows, macOS, linux, android, iOS];
@@ -51,15 +51,15 @@
   /// If no operating system is found, returns [none].
   static OperatingSystem findByIoName(String name) {
     switch (name) {
-      case "windows":
+      case 'windows':
         return windows;
-      case "macos":
+      case 'macos':
         return macOS;
-      case "linux":
+      case 'linux':
         return linux;
-      case "android":
+      case 'android':
         return android;
-      case "ios":
+      case 'ios':
         return iOS;
       default:
         return none;
@@ -77,5 +77,6 @@
 
   const OperatingSystem._(this.name, this.identifier);
 
+  @override
   String toString() => name;
 }
diff --git a/test_api/lib/src/backend/platform_selector.dart b/test_api/lib/src/backend/platform_selector.dart
index 8fd956f..f2ab5a9 100644
--- a/test_api/lib/src/backend/platform_selector.dart
+++ b/test_api/lib/src/backend/platform_selector.dart
@@ -10,10 +10,16 @@
 import 'suite_platform.dart';
 
 /// The set of variable names that are valid for all platform selectors.
-final _universalValidVariables =
-    Set<String>.from(["posix", "dart-vm", "browser", "js", "blink", "google"])
-      ..addAll(Runtime.builtIn.map((runtime) => runtime.identifier))
-      ..addAll(OperatingSystem.all.map((os) => os.identifier));
+final _universalValidVariables = {
+  'posix',
+  'dart-vm',
+  'browser',
+  'js',
+  'blink',
+  'google',
+  for (var runtime in Runtime.builtIn) runtime.identifier,
+  for (var os in OperatingSystem.all) os.identifier,
+};
 
 /// An expression for selecting certain platforms, including operating systems
 /// and browsers.
@@ -46,7 +52,7 @@
   /// [SourceSpanFormatException] using [span].
   ///
   /// If [span] is `null`, runs [body] as-is.
-  static T _wrapFormatException<T>(T body(), SourceSpan span) {
+  static T _wrapFormatException<T>(T Function() body, SourceSpan span) {
     if (span == null) return body();
 
     try {
@@ -78,17 +84,17 @@
       if (variable == platform.runtime.parent?.identifier) return true;
       if (variable == platform.os.identifier) return true;
       switch (variable) {
-        case "dart-vm":
+        case 'dart-vm':
           return platform.runtime.isDartVM;
-        case "browser":
+        case 'browser':
           return platform.runtime.isBrowser;
-        case "js":
+        case 'js':
           return platform.runtime.isJS;
-        case "blink":
+        case 'blink':
           return platform.runtime.isBlink;
-        case "posix":
+        case 'posix':
           return platform.os.isPosix;
-        case "google":
+        case 'google':
           return platform.inGoogle;
         default:
           return false;
@@ -103,10 +109,13 @@
     return PlatformSelector._(_inner.intersection(other._inner));
   }
 
+  @override
   String toString() => _inner.toString();
 
+  @override
   bool operator ==(other) =>
       other is PlatformSelector && _inner == other._inner;
 
+  @override
   int get hashCode => _inner.hashCode;
 }
diff --git a/test_api/lib/src/backend/runtime.dart b/test_api/lib/src/backend/runtime.dart
index 4236a8f..380be9c 100644
--- a/test_api/lib/src/backend/runtime.dart
+++ b/test_api/lib/src/backend/runtime.dart
@@ -8,30 +8,30 @@
   // variable tests in test/backend/platform_selector/evaluate_test.
 
   /// The command-line Dart VM.
-  static const Runtime vm = Runtime("VM", "vm", isDartVM: true);
+  static const Runtime vm = Runtime('VM', 'vm', isDartVM: true);
 
   /// Google Chrome.
   static const Runtime chrome =
-      Runtime("Chrome", "chrome", isBrowser: true, isJS: true, isBlink: true);
+      Runtime('Chrome', 'chrome', isBrowser: true, isJS: true, isBlink: true);
 
   /// PhantomJS.
-  static const Runtime phantomJS = Runtime("PhantomJS", "phantomjs",
+  static const Runtime phantomJS = Runtime('PhantomJS', 'phantomjs',
       isBrowser: true, isJS: true, isBlink: true, isHeadless: true);
 
   /// Mozilla Firefox.
   static const Runtime firefox =
-      Runtime("Firefox", "firefox", isBrowser: true, isJS: true);
+      Runtime('Firefox', 'firefox', isBrowser: true, isJS: true);
 
   /// Apple Safari.
   static const Runtime safari =
-      Runtime("Safari", "safari", isBrowser: true, isJS: true);
+      Runtime('Safari', 'safari', isBrowser: true, isJS: true);
 
   /// Microsoft Internet Explorer.
   static const Runtime internetExplorer =
-      Runtime("Internet Explorer", "ie", isBrowser: true, isJS: true);
+      Runtime('Internet Explorer', 'ie', isBrowser: true, isJS: true);
 
   /// The command-line Node.js VM.
-  static const Runtime nodeJS = Runtime("Node.js", "node", isJS: true);
+  static const Runtime nodeJS = Runtime('Node.js', 'node', isJS: true);
 
   /// The platforms that are supported by the test runner by default.
   static const List<Runtime> builtIn = [
@@ -102,45 +102,45 @@
     }
 
     var map = serialized as Map;
-    var parent = map["parent"];
+    var parent = map['parent'];
     if (parent != null) {
       // Note that the returned platform's [parent] won't necessarily be `==` to
       // a separately-deserialized parent platform. This should be fine, though,
       // since we only deserialize platforms in the remote execution context
       // where they're only used to evaluate platform selectors.
-      return Runtime._child(map["name"] as String, map["identifier"] as String,
+      return Runtime._child(map['name'] as String, map['identifier'] as String,
           Runtime.deserialize(parent));
     }
 
-    return Runtime(map["name"] as String, map["identifier"] as String,
-        isDartVM: map["isDartVM"] as bool,
-        isBrowser: map["isBrowser"] as bool,
-        isJS: map["isJS"] as bool,
-        isBlink: map["isBlink"] as bool,
-        isHeadless: map["isHeadless"] as bool);
+    return Runtime(map['name'] as String, map['identifier'] as String,
+        isDartVM: map['isDartVM'] as bool,
+        isBrowser: map['isBrowser'] as bool,
+        isJS: map['isJS'] as bool,
+        isBlink: map['isBlink'] as bool,
+        isHeadless: map['isHeadless'] as bool);
   }
 
   /// Converts [this] into a JSON-safe object that can be converted back to a
-  /// [Runtime] using [new Runtime.deserialize].
+  /// [Runtime] using [Runtime.deserialize].
   Object serialize() {
     if (builtIn.contains(this)) return identifier;
 
     if (parent != null) {
       return {
-        "name": name,
-        "identifier": identifier,
-        "parent": parent.serialize()
+        'name': name,
+        'identifier': identifier,
+        'parent': parent.serialize()
       };
     }
 
     return {
-      "name": name,
-      "identifier": identifier,
-      "isDartVM": isDartVM,
-      "isBrowser": isBrowser,
-      "isJS": isJS,
-      "isBlink": isBlink,
-      "isHeadless": isHeadless
+      'name': name,
+      'identifier': identifier,
+      'isDartVM': isDartVM,
+      'isBrowser': isBrowser,
+      'isJS': isJS,
+      'isBlink': isBlink,
+      'isHeadless': isHeadless
     };
   }
 
@@ -150,8 +150,9 @@
   /// This may not be called on a platform that's already a child.
   Runtime extend(String name, String identifier) {
     if (parent == null) return Runtime._child(name, identifier, this);
-    throw StateError("A child platform may not be extended.");
+    throw StateError('A child platform may not be extended.');
   }
 
+  @override
   String toString() => name;
 }
diff --git a/test_api/lib/src/backend/stack_trace_formatter.dart b/test_api/lib/src/backend/stack_trace_formatter.dart
index 62d5243..2bb897e 100644
--- a/test_api/lib/src/backend/stack_trace_formatter.dart
+++ b/test_api/lib/src/backend/stack_trace_formatter.dart
@@ -22,12 +22,12 @@
   /// as-is.
   StackTraceMapper _mapper;
 
-  /// The list of packages to fold when producing terse [Chain]s.
-  var _except = Set<String>.from(['test', 'stream_channel', 'test_api']);
+  /// The set of packages to fold when producing terse [Chain]s.
+  var _except = {'test', 'stream_channel', 'test_api'};
 
   /// If non-empty, all packages not in this list will be folded when producing
   /// terse [Chain]s.
-  var _only = Set<String>();
+  var _only = <String>{};
 
   /// Returns the current manager, or `null` if this isn't called within a call
   /// to [asCurrent].
@@ -38,7 +38,8 @@
   ///
   /// This is zone-scoped, so [this] will be the current configuration in any
   /// asynchronous callbacks transitively created by [body].
-  T asCurrent<T>(T body()) => runZoned(body, zoneValues: {_currentKey: this});
+  T asCurrent<T>(T Function() body) =>
+      runZoned(body, zoneValues: {_currentKey: this});
 
   /// Configure how stack traces are formatted.
   ///
diff --git a/test_api/lib/src/backend/state.dart b/test_api/lib/src/backend/state.dart
index 3151c1b..ba82cd0 100644
--- a/test_api/lib/src/backend/state.dart
+++ b/test_api/lib/src/backend/state.dart
@@ -27,26 +27,29 @@
 
   const State(this.status, this.result);
 
+  @override
   bool operator ==(other) =>
       other is State && status == other.status && result == other.result;
 
+  @override
   int get hashCode => status.hashCode ^ (7 * result.hashCode);
 
+  @override
   String toString() {
-    if (status == Status.pending) return "pending";
+    if (status == Status.pending) return 'pending';
     if (status == Status.complete) return result.toString();
-    if (result == Result.success) return "running";
-    return "running with $result";
+    if (result == Result.success) return 'running';
+    return 'running with $result';
   }
 }
 
 /// Where the test is in its process of running.
 class Status {
   /// The test has not yet begun running.
-  static const pending = Status._("pending");
+  static const pending = Status._('pending');
 
   /// The test is currently running.
-  static const running = Status._("running");
+  static const running = Status._('running');
 
   /// The test has finished running.
   ///
@@ -55,18 +58,18 @@
   /// first error or when all [expectAsync] callbacks have been called and any
   /// returned [Future] has completed, but it's possible for further processing
   /// to happen, which may cause further errors.
-  static const complete = Status._("complete");
+  static const complete = Status._('complete');
 
   /// The name of the status.
   final String name;
 
   factory Status.parse(String name) {
     switch (name) {
-      case "pending":
+      case 'pending':
         return Status.pending;
-      case "running":
+      case 'running':
         return Status.running;
-      case "complete":
+      case 'complete':
         return Status.complete;
       default:
         throw ArgumentError('Invalid status name "$name".');
@@ -75,6 +78,7 @@
 
   const Status._(this.name);
 
+  @override
   String toString() => name;
 }
 
@@ -83,24 +87,24 @@
   /// The test has not yet failed in any way.
   ///
   /// Note that this doesn't mean that the test won't fail in the future.
-  static const success = Result._("success");
+  static const success = Result._('success');
 
   /// The test, or some part of it, has been skipped.
   ///
   /// This implies that the test hasn't failed *yet*. However, it this doesn't
   /// mean that the test won't fail in the future.
-  static const skipped = Result._("skipped");
+  static const skipped = Result._('skipped');
 
   /// The test has failed.
   ///
   /// A failure is specifically caused by a [TestFailure] being thrown; any
   /// other exception causes an error.
-  static const failure = Result._("failure");
+  static const failure = Result._('failure');
 
   /// The test has crashed.
   ///
   /// Any exception other than a [TestFailure] is considered to be an error.
-  static const error = Result._("error");
+  static const error = Result._('error');
 
   /// The name of the result.
   final String name;
@@ -119,13 +123,13 @@
 
   factory Result.parse(String name) {
     switch (name) {
-      case "success":
+      case 'success':
         return Result.success;
-      case "skipped":
+      case 'skipped':
         return Result.skipped;
-      case "failure":
+      case 'failure':
         return Result.failure;
-      case "error":
+      case 'error':
         return Result.error;
       default:
         throw ArgumentError('Invalid result name "$name".');
@@ -134,5 +138,6 @@
 
   const Result._(this.name);
 
+  @override
   String toString() => name;
 }
diff --git a/test_api/lib/src/backend/suite.dart b/test_api/lib/src/backend/suite.dart
index 2a1a13f..695d305 100644
--- a/test_api/lib/src/backend/suite.dart
+++ b/test_api/lib/src/backend/suite.dart
@@ -48,9 +48,9 @@
   ///
   /// Unlike [GroupEntry.filter], this never returns `null`. If all entries are
   /// filtered out, it returns an empty suite.
-  Suite filter(bool callback(Test test)) {
+  Suite filter(bool Function(Test) callback) {
     var filtered = group.filter(callback);
-    if (filtered == null) filtered = Group.root([], metadata: metadata);
+    filtered ??= Group.root([], metadata: metadata);
     return Suite(filtered, platform, path: path);
   }
 
diff --git a/test_api/lib/src/backend/suite_platform.dart b/test_api/lib/src/backend/suite_platform.dart
index 1f049eb..5f80997 100644
--- a/test_api/lib/src/backend/suite_platform.dart
+++ b/test_api/lib/src/backend/suite_platform.dart
@@ -41,7 +41,7 @@
   }
 
   /// Converts [this] into a JSON-safe object that can be converted back to a
-  /// [SuitePlatform] using [new SuitePlatform.deserialize].
+  /// [SuitePlatform] using [SuitePlatform.deserialize].
   Object serialize() => {
         'runtime': runtime.serialize(),
         'os': os.identifier,
diff --git a/test_api/lib/src/backend/test.dart b/test_api/lib/src/backend/test.dart
index 07df8c3..870f5e1 100644
--- a/test_api/lib/src/backend/test.dart
+++ b/test_api/lib/src/backend/test.dart
@@ -17,10 +17,13 @@
 /// directly. To run one, load a live version using [Test.load] and run it using
 /// [LiveTest.run].
 abstract class Test implements GroupEntry {
+  @override
   String get name;
 
+  @override
   Metadata get metadata;
 
+  @override
   Trace get trace;
 
   /// Loads a live version of this test, which can be used to run it a single
@@ -31,7 +34,9 @@
   /// defaults to just containing `suite.group`.
   LiveTest load(Suite suite, {Iterable<Group> groups});
 
+  @override
   Test forPlatform(SuitePlatform platform);
 
-  Test filter(bool callback(Test test)) => callback(this) ? this : null;
+  @override
+  Test filter(bool Function(Test) callback) => callback(this) ? this : null;
 }
diff --git a/test_api/lib/src/frontend/async_matcher.dart b/test_api/lib/src/frontend/async_matcher.dart
index e2c544e..e956aec 100644
--- a/test_api/lib/src/frontend/async_matcher.dart
+++ b/test_api/lib/src/frontend/async_matcher.dart
@@ -27,13 +27,14 @@
   ///
   /// If this returns a [String] synchronously, [expect] will synchronously
   /// throw a [TestFailure] and [matches] will synchronusly return `false`.
-  /*FutureOr<String>*/ matchAsync(item);
+  dynamic /*FutureOr<String>*/ matchAsync(item);
 
+  @override
   bool matches(item, Map matchState) {
     var result = matchAsync(item);
     expect(result,
         anyOf([equals(null), TypeMatcher<Future>(), TypeMatcher<String>()]),
-        reason: "matchAsync() may only return a String, a Future, or null.");
+        reason: 'matchAsync() may only return a String, a Future, or null.');
 
     if (result is Future) {
       Invoker.current.addOutstandingCallback();
@@ -51,6 +52,7 @@
     return true;
   }
 
+  @override
   Description describeMismatch(
           item, Description description, Map matchState, bool verbose) =>
       StringDescription(matchState[this] as String);
diff --git a/test_api/lib/src/frontend/expect.dart b/test_api/lib/src/frontend/expect.dart
index 7fcd503..b69dc2f 100644
--- a/test_api/lib/src/frontend/expect.dart
+++ b/test_api/lib/src/frontend/expect.dart
@@ -18,12 +18,13 @@
 
   TestFailure(this.message);
 
+  @override
   String toString() => message;
 }
 
 /// The type used for functions that can be used to build up error reports
 /// upon failures in [expect].
-@Deprecated("Will be removed in 0.13.0.")
+@Deprecated('Will be removed in 0.13.0.')
 typedef ErrorFormatter = String Function(dynamic actual, Matcher matcher,
     String reason, Map matchState, bool verbose);
 
@@ -54,8 +55,8 @@
 void expect(actual, matcher,
     {String reason,
     skip,
-    @Deprecated("Will be removed in 0.13.0.") bool verbose = false,
-    @Deprecated("Will be removed in 0.13.0.") ErrorFormatter formatter}) {
+    @Deprecated('Will be removed in 0.13.0.') bool verbose = false,
+    @Deprecated('Will be removed in 0.13.0.') ErrorFormatter formatter}) {
   _expect(actual, matcher,
       reason: reason, skip: skip, verbose: verbose, formatter: formatter);
 }
@@ -86,25 +87,25 @@
   };
 
   if (Invoker.current == null) {
-    throw StateError("expect() may only be called within a test.");
+    throw StateError('expect() may only be called within a test.');
   }
 
   if (Invoker.current.closed) throw ClosedException();
 
   if (skip != null && skip is! bool && skip is! String) {
-    throw ArgumentError.value(skip, "skip", "must be a bool or a String");
+    throw ArgumentError.value(skip, 'skip', 'must be a bool or a String');
   }
 
   matcher = wrapMatcher(matcher);
   if (skip != null && skip != false) {
     String message;
     if (skip is String) {
-      message = "Skip expect: $skip";
+      message = 'Skip expect: $skip';
     } else if (reason != null) {
-      message = "Skip expect ($reason).";
+      message = 'Skip expect ($reason).';
     } else {
       var description = StringDescription().addDescriptionOf(matcher);
-      message = "Skip expect ($description).";
+      message = 'Skip expect ($description).';
     }
 
     Invoker.current.skip(message);
@@ -116,7 +117,7 @@
     var result = matcher.matchAsync(actual);
     expect(result,
         anyOf([equals(null), TypeMatcher<Future>(), TypeMatcher<String>()]),
-        reason: "matchAsync() may only return a String, a Future, or null.");
+        reason: 'matchAsync() may only return a String, a Future, or null.');
 
     if (result is String) {
       fail(formatFailure(matcher as Matcher, actual, result, reason: reason));
@@ -153,7 +154,7 @@
 Null fail(String message) => throw TestFailure(message);
 
 // The default error formatter.
-@Deprecated("Will be removed in 0.13.0.")
+@Deprecated('Will be removed in 0.13.0.')
 String formatFailure(Matcher expected, actual, String which, {String reason}) {
   var buffer = StringBuffer();
   buffer.writeln(indent(prettyPrint(expected), first: 'Expected: '));
diff --git a/test_api/lib/src/frontend/expect_async.dart b/test_api/lib/src/frontend/expect_async.dart
index 07d408c..10abf03 100644
--- a/test_api/lib/src/frontend/expect_async.dart
+++ b/test_api/lib/src/frontend/expect_async.dart
@@ -18,20 +18,6 @@
 typedef Func5<T, A, B, C, D, E> = T Function([A a, B b, C c, D d, E e]);
 typedef Func6<T, A, B, C, D, E, F> = T Function([A a, B b, C c, D d, E e, F f]);
 
-// Functions used to check how many arguments a callback takes. We can't use the
-// previous functions for this, because (a) {} is not a subtype of
-// ([dynamic]) -> dynamic.
-
-typedef _Func0 = Function();
-typedef _Func1 = Function(Null a);
-typedef _Func2 = Function(Null a, Null b);
-typedef _Func3 = Function(Null a, Null b, Null c);
-typedef _Func4 = Function(Null a, Null b, Null c, Null d);
-typedef _Func5 = Function(Null a, Null b, Null c, Null d, Null e);
-typedef _Func6 = Function(Null a, Null b, Null c, Null d, Null e, Null f);
-
-typedef _IsDoneCallback = bool Function();
-
 /// A wrapper for a function that ensures that it's called the appropriate
 /// number of times.
 ///
@@ -62,7 +48,7 @@
   ///
   /// This may be `null`. If so, the function is considered to be done after
   /// it's been run once.
-  final _IsDoneCallback _isDone;
+  final bool Function() _isDone;
 
   /// A descriptive name for the function.
   final String _id;
@@ -91,20 +77,20 @@
   /// as a reason it's expected to be called. If [isDone] is passed, the test
   /// won't be allowed to complete until it returns `true`.
   _ExpectedFunction(Function callback, int minExpected, int maxExpected,
-      {String id, String reason, bool isDone()})
-      : this._callback = callback,
+      {String id, String reason, bool Function() isDone})
+      : _callback = callback,
         _minExpectedCalls = minExpected,
         _maxExpectedCalls =
             (maxExpected == 0 && minExpected > 0) ? minExpected : maxExpected,
-        this._isDone = isDone,
-        this._reason = reason == null ? '' : '\n$reason',
-        this._zone = Zone.current,
-        this._id = _makeCallbackId(id, callback) {
+        _isDone = isDone,
+        _reason = reason == null ? '' : '\n$reason',
+        _zone = Zone.current,
+        _id = _makeCallbackId(id, callback) {
     if (_invoker == null) {
-      throw StateError("[expectAsync] was called outside of a test.");
+      throw StateError('[expectAsync] was called outside of a test.');
     } else if (maxExpected > 0 && minExpected > maxExpected) {
-      throw ArgumentError("max ($maxExpected) may not be less than count "
-          "($minExpected).");
+      throw ArgumentError('max ($maxExpected) may not be less than count '
+          '($minExpected).');
     }
 
     if (isDone != null || minExpected > 0) {
@@ -120,7 +106,7 @@
   /// If [id] is passed, uses that. Otherwise, tries to determine a name from
   /// calling `toString`. If no name can be found, returns the empty string.
   static String _makeCallbackId(String id, Function callback) {
-    if (id != null) return "$id ";
+    if (id != null) return '$id ';
 
     // If the callback is not an anonymous closure, try to get the
     // name.
@@ -132,19 +118,19 @@
     start += prefix.length;
     var end = toString.indexOf("'", start);
     if (end == -1) return '';
-    return "${toString.substring(start, end)} ";
+    return '${toString.substring(start, end)} ';
   }
 
   /// Returns a function that has the same number of positional arguments as the
   /// wrapped function (up to a total of 6).
   Function get func {
-    if (_callback is _Func6) return max6;
-    if (_callback is _Func5) return max5;
-    if (_callback is _Func4) return max4;
-    if (_callback is _Func3) return max3;
-    if (_callback is _Func2) return max2;
-    if (_callback is _Func1) return max1;
-    if (_callback is _Func0) return max0;
+    if (_callback is Function(Null, Null, Null, Null, Null Nulll)) return max6;
+    if (_callback is Function(Null, Null, Null, Null, Null)) return max5;
+    if (_callback is Function(Null, Null, Null, Null)) return max4;
+    if (_callback is Function(Null, Null, Null)) return max3;
+    if (_callback is Function(Null, Null)) return max2;
+    if (_callback is Function(Null)) return max1;
+    if (_callback is Function()) return max0;
 
     _invoker.removeOutstandingCallback();
     throw ArgumentError(
@@ -227,11 +213,11 @@
 /// Use [expectAsync0], [expectAsync1],
 /// [expectAsync2], [expectAsync3], [expectAsync4], [expectAsync5], or
 /// [expectAsync6] instead.
-@Deprecated("Will be removed in 0.13.0")
+@Deprecated('Will be removed in 0.13.0')
 Function expectAsync(Function callback,
     {int count = 1, int max = 0, String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsync() may only be called within a test.");
+    throw StateError('expectAsync() may only be called within a test.');
   }
 
   return _ExpectedFunction(callback, count, max, id: id, reason: reason).func;
@@ -258,10 +244,10 @@
 /// This method takes callbacks with zero arguments. See also
 /// [expectAsync1], [expectAsync2], [expectAsync3], [expectAsync4],
 /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func0<T> expectAsync0<T>(T callback(),
+Func0<T> expectAsync0<T>(T Function() callback,
     {int count = 1, int max = 0, String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsync0() may only be called within a test.");
+    throw StateError('expectAsync0() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -289,10 +275,10 @@
 /// This method takes callbacks with one argument. See also
 /// [expectAsync0], [expectAsync2], [expectAsync3], [expectAsync4],
 /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func1<T, A> expectAsync1<T, A>(T callback(A a),
+Func1<T, A> expectAsync1<T, A>(T Function(A) callback,
     {int count = 1, int max = 0, String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsync1() may only be called within a test.");
+    throw StateError('expectAsync1() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -320,10 +306,10 @@
 /// This method takes callbacks with two arguments. See also
 /// [expectAsync0], [expectAsync1], [expectAsync3], [expectAsync4],
 /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func2<T, A, B> expectAsync2<T, A, B>(T callback(A a, B b),
+Func2<T, A, B> expectAsync2<T, A, B>(T Function(A, B) callback,
     {int count = 1, int max = 0, String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsync2() may only be called within a test.");
+    throw StateError('expectAsync2() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -351,10 +337,10 @@
 /// This method takes callbacks with three arguments. See also
 /// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync4],
 /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func3<T, A, B, C> expectAsync3<T, A, B, C>(T callback(A a, B b, C c),
+Func3<T, A, B, C> expectAsync3<T, A, B, C>(T Function(A, B, C) callback,
     {int count = 1, int max = 0, String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsync3() may only be called within a test.");
+    throw StateError('expectAsync3() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -382,10 +368,14 @@
 /// This method takes callbacks with four arguments. See also
 /// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
 /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func4<T, A, B, C, D> expectAsync4<T, A, B, C, D>(T callback(A a, B b, C c, D d),
-    {int count = 1, int max = 0, String id, String reason}) {
+Func4<T, A, B, C, D> expectAsync4<T, A, B, C, D>(
+    T Function(A, B, C, D) callback,
+    {int count = 1,
+    int max = 0,
+    String id,
+    String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsync4() may only be called within a test.");
+    throw StateError('expectAsync4() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -414,13 +404,13 @@
 /// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
 /// [expectAsync4], and [expectAsync6] for callbacks with different arity.
 Func5<T, A, B, C, D, E> expectAsync5<T, A, B, C, D, E>(
-    T callback(A a, B b, C c, D d, E e),
+    T Function(A, B, C, D, E) callback,
     {int count = 1,
     int max = 0,
     String id,
     String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsync5() may only be called within a test.");
+    throw StateError('expectAsync5() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -449,13 +439,13 @@
 /// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
 /// [expectAsync4], and [expectAsync5] for callbacks with different arity.
 Func6<T, A, B, C, D, E, F> expectAsync6<T, A, B, C, D, E, F>(
-    T callback(A a, B b, C c, D d, E e, F f),
+    T Function(A, B, C, D, E, F) callback,
     {int count = 1,
     int max = 0,
     String id,
     String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsync6() may only be called within a test.");
+    throw StateError('expectAsync6() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -466,11 +456,11 @@
 /// Use [expectAsyncUntil0], [expectAsyncUntil1],
 /// [expectAsyncUntil2], [expectAsyncUntil3], [expectAsyncUntil4],
 /// [expectAsyncUntil5], or [expectAsyncUntil6] instead.
-@Deprecated("Will be removed in 0.13.0")
-Function expectAsyncUntil(Function callback, bool isDone(),
+@Deprecated('Will be removed in 0.13.0')
+Function expectAsyncUntil(Function callback, bool Function() isDone,
     {String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsyncUntil() may only be called within a test.");
+    throw StateError('expectAsyncUntil() may only be called within a test.');
   }
 
   return _ExpectedFunction(callback, 0, -1,
@@ -495,10 +485,10 @@
 /// [expectAsyncUntil1], [expectAsyncUntil2], [expectAsyncUntil3],
 /// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
 /// callbacks with different arity.
-Func0<T> expectAsyncUntil0<T>(T callback(), bool isDone(),
+Func0<T> expectAsyncUntil0<T>(T Function() callback, bool Function() isDone,
     {String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsyncUntil0() may only be called within a test.");
+    throw StateError('expectAsyncUntil0() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, 0, -1,
@@ -523,10 +513,11 @@
 /// [expectAsyncUntil0], [expectAsyncUntil2], [expectAsyncUntil3],
 /// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
 /// callbacks with different arity.
-Func1<T, A> expectAsyncUntil1<T, A>(T callback(A a), bool isDone(),
+Func1<T, A> expectAsyncUntil1<T, A>(
+    T Function(A) callback, bool Function() isDone,
     {String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsyncUntil1() may only be called within a test.");
+    throw StateError('expectAsyncUntil1() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, 0, -1,
@@ -551,10 +542,11 @@
 /// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil3],
 /// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
 /// callbacks with different arity.
-Func2<T, A, B> expectAsyncUntil2<T, A, B>(T callback(A a, B b), bool isDone(),
+Func2<T, A, B> expectAsyncUntil2<T, A, B>(
+    T Function(A, B) callback, bool Function() isDone,
     {String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsyncUntil2() may only be called within a test.");
+    throw StateError('expectAsyncUntil2() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, 0, -1,
@@ -580,10 +572,10 @@
 /// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
 /// callbacks with different arity.
 Func3<T, A, B, C> expectAsyncUntil3<T, A, B, C>(
-    T callback(A a, B b, C c), bool isDone(),
+    T Function(A, B, C) callback, bool Function() isDone,
     {String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsyncUntil3() may only be called within a test.");
+    throw StateError('expectAsyncUntil3() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, 0, -1,
@@ -609,10 +601,10 @@
 /// [expectAsyncUntil3], [expectAsyncUntil5], and [expectAsyncUntil6] for
 /// callbacks with different arity.
 Func4<T, A, B, C, D> expectAsyncUntil4<T, A, B, C, D>(
-    T callback(A a, B b, C c, D d), bool isDone(),
+    T Function(A, B, C, D) callback, bool Function() isDone,
     {String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsyncUntil4() may only be called within a test.");
+    throw StateError('expectAsyncUntil4() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, 0, -1,
@@ -638,10 +630,10 @@
 /// [expectAsyncUntil3], [expectAsyncUntil4], and [expectAsyncUntil6] for
 /// callbacks with different arity.
 Func5<T, A, B, C, D, E> expectAsyncUntil5<T, A, B, C, D, E>(
-    T callback(A a, B b, C c, D d, E e), bool isDone(),
+    T Function(A, B, C, D, E) callback, bool Function() isDone,
     {String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsyncUntil5() may only be called within a test.");
+    throw StateError('expectAsyncUntil5() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, 0, -1,
@@ -667,10 +659,10 @@
 /// [expectAsyncUntil3], [expectAsyncUntil4], and [expectAsyncUntil5] for
 /// callbacks with different arity.
 Func6<T, A, B, C, D, E, F> expectAsyncUntil6<T, A, B, C, D, E, F>(
-    T callback(A a, B b, C c, D d, E e, F f), bool isDone(),
+    T Function(A, B, C, D, E, F) callback, bool Function() isDone,
     {String id, String reason}) {
   if (Invoker.current == null) {
-    throw StateError("expectAsyncUntil() may only be called within a test.");
+    throw StateError('expectAsyncUntil() may only be called within a test.');
   }
 
   return _ExpectedFunction<T>(callback, 0, -1,
diff --git a/test_api/lib/src/frontend/future_matchers.dart b/test_api/lib/src/frontend/future_matchers.dart
index e9566c3..8117395 100644
--- a/test_api/lib/src/frontend/future_matchers.dart
+++ b/test_api/lib/src/frontend/future_matchers.dart
@@ -45,8 +45,9 @@
   const _Completes(this._matcher);
 
   // Avoid async/await so we synchronously start listening to [item].
-  /*FutureOr<String>*/ matchAsync(item) {
-    if (item is! Future) return "was not a Future";
+  @override
+  dynamic /*FutureOr<String>*/ matchAsync(item) {
+    if (item is! Future) return 'was not a Future';
 
     return item.then((value) async {
       if (_matcher == null) return null;
@@ -70,6 +71,7 @@
     });
   }
 
+  @override
   Description describe(Description description) {
     if (_matcher == null) {
       description.add('completes successfully');
@@ -90,11 +92,13 @@
 class _DoesNotComplete extends Matcher {
   const _DoesNotComplete();
 
+  @override
   Description describe(Description description) {
-    description.add("does not complete");
+    description.add('does not complete');
     return description;
   }
 
+  @override
   bool matches(item, Map matchState) {
     if (item is! Future) return false;
     item.then((value) {
@@ -105,9 +109,10 @@
     return true;
   }
 
+  @override
   Description describeMismatch(
       item, Description description, Map matchState, bool verbose) {
-    if (item is! Future) return description.add("$item is not a Future");
+    if (item is! Future) return description.add('$item is not a Future');
     return description;
   }
 }
diff --git a/test_api/lib/src/frontend/never_called.dart b/test_api/lib/src/frontend/never_called.dart
index 98bc314..0ea5351 100644
--- a/test_api/lib/src/frontend/never_called.dart
+++ b/test_api/lib/src/frontend/never_called.dart
@@ -57,10 +57,10 @@
 
     zone.handleUncaughtError(
         TestFailure(
-            "Callback should never have been called, but it was called with" +
+            'Callback should never have been called, but it was called with' +
                 (arguments.isEmpty
-                    ? " no arguments."
-                    : ":\n${bullet(arguments.map(prettyPrint))}")),
+                    ? ' no arguments.'
+                    : ':\n${bullet(arguments.map(prettyPrint))}')),
         zone.run(() => Chain.current()));
     return null;
   };
diff --git a/test_api/lib/src/frontend/prints_matcher.dart b/test_api/lib/src/frontend/prints_matcher.dart
index 5f0380e..48cf8a9 100644
--- a/test_api/lib/src/frontend/prints_matcher.dart
+++ b/test_api/lib/src/frontend/prints_matcher.dart
@@ -30,8 +30,9 @@
 
   // Avoid async/await so we synchronously fail if the function is
   // synchronous.
-  /*FutureOr<String>*/ matchAsync(item) {
-    if (item is! Function()) return "was not a unary Function";
+  @override
+  dynamic /*FutureOr<String>*/ matchAsync(item) {
+    if (item is! Function()) return 'was not a unary Function';
 
     var buffer = StringBuffer();
     var result = runZoned(item as Function(),
@@ -44,6 +45,7 @@
         : _check(buffer.toString());
   }
 
+  @override
   Description describe(Description description) =>
       description.add('prints ').addDescriptionOf(_matcher);
 
diff --git a/test_api/lib/src/frontend/spawn_hybrid.dart b/test_api/lib/src/frontend/spawn_hybrid.dart
index 46c9d68..1b0cde2 100644
--- a/test_api/lib/src/frontend/spawn_hybrid.dart
+++ b/test_api/lib/src/frontend/spawn_hybrid.dart
@@ -24,17 +24,17 @@
 // `hybridMain` can send any json encodeable type.
 final _transformer = StreamChannelTransformer<dynamic, dynamic>(
     StreamTransformer.fromHandlers(handleData: (message, sink) {
-  switch (message["type"] as String) {
-    case "data":
-      sink.add(message["data"]);
+  switch (message['type'] as String) {
+    case 'data':
+      sink.add(message['data']);
       break;
 
-    case "print":
-      print(message["line"]);
+    case 'print':
+      print(message['line']);
       break;
 
-    case "error":
-      var error = RemoteException.deserialize(message["error"]);
+    case 'error':
+      var error = RemoteException.deserialize(message['error']);
       sink.addError(error.error, error.stackTrace);
       break;
   }
@@ -98,12 +98,12 @@
   } else if (uri is String) {
     parsedUrl = Uri.parse(uri);
   } else {
-    throw ArgumentError.value(uri, "uri", "must be a Uri or a String.");
+    throw ArgumentError.value(uri, 'uri', 'must be a Uri or a String.');
   }
 
   String absoluteUri;
   if (parsedUrl.scheme.isEmpty) {
-    var isRootRelative = parsedUrl.path.startsWith("/");
+    var isRootRelative = parsedUrl.path.startsWith('/');
 
     // If we're running in a browser context, the working directory is already
     // relative to the test file, whereas on the VM the working directory is the
@@ -113,9 +113,9 @@
         // A root-relative URL is interpreted as relative to the package root,
         // which means placing it beneath the URL secret.
         var secret = Uri.encodeComponent(Uri.base.pathSegments[0]);
-        absoluteUri = p.absolute("/$secret$parsedUrl");
-        print("Uri.base: ${Uri.base}");
-        print("absoluteUri: ${absoluteUri}");
+        absoluteUri = p.absolute('/$secret$parsedUrl');
+        print('Uri.base: ${Uri.base}');
+        print('absoluteUri: ${absoluteUri}');
       } else {
         absoluteUri = p.absolute(parsedUrl.toString());
       }
@@ -192,8 +192,6 @@
 StreamChannel _spawn(String uri, Object message, {bool stayAlive = false}) {
   var channel = Zone.current[#test.runner.test_channel] as MultiChannel;
   if (channel == null) {
-    // TODO(nweiz): Link to an issue tracking support when running the test file
-    // directly.
     throw UnsupportedError("Can't connect to the test runner.\n"
         'spawnHybridUri() is currently only supported within "pub run test".');
   }
@@ -203,10 +201,10 @@
   var virtualChannel = channel.virtualChannel();
   StreamChannel isolateChannel = virtualChannel;
   channel.sink.add({
-    "type": "spawn-hybrid-uri",
-    "url": uri,
-    "message": message,
-    "channel": virtualChannel.id
+    'type': 'spawn-hybrid-uri',
+    'url': uri,
+    'message': message,
+    'channel': virtualChannel.id
   });
 
   if (!stayAlive) {
diff --git a/test_api/lib/src/frontend/stream_matcher.dart b/test_api/lib/src/frontend/stream_matcher.dart
index e37c5c6..b1b96e9 100644
--- a/test_api/lib/src/frontend/stream_matcher.dart
+++ b/test_api/lib/src/frontend/stream_matcher.dart
@@ -6,15 +6,11 @@
 
 import 'package:async/async.dart';
 import 'package:matcher/matcher.dart';
-import 'package:pedantic/pedantic.dart';
 
 import '../utils.dart';
 import 'async_matcher.dart';
 import 'format_stack_trace.dart';
 
-/// The type for [_StreamMatcher._matchQueue].
-typedef _MatchQueue = Future<String> Function(StreamQueue queue);
-
 /// A matcher that matches events from [Stream]s or [StreamQueue]s.
 ///
 /// Stream matchers are designed to make it straightforward to create complex
@@ -46,17 +42,17 @@
 /// at different times:
 ///
 /// ```dart
-/// var stdout = new StreamQueue(stdoutLineStream);
+/// var stdout = StreamQueue(stdoutLineStream);
 ///
 /// // Ignore lines from the process until it's about to emit the URL.
-/// await expect(stdout, emitsThrough("WebSocket URL:"));
+/// await expectLater(stdout, emitsThrough('WebSocket URL:'));
 ///
 /// // Parse the next line as a URL.
 /// var url = Uri.parse(await stdout.next);
 /// expect(url.host, equals('localhost'));
 ///
 /// // You can match against the same StreamQueue multiple times.
-/// await expect(stdout, emits("Waiting for connection..."));
+/// await expectLater(stdout, emits('Waiting for connection...'));
 /// ```
 ///
 /// Users can call [new StreamMatcher] to create custom matchers.
@@ -89,7 +85,7 @@
   /// should be grammatically valid when used after the word "should". For
   /// example, it might be "emit the right events".
   factory StreamMatcher(
-          Future<String> matchQueue(StreamQueue queue), String description) =
+          Future<String> Function(StreamQueue) matchQueue, String description) =
       _StreamMatcher;
 
   /// Tries to match events emitted by [queue].
@@ -116,23 +112,28 @@
 /// This is separate from the original type to hide the private [AsyncMatcher]
 /// interface.
 class _StreamMatcher extends AsyncMatcher implements StreamMatcher {
+  @override
   final String description;
 
   /// The callback used to implement [matchQueue].
-  final _MatchQueue _matchQueue;
+  final Future<String> Function(StreamQueue) _matchQueue;
 
   _StreamMatcher(this._matchQueue, this.description);
 
+  @override
   Future<String> matchQueue(StreamQueue queue) => _matchQueue(queue);
 
-  /*FutureOr<String>*/ matchAsync(item) {
+  @override
+  dynamic /*FutureOr<String>*/ matchAsync(item) {
     StreamQueue queue;
+    var shouldCancelQueue = false;
     if (item is StreamQueue) {
       queue = item;
     } else if (item is Stream) {
       queue = StreamQueue(item);
+      shouldCancelQueue = true;
     } else {
-      return "was not a Stream or a StreamQueue";
+      return 'was not a Stream or a StreamQueue';
     }
 
     // Avoid async/await in the outer method so that we synchronously error out
@@ -161,30 +162,34 @@
 
       var eventsString = events.map((event) {
         if (event == null) {
-          return "x Stream closed.";
+          return 'x Stream closed.';
         } else if (event.isValue) {
           return addBullet(event.asValue.value.toString());
         } else {
           var error = event.asError;
           var chain = formatStackTrace(error.stackTrace);
-          var text = "${error.error}\n$chain";
-          return prefixLines(text, "  ", first: "! ");
+          var text = '${error.error}\n$chain';
+          return prefixLines(text, '  ', first: '! ');
         }
-      }).join("\n");
-      if (eventsString.isEmpty) eventsString = "no events";
+      }).join('\n');
+      if (eventsString.isEmpty) eventsString = 'no events';
 
       transaction.reject();
 
       var buffer = StringBuffer();
-      buffer.writeln(indent(eventsString, first: "emitted "));
-      if (result.isNotEmpty) buffer.writeln(indent(result, first: "  which "));
+      buffer.writeln(indent(eventsString, first: 'emitted '));
+      if (result.isNotEmpty) buffer.writeln(indent(result, first: '  which '));
       return buffer.toString().trimRight();
     }, onError: (error) {
       transaction.reject();
       throw error;
+    }).then((result) {
+      if (shouldCancelQueue) queue.cancel();
+      return result;
     });
   }
 
+  @override
   Description describe(Description description) =>
-      description.add("should ").add(this.description);
+      description.add('should ').add(this.description);
 }
diff --git a/test_api/lib/src/frontend/stream_matchers.dart b/test_api/lib/src/frontend/stream_matchers.dart
index dec9859..53f7c8c 100644
--- a/test_api/lib/src/frontend/stream_matchers.dart
+++ b/test_api/lib/src/frontend/stream_matchers.dart
@@ -14,7 +14,7 @@
 
 /// Returns a [StreamMatcher] that asserts that the stream emits a "done" event.
 final emitsDone = StreamMatcher(
-    (queue) async => (await queue.hasNext) ? "" : null, "be done");
+    (queue) async => (await queue.hasNext) ? '' : null, 'be done');
 
 /// Returns a [StreamMatcher] for [matcher].
 ///
@@ -32,7 +32,7 @@
   var matcherDescription = wrapped.describe(StringDescription());
 
   return StreamMatcher((queue) async {
-    if (!await queue.hasNext) return "";
+    if (!await queue.hasNext) return '';
 
     var matchState = {};
     var actual = await queue.next;
@@ -41,11 +41,11 @@
     var mismatchDescription = StringDescription();
     wrapped.describeMismatch(actual, mismatchDescription, matchState, false);
 
-    if (mismatchDescription.length == 0) return "";
-    return "emitted an event that $mismatchDescription";
+    if (mismatchDescription.length == 0) return '';
+    return 'emitted an event that $mismatchDescription';
   },
       // TODO(nweiz): add "should" once matcher#42 is fixed.
-      "emit an event that $matcherDescription");
+      'emit an event that $matcherDescription');
 }
 
 /// Returns a [StreamMatcher] that matches a single error event that matches
@@ -58,7 +58,7 @@
   return StreamMatcher(
       (queue) => throwsMatcher.matchAsync(queue.next) as Future<String>,
       // TODO(nweiz): add "should" once matcher#42 is fixed.
-      "emit an error that $matcherDescription");
+      'emit an error that $matcherDescription');
 }
 
 /// Returns a [StreamMatcher] that allows (but doesn't require) [matcher] to
@@ -72,7 +72,7 @@
     await queue.withTransaction(
         (copy) async => (await streamMatcher.matchQueue(copy)) == null);
     return null;
-  }, "maybe ${streamMatcher.description}");
+  }, 'maybe ${streamMatcher.description}');
 }
 
 /// Returns a [StreamMatcher] that matches the stream if at least one of
@@ -87,11 +87,11 @@
 StreamMatcher emitsAnyOf(Iterable matchers) {
   var streamMatchers = matchers.map(emits).toList();
   if (streamMatchers.isEmpty) {
-    throw ArgumentError("matcher may not be empty");
+    throw ArgumentError('matcher may not be empty');
   }
 
   if (streamMatchers.length == 1) return streamMatchers.first;
-  var description = "do one of the following:\n" +
+  var description = 'do one of the following:\n' +
       bullet(streamMatchers.map((matcher) => matcher.description));
 
   return StreamMatcher((queue) async {
@@ -143,16 +143,16 @@
 
       var failureMessages = <String>[];
       for (var i = 0; i < matchers.length; i++) {
-        var message = "failed to ${streamMatchers[i].description}";
+        var message = 'failed to ${streamMatchers[i].description}';
         if (failures[i].isNotEmpty) {
-          message += message.contains("\n") ? "\n" : " ";
-          message += "because it ${failures[i]}";
+          message += message.contains('\n') ? '\n' : ' ';
+          message += 'because it ${failures[i]}';
         }
 
         failureMessages.add(message);
       }
 
-      return "failed all options:\n${bullet(failureMessages)}";
+      return 'failed all options:\n${bullet(failureMessages)}';
     } else {
       transaction.commit(consumedMost);
       return null;
@@ -168,7 +168,7 @@
   var streamMatchers = matchers.map(emits).toList();
   if (streamMatchers.length == 1) return streamMatchers.first;
 
-  var description = "do the following in order:\n" +
+  var description = 'do the following in order:\n' +
       bullet(streamMatchers.map((matcher) => matcher.description));
 
   return StreamMatcher((queue) async {
@@ -179,8 +179,8 @@
 
       var newResult = "didn't ${matcher.description}";
       if (result.isNotEmpty) {
-        newResult += newResult.contains("\n") ? "\n" : " ";
-        newResult += "because it $result";
+        newResult += newResult.contains('\n') ? '\n' : ' ';
+        newResult += 'because it $result';
       }
       return newResult;
     }
@@ -199,7 +199,7 @@
   return StreamMatcher((queue) async {
     var failures = <String>[];
 
-    tryHere() => queue.withTransaction((copy) async {
+    Future<bool> tryHere() => queue.withTransaction((copy) async {
           var result = await streamMatcher.matchQueue(copy);
           if (result == null) return true;
           failures.add(result);
@@ -215,17 +215,17 @@
     // stream.
     if (await tryHere()) return null;
 
-    var result = "never did ${streamMatcher.description}";
+    var result = 'never did ${streamMatcher.description}';
 
     var failureMessages =
         bullet(failures.where((failure) => failure.isNotEmpty));
     if (failureMessages.isNotEmpty) {
-      result += result.contains("\n") ? "\n" : " ";
-      result += "because it:\n$failureMessages";
+      result += result.contains('\n') ? '\n' : ' ';
+      result += 'because it:\n$failureMessages';
     }
 
     return result;
-  }, "eventually ${streamMatcher.description}");
+  }, 'eventually ${streamMatcher.description}');
 }
 
 /// Returns a [StreamMatcher] that matches any number of events that match
@@ -238,8 +238,8 @@
   var streamMatcher = emits(matcher);
 
   var description = streamMatcher.description;
-  description += description.contains("\n") ? "\n" : " ";
-  description += "zero or more times";
+  description += description.contains('\n') ? '\n' : ' ';
+  description += 'zero or more times';
 
   return StreamMatcher((queue) async {
     while (await _tryMatch(queue, streamMatcher)) {
@@ -279,8 +279,8 @@
 
     if (!matched) return null;
     return "after $events ${pluralize('event', events)} did "
-        "${streamMatcher.description}";
-  }, "never ${streamMatcher.description}");
+        '${streamMatcher.description}';
+  }, 'never ${streamMatcher.description}');
 }
 
 /// Returns whether [matcher] matches [queue] at its current position.
@@ -312,11 +312,11 @@
 StreamMatcher emitsInAnyOrder(Iterable matchers) {
   var streamMatchers = matchers.map(emits).toSet();
   if (streamMatchers.length == 1) return streamMatchers.first;
-  var description = "do the following in any order:\n" +
+  var description = 'do the following in any order:\n' +
       bullet(streamMatchers.map((matcher) => matcher.description));
 
   return StreamMatcher(
-      (queue) async => await _tryInAnyOrder(queue, streamMatchers) ? null : "",
+      (queue) async => await _tryInAnyOrder(queue, streamMatchers) ? null : '',
       description);
 }
 
diff --git a/test_api/lib/src/frontend/throws_matcher.dart b/test_api/lib/src/frontend/throws_matcher.dart
index c6e34d7..cdf9c6e 100644
--- a/test_api/lib/src/frontend/throws_matcher.dart
+++ b/test_api/lib/src/frontend/throws_matcher.dart
@@ -15,7 +15,7 @@
 /// Use [throwsA] instead. We strongly recommend that you add assertions about
 /// at least the type of the error, but you can write `throwsA(anything)` to
 /// mimic the behavior of this matcher.
-@Deprecated("Will be removed in 0.13.0")
+@Deprecated('Will be removed in 0.13.0')
 const Matcher throws = Throws();
 
 /// This can be used to match three kinds of objects:
@@ -38,17 +38,18 @@
 Matcher throwsA(matcher) => Throws(wrapMatcher(matcher));
 
 /// Use the [throwsA] function instead.
-@Deprecated("Will be removed in 0.13.0")
+@Deprecated('Will be removed in 0.13.0')
 class Throws extends AsyncMatcher {
   final Matcher _matcher;
 
-  const Throws([Matcher matcher]) : this._matcher = matcher;
+  const Throws([Matcher matcher]) : _matcher = matcher;
 
   // Avoid async/await so we synchronously fail if we match a synchronous
   // function.
-  /*FutureOr<String>*/ matchAsync(item) {
+  @override
+  dynamic /*FutureOr<String>*/ matchAsync(item) {
     if (item is! Function && item is! Future) {
-      return "was not a Function or Future";
+      return 'was not a Function or Future';
     }
 
     if (item is Future) {
@@ -71,9 +72,10 @@
     }
   }
 
+  @override
   Description describe(Description description) {
     if (_matcher == null) {
-      return description.add("throws");
+      return description.add('throws');
     } else {
       return description.add('throws ').addDescriptionOf(_matcher);
     }
diff --git a/test_api/lib/src/frontend/timeout.dart b/test_api/lib/src/frontend/timeout.dart
index 21b8890..9c1e02e 100644
--- a/test_api/lib/src/frontend/timeout.dart
+++ b/test_api/lib/src/frontend/timeout.dart
@@ -9,18 +9,18 @@
 /// This is intended to scan through a number without actually encoding the full
 /// Dart number grammar. It doesn't stop on "e" because that can be a component
 /// of numbers.
-final _untilUnit = RegExp(r"[^a-df-z\s]+", caseSensitive: false);
+final _untilUnit = RegExp(r'[^a-df-z\s]+', caseSensitive: false);
 
 /// A regular expression that matches a time unit.
-final _unit = RegExp(r"([um]s|[dhms])", caseSensitive: false);
+final _unit = RegExp(r'([um]s|[dhms])', caseSensitive: false);
 
 /// A regular expression that matches a section of whitespace.
-final _whitespace = RegExp(r"\s+");
+final _whitespace = RegExp(r'\s+');
 
 /// A class representing a modification to the default timeout for a test.
 ///
 /// By default, a test will time out after 30 seconds. With [new Timeout], that
-/// can be overridden entirely; with [new Timeout.factor], it can be scaled
+/// can be overridden entirely; with [Timeout.factor], it can be scaled
 /// relative to the default.
 class Timeout {
   /// A constant indicating that a test should never time out.
@@ -70,17 +70,17 @@
     var scanner = StringScanner(timeout);
 
     // First check for the string "none".
-    if (scanner.scan("none")) {
+    if (scanner.scan('none')) {
       scanner.expectDone();
       return Timeout.none;
     }
 
     // Scan a number. This will be either a time unit or a scale factor.
-    scanner.expect(_untilUnit, name: "number");
+    scanner.expect(_untilUnit, name: 'number');
     var number = double.parse(scanner.lastMatch[0]);
 
     // A number followed by "x" is a scale factor.
-    if (scanner.scan("x") || scanner.scan("X")) {
+    if (scanner.scan('x') || scanner.scan('X')) {
       scanner.expectDone();
       return Timeout.factor(number);
     }
@@ -89,7 +89,7 @@
     // the loop because we've already parsed the first number.
     var microseconds = 0.0;
     while (true) {
-      scanner.expect(_unit, name: "unit");
+      scanner.expect(_unit, name: 'unit');
       microseconds += _microsecondsFor(number, scanner.lastMatch[0]);
 
       scanner.scan(_whitespace);
@@ -106,20 +106,20 @@
   /// Returns the number of microseconds in [number] [unit]s.
   static double _microsecondsFor(double number, String unit) {
     switch (unit) {
-      case "d":
+      case 'd':
         return number * 24 * 60 * 60 * 1000000;
-      case "h":
+      case 'h':
         return number * 60 * 60 * 1000000;
-      case "m":
+      case 'm':
         return number * 60 * 1000000;
-      case "s":
+      case 's':
         return number * 1000000;
-      case "ms":
+      case 'ms':
         return number * 1000;
-      case "us":
+      case 'us':
         return number;
       default:
-        throw ArgumentError("Unknown unit $unit.");
+        throw ArgumentError('Unknown unit $unit.');
     }
   }
 
@@ -141,19 +141,22 @@
   /// If this is [none], returns `null`.
   Duration apply(Duration base) {
     if (this == none) return null;
-    return duration == null ? base * scaleFactor : duration;
+    return duration ?? base * scaleFactor;
   }
 
+  @override
   int get hashCode => duration.hashCode ^ 5 * scaleFactor.hashCode;
 
+  @override
   bool operator ==(other) =>
       other is Timeout &&
       other.duration == duration &&
       other.scaleFactor == scaleFactor;
 
+  @override
   String toString() {
     if (duration != null) return duration.toString();
-    if (scaleFactor != null) return "${scaleFactor}x";
-    return "none";
+    if (scaleFactor != null) return '${scaleFactor}x';
+    return 'none';
   }
 }
diff --git a/test_api/lib/src/frontend/utils.dart b/test_api/lib/src/frontend/utils.dart
index c91e16e..17dc2bd 100644
--- a/test_api/lib/src/frontend/utils.dart
+++ b/test_api/lib/src/frontend/utils.dart
@@ -14,9 +14,6 @@
 Future pumpEventQueue({int times}) {
   times ??= 20;
   if (times == 0) return Future.value();
-  // Use [new Future] future to allow microtask events to finish. The [new
-  // Future.value] constructor uses scheduleMicrotask itself and would therefore
-  // not wait for microtask callbacks that are scheduled after invoking this
-  // method.
+  // Use the event loop to allow the microtask queue to finish.
   return Future(() => pumpEventQueue(times: times - 1));
 }
diff --git a/test_api/lib/src/remote_listener.dart b/test_api/lib/src/remote_listener.dart
index 970b598..e745eb4 100644
--- a/test_api/lib/src/remote_listener.dart
+++ b/test_api/lib/src/remote_listener.dart
@@ -44,8 +44,8 @@
   ///
   /// If [beforeLoad] is passed, it's called before the tests have been declared
   /// for this worker.
-  static StreamChannel start(Function getMain(),
-      {bool hidePrints = true, Future beforeLoad()}) {
+  static StreamChannel start(Function Function() getMain,
+      {bool hidePrints = true, Future Function() beforeLoad}) {
     // This has to be synchronous to work around sdk#25745. Otherwise, there'll
     // be an asynchronous pause before a syntax error notification is sent,
     // which will cause the send to fail entirely.
@@ -58,7 +58,7 @@
     var printZone = hidePrints ? null : Zone.current;
     var spec = ZoneSpecification(print: (_, __, ___, line) {
       if (printZone != null) printZone.print(line);
-      channel.sink.add({"type": "print", "line": line});
+      channel.sink.add({'type': 'print', 'line': line});
     });
 
     // Work-around for https://github.com/dart-lang/sdk/issues/32556. Remove
@@ -73,7 +73,7 @@
             main = getMain();
           } on NoSuchMethodError catch (_) {
             _sendLoadException(
-                channel, "No top-level main() function defined.");
+                channel, 'No top-level main() function defined.');
             return;
           } catch (error, stackTrace) {
             _sendError(channel, error, stackTrace, verboseChain);
@@ -82,11 +82,11 @@
 
           if (main is! Function) {
             _sendLoadException(
-                channel, "Top-level main getter is not a function.");
+                channel, 'Top-level main getter is not a function.');
             return;
           } else if (main is! Function()) {
             _sendLoadException(
-                channel, "Top-level main() function takes arguments.");
+                channel, 'Top-level main() function takes arguments.');
             return;
           }
 
@@ -95,12 +95,12 @@
           assert(message['type'] == 'initial');
 
           queue.rest.listen((message) {
-            if (message["type"] == "close") {
+            if (message['type'] == 'close') {
               controller.local.sink.close();
               return;
             }
 
-            assert(message["type"] == "suiteChannel");
+            assert(message['type'] == 'suiteChannel');
             SuiteChannelManager.current.connectIn(message['name'] as String,
                 channel.virtualChannel(message['id'] as int));
           });
@@ -155,15 +155,15 @@
   ///
   /// [message] should describe the failure.
   static void _sendLoadException(StreamChannel channel, String message) {
-    channel.sink.add({"type": "loadException", "message": message});
+    channel.sink.add({'type': 'loadException', 'message': message});
   }
 
   /// Sends a message over [channel] indicating an error from user code.
   static void _sendError(
       StreamChannel channel, error, StackTrace stackTrace, bool verboseChain) {
     channel.sink.add({
-      "type": "error",
-      "error": RemoteException.serialize(
+      'type': 'error',
+      'error': RemoteException.serialize(
           error,
           StackTraceFormatter.current
               .formatStackTrace(stackTrace, verbose: verboseChain))
@@ -176,8 +176,8 @@
   /// commands to run the tests.
   void _listen(MultiChannel channel) {
     channel.sink.add({
-      "type": "success",
-      "root": _serializeGroup(channel, _suite.group, [])
+      'type': 'success',
+      'root': _serializeGroup(channel, _suite.group, [])
     });
   }
 
@@ -188,13 +188,13 @@
       MultiChannel channel, Group group, Iterable<Group> parents) {
     parents = parents.toList()..add(group);
     return {
-      "type": "group",
-      "name": group.name,
-      "metadata": group.metadata.serialize(),
-      "trace": group.trace?.toString(),
-      "setUpAll": _serializeTest(channel, group.setUpAll, parents),
-      "tearDownAll": _serializeTest(channel, group.tearDownAll, parents),
-      "entries": group.entries.map((entry) {
+      'type': 'group',
+      'name': group.name,
+      'metadata': group.metadata.serialize(),
+      'trace': group.trace?.toString(),
+      'setUpAll': _serializeTest(channel, group.setUpAll, parents),
+      'tearDownAll': _serializeTest(channel, group.tearDownAll, parents),
+      'entries': group.entries.map((entry) {
         return entry is Group
             ? _serializeGroup(channel, entry, parents)
             : _serializeTest(channel, entry as Test, parents);
@@ -217,11 +217,11 @@
     });
 
     return {
-      "type": "test",
-      "name": test.name,
-      "metadata": test.metadata.serialize(),
-      "trace": test.trace?.toString(),
-      "channel": testChannel.id
+      'type': 'test',
+      'name': test.name,
+      'metadata': test.metadata.serialize(),
+      'trace': test.trace?.toString(),
+      'channel': testChannel.id
     };
   }
 
@@ -234,16 +234,16 @@
 
     liveTest.onStateChange.listen((state) {
       channel.sink.add({
-        "type": "state-change",
-        "status": state.status.name,
-        "result": state.result.name
+        'type': 'state-change',
+        'status': state.status.name,
+        'result': state.result.name
       });
     });
 
     liveTest.onError.listen((asyncError) {
       channel.sink.add({
-        "type": "error",
-        "error": RemoteException.serialize(
+        'type': 'error',
+        'error': RemoteException.serialize(
             asyncError.error,
             StackTraceFormatter.current.formatStackTrace(asyncError.stackTrace,
                 verbose: liveTest.test.metadata.verboseTrace))
@@ -253,14 +253,14 @@
     liveTest.onMessage.listen((message) {
       if (_printZone != null) _printZone.print(message.text);
       channel.sink.add({
-        "type": "message",
-        "message-type": message.type.name,
-        "text": message.text
+        'type': 'message',
+        'message-type': message.type.name,
+        'text': message.text
       });
     });
 
     runZoned(() {
-      liveTest.run().then((_) => channel.sink.add({"type": "complete"}));
+      liveTest.run().then((_) => channel.sink.add({'type': 'complete'}));
     }, zoneValues: {#test.runner.test_channel: channel});
   }
 }
diff --git a/test_api/lib/src/suite_channel_manager.dart b/test_api/lib/src/suite_channel_manager.dart
index aebe837..1f70d5f 100644
--- a/test_api/lib/src/suite_channel_manager.dart
+++ b/test_api/lib/src/suite_channel_manager.dart
@@ -20,7 +20,7 @@
   final _outgoingConnections = <String, StreamChannelCompleter>{};
 
   /// The channel names that have already been used.
-  final _names = Set<String>();
+  final _names = <String>{};
 
   /// Returns the current manager, or `null` if this isn't called within a call
   /// to [asCurrent].
@@ -31,7 +31,8 @@
   ///
   /// This is zone-scoped, so [this] will be the current configuration in any
   /// asynchronous callbacks transitively created by [body].
-  T asCurrent<T>(T body()) => runZoned(body, zoneValues: {_currentKey: this});
+  T asCurrent<T>(T Function() body) =>
+      runZoned(body, zoneValues: {_currentKey: this});
 
   /// Creates a connection to the test runnner's channel with the given [name].
   StreamChannel connectOut(String name) {
diff --git a/test_api/lib/src/util/iterable_set.dart b/test_api/lib/src/util/iterable_set.dart
index 5166a72..bba6433 100644
--- a/test_api/lib/src/util/iterable_set.dart
+++ b/test_api/lib/src/util/iterable_set.dart
@@ -19,17 +19,22 @@
   /// The base iterable that set operations forward to.
   final Iterable<E> _base;
 
+  @override
   int get length => _base.length;
 
+  @override
   Iterator<E> get iterator => _base.iterator;
 
   /// Creates a [Set] view of [base].
   IterableSet(this._base);
 
+  @override
   bool contains(Object element) => _base.contains(element);
 
+  @override
   E lookup(Object needle) =>
       _base.firstWhere((element) => element == needle, orElse: () => null);
 
+  @override
   Set<E> toSet() => _base.toSet();
 }
diff --git a/test_api/lib/src/util/remote_exception.dart b/test_api/lib/src/util/remote_exception.dart
index a0582d5..bb6fc62 100644
--- a/test_api/lib/src/util/remote_exception.dart
+++ b/test_api/lib/src/util/remote_exception.dart
@@ -29,7 +29,7 @@
   ///
   /// Other than JSON- and isolate-safety, no guarantees are made about the
   /// serialized format.
-  static serialize(error, StackTrace stackTrace) {
+  static Map<String, dynamic> serialize(error, StackTrace stackTrace) {
     String message;
     if (error is String) {
       message = error;
@@ -77,6 +77,7 @@
 
   RemoteException._(this.message, this.type, this._toString);
 
+  @override
   String toString() => _toString;
 }
 
diff --git a/test_api/lib/src/util/test.dart b/test_api/lib/src/util/test.dart
index ae5e6a8..de36fbf 100644
--- a/test_api/lib/src/util/test.dart
+++ b/test_api/lib/src/util/test.dart
@@ -13,7 +13,7 @@
 /// callbacks registered outside of [body].
 ///
 /// This may only be called within a test.
-Future errorsDontStopTest(body()) {
+Future errorsDontStopTest(dynamic Function() body) {
   var completer = Completer();
 
   Invoker.current.addOutstandingCallback();
diff --git a/test_api/lib/src/utils.dart b/test_api/lib/src/utils.dart
index 2e90a7c..ee1cde6 100644
--- a/test_api/lib/src/utils.dart
+++ b/test_api/lib/src/utils.dart
@@ -31,7 +31,7 @@
 final chunksToLines = StreamChannelTransformer<String, String>(
     const LineSplitter(),
     StreamSinkTransformer.fromHandlers(
-        handleData: (data, sink) => sink.add("$data\n")));
+        handleData: (data, sink) => sink.add('$data\n')));
 
 /// A regular expression to match the exception prefix that some exceptions'
 /// [Object.toString] values contain.
@@ -43,8 +43,13 @@
 /// Directories that are specific to OS X.
 ///
 /// This is used to try to distinguish OS X and Linux in [currentOSGuess].
-final _macOSDirectories = Set<String>.from(
-    ["/Applications", "/Library", "/Network", "/System", "/Users"]);
+final _macOSDirectories = {
+  '/Applications',
+  '/Library',
+  '/Network',
+  '/System',
+  '/Users',
+};
 
 /// Returns the best guess for the current operating system without using
 /// `dart:io`.
@@ -63,12 +68,12 @@
 ///
 /// This is like a standard Dart identifier, except that it can also contain
 /// hyphens.
-final _hyphenatedIdentifier = RegExp(r"[a-zA-Z_-][a-zA-Z0-9_-]*");
+final _hyphenatedIdentifier = RegExp(r'[a-zA-Z_-][a-zA-Z0-9_-]*');
 
 /// Like [_hyphenatedIdentifier], but anchored so that it must match the entire
 /// string.
 final anchoredHyphenatedIdentifier =
-    RegExp("^${_hyphenatedIdentifier.pattern}\$");
+    RegExp('^${_hyphenatedIdentifier.pattern}\$');
 
 /// A pair of values.
 class Pair<E, F> {
@@ -77,13 +82,16 @@
 
   Pair(this.first, this.last);
 
+  @override
   String toString() => '($first, $last)';
 
+  @override
   bool operator ==(other) {
     if (other is! Pair) return false;
     return other.first == first && other.last == last;
   }
 
+  @override
   int get hashCode => first.hashCode ^ last.hashCode;
 }
 
@@ -100,7 +108,7 @@
 /// [size] defaults to `first.length`. Otherwise, [size] defaults to 2.
 String indent(String string, {int size, String first}) {
   size ??= first == null ? 2 : first.length;
-  return prefixLines(string, " " * size, first: first);
+  return prefixLines(string, ' ' * size, first: first);
 }
 
 /// Returns a sentence fragment listing the elements of [iter].
@@ -111,8 +119,8 @@
 String toSentence(Iterable iter, {String conjunction}) {
   if (iter.length == 1) return iter.first.toString();
 
-  var result = iter.take(iter.length - 1).join(", ");
-  if (iter.length > 2) result += ",";
+  var result = iter.take(iter.length - 1).join(', ');
+  if (iter.length > 2) result += ',';
   return "$result ${conjunction ?? 'and'} ${iter.last}";
 }
 
@@ -128,7 +136,7 @@
 
 /// Returns [noun] with an indefinite article ("a" or "an") added, based on
 /// whether its first letter is a vowel.
-String a(String noun) => noun.startsWith(_vowel) ? "an $noun" : "a $noun";
+String a(String noun) => noun.startsWith(_vowel) ? 'an $noun' : 'a $noun';
 
 /// A regular expression matching terminal color codes.
 final _colorCode = RegExp('\u001b\\[[0-9;]+m');
@@ -141,7 +149,7 @@
 ///
 /// The return value *may or may not* be unmodifiable.
 Map<K, V> mergeUnmodifiableMaps<K, V>(Map<K, V> map1, Map<K, V> map2,
-    {V value(V value1, V value2)}) {
+    {V Function(V, V) value}) {
   if (map1.isEmpty) return map2;
   if (map2.isEmpty) return map1;
   return mergeMaps(map1, map2, value: value);
@@ -195,13 +203,13 @@
   var decaseconds = (duration.inMilliseconds % 1000) ~/ 100;
 
   var buffer = StringBuffer();
-  if (minutes != 0) buffer.write("$minutes minutes");
+  if (minutes != 0) buffer.write('$minutes minutes');
 
   if (minutes == 0 || seconds != 0) {
-    if (minutes != 0) buffer.write(", ");
+    if (minutes != 0) buffer.write(', ');
     buffer.write(seconds);
-    if (decaseconds != 0) buffer.write(".$decaseconds");
-    buffer.write(" seconds");
+    if (decaseconds != 0) buffer.write('.$decaseconds');
+    buffer.write(' seconds');
   }
 
   return buffer.toString();
@@ -233,14 +241,6 @@
   return controller.stream;
 }
 
-/// Runs [fn] and discards its return value.
-///
-/// This is useful for making a block of code async without forcing the
-/// containing method to return a future.
-void invoke(fn()) {
-  fn();
-}
-
 /// Returns a random base64 string containing [bytes] bytes of data.
 ///
 /// [seed] is passed to [math.Random].
@@ -279,10 +279,10 @@
 
 /// Indents [text], and adds a bullet at the beginning.
 String addBullet(String text) =>
-    prefixLines(text, "  ", first: "${glyph.bullet} ");
+    prefixLines(text, '  ', first: '${glyph.bullet} ');
 
 /// Converts [strings] to a bulleted list.
-String bullet(Iterable<String> strings) => strings.map(addBullet).join("\n");
+String bullet(Iterable<String> strings) => strings.map(addBullet).join('\n');
 
 /// Prepends each line in [text] with [prefix].
 ///
@@ -297,15 +297,15 @@
   single ??= first ?? last ?? prefix;
 
   var lines = text.split('\n');
-  if (lines.length == 1) return "$single$text";
+  if (lines.length == 1) return '$single$text';
 
-  var buffer = StringBuffer("$first${lines.first}\n");
+  var buffer = StringBuffer('$first${lines.first}\n');
 
   // Write out all but the first and last lines with [prefix].
   for (var line in lines.skip(1).take(lines.length - 2)) {
-    buffer.writeln("$prefix$line");
+    buffer.writeln('$prefix$line');
   }
-  buffer.write("$last${lines.last}");
+  buffer.write('$last${lines.last}');
   return buffer.toString();
 }
 
@@ -315,3 +315,12 @@
 /// we can use it through StringDescription.
 String prettyPrint(value) =>
     StringDescription().addDescriptionOf(value).toString();
+
+/// Indicates to tools that [future] is intentionally not `await`-ed.
+///
+/// In an `async` context, it is normally expected that all [Future]s are
+/// awaited, and that is the basis of the lint `unawaited_futures`. However,
+/// there are times where one or more futures are intentionally not awaited.
+/// This function may be used to ignore a particular future. It silences the
+/// `unawaited_futures` lint.
+void unawaited(Future<void> future) {}
diff --git a/test_api/lib/test_api.dart b/test_api/lib/test_api.dart
index 9fab4e1..2927580 100644
--- a/test_api/lib/test_api.dart
+++ b/test_api/lib/test_api.dart
@@ -73,15 +73,15 @@
 /// annotation classes: [Timeout], [Skip], or lists of those. These
 /// annotations apply only on the given platforms. For example:
 ///
-///     test("potentially slow test", () {
+///     test('potentially slow test', () {
 ///       // ...
 ///     }, onPlatform: {
 ///       // This test is especially slow on Windows.
-///       "windows": new Timeout.factor(2),
-///       "browser": [
-///         new Skip("TODO: add browser support"),
+///       'windows': Timeout.factor(2),
+///       'browser': [
+///         Skip('TODO: add browser support'),
 ///         // This will be slow on browsers once it works on them.
-///         new Timeout.factor(2)
+///         Timeout.factor(2)
 ///       ]
 ///     });
 ///
@@ -94,7 +94,7 @@
 /// avoid this flag if possible and instead use the test runner flag `-n` to
 /// filter tests by name.
 @isTest
-void test(description, body(),
+void test(description, dynamic Function() body,
     {String testOn,
     Timeout timeout,
     skip,
@@ -151,15 +151,15 @@
 /// annotation classes: [Timeout], [Skip], or lists of those. These
 /// annotations apply only on the given platforms. For example:
 ///
-///     group("potentially slow tests", () {
+///     group('potentially slow tests', () {
 ///       // ...
 ///     }, onPlatform: {
 ///       // These tests are especially slow on Windows.
-///       "windows": new Timeout.factor(2),
-///       "browser": [
-///         new Skip("TODO: add browser support"),
+///       'windows': Timeout.factor(2),
+///       'browser': [
+///         Skip('TODO: add browser support'),
 ///         // They'll be slow on browsers once it works on them.
-///         new Timeout.factor(2)
+///         Timeout.factor(2)
 ///       ]
 ///     });
 ///
@@ -172,7 +172,7 @@
 /// avoid this flag if possible, and instead use the test runner flag `-n` to
 /// filter tests by name.
 @isTestGroup
-void group(description, body(),
+void group(description, dynamic Function() body,
     {String testOn,
     Timeout timeout,
     skip,
@@ -207,7 +207,7 @@
 ///
 /// Each callback at the top level or in a given group will be run in the order
 /// they were declared.
-void setUp(callback()) => _declarer.setUp(callback);
+void setUp(dynamic Function() callback) => _declarer.setUp(callback);
 
 /// Registers a function to be run after tests.
 ///
@@ -222,7 +222,7 @@
 /// reverse of the order they were declared.
 ///
 /// See also [addTearDown], which adds tear-downs to a running test.
-void tearDown(callback()) => _declarer.tearDown(callback);
+void tearDown(dynamic Function() callback) => _declarer.tearDown(callback);
 
 /// Registers a function to be run after the current test.
 ///
@@ -235,9 +235,9 @@
 ///
 /// If this is called from within a [setUpAll] or [tearDownAll] callback, it
 /// instead runs the function after *all* tests in the current test suite.
-void addTearDown(callback()) {
+void addTearDown(dynamic Function() callback) {
   if (Invoker.current == null) {
-    throw StateError("addTearDown() may only be called within a test.");
+    throw StateError('addTearDown() may only be called within a test.');
   }
 
   Invoker.current.addTearDown(callback);
@@ -256,7 +256,7 @@
 /// dependencies between tests that should be isolated. In general, you should
 /// prefer [setUp], and only use [setUpAll] if the callback is prohibitively
 /// slow.
-void setUpAll(callback()) => _declarer.setUpAll(callback);
+void setUpAll(dynamic Function() callback) => _declarer.setUpAll(callback);
 
 /// Registers a function to be run once after all tests.
 ///
@@ -269,7 +269,8 @@
 /// dependencies between tests that should be isolated. In general, you should
 /// prefer [tearDown], and only use [tearDownAll] if the callback is
 /// prohibitively slow.
-void tearDownAll(callback()) => _declarer.tearDownAll(callback);
+void tearDownAll(dynamic Function() callback) =>
+    _declarer.tearDownAll(callback);
 
 /// Registers an exception that was caught for the current test.
 void registerException(error, [StackTrace stackTrace]) {
diff --git a/test_api/mono_pkg.yaml b/test_api/mono_pkg.yaml
index 62b9aba..5f08191 100644
--- a/test_api/mono_pkg.yaml
+++ b/test_api/mono_pkg.yaml
@@ -6,7 +6,7 @@
         dart: dev
       - group:
         - dartanalyzer: --fatal-warnings .
-        dart: 2.1.0
+        dart: 2.4.0
     - unit_test:
       - group:
         - test: --preset travis
diff --git a/test_api/pubspec.yaml b/test_api/pubspec.yaml
index eab4b86..8b34a9c 100644
--- a/test_api/pubspec.yaml
+++ b/test_api/pubspec.yaml
@@ -1,19 +1,17 @@
 name: test_api
-version: 0.2.11
-author: Dart Team <misc@dartlang.org>
+version: 0.2.15
 description: A library for writing Dart tests.
 homepage: https://github.com/dart-lang/test/blob/master/pkgs/test_api
 
 environment:
-  sdk: ">=2.2.0 <3.0.0"
+  sdk: ">=2.4.0 <3.0.0"
 
 dependencies:
   async: ^2.0.0
-  boolean_selector: ^1.0.0
+  boolean_selector: ">=1.0.0 <3.0.0"
   collection: ^1.8.0
   meta: ^1.1.5
   path: ^1.2.0
-  pedantic: ^1.0.0
   source_span: ^1.4.0
   stack_trace: ^1.9.0
   stream_channel: ">=1.7.0 <3.0.0"
@@ -26,6 +24,7 @@
 
 dev_dependencies:
   fake_async: ^1.0.0
+  pedantic: ^1.0.0
   test_descriptor: ^1.0.0
   test_process: ^1.0.0
   test: any
diff --git a/test_core/BUILD.gn b/test_core/BUILD.gn
index 033d445..f8e5333 100644
--- a/test_core/BUILD.gn
+++ b/test_core/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for test_core-0.2.15
+# This file is generated by importer.py for test_core-0.3.2
 
 import("//build/dart/dart_library.gni")
 
@@ -23,13 +23,12 @@
     "//third_party/dart-pkg/pub/meta",
     "//third_party/dart-pkg/pub/analyzer",
     "//third_party/dart-pkg/pub/io",
-    "//third_party/dart-pkg/pub/source_span",
     "//third_party/dart-pkg/pub/path",
+    "//third_party/dart-pkg/pub/source_span",
     "//third_party/dart-pkg/pub/stream_channel",
     "//third_party/dart-pkg/pub/pool",
     "//third_party/dart-pkg/pub/source_maps",
     "//third_party/dart-pkg/pub/source_map_stack_trace",
-    "//third_party/dart-pkg/pub/package_resolver",
     "//third_party/dart-pkg/pub/yaml",
     "//third_party/dart-pkg/pub/vm_service",
     "//third_party/dart-pkg/pub/boolean_selector",
diff --git a/test_core/CHANGELOG.md b/test_core/CHANGELOG.md
index cb4d969..dcb572a 100644
--- a/test_core/CHANGELOG.md
+++ b/test_core/CHANGELOG.md
@@ -1,3 +1,51 @@
+## 0.3.2
+
+* Drop the `package_resolver` dependency.
+
+## 0.3.1
+
+* Support latest `package:vm_service`.
+* Enable asserts in code running through `spawnHybrid` APIs.
+* Exit with a non-zero code if no tests were ran, whether due to skips or having
+  no tests defined.
+
+## 0.3.0
+
+* Bump minimum SDK to `2.4.0` for safer usage of for-loop elements.
+* Deprecate `PhantomJS` and provide warning when used. Support for `PhantomJS`
+  will be removed in version `2.0.0`.
+* Differentiate between test-randomize-ordering-seed not set and 0 being chosen
+  as the random seed.
+* `deserializeSuite` now takes an optional `gatherCoverage` callback.
+* Support retrying of entire test suites when they fail to load.
+* Fix the `compiling` message in precompiled mode so it says `loading` instead,
+  which is more accurate.
+* Change the behavior of the concurrency setting so that loading and running
+  don't have separate pools.
+  * The loading and running of a test are now done with the same resource, and
+    the concurrency setting uniformly affects each. With `-j1` only a single
+    test will ever be loaded at a time.
+  * Previously the loading pool was 2x larger than the actual concurrency
+    setting which could cause flaky tests due to tests being loaded while
+    other tests were running, even with `-j1`.
+* Avoid printing uncaught errors within `spawnHybridUri`.
+
+## 0.2.18
+
+* Allow `test_api` `0.2.13` to work around a bug in the SDK version `2.3.0`.
+
+## 0.2.17
+
+* Add `file_reporters` configuration option and `--file-reporter` CLI option to
+  allow specifying a separate reporter that writes to a file instead of stdout.
+
+## 0.2.16
+
+* Internal cleanup.
+* Add `customHtmlTemplateFile` configuration option to allow sharing an
+  html template between tests
+* Depend on the latest `test_api`.
+
 ## 0.2.15
 
 * Add a `StringSink` argument to reporters to prepare for reporting to a file.
diff --git a/test_core/lib/src/bootstrap/vm.dart b/test_core/lib/src/bootstrap/vm.dart
index d18366e..41b9269 100644
--- a/test_core/lib/src/bootstrap/vm.dart
+++ b/test_core/lib/src/bootstrap/vm.dart
@@ -2,14 +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.
 
-import "dart:isolate";
+import 'dart:isolate';
 
-import "package:stream_channel/isolate_channel.dart";
+import 'package:stream_channel/isolate_channel.dart';
 
-import "package:test_core/src/runner/plugin/remote_platform_helpers.dart";
+import 'package:test_core/src/runner/plugin/remote_platform_helpers.dart';
 
 /// Bootstraps a vm test to communicate with the test runner.
-void internalBootstrapVmTest(Function getMain(), SendPort sendPort) {
+void internalBootstrapVmTest(Function Function() getMain, SendPort sendPort) {
   var channel = serializeSuite(getMain);
   IsolateChannel.connectSend(sendPort).pipe(channel);
 }
diff --git a/test_core/lib/src/executable.dart b/test_core/lib/src/executable.dart
index f1e3bb5..f3749f0 100644
--- a/test_core/lib/src/executable.dart
+++ b/test_core/lib/src/executable.dart
@@ -2,9 +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.
 
-// TODO(nweiz): This is under lib so that it can be used by the unittest dummy
-// package. Once that package is no longer being updated, move this back into
-// bin.
 import 'dart:async';
 import 'dart:io';
 
@@ -14,11 +11,10 @@
 import 'package:stack_trace/stack_trace.dart';
 import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
 
-import 'runner.dart';
 import 'runner/application_exception.dart';
 import 'runner/configuration.dart';
 import 'runner/version.dart';
-
+import 'runner.dart';
 import 'util/exit_codes.dart' as exit_codes;
 import 'util/io.dart';
 
@@ -36,7 +32,7 @@
   }
 }();
 
-main(List<String> args) async {
+Future<void> main(List<String> args) async {
   await _execute(args);
   completeShutdown();
 }
@@ -159,9 +155,9 @@
   } catch (error, stackTrace) {
     stderr.writeln(getErrorMessage(error));
     stderr.writeln(Trace.from(stackTrace).terse);
-    stderr.writeln("This is an unexpected error. Please file an issue at "
-        "http://github.com/dart-lang/test\n"
-        "with the stack trace and instructions for reproducing the error.");
+    stderr.writeln('This is an unexpected error. Please file an issue at '
+        'http://github.com/dart-lang/test\n'
+        'with the stack trace and instructions for reproducing the error.');
     exitCode = exit_codes.software;
   } finally {
     await runner?.close();
@@ -169,7 +165,7 @@
 
   // TODO(grouma) - figure out why the executable can hang in the travis
   // environment. https://github.com/dart-lang/test/issues/599
-  if (Platform.environment["FORCE_TEST_EXIT"] == "true") {
+  if (Platform.environment['FORCE_TEST_EXIT'] == 'true') {
     exit(exitCode);
   }
 
@@ -183,16 +179,16 @@
 void _printUsage([String error]) {
   var output = stdout;
 
-  var message = "Runs tests in this package.";
+  var message = 'Runs tests in this package.';
   if (error != null) {
     message = error;
     output = stderr;
   }
 
-  output.write("""${wordWrap(message)}
+  output.write('''${wordWrap(message)}
 
 Usage: pub run test [files or directories...]
 
 ${Configuration.usage}
-""");
+''');
 }
diff --git a/test_core/lib/src/runner.dart b/test_core/lib/src/runner.dart
index 68a3331..89ed8bd 100644
--- a/test_core/lib/src/runner.dart
+++ b/test_core/lib/src/runner.dart
@@ -16,6 +16,7 @@
 import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
 import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/reporter/multiplex.dart';
 
 import 'util/io.dart';
 import 'runner/application_exception.dart';
@@ -58,7 +59,7 @@
   ///
   /// This is used to avoid printing duplicate warnings when a suite is loaded
   /// on multiple platforms.
-  final _tagWarningSuites = Set<String>();
+  final _tagWarningSuites = <String>{};
 
   /// The current debug operation, if any.
   ///
@@ -69,17 +70,36 @@
   final _closeMemo = AsyncMemoizer();
   bool get _closed => _closeMemo.hasRun;
 
+  /// Sinks created for each file reporter (if there are any).
+  final List<IOSink> _sinks;
+
   /// Creates a new runner based on [configuration].
   factory Runner(Configuration config) => config.asCurrent(() {
         var engine =
             Engine(concurrency: config.concurrency, coverage: config.coverage);
 
-        var reporterDetails = allReporters[config.reporter];
+        var sinks = <IOSink>[];
+        Reporter createFileReporter(String reporterName, String filepath) {
+          final sink =
+              (File(filepath)..createSync(recursive: true)).openWrite();
+          sinks.add(sink);
+          return allReporters[reporterName].factory(config, engine, sink);
+        }
+
         return Runner._(
-            engine, reporterDetails.factory(config, engine, stdout));
+          engine,
+          MultiplexReporter([
+            // Standard reporter.
+            allReporters[config.reporter].factory(config, engine, stdout),
+            // File reporters.
+            for (var reporter in config.fileReporters.keys)
+              createFileReporter(reporter, config.fileReporters[reporter]),
+          ]),
+          sinks,
+        );
       });
 
-  Runner._(this._engine, this._reporter);
+  Runner._(this._engine, this._reporter, this._sinks);
 
   /// Starts the runner.
   ///
@@ -87,7 +107,7 @@
   /// or not they ran successfully.
   Future<bool> run() => _config.asCurrent(() async {
         if (_closed) {
-          throw StateError("run() may not be called on a closed Runner.");
+          throw StateError('run() may not be called on a closed Runner.');
         }
 
         _warnForUnsupportedPlatforms();
@@ -140,9 +160,8 @@
           throw ApplicationException('No tests match $patterns.');
         }
 
-        // Explicitly check "== true" here because [Engine.run] can return `null`
-        // if the engine was closed prematurely.
-        return success == true;
+        return (success ?? false) &&
+            (_engine.passed.isNotEmpty || _engine.skipped.isNotEmpty);
       });
 
   /// Emits a warning if the user is trying to run on a platform that's
@@ -175,7 +194,7 @@
         unsupportedNames
             .addAll(unsupportedBrowsers.map((runtime) => runtime.name));
       } else {
-        unsupportedNames.add("browsers");
+        unsupportedNames.add('browsers');
       }
     }
 
@@ -188,13 +207,13 @@
       if (supportsAnyOS) {
         unsupportedNames.add(currentOS.name);
       } else {
-        unsupportedNames.add("the Dart VM");
+        unsupportedNames.add('the Dart VM');
       }
     }
 
     warn("this package doesn't support running tests on " +
-        toSentence(unsupportedNames, conjunction: "or") +
-        ".");
+        toSentence(unsupportedNames, conjunction: 'or') +
+        '.');
   }
 
   /// Closes the runner.
@@ -211,8 +230,8 @@
             // Pause the reporter while we print to ensure that we don't interfere
             // with its output.
             _reporter.pause();
-            print("Waiting for current test(s) to finish.");
-            print("Press Control-C again to terminate immediately.");
+            print('Waiting for current test(s) to finish.');
+            print('Press Control-C again to terminate immediately.');
             _reporter.resume();
           });
         }
@@ -231,6 +250,10 @@
         await Future.wait([_loader.closeEphemeral(), _engine.close()]);
         if (timer != null) timer.cancel();
         await _loader.close();
+
+        // Flush any IOSinks created for file reporters.
+        await Future.wait(_sinks.map((s) => s.flush().then((_) => s.close())));
+        _sinks.clear();
       });
 
   /// Return a stream of [LoadSuite]s in [_config.paths].
@@ -261,12 +284,12 @@
           }
 
           // If the user provided tags, skip tests that don't match all of them.
-          if (!suite.config.includeTags.evaluate(test.metadata.tags)) {
+          if (!suite.config.includeTags.evaluate(test.metadata.tags.contains)) {
             return false;
           }
 
           // Skip tests that do match any tags the user wants to exclude.
-          if (suite.config.excludeTags.evaluate(test.metadata.tags)) {
+          if (suite.config.excludeTags.evaluate(test.metadata.tags.contains)) {
             return false;
           }
 
@@ -290,23 +313,23 @@
     var noColor = _config.color ? '\u001b[0m' : '';
 
     var buffer = StringBuffer()
-      ..write("${yellow}Warning:$noColor ")
-      ..write(unknownTags.length == 1 ? "A tag was " : "Tags were ")
-      ..write("used that ")
+      ..write('${yellow}Warning:$noColor ')
+      ..write(unknownTags.length == 1 ? 'A tag was ' : 'Tags were ')
+      ..write('used that ')
       ..write(unknownTags.length == 1 ? "wasn't " : "weren't ")
-      ..writeln("specified in dart_test.yaml.");
+      ..writeln('specified in dart_test.yaml.');
 
     unknownTags.forEach((tag, entries) {
-      buffer.write("  $bold$tag$noColor was used in");
+      buffer.write('  $bold$tag$noColor was used in');
 
       if (entries.length == 1) {
-        buffer.writeln(" ${_entryDescription(entries.single)}");
+        buffer.writeln(' ${_entryDescription(entries.single)}');
         return;
       }
 
-      buffer.write(":");
+      buffer.write(':');
       for (var entry in entries) {
-        buffer.write("\n    ${_entryDescription(entry)}");
+        buffer.write('\n    ${_entryDescription(entry)}');
       }
       buffer.writeln();
     });
@@ -320,10 +343,10 @@
   /// This returns a map from tag names to lists of entries that use those tags.
   Map<String, List<GroupEntry>> _collectUnknownTags(Suite suite) {
     var unknownTags = <String, List<GroupEntry>>{};
-    var currentTags = Set<String>();
+    var currentTags = <String>{};
 
-    collect(GroupEntry entry) {
-      var newTags = Set<String>();
+    void collect(GroupEntry entry) {
+      var newTags = <String>{};
       for (var unknownTag
           in entry.metadata.tags.difference(_config.knownTags)) {
         if (currentTags.contains(unknownTag)) continue;
diff --git a/test_core/lib/src/runner/application_exception.dart b/test_core/lib/src/runner/application_exception.dart
index 919d3ec..23155a2 100644
--- a/test_core/lib/src/runner/application_exception.dart
+++ b/test_core/lib/src/runner/application_exception.dart
@@ -8,5 +8,6 @@
 
   ApplicationException(this.message);
 
+  @override
   String toString() => message;
 }
diff --git a/test_core/lib/src/runner/compiler_pool.dart b/test_core/lib/src/runner/compiler_pool.dart
index 0465b07..7556ab5 100644
--- a/test_core/lib/src/runner/compiler_pool.dart
+++ b/test_core/lib/src/runner/compiler_pool.dart
@@ -5,9 +5,9 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+import 'dart:isolate';
 
 import 'package:async/async.dart';
-import 'package:package_resolver/package_resolver.dart';
 import 'package:path/path.dart' as p;
 import 'package:pool/pool.dart';
 
@@ -17,7 +17,7 @@
 
 /// A regular expression matching the first status line printed by dart2js.
 final _dart2jsStatus =
-    RegExp(r"^Dart file \(.*\) compiled to JavaScript: .*\n?");
+    RegExp(r'^Dart file \(.*\) compiled to JavaScript: .*\n?');
 
 /// A pool of `dart2js` instances.
 ///
@@ -30,7 +30,7 @@
   final Pool _pool;
 
   /// The currently-active dart2js processes.
-  final _processes = Set<Process>();
+  final _processes = <Process>{};
 
   /// Whether [close] has been called.
   bool get _closed => _closeMemo.hasRun;
@@ -57,22 +57,22 @@
       if (_closed) return null;
 
       return withTempDir((dir) async {
-        var wrapperPath = p.join(dir, "runInBrowser.dart");
+        var wrapperPath = p.join(dir, 'runInBrowser.dart');
         File(wrapperPath).writeAsStringSync(code);
 
         var dart2jsPath = _config.dart2jsPath;
         if (Platform.isWindows) dart2jsPath += '.bat';
 
         var args = [
-          "--enable-asserts",
+          '--enable-asserts',
           wrapperPath,
-          "--out=$jsPath",
-          await PackageResolver.current.processArgument
-        ]
-          ..addAll(_extraArgs)
-          ..addAll(suiteConfig.dart2jsArgs);
+          '--out=$jsPath',
+          '--packages=${await Isolate.packageConfig}',
+          ..._extraArgs,
+          ...suiteConfig.dart2jsArgs
+        ];
 
-        if (_config.color) args.add("--enable-diagnostic-colors");
+        if (_config.color) args.add('--enable-diagnostic-colors');
 
         var process = await Process.start(dart2jsPath, args);
         if (_closed) {
@@ -101,7 +101,7 @@
         var output = buffer.toString().replaceFirst(_dart2jsStatus, '');
         if (output.isNotEmpty) print(output);
 
-        if (exitCode != 0) throw "dart2js failed.";
+        if (exitCode != 0) throw 'dart2js failed.';
 
         _fixSourceMap(jsPath + '.map');
       });
@@ -118,7 +118,7 @@
     map['sources'] = map['sources'].map((source) {
       var url = Uri.parse(root + '$source');
       if (url.scheme != '' && url.scheme != 'file') return source;
-      if (url.path.endsWith("/runInBrowser.dart")) return "";
+      if (url.path.endsWith('/runInBrowser.dart')) return '';
       return p.toUri(mapPath).resolveUri(url).toString();
     }).toList();
 
diff --git a/test_core/lib/src/runner/configuration.dart b/test_core/lib/src/runner/configuration.dart
index 26f0c62..e442f91 100644
--- a/test_core/lib/src/runner/configuration.dart
+++ b/test_core/lib/src/runner/configuration.dart
@@ -43,6 +43,9 @@
   bool get help => _help ?? false;
   final bool _help;
 
+  /// Custom HTML template file.
+  final String customHtmlTemplatePath;
+
   /// Whether `--version` was passed.
   bool get version => _version ?? false;
   final bool _version;
@@ -62,7 +65,7 @@
   /// The path to the file from which to load more configuration information.
   ///
   /// This is *not* resolved automatically.
-  String get configurationPath => _configurationPath ?? "dart_test.yaml";
+  String get configurationPath => _configurationPath ?? 'dart_test.yaml';
   final String _configurationPath;
 
   /// The path to dart2js.
@@ -73,6 +76,10 @@
   String get reporter => _reporter ?? defaultReporter;
   final String _reporter;
 
+  /// The map of file reporters where the key is the name of the reporter and
+  /// the value is the filepath to which its output should be written.
+  final Map<String, String> fileReporters;
+
   /// Whether to disable retries of tests.
   bool get noRetry => _noRetry ?? false;
   final bool _noRetry;
@@ -112,16 +119,16 @@
   final int totalShards;
 
   /// The list of packages to fold when producing [StackTrace]s.
-  Set<String> get foldTraceExcept => _foldTraceExcept ?? Set();
+  Set<String> get foldTraceExcept => _foldTraceExcept ?? {};
   final Set<String> _foldTraceExcept;
 
   /// If non-empty, all packages not in this list will be folded when producing
   /// [StackTrace]s.
-  Set<String> get foldTraceOnly => _foldTraceOnly ?? Set();
+  Set<String> get foldTraceOnly => _foldTraceOnly ?? {};
   final Set<String> _foldTraceOnly;
 
   /// The paths from which to load tests.
-  List<String> get paths => _paths ?? ["test"];
+  List<String> get paths => _paths ?? ['test'];
   final List<String> _paths;
 
   /// Whether the load paths were passed explicitly or the default was used.
@@ -216,6 +223,7 @@
 
   factory Configuration(
       {bool help,
+      String customHtmlTemplatePath,
       bool version,
       bool pauseAfterLoad,
       bool debug,
@@ -223,6 +231,7 @@
       String configurationPath,
       String dart2jsPath,
       String reporter,
+      Map<String, String> fileReporters,
       String coverage,
       int pubServePort,
       int concurrency,
@@ -263,6 +272,7 @@
     var chosenPresetSet = chosenPresets?.toSet();
     var configuration = Configuration._(
         help: help,
+        customHtmlTemplatePath: customHtmlTemplatePath,
         version: version,
         pauseAfterLoad: pauseAfterLoad,
         debug: debug,
@@ -270,6 +280,7 @@
         configurationPath: configurationPath,
         dart2jsPath: dart2jsPath,
         reporter: reporter,
+        fileReporters: fileReporters,
         coverage: coverage,
         pubServePort: pubServePort,
         concurrency: concurrency,
@@ -323,6 +334,7 @@
   /// Unlike [new Configuration], this assumes [presets] is already resolved.
   Configuration._(
       {bool help,
+      String customHtmlTemplatePath,
       bool version,
       bool pauseAfterLoad,
       bool debug,
@@ -330,6 +342,7 @@
       String configurationPath,
       String dart2jsPath,
       String reporter,
+      Map<String, String> fileReporters,
       String coverage,
       int pubServePort,
       int concurrency,
@@ -346,6 +359,7 @@
       bool noRetry,
       SuiteConfiguration suiteDefaults})
       : _help = help,
+        customHtmlTemplatePath = customHtmlTemplatePath,
         _version = version,
         _pauseAfterLoad = pauseAfterLoad,
         _debug = debug,
@@ -353,16 +367,17 @@
         _configurationPath = configurationPath,
         _dart2jsPath = dart2jsPath,
         _reporter = reporter,
+        fileReporters = fileReporters ?? {},
         _coverage = coverage,
         pubServeUrl = pubServePort == null
             ? null
-            : Uri.parse("http://localhost:$pubServePort"),
+            : Uri.parse('http://localhost:$pubServePort'),
         _concurrency = concurrency,
         _paths = _list(paths),
         _foldTraceExcept = _set(foldTraceExcept),
         _foldTraceOnly = _set(foldTraceOnly),
         _filename = filename,
-        chosenPresets = UnmodifiableSetView(chosenPresets?.toSet() ?? Set()),
+        chosenPresets = UnmodifiableSetView(chosenPresets?.toSet() ?? {}),
         presets = _map(presets),
         overrideRuntimes = _map(overrideRuntimes),
         defineRuntimes = _map(defineRuntimes),
@@ -374,15 +389,15 @@
     if (_filename != null && _filename.context.style != p.style) {
       throw ArgumentError(
           "filename's context must match the current operating system, was "
-          "${_filename.context.style}.");
+          '${_filename.context.style}.');
     }
 
     if ((shardIndex == null) != (totalShards == null)) {
       throw ArgumentError(
-          "shardIndex and totalShards may only be passed together.");
+          'shardIndex and totalShards may only be passed together.');
     } else if (shardIndex != null) {
       RangeError.checkValueInInterval(
-          shardIndex, 0, totalShards - 1, "shardIndex");
+          shardIndex, 0, totalShards - 1, 'shardIndex');
     }
   }
 
@@ -420,7 +435,8 @@
   ///
   /// This is zone-scoped, so [this] will be the current configuration in any
   /// asynchronous callbacks transitively created by [body].
-  T asCurrent<T>(T body()) => runZoned(body, zoneValues: {_currentKey: this});
+  T asCurrent<T>(T Function() body) =>
+      runZoned(body, zoneValues: {_currentKey: this});
 
   /// Throws a [FormatException] if [this] refers to any undefined runtimes.
   void validateRuntimes(List<Runtime> allRuntimes) {
@@ -469,12 +485,15 @@
 
     var result = Configuration._(
         help: other._help ?? _help,
+        customHtmlTemplatePath:
+            other.customHtmlTemplatePath ?? customHtmlTemplatePath,
         version: other._version ?? _version,
         pauseAfterLoad: other._pauseAfterLoad ?? _pauseAfterLoad,
         color: other._color ?? _color,
         configurationPath: other._configurationPath ?? _configurationPath,
         dart2jsPath: other._dart2jsPath ?? _dart2jsPath,
         reporter: other._reporter ?? _reporter,
+        fileReporters: mergeMaps(fileReporters, other.fileReporters),
         coverage: other._coverage ?? _coverage,
         pubServePort: (other.pubServeUrl ?? pubServeUrl)?.port,
         concurrency: other._concurrency ?? _concurrency,
@@ -510,6 +529,7 @@
   /// always replaced by the new one.
   Configuration change(
       {bool help,
+      String customHtmlTemplatePath,
       bool version,
       bool pauseAfterLoad,
       bool color,
@@ -553,6 +573,8 @@
       Iterable<String> addTags}) {
     var config = Configuration._(
         help: help ?? _help,
+        customHtmlTemplatePath:
+            customHtmlTemplatePath ?? this.customHtmlTemplatePath,
         version: version ?? _version,
         pauseAfterLoad: pauseAfterLoad ?? _pauseAfterLoad,
         color: color ?? _color,
@@ -615,12 +637,12 @@
             merged.merge(newPresets.remove(preset) ?? Configuration.empty));
 
     if (merged == empty) return this;
-    var result = this.change(presets: newPresets).merge(merged);
+    var result = change(presets: newPresets).merge(merged);
 
     // Make sure the configuration knows about presets that were selected and
     // thus removed from [newPresets].
-    result._knownPresets = UnmodifiableSetView(
-        result.knownPresets.toSet()..addAll(this.presets.keys));
+    result._knownPresets =
+        UnmodifiableSetView(result.knownPresets.toSet()..addAll(presets.keys));
 
     return result;
   }
diff --git a/test_core/lib/src/runner/configuration/args.dart b/test_core/lib/src/runner/configuration/args.dart
index 0d04fdb..02e5384 100644
--- a/test_core/lib/src/runner/configuration/args.dart
+++ b/test_core/lib/src/runner/configuration/args.dart
@@ -7,11 +7,12 @@
 
 import 'package:args/args.dart';
 import 'package:boolean_selector/boolean_selector.dart';
-
 import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
 import 'package:test_api/src/frontend/timeout.dart'; // ignore: implementation_imports
-import '../runtime_selection.dart';
+
+import '../../util/io.dart';
 import '../configuration.dart';
+import '../runtime_selection.dart';
 import 'reporters.dart';
 import 'values.dart';
 
@@ -23,129 +24,133 @@
   if (!Platform.isMacOS) allRuntimes.remove(Runtime.safari);
   if (!Platform.isWindows) allRuntimes.remove(Runtime.internetExplorer);
 
-  parser.addFlag("help",
-      abbr: "h", negatable: false, help: "Shows this usage information.");
-  parser.addFlag("version",
+  parser.addFlag('help',
+      abbr: 'h', negatable: false, help: 'Shows this usage information.');
+  parser.addFlag('version',
       negatable: false, help: "Shows the package's version.");
 
   // Note that defaultsTo declarations here are only for documentation purposes.
-  // We pass null values rather than defaults to [new Configuration] so that it
-  // merges properly with the config file.
+  // We pass null instead of the default so that it merges properly with the
+  // config file.
 
-  parser.addSeparator("======== Selecting Tests");
-  parser.addMultiOption("name",
+  parser.addSeparator('======== Selecting Tests');
+  parser.addMultiOption('name',
       abbr: 'n',
       help: 'A substring of the name of the test to run.\n'
           'Regular expression syntax is supported.\n'
           'If passed multiple times, tests must match all substrings.',
       splitCommas: false);
-  parser.addMultiOption("plain-name",
+  parser.addMultiOption('plain-name',
       abbr: 'N',
       help: 'A plain-text substring of the name of the test to run.\n'
           'If passed multiple times, tests must match all substrings.',
       splitCommas: false);
-  parser.addMultiOption("tags",
+  parser.addMultiOption('tags',
       abbr: 't',
       help: 'Run only tests with all of the specified tags.\n'
           'Supports boolean selector syntax.');
-  parser.addMultiOption("tag", hide: true);
-  parser.addMultiOption("exclude-tags",
+  parser.addMultiOption('tag', hide: true);
+  parser.addMultiOption('exclude-tags',
       abbr: 'x',
       help: "Don't run tests with any of the specified tags.\n"
-          "Supports boolean selector syntax.");
-  parser.addMultiOption("exclude-tag", hide: true);
-  parser.addFlag("run-skipped",
+          'Supports boolean selector syntax.');
+  parser.addMultiOption('exclude-tag', hide: true);
+  parser.addFlag('run-skipped',
       help: 'Run skipped tests instead of skipping them.');
 
-  parser.addSeparator("======== Running Tests");
+  parser.addSeparator('======== Running Tests');
 
   // The UI term "platform" corresponds with the implementation term "runtime".
   // The [Runtime] class used to be called [TestPlatform], but it was changed to
   // avoid conflicting with [SuitePlatform]. We decided not to also change the
   // UI to avoid a painful migration.
-  parser.addMultiOption("platform",
+  parser.addMultiOption('platform',
       abbr: 'p',
       help: 'The platform(s) on which to run the tests.\n'
           '[vm (default), '
           '${allRuntimes.map((runtime) => runtime.identifier).join(", ")}]');
-  parser.addMultiOption("preset",
+  parser.addMultiOption('preset',
       abbr: 'P', help: 'The configuration preset(s) to use.');
-  parser.addOption("concurrency",
+  parser.addOption('concurrency',
       abbr: 'j',
       help: 'The number of concurrent test suites run.',
       defaultsTo: defaultConcurrency.toString(),
       valueHelp: 'threads');
-  parser.addOption("total-shards",
+  parser.addOption('total-shards',
       help: 'The total number of invocations of the test runner being run.');
-  parser.addOption("shard-index",
+  parser.addOption('shard-index',
       help: 'The index of this test runner invocation (of --total-shards).');
-  parser.addOption("pub-serve",
+  parser.addOption('pub-serve',
       help: 'The port of a pub serve instance serving "test/".',
       valueHelp: 'port');
-  parser.addOption("timeout",
+  parser.addOption('timeout',
       help: 'The default test timeout. For example: 15s, 2x, none',
       defaultsTo: '30s');
-  parser.addFlag("pause-after-load",
+  parser.addFlag('pause-after-load',
       help: 'Pauses for debugging before any tests execute.\n'
           'Implies --concurrency=1, --debug, and --timeout=none.\n'
           'Currently only supported for browser tests.',
       negatable: false);
-  parser.addFlag("debug",
+  parser.addFlag('debug',
       help: 'Runs the VM and Chrome tests in debug mode.', negatable: false);
-  parser.addOption("coverage",
+  parser.addOption('coverage',
       help: 'Gathers coverage and outputs it to the specified directory.\n'
           'Implies --debug.',
       valueHelp: 'directory');
-  parser.addFlag("chain-stack-traces",
+  parser.addFlag('chain-stack-traces',
       help: 'Chained stack traces to provide greater exception details\n'
           'especially for asynchronous code. It may be useful to disable\n'
           'to provide improved test performance but at the cost of\n'
           'debuggability.',
       defaultsTo: true);
-  parser.addFlag("no-retry",
+  parser.addFlag('no-retry',
       help: "Don't re-run tests that have retry set.",
       defaultsTo: false,
       negatable: false);
-  parser.addOption("test-randomize-ordering-seed",
-      help: 'If positive, use this as a seed to randomize the execution\n'
-          'of test cases (must be a 32bit unsigned integer).\n'
+  parser.addOption('test-randomize-ordering-seed',
+      help: 'The seed to randomize the execution order of test cases.\n'
+          'Must be a 32bit unsigned integer or "random".\n'
           'If "random", pick a random seed to use.\n'
-          'If 0 or not set, do not randomize test case execution order.\n');
+          'If not passed, do not randomize test case execution order.');
 
   var reporterDescriptions = <String, String>{};
   for (var reporter in allReporters.keys) {
     reporterDescriptions[reporter] = allReporters[reporter].description;
   }
 
-  parser.addSeparator("======== Output");
-  parser.addOption("reporter",
+  parser.addSeparator('======== Output');
+  parser.addOption('reporter',
       abbr: 'r',
       help: 'The runner used to print test results.',
       defaultsTo: defaultReporter,
       allowed: reporterDescriptions.keys.toList(),
       allowedHelp: reporterDescriptions);
-  parser.addFlag("verbose-trace",
+  parser.addOption('file-reporter',
+      help: 'The reporter used to write test results to a file.\n'
+          'Should be in the form <reporter>:<filepath>, '
+          'e.g. "json:reports/tests.json"');
+  parser.addFlag('verbose-trace',
       negatable: false,
       help: 'Whether to emit stack traces with core library frames.');
-  parser.addFlag("js-trace",
+  parser.addFlag('js-trace',
       negatable: false,
       help: 'Whether to emit raw JavaScript stack traces for browser tests.');
-  parser.addFlag("color",
+  parser.addFlag('color',
       help: 'Whether to use terminal colors.\n(auto-detected by default)');
 
   /// The following options are used only by the internal Google test runner.
   /// They're hidden and not supported as stable API surface outside Google.
 
-  parser.addOption("configuration",
+  parser.addOption('configuration',
       help: 'The path to the configuration file.', hide: true);
-  parser.addOption("dart2js-path",
+  parser.addOption('dart2js-path',
       help: 'The path to the dart2js executable.', hide: true);
-  parser.addMultiOption("dart2js-args",
+  parser.addMultiOption('dart2js-args',
       help: 'Extra arguments to pass to dart2js.', hide: true);
 
   // If we're running test/dir/my_test.dart, we'll look for
   // test/dir/my_test.dart.html in the precompiled directory.
-  parser.addOption("precompiled",
+  parser.addOption('precompiled',
       help: 'The path to a mirror of the package directory containing HTML '
           'that points to precompiled JS.',
       hide: true);
@@ -200,13 +205,13 @@
     var totalShards = _parseOption('total-shards', int.parse);
     if ((shardIndex == null) != (totalShards == null)) {
       throw FormatException(
-          "--shard-index and --total-shards may only be passed together.");
+          '--shard-index and --total-shards may only be passed together.');
     } else if (shardIndex != null) {
       if (shardIndex < 0) {
-        throw FormatException("--shard-index may not be negative.");
+        throw FormatException('--shard-index may not be negative.');
       } else if (shardIndex >= totalShards) {
         throw FormatException(
-            "--shard-index must be less than --total-shards.");
+            '--shard-index must be less than --total-shards.');
       }
     }
 
@@ -215,12 +220,26 @@
       var seed = value == 'random'
           ? Random().nextInt(4294967295)
           : int.parse(value).toUnsigned(32);
-      if (seed != null && seed > 0) {
+      if (seed != null) {
         print('Shuffling test order with --test-randomize-ordering-seed=$seed');
       }
       return seed;
     });
 
+    var color = _ifParsed<bool>('color') ?? canUseSpecialChars;
+
+    var platform = _ifParsed<List<String>>('platform')
+        ?.map((runtime) => RuntimeSelection(runtime))
+        ?.toList();
+    if (platform
+            ?.any((runtime) => runtime.name == Runtime.phantomJS.identifier) ??
+        false) {
+      var yellow = color ? '\u001b[33m' : '';
+      var noColor = color ? '\u001b[0m' : '';
+      print('${yellow}Warning:$noColor '
+          'PhatomJS is deprecated and will be removed in version ^2.0.0');
+    }
+
     return Configuration(
         help: _ifParsed('help'),
         version: _ifParsed('version'),
@@ -229,12 +248,13 @@
         jsTrace: _ifParsed('js-trace'),
         pauseAfterLoad: _ifParsed('pause-after-load'),
         debug: _ifParsed('debug'),
-        color: _ifParsed('color'),
+        color: color,
         configurationPath: _ifParsed('configuration'),
         dart2jsPath: _ifParsed('dart2js-path'),
         dart2jsArgs: _ifParsed('dart2js-args'),
         precompiledPath: _ifParsed('precompiled'),
         reporter: _ifParsed('reporter'),
+        fileReporters: _parseFileReporterOption(),
         coverage: _ifParsed('coverage'),
         pubServePort: _parseOption('pub-serve', int.parse),
         concurrency: _parseOption('concurrency', int.parse),
@@ -242,9 +262,7 @@
         totalShards: totalShards,
         timeout: _parseOption('timeout', (value) => Timeout.parse(value)),
         patterns: patterns,
-        runtimes: _ifParsed<List<String>>('platform')
-            ?.map((runtime) => RuntimeSelection(runtime))
-            ?.toList(),
+        runtimes: platform,
         runSkipped: _ifParsed('run-skipped'),
         chosenPresets: _ifParsed('preset'),
         paths: _options.rest.isEmpty ? null : _options.rest,
@@ -264,7 +282,7 @@
 
   /// Runs [parse] on the value of the option [name], and wraps any
   /// [FormatException] it throws with additional information.
-  T _parseOption<T>(String name, T parse(String value)) {
+  T _parseOption<T>(String name, T Function(String) parse) {
     if (!_options.wasParsed(name)) return null;
 
     var value = _options[name];
@@ -273,9 +291,24 @@
     return _wrapFormatException(name, () => parse(value as String));
   }
 
+  Map<String, String> _parseFileReporterOption() =>
+      _parseOption('file-reporter', (value) {
+        if (!value.contains(':')) {
+          throw FormatException(
+              'option must be in the form <reporter>:<filepath>, e.g. '
+              '"json:reports/tests.json"');
+        }
+        final sep = value.indexOf(':');
+        final reporter = value.substring(0, sep);
+        if (!allReporters.containsKey(reporter)) {
+          throw FormatException('"$reporter" is not a supported reporter');
+        }
+        return {reporter: value.substring(sep + 1)};
+      });
+
   /// Runs [parse], and wraps any [FormatException] it throws with additional
   /// information.
-  T _wrapFormatException<T>(String name, T parse()) {
+  T _wrapFormatException<T>(String name, T Function() parse) {
     try {
       return parse();
     } on FormatException catch (error) {
diff --git a/test_core/lib/src/runner/configuration/load.dart b/test_core/lib/src/runner/configuration/load.dart
index fdb5c43..d188b3e 100644
--- a/test_core/lib/src/runner/configuration/load.dart
+++ b/test_core/lib/src/runner/configuration/load.dart
@@ -27,7 +27,7 @@
 /// A regular expression matching a Dart identifier.
 ///
 /// This also matches a package name, since they must be Dart identifiers.
-final _identifierRegExp = RegExp(r"[a-zA-Z_]\w*");
+final _identifierRegExp = RegExp(r'[a-zA-Z_]\w*');
 
 /// A regular expression matching allowed package names.
 ///
@@ -35,7 +35,7 @@
 /// compatibility with Google's internal Dart packages, but they may not be used
 /// when publishing a package to pub.dev.
 final _packageName =
-    RegExp("^${_identifierRegExp.pattern}(\\.${_identifierRegExp.pattern})*\$");
+    RegExp('^${_identifierRegExp.pattern}(\\.${_identifierRegExp.pattern})*\$');
 
 /// Loads configuration information from a YAML file at [path].
 ///
@@ -52,7 +52,7 @@
 
   if (document is! Map) {
     throw SourceSpanFormatException(
-        "The configuration must be a YAML map.", document.span, source);
+        'The configuration must be a YAML map.', document.span, source);
   }
 
   var loader =
@@ -91,14 +91,14 @@
   /// If an `include` node is contained in [node], merges and returns [config].
   Configuration _loadIncludeConfig() {
     if (!_runnerConfig) {
-      _disallow("include");
+      _disallow('include');
       return Configuration.empty;
     }
 
-    var includeNode = _document.nodes["include"];
+    var includeNode = _document.nodes['include'];
     if (includeNode == null) return Configuration.empty;
 
-    var includePath = _parseNode(includeNode, "include path", p.fromUri);
+    var includePath = _parseNode(includeNode, 'include path', p.fromUri);
     var basePath =
         p.join(p.dirname(p.fromUri(_document.span.sourceUrl)), includePath);
     try {
@@ -111,22 +111,22 @@
 
   /// Loads test configuration that's allowed in the global configuration file.
   Configuration _loadGlobalTestConfig() {
-    var verboseTrace = _getBool("verbose_trace");
-    var chainStackTraces = _getBool("chain_stack_traces");
+    var verboseTrace = _getBool('verbose_trace');
+    var chainStackTraces = _getBool('chain_stack_traces');
     var foldStackFrames = _loadFoldedStackFrames();
-    var jsTrace = _getBool("js_trace");
+    var jsTrace = _getBool('js_trace');
 
-    var timeout = _parseValue("timeout", (value) => Timeout.parse(value));
+    var timeout = _parseValue('timeout', (value) => Timeout.parse(value));
 
-    var onPlatform = _getMap("on_platform",
-        key: (keyNode) => _parseNode(keyNode, "on_platform key",
+    var onPlatform = _getMap('on_platform',
+        key: (keyNode) => _parseNode(keyNode, 'on_platform key',
             (value) => PlatformSelector.parse(value, keyNode.span)),
         value: (valueNode) =>
-            _nestedConfig(valueNode, "on_platform value", runnerConfig: false));
+            _nestedConfig(valueNode, 'on_platform value', runnerConfig: false));
 
-    var onOS = _getMap("on_os",
+    var onOS = _getMap('on_os',
         key: (keyNode) {
-          _validate(keyNode, "on_os key must be a string.",
+          _validate(keyNode, 'on_os key must be a string.',
               (value) => value is String);
 
           var os = OperatingSystem.find(keyNode.value as String);
@@ -137,11 +137,11 @@
               keyNode.span,
               _source);
         },
-        value: (valueNode) => _nestedConfig(valueNode, "on_os value"));
+        value: (valueNode) => _nestedConfig(valueNode, 'on_os value'));
 
-    var presets = _getMap("presets",
-        key: (keyNode) => _parseIdentifierLike(keyNode, "presets key"),
-        value: (valueNode) => _nestedConfig(valueNode, "presets value"));
+    var presets = _getMap('presets',
+        key: (keyNode) => _parseIdentifierLike(keyNode, 'presets key'),
+        value: (valueNode) => _nestedConfig(valueNode, 'presets value'));
 
     var config = Configuration(
             verboseTrace: verboseTrace,
@@ -149,8 +149,8 @@
             timeout: timeout,
             presets: presets,
             chainStackTraces: chainStackTraces,
-            foldTraceExcept: foldStackFrames["except"],
-            foldTraceOnly: foldStackFrames["only"])
+            foldTraceExcept: foldStackFrames['except'],
+            foldTraceOnly: foldStackFrames['only'])
         .merge(_extractPresets<PlatformSelector>(
             onPlatform, (map) => Configuration(onPlatform: map)));
 
@@ -165,15 +165,15 @@
   /// configuration fields.
   Configuration _loadLocalTestConfig() {
     if (_global) {
-      _disallow("skip");
-      _disallow("retry");
-      _disallow("test_on");
-      _disallow("add_tags");
-      _disallow("tags");
+      _disallow('skip');
+      _disallow('retry');
+      _disallow('test_on');
+      _disallow('add_tags');
+      _disallow('tags');
       return Configuration.empty;
     }
 
-    var skipRaw = _getValue("skip", "boolean or string",
+    var skipRaw = _getValue('skip', 'boolean or string',
         (value) => value is bool || value is String);
     String skipReason;
     bool skip;
@@ -184,18 +184,18 @@
       skip = skipRaw as bool;
     }
 
-    var testOn = _parsePlatformSelector("test_on");
+    var testOn = _parsePlatformSelector('test_on');
 
     var addTags = _getList(
-        "add_tags", (tagNode) => _parseIdentifierLike(tagNode, "Tag name"));
+        'add_tags', (tagNode) => _parseIdentifierLike(tagNode, 'Tag name'));
 
-    var tags = _getMap("tags",
+    var tags = _getMap('tags',
         key: (keyNode) => _parseNode(
-            keyNode, "tags key", (value) => BooleanSelector.parse(value)),
+            keyNode, 'tags key', (value) => BooleanSelector.parse(value)),
         value: (valueNode) =>
-            _nestedConfig(valueNode, "tag value", runnerConfig: false));
+            _nestedConfig(valueNode, 'tag value', runnerConfig: false));
 
-    var retry = _getNonNegativeInt("retry");
+    var retry = _getNonNegativeInt('retry');
 
     return Configuration(
             skip: skip,
@@ -214,47 +214,66 @@
   /// runner-level configuration fields.
   Configuration _loadGlobalRunnerConfig() {
     if (!_runnerConfig) {
-      _disallow("pause_after_load");
-      _disallow("reporter");
-      _disallow("concurrency");
-      _disallow("names");
-      _disallow("plain_names");
-      _disallow("platforms");
-      _disallow("add_presets");
-      _disallow("override_platforms");
-      _disallow("include");
+      _disallow('pause_after_load');
+      _disallow('reporter');
+      _disallow('file_reporters');
+      _disallow('concurrency');
+      _disallow('names');
+      _disallow('plain_names');
+      _disallow('platforms');
+      _disallow('add_presets');
+      _disallow('override_platforms');
+      _disallow('include');
       return Configuration.empty;
     }
 
-    var pauseAfterLoad = _getBool("pause_after_load");
-    var runSkipped = _getBool("run_skipped");
+    var pauseAfterLoad = _getBool('pause_after_load');
+    var runSkipped = _getBool('run_skipped');
 
-    var reporter = _getString("reporter");
+    var reporter = _getString('reporter');
     if (reporter != null && !allReporters.keys.contains(reporter)) {
-      _error('Unknown reporter "$reporter".', "reporter");
+      _error('Unknown reporter "$reporter".', 'reporter');
     }
 
-    var concurrency = _getInt("concurrency");
+    var fileReporters = _getMap('file_reporters', key: (keyNode) {
+      _validate(keyNode, 'file_reporters key must be a string',
+          (value) => value is String);
+      final reporter = keyNode.value as String;
+      if (!allReporters.keys.contains(reporter)) {
+        _error('Unknown reporter "$reporter".', 'file_reporters');
+      }
+      return reporter;
+    }, value: (valueNode) {
+      _validate(valueNode, 'file_reporters value must be a string',
+          (value) => value is String);
+      return valueNode.value as String;
+    });
+
+    var concurrency = _getInt('concurrency');
 
     // The UI term "platform" corresponds with the implementation term
     // "runtime". The [Runtime] class used to be called [TestPlatform], but it
     // was changed to avoid conflicting with [SuitePlatform]. We decided not to
     // also change the UI to avoid a painful migration.
     var runtimes = _getList(
-        "platforms",
+        'platforms',
         (runtimeNode) => RuntimeSelection(
-            _parseIdentifierLike(runtimeNode, "Platform name"),
+            _parseIdentifierLike(runtimeNode, 'Platform name'),
             runtimeNode.span));
 
-    var chosenPresets = _getList("add_presets",
-        (presetNode) => _parseIdentifierLike(presetNode, "Preset name"));
+    var chosenPresets = _getList('add_presets',
+        (presetNode) => _parseIdentifierLike(presetNode, 'Preset name'));
 
     var overrideRuntimes = _loadOverrideRuntimes();
 
+    var customHtmlTemplatePath = _getString('custom_html_template_path');
+
     return Configuration(
         pauseAfterLoad: pauseAfterLoad,
+        customHtmlTemplatePath: customHtmlTemplatePath,
         runSkipped: runSkipped,
         reporter: reporter,
+        fileReporters: fileReporters,
         concurrency: concurrency,
         runtimes: runtimes,
         chosenPresets: chosenPresets,
@@ -264,21 +283,21 @@
   /// Loads the `override_platforms` field.
   Map<String, RuntimeSettings> _loadOverrideRuntimes() {
     var runtimesNode =
-        _getNode("override_platforms", "map", (value) => value is Map)
+        _getNode('override_platforms', 'map', (value) => value is Map)
             as YamlMap;
     if (runtimesNode == null) return const {};
 
     var runtimes = <String, RuntimeSettings>{};
     runtimesNode.nodes.forEach((identifierNode, valueNode) {
       var identifier = _parseIdentifierLike(
-          identifierNode as YamlNode, "Platform identifier");
+          identifierNode as YamlNode, 'Platform identifier');
 
-      _validate(valueNode, "Platform definition must be a map.",
+      _validate(valueNode, 'Platform definition must be a map.',
           (value) => value is Map);
       var map = valueNode as YamlMap;
 
-      var settings = _expect(map, "settings");
-      _validate(settings, "Must be a map.", (value) => value is Map);
+      var settings = _expect(map, 'settings');
+      _validate(settings, 'Must be a map.', (value) => value is Map);
 
       runtimes[identifier] = RuntimeSettings(
           identifier, (identifierNode as YamlNode).span, [settings as YamlMap]);
@@ -293,41 +312,41 @@
   /// if there are any local test-level configuration fields.
   Configuration _loadLocalRunnerConfig() {
     if (!_runnerConfig || _global) {
-      _disallow("pub_serve");
-      _disallow("names");
-      _disallow("plain_names");
-      _disallow("paths");
-      _disallow("filename");
-      _disallow("include_tags");
-      _disallow("exclude_tags");
-      _disallow("define_platforms");
+      _disallow('pub_serve');
+      _disallow('names');
+      _disallow('plain_names');
+      _disallow('paths');
+      _disallow('filename');
+      _disallow('include_tags');
+      _disallow('exclude_tags');
+      _disallow('define_platforms');
       return Configuration.empty;
     }
 
-    var pubServePort = _getInt("pub_serve");
+    var pubServePort = _getInt('pub_serve');
 
-    var patterns = _getList("names", (nameNode) {
-      _validate(nameNode, "Names must be strings.", (value) => value is String);
-      return _parseNode(nameNode, "name", (value) => RegExp(value));
+    var patterns = _getList('names', (nameNode) {
+      _validate(nameNode, 'Names must be strings.', (value) => value is String);
+      return _parseNode(nameNode, 'name', (value) => RegExp(value));
     })
-      ..addAll(_getList("plain_names", (nameNode) {
+      ..addAll(_getList('plain_names', (nameNode) {
         _validate(
-            nameNode, "Names must be strings.", (value) => value is String);
-        return _parseNode(nameNode, "name", (value) => RegExp(value));
+            nameNode, 'Names must be strings.', (value) => value is String);
+        return _parseNode(nameNode, 'name', (value) => RegExp(value));
       }));
 
-    var paths = _getList("paths", (pathNode) {
-      _validate(pathNode, "Paths must be strings.", (value) => value is String);
-      _validate(pathNode, "Paths must be relative.",
+    var paths = _getList('paths', (pathNode) {
+      _validate(pathNode, 'Paths must be strings.', (value) => value is String);
+      _validate(pathNode, 'Paths must be relative.',
           (value) => p.url.isRelative(value as String));
 
-      return _parseNode(pathNode, "path", p.fromUri);
+      return _parseNode(pathNode, 'path', p.fromUri);
     });
 
-    var filename = _parseValue("filename", (value) => Glob(value));
+    var filename = _parseValue('filename', (value) => Glob(value));
 
-    var includeTags = _parseBooleanSelector("include_tags");
-    var excludeTags = _parseBooleanSelector("exclude_tags");
+    var includeTags = _parseBooleanSelector('include_tags');
+    var excludeTags = _parseBooleanSelector('exclude_tags');
 
     var defineRuntimes = _loadDefineRuntimes();
 
@@ -348,10 +367,10 @@
   /// test [Chain].
   Map<String, List<String>> _loadFoldedStackFrames() {
     var foldOptionSet = false;
-    return _getMap("fold_stack_frames", key: (keyNode) {
-      _validate(keyNode, "Must be a string", (value) => value is String);
+    return _getMap('fold_stack_frames', key: (keyNode) {
+      _validate(keyNode, 'Must be a string', (value) => value is String);
       _validate(keyNode, 'Must be "only" or "except".',
-          (value) => value == "only" || value == "except");
+          (value) => value == 'only' || value == 'except');
 
       if (foldOptionSet) {
         throw SourceSpanFormatException(
@@ -364,14 +383,14 @@
     }, value: (valueNode) {
       _validate(
           valueNode,
-          "Folded packages must be strings.",
+          'Folded packages must be strings.',
           (valueList) =>
               valueList is YamlList &&
               valueList.every((value) => value is String));
 
       _validate(
           valueNode,
-          "Invalid package name.",
+          'Invalid package name.',
           (valueList) => (valueList as Iterable)
               .every((value) => _packageName.hasMatch(value as String)));
 
@@ -382,27 +401,27 @@
   /// Loads the `define_platforms` field.
   Map<String, CustomRuntime> _loadDefineRuntimes() {
     var runtimesNode =
-        _getNode("define_platforms", "map", (value) => value is Map) as YamlMap;
+        _getNode('define_platforms', 'map', (value) => value is Map) as YamlMap;
     if (runtimesNode == null) return const {};
 
     var runtimes = <String, CustomRuntime>{};
     runtimesNode.nodes.forEach((identifierNode, valueNode) {
       var identifier = _parseIdentifierLike(
-          identifierNode as YamlNode, "Platform identifier");
+          identifierNode as YamlNode, 'Platform identifier');
 
-      _validate(valueNode, "Platform definition must be a map.",
+      _validate(valueNode, 'Platform definition must be a map.',
           (value) => value is Map);
       var map = valueNode as YamlMap;
 
-      var nameNode = _expect(map, "name");
-      _validate(nameNode, "Must be a string.", (value) => value is String);
+      var nameNode = _expect(map, 'name');
+      _validate(nameNode, 'Must be a string.', (value) => value is String);
       var name = nameNode.value as String;
 
-      var parentNode = _expect(map, "extends");
-      var parent = _parseIdentifierLike(parentNode, "Platform parent");
+      var parentNode = _expect(map, 'extends');
+      var parent = _parseIdentifierLike(parentNode, 'Platform parent');
 
-      var settings = _expect(map, "settings");
-      _validate(settings, "Must be a map.", (value) => value is Map);
+      var settings = _expect(map, 'settings');
+      _validate(settings, 'Must be a map.', (value) => value is Map);
 
       runtimes[identifier] = CustomRuntime(
           name,
@@ -418,7 +437,7 @@
 
   /// Throws an exception with [message] if [test] returns `false` when passed
   /// [node]'s value.
-  void _validate(YamlNode node, String message, bool test(value)) {
+  void _validate(YamlNode node, String message, bool Function(dynamic) test) {
     if (test(node.value)) return;
     throw SourceSpanFormatException(message, node.span, _source);
   }
@@ -427,45 +446,47 @@
   ///
   /// If [typeTest] returns `false` for that value, instead throws an error
   /// complaining that the field is not a [typeName].
-  _getValue(String field, String typeName, bool typeTest(value)) {
+  dynamic _getValue(
+      String field, String typeName, bool Function(dynamic) typeTest) {
     var value = _document[field];
     if (value == null || typeTest(value)) return value;
-    _error("$field must be ${a(typeName)}.", field);
+    _error('$field must be ${a(typeName)}.', field);
   }
 
   /// Returns the YAML node at [field].
   ///
   /// If [typeTest] returns `false` for that node's value, instead throws an
   /// error complaining that the field is not a [typeName].
-  YamlNode _getNode(String field, String typeName, bool typeTest(value)) {
+  YamlNode _getNode(
+      String field, String typeName, bool Function(dynamic) typeTest) {
     var node = _document.nodes[field];
     if (node == null) return null;
-    _validate(node, "$field must be ${a(typeName)}.", typeTest);
+    _validate(node, '$field must be ${a(typeName)}.', typeTest);
     return node;
   }
 
   /// Asserts that [field] is an int and returns its value.
   int _getInt(String field) =>
-      _getValue(field, "int", (value) => value is int) as int;
+      _getValue(field, 'int', (value) => value is int) as int;
 
   /// Asserts that [field] is a non-negative int and returns its value.
   int _getNonNegativeInt(String field) => _getValue(
-      field, "non-negative int", (value) => value is int && value >= 0) as int;
+      field, 'non-negative int', (value) => value is int && value >= 0) as int;
 
   /// Asserts that [field] is a boolean and returns its value.
   bool _getBool(String field) =>
-      _getValue(field, "boolean", (value) => value is bool) as bool;
+      _getValue(field, 'boolean', (value) => value is bool) as bool;
 
   /// Asserts that [field] is a string and returns its value.
   String _getString(String field) =>
-      _getValue(field, "string", (value) => value is String) as String;
+      _getValue(field, 'string', (value) => value is String) as String;
 
   /// Asserts that [field] is a list and runs [forElement] for each element it
   /// contains.
   ///
   /// Returns a list of values returned by [forElement].
-  List<T> _getList<T>(String field, T forElement(YamlNode elementNode)) {
-    var node = _getNode(field, "list", (value) => value is List) as YamlList;
+  List<T> _getList<T>(String field, T Function(YamlNode) forElement) {
+    var node = _getNode(field, 'list', (value) => value is List) as YamlList;
     if (node == null) return [];
     return node.nodes.map(forElement).toList();
   }
@@ -475,19 +496,19 @@
   /// Returns a map with the keys and values returned by [key] and [value]. Each
   /// of these defaults to asserting that the value is a string.
   Map<K, V> _getMap<K, V>(String field,
-      {K key(YamlNode keyNode), V value(YamlNode valueNode)}) {
-    var node = _getNode(field, "map", (value) => value is Map) as YamlMap;
+      {K Function(YamlNode) key, V Function(YamlNode) value}) {
+    var node = _getNode(field, 'map', (value) => value is Map) as YamlMap;
     if (node == null) return {};
 
     key ??= (keyNode) {
       _validate(
-          keyNode, "$field keys must be strings.", (value) => value is String);
+          keyNode, '$field keys must be strings.', (value) => value is String);
 
       return keyNode.value as K;
     };
 
     value ??= (valueNode) {
-      _validate(valueNode, "$field values must be strings.",
+      _validate(valueNode, '$field values must be strings.',
           (value) => value is String);
 
       return valueNode.value as V;
@@ -500,8 +521,8 @@
   /// Verifies that [node]'s value is an optionally hyphenated Dart identifier,
   /// and returns it
   String _parseIdentifierLike(YamlNode node, String name) {
-    _validate(node, "$name must be a string.", (value) => value is String);
-    _validate(node, "$name must be an (optionally hyphenated) Dart identifier.",
+    _validate(node, '$name must be a string.', (value) => value is String);
+    _validate(node, '$name must be an (optionally hyphenated) Dart identifier.',
         (value) => (value as String).contains(anchoredHyphenatedIdentifier));
     return node.value as String;
   }
@@ -523,8 +544,8 @@
   ///
   /// If [parse] throws a [FormatException], it's wrapped to include [node]'s
   /// span.
-  T _parseNode<T>(YamlNode node, String name, T parse(String value)) {
-    _validate(node, "$name must be a string.", (value) => value is String);
+  T _parseNode<T>(YamlNode node, String name, T Function(String) parse) {
+    _validate(node, '$name must be a string.', (value) => value is String);
 
     try {
       return parse(node.value as String);
@@ -539,7 +560,7 @@
   ///
   /// If [parse] throws a [FormatException], it's wrapped to include [field]'s
   /// span.
-  T _parseValue<T>(String field, T parse(String value)) {
+  T _parseValue<T>(String field, T Function(String) parse) {
     var node = _document.nodes[field];
     if (node == null) return null;
     return _parseNode(node, field, parse);
@@ -553,7 +574,7 @@
   Configuration _nestedConfig(YamlNode node, String name, {bool runnerConfig}) {
     if (node == null || node.value == null) return Configuration.empty;
 
-    _validate(node, "$name must be a map.", (value) => value is Map);
+    _validate(node, '$name must be a map.', (value) => value is Map);
     var loader = _ConfigurationLoader(node as YamlMap, _source,
         global: _global, runnerConfig: runnerConfig ?? _runnerConfig);
     return loader.load();
@@ -569,7 +590,7 @@
   /// [SuiteConfiguration]s. The [create] function is used to construct
   /// [Configuration]s from the resolved maps.
   Configuration _extractPresets<T>(Map<T, Configuration> map,
-      Configuration create(Map<T, SuiteConfiguration> map)) {
+      Configuration Function(Map<T, SuiteConfiguration>) create) {
     if (map.isEmpty) return Configuration.empty;
 
     var base = <T, SuiteConfiguration>{};
diff --git a/test_core/lib/src/runner/configuration/reporters.dart b/test_core/lib/src/runner/configuration/reporters.dart
index 7fe1656..dc557cf 100644
--- a/test_core/lib/src/runner/configuration/reporters.dart
+++ b/test_core/lib/src/runner/configuration/reporters.dart
@@ -29,17 +29,17 @@
     UnmodifiableMapView<String, ReporterDetails>(_allReporters);
 
 final _allReporters = <String, ReporterDetails>{
-  "expanded": ReporterDetails(
-      "A separate line for each update.",
+  'expanded': ReporterDetails(
+      'A separate line for each update.',
       (config, engine, sink) => ExpandedReporter.watch(engine, sink,
           color: config.color,
           printPath: config.paths.length > 1 ||
               Directory(config.paths.single).existsSync(),
           printPlatform: config.suiteDefaults.runtimes.length > 1)),
-  "compact": ReporterDetails("A single line, updated continuously.",
+  'compact': ReporterDetails('A single line, updated continuously.',
       (_, engine, sink) => CompactReporter.watch(engine, sink)),
-  "json": ReporterDetails(
-      "A machine-readable format (see https://goo.gl/gBsV1a).",
+  'json': ReporterDetails(
+      'A machine-readable format (see https://goo.gl/gBsV1a).',
       (_, engine, sink) => JsonReporter.watch(engine, sink)),
 };
 
diff --git a/test_core/lib/src/runner/configuration/values.dart b/test_core/lib/src/runner/configuration/values.dart
index 37abc16..6e2f50a 100644
--- a/test_core/lib/src/runner/configuration/values.dart
+++ b/test_core/lib/src/runner/configuration/values.dart
@@ -16,4 +16,4 @@
 /// The default filename pattern.
 ///
 /// This is stored here so that we don't have to recompile it multiple times.
-final defaultFilename = Glob("*_test.dart");
+final defaultFilename = Glob('*_test.dart');
diff --git a/test_core/lib/src/runner/console.dart b/test_core/lib/src/runner/console.dart
index 85fd112..1592d6d 100644
--- a/test_core/lib/src/runner/console.dart
+++ b/test_core/lib/src/runner/console.dart
@@ -6,8 +6,7 @@
 import 'dart:math' as math;
 
 import 'package:async/async.dart';
-
-import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
+import 'package:pedantic/pedantic.dart';
 
 import '../util/io.dart';
 
@@ -41,7 +40,7 @@
       : _red = color ? '\u001b[31m' : '',
         _bold = color ? '\u001b[1m' : '',
         _noColor = color ? '\u001b[0m' : '' {
-    registerCommand("help", "Displays this help information.", _displayHelp);
+    registerCommand('help', 'Displays this help information.', _displayHelp);
   }
 
   /// Registers a command to be run whenever the user types [name].
@@ -49,7 +48,8 @@
   /// The [description] should be a one-line description of the command to print
   /// in the help output. The [body] callback will be called when the user types
   /// the command, and may return a [Future].
-  void registerCommand(String name, String description, body()) {
+  void registerCommand(
+      String name, String description, dynamic Function() body) {
     if (_commands.containsKey(name)) {
       throw ArgumentError('The console already has a command named "$name".');
     }
@@ -62,9 +62,9 @@
   /// This prints the initial prompt and loops while waiting for user input.
   void start() {
     _running = true;
-    invoke(() async {
+    unawaited(() async {
       while (_running) {
-        stdout.write("> ");
+        stdout.write('> ');
         _nextLine = stdinLines.cancelable((queue) => queue.next);
         var commandName = await _nextLine.value;
         _nextLine = null;
@@ -72,13 +72,13 @@
         var command = _commands[commandName];
         if (command == null) {
           stderr.writeln(
-              "${_red}Unknown command $_bold$commandName$_noColor$_red."
-              "$_noColor");
+              '${_red}Unknown command $_bold$commandName$_noColor$_red.'
+              '$_noColor');
         } else {
           await command.body();
         }
       }
-    });
+    }());
   }
 
   /// Stops the console running.
@@ -97,7 +97,7 @@
 
     for (var command in _commands.values) {
       var name = command.name.padRight(maxCommandLength + 4);
-      print("$_bold$name$_noColor${command.description}");
+      print('$_bold$name$_noColor${command.description}');
     }
   }
 }
diff --git a/test_core/lib/src/runner/coverage.dart b/test_core/lib/src/runner/coverage.dart
index 7dc2184..841bdd7 100644
--- a/test_core/lib/src/runner/coverage.dart
+++ b/test_core/lib/src/runner/coverage.dart
@@ -5,30 +5,20 @@
 import 'dart:convert';
 import 'dart:io';
 
-import 'package:coverage/coverage.dart';
 import 'package:path/path.dart' as p;
 
 import 'live_suite_controller.dart';
-import 'runner_suite.dart';
 
-/// Collects coverage and outputs to the [coverage] path.
-Future<void> gatherCoverage(
-    String coverage, LiveSuiteController controller) async {
-  final RunnerSuite suite = controller.liveSuite.suite;
-
-  if (!suite.platform.runtime.isDartVM) return;
-
-  final String isolateId = Uri.parse(suite.environment.observatoryUrl.fragment)
-      .queryParameters['isolateId'];
-
-  final cov = await collect(
-      suite.environment.observatoryUrl, false, false, false, Set(),
-      isolateIds: {isolateId});
-
-  final outfile = File(p.join('$coverage', '${suite.path}.vm.json'))
+/// Collects coverage and outputs to the [coveragePath] path.
+Future<void> writeCoverage(
+    String coveragePath, LiveSuiteController controller) async {
+  var suite = controller.liveSuite.suite;
+  var coverage = await controller.liveSuite.suite.gatherCoverage();
+  final outfile = File(p.join(coveragePath,
+      '${suite.path}.${suite.platform.runtime.name.toLowerCase()}.json'))
     ..createSync(recursive: true);
-  final IOSink out = outfile.openWrite();
-  out.write(json.encode(cov));
+  final out = outfile.openWrite();
+  out.write(json.encode(coverage));
   await out.flush();
   await out.close();
 }
diff --git a/test_core/lib/src/runner/coverage_stub.dart b/test_core/lib/src/runner/coverage_stub.dart
index 5a2285f..64f69c7 100644
--- a/test_core/lib/src/runner/coverage_stub.dart
+++ b/test_core/lib/src/runner/coverage_stub.dart
@@ -4,6 +4,7 @@
 
 import 'live_suite_controller.dart';
 
-Future<void> gatherCoverage(String coverage, LiveSuiteController controller) =>
+Future<void> writeCoverage(
+        String coveragePath, LiveSuiteController controller) =>
     throw UnsupportedError(
         'Coverage is only supported through the test runner.');
diff --git a/test_core/lib/src/runner/debugger.dart b/test_core/lib/src/runner/debugger.dart
index e273d1c..524f08e 100644
--- a/test_core/lib/src/runner/debugger.dart
+++ b/test_core/lib/src/runner/debugger.dart
@@ -89,8 +89,8 @@
 
   _Debugger(this._engine, this._reporter, this._suite)
       : _console = Console(color: Configuration.current.color) {
-    _console.registerCommand("restart",
-        "Restart the current test after it finishes running.", _restartTest);
+    _console.registerCommand('restart',
+        'Restart the current test after it finishes running.', _restartTest);
 
     _onRestartSubscription = _suite.environment.onRestart.listen((_) {
       _restartTest();
@@ -141,35 +141,35 @@
           var url = _suite.environment.observatoryUrl;
           if (url == null) {
             print("${yellow}Observatory URL not found. Make sure you're using "
-                "${runtime.name} 1.11 or later.$noColor");
+                '${runtime.name} 1.11 or later.$noColor');
           } else {
-            print("Observatory URL: $bold$url$noColor");
+            print('Observatory URL: $bold$url$noColor');
           }
         }
 
         if (runtime.isHeadless && !runtime.isDartVM) {
           var url = _suite.environment.remoteDebuggerUrl;
           if (url == null) {
-            print("${yellow}Remote debugger URL not found.$noColor");
+            print('${yellow}Remote debugger URL not found.$noColor');
           } else {
-            print("Remote debugger URL: $bold$url$noColor");
+            print('Remote debugger URL: $bold$url$noColor');
           }
         }
 
         var buffer =
-            StringBuffer("${bold}The test runner is paused.${noColor} ");
+            StringBuffer('${bold}The test runner is paused.${noColor} ');
         if (runtime.isDartVM) {
-          buffer.write("Open the Observatory ");
+          buffer.write('Open the Observatory ');
         } else {
           if (!runtime.isHeadless) {
-            buffer.write("Open the dev console in $runtime ");
+            buffer.write('Open the dev console in $runtime ');
           } else {
-            buffer.write("Open the remote debugger ");
+            buffer.write('Open the remote debugger ');
           }
         }
 
         buffer.write("and set breakpoints. Once you're finished, return to "
-            "this terminal and press Enter.");
+            'this terminal and press Enter.');
 
         print(wordWrap(buffer.toString()));
       }
diff --git a/test_core/lib/src/runner/engine.dart b/test_core/lib/src/runner/engine.dart
index 812d7a8..a60ea7f 100644
--- a/test_core/lib/src/runner/engine.dart
+++ b/test_core/lib/src/runner/engine.dart
@@ -73,12 +73,6 @@
   /// A pool that limits the number of test suites running concurrently.
   final Pool _runPool;
 
-  /// A pool that limits the number of test suites loaded concurrently.
-  ///
-  /// Once this reaches its limit, loading any additional test suites will cause
-  /// previous suites to be unloaded in the order they completed.
-  final Pool _loadPool;
-
   /// A completer that will complete when [this] is unpaused.
   ///
   /// If [this] isn't paused, [_pauseCompleter] is `null`.
@@ -96,8 +90,7 @@
   /// This will be `null` if [close] was called before all the tests finished
   /// running.
   Future<bool> get success async {
-    await Future.wait(<Future>[_group.future, _loadPool.done],
-        eagerError: true);
+    await Future.wait(<Future>[_group.future, _runPool.done], eagerError: true);
     if (_closedBeforeDone) return null;
     return liveTests.every((liveTest) =>
         liveTest.state.result.isPassing &&
@@ -108,7 +101,7 @@
   final _group = FutureGroup();
 
   /// All of the engine's stream subscriptions.
-  final _subscriptions = Set<StreamSubscription>();
+  final _subscriptions = <StreamSubscription>{};
 
   /// A sink used to pass [RunnerSuite]s in to the engine to run.
   ///
@@ -125,7 +118,7 @@
   /// Note that if a [LoadSuite] is added, this will only contain that suite,
   /// not the suite it loads.
   Set<RunnerSuite> get addedSuites => UnmodifiableSetView(_addedSuites);
-  final _addedSuites = Set<RunnerSuite>();
+  final _addedSuites = <RunnerSuite>{};
 
   /// A broadcast stream that emits each [RunnerSuite] as it's added to the
   /// engine via [suiteSink].
@@ -146,7 +139,7 @@
   /// [LoadSuite]s, both the [LoadSuite] and the suite it loads will eventually
   /// be in this set.
   Set<LiveSuite> get liveSuites => UnmodifiableSetView(_liveSuites);
-  final _liveSuites = Set<LiveSuite>();
+  final _liveSuites = <LiveSuite>{};
 
   /// A broadcast stream that emits each [LiveSuite] as it's loaded.
   ///
@@ -196,13 +189,13 @@
   ///
   /// This is always a subset of [active]. Once a test in here has finished
   /// running, it's run again.
-  final _restarted = Set<LiveTest>();
+  final _restarted = <LiveTest>{};
 
   /// The tests from [LoadSuite]s that are still running, in the order they
   /// began running.
   ///
   /// This is separate from [active] because load tests aren't always surfaced.
-  final _activeLoadTests = List<LiveTest>();
+  final _activeLoadTests = <LiveTest>{};
 
   /// Whether this engine is idle—that is, not currently executing a test.
   bool get isIdle => _group.isIdle;
@@ -215,17 +208,15 @@
   // dart:io is unavailable.
   /// Creates an [Engine] that will run all tests provided via [suiteSink].
   ///
-  /// [concurrency] controls how many suites are run at once, and defaults to 1.
-  /// [maxSuites] controls how many suites are *loaded* at once, and defaults to
-  /// four times [concurrency].
-  Engine({int concurrency, int maxSuites, String coverage})
+  /// [concurrency] controls how many suites are loaded and ran at once, and
+  /// defaults to 1.
+  Engine({int concurrency, String coverage})
       : _runPool = Pool(concurrency ?? 1),
-        _loadPool = Pool(maxSuites ?? (concurrency ?? 1) * 2),
         _coverage = coverage {
     _group.future.then((_) {
       _onTestStartedGroup.close();
       _onSuiteStartedController.close();
-      if (_closedBeforeDone == null) _closedBeforeDone = false;
+      _closedBeforeDone ??= false;
     }).catchError((_) {
       // Don't top-level errors. They'll be thrown via [success] anyway.
     });
@@ -255,7 +246,7 @@
   /// closed.
   Future<bool> run() {
     if (_runCalled) {
-      throw StateError("Engine.run() may not be called more than once.");
+      throw StateError('Engine.run() may not be called more than once.');
     }
     _runCalled = true;
 
@@ -265,35 +256,32 @@
       _onSuiteAddedController.add(suite);
 
       _group.add(() async {
-        var loadResource = await _loadPool.request();
-
+        var resource = await _runPool.request();
         LiveSuiteController controller;
-        if (suite is LoadSuite) {
-          await _onUnpaused;
-          controller = await _addLoadSuite(suite);
-          if (controller == null) {
-            loadResource.release();
-            return;
+        try {
+          if (suite is LoadSuite) {
+            await _onUnpaused;
+            controller = await _addLoadSuite(suite);
+            if (controller == null) return;
+          } else {
+            controller = LiveSuiteController(suite);
           }
-        } else {
-          controller = LiveSuiteController(suite);
-        }
 
-        _addLiveSuite(controller.liveSuite);
+          _addLiveSuite(controller.liveSuite);
 
-        await _runPool.withResource(() async {
           if (_closed) return;
           await _runGroup(controller, controller.liveSuite.suite.group, []);
           controller.noMoreLiveTests();
-          if (_coverage != null) await gatherCoverage(_coverage, controller);
-          loadResource.allowRelease(() => controller.close());
-        });
+          if (_coverage != null) await writeCoverage(_coverage, controller);
+        } finally {
+          resource.allowRelease(() => controller?.close());
+        }
       }());
     }, onDone: () {
       _subscriptions.remove(subscription);
       _onSuiteAddedController.close();
       _group.close();
-      _loadPool.close();
+      _runPool.close();
     });
     _subscriptions.add(subscription);
 
@@ -323,7 +311,8 @@
       if (!_closed && setUpAllSucceeded) {
         // shuffle the group entries
         var entries = group.entries.toList();
-        if (suiteConfig.testRandomizeOrderingSeed > 0) {
+        if (suiteConfig.testRandomizeOrderingSeed != null &&
+            suiteConfig.testRandomizeOrderingSeed > 0) {
           entries.shuffle(Random(suiteConfig.testRandomizeOrderingSeed));
         }
 
@@ -416,7 +405,7 @@
 
       if (skipped.metadata.skipReason != null) {
         controller
-            .message(Message.skip("Skip: ${skipped.metadata.skipReason}"));
+            .message(Message.skip('Skip: ${skipped.metadata.skipReason}'));
       }
 
       controller.setState(const State(Status.complete, Result.skipped));
@@ -437,7 +426,7 @@
 
     if (!_active.contains(liveTest)) {
       throw StateError("Can't restart inactive test "
-          "\"${liveTest.test.name}\".");
+          '\"${liveTest.test.name}\".');
     }
 
     _restarted.add(liveTest);
@@ -545,23 +534,21 @@
   /// Closing [suiteSink] indicates that no more input will be provided, closing
   /// the engine indicates that no more output should be emitted.
   Future close() async {
-    // TODO(grouma) - Remove this unecessary await.
-    await Future(() {});
     _closed = true;
     if (_closedBeforeDone != null) _closedBeforeDone = true;
-    await _onSuiteAddedController.close();
     await _suiteController.close();
+    await _onSuiteAddedController.close();
 
     // Close the running tests first so that we're sure to wait for them to
     // finish before we close their suites and cause them to become unloaded.
     var allLiveTests = liveTests.toSet()..addAll(_activeLoadTests);
     var futures = allLiveTests.map((liveTest) => liveTest.close()).toList();
 
-    // Closing the load pool will close the test suites as soon as their tests
+    // Closing the run pool will close the test suites as soon as their tests
     // are done. For browser suites this is effectively immediate since their
     // tests shut down as soon as they're closed, but for VM suites we may need
     // to wait for tearDowns or tearDownAlls to run.
-    futures.add(_loadPool.close());
+    futures.add(_runPool.close());
     await Future.wait(futures, eagerError: true);
   }
 }
diff --git a/test_core/lib/src/runner/environment.dart b/test_core/lib/src/runner/environment.dart
index 164aaa4..2ddfdb3 100644
--- a/test_core/lib/src/runner/environment.dart
+++ b/test_core/lib/src/runner/environment.dart
@@ -36,15 +36,20 @@
 
 /// The default environment for platform plugins.
 class PluginEnvironment implements Environment {
+  @override
   final supportsDebugging = false;
+  @override
   Stream get onRestart => StreamController.broadcast().stream;
 
   const PluginEnvironment();
 
+  @override
   Uri get observatoryUrl => null;
 
+  @override
   Uri get remoteDebuggerUrl => null;
 
+  @override
   CancelableOperation displayPause() => throw UnsupportedError(
-      "PluginEnvironment.displayPause is not supported.");
+      'PluginEnvironment.displayPause is not supported.');
 }
diff --git a/test_core/lib/src/runner/hybrid_listener.dart b/test_core/lib/src/runner/hybrid_listener.dart
index c818a59..022405b 100644
--- a/test_core/lib/src/runner/hybrid_listener.dart
+++ b/test_core/lib/src/runner/hybrid_listener.dart
@@ -2,14 +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.
 
-import "dart:async";
-import "dart:isolate";
+import 'dart:async';
+import 'dart:isolate';
 
-import "package:async/async.dart";
-import "package:stack_trace/stack_trace.dart";
-import "package:stream_channel/isolate_channel.dart";
-import "package:stream_channel/stream_channel.dart";
-import "package:test_api/src/util/remote_exception.dart"; // ignore: implementation_imports
+import 'package:async/async.dart';
+import 'package:stack_trace/stack_trace.dart';
+import 'package:stream_channel/isolate_channel.dart';
+import 'package:stream_channel/stream_channel.dart';
+import 'package:test_api/src/util/remote_exception.dart'; // ignore: implementation_imports
 import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
 
 /// A sink transformer that wraps data and error events so that errors can be
@@ -17,10 +17,10 @@
 final _transformer = StreamSinkTransformer<dynamic, dynamic>.fromHandlers(
     handleData: (data, sink) {
   ensureJsonEncodable(data);
-  sink.add({"type": "data", "data": data});
+  sink.add({'type': 'data', 'data': data});
 }, handleError: (error, stackTrace, sink) {
   sink.add(
-      {"type": "error", "error": RemoteException.serialize(error, stackTrace)});
+      {'type': 'error', 'error': RemoteException.serialize(error, stackTrace)});
 });
 
 /// Runs the body of a hybrid isolate and communicates its messages, errors, and
@@ -32,7 +32,7 @@
 ///
 /// The [data] argument contains two values: a [SendPort] that communicates with
 /// the main isolate, and a message to pass to `hybridMain()`.
-void listen(Function getMain(), List data) {
+void listen(Function Function() getMain, List data) {
   var channel = IsolateChannel.connectSend(data.first as SendPort);
   var message = data.last;
 
@@ -42,7 +42,7 @@
       try {
         main = getMain();
       } on NoSuchMethodError catch (_) {
-        _sendError(channel, "No top-level hybridMain() function defined.");
+        _sendError(channel, 'No top-level hybridMain() function defined.');
         return;
       } catch (error, stackTrace) {
         _sendError(channel, error, stackTrace);
@@ -50,12 +50,12 @@
       }
 
       if (main is! Function) {
-        _sendError(channel, "Top-level hybridMain is not a function.");
+        _sendError(channel, 'Top-level hybridMain is not a function.');
         return;
       } else if (main is! Function(StreamChannel) &&
           main is! Function(StreamChannel, Null)) {
         _sendError(channel,
-            "Top-level hybridMain() function must take one or two arguments.");
+            'Top-level hybridMain() function must take one or two arguments.');
         return;
       }
 
@@ -69,19 +69,19 @@
         main(transformedChannel, message);
       }
     }, zoneSpecification: ZoneSpecification(print: (_, __, ___, line) {
-      channel.sink.add({"type": "print", "line": line});
+      channel.sink.add({'type': 'print', 'line': line});
     }));
   }, onError: (error, stackTrace) async {
     _sendError(channel, error, stackTrace);
     await channel.sink.close();
-    Zone.current.handleUncaughtError(error, stackTrace);
+    Isolate.current.kill();
   });
 }
 
 /// Sends a message over [channel] indicating an error from user code.
 void _sendError(StreamChannel channel, error, [StackTrace stackTrace]) {
   channel.sink.add({
-    "type": "error",
-    "error": RemoteException.serialize(error, stackTrace ?? Chain.current())
+    'type': 'error',
+    'error': RemoteException.serialize(error, stackTrace ?? Chain.current())
   });
 }
diff --git a/test_core/lib/src/runner/live_suite.dart b/test_core/lib/src/runner/live_suite.dart
index 9c84492..e580845 100644
--- a/test_core/lib/src/runner/live_suite.dart
+++ b/test_core/lib/src/runner/live_suite.dart
@@ -59,11 +59,12 @@
   ///
   /// This is guaranteed to contain the same tests as the union of [passed],
   /// [skipped], [failed], and [active].
-  Set<LiveTest> get liveTests {
-    var sets = [passed, skipped, failed];
-    if (active != null) sets.add(Set.from([active]));
-    return UnionSet.from(sets);
-  }
+  Set<LiveTest> get liveTests => UnionSet.from([
+        passed,
+        skipped,
+        failed,
+        if (active != null) {active}
+      ]);
 
   /// A stream that emits each [LiveTest] in this suite as it's about to start
   /// running.
diff --git a/test_core/lib/src/runner/live_suite_controller.dart b/test_core/lib/src/runner/live_suite_controller.dart
index e33bfde..e2ec1dc 100644
--- a/test_core/lib/src/runner/live_suite_controller.dart
+++ b/test_core/lib/src/runner/live_suite_controller.dart
@@ -18,25 +18,35 @@
 class _LiveSuite extends LiveSuite {
   final LiveSuiteController _controller;
 
+  @override
   RunnerSuite get suite => _controller._suite;
 
+  @override
   bool get isComplete => _controller._isComplete;
 
+  @override
   Future get onComplete => _controller._onCompleteGroup.future;
 
+  @override
   bool get isClosed => _controller._onCloseCompleter.isCompleted;
 
+  @override
   Future get onClose => _controller._onCloseCompleter.future;
 
+  @override
   Stream<LiveTest> get onTestStarted =>
       _controller._onTestStartedController.stream;
 
+  @override
   Set<LiveTest> get passed => UnmodifiableSetView(_controller._passed);
 
+  @override
   Set<LiveTest> get skipped => UnmodifiableSetView(_controller._skipped);
 
+  @override
   Set<LiveTest> get failed => UnmodifiableSetView(_controller._failed);
 
+  @override
   LiveTest get active => _controller._active;
 
   _LiveSuite(this._controller);
@@ -76,13 +86,13 @@
       StreamController<LiveTest>.broadcast(sync: true);
 
   /// The set that backs [LiveTest.passed].
-  final _passed = Set<LiveTest>();
+  final _passed = <LiveTest>{};
 
   /// The set that backs [LiveTest.skipped].
-  final _skipped = Set<LiveTest>();
+  final _skipped = <LiveTest>{};
 
   /// The set that backs [LiveTest.failed].
-  final _failed = Set<LiveTest>();
+  final _failed = <LiveTest>{};
 
   /// The test exposed through [LiveTest.active].
   LiveTest _active;
diff --git a/test_core/lib/src/runner/load_exception.dart b/test_core/lib/src/runner/load_exception.dart
index b94df49..dcc5f17 100644
--- a/test_core/lib/src/runner/load_exception.dart
+++ b/test_core/lib/src/runner/load_exception.dart
@@ -12,6 +12,7 @@
 
   LoadException(this.path, this.innerError);
 
+  @override
   String toString({bool color = false}) {
     var buffer = StringBuffer();
     if (color) buffer.write('\u001b[31m'); // red
@@ -22,10 +23,10 @@
     if (innerError is SourceSpanException) {
       innerString = (innerError as SourceSpanException)
           .toString(color: color)
-          .replaceFirst(" of $path", "");
+          .replaceFirst(' of $path', '');
     }
 
-    buffer.write(innerString.contains("\n") ? "\n" : " ");
+    buffer.write(innerString.contains('\n') ? '\n' : ' ');
     buffer.write(innerString);
     return buffer.toString();
   }
diff --git a/test_core/lib/src/runner/load_suite.dart b/test_core/lib/src/runner/load_suite.dart
index 246c489..fd6dfb0 100644
--- a/test_core/lib/src/runner/load_suite.dart
+++ b/test_core/lib/src/runner/load_suite.dart
@@ -6,27 +6,23 @@
 
 import 'package:stack_trace/stack_trace.dart';
 import 'package:stream_channel/stream_channel.dart';
-
 import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports
+import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
-import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
 import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
 
-import 'runner_suite.dart';
-import 'suite.dart';
-
 import '../../test_core.dart';
-
-// ignore: uri_does_not_exist
 import '../util/io_stub.dart'
     // ignore: uri_does_not_exist
     if (dart.library.io) '../util/io.dart';
 import 'load_exception.dart';
 import 'plugin/environment.dart';
+import 'runner_suite.dart';
+import 'suite.dart';
 
 /// The timeout for loading a test suite.
 ///
@@ -51,9 +47,13 @@
 /// suite itself is returned by [suite] once it's avaialble, but any errors or
 /// prints will be emitted through the running [LiveTest].
 class LoadSuite extends Suite implements RunnerSuite {
+  @override
   final environment = const PluginEnvironment();
+  @override
   final SuiteConfiguration config;
+  @override
   final isDebugging = false;
+  @override
   final onDebugging = StreamController<bool>().stream;
 
   @override
@@ -87,14 +87,14 @@
   /// If the the load test is closed before [body] is complete, it will close
   /// the suite returned by [body] once it completes.
   factory LoadSuite(String name, SuiteConfiguration config,
-      SuitePlatform platform, FutureOr<RunnerSuite> body(),
+      SuitePlatform platform, FutureOr<RunnerSuite> Function() body,
       {String path}) {
     var completer = Completer<Pair<RunnerSuite, Zone>>.sync();
     return LoadSuite._(name, config, platform, () {
       var invoker = Invoker.current;
       invoker.addOutstandingCallback();
 
-      invoke(() async {
+      unawaited(() async {
         var suite = await body();
         if (completer.isCompleted) {
           // If the load test has already been closed, close the suite it
@@ -105,7 +105,7 @@
 
         completer.complete(suite == null ? null : Pair(suite, Zone.current));
         invoker.removeOutstandingCallback();
-      });
+      }());
 
       // If the test completes before the body callback, either an out-of-band
       // error occurred or the test was canceled. Either way, we return a `null`
@@ -126,10 +126,10 @@
   factory LoadSuite.forLoadException(
       LoadException exception, SuiteConfiguration config,
       {SuitePlatform platform, StackTrace stackTrace}) {
-    if (stackTrace == null) stackTrace = Trace.current();
+    stackTrace ??= Trace.current();
 
     return LoadSuite(
-        "loading ${exception.path}",
+        'loading ${exception.path}',
         config ?? SuiteConfiguration.empty,
         platform ?? currentPlatform(Runtime.vm),
         () => Future.error(exception, stackTrace),
@@ -139,12 +139,12 @@
   /// A utility constructor for a load suite that just emits [suite].
   factory LoadSuite.forSuite(RunnerSuite suite) {
     return LoadSuite(
-        "loading ${suite.path}", suite.config, suite.platform, () => suite,
+        'loading ${suite.path}', suite.config, suite.platform, () => suite,
         path: suite.path);
   }
 
-  LoadSuite._(String name, this.config, SuitePlatform platform, void body(),
-      this._suiteAndZone, {String path})
+  LoadSuite._(String name, this.config, SuitePlatform platform,
+      void Function() body, this._suiteAndZone, {String path})
       : super(
             Group.root(
                 [LocalTest(name, Metadata(timeout: Timeout(_timeout)), body)]),
@@ -168,7 +168,7 @@
   /// If [suite] completes to `null`, [change] won't be run. [change] is run
   /// within the load test's zone, so any errors or prints it emits will be
   /// associated with that test.
-  LoadSuite changeSuite(RunnerSuite change(RunnerSuite suite)) {
+  LoadSuite changeSuite(RunnerSuite Function(RunnerSuite) change) {
     return LoadSuite._changeSuite(this, _suiteAndZone.then((pair) {
       if (pair == null) return null;
 
@@ -197,14 +197,21 @@
     throw 'unreachable';
   }
 
-  LoadSuite filter(bool callback(Test test)) {
+  @override
+  LoadSuite filter(bool Function(Test) callback) {
     var filtered = this.group.filter(callback);
-    if (filtered == null) filtered = Group.root([], metadata: metadata);
+    filtered ??= Group.root([], metadata: metadata);
     return LoadSuite._filtered(this, filtered);
   }
 
+  @override
   StreamChannel channel(String name) =>
-      throw UnsupportedError("LoadSuite.channel() is not supported.");
+      throw UnsupportedError('LoadSuite.channel() is not supported.');
 
+  @override
   Future close() async {}
+
+  @override
+  Future<Map<String, dynamic>> gatherCoverage() =>
+      throw UnsupportedError('Coverage is not supported for LoadSuite tests.');
 }
diff --git a/test_core/lib/src/runner/loader.dart b/test_core/lib/src/runner/loader.dart
index 74fe5f2..b8c779f 100644
--- a/test_core/lib/src/runner/loader.dart
+++ b/test_core/lib/src/runner/loader.dart
@@ -35,7 +35,7 @@
   final _config = Configuration.current;
 
   /// All suites that have been created by the loader.
-  final _suites = Set<RunnerSuite>();
+  final _suites = <RunnerSuite>{};
 
   /// Memoizers for platform plugins, indexed by the runtimes they support.
   final _platformPlugins = <Runtime, AsyncMemoizer<PlatformPlugin>>{};
@@ -179,7 +179,8 @@
       return;
     }
 
-    if (_config.suiteDefaults.excludeTags.evaluate(suiteConfig.metadata.tags)) {
+    if (_config.suiteDefaults.excludeTags
+        .evaluate(suiteConfig.metadata.tags.contains)) {
       return;
     }
 
@@ -207,28 +208,44 @@
         yield LoadSuite.forSuite(RunnerSuite(
             const PluginEnvironment(),
             platformConfig,
-            Group.root([LocalTest("(suite)", platformConfig.metadata, () {})],
+            Group.root([LocalTest('(suite)', platformConfig.metadata, () {})],
                 metadata: platformConfig.metadata),
             platform,
             path: path));
         continue;
       }
 
-      var name = (platform.runtime.isJS ? "compiling " : "loading ") + path;
+      var name =
+          (platform.runtime.isJS && platformConfig.precompiledPath == null
+                  ? 'compiling '
+                  : 'loading ') +
+              path;
       yield LoadSuite(name, platformConfig, platform, () async {
         var memo = _platformPlugins[platform.runtime];
 
-        try {
-          var plugin = await memo.runOnce(_platformCallbacks[platform.runtime]);
-          _customizePlatform(plugin, platform.runtime);
-          var suite = await plugin.load(path, platform, platformConfig,
-              {"platformVariables": _runtimeVariables.toList()});
-          if (suite != null) _suites.add(suite);
-          return suite;
-        } catch (error, stackTrace) {
-          if (error is LoadException) rethrow;
-          await Future.error(LoadException(path, error), stackTrace);
-          return null;
+        var retriesLeft = suiteConfig.metadata.retry;
+        while (true) {
+          try {
+            var plugin =
+                await memo.runOnce(_platformCallbacks[platform.runtime]);
+            _customizePlatform(plugin, platform.runtime);
+            var suite = await plugin.load(path, platform, platformConfig,
+                {'platformVariables': _runtimeVariables.toList()});
+            if (suite != null) _suites.add(suite);
+            return suite;
+          } catch (error, stackTrace) {
+            if (retriesLeft > 0) {
+              retriesLeft--;
+              print('Retrying load of $path in 1s ($retriesLeft remaining)');
+              await Future.delayed(Duration(seconds: 1));
+              continue;
+            }
+            if (error is LoadException) {
+              rethrow;
+            }
+            await Future.error(LoadException(path, error), stackTrace);
+            return null;
+          }
         }
       }, path: path);
     }
diff --git a/test_core/lib/src/runner/parse_metadata.dart b/test_core/lib/src/runner/parse_metadata.dart
index 40366a2..1de3d33 100644
--- a/test_core/lib/src/runner/parse_metadata.dart
+++ b/test_core/lib/src/runner/parse_metadata.dart
@@ -42,7 +42,7 @@
   Set<String> _prefixes;
 
   /// The actual contents of the file.
-  String _contents;
+  final String _contents;
 
   _Parser(this._path, this._contents, this._platformVariables) {
     // ignore: deprecated_member_use
@@ -162,7 +162,7 @@
   /// constructor for the annotation, if any.
   ///
   /// Returns either `true` or a reason string.
-  _parseSkip(Annotation annotation, String constructorName) {
+  dynamic _parseSkip(Annotation annotation, String constructorName) {
     var args = annotation.arguments.arguments;
     return args.isEmpty ? true : _parseString(args.first).stringValue;
   }
@@ -170,7 +170,7 @@
   /// Parses a `Skip` constructor.
   ///
   /// Returns either `true` or a reason string.
-  _parseSkipConstructor(Expression constructor) {
+  dynamic _parseSkipConstructor(Expression constructor) {
     _findConstructorName(constructor, 'Skip');
     var arguments = _parseArguments(constructor);
     return arguments.isEmpty ? true : _parseString(arguments.first).stringValue;
@@ -283,9 +283,10 @@
 
   Map<String, Expression> _parseNamedArguments(
           NodeList<Expression> arguments) =>
-      Map.fromIterable(arguments.whereType<NamedExpression>(),
-          key: (a) => (a as NamedExpression).name.label.name,
-          value: (a) => (a as NamedExpression).expression);
+      {
+        for (var a in arguments.whereType<NamedExpression>())
+          a.name.label.name: a.expression
+      };
 
   /// Asserts that [existing] is null.
   ///
@@ -435,7 +436,7 @@
   /// By default, returns [Expression] keys and values. These can be overridden
   /// with the [key] and [value] parameters.
   Map<K, V> _parseMap<K, V>(Expression expression,
-      {K key(Expression expression), V value(Expression expression)}) {
+      {K Function(Expression) key, V Function(Expression) value}) {
     key ??= (expression) => expression as K;
     value ??= (expression) => expression as V;
 
@@ -505,7 +506,7 @@
 
   /// Runs [fn] and contextualizes any [SourceSpanFormatException]s that occur
   /// in it relative to [literal].
-  T _contextualize<T>(StringLiteral literal, T fn()) {
+  T _contextualize<T>(StringLiteral literal, T Function() fn) {
     try {
       return fn();
     } on SourceSpanFormatException catch (error) {
diff --git a/test_core/lib/src/runner/plugin/environment.dart b/test_core/lib/src/runner/plugin/environment.dart
index e8cb05f..40e88b2 100644
--- a/test_core/lib/src/runner/plugin/environment.dart
+++ b/test_core/lib/src/runner/plugin/environment.dart
@@ -10,15 +10,20 @@
 
 /// The default environment for platform plugins.
 class PluginEnvironment implements Environment {
+  @override
   final supportsDebugging = false;
+  @override
   Stream get onRestart => StreamController.broadcast().stream;
 
   const PluginEnvironment();
 
+  @override
   Uri get observatoryUrl => null;
 
+  @override
   Uri get remoteDebuggerUrl => null;
 
+  @override
   CancelableOperation displayPause() => throw UnsupportedError(
-      "PluginEnvironment.displayPause is not supported.");
+      'PluginEnvironment.displayPause is not supported.');
 }
diff --git a/test_core/lib/src/runner/plugin/platform_helpers.dart b/test_core/lib/src/runner/plugin/platform_helpers.dart
index 442c0c6..bd11058 100644
--- a/test_core/lib/src/runner/plugin/platform_helpers.dart
+++ b/test_core/lib/src/runner/plugin/platform_helpers.dart
@@ -7,19 +7,18 @@
 
 import 'package:stack_trace/stack_trace.dart';
 import 'package:stream_channel/stream_channel.dart';
-
 import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
 import 'package:test_api/src/util/remote_exception.dart'; // ignore: implementation_imports
 
-import '../runner_suite.dart';
-import '../environment.dart';
-import '../suite.dart';
 import '../configuration.dart';
+import '../environment.dart';
 import '../load_exception.dart';
+import '../runner_suite.dart';
 import '../runner_test.dart';
+import '../suite.dart';
 
 /// A helper method for creating a [RunnerSuiteController] containing tests
 /// that communicate over [channel].
@@ -35,13 +34,17 @@
 ///
 /// If [mapper] is passed, it will be used to adjust stack traces for any errors
 /// emitted by tests.
+///
+/// [gatherCoverage] is a callback which returns a hit-map containing merged
+/// coverage report suitable for use with `package:coverage`.
 RunnerSuiteController deserializeSuite(
     String path,
     SuitePlatform platform,
     SuiteConfiguration suiteConfig,
     Environment environment,
     StreamChannel channel,
-    Object message) {
+    Object message,
+    {Future<Map<String, dynamic>> Function() gatherCoverage}) {
   var disconnector = Disconnector();
   var suiteChannel = MultiChannel(channel.transform(disconnector));
 
@@ -51,7 +54,8 @@
     'metadata': suiteConfig.metadata.serialize(),
     'asciiGlyphs': Platform.isWindows,
     'path': path,
-    'collectTraces': Configuration.current.reporter == 'json',
+    'collectTraces': Configuration.current.reporter == 'json' ||
+        Configuration.current.fileReporters.containsKey('json'),
     'noRetry': Configuration.current.noRetry,
     'foldTraceExcept': Configuration.current.foldTraceExcept.toList(),
     'foldTraceOnly': Configuration.current.foldTraceOnly.toList(),
@@ -60,7 +64,7 @@
   var completer = Completer<Group>();
 
   var loadSuiteZone = Zone.current;
-  handleError(error, StackTrace stackTrace) {
+  void handleError(error, StackTrace stackTrace) {
     disconnector.disconnect();
 
     if (completer.isCompleted) {
@@ -75,26 +79,26 @@
 
   suiteChannel.stream.listen(
       (response) {
-        switch (response["type"] as String) {
-          case "print":
-            print(response["line"]);
+        switch (response['type'] as String) {
+          case 'print':
+            print(response['line']);
             break;
 
-          case "loadException":
+          case 'loadException':
             handleError(
-                LoadException(path, response["message"]), Trace.current());
+                LoadException(path, response['message']), Trace.current());
             break;
 
-          case "error":
-            var asyncError = RemoteException.deserialize(response["error"]);
+          case 'error':
+            var asyncError = RemoteException.deserialize(response['error']);
             handleError(
                 LoadException(path, asyncError.error), asyncError.stackTrace);
             break;
 
-          case "success":
+          case 'success':
             var deserializer = _Deserializer(suiteChannel);
             completer.complete(
-                deserializer.deserializeGroup(response["root"] as Map));
+                deserializer.deserializeGroup(response['root'] as Map));
             break;
         }
       },
@@ -102,14 +106,15 @@
       onDone: () {
         if (completer.isCompleted) return;
         completer.completeError(
-            LoadException(path, "Connection closed before test suite loaded."),
+            LoadException(path, 'Connection closed before test suite loaded.'),
             Trace.current());
       });
 
   return RunnerSuiteController(
       environment, suiteConfig, suiteChannel, completer.future, platform,
       path: path,
-      onClose: () => disconnector.disconnect().catchError(handleError));
+      onClose: () => disconnector.disconnect().catchError(handleError),
+      gatherCoverage: gatherCoverage);
 }
 
 /// A utility class for storing state while deserializing tests.
diff --git a/test_core/lib/src/runner/plugin/remote_platform_helpers.dart b/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
index 310d0f5..17c6d4c 100644
--- a/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
+++ b/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
@@ -30,8 +30,8 @@
 ///
 /// If [beforeLoad] is passed, it's called before the tests have been declared
 /// for this worker.
-StreamChannel serializeSuite(Function getMain(),
-        {bool hidePrints = true, Future beforeLoad()}) =>
+StreamChannel serializeSuite(Function Function() getMain,
+        {bool hidePrints = true, Future Function() beforeLoad}) =>
     RemoteListener.start(getMain,
         hidePrints: hidePrints, beforeLoad: beforeLoad);
 
diff --git a/test_core/lib/src/runner/reporter/compact.dart b/test_core/lib/src/runner/reporter/compact.dart
index 7827811..4c3e69a 100644
--- a/test_core/lib/src/runner/reporter/compact.dart
+++ b/test_core/lib/src/runner/reporter/compact.dart
@@ -99,7 +99,7 @@
   var _paused = false;
 
   /// The set of all subscriptions to various streams.
-  final _subscriptions = Set<StreamSubscription>();
+  final _subscriptions = <StreamSubscription>{};
 
   /// Watches the tests run by [engine] and prints their results to the
   /// terminal.
@@ -114,6 +114,7 @@
     _subscriptions.add(_engine.success.asStream().listen(_onDone));
   }
 
+  @override
   void pause() {
     if (_paused) return;
     _paused = true;
@@ -132,6 +133,7 @@
     }
   }
 
+  @override
   void resume() {
     if (!_paused) return;
     _paused = false;
@@ -143,6 +145,7 @@
     }
   }
 
+  @override
   void cancel() {
     for (var subscription in _subscriptions) {
       subscription.cancel();
@@ -207,7 +210,7 @@
     if (liveTest.state.status != Status.complete) return;
 
     _progressLine(_description(liveTest),
-        truncate: false, suffix: " $_bold$_red[E]$_noColor");
+        truncate: false, suffix: ' $_bold$_red[E]$_noColor');
     if (!_printedNewline) _sink.writeln('');
     _printedNewline = true;
 
@@ -242,33 +245,33 @@
     // shouldn't print summary information, we should just make sure the
     // terminal cursor is on its own line.
     if (success == null) {
-      if (!_printedNewline) _sink.writeln("");
+      if (!_printedNewline) _sink.writeln('');
       _printedNewline = true;
       return;
     }
 
     if (_engine.liveTests.isEmpty) {
-      if (!_printedNewline) _sink.write("\r");
-      var message = "No tests ran.";
+      if (!_printedNewline) _sink.write('\r');
+      var message = 'No tests ran.';
       _sink.write(message);
 
       // Add extra padding to overwrite any load messages.
-      if (!_printedNewline) _sink.write(" " * (lineLength - message.length));
+      if (!_printedNewline) _sink.write(' ' * (lineLength - message.length));
       _sink.writeln('');
     } else if (!success) {
       for (var liveTest in _engine.active) {
         _progressLine(_description(liveTest),
             truncate: false,
-            suffix: " - did not complete $_bold$_red[E]$_noColor");
+            suffix: ' - did not complete $_bold$_red[E]$_noColor');
         _sink.writeln('');
       }
       _progressLine('Some tests failed.', color: _red);
       _sink.writeln('');
     } else if (_engine.passed.isEmpty) {
-      _progressLine("All tests skipped.");
+      _progressLine('All tests skipped.');
       _sink.writeln('');
     } else {
-      _progressLine("All tests passed!");
+      _progressLine('All tests passed!');
       _sink.writeln('');
     }
   }
@@ -309,7 +312,7 @@
     _lastProgressTruncated = truncate;
 
     if (suffix != null) message += suffix;
-    if (color == null) color = '';
+    color ??= '';
     var duration = _stopwatch.elapsed;
     var buffer = StringBuffer();
 
@@ -369,15 +372,15 @@
     if (_printPath &&
         liveTest.suite is! LoadSuite &&
         liveTest.suite.path != null) {
-      name = "${liveTest.suite.path}: $name";
+      name = '${liveTest.suite.path}: $name';
     }
 
     if (_config.suiteDefaults.runtimes.length > 1 &&
         liveTest.suite.platform != null) {
-      name = "[${liveTest.suite.platform.runtime.name}] $name";
+      name = '[${liveTest.suite.platform.runtime.name}] $name';
     }
 
-    if (liveTest.suite is LoadSuite) name = "$_bold$_gray$name$_noColor";
+    if (liveTest.suite is LoadSuite) name = '$_bold$_gray$name$_noColor';
 
     return name;
   }
diff --git a/test_core/lib/src/runner/reporter/expanded.dart b/test_core/lib/src/runner/reporter/expanded.dart
index 87588d0..2785ae9 100644
--- a/test_core/lib/src/runner/reporter/expanded.dart
+++ b/test_core/lib/src/runner/reporter/expanded.dart
@@ -82,7 +82,7 @@
   var _paused = false;
 
   /// The set of all subscriptions to various streams.
-  final _subscriptions = Set<StreamSubscription>();
+  final _subscriptions = <StreamSubscription>{};
 
   final StringSink _sink;
 
@@ -119,6 +119,7 @@
     _subscriptions.add(_engine.success.asStream().listen(_onDone));
   }
 
+  @override
   void pause() {
     if (_paused) return;
     _paused = true;
@@ -130,6 +131,7 @@
     }
   }
 
+  @override
   void resume() {
     if (!_paused) return;
     _stopwatch.start();
@@ -139,6 +141,7 @@
     }
   }
 
+  @override
   void cancel() {
     for (var subscription in _subscriptions) {
       subscription.cancel();
@@ -162,7 +165,7 @@
           .listen((state) => _onStateChange(liveTest, state)));
     } else if (_engine.active.length == 1 &&
         _engine.active.first == liveTest &&
-        liveTest.test.name.startsWith("compiling ")) {
+        liveTest.test.name.startsWith('compiling ')) {
       // Print a progress line for load tests that come from compiling JS, since
       // that takes a long time.
       _progressLine(_description(liveTest));
@@ -194,7 +197,7 @@
   void _onError(LiveTest liveTest, error, StackTrace stackTrace) {
     if (liveTest.state.status != Status.complete) return;
 
-    _progressLine(_description(liveTest), suffix: " $_bold$_red[E]$_noColor");
+    _progressLine(_description(liveTest), suffix: ' $_bold$_red[E]$_noColor');
 
     if (error is! LoadException) {
       _sink..writeln(indent('$error'))..writeln(indent('$stackTrace'));
@@ -221,17 +224,17 @@
     if (success == null) return;
 
     if (_engine.liveTests.isEmpty) {
-      _sink.writeln("No tests ran.");
+      _sink.writeln('No tests ran.');
     } else if (!success) {
       for (var liveTest in _engine.active) {
         _progressLine(_description(liveTest),
-            suffix: " - did not complete $_bold$_red[E]$_noColor");
+            suffix: ' - did not complete $_bold$_red[E]$_noColor');
       }
       _progressLine('Some tests failed.', color: _red);
     } else if (_engine.passed.isEmpty) {
-      _progressLine("All tests skipped.");
+      _progressLine('All tests skipped.');
     } else {
-      _progressLine("All tests passed!");
+      _progressLine('All tests passed!');
     }
   }
 
@@ -258,7 +261,7 @@
     _lastProgressSuffix = suffix;
 
     if (suffix != null) message += suffix;
-    if (color == null) color = '';
+    color ??= '';
     var duration = _stopwatch.elapsed;
     var buffer = StringBuffer();
 
@@ -307,14 +310,14 @@
     if (_printPath &&
         liveTest.suite is! LoadSuite &&
         liveTest.suite.path != null) {
-      name = "${liveTest.suite.path}: $name";
+      name = '${liveTest.suite.path}: $name';
     }
 
     if (_printPlatform) {
-      name = "[${liveTest.suite.platform.runtime.name}] $name";
+      name = '[${liveTest.suite.platform.runtime.name}] $name';
     }
 
-    if (liveTest.suite is LoadSuite) name = "$_bold$_gray$name$_noColor";
+    if (liveTest.suite is LoadSuite) name = '$_bold$_gray$name$_noColor';
 
     return name;
   }
diff --git a/test_core/lib/src/runner/reporter/json.dart b/test_core/lib/src/runner/reporter/json.dart
index eb3c9fb..5edb4a0 100644
--- a/test_core/lib/src/runner/reporter/json.dart
+++ b/test_core/lib/src/runner/reporter/json.dart
@@ -48,16 +48,16 @@
   var _paused = false;
 
   /// The set of all subscriptions to various streams.
-  final _subscriptions = Set<StreamSubscription>();
+  final _subscriptions = <StreamSubscription>{};
 
   /// An expando that associates unique IDs with [LiveTest]s.
-  final _liveTestIDs = Map<LiveTest, int>();
+  final _liveTestIDs = <LiveTest, int>{};
 
   /// An expando that associates unique IDs with [Suite]s.
-  final _suiteIDs = Map<Suite, int>();
+  final _suiteIDs = <Suite, int>{};
 
   /// An expando that associates unique IDs with [Group]s.
-  final _groupIDs = Map<Group, int>();
+  final _groupIDs = <Group, int>{};
 
   /// The next ID to associate with a [LiveTest].
   var _nextID = 0;
@@ -74,13 +74,14 @@
     _subscriptions.add(_engine.success.asStream().listen(_onDone));
 
     _subscriptions.add(_engine.onSuiteAdded.listen(null, onDone: () {
-      _emit("allSuites", {"count": _engine.addedSuites.length});
+      _emit('allSuites', {'count': _engine.addedSuites.length});
     }));
 
-    _emit("start",
-        {"protocolVersion": "0.1.1", "runnerVersion": testVersion, "pid": pid});
+    _emit('start',
+        {'protocolVersion': '0.1.1', 'runnerVersion': testVersion, 'pid': pid});
   }
 
+  @override
   void pause() {
     if (_paused) return;
     _paused = true;
@@ -92,6 +93,7 @@
     }
   }
 
+  @override
   void resume() {
     if (!_paused) return;
     _paused = false;
@@ -103,6 +105,7 @@
     }
   }
 
+  @override
   void cancel() {
     for (var subscription in _subscriptions) {
       subscription.cancel();
@@ -128,15 +131,15 @@
     var suiteConfig = _configFor(liveTest.suite);
     var id = _nextID++;
     _liveTestIDs[liveTest] = id;
-    _emit("testStart", {
-      "test": _addFrameInfo(
+    _emit('testStart', {
+      'test': _addFrameInfo(
           suiteConfig,
           {
-            "id": id,
-            "name": liveTest.test.name,
-            "suiteID": suiteID,
-            "groupIDs": groupIDs,
-            "metadata": _serializeMetadata(suiteConfig, liveTest.test.metadata)
+            'id': id,
+            'name': liveTest.test.name,
+            'suiteID': suiteID,
+            'groupIDs': groupIDs,
+            'metadata': _serializeMetadata(suiteConfig, liveTest.test.metadata)
           },
           liveTest.test,
           liveTest.suite.platform.runtime,
@@ -152,10 +155,10 @@
         .listen((error) => _onError(liveTest, error.error, error.stackTrace)));
 
     _subscriptions.add(liveTest.onMessage.listen((message) {
-      _emit("print", {
-        "testID": id,
-        "messageType": message.type.name,
-        "message": message.text
+      _emit('print', {
+        'testID': id,
+        'messageType': message.type.name,
+        'message': message.text
       });
     }));
   }
@@ -179,20 +182,20 @@
 
         // TODO(nweiz): test this when we have a library for communicating with
         // the Chrome remote debugger, or when we have VM debug support.
-        _emit("debug", {
-          "suiteID": id,
-          "observatory": runnerSuite.environment.observatoryUrl?.toString(),
-          "remoteDebugger":
+        _emit('debug', {
+          'suiteID': id,
+          'observatory': runnerSuite.environment.observatoryUrl?.toString(),
+          'remoteDebugger':
               runnerSuite.environment.remoteDebuggerUrl?.toString(),
         });
       });
     }
 
-    _emit("suite", {
-      "suite": {
-        "id": id,
-        "platform": suite.platform.runtime.identifier,
-        "path": suite.path
+    _emit('suite', {
+      'suite': {
+        'id': id,
+        'platform': suite.platform.runtime.identifier,
+        'path': suite.path
       }
     });
     return id;
@@ -215,16 +218,16 @@
       _groupIDs[group] = id;
 
       var suiteConfig = _configFor(suite);
-      _emit("group", {
-        "group": _addFrameInfo(
+      _emit('group', {
+        'group': _addFrameInfo(
             suiteConfig,
             {
-              "id": id,
-              "suiteID": _idForSuite(suite),
-              "parentID": parentID,
-              "name": group.name,
-              "metadata": _serializeMetadata(suiteConfig, group.metadata),
-              "testCount": group.testCount
+              'id': id,
+              'suiteID': _idForSuite(suite),
+              'parentID': parentID,
+              'name': group.name,
+              'metadata': _serializeMetadata(suiteConfig, group.metadata),
+              'testCount': group.testCount
             },
             group,
             suite.platform.runtime,
@@ -238,29 +241,29 @@
   /// Serializes [metadata] into a JSON-protocol-compatible map.
   Map _serializeMetadata(SuiteConfiguration suiteConfig, Metadata metadata) =>
       suiteConfig.runSkipped
-          ? {"skip": false, "skipReason": null}
-          : {"skip": metadata.skip, "skipReason": metadata.skipReason};
+          ? {'skip': false, 'skipReason': null}
+          : {'skip': metadata.skip, 'skipReason': metadata.skipReason};
 
   /// A callback called when [liveTest] finishes running.
   void _onComplete(LiveTest liveTest) {
-    _emit("testDone", {
-      "testID": _liveTestIDs[liveTest],
+    _emit('testDone', {
+      'testID': _liveTestIDs[liveTest],
       // For backwards-compatibility, report skipped tests as successes.
-      "result": liveTest.state.result == Result.skipped
-          ? "success"
+      'result': liveTest.state.result == Result.skipped
+          ? 'success'
           : liveTest.state.result.toString(),
-      "skipped": liveTest.state.result == Result.skipped,
-      "hidden": !_engine.liveTests.contains(liveTest)
+      'skipped': liveTest.state.result == Result.skipped,
+      'hidden': !_engine.liveTests.contains(liveTest)
     });
   }
 
   /// A callback called when [liveTest] throws [error].
   void _onError(LiveTest liveTest, error, StackTrace stackTrace) {
-    _emit("error", {
-      "testID": _liveTestIDs[liveTest],
-      "error": error.toString(),
-      "stackTrace": '$stackTrace',
-      "isFailure": error is TestFailure
+    _emit('error', {
+      'testID': _liveTestIDs[liveTest],
+      'error': error.toString(),
+      'stackTrace': '$stackTrace',
+      'isFailure': error is TestFailure
     });
   }
 
@@ -272,7 +275,7 @@
     cancel();
     _stopwatch.stop();
 
-    _emit("done", {"success": success});
+    _emit('done', {'success': success});
   }
 
   /// Returns the configuration for [suite].
@@ -284,8 +287,8 @@
 
   /// Emits an event with the given type and attributes.
   void _emit(String type, Map attributes) {
-    attributes["type"] = type;
-    attributes["time"] = _stopwatch.elapsed.inMilliseconds;
+    attributes['type'] = type;
+    attributes['time'] = _stopwatch.elapsed.inMilliseconds;
     _sink.writeln(jsonEncode(attributes));
   }
 
@@ -310,13 +313,13 @@
       rootFrame = null;
     }
 
-    map["line"] = frame?.line;
-    map["column"] = frame?.column;
-    map["url"] = frame?.uri?.toString();
+    map['line'] = frame?.line;
+    map['column'] = frame?.column;
+    map['url'] = frame?.uri?.toString();
     if (rootFrame != null && rootFrame != frame) {
-      map["root_line"] = rootFrame.line;
-      map["root_column"] = rootFrame.column;
-      map["root_url"] = rootFrame.uri.toString();
+      map['root_line'] = rootFrame.line;
+      map['root_column'] = rootFrame.column;
+      map['root_url'] = rootFrame.uri.toString();
     }
     return map;
   }
diff --git a/test_core/lib/src/runner/reporter/multiplex.dart b/test_core/lib/src/runner/reporter/multiplex.dart
new file mode 100644
index 0000000..e13c1b4
--- /dev/null
+++ b/test_core/lib/src/runner/reporter/multiplex.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for 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 '../reporter.dart';
+
+class MultiplexReporter implements Reporter {
+  Iterable<Reporter> delegates;
+
+  MultiplexReporter(this.delegates);
+
+  @override
+  void cancel() {
+    for (var d in delegates) {
+      d.cancel();
+    }
+  }
+
+  @override
+  void pause() {
+    for (var d in delegates) {
+      d.pause();
+    }
+  }
+
+  @override
+  void resume() {
+    for (var d in delegates) {
+      d.resume();
+    }
+  }
+}
diff --git a/test_core/lib/src/runner/runner_suite.dart b/test_core/lib/src/runner/runner_suite.dart
index 4bed418..1b166d3 100644
--- a/test_core/lib/src/runner/runner_suite.dart
+++ b/test_core/lib/src/runner/runner_suite.dart
@@ -6,14 +6,13 @@
 
 import 'package:async/async.dart';
 import 'package:stream_channel/stream_channel.dart';
-
 import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
 
-import 'suite.dart';
 import 'environment.dart';
+import 'suite.dart';
 
 /// A suite produced and consumed by the test runner that has runner-specific
 /// logic and lifecycle management.
@@ -68,7 +67,8 @@
       this._controller, Group group, String path, SuitePlatform platform)
       : super(group, platform, path: path);
 
-  RunnerSuite filter(bool callback(Test test)) {
+  @override
+  RunnerSuite filter(bool Function(Test) callback) {
     var filtered = group.filter(callback);
     filtered ??= Group.root([], metadata: metadata);
     return RunnerSuite._(_controller, filtered, path, platform);
@@ -76,6 +76,13 @@
 
   /// Closes the suite and releases any resources associated with it.
   Future close() => _controller._close();
+
+  /// Collects a hit-map containing merged coverage.
+  ///
+  /// Result is suitable for input to the coverage formatters provided by
+  /// `package:coverage`.
+  Future<Map<String, dynamic>> gatherCoverage() async =>
+      (await _controller._gatherCoverage?.call()) ?? {};
 }
 
 /// A class that exposes and controls a [RunnerSuite].
@@ -103,12 +110,18 @@
   final _onDebuggingController = StreamController<bool>.broadcast();
 
   /// The channel names that have already been used.
-  final _channelNames = Set<String>();
+  final _channelNames = <String>{};
+
+  /// Collects a hit-map containing merged coverage.
+  final Future<Map<String, dynamic>> Function() _gatherCoverage;
 
   RunnerSuiteController(this._environment, this._config, this._suiteChannel,
       Future<Group> groupFuture, SuitePlatform platform,
-      {String path, Function() onClose})
-      : _onClose = onClose {
+      {String path,
+      Function() onClose,
+      Future<Map<String, dynamic>> Function() gatherCoverage})
+      : _onClose = onClose,
+        _gatherCoverage = gatherCoverage {
     _suite =
         groupFuture.then((group) => RunnerSuite._(this, group, path, platform));
   }
@@ -116,9 +129,11 @@
   /// Used by [new RunnerSuite] to create a runner suite that's not loaded from
   /// an external source.
   RunnerSuiteController._local(this._environment, this._config,
-      {Function() onClose})
+      {Function() onClose,
+      Future<Map<String, dynamic>> Function() gatherCoverage})
       : _suiteChannel = null,
-        _onClose = onClose;
+        _onClose = onClose,
+        _gatherCoverage = gatherCoverage;
 
   /// Sets whether the suite is paused for debugging.
   ///
@@ -146,7 +161,7 @@
 
     var channel = _suiteChannel.virtualChannel();
     _suiteChannel.sink
-        .add({"type": "suiteChannel", "name": name, "id": channel.id});
+        .add({'type': 'suiteChannel', 'name': name, 'id': channel.id});
     return channel;
   }
 
diff --git a/test_core/lib/src/runner/runner_test.dart b/test_core/lib/src/runner/runner_test.dart
index f19cad1..44fb3a7 100644
--- a/test_core/lib/src/runner/runner_test.dart
+++ b/test_core/lib/src/runner/runner_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:pedantic/pedantic.dart';
 import 'package:stack_trace/stack_trace.dart';
 import 'package:stream_channel/stream_channel.dart';
-
 import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/live_test.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/live_test_controller.dart'; // ignore: implementation_imports
@@ -15,14 +15,16 @@
 import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
 import 'package:test_api/src/util/remote_exception.dart'; // ignore: implementation_imports
-import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
 
 import 'spawn_hybrid.dart';
 
 /// A test running remotely, controlled by a stream channel.
 class RunnerTest extends Test {
+  @override
   final String name;
+  @override
   final Metadata metadata;
+  @override
   final Trace trace;
 
   /// The channel used to communicate with the test's [IframeListener].
@@ -32,6 +34,7 @@
 
   RunnerTest._(this.name, this.metadata, this.trace, this._channel);
 
+  @override
   LiveTest load(Suite suite, {Iterable<Group> groups}) {
     LiveTestController controller;
     VirtualChannel testChannel;
@@ -85,18 +88,19 @@
         return;
       }
 
-      invoke(() async {
+      unawaited(() async {
         // If the test is still running, send it a message telling it to shut
         // down ASAP. This causes the [Invoker] to eagerly throw exceptions
         // whenever the test touches it.
         testChannel.sink.add({'command': 'close'});
         await controller.completer.future;
         await testChannel.sink.close();
-      });
+      }());
     }, groups: groups);
     return controller.liveTest;
   }
 
+  @override
   Test forPlatform(SuitePlatform platform) {
     if (!metadata.testOn.evaluate(platform)) return null;
     return RunnerTest._(name, metadata.forPlatform(platform), trace, _channel);
diff --git a/test_core/lib/src/runner/runtime_selection.dart b/test_core/lib/src/runner/runtime_selection.dart
index 0585a0f..8105dcd 100644
--- a/test_core/lib/src/runner/runtime_selection.dart
+++ b/test_core/lib/src/runner/runtime_selection.dart
@@ -16,7 +16,9 @@
 
   RuntimeSelection(this.name, [this.span]);
 
+  @override
   bool operator ==(other) => other is RuntimeSelection && other.name == name;
 
+  @override
   int get hashCode => name.hashCode;
 }
diff --git a/test_core/lib/src/runner/spawn_hybrid.dart b/test_core/lib/src/runner/spawn_hybrid.dart
index 797ba66..1db6769 100644
--- a/test_core/lib/src/runner/spawn_hybrid.dart
+++ b/test_core/lib/src/runner/spawn_hybrid.dart
@@ -24,13 +24,13 @@
     var port = ReceivePort();
     var onExitPort = ReceivePort();
     try {
-      var code = """
+      var code = '''
         import "package:test_core/src/runner/hybrid_listener.dart";
 
         import "${url.replaceAll(r'$', '%24')}" as lib;
 
         void main(_, List data) => listen(() => lib.hybridMain, data);
-      """;
+      ''';
 
       var isolate = await dart.runInIsolate(code, [port.sendPort, message],
           onExit: onExitPort.sendPort);
@@ -57,8 +57,8 @@
       // Make sure any errors in spawning the isolate are forwarded to the test.
       return StreamChannel(
           Stream.fromFuture(Future.value({
-            "type": "error",
-            "error": RemoteException.serialize(error, stackTrace)
+            'type': 'error',
+            'error': RemoteException.serialize(error, stackTrace)
           })),
           NullStreamSink());
     }
diff --git a/test_core/lib/src/runner/suite.dart b/test_core/lib/src/runner/suite.dart
index 08c6ab4..c95494a 100644
--- a/test_core/lib/src/runner/suite.dart
+++ b/test_core/lib/src/runner/suite.dart
@@ -55,7 +55,7 @@
 
   /// The set of runtimes on which to run tests.
   List<String> get runtimes => _runtimes == null
-      ? const ["vm"]
+      ? const ['vm']
       : List.unmodifiable(_runtimes.map((runtime) => runtime.name));
   final List<RuntimeSelection> _runtimes;
 
@@ -85,10 +85,9 @@
   final Map<PlatformSelector, SuiteConfiguration> onPlatform;
 
   /// The seed with which to shuffle the test order.
-  /// Default value is 0 if not provided and will not change the test order.
+  /// Default value is null if not provided and will not change the test order.
   /// The same seed will shuffle the tests in the same way every time.
-  int get testRandomizeOrderingSeed => _testRandomizeOrderingSeed ?? 0;
-  final int _testRandomizeOrderingSeed;
+  final int testRandomizeOrderingSeed;
 
   /// The global test metadata derived from this configuration.
   Metadata get metadata {
@@ -196,13 +195,13 @@
       : _jsTrace = jsTrace,
         _runSkipped = runSkipped,
         dart2jsArgs = _list(dart2jsArgs) ?? const [],
-        patterns = UnmodifiableSetView(patterns?.toSet() ?? Set()),
+        patterns = UnmodifiableSetView(patterns?.toSet() ?? {}),
         _runtimes = _list(runtimes),
         includeTags = includeTags ?? BooleanSelector.all,
         excludeTags = excludeTags ?? BooleanSelector.none,
         tags = _map(tags),
         onPlatform = _map(onPlatform),
-        _testRandomizeOrderingSeed = testRandomizeOrderingSeed,
+        testRandomizeOrderingSeed = testRandomizeOrderingSeed,
         _metadata = metadata ?? Metadata.empty;
 
   /// Creates a new [SuiteConfiguration] that takes its configuration from
@@ -252,7 +251,7 @@
         tags: _mergeConfigMaps(tags, other.tags),
         onPlatform: _mergeConfigMaps(onPlatform, other.onPlatform),
         testRandomizeOrderingSeed:
-            other._testRandomizeOrderingSeed ?? _testRandomizeOrderingSeed,
+            other.testRandomizeOrderingSeed ?? testRandomizeOrderingSeed,
         metadata: metadata.merge(other.metadata));
     return config._resolveTags();
   }
@@ -295,7 +294,7 @@
         tags: tags ?? this.tags,
         onPlatform: onPlatform ?? this.onPlatform,
         testRandomizeOrderingSeed:
-            testRandomizeOrderingSeed ?? _testRandomizeOrderingSeed,
+            testRandomizeOrderingSeed ?? testRandomizeOrderingSeed,
         metadata: _metadata.change(
             timeout: timeout,
             verboseTrace: verboseTrace,
@@ -364,11 +363,11 @@
     // Otherwise, resolve the tag-specific components.
     var newTags = Map<BooleanSelector, SuiteConfiguration>.from(tags);
     var merged = tags.keys.fold(empty, (SuiteConfiguration merged, selector) {
-      if (!selector.evaluate(_metadata.tags)) return merged;
+      if (!selector.evaluate(_metadata.tags.contains)) return merged;
       return merged.merge(newTags.remove(selector));
     });
 
     if (merged == empty) return this;
-    return this.change(tags: newTags).merge(merged);
+    return change(tags: newTags).merge(merged);
   }
 }
diff --git a/test_core/lib/src/runner/version.dart b/test_core/lib/src/runner/version.dart
index 23d8048..b10aefa 100644
--- a/test_core/lib/src/runner/version.dart
+++ b/test_core/lib/src/runner/version.dart
@@ -13,7 +13,7 @@
 final String testVersion = (() {
   dynamic lockfile;
   try {
-    lockfile = loadYaml(File("pubspec.lock").readAsStringSync());
+    lockfile = loadYaml(File('pubspec.lock').readAsStringSync());
   } on FormatException catch (_) {
     return null;
   } on IOException catch (_) {
@@ -21,38 +21,38 @@
   }
 
   if (lockfile is! Map) return null;
-  var packages = lockfile["packages"];
+  var packages = lockfile['packages'];
   if (packages is! Map) return null;
-  var package = packages["test"];
+  var package = packages['test'];
   if (package is! Map) return null;
 
-  var source = package["source"];
+  var source = package['source'];
   if (source is! String) return null;
 
   switch (source as String) {
-    case "hosted":
-      var version = package["version"];
+    case 'hosted':
+      var version = package['version'];
       return (version is String) ? version : null;
 
-    case "git":
-      var version = package["version"];
+    case 'git':
+      var version = package['version'];
       if (version is! String) return null;
-      var description = package["description"];
+      var description = package['description'];
       if (description is! Map) return null;
-      var ref = description["resolved-ref"];
+      var ref = description['resolved-ref'];
       if (ref is! String) return null;
 
-      return "$version (${ref.substring(0, 7)})";
+      return '$version (${ref.substring(0, 7)})';
 
-    case "path":
-      var version = package["version"];
+    case 'path':
+      var version = package['version'];
       if (version is! String) return null;
-      var description = package["description"];
+      var description = package['description'];
       if (description is! Map) return null;
-      var path = description["path"];
+      var path = description['path'];
       if (path is! String) return null;
 
-      return "$version (from $path)";
+      return '$version (from $path)';
 
     default:
       return null;
diff --git a/test_core/lib/src/runner/vm/environment.dart b/test_core/lib/src/runner/vm/environment.dart
index 6fedbec..6f919bf 100644
--- a/test_core/lib/src/runner/vm/environment.dart
+++ b/test_core/lib/src/runner/vm/environment.dart
@@ -10,7 +10,9 @@
 
 /// The environment in which VM tests are loaded.
 class VMEnvironment implements Environment {
+  @override
   final supportsDebugging = true;
+  @override
   final Uri observatoryUrl;
 
   /// The VM service isolate object used to control this isolate.
@@ -19,10 +21,13 @@
 
   VMEnvironment(this.observatoryUrl, this._isolate, this._client);
 
+  @override
   Uri get remoteDebuggerUrl => null;
 
+  @override
   Stream get onRestart => StreamController.broadcast().stream;
 
+  @override
   CancelableOperation displayPause() {
     var completer =
         CancelableCompleter(onCancel: () => _client.resume(_isolate.id));
diff --git a/test_core/lib/src/runner/vm/platform.dart b/test_core/lib/src/runner/vm/platform.dart
index 4f521be..83e4b4f 100644
--- a/test_core/lib/src/runner/vm/platform.dart
+++ b/test_core/lib/src/runner/vm/platform.dart
@@ -7,23 +7,23 @@
 import 'dart:io';
 import 'dart:isolate';
 
+import 'package:coverage/coverage.dart';
 import 'package:path/path.dart' as p;
 import 'package:stream_channel/isolate_channel.dart';
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/load_exception.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/platform.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/plugin/environment.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
-import 'package:test_core/src/util/dart.dart' // ignore: implementation_imports
-    as dart;
 import 'package:vm_service/vm_service.dart' hide Isolate;
 import 'package:vm_service/vm_service_io.dart';
 
+import '../../runner/configuration.dart';
+import '../../runner/environment.dart';
+import '../../runner/load_exception.dart';
+import '../../runner/platform.dart';
+import '../../runner/plugin/platform_helpers.dart';
+import '../../runner/runner_suite.dart';
+import '../../runner/suite.dart';
+import '../../util/dart.dart' as dart;
 import 'environment.dart';
 
 /// A platform that loads tests in isolates spawned within this Dart process.
@@ -33,9 +33,11 @@
 
   VMPlatform();
 
+  @override
   StreamChannel loadChannel(String path, SuitePlatform platform) =>
       throw UnimplementedError();
 
+  @override
   Future<RunnerSuite> load(String path, SuitePlatform platform,
       SuiteConfiguration suiteConfig, Object message) async {
     assert(platform.runtime == Runtime.vm);
@@ -59,7 +61,7 @@
       sink.close();
     }));
 
-    VMEnvironment environment;
+    Environment environment;
     IsolateRef isolateRef;
     if (_config.debug) {
       // Print an empty line because the VM prints an "Observatory listening on"
@@ -72,7 +74,7 @@
 
       var libraryPath = p.toUri(p.absolute(path)).toString();
       client = await vmServiceConnectUri(_wsUriFor(info.serverUri.toString()));
-      var isolateNumber = int.parse(isolateID.split("/").last);
+      var isolateNumber = int.parse(isolateID.split('/').last);
       isolateRef = (await client.getVM())
           .isolates
           .firstWhere((isolate) => isolate.number == isolateNumber.toString());
@@ -85,8 +87,11 @@
       environment = VMEnvironment(url, isolateRef, client);
     }
 
-    var controller = deserializeSuite(path, platform, suiteConfig,
-        environment ?? PluginEnvironment(), channel, message);
+    environment ??= PluginEnvironment();
+
+    var controller = deserializeSuite(
+        path, platform, suiteConfig, environment, channel, message,
+        gatherCoverage: () => _gatherCoverage(environment));
 
     if (isolateRef != null) {
       await client.streamListen('Debug');
@@ -134,7 +139,7 @@
       var channel = serializeSuite(() => test.main);
       IsolateChannel.connectSend(message).pipe(channel);
     }
-  ''', message, checked: true);
+  ''', message);
 }
 
 Future<Isolate> _spawnPrecompiledIsolate(
@@ -150,6 +155,13 @@
       checked: true);
 }
 
+Future<Map<String, dynamic>> _gatherCoverage(Environment environment) async {
+  final isolateId = Uri.parse(environment.observatoryUrl.fragment)
+      .queryParameters['isolateId'];
+  return await collect(environment.observatoryUrl, false, false, false, {},
+      isolateIds: {isolateId});
+}
+
 Future<Isolate> _spawnPubServeIsolate(
     String testPath, SendPort message, Uri pubServeUrl) async {
   var url = pubServeUrl.resolveUri(
@@ -158,16 +170,16 @@
   try {
     return await Isolate.spawnUri(url, [], message, checked: true);
   } on IsolateSpawnException catch (error) {
-    if (error.message.contains("OS Error: Connection refused") ||
-        error.message.contains("The remote computer refused")) {
+    if (error.message.contains('OS Error: Connection refused') ||
+        error.message.contains('The remote computer refused')) {
       throw LoadException(
           testPath,
-          "Error getting $url: Connection refused\n"
+          'Error getting $url: Connection refused\n'
           'Make sure "pub serve" is running.');
-    } else if (error.message.contains("404 Not Found")) {
+    } else if (error.message.contains('404 Not Found')) {
       throw LoadException(
           testPath,
-          "Error getting $url: 404 Not Found\n"
+          'Error getting $url: 404 Not Found\n'
           'Make sure "pub serve" is serving the test/ directory.');
     }
 
@@ -179,5 +191,5 @@
     "ws:${observatoryUrl.split(':').sublist(1).join(':')}ws";
 
 Uri _observatoryUrlFor(String base, String isolateId, String id) =>
-    Uri.parse("$base#/inspect?isolateId=${Uri.encodeQueryComponent(isolateId)}&"
-        "objectId=${Uri.encodeQueryComponent(id)}");
+    Uri.parse('$base#/inspect?isolateId=${Uri.encodeQueryComponent(isolateId)}&'
+        'objectId=${Uri.encodeQueryComponent(id)}');
diff --git a/test_core/lib/src/util/dart.dart b/test_core/lib/src/util/dart.dart
index e142dca..bdb39ea 100644
--- a/test_core/lib/src/util/dart.dart
+++ b/test_core/lib/src/util/dart.dart
@@ -8,7 +8,6 @@
 
 // ignore: deprecated_member_use
 import 'package:analyzer/analyzer.dart';
-import 'package:package_resolver/package_resolver.dart';
 import 'package:source_span/source_span.dart';
 
 import 'string_literal_iterator.dart';
@@ -19,23 +18,16 @@
 /// they will be resolved in the same context as the host isolate. [message] is
 /// passed to the [main] method of the code being run; the caller is responsible
 /// for using this to establish communication with the isolate.
-///
-/// If [resolver] is passed, its package resolution strategy is used to resolve
-/// code in the spawned isolate. It defaults to [PackageResolver.current].
-Future<Isolate> runInIsolate(String code, message,
-    {PackageResolver resolver, bool checked, SendPort onExit}) async {
-  resolver ??= PackageResolver.current;
-  return await Isolate.spawnUri(
-      Uri.dataFromString(code, mimeType: 'application/dart', encoding: utf8),
-      [],
-      message,
-      packageConfig: await resolver.packageConfigUri,
-      checked: checked,
-      onExit: onExit);
-}
+Future<Isolate> runInIsolate(String code, Object message,
+        {SendPort onExit}) async =>
+    Isolate.spawnUri(
+        Uri.dataFromString(code, mimeType: 'application/dart', encoding: utf8),
+        [],
+        message,
+        packageConfig: await Isolate.packageConfig,
+        checked: true,
+        onExit: onExit);
 
-// TODO(nweiz): Move this into the analyzer once it starts using SourceSpan
-// (issue 22977).
 /// Takes a span whose source is the value of a string that has been parsed from
 /// a Dart file and returns the corresponding span from within that Dart file.
 ///
diff --git a/test_core/lib/src/util/io.dart b/test_core/lib/src/util/io.dart
index fafa9b0..c2cc3da 100644
--- a/test_core/lib/src/util/io.dart
+++ b/test_core/lib/src/util/io.dart
@@ -21,7 +21,7 @@
 const _defaultLineLength = 200;
 
 /// Whether the test runner is running on Google-internal infrastructure.
-final bool inGoogle = Platform.version.contains("(google3)");
+final bool inGoogle = Platform.version.contains('(google3)');
 
 /// The maximum line length for output.
 final int lineLength = () {
@@ -48,9 +48,6 @@
   throw UnsupportedError('Unsupported operating system "$name".');
 })();
 
-// TODO(nweiz): Make this `new SuitePlatform.current()` once we only support
-// Dart 2 and we can import `dart:io` from within cross-platform libraries. See
-// commit 4ffda6d2.
 /// Returns a [SuitePlatform] with the given [runtime], and with [os] and
 /// [inGoogle] determined automatically.
 ///
@@ -63,15 +60,15 @@
 final stdinLines = StreamQueue(lineSplitter.bind(stdin));
 
 /// Whether this is being run as a subprocess in the test package's own tests.
-bool inTestTests = Platform.environment["_DART_TEST_TESTING"] == "true";
+bool inTestTests = Platform.environment['_DART_TEST_TESTING'] == 'true';
 
 /// The root directory below which to nest temporary directories created by the
 /// test runner.
 ///
 /// This is configurable so that the test code can validate that the runner
 /// cleans up after itself fully.
-final _tempDir = Platform.environment.containsKey("_UNITTEST_TEMP_DIR")
-    ? Platform.environment["_UNITTEST_TEMP_DIR"]
+final _tempDir = Platform.environment.containsKey('_UNITTEST_TEMP_DIR')
+    ? Platform.environment['_UNITTEST_TEMP_DIR']
     : Directory.systemTemp.path;
 
 /// Whether or not the current terminal supports ansi escape codes.
@@ -92,7 +89,7 @@
 ///
 /// Returns a future that completes to the value that the future returned from
 /// [fn] completes to.
-Future withTempDir(Future fn(String path)) {
+Future withTempDir(Future Function(String) fn) {
   return Future.sync(() {
     var tempDir = createTempDir();
     return Future.sync(() => fn(tempDir))
@@ -106,10 +103,10 @@
 /// part of a word's length. It only splits words on spaces, not on other sorts
 /// of whitespace.
 String wordWrap(String text) {
-  return text.split("\n").map((originalLine) {
+  return text.split('\n').map((originalLine) {
     var buffer = StringBuffer();
     var lengthSoFar = 0;
-    for (var word in originalLine.split(" ")) {
+    for (var word in originalLine.split(' ')) {
       var wordLength = withoutColors(word).length;
       if (wordLength > lineLength) {
         if (lengthSoFar != 0) buffer.writeln();
@@ -122,12 +119,12 @@
         buffer.write(word);
         lengthSoFar = wordLength;
       } else {
-        buffer.write(" $word");
+        buffer.write(' $word');
         lengthSoFar += 1 + wordLength;
       }
     }
     return buffer.toString();
-  }).join("\n");
+  }).join('\n');
 }
 
 /// Print a warning containing [message].
@@ -139,9 +136,9 @@
 /// If [print] is `true`, this prints the message using [print] to associate it
 /// with the current test. Otherwise, it prints it using [stderr].
 void warn(String message, {bool color, bool print = false}) {
-  if (color == null) color = canUseSpecialChars;
-  var header = color ? "\u001b[33mWarning:\u001b[0m" : "Warning:";
-  (print ? core.print : stderr.writeln)(wordWrap("$header $message\n"));
+  color ??= canUseSpecialChars;
+  var header = color ? '\u001b[33mWarning:\u001b[0m' : 'Warning:';
+  (print ? core.print : stderr.writeln)(wordWrap('$header $message\n'));
 }
 
 /// Repeatedly finds a probably-unused port on localhost and passes it to
@@ -153,7 +150,7 @@
 ///
 /// This is necessary for ensuring that our port binding isn't flaky for
 /// applications that don't print out the bound port.
-Future<T> getUnusedPort<T>(FutureOr<T> tryPort(int port)) async {
+Future<T> getUnusedPort<T>(FutureOr<T> Function(int port) tryPort) async {
   T value;
   await Future.doWhile(() async {
     value = await tryPort(await getUnsafeUnusedPort());
@@ -198,11 +195,11 @@
 Future<Uri> getRemoteDebuggerUrl(Uri base) async {
   try {
     var client = HttpClient();
-    var request = await client.getUrl(base.resolve("/json/list"));
+    var request = await client.getUrl(base.resolve('/json/list'));
     var response = await request.close();
     var jsonObject =
         await json.fuse(utf8).decoder.bind(response).single as List;
-    return base.resolve(jsonObject.first["devtoolsFrontendUrl"] as String);
+    return base.resolve(jsonObject.first['devtoolsFrontendUrl'] as String);
   } catch (_) {
     // If we fail to talk to the remote debugger protocol, give up and return
     // the raw URL rather than crashing.
diff --git a/test_core/lib/src/util/stack_trace_mapper.dart b/test_core/lib/src/util/stack_trace_mapper.dart
index d99608c..4f4a821 100644
--- a/test_core/lib/src/util/stack_trace_mapper.dart
+++ b/test_core/lib/src/util/stack_trace_mapper.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:package_resolver/package_resolver.dart';
 import 'package:source_map_stack_trace/source_map_stack_trace.dart' as mapper;
 import 'package:source_maps/source_maps.dart';
 import 'package:test_api/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports
@@ -14,8 +13,8 @@
   /// This is initialized lazily in `mapStackTrace()`.
   Mapping _mapping;
 
-  /// The package resolution information passed to dart2js.
-  final SyncPackageResolver _packageResolver;
+  /// The same package resolution information as was passed to dart2js.
+  final Map<String, Uri> _packageMap;
 
   /// The URL of the SDK root from which dart2js loaded its sources.
   final Uri _sdkRoot;
@@ -27,26 +26,26 @@
   final Uri _mapUrl;
 
   JSStackTraceMapper(this._mapContents,
-      {Uri mapUrl, SyncPackageResolver packageResolver, Uri sdkRoot})
+      {Uri mapUrl, Map<String, Uri> packageMap, Uri sdkRoot})
       : _mapUrl = mapUrl,
-        _packageResolver = packageResolver,
+        _packageMap = packageMap,
         _sdkRoot = sdkRoot;
 
   /// Converts [trace] into a Dart stack trace.
+  @override
   StackTrace mapStackTrace(StackTrace trace) {
     _mapping ??= parseExtended(_mapContents, mapUrl: _mapUrl);
     return mapper.mapStackTrace(_mapping, trace,
-        packageResolver: _packageResolver, sdkRoot: _sdkRoot);
+        packageMap: _packageMap, sdkRoot: _sdkRoot);
   }
 
   /// Returns a Map representation which is suitable for JSON serialization.
+  @override
   Map<String, dynamic> serialize() {
     return {
       'mapContents': _mapContents,
       'sdkRoot': _sdkRoot?.toString(),
-      'packageConfigMap':
-          _serializePackageConfigMap(_packageResolver.packageConfigMap),
-      'packageRoot': _packageResolver.packageRoot?.toString(),
+      'packageConfigMap': _serializePackageConfigMap(_packageMap),
       'mapUrl': _mapUrl?.toString(),
     };
   }
@@ -55,15 +54,12 @@
   /// representation.
   static StackTraceMapper deserialize(Map serialized) {
     if (serialized == null) return null;
-    String packageRoot = serialized['packageRoot'] as String ?? '';
+    var deserialized = _deserializePackageConfigMap(
+        (serialized['packageConfigMap'] as Map).cast<String, String>());
+
     return JSStackTraceMapper(serialized['mapContents'] as String,
         sdkRoot: Uri.parse(serialized['sdkRoot'] as String),
-        packageResolver: packageRoot.isNotEmpty
-            ? SyncPackageResolver.root(
-                Uri.parse(serialized['packageRoot'] as String))
-            : SyncPackageResolver.config(_deserializePackageConfigMap(
-                (serialized['packageConfigMap'] as Map)
-                    .cast<String, String>())),
+        packageMap: deserialized,
         mapUrl: Uri.parse(serialized['mapUrl'] as String));
   }
 
diff --git a/test_core/lib/src/util/string_literal_iterator.dart b/test_core/lib/src/util/string_literal_iterator.dart
index 6b340c2..24caa08 100644
--- a/test_core/lib/src/util/string_literal_iterator.dart
+++ b/test_core/lib/src/util/string_literal_iterator.dart
@@ -37,6 +37,7 @@
 /// In addition to exposing the values of the runes themselves, this also
 /// exposes the offset of the current rune in the Dart source file.
 class StringLiteralIterator extends Iterator<int> {
+  @override
   int get current => _current;
   int _current;
 
@@ -96,6 +97,7 @@
     _offset = _strings.first.contentsOffset - 1;
   }
 
+  @override
   bool moveNext() {
     // If we're at beginning of a [SimpleStringLiteral], move forward until
     // there's actually text to consume.
diff --git a/test_core/lib/test_core.dart b/test_core/lib/test_core.dart
index 3e937c0..3dc5960 100644
--- a/test_core/lib/test_core.dart
+++ b/test_core/lib/test_core.dart
@@ -10,7 +10,6 @@
 
 import 'package:meta/meta.dart';
 import 'package:path/path.dart' as p;
-import 'package:pedantic/pedantic.dart';
 import 'package:test_api/backend.dart'; //ignore: deprecated_member_use
 import 'package:test_api/src/backend/declarer.dart'; // ignore: implementation_imports
 import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
@@ -65,10 +64,9 @@
 
     var success = await runZoned(() => Invoker.guard(engine.run),
         zoneValues: {#test.declarer: _globalDeclarer});
-    // TODO(nweiz): Set the exit code on the VM when issue 6943 is fixed.
     if (success) return null;
     print('');
-    unawaited(Future.error("Dummy exception to set exit code."));
+    unawaited(Future.error('Dummy exception to set exit code.'));
   });
   return _globalDeclarer;
 }
@@ -108,15 +106,15 @@
 /// annotation classes: [Timeout], [Skip], or lists of those. These
 /// annotations apply only on the given platforms. For example:
 ///
-///     test("potentially slow test", () {
+///     test('potentially slow test', () {
 ///       // ...
 ///     }, onPlatform: {
 ///       // This test is especially slow on Windows.
-///       "windows": new Timeout.factor(2),
-///       "browser": [
-///         new Skip("TODO: add browser support"),
+///       'windows': Timeout.factor(2),
+///       'browser': [
+///         Skip('TODO: add browser support'),
 ///         // This will be slow on browsers once it works on them.
-///         new Timeout.factor(2)
+///         Timeout.factor(2)
 ///       ]
 ///     });
 ///
@@ -129,7 +127,7 @@
 /// avoid this flag if possible and instead use the test runner flag `-n` to
 /// filter tests by name.
 @isTest
-void test(description, body(),
+void test(description, dynamic Function() body,
     {String testOn,
     Timeout timeout,
     skip,
@@ -186,15 +184,15 @@
 /// annotation classes: [Timeout], [Skip], or lists of those. These
 /// annotations apply only on the given platforms. For example:
 ///
-///     group("potentially slow tests", () {
+///     group('potentially slow tests', () {
 ///       // ...
 ///     }, onPlatform: {
 ///       // These tests are especially slow on Windows.
-///       "windows": new Timeout.factor(2),
-///       "browser": [
-///         new Skip("TODO: add browser support"),
+///       'windows': Timeout.factor(2),
+///       'browser': [
+///         Skip('TODO: add browser support'),
 ///         // They'll be slow on browsers once it works on them.
-///         new Timeout.factor(2)
+///         Timeout.factor(2)
 ///       ]
 ///     });
 ///
@@ -207,7 +205,7 @@
 /// avoid this flag if possible, and instead use the test runner flag `-n` to
 /// filter tests by name.
 @isTestGroup
-void group(description, body(),
+void group(description, dynamic Function() body,
     {String testOn,
     Timeout timeout,
     skip,
@@ -242,7 +240,7 @@
 ///
 /// Each callback at the top level or in a given group will be run in the order
 /// they were declared.
-void setUp(callback()) => _declarer.setUp(callback);
+void setUp(dynamic Function() callback) => _declarer.setUp(callback);
 
 /// Registers a function to be run after tests.
 ///
@@ -257,7 +255,7 @@
 /// reverse of the order they were declared.
 ///
 /// See also [addTearDown], which adds tear-downs to a running test.
-void tearDown(callback()) => _declarer.tearDown(callback);
+void tearDown(dynamic Function() callback) => _declarer.tearDown(callback);
 
 /// Registers a function to be run once before all tests.
 ///
@@ -272,7 +270,7 @@
 /// dependencies between tests that should be isolated. In general, you should
 /// prefer [setUp], and only use [setUpAll] if the callback is prohibitively
 /// slow.
-void setUpAll(callback()) => _declarer.setUpAll(callback);
+void setUpAll(dynamic Function() callback) => _declarer.setUpAll(callback);
 
 /// Registers a function to be run once after all tests.
 ///
@@ -285,4 +283,5 @@
 /// dependencies between tests that should be isolated. In general, you should
 /// prefer [tearDown], and only use [tearDownAll] if the callback is
 /// prohibitively slow.
-void tearDownAll(callback()) => _declarer.tearDownAll(callback);
+void tearDownAll(dynamic Function() callback) =>
+    _declarer.tearDownAll(callback);
diff --git a/test_core/mono_pkg.yaml b/test_core/mono_pkg.yaml
index 995000f..f6da98d 100644
--- a/test_core/mono_pkg.yaml
+++ b/test_core/mono_pkg.yaml
@@ -6,4 +6,4 @@
       dart: dev
     - group:
       - dartanalyzer: --fatal-warnings .
-      dart: 2.1.0
+      dart: 2.7.0
diff --git a/test_core/pubspec.yaml b/test_core/pubspec.yaml
index 8c6a1f1..881878a 100644
--- a/test_core/pubspec.yaml
+++ b/test_core/pubspec.yaml
@@ -1,36 +1,33 @@
 name: test_core
-version: 0.2.15
-author: Dart Team <misc@dartlang.org>
+version: 0.3.2
 description: A basic library for writing tests and running them on the VM.
 homepage: https://github.com/dart-lang/test/blob/master/pkgs/test_core
 
 environment:
-  sdk: ">=2.2.0 <3.0.0"
+  sdk: ">=2.7.0 <3.0.0"
 
 dependencies:
   analyzer: ">=0.36.0 <0.40.0"
   async: ^2.0.0
   args: ^1.4.0
-  boolean_selector: ^1.0.0
+  boolean_selector: ">=1.0.0 <3.0.0"
   collection: ^1.8.0
   coverage: ^0.13.3
   glob: ^1.0.0
   io: ^0.3.0
   meta: ^1.1.5
-  package_resolver: ^1.0.0
   path: ^1.2.0
   pedantic: ^1.0.0
   pool: ^1.3.0
-  source_map_stack_trace: ^1.1.4
+  source_map_stack_trace: ^2.0.0
   source_maps: ^0.10.2
   source_span: ^1.4.0
   stack_trace: ^1.9.0
   stream_channel: ">=1.7.0 <3.0.0"
-  vm_service: '>=1.0.0 <3.0.0'
+  vm_service: '>=1.0.0 <4.0.0'
   yaml: ^2.0.0
   # Use a tight version constraint to ensure that a constraint on matcher
   # properly constrains all features it provides.
   matcher: ">=0.12.6 <0.12.7"
   # Use an exact version until the test_api package is stable.
-  test_api: 0.2.11
-
+  test_api: 0.2.15
diff --git a/timing/.gitignore b/timing/.gitignore
deleted file mode 100644
index 1ddf798..0000000
--- a/timing/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.packages
-/build/
-pubspec.lock
-
-# Files generated by dart tools
-.dart_tool
-doc/
diff --git a/timing/.travis.yml b/timing/.travis.yml
deleted file mode 100644
index 581db89..0000000
--- a/timing/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: dart
-
-dart:
-  - 2.2.0
-  - dev
-
-dart_task:
-- dartanalyzer: --fatal-infos --fatal-warnings .
-- test
-
-matrix:
-  include:
-  # Only validate formatting using the dev release
-  - dart: dev
-    dart_task: dartfmt
-
-branches:
-  only:
-  - master
-
-cache:
-  directories:
-  - $HOME/.pub-cache
diff --git a/timing/BUILD.gn b/timing/BUILD.gn
deleted file mode 100644
index d6b6e7e..0000000
--- a/timing/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is generated by importer.py for timing-0.1.1+2
-
-import("//build/dart/dart_library.gni")
-
-dart_library("timing") {
-  package_name = "timing"
-
-  # This parameter is left empty as we don't care about analysis or exporting
-  # these sources outside of the tree.
-  sources = []
-
-  disable_analysis = true
-
-  deps = [
-    "//third_party/dart-pkg/pub/json_annotation",
-  ]
-}
diff --git a/timing/CHANGELOG.md b/timing/CHANGELOG.md
deleted file mode 100644
index 8cb1627..0000000
--- a/timing/CHANGELOG.md
+++ /dev/null
@@ -1,16 +0,0 @@
-## 0.1.1+2
-
-- Support the latest version of `package:json_annotation`.
-- Require Dart 2.2 or later.
-
-## 0.1.1+1
-
-- Support the latest version of `package:json_annotation`.
-
-## 0.1.1
-
-- Add JSON serialization
-
-## 0.1.0
-
-- Initial release
diff --git a/timing/LICENSE b/timing/LICENSE
deleted file mode 100644
index c4dc9ba..0000000
--- a/timing/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/timing/README.md b/timing/README.md
deleted file mode 100644
index 400bc4b..0000000
--- a/timing/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# [![Build Status](https://travis-ci.org/dart-lang/timing.svg?branch=master)](https://travis-ci.org/dart-lang/timing)
-
-Timing is a simple package for tracking performance of both async and sync actions
-
-```dart
-var tracker = AsyncTimeTracker();
-await tracker.track(() async {
-  // some async code here
-});
-
-// Use results
-print('${tracker.duration} ${tracker.innerDuration} ${tracker.slices}');
-```
-
-
-## Building
-
-Use the following command to re-generate `lib/src/timing.g.dart` file:
-
-```bash
-pub run build_runner build
-```
\ No newline at end of file
diff --git a/timing/analysis_options.yaml b/timing/analysis_options.yaml
deleted file mode 100644
index 210b18f..0000000
--- a/timing/analysis_options.yaml
+++ /dev/null
@@ -1,93 +0,0 @@
-include: package:pedantic/analysis_options.yaml
-analyzer:
-  strong-mode:
-    implicit-casts: false
-linter:
-  rules:
-    - always_declare_return_types
-    - annotate_overrides
-    - avoid_bool_literals_in_conditional_expressions
-    - avoid_classes_with_only_static_members
-    - avoid_empty_else
-    - avoid_function_literals_in_foreach_calls
-    - avoid_init_to_null
-    - avoid_null_checks_in_equality_operators
-    - avoid_relative_lib_imports
-    - avoid_renaming_method_parameters
-    - avoid_return_types_on_setters
-    - avoid_returning_null
-    - avoid_returning_null_for_void
-    - avoid_returning_this
-    - avoid_shadowing_type_parameters
-    - avoid_single_cascade_in_expression_statements
-    - avoid_types_as_parameter_names
-    - avoid_unused_constructor_parameters
-    - await_only_futures
-    - camel_case_types
-    - cancel_subscriptions
-    - cascade_invocations
-    - comment_references
-    - constant_identifier_names
-    - control_flow_in_finally
-    - curly_braces_in_flow_control_structures
-    - directives_ordering
-    - empty_catches
-    - empty_constructor_bodies
-    - empty_statements
-    - file_names
-    - hash_and_equals
-    - implementation_imports
-    - invariant_booleans
-    - iterable_contains_unrelated_type
-    - join_return_with_assignment
-    - library_names
-    - library_prefixes
-    - list_remove_unrelated_type
-    - literal_only_boolean_expressions
-    - no_duplicate_case_values
-    - non_constant_identifier_names
-    - null_closures
-    - omit_local_variable_types
-    - only_throw_errors
-    - overridden_fields
-    - package_api_docs
-    - package_names
-    - package_prefixed_library_names
-    - prefer_adjacent_string_concatenation
-    - prefer_collection_literals
-    - prefer_conditional_assignment
-    - prefer_const_constructors
-    - prefer_contains
-    - prefer_equal_for_default_values
-    - prefer_final_fields
-    - prefer_final_locals
-    - prefer_generic_function_type_aliases
-    - prefer_initializing_formals
-    - prefer_interpolation_to_compose_strings
-    - prefer_iterable_whereType
-    - prefer_is_empty
-    - prefer_is_not_empty
-    - prefer_null_aware_operators
-    - prefer_single_quotes
-    - prefer_typing_uninitialized_variables
-    - prefer_void_to_null
-    - recursive_getters
-    - slash_for_doc_comments
-    - test_types_in_equals
-    - throw_in_finally
-    - type_init_formals
-    - unawaited_futures
-    - unnecessary_brace_in_string_interps
-    - unnecessary_const
-    - unnecessary_getters_setters
-    - unnecessary_lambdas
-    - unnecessary_new
-    - unnecessary_null_aware_assignments
-    - unnecessary_null_in_if_null_operators
-    - unnecessary_parenthesis
-    - unnecessary_statements
-    - unnecessary_this
-    - unrelated_type_equality_checks
-    - use_rethrow_when_possible
-    - valid_regexps
-    - void_checks
diff --git a/timing/lib/src/clock.dart b/timing/lib/src/clock.dart
deleted file mode 100644
index ae1f25f..0000000
--- a/timing/lib/src/clock.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-/// A function that returns the current [DateTime].
-typedef _Clock = DateTime Function();
-DateTime _defaultClock() => DateTime.now();
-
-const _zoneKey = #timing_Clock;
-
-/// Returns the current [DateTime].
-///
-/// May be overridden for tests using [scopeClock].
-DateTime now() => (Zone.current[_zoneKey] as _Clock ?? _defaultClock)();
-
-/// Runs [f], with [clock] scoped whenever [now] is called.
-T scopeClock<T>(DateTime clock(), T f()) =>
-    runZoned(f, zoneValues: {_zoneKey: clock});
diff --git a/timing/lib/src/timing.dart b/timing/lib/src/timing.dart
deleted file mode 100644
index 17e2fb1..0000000
--- a/timing/lib/src/timing.dart
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:json_annotation/json_annotation.dart';
-
-import 'clock.dart';
-
-part 'timing.g.dart';
-
-/// The timings of an operation, including its [startTime], [stopTime], and
-/// [duration].
-@JsonSerializable(nullable: false)
-class TimeSlice {
-  /// The total duration of this operation, equivalent to taking the difference
-  /// between [stopTime] and [startTime].
-  Duration get duration => stopTime.difference(startTime);
-
-  final DateTime startTime;
-
-  final DateTime stopTime;
-
-  TimeSlice(this.startTime, this.stopTime);
-
-  factory TimeSlice.fromJson(Map<String, dynamic> json) =>
-      _$TimeSliceFromJson(json);
-
-  Map<String, dynamic> toJson() => _$TimeSliceToJson(this);
-
-  @override
-  String toString() => '($startTime + $duration)';
-}
-
-/// The timings of an async operation, consist of several sync [slices] and
-/// includes total [startTime], [stopTime], and [duration].
-@JsonSerializable(nullable: false)
-class TimeSliceGroup implements TimeSlice {
-  final List<TimeSlice> slices;
-
-  @override
-  DateTime get startTime => slices.first.startTime;
-
-  @override
-  DateTime get stopTime => slices.last.stopTime;
-
-  /// The total duration of this operation, equivalent to taking the difference
-  /// between [stopTime] and [startTime].
-  @override
-  Duration get duration => stopTime.difference(startTime);
-
-  /// Sum of [duration]s of all [slices].
-  ///
-  /// If some of slices implements [TimeSliceGroup] [innerDuration] will be used
-  /// to compute sum.
-  Duration get innerDuration => slices.fold(
-      Duration.zero,
-      (duration, slice) =>
-          duration +
-          (slice is TimeSliceGroup ? slice.innerDuration : slice.duration));
-
-  TimeSliceGroup(this.slices);
-
-  /// Constructs TimeSliceGroup from JSON representation
-  factory TimeSliceGroup.fromJson(Map<String, dynamic> json) =>
-      _$TimeSliceGroupFromJson(json);
-
-  @override
-  Map<String, dynamic> toJson() => _$TimeSliceGroupToJson(this);
-
-  @override
-  String toString() => slices.toString();
-}
-
-abstract class TimeTracker implements TimeSlice {
-  /// Whether tracking is active.
-  ///
-  /// Tracking is only active after `isStarted` and before `isFinished`.
-  bool get isTracking;
-
-  /// Whether tracking is finished.
-  ///
-  /// Tracker can't be used as [TimeSlice] before it is finished
-  bool get isFinished;
-
-  /// Whether tracking was started.
-  ///
-  /// Equivalent of `isTracking || isFinished`
-  bool get isStarted;
-
-  T track<T>(T Function() action);
-}
-
-/// Tracks only sync actions
-class SyncTimeTracker implements TimeTracker {
-  /// When this operation started, call [_start] to set this.
-  @override
-  DateTime get startTime => _startTime;
-  DateTime _startTime;
-
-  /// When this operation stopped, call [_stop] to set this.
-  @override
-  DateTime get stopTime => _stopTime;
-  DateTime _stopTime;
-
-  /// Start tracking this operation, must only be called once, before [_stop].
-  void _start() {
-    assert(_startTime == null && _stopTime == null);
-    _startTime = now();
-  }
-
-  /// Stop tracking this operation, must only be called once, after [_start].
-  void _stop() {
-    assert(_startTime != null && _stopTime == null);
-    _stopTime = now();
-  }
-
-  /// Splits tracker into two slices
-  ///
-  /// Returns new [TimeSlice] started on [startTime] and ended now.
-  /// Modifies [startTime] of tracker to current time point
-  ///
-  /// Don't change state of tracker. Can be called only while [isTracking], and
-  /// tracker will sill be tracking after call.
-  TimeSlice _split() {
-    if (!isTracking) {
-      throw StateError('Can be only called while tracking');
-    }
-    final _now = now();
-    final prevSlice = TimeSlice(_startTime, _now);
-    _startTime = _now;
-    return prevSlice;
-  }
-
-  @override
-  T track<T>(T Function() action) {
-    if (isStarted) {
-      throw StateError('Can not be tracked twice');
-    }
-    _start();
-    try {
-      return action();
-    } finally {
-      _stop();
-    }
-  }
-
-  @override
-  bool get isStarted => startTime != null;
-
-  @override
-  bool get isTracking => startTime != null && stopTime == null;
-
-  @override
-  bool get isFinished => startTime != null && stopTime != null;
-
-  @override
-  Duration get duration => stopTime?.difference(startTime);
-
-  /// Converts to JSON representation
-  ///
-  /// Can't be used before [isFinished]
-  @override
-  Map<String, dynamic> toJson() => _$TimeSliceToJson(this);
-}
-
-/// Async actions returning [Future] will be tracked as single sync time span
-/// from the beginning of execution till completion of future
-class SimpleAsyncTimeTracker extends SyncTimeTracker {
-  @override
-  T track<T>(T Function() action) {
-    if (isStarted) {
-      throw StateError('Can not be tracked twice');
-    }
-    T result;
-    _start();
-    try {
-      result = action();
-    } catch (_) {
-      _stop();
-      rethrow;
-    }
-    if (result is Future) {
-      return result.whenComplete(_stop) as T;
-    } else {
-      _stop();
-      return result;
-    }
-  }
-}
-
-/// No-op implementation of [SyncTimeTracker] that does nothing.
-class NoOpTimeTracker implements TimeTracker {
-  static final sharedInstance = NoOpTimeTracker();
-
-  @override
-  Duration get duration =>
-      throw UnsupportedError('Unsupported in no-op implementation');
-
-  @override
-  DateTime get startTime =>
-      throw UnsupportedError('Unsupported in no-op implementation');
-
-  @override
-  DateTime get stopTime =>
-      throw UnsupportedError('Unsupported in no-op implementation');
-
-  @override
-  bool get isStarted =>
-      throw UnsupportedError('Unsupported in no-op implementation');
-
-  @override
-  bool get isTracking =>
-      throw UnsupportedError('Unsupported in no-op implementation');
-
-  @override
-  bool get isFinished =>
-      throw UnsupportedError('Unsupported in no-op implementation');
-
-  @override
-  T track<T>(T Function() action) => action();
-
-  @override
-  Map<String, dynamic> toJson() =>
-      throw UnsupportedError('Unsupported in no-op implementation');
-}
-
-/// Track all async execution as disjoint time [slices] in ascending order.
-///
-/// Can [track] both async and sync actions.
-/// Can exclude time of tested trackers.
-///
-/// If tracked action spawns some dangled async executions behavior is't
-/// defined. Tracked might or might not track time of such executions
-class AsyncTimeTracker extends TimeSliceGroup implements TimeTracker {
-  final bool trackNested;
-
-  static const _zoneKey = #timing_AsyncTimeTracker;
-
-  AsyncTimeTracker({this.trackNested = true}) : super([]);
-
-  T _trackSyncSlice<T>(ZoneDelegate parent, Zone zone, T Function() action) {
-    // Ignore dangling runs after tracker completes
-    if (isFinished) {
-      return action();
-    }
-
-    final isNestedRun = slices.isNotEmpty &&
-        slices.last is SyncTimeTracker &&
-        (slices.last as SyncTimeTracker).isTracking;
-    final isExcludedNestedTrack = !trackNested && zone[_zoneKey] != this;
-
-    // Exclude nested sync tracks
-    if (isNestedRun && isExcludedNestedTrack) {
-      final timer = slices.last as SyncTimeTracker;
-      // Split already tracked time into new slice.
-      // Replace tracker in slices.last with splitted slice, to indicate for
-      // recursive calls that we not tracking.
-      slices.last = parent.run(zone, timer._split);
-      try {
-        return action();
-      } finally {
-        // Split tracker again and discard slice that was spend in nested tracker
-        parent.run(zone, timer._split);
-        // Add tracker back to list of slices and continue tracking
-        slices.add(timer);
-      }
-    }
-
-    // Exclude nested async tracks
-    if (isExcludedNestedTrack) {
-      return action();
-    }
-
-    // Split time slices in nested sync runs
-    if (isNestedRun) {
-      return action();
-    }
-
-    final timer = SyncTimeTracker();
-    slices.add(timer);
-
-    // Pass to parent zone, in case of overwritten clock
-    return parent.runUnary(zone, timer.track, action);
-  }
-
-  static final asyncTimeTrackerZoneSpecification = ZoneSpecification(
-    run: <R>(Zone self, ZoneDelegate parent, Zone zone, R Function() f) {
-      final tracker = self[_zoneKey] as AsyncTimeTracker;
-      return tracker._trackSyncSlice(parent, zone, () => parent.run(zone, f));
-    },
-    runUnary: <R, T>(Zone self, ZoneDelegate parent, Zone zone, R Function(T) f,
-        T arg) {
-      final tracker = self[_zoneKey] as AsyncTimeTracker;
-      return tracker._trackSyncSlice(
-          parent, zone, () => parent.runUnary(zone, f, arg));
-    },
-    runBinary: <R, T1, T2>(Zone self, ZoneDelegate parent, Zone zone,
-        R Function(T1, T2) f, T1 arg1, T2 arg2) {
-      final tracker = self[_zoneKey] as AsyncTimeTracker;
-      return tracker._trackSyncSlice(
-          parent, zone, () => parent.runBinary(zone, f, arg1, arg2));
-    },
-  );
-
-  @override
-  T track<T>(T Function() action) {
-    if (isStarted) {
-      throw StateError('Can not be tracked twice');
-    }
-    _tracking = true;
-    final result = runZoned(action,
-        zoneSpecification: asyncTimeTrackerZoneSpecification,
-        zoneValues: {_zoneKey: this});
-    if (result is Future) {
-      return result
-          // Break possible sync processing of future completion, so slice trackers can be finished
-          .whenComplete(() => Future.value())
-          .whenComplete(() => _tracking = false) as T;
-    } else {
-      _tracking = false;
-      return result;
-    }
-  }
-
-  bool _tracking;
-
-  @override
-  bool get isStarted => _tracking != null;
-
-  @override
-  bool get isFinished => _tracking == false;
-
-  @override
-  bool get isTracking => _tracking == true;
-}
diff --git a/timing/lib/src/timing.g.dart b/timing/lib/src/timing.g.dart
deleted file mode 100644
index 91293b2..0000000
--- a/timing/lib/src/timing.g.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'timing.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-TimeSlice _$TimeSliceFromJson(Map<String, dynamic> json) {
-  return TimeSlice(
-    DateTime.parse(json['startTime'] as String),
-    DateTime.parse(json['stopTime'] as String),
-  );
-}
-
-Map<String, dynamic> _$TimeSliceToJson(TimeSlice instance) => <String, dynamic>{
-      'startTime': instance.startTime.toIso8601String(),
-      'stopTime': instance.stopTime.toIso8601String(),
-    };
-
-TimeSliceGroup _$TimeSliceGroupFromJson(Map<String, dynamic> json) {
-  return TimeSliceGroup(
-    (json['slices'] as List)
-        .map((e) => TimeSlice.fromJson(e as Map<String, dynamic>))
-        .toList(),
-  );
-}
-
-Map<String, dynamic> _$TimeSliceGroupToJson(TimeSliceGroup instance) =>
-    <String, dynamic>{
-      'slices': instance.slices,
-    };
diff --git a/timing/lib/timing.dart b/timing/lib/timing.dart
deleted file mode 100644
index 0163e8d..0000000
--- a/timing/lib/timing.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-export 'src/timing.dart'
-    show
-        TimeSlice,
-        TimeSliceGroup,
-        TimeTracker,
-        SyncTimeTracker,
-        SimpleAsyncTimeTracker,
-        AsyncTimeTracker,
-        NoOpTimeTracker;
diff --git a/timing/pubspec.yaml b/timing/pubspec.yaml
deleted file mode 100644
index 0b45123..0000000
--- a/timing/pubspec.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: timing
-version: 0.1.1+2
-description: >-
-  A simple package for tracking the performance of synchronous and asynchronous
-  actions.
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/timing
-
-environment:
-  sdk: ">=2.2.0 <3.0.0"
-
-dependencies:
-  json_annotation: '>=1.0.0 <4.0.0'
-
-dev_dependencies:
-  build_runner: ^1.0.0
-  json_serializable: ^3.1.0
-  pedantic: ^1.1.0
-  test: ^1.0.0
diff --git a/url_launcher/BUILD.gn b/url_launcher/BUILD.gn
index 51448e6..ec21259 100644
--- a/url_launcher/BUILD.gn
+++ b/url_launcher/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher-5.4.1
+# This file is generated by importer.py for url_launcher-5.4.2
 
 import("//build/dart/dart_library.gni")
 
diff --git a/url_launcher/CHANGELOG.md b/url_launcher/CHANGELOG.md
index a38c3eb..0cab101 100644
--- a/url_launcher/CHANGELOG.md
+++ b/url_launcher/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 5.4.2
+
+* Make the pedantic dev_dependency explicit.
+
 ## 5.4.1
 
 * Update unit tests to work with the PlatformInterface from package `plugin_platform_interface`.
diff --git a/url_launcher/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/url_launcher/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/url_launcher/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/url_launcher/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/url_launcher/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/url_launcher/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>
diff --git a/url_launcher/example/pubspec.yaml b/url_launcher/example/pubspec.yaml
index 4d9d01a..065693e 100644
--- a/url_launcher/example/pubspec.yaml
+++ b/url_launcher/example/pubspec.yaml
@@ -11,6 +11,7 @@
   e2e: "^0.2.0"
   flutter_driver:
     sdk: flutter
+  pedantic: ^1.8.0
 
 flutter:
   uses-material-design: true
diff --git a/url_launcher/pubspec.yaml b/url_launcher/pubspec.yaml
index cd51673..ba92970 100644
--- a/url_launcher/pubspec.yaml
+++ b/url_launcher/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Flutter plugin for launching a URL on Android and iOS. Supports
   web, phone, SMS, and email schemes.
 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher
-version: 5.4.1
+version: 5.4.2
 
 flutter:
   plugin:
@@ -35,6 +35,7 @@
   test: ^1.3.0
   mockito: ^4.1.1
   plugin_platform_interface: ^1.0.0
+  pedantic: ^1.8.0
 
 environment:
   sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/url_launcher_macos/BUILD.gn b/url_launcher_macos/BUILD.gn
index f91dd9d..e4bf2db 100644
--- a/url_launcher_macos/BUILD.gn
+++ b/url_launcher_macos/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher_macos-0.0.1+2
+# This file is generated by importer.py for url_launcher_macos-0.0.1+4
 
 import("//build/dart/dart_library.gni")
 
diff --git a/url_launcher_macos/CHANGELOG.md b/url_launcher_macos/CHANGELOG.md
index 446b448..6ecac5b 100644
--- a/url_launcher_macos/CHANGELOG.md
+++ b/url_launcher_macos/CHANGELOG.md
@@ -1,3 +1,11 @@
+# 0.0.1+4
+
+* Make the pedantic dev_dependency explicit.
+
+# 0.0.1+3
+
+* Update Gradle version.
+
 # 0.0.1+2
 
 * Update README.
diff --git a/url_launcher_macos/android/gradle/wrapper/gradle-wrapper.properties b/url_launcher_macos/android/gradle/wrapper/gradle-wrapper.properties
index 019065d..d757f3d 100644
--- a/url_launcher_macos/android/gradle/wrapper/gradle-wrapper.properties
+++ b/url_launcher_macos/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
diff --git a/url_launcher_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/url_launcher_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/url_launcher_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/url_launcher_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/url_launcher_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/url_launcher_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>
diff --git a/url_launcher_macos/example/pubspec.yaml b/url_launcher_macos/example/pubspec.yaml
index 2552786..1125b6d 100644
--- a/url_launcher_macos/example/pubspec.yaml
+++ b/url_launcher_macos/example/pubspec.yaml
@@ -12,6 +12,7 @@
   e2e: "^0.2.0"
   flutter_driver:
     sdk: flutter
+  pedantic: ^1.8.0
 
 flutter:
   uses-material-design: true
diff --git a/url_launcher_macos/pubspec.yaml b/url_launcher_macos/pubspec.yaml
index 9e4b200..3f6d5e0 100644
--- a/url_launcher_macos/pubspec.yaml
+++ b/url_launcher_macos/pubspec.yaml
@@ -1,6 +1,6 @@
 name: url_launcher_macos
 description: macOS implementation of the url_launcher plugin.
-version: 0.0.1+2
+version: 0.0.1+4
 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_macos
 
 flutter:
@@ -17,3 +17,6 @@
 dependencies:
   flutter:
     sdk: flutter
+
+dev_dependencies:
+  pedantic: ^1.8.0
diff --git a/url_launcher_platform_interface/BUILD.gn b/url_launcher_platform_interface/BUILD.gn
index 4564bfc..ac8d95a 100644
--- a/url_launcher_platform_interface/BUILD.gn
+++ b/url_launcher_platform_interface/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher_platform_interface-1.0.5
+# This file is generated by importer.py for url_launcher_platform_interface-1.0.6
 
 import("//build/dart/dart_library.gni")
 
diff --git a/url_launcher_platform_interface/CHANGELOG.md b/url_launcher_platform_interface/CHANGELOG.md
index f55b4cb..592102f 100644
--- a/url_launcher_platform_interface/CHANGELOG.md
+++ b/url_launcher_platform_interface/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.6
+
+* Make the pedantic dev_dependency explicit.
+
 ## 1.0.5
 
 * Make the `PlatformInterface` `_token` non `const` (as `const` `Object`s are not unique).
diff --git a/url_launcher_platform_interface/pubspec.yaml b/url_launcher_platform_interface/pubspec.yaml
index aa57b14..806c967 100644
--- a/url_launcher_platform_interface/pubspec.yaml
+++ b/url_launcher_platform_interface/pubspec.yaml
@@ -3,7 +3,7 @@
 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_platform_interface
 # NOTE: We strongly prefer non-breaking changes, even at the expense of a
 # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 1.0.5
+version: 1.0.6
 
 dependencies:
   flutter:
@@ -15,6 +15,7 @@
   flutter_test:
     sdk: flutter
   mockito: ^4.1.1
+  pedantic: ^1.8.0
 
 environment:
   sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/url_launcher_web/BUILD.gn b/url_launcher_web/BUILD.gn
index afe68bd..c277ba0 100644
--- a/url_launcher_web/BUILD.gn
+++ b/url_launcher_web/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher_web-0.1.1
+# This file is generated by importer.py for url_launcher_web-0.1.1+1
 
 import("//build/dart/dart_library.gni")
 
diff --git a/url_launcher_web/CHANGELOG.md b/url_launcher_web/CHANGELOG.md
index df73939..0cb57ef 100644
--- a/url_launcher_web/CHANGELOG.md
+++ b/url_launcher_web/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.1.1+1
+
+- Make the pedantic dev_dependency explicit.
+
 # 0.1.1
 
 - Added support for mailto scheme
diff --git a/url_launcher_web/pubspec.yaml b/url_launcher_web/pubspec.yaml
index d02d250..8e74677 100644
--- a/url_launcher_web/pubspec.yaml
+++ b/url_launcher_web/pubspec.yaml
@@ -1,7 +1,7 @@
 name: url_launcher_web
 description: Web platform implementation of url_launcher
 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_web
-version: 0.1.1
+version: 0.1.1+1
 
 flutter:
   plugin:
@@ -22,6 +22,7 @@
   flutter_test:
     sdk: flutter
   url_launcher: ^5.2.5
+  pedantic: ^1.8.0
 
 environment:
   sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/video_player_platform_interface/BUILD.gn b/video_player_platform_interface/BUILD.gn
index c75bc39..a22628c 100644
--- a/video_player_platform_interface/BUILD.gn
+++ b/video_player_platform_interface/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for video_player_platform_interface-1.0.4
+# This file is generated by importer.py for video_player_platform_interface-1.0.5
 
 import("//build/dart/dart_library.gni")
 
diff --git a/video_player_platform_interface/CHANGELOG.md b/video_player_platform_interface/CHANGELOG.md
index 79be27a..be1b0e3 100644
--- a/video_player_platform_interface/CHANGELOG.md
+++ b/video_player_platform_interface/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.5
+
+* Make the pedantic dev_dependency explicit.
+
 ## 1.0.4
 
 * Remove the deprecated `author:` field from pubspec.yaml
diff --git a/video_player_platform_interface/pubspec.yaml b/video_player_platform_interface/pubspec.yaml
index 8bae556..2ce3bd1 100644
--- a/video_player_platform_interface/pubspec.yaml
+++ b/video_player_platform_interface/pubspec.yaml
@@ -3,7 +3,7 @@
 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_platform_interface
 # NOTE: We strongly prefer non-breaking changes, even at the expense of a
 # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 1.0.4
+version: 1.0.5
 
 dependencies:
   flutter:
@@ -14,6 +14,7 @@
   flutter_test:
     sdk: flutter
   mockito: ^4.1.1
+  pedantic: ^1.8.0
 
 environment:
   sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/video_player_web/BUILD.gn b/video_player_web/BUILD.gn
index 5a949ae..27d4a7e 100644
--- a/video_player_web/BUILD.gn
+++ b/video_player_web/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for video_player_web-0.1.2
+# This file is generated by importer.py for video_player_web-0.1.2+1
 
 import("//build/dart/dart_library.gni")
 
diff --git a/video_player_web/CHANGELOG.md b/video_player_web/CHANGELOG.md
index 4c3aaa7..00fc486 100644
--- a/video_player_web/CHANGELOG.md
+++ b/video_player_web/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.2+1
+
+* Make the pedantic dev_dependency explicit.
+
 ## 0.1.2
 
 * Add a `PlatformException` to the player's `eventController` when there's a `videoElement.onError`. Fixes https://github.com/flutter/flutter/issues/48884.
diff --git a/video_player_web/pubspec.yaml b/video_player_web/pubspec.yaml
index 4358f82..e1435c8 100644
--- a/video_player_web/pubspec.yaml
+++ b/video_player_web/pubspec.yaml
@@ -1,7 +1,7 @@
 name: video_player_web
 description: Web platform implementation of video_player
 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_web
-version: 0.1.2
+version: 0.1.2+1
 
 flutter:
   plugin:
@@ -23,6 +23,7 @@
     sdk: flutter
   video_player:
     path: ../video_player
+  pedantic: ^1.8.0
 
 environment:
   sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/webdriver/BUILD.gn b/webdriver/BUILD.gn
index 1c2312d..ddb3675 100644
--- a/webdriver/BUILD.gn
+++ b/webdriver/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for webdriver-2.1.1
+# This file is generated by importer.py for webdriver-2.1.2
 
 import("//build/dart/dart_library.gni")
 
diff --git a/webdriver/CHANGELOG.md b/webdriver/CHANGELOG.md
index db252ae..1b9b0b0 100644
--- a/webdriver/CHANGELOG.md
+++ b/webdriver/CHANGELOG.md
@@ -1,3 +1,7 @@
+## v2.1.2
+
+* Updated to latest version of sync_http.
+
 ## v2.1.1
 
 * Forward-compatible fix for upcoming Dart SDK breaking change
diff --git a/webdriver/analysis_options.yaml b/webdriver/analysis_options.yaml
index 0b79a58..6f8b463 100644
--- a/webdriver/analysis_options.yaml
+++ b/webdriver/analysis_options.yaml
@@ -1,5 +1,3 @@
-analyzer:
-  strong-mode: true
 linter:
   rules:
     - always_declare_return_types
@@ -13,7 +11,6 @@
     - cancel_subscriptions
     - control_flow_in_finally
     - empty_constructor_bodies
-    - empty_constructor_bodies
     - empty_statements
     - hash_and_equals
     - implementation_imports
@@ -43,8 +40,6 @@
     - prefer_typing_uninitialized_variables
     - recursive_getters
     - slash_for_doc_comments
-    - slash_for_doc_comments
-    - super_goes_last
     - test_types_in_equals
     - throw_in_finally
     - type_init_formals
diff --git a/webdriver/lib/async_core.dart b/webdriver/lib/async_core.dart
index ce49382..8013467 100644
--- a/webdriver/lib/async_core.dart
+++ b/webdriver/lib/async_core.dart
@@ -124,5 +124,5 @@
   }
 
   return WebDriver(uri, sessionId, UnmodifiableMapView(capabilities),
-      createRequestClient(uri.resolve('session/${sessionId}/')), spec);
+      createRequestClient(uri.resolve('session/$sessionId/')), spec);
 }
diff --git a/webdriver/lib/src/async/common.dart b/webdriver/lib/src/async/common.dart
index 26f7e9e..d015eb6 100644
--- a/webdriver/lib/src/async/common.dart
+++ b/webdriver/lib/src/async/common.dart
@@ -23,7 +23,7 @@
 /// Simple class to provide access to indexed properties such as WebElement
 /// attributes or css styles.
 class Attributes {
-  GetAttribute _getAttribute;
+  final GetAttribute _getAttribute;
 
   Attributes(this._getAttribute);
 
diff --git a/webdriver/lib/src/handler/json_wire_handler.dart b/webdriver/lib/src/handler/json_wire_handler.dart
index 3bad7bd..4bcd061 100644
--- a/webdriver/lib/src/handler/json_wire_handler.dart
+++ b/webdriver/lib/src/handler/json_wire_handler.dart
@@ -69,5 +69,5 @@
       deserialize(parseJsonWireResponse(response), createElement);
 
   @override
-  String toString() => "JsonWire";
+  String toString() => 'JsonWire';
 }
diff --git a/webdriver/pubspec.yaml b/webdriver/pubspec.yaml
index 8fed1b8..31a5052 100644
--- a/webdriver/pubspec.yaml
+++ b/webdriver/pubspec.yaml
@@ -1,5 +1,5 @@
 name: webdriver
-version: 2.1.1
+version: 2.1.2
 authors:
   - Marc Fisher II <fisherii@google.com>
   - Matt Staats<staats@google.com>
@@ -15,6 +15,6 @@
   matcher: ^0.12.3
   path: ^1.3.0
   stack_trace: ^1.3.0
-  sync_http: ^0.1.1
+  sync_http: '>=0.1.1 <0.3.0'
 dev_dependencies:
   test: '^1.0.0'
diff --git a/webkit_inspection_protocol/.travis.yml b/webkit_inspection_protocol/.travis.yml
index ad23559..35e0ab9 100644
--- a/webkit_inspection_protocol/.travis.yml
+++ b/webkit_inspection_protocol/.travis.yml
@@ -1,11 +1,10 @@
 language: dart
-sudo: false
 
 dart:
   - dev
 
-before_install:
-  - export DISPLAY=:99.0
-  - sh -e /etc/init.d/xvfb start
+#before_install:
+#  - export DISPLAY=:99.0
+#  - sh -e /etc/init.d/xvfb start
 
 script: ./tool/travis.sh
diff --git a/webkit_inspection_protocol/BUILD.gn b/webkit_inspection_protocol/BUILD.gn
index 12419e9..60ef4d0 100644
--- a/webkit_inspection_protocol/BUILD.gn
+++ b/webkit_inspection_protocol/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for webkit_inspection_protocol-0.5.0
+# This file is generated by importer.py for webkit_inspection_protocol-0.5.0+1
 
 import("//build/dart/dart_library.gni")
 
diff --git a/webkit_inspection_protocol/changelog.md b/webkit_inspection_protocol/changelog.md
index 1f1847f..27a9bb7 100644
--- a/webkit_inspection_protocol/changelog.md
+++ b/webkit_inspection_protocol/changelog.md
@@ -1,5 +1,8 @@
 # webkit_inspection_protocol.dart
 
+## 0.5.0+1
+- fixed a bug in reading type of `WipScope`
+
 ## 0.5.0
 - removed the bin/multiplex.dart binary to the example/ directory
 - remove dependencies on `package:args`, package:shelf`, and `package:shelf_web_socket`
diff --git a/webkit_inspection_protocol/lib/src/debugger.dart b/webkit_inspection_protocol/lib/src/debugger.dart
index 5c3808b..fa4c428 100644
--- a/webkit_inspection_protocol/lib/src/debugger.dart
+++ b/webkit_inspection_protocol/lib/src/debugger.dart
@@ -160,7 +160,7 @@
   WipScope(this._map);
 
   // "catch", "closure", "global", "local", "with"
-  String get scope => _map['scope'] as String;
+  String get scope => _map['type'] as String;
 
   /// Object representing the scope. For global and with scopes it represents
   /// the actual object; for the rest of the scopes, it is artificial transient
diff --git a/webkit_inspection_protocol/pubspec.yaml b/webkit_inspection_protocol/pubspec.yaml
index 8df358b..1de55da 100644
--- a/webkit_inspection_protocol/pubspec.yaml
+++ b/webkit_inspection_protocol/pubspec.yaml
@@ -1,5 +1,5 @@
 name: webkit_inspection_protocol
-version: 0.5.0
+version: 0.5.0+1
 description: A client for the Chrome DevTools Protocol (previously called the Webkit Inspection Protocol).
 
 homepage: https://github.com/google/webkit_inspection_protocol.dart