diff --git a/CHANGELOG.md b/CHANGELOG.md
index c4e881b..59dbf53 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,9 @@
 #### 4.0.0-dev
 
-* Remove implicit casts in preparation for null-safety
-* Remove dependency on `package:intl`
+* Migrate to null-safety.
+* Remove record/replay functionality.
+* Remove implicit casts in preparation for null-safety.
+* Remove dependency on `package:intl` and `package:meta`.
 
 #### 3.0.13
 
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 2b88268..2c72e4b 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,4 +1,6 @@
 analyzer:
+  enable-experiment:
+    - non-nullable
   strong-mode:
     implicit-dynamic: false
     implicit-casts: false
diff --git a/dev/travis.sh b/dev/travis.sh
index 866b361..192b2e8 100755
--- a/dev/travis.sh
+++ b/dev/travis.sh
@@ -27,4 +27,4 @@
 set -e
 
 # Run the tests.
-pub run test
+pub run --enable-experiment=non-nullable test
diff --git a/lib/process.dart b/lib/process.dart
index dfeb1d0..a407c48 100644
--- a/lib/process.dart
+++ b/lib/process.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.
 
+// @dart=2.10
 export 'src/interface/local_process_manager.dart';
 export 'src/interface/process_manager.dart';
 export 'src/interface/process_wrapper.dart';
diff --git a/lib/record_replay.dart b/lib/record_replay.dart
deleted file mode 100644
index e9211bb..0000000
--- a/lib/record_replay.dart
+++ /dev/null
@@ -1,7 +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/record_replay/command_element.dart';
-export 'src/record_replay/recording_process_manager.dart';
-export 'src/record_replay/replay_process_manager.dart';
diff --git a/lib/src/interface/common.dart b/lib/src/interface/common.dart
index 89c8036..f2db1c3 100644
--- a/lib/src/interface/common.dart
+++ b/lib/src/interface/common.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.
 
+// @dart=2.10
 import 'package:file/file.dart';
 import 'package:file/local.dart';
 import 'package:path/path.dart' show Context;
@@ -48,9 +49,9 @@
 /// could not be found.
 ///
 /// If [platform] is not specified, it will default to the current platform.
-String getExecutablePath(
+String? getExecutablePath(
   String command,
-  String workingDirectory, {
+  String? workingDirectory, {
   Platform platform = const LocalPlatform(),
   FileSystem fs = const LocalFileSystem(),
 }) {
@@ -72,7 +73,7 @@
 
   List<String> extensions = <String>[];
   if (platform.isWindows && context.extension(command).isEmpty) {
-    extensions = platform.environment['PATHEXT'].split(pathSeparator);
+    extensions = platform.environment['PATHEXT']!.split(pathSeparator);
   }
 
   List<String> candidates = <String>[];
@@ -80,11 +81,16 @@
     candidates = _getCandidatePaths(
         command, <String>[workingDirectory], extensions, context);
   } else {
-    List<String> searchPath = platform.environment['PATH'].split(pathSeparator);
+    List<String> searchPath =
+        platform.environment['PATH']!.split(pathSeparator);
     candidates = _getCandidatePaths(command, searchPath, extensions, context);
   }
-  return candidates.firstWhere((String path) => fs.file(path).existsSync(),
-      orElse: () => null);
+  for (String path in candidates) {
+    if (fs.file(path).existsSync()) {
+      return path;
+    }
+  }
+  return null;
 }
 
 /// Returns all possible combinations of `$searchPath\$command.$ext` for
diff --git a/lib/src/interface/local_process_manager.dart b/lib/src/interface/local_process_manager.dart
index 268bcf7..648540a 100644
--- a/lib/src/interface/local_process_manager.dart
+++ b/lib/src/interface/local_process_manager.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.
 
+// @dart=2.10
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io'
@@ -31,8 +32,8 @@
   @override
   Future<Process> start(
     covariant List<Object> command, {
-    String workingDirectory,
-    Map<String, String> environment,
+    String? workingDirectory,
+    Map<String, String>? environment,
     bool includeParentEnvironment = true,
     bool runInShell = false,
     ProcessStartMode mode = ProcessStartMode.normal,
@@ -55,8 +56,8 @@
   @override
   Future<ProcessResult> run(
     covariant List<Object> command, {
-    String workingDirectory,
-    Map<String, String> environment,
+    String? workingDirectory,
+    Map<String, String>? environment,
     bool includeParentEnvironment = true,
     bool runInShell = false,
     Encoding stdoutEncoding = systemEncoding,
@@ -81,8 +82,8 @@
   @override
   ProcessResult runSync(
     covariant List<Object> command, {
-    String workingDirectory,
-    Map<String, String> environment,
+    String? workingDirectory,
+    Map<String, String>? environment,
     bool includeParentEnvironment = true,
     bool runInShell = false,
     Encoding stdoutEncoding = systemEncoding,
@@ -105,7 +106,7 @@
   }
 
   @override
-  bool canRun(covariant String executable, {String workingDirectory}) =>
+  bool canRun(covariant String executable, {String? workingDirectory}) =>
       getExecutablePath(executable, workingDirectory) != null;
 
   @override
@@ -115,12 +116,12 @@
 }
 
 String _getExecutable(
-    List<dynamic> command, String workingDirectory, bool runInShell) {
+    List<dynamic> command, String? workingDirectory, bool runInShell) {
   String commandName = command.first.toString();
   if (runInShell) {
     return commandName;
   }
-  String exe = getExecutablePath(commandName, workingDirectory);
+  String? exe = getExecutablePath(commandName, workingDirectory);
   if (exe == null) {
     throw ArgumentError('Cannot find executable for $commandName.');
   }
diff --git a/lib/src/interface/process_manager.dart b/lib/src/interface/process_manager.dart
index 67fd079..8c0e5b7 100644
--- a/lib/src/interface/process_manager.dart
+++ b/lib/src/interface/process_manager.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.
 
+// @dart=2.10
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io'
diff --git a/lib/src/interface/process_wrapper.dart b/lib/src/interface/process_wrapper.dart
index e2ebee4..9c275f5 100644
--- a/lib/src/interface/process_wrapper.dart
+++ b/lib/src/interface/process_wrapper.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.
 
+// @dart=2.10
 import 'dart:async';
 import 'dart:io' as io;
 
@@ -53,7 +54,7 @@
   ///
   /// The future returned here will complete with the exit code of the process.
   Future<int> get done async {
-    int result;
+    late int result;
     await Future.wait<void>(<Future<void>>[
       _stdoutDone.future,
       _stderrDone.future,
@@ -61,7 +62,6 @@
         result = value;
       }),
     ]);
-    assert(result != null);
     return result;
   }
 
diff --git a/lib/src/record_replay/can_run_manifest_entry.dart b/lib/src/record_replay/can_run_manifest_entry.dart
deleted file mode 100644
index ec9a64a..0000000
--- a/lib/src/record_replay/can_run_manifest_entry.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-import 'manifest_entry.dart';
-
-/// An entry in the process invocation manifest for `canRun`.
-class CanRunManifestEntry extends ManifestEntry {
-  /// Creates a new manifest entry with the given properties.
-  CanRunManifestEntry({this.executable, this.result});
-
-  /// Creates a new manifest entry populated with the specified JSON [data].
-  ///
-  /// If any required fields are missing from the JSON data, this will throw
-  /// a [FormatException].
-  factory CanRunManifestEntry.fromJson(Map<String, dynamic> data) {
-    checkRequiredField(data, 'executable');
-    checkRequiredField(data, 'result');
-    CanRunManifestEntry entry = CanRunManifestEntry(
-      executable: data['executable'] as String,
-      result: data['result'] as bool,
-    );
-    return entry;
-  }
-
-  @override
-  final String type = 'can_run';
-
-  /// The name of the executable for which the run-ability is checked.
-  final String executable;
-
-  /// The result of the check.
-  final bool result;
-
-  @override
-  Map<String, dynamic> toJson() =>
-      JsonBuilder().add('executable', executable).add('result', result).entry;
-}
diff --git a/lib/src/record_replay/command_element.dart b/lib/src/record_replay/command_element.dart
deleted file mode 100644
index c38a948..0000000
--- a/lib/src/record_replay/command_element.dart
+++ /dev/null
@@ -1,60 +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:process/process.dart';
-
-/// Callback used to [sanitize](CommandElement.sanitized) a [CommandElement]
-/// for the purpose of recording.
-typedef CommandSanitizer = String Function(String rawValue);
-
-/// A command element capable of holding both a raw and sanitized value.
-///
-/// Instances of this type can be used in the `command` list of the
-/// [ProcessManager.start], [ProcessManager.run], and [ProcessManager.runSync]
-/// methods.
-///
-/// Each command element has:
-///   - A raw value, which is the value that should passed to the underlying
-///     operating system to invoke the process.
-///   - A sanitized value, which is the value that's serialized when used with
-///     [RecordingProcessManager] and looked up in the replay log when used
-///     with [ReplayProcessManager]. Sanitized values typically will remove
-///     user-specific segments (such as the user's home directory) or random
-///     segments (such as temporary file names). Sanitizing values allows you
-///     to guarantee determinism in your process invocation lookups, thus
-///     removing flakiness in tests.
-///
-/// This class implements [toString] to return the element's raw value, meaning
-/// instances of this class can be passed directly to [LocalProcessManager]
-/// and will work as intended.
-class CommandElement {
-  /// Creates a new command element with the specified [raw] value.
-  ///
-  /// If a [sanitizer] is specified, it will be used to generate this command
-  /// element's [sanitized] value. If it is unspecified, the raw value will be
-  /// used as the sanitized value.
-  CommandElement(this.raw, {CommandSanitizer sanitizer})
-      : _sanitizer = sanitizer;
-
-  final CommandSanitizer _sanitizer;
-
-  /// This command element's raw, unsanitized, value.
-  ///
-  /// This value is liable to contain non-deterministic segments, such as
-  /// OS-generated temporary file names. It is suitable for passing to the
-  /// operating system to invoke a process, but it is not suitable for
-  /// record/replay.
-  final String raw;
-
-  /// This command element's sanitized value.
-  ///
-  /// This value has been stripped of any non-deterministic segments, such as
-  /// OS-generated temporary file names or user-specific values. It is suitable
-  /// for record/replay, but it is not suitable for passing to the operating
-  /// system to invoke a process.
-  String get sanitized => _sanitizer == null ? raw : _sanitizer(raw);
-
-  @override
-  String toString() => raw;
-}
diff --git a/lib/src/record_replay/common.dart b/lib/src/record_replay/common.dart
deleted file mode 100644
index fae84a4..0000000
--- a/lib/src/record_replay/common.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 'command_element.dart';
-
-/// Sanitizes the specified [command] by running any non-deterministic
-/// segments through a [sanitizer](CommandSanitizer) if possible.
-List<String> sanitize(List<dynamic> command) {
-  return command
-      .map((dynamic element) {
-        if (element is CommandElement) {
-          return element.sanitized;
-        }
-        return element.toString();
-      })
-      .toList()
-      .cast<String>();
-}
diff --git a/lib/src/record_replay/constants.dart b/lib/src/record_replay/constants.dart
deleted file mode 100644
index 732d607..0000000
--- a/lib/src/record_replay/constants.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.
-
-/// The name of the invocation manifest file.
-const String kManifestName = 'MANIFEST.txt';
diff --git a/lib/src/record_replay/manifest.dart b/lib/src/record_replay/manifest.dart
deleted file mode 100644
index 9aae5fd..0000000
--- a/lib/src/record_replay/manifest.dart
+++ /dev/null
@@ -1,128 +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' show ProcessStartMode;
-
-import 'can_run_manifest_entry.dart';
-import 'manifest_entry.dart';
-import 'run_manifest_entry.dart';
-
-/// Tests if two lists contain pairwise equal elements.
-bool _areListsEqual<T>(List<T> list1, List<T> list2) {
-  int i = 0;
-  return list1 != null &&
-      list2 != null &&
-      list1.length == list2.length &&
-      list1.every((dynamic element) => element == list2[i++]);
-}
-
-/// Tells whether [testValue] is non-null and equal to [entryValue]. If
-/// [isEqual] is specified, it will be used to determine said equality.
-bool _isHit<T>(
-  T entryValue,
-  T testValue, [
-  bool isEqual(T value1, T value2),
-]) {
-  if (testValue == null) {
-    return true;
-  } else if (isEqual != null) {
-    return isEqual(entryValue, testValue);
-  }
-  return entryValue == testValue;
-}
-
-/// The process invocation manifest, holding metadata about every recorded
-/// process invocation.
-class Manifest {
-  /// Creates a new manifest.
-  Manifest();
-
-  /// Creates a new manifest populated with the specified [json] data.
-  ///
-  /// If [json] does not represent a valid JSON string (matching the format of
-  /// [toJson]), a [FormatException] will be thrown.
-  factory Manifest.fromJson(String json) {
-    List<Map<String, dynamic>> decoded =
-        (jsonDecode(json) as List<dynamic>).cast<Map<String, dynamic>>();
-    Manifest manifest = Manifest();
-    decoded.forEach((Map<String, dynamic> entry) {
-      switch (entry['type'] as String) {
-        case 'run':
-          manifest._entries.add(
-              RunManifestEntry.fromJson(entry['body'] as Map<String, dynamic>));
-          break;
-        case 'can_run':
-          manifest._entries.add(CanRunManifestEntry.fromJson(
-              entry['body'] as Map<String, dynamic>));
-          break;
-        default:
-          throw UnsupportedError('Manifest type ${entry['type']} is unkown.');
-      }
-    });
-    return manifest;
-  }
-
-  final List<ManifestEntry> _entries = <ManifestEntry>[];
-
-  /// Adds the specified [entry] to this manifest.
-  void add(ManifestEntry entry) => _entries.add(entry);
-
-  /// The number of entries currently in the manifest.
-  int get length => _entries.length;
-
-  /// Gets the entry whose [RunManifestEntry.pid] matches the specified [pid].
-  ManifestEntry getRunEntry(int pid) {
-    return _entries.firstWhere(
-        (ManifestEntry entry) => entry is RunManifestEntry && entry.pid == pid);
-  }
-
-  /// Finds the first manifest entry that has not been invoked and whose
-  /// metadata matches the specified criteria. If no arguments are specified,
-  /// this will simply return the first entry that has not yet been invoked.
-  ManifestEntry findPendingRunEntry({
-    List<String> command,
-    ProcessStartMode mode,
-    Encoding stdoutEncoding,
-    Encoding stderrEncoding,
-  }) {
-    return _entries.firstWhere(
-      (ManifestEntry entry) {
-        return entry is RunManifestEntry &&
-            !entry.invoked &&
-            _isHit(entry.command, command, _areListsEqual) &&
-            _isHit(entry.mode, mode) &&
-            _isHit(entry.stdoutEncoding, stdoutEncoding) &&
-            _isHit(entry.stderrEncoding, stderrEncoding);
-      },
-      orElse: () => null,
-    );
-  }
-
-  /// Finds the first manifest entry that has not been invoked and whose
-  /// metadata matches the specified criteria. If no arguments are specified,
-  /// this will simply return the first entry that has not yet been invoked.
-  ManifestEntry findPendingCanRunEntry({
-    String executable,
-  }) {
-    return _entries.firstWhere(
-      (ManifestEntry entry) {
-        return entry is CanRunManifestEntry &&
-            !entry.invoked &&
-            _isHit(entry.executable, executable);
-      },
-      orElse: () => null,
-    );
-  }
-
-  /// Returns a JSON-encoded representation of this manifest.
-  String toJson() {
-    List<Map<String, dynamic>> list = <Map<String, dynamic>>[];
-    _entries.forEach((ManifestEntry entry) => list.add(JsonBuilder()
-        .add('type', entry.type)
-        .add('body', entry.toJson())
-        .entry));
-    return const JsonEncoder.withIndent('  ').convert(list);
-  }
-}
diff --git a/lib/src/record_replay/manifest_entry.dart b/lib/src/record_replay/manifest_entry.dart
deleted file mode 100644
index 78d0314..0000000
--- a/lib/src/record_replay/manifest_entry.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-import 'manifest.dart';
-import 'replay_process_manager.dart';
-
-/// An entry in the process invocation manifest.
-///
-/// Each entry in the [Manifest] represents a single recorded process
-/// invocation.
-abstract class ManifestEntry {
-  /// Whether this entry has been "invoked" by [ReplayProcessManager].
-  bool get invoked => _invoked;
-  bool _invoked = false;
-
-  /// Marks this entry as having been "invoked" by [ReplayProcessManager].
-  void setInvoked() {
-    _invoked = true;
-  }
-
-  /// The type of this [ManifestEntry].
-  String get type;
-
-  /// Returns a JSON-encodable representation of this manifest entry.
-  Map<String, dynamic> toJson();
-}
-
-/// A lightweight class that provides a means of building a manifest entry
-/// JSON object.
-class JsonBuilder {
-  /// The JSON-encodable object.
-  final Map<String, dynamic> entry = <String, dynamic>{};
-
-  /// Adds the specified key/value pair to the manifest entry iff the value
-  /// is non-null. If [jsonValue] is specified, its value will be used instead
-  /// of the raw value.
-  JsonBuilder add(String name, dynamic value, [dynamic jsonValue()]) {
-    if (value != null) {
-      entry[name] = jsonValue == null ? value : jsonValue();
-    }
-    return this;
-  }
-}
-
-/// Throws a [FormatException] if [data] does not contain [key].
-void checkRequiredField(Map<String, dynamic> data, String key) {
-  if (!data.containsKey(key))
-    throw FormatException('Required field missing: $key');
-}
diff --git a/lib/src/record_replay/recording_process_manager.dart b/lib/src/record_replay/recording_process_manager.dart
deleted file mode 100644
index a2e1c41..0000000
--- a/lib/src/record_replay/recording_process_manager.dart
+++ /dev/null
@@ -1,416 +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' as io
-    show
-        IOSink,
-        Process,
-        ProcessResult,
-        ProcessSignal,
-        ProcessStartMode,
-        systemEncoding;
-
-import 'package:file/file.dart';
-import 'package:path/path.dart' as path;
-
-import '../interface/process_manager.dart';
-import 'can_run_manifest_entry.dart';
-import 'common.dart';
-import 'constants.dart';
-import 'manifest.dart';
-import 'replay_process_manager.dart';
-import 'run_manifest_entry.dart';
-
-/// Records process invocation activity and serializes it to disk.
-///
-/// A `RecordingProcessManager` decorates another `ProcessManager` instance by
-/// recording all process invocation activity (including the stdout and stderr
-/// of the associated processes) before delegating to the underlying manager.
-///
-/// This class enables "record / replay" tests, where you record the process
-/// invocation activity during a real program run, serialize the activity to
-/// disk, then fake all invocation activity during tests by replaying the
-/// serialized recording.
-///
-/// See also:
-///
-/// * [ReplayProcessManager].
-class RecordingProcessManager implements ProcessManager {
-  /// Constructs a new `RecordingProcessManager`.
-  ///
-  /// This manager will record all process invocations and serialize them to
-  /// the specified [destination]. The underlying `ProcessManager` functionality
-  /// will be delegated to [delegate].
-  ///
-  /// If [destination] does not already exist, or if it exists and is not empty,
-  /// a [StateError] will be thrown.
-  ///
-  /// [destination] should be treated as opaque. Its contents are intended to
-  /// be consumed only by [ReplayProcessManager] and are subject to change
-  /// between versions of `package:process`.
-  RecordingProcessManager(this.delegate, this.destination) {
-    if (!destination.existsSync() || destination.listSync().isNotEmpty) {
-      throw StateError('Cannot record to ${destination.path}');
-    }
-  }
-
-  static const List<String> _kSkippableExecutables = <String>[
-    'env',
-    'xcrun',
-  ];
-
-  /// The manager to which this manager delegates.
-  final ProcessManager delegate;
-
-  /// The directory to which serialized invocation metadata will be written.
-  final Directory destination;
-
-  /// List of invocation metadata. Will be serialized as [kManifestName].
-  final Manifest _manifest = Manifest();
-
-  /// Maps process IDs of running processes to exit code futures.
-  final Map<int, Future<int>> _runningProcesses = <int, Future<int>>{};
-
-  /// The file system in which this manager will create recording files.
-  FileSystem get fs => destination.fileSystem;
-
-  @override
-  Future<io.Process> start(
-    List<dynamic> command, {
-    String workingDirectory,
-    Map<String, String> environment,
-    bool includeParentEnvironment = true,
-    bool runInShell = false,
-    io.ProcessStartMode mode = io.ProcessStartMode.normal,
-  }) async {
-    io.Process process = await delegate.start(
-      command,
-      workingDirectory: workingDirectory,
-      environment: environment,
-      includeParentEnvironment: includeParentEnvironment,
-      runInShell: runInShell,
-      mode: mode,
-    );
-
-    List<String> sanitizedCommand = sanitize(command);
-    String basename = _getBasename(process.pid, sanitizedCommand);
-    RunManifestEntry entry = RunManifestEntry(
-      pid: process.pid,
-      basename: basename,
-      command: sanitizedCommand,
-      workingDirectory: workingDirectory,
-      environment: environment,
-      includeParentEnvironment: includeParentEnvironment,
-      runInShell: runInShell,
-      mode: mode,
-    );
-    _manifest.add(entry);
-
-    _RecordingProcess result = _RecordingProcess(
-      manager: this,
-      basename: basename,
-      delegate: process,
-    );
-    await result.startRecording();
-    _runningProcesses[process.pid] = result.exitCode.then((int exitCode) {
-      _runningProcesses.remove(process.pid);
-      entry.exitCode = exitCode;
-      return exitCode;
-    });
-
-    return result;
-  }
-
-  @override
-  Future<io.ProcessResult> run(
-    List<dynamic> command, {
-    String workingDirectory,
-    Map<String, String> environment,
-    bool includeParentEnvironment = true,
-    bool runInShell = false,
-    Encoding stdoutEncoding = io.systemEncoding,
-    Encoding stderrEncoding = io.systemEncoding,
-  }) async {
-    io.ProcessResult result = await delegate.run(
-      command,
-      workingDirectory: workingDirectory,
-      environment: environment,
-      includeParentEnvironment: includeParentEnvironment,
-      runInShell: runInShell,
-      stdoutEncoding: stdoutEncoding,
-      stderrEncoding: stderrEncoding,
-    );
-
-    List<String> sanitizedCommand = sanitize(command);
-    String basename = _getBasename(result.pid, sanitizedCommand);
-    _manifest.add(RunManifestEntry(
-      pid: result.pid,
-      basename: basename,
-      command: sanitizedCommand,
-      workingDirectory: workingDirectory,
-      environment: environment,
-      includeParentEnvironment: includeParentEnvironment,
-      runInShell: runInShell,
-      stdoutEncoding: stdoutEncoding,
-      stderrEncoding: stderrEncoding,
-      exitCode: result.exitCode,
-    ));
-
-    await _recordData(result.stdout, stdoutEncoding, '$basename.stdout');
-    await _recordData(result.stderr, stderrEncoding, '$basename.stderr');
-
-    return result;
-  }
-
-  Future<Null> _recordData(
-      dynamic data, Encoding encoding, String basename) async {
-    File file = fs.file('${destination.path}/$basename');
-    IOSink recording = file.openWrite(encoding: encoding);
-    try {
-      if (encoding == null)
-        recording.add(data as List<int>);
-      else
-        recording.write(data);
-      await recording.flush();
-    } finally {
-      await recording.close();
-    }
-  }
-
-  @override
-  io.ProcessResult runSync(
-    List<dynamic> command, {
-    String workingDirectory,
-    Map<String, String> environment,
-    bool includeParentEnvironment = true,
-    bool runInShell = false,
-    Encoding stdoutEncoding = io.systemEncoding,
-    Encoding stderrEncoding = io.systemEncoding,
-  }) {
-    io.ProcessResult result = delegate.runSync(
-      command,
-      workingDirectory: workingDirectory,
-      environment: environment,
-      includeParentEnvironment: includeParentEnvironment,
-      runInShell: runInShell,
-      stdoutEncoding: stdoutEncoding,
-      stderrEncoding: stderrEncoding,
-    );
-
-    List<String> sanitizedCommand = sanitize(command);
-    String basename = _getBasename(result.pid, sanitizedCommand);
-    _manifest.add(RunManifestEntry(
-      pid: result.pid,
-      basename: basename,
-      command: sanitizedCommand,
-      workingDirectory: workingDirectory,
-      environment: environment,
-      includeParentEnvironment: includeParentEnvironment,
-      runInShell: runInShell,
-      stdoutEncoding: stdoutEncoding,
-      stderrEncoding: stderrEncoding,
-      exitCode: result.exitCode,
-    ));
-
-    _recordDataSync(result.stdout, stdoutEncoding, '$basename.stdout');
-    _recordDataSync(result.stderr, stderrEncoding, '$basename.stderr');
-
-    return result;
-  }
-
-  void _recordDataSync(dynamic data, Encoding encoding, String basename) {
-    File file = fs.file('${destination.path}/$basename');
-    if (encoding == null)
-      file.writeAsBytesSync(data as List<int>, flush: true);
-    else
-      file.writeAsStringSync(data as String, encoding: encoding, flush: true);
-  }
-
-  @override
-  bool canRun(dynamic executable, {String workingDirectory}) {
-    bool result =
-        delegate.canRun(executable, workingDirectory: workingDirectory);
-    _manifest.add(
-        CanRunManifestEntry(executable: executable.toString(), result: result));
-    return result;
-  }
-
-  @override
-  bool killPid(int pid, [io.ProcessSignal signal = io.ProcessSignal.sigterm]) {
-    return delegate.killPid(pid, signal);
-  }
-
-  /// Returns a human-readable identifier for the specified executable.
-  String _getBasename(int pid, List<String> sanitizedCommand) {
-    String index = _manifest.length.toString();
-    String identifier = 'executable';
-    for (String element in sanitizedCommand) {
-      if (element.startsWith('-')) {
-        // Ignore flags.
-        continue;
-      }
-      identifier = path.basename(element);
-      if (!_kSkippableExecutables.contains(identifier)) {
-        break;
-      }
-    }
-    return '$index.$identifier.$pid';
-  }
-
-  /// Flushes pending data to [destination].
-  ///
-  /// This manager may buffer invocation metadata in memory as it sees fit.
-  /// Calling `flush` will force the manager to write any pending data to disk.
-  /// This returns a future that completes when all pending data has been
-  /// written to disk.
-  ///
-  /// Failure to call this method before the current process exits will likely
-  /// cause invocation data to be lost.
-  ///
-  /// If [finishRunningProcesses] is true, the returned future will only
-  /// complete after all running processes have exited, thus guaranteeing that
-  /// no new invocation data will be generated until new processes are invoked.
-  /// Any processes that don't exit on their own within the specified [timeout]
-  /// will be marked as daemon processes in the serialized metadata and will be
-  /// signalled with `SIGTERM`. If such processes *still* don't exit within the
-  /// specified [timeout] after being signalled, they'll be marked as not
-  /// responding in the serialized metadata.
-  ///
-  /// If [finishRunningProcesses] is false (the default), then [timeout] is
-  /// ignored.
-  Future<Null> flush({
-    bool finishRunningProcesses = false,
-    Duration timeout = const Duration(milliseconds: 20),
-  }) async {
-    if (finishRunningProcesses) {
-      await _waitForRunningProcessesToExit(timeout);
-    }
-    await _writeManifestToDisk();
-  }
-
-  /// Waits for all running processes to exit, and records their exit codes in
-  /// the process manifest. Any process that doesn't exit within [timeout]
-  /// will be marked as a [RunManifestEntry.daemon] and be signalled with
-  /// `SIGTERM`. If such processes *still* don't exit within [timeout] after
-  /// being signalled, they'll be marked as [RunManifestEntry.notResponding].
-  Future<Null> _waitForRunningProcessesToExit(Duration timeout) async {
-    await _waitForRunningProcessesToExitWithTimeout(
-        timeout: timeout,
-        onTimeout: (RunManifestEntry entry) {
-          entry.daemon = true;
-          delegate.killPid(entry.pid);
-        });
-    // Now that we explicitly signalled the processes that timed out asking
-    // them to shutdown, wait one more time for those processes to exit.
-    await _waitForRunningProcessesToExitWithTimeout(
-        timeout: timeout,
-        onTimeout: (RunManifestEntry entry) {
-          entry.notResponding = true;
-        });
-  }
-
-  Future<Null> _waitForRunningProcessesToExitWithTimeout({
-    Duration timeout,
-    void onTimeout(RunManifestEntry entry),
-  }) async {
-    void callOnTimeout(int pid) =>
-        onTimeout(_manifest.getRunEntry(pid) as RunManifestEntry);
-    await Future.wait(List<Future<int>>.from(_runningProcesses.values))
-        .timeout(timeout, onTimeout: () {
-      _runningProcesses.keys.forEach(callOnTimeout);
-      return null;
-    });
-  }
-
-  /// Writes our process invocation manifest to disk in the destination folder.
-  Future<Null> _writeManifestToDisk() async {
-    File manifestFile = fs.file('${destination.path}/$kManifestName');
-    await manifestFile.writeAsString(_manifest.toJson(), flush: true);
-  }
-}
-
-/// A [io.Process] implementation that records `stdout` and `stderr` stream events
-/// to disk before forwarding them on to the underlying stream listener.
-class _RecordingProcess implements io.Process {
-  _RecordingProcess({this.manager, this.basename, this.delegate});
-
-  final io.Process delegate;
-  final String basename;
-  final RecordingProcessManager manager;
-
-  // ignore: close_sinks
-  final StreamController<List<int>> _stdout = StreamController<List<int>>();
-  // ignore: close_sinks
-  final StreamController<List<int>> _stderr = StreamController<List<int>>();
-
-  bool _started = false;
-
-  Future<Null> startRecording() async {
-    assert(!_started);
-    _started = true;
-    await Future.wait(<Future<Null>>[
-      _recordStream(delegate.stdout, _stdout, 'stdout'),
-      _recordStream(delegate.stderr, _stderr, 'stderr'),
-    ]);
-  }
-
-  Future<Null> _recordStream(
-    Stream<List<int>> stream,
-    StreamController<List<int>> controller,
-    String suffix,
-  ) async {
-    String path = '${manager.destination.path}/$basename.$suffix';
-    File file = await manager.fs.file(path).create();
-    RandomAccessFile recording = await file.open(mode: FileMode.write);
-    stream.listen(
-      (List<int> data) {
-        // Write synchronously to guarantee that the order of data
-        // within our recording is preserved across stream notifications.
-        recording.writeFromSync(data);
-        // Flush immediately so that if the program crashes, forensic
-        // data from the recording won't be lost.
-        recording.flushSync();
-        controller.add(data);
-      },
-      onError: (dynamic error, StackTrace stackTrace) {
-        recording.closeSync();
-        controller.addError(error, stackTrace);
-      },
-      onDone: () {
-        recording.closeSync();
-        controller.close();
-      },
-    );
-  }
-
-  @override
-  Future<int> get exitCode => delegate.exitCode;
-
-  @override
-  Stream<List<int>> get stdout {
-    assert(_started);
-    return _stdout.stream;
-  }
-
-  @override
-  Stream<List<int>> get stderr {
-    assert(_started);
-    return _stderr.stream;
-  }
-
-  @override
-  io.IOSink get stdin {
-    // We don't currently support recording `stdin`.
-    return delegate.stdin;
-  }
-
-  @override
-  int get pid => delegate.pid;
-
-  @override
-  bool kill([io.ProcessSignal signal = io.ProcessSignal.sigterm]) =>
-      delegate.kill(signal);
-}
diff --git a/lib/src/record_replay/replay_process_manager.dart b/lib/src/record_replay/replay_process_manager.dart
deleted file mode 100644
index 53fdfeb..0000000
--- a/lib/src/record_replay/replay_process_manager.dart
+++ /dev/null
@@ -1,323 +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' as io
-    show
-        IOSink,
-        Process,
-        ProcessException,
-        ProcessResult,
-        ProcessSignal,
-        ProcessStartMode,
-        systemEncoding;
-
-import 'package:file/file.dart';
-import 'package:path/path.dart' as path;
-
-import '../interface/process_manager.dart';
-import 'can_run_manifest_entry.dart';
-import 'common.dart';
-import 'constants.dart';
-import 'manifest.dart';
-import 'run_manifest_entry.dart';
-import 'recording_process_manager.dart';
-
-/// Fakes all process invocations by replaying a previously-recorded series
-/// of invocations.
-///
-/// Recordings exist as opaque directories that are produced by
-/// [RecordingProcessManager].
-class ReplayProcessManager implements ProcessManager {
-  ReplayProcessManager._(this._manifest, this.location, this.streamDelay);
-
-  final Manifest _manifest;
-
-  /// The location of the serialized recording that's driving this manager.
-  final Directory location;
-
-  /// If non-null, processes spawned by this manager will delay their
-  /// `stdout` and `stderr` stream production by the this amount. See
-  /// description of the associated parameter in [create].
-  final Duration streamDelay;
-
-  /// Creates a new `ReplayProcessManager` capable of replaying a recording that
-  /// was serialized to the specified [location] by [RecordingProcessManager].
-  ///
-  /// If [location] does not exist, or if it does not represent a valid
-  /// recording (as determined by [RecordingProcessManager]), an [ArgumentError]
-  /// will be thrown.
-  ///
-  /// If [streamDelay] is specified, processes spawned by this manager will
-  /// delay their `stdout` and `stderr` stream production by the specified
-  /// amount. This is useful in cases where the real process invocation had
-  /// a necessary delay in stream production, and you need to mirror that
-  /// behavior. e.g. you spawn a `tail` process to tail a log file, then in a
-  /// follow-on event loop, you invoke a `startServer` process, which starts
-  /// producing log output. In this case, you may need to delay the `tail`
-  /// output to prevent its stream from flushing all its content before you
-  /// start listening.
-  static Future<ReplayProcessManager> create(
-    Directory location, {
-    Duration streamDelay = Duration.zero,
-  }) async {
-    assert(streamDelay != null);
-
-    if (!location.existsSync()) {
-      throw ArgumentError.value(location.path, 'location', "Doesn't exist");
-    }
-
-    FileSystem fs = location.fileSystem;
-    File manifestFile = fs.file(path.join(location.path, kManifestName));
-    if (!manifestFile.existsSync()) {
-      throw ArgumentError.value(
-          location, 'location', 'Does not represent a valid recording');
-    }
-
-    String content = await manifestFile.readAsString();
-    try {
-      // We don't validate the existence of all stdout and stderr files
-      // referenced in the manifest.
-      Manifest manifest = Manifest.fromJson(content);
-      return ReplayProcessManager._(manifest, location, streamDelay);
-    } on FormatException catch (e) {
-      throw ArgumentError('$kManifestName is not a valid JSON file: $e');
-    }
-  }
-
-  @override
-  Future<io.Process> start(
-    List<dynamic> command, {
-    String workingDirectory,
-    Map<String, String> environment,
-    bool includeParentEnvironment = true,
-    bool runInShell = false,
-    io.ProcessStartMode mode = io.ProcessStartMode.normal,
-  }) async {
-    RunManifestEntry entry = _popRunEntry(command, mode: mode);
-    _ReplayResult result = await _ReplayResult.create(this, entry);
-    return result.asProcess(entry.daemon);
-  }
-
-  @override
-  Future<io.ProcessResult> run(
-    List<dynamic> command, {
-    String workingDirectory,
-    Map<String, String> environment,
-    bool includeParentEnvironment = true,
-    bool runInShell = false,
-    Encoding stdoutEncoding = io.systemEncoding,
-    Encoding stderrEncoding = io.systemEncoding,
-  }) async {
-    RunManifestEntry entry = _popRunEntry(command,
-        stdoutEncoding: stdoutEncoding, stderrEncoding: stderrEncoding);
-    return await _ReplayResult.create(this, entry);
-  }
-
-  @override
-  io.ProcessResult runSync(
-    List<dynamic> command, {
-    String workingDirectory,
-    Map<String, String> environment,
-    bool includeParentEnvironment = true,
-    bool runInShell = false,
-    Encoding stdoutEncoding = io.systemEncoding,
-    Encoding stderrEncoding = io.systemEncoding,
-  }) {
-    RunManifestEntry entry = _popRunEntry(command,
-        stdoutEncoding: stdoutEncoding, stderrEncoding: stderrEncoding);
-    return _ReplayResult.createSync(this, entry);
-  }
-
-  /// Finds and returns the next entry in the process manifest that matches
-  /// the specified process arguments. Once found, it marks the manifest entry
-  /// as having been invoked and thus not eligible for invocation again.
-  RunManifestEntry _popRunEntry(
-    List<dynamic> command, {
-    io.ProcessStartMode mode,
-    Encoding stdoutEncoding,
-    Encoding stderrEncoding,
-  }) {
-    List<String> sanitizedCommand = sanitize(command);
-    RunManifestEntry entry = _manifest.findPendingRunEntry(
-      command: sanitizedCommand,
-      mode: mode,
-      stdoutEncoding: stdoutEncoding,
-      stderrEncoding: stderrEncoding,
-    ) as RunManifestEntry;
-
-    if (entry == null) {
-      throw io.ProcessException(sanitizedCommand.first,
-          sanitizedCommand.skip(1).toList(), 'No matching invocation found');
-    }
-
-    entry.setInvoked();
-    return entry;
-  }
-
-  @override
-  bool canRun(dynamic executable, {String workingDirectory}) {
-    CanRunManifestEntry entry = _manifest.findPendingCanRunEntry(
-      executable: executable.toString(),
-    ) as CanRunManifestEntry;
-    if (entry == null) {
-      throw ArgumentError('No matching invocation found for $executable');
-    }
-    entry.setInvoked();
-    return entry.result;
-  }
-
-  @override
-  bool killPid(int pid, [io.ProcessSignal signal = io.ProcessSignal.sigterm]) {
-    throw UnsupportedError(
-        "$runtimeType.killPid() has not been implemented because at the time "
-        "of its writing, it wasn't needed. If you're hitting this error, you "
-        "should implement it.");
-  }
-}
-
-/// A [io.ProcessResult] implementation that derives its data from a recording
-/// fragment.
-class _ReplayResult implements io.ProcessResult {
-  _ReplayResult._({
-    this.manager,
-    this.pid,
-    this.exitCode,
-    this.stdout,
-    this.stderr,
-  });
-
-  final ReplayProcessManager manager;
-
-  @override
-  final int pid;
-
-  @override
-  final int exitCode;
-
-  @override
-  final dynamic stdout;
-
-  @override
-  final dynamic stderr;
-
-  static Future<_ReplayResult> create(
-    ReplayProcessManager manager,
-    RunManifestEntry entry,
-  ) async {
-    FileSystem fs = manager.location.fileSystem;
-    String basePath = path.join(manager.location.path, entry.basename);
-    try {
-      return _ReplayResult._(
-        manager: manager,
-        pid: entry.pid,
-        exitCode: entry.exitCode,
-        stdout: await _getData(fs, '$basePath.stdout', entry.stdoutEncoding),
-        stderr: await _getData(fs, '$basePath.stderr', entry.stderrEncoding),
-      );
-    } catch (e) {
-      throw io.ProcessException(
-          entry.executable, entry.arguments, e.toString());
-    }
-  }
-
-  static Future<dynamic> _getData(
-      FileSystem fs, String path, Encoding encoding) async {
-    File file = fs.file(path);
-    return encoding == null
-        ? await file.readAsBytes()
-        : await file.readAsString(encoding: encoding);
-  }
-
-  static _ReplayResult createSync(
-    ReplayProcessManager manager,
-    RunManifestEntry entry,
-  ) {
-    FileSystem fs = manager.location.fileSystem;
-    String basePath = path.join(manager.location.path, entry.basename);
-    try {
-      return _ReplayResult._(
-        manager: manager,
-        pid: entry.pid,
-        exitCode: entry.exitCode,
-        stdout: _getDataSync(fs, '$basePath.stdout', entry.stdoutEncoding),
-        stderr: _getDataSync(fs, '$basePath.stderr', entry.stderrEncoding),
-      );
-    } catch (e) {
-      throw io.ProcessException(
-          entry.executable, entry.arguments, e.toString());
-    }
-  }
-
-  static dynamic _getDataSync(FileSystem fs, String path, Encoding encoding) {
-    File file = fs.file(path);
-    return encoding == null
-        ? file.readAsBytesSync()
-        : file.readAsStringSync(encoding: encoding);
-  }
-
-  io.Process asProcess(bool daemon) {
-    assert(stdout is List<int>);
-    assert(stderr is List<int>);
-    return _ReplayProcess(this, daemon);
-  }
-}
-
-/// A [io.Process] implementation derives its data from a recording fragment.
-class _ReplayProcess implements io.Process {
-  _ReplayProcess(_ReplayResult result, bool daemon)
-      : pid = result.pid,
-        _stdout = result.stdout as List<int>,
-        _stderr = result.stderr as List<int>,
-        _stdoutController = StreamController<List<int>>(),
-        _stderrController = StreamController<List<int>>(),
-        _exitCode = result.exitCode,
-        _exitCodeCompleter = Completer<int>() {
-    // Don't flush our stdio streams until we at least reach the outer event
-    // loop. i.e. even if `streamDelay` is zero, we still want to use the timer.
-    Timer(result.manager.streamDelay, () {
-      if (!_stdoutController.isClosed) {
-        _stdoutController.add(_stdout);
-      }
-      if (!_stderrController.isClosed) {
-        _stderrController.add(_stderr);
-      }
-      if (!daemon) kill();
-    });
-  }
-
-  @override
-  final int pid;
-
-  final List<int> _stdout;
-  final List<int> _stderr;
-  final StreamController<List<int>> _stdoutController;
-  final StreamController<List<int>> _stderrController;
-  final int _exitCode;
-  final Completer<int> _exitCodeCompleter;
-
-  @override
-  Stream<List<int>> get stdout => _stdoutController.stream;
-
-  @override
-  Stream<List<int>> get stderr => _stderrController.stream;
-
-  @override
-  Future<int> get exitCode => _exitCodeCompleter.future;
-
-  @override
-  io.IOSink get stdin => throw UnimplementedError();
-
-  @override
-  bool kill([io.ProcessSignal signal = io.ProcessSignal.sigterm]) {
-    if (!_exitCodeCompleter.isCompleted) {
-      _stdoutController.close();
-      _stderrController.close();
-      _exitCodeCompleter.complete(_exitCode);
-      return true;
-    }
-    return false;
-  }
-}
diff --git a/lib/src/record_replay/run_manifest_entry.dart b/lib/src/record_replay/run_manifest_entry.dart
deleted file mode 100644
index a3dfd35..0000000
--- a/lib/src/record_replay/run_manifest_entry.dart
+++ /dev/null
@@ -1,149 +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' show ProcessStartMode, systemEncoding;
-
-import 'manifest_entry.dart';
-
-/// Gets a `ProcessStartMode` value by its string name.
-ProcessStartMode _getProcessStartMode(String value) {
-  if (value != null) {
-    for (ProcessStartMode mode in ProcessStartMode.values) {
-      if (mode.toString() == value) {
-        return mode;
-      }
-    }
-    throw FormatException('Invalid value for mode: $value');
-  }
-  return null;
-}
-
-/// Gets an `Encoding` instance by the encoding name.
-Encoding _getEncoding(String encoding) {
-  if (encoding == 'system') {
-    return systemEncoding;
-  } else if (encoding != null) {
-    return Encoding.getByName(encoding);
-  }
-  return null;
-}
-
-/// An entry in the process invocation manifest for running an executable.
-class RunManifestEntry extends ManifestEntry {
-  /// Creates a new manifest entry with the given properties.
-  RunManifestEntry({
-    this.pid,
-    this.basename,
-    this.command,
-    this.workingDirectory,
-    this.environment,
-    this.includeParentEnvironment,
-    this.runInShell,
-    this.mode,
-    this.stdoutEncoding,
-    this.stderrEncoding,
-    this.exitCode,
-  });
-
-  /// Creates a new manifest entry populated with the specified JSON [data].
-  ///
-  /// If any required fields are missing from the JSON data, this will throw
-  /// a [FormatException].
-  factory RunManifestEntry.fromJson(Map<String, dynamic> data) {
-    checkRequiredField(data, 'pid');
-    checkRequiredField(data, 'basename');
-    checkRequiredField(data, 'command');
-    RunManifestEntry entry = RunManifestEntry(
-      pid: data['pid'] as int,
-      basename: data['basename'] as String,
-      command: (data['command'] as List<dynamic>)?.cast<String>(),
-      workingDirectory: data['workingDirectory'] as String,
-      environment: (data['environment'] as Map<dynamic, dynamic>)
-          ?.cast<String, String>(),
-      includeParentEnvironment: data['includeParentEnvironment'] as bool,
-      runInShell: data['runInShell'] as bool,
-      mode: _getProcessStartMode(data['mode'] as String),
-      stdoutEncoding: _getEncoding(data['stdoutEncoding'] as String),
-      stderrEncoding: _getEncoding(data['stderrEncoding'] as String),
-      exitCode: data['exitCode'] as int,
-    );
-    entry.daemon = data['daemon'] as bool;
-    entry.notResponding = data['notResponding'] as bool;
-    return entry;
-  }
-
-  @override
-  final String type = 'run';
-
-  /// The process id.
-  final int pid;
-
-  /// The base file name for this entry. `stdout` and `stderr` files for this
-  /// process will be serialized in the recording directory as
-  /// `$basename.stdout` and `$basename.stderr`, respectively.
-  final String basename;
-
-  /// The command that was run. The first element is the executable, and the
-  /// remaining elements are the arguments to the executable.
-  final List<String> command;
-
-  /// The process' working directory when it was spawned.
-  final String workingDirectory;
-
-  /// The environment variables that were passed to the process.
-  final Map<String, String> environment;
-
-  /// Whether the invoker's environment was made available to the process.
-  final bool includeParentEnvironment;
-
-  /// Whether the process was spawned through a system shell.
-  final bool runInShell;
-
-  /// The mode with which the process was spawned.
-  final ProcessStartMode mode;
-
-  /// The encoding used for the `stdout` of the process.
-  final Encoding stdoutEncoding;
-
-  /// The encoding used for the `stderr` of the process.
-  final Encoding stderrEncoding;
-
-  /// The exit code of the process.
-  int exitCode;
-
-  /// The executable that was invoked.
-  String get executable => command.first;
-
-  /// The arguments that were passed to [executable].
-  List<String> get arguments => command.skip(1).toList();
-
-  /// Indicates that the process is a daemon.
-  bool get daemon => _daemon;
-  bool _daemon = false;
-  set daemon(bool value) => _daemon = value ?? false;
-
-  /// Indicates that the process did not respond to `SIGTERM`.
-  bool get notResponding => _notResponding;
-  bool _notResponding = false;
-  set notResponding(bool value) => _notResponding = value ?? false;
-
-  /// Returns a JSON-encodable representation of this manifest entry.
-  @override
-  Map<String, dynamic> toJson() => JsonBuilder()
-      .add('pid', pid)
-      .add('basename', basename)
-      .add('command', command)
-      .add('workingDirectory', workingDirectory)
-      .add('environment', environment)
-      .add('includeParentEnvironment', includeParentEnvironment)
-      .add('runInShell', runInShell)
-      .add('mode', mode, () => mode.toString())
-      .add('stdoutEncoding', stdoutEncoding, () => stdoutEncoding.name)
-      .add('stderrEncoding', stderrEncoding, () => stderrEncoding.name)
-      .add('daemon', daemon)
-      .add('notResponding', notResponding)
-      .add('exitCode', exitCode)
-      .entry;
-}
diff --git a/pubspec.yaml b/pubspec.yaml
index b6a7362..b25b238 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -5,7 +5,6 @@
 
 dependencies:
   file: '^5.0.0'
-  meta: ^1.1.2
   path: ^1.5.1
   platform: '>=1.0.1'
 
@@ -13,4 +12,4 @@
   test: ^1.0.0
 
 environment:
-  sdk: '>=2.0.0 <3.0.0'
+  sdk: '>=2.9.0 <3.0.0'
diff --git a/test/record_test.dart b/test/record_test.dart
deleted file mode 100644
index 6f827df..0000000
--- a/test/record_test.dart
+++ /dev/null
@@ -1,174 +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' show Platform, Process, ProcessResult, systemEncoding;
-
-import 'package:file/file.dart';
-import 'package:file/local.dart';
-import 'package:path/path.dart' as p;
-import 'package:process/process.dart';
-import 'package:process/record_replay.dart';
-import 'package:test/test.dart';
-
-import 'utils.dart';
-
-void main() {
-  FileSystem fs = LocalFileSystem();
-  // TODO(goderbauer): refactor when github.com/google/platform.dart/issues/1
-  //     is available.
-  String newline = Platform.isWindows ? '\r\n' : '\n';
-
-  group('RecordingProcessManager', () {
-    Directory tmp;
-    RecordingProcessManager manager;
-
-    setUp(() {
-      tmp = fs.systemTempDirectory.createTempSync('process_tests_');
-      manager = RecordingProcessManager(LocalProcessManager(), tmp);
-    });
-
-    tearDown(() {
-      tmp.deleteSync(recursive: true);
-    });
-
-    test('start', () async {
-      Process process =
-          await manager.start(<String>['echo', 'foo'], runInShell: true);
-      int pid = process.pid;
-      int exitCode = await process.exitCode;
-      List<int> stdout = await consume(process.stdout);
-      List<int> stderr = await consume(process.stderr);
-      expect(exitCode, 0);
-      expect(decode(stdout), <String>['foo']);
-      expect(stderr, isEmpty);
-
-      // Force the recording to be written to disk.
-      await manager.flush(finishRunningProcesses: true);
-
-      _Recording recording = _Recording(tmp);
-      expect(recording.manifest, hasLength(1));
-      Map<String, dynamic> entry = recording.manifest.first;
-      expect(entry['type'], 'run');
-      Map<String, dynamic> body = entry['body'] as Map<String, dynamic>;
-      expect(body['pid'], pid);
-      expect(body['command'], <String>['echo', 'foo']);
-      expect(body['mode'], 'normal');
-      expect(body['exitCode'], exitCode);
-      expect(recording.stdoutForEntryAt(0), stdout);
-      expect(recording.stderrForEntryAt(0), stderr);
-    });
-
-    test('run', () async {
-      ProcessResult result =
-          await manager.run(<String>['echo', 'bar'], runInShell: true);
-      int pid = result.pid;
-      int exitCode = result.exitCode;
-      String stdout = result.stdout as String;
-      String stderr = result.stderr as String;
-      expect(exitCode, 0);
-      expect(stdout, 'bar$newline');
-      expect(stderr, isEmpty);
-
-      // Force the recording to be written to disk.
-      await manager.flush(finishRunningProcesses: true);
-
-      _Recording recording = _Recording(tmp);
-      expect(recording.manifest, hasLength(1));
-      Map<String, dynamic> entry = recording.manifest.first;
-      expect(entry['type'], 'run');
-      Map<String, dynamic> body = entry['body'] as Map<String, dynamic>;
-      expect(body['pid'], pid);
-      expect(body['command'], <String>['echo', 'bar']);
-      expect(body['stdoutEncoding'], 'system');
-      expect(body['stderrEncoding'], 'system');
-      expect(body['exitCode'], exitCode);
-      expect(recording.stdoutForEntryAt(0), stdout);
-      expect(recording.stderrForEntryAt(0), stderr);
-    });
-
-    test('runSync', () async {
-      ProcessResult result =
-          manager.runSync(<String>['echo', 'baz'], runInShell: true);
-      int pid = result.pid;
-      int exitCode = result.exitCode;
-      String stdout = result.stdout as String;
-      String stderr = result.stderr as String;
-      expect(exitCode, 0);
-      expect(stdout, 'baz$newline');
-      expect(stderr, isEmpty);
-
-      // Force the recording to be written to disk.
-      await manager.flush(finishRunningProcesses: true);
-
-      _Recording recording = _Recording(tmp);
-      expect(recording.manifest, hasLength(1));
-      Map<String, dynamic> entry = recording.manifest.first;
-      expect(entry['type'], 'run');
-      Map<String, dynamic> body = entry['body'] as Map<String, dynamic>;
-      expect(body['pid'], pid);
-      expect(body['command'], <String>['echo', 'baz']);
-      expect(body['stdoutEncoding'], 'system');
-      expect(body['stderrEncoding'], 'system');
-      expect(body['exitCode'], exitCode);
-      expect(recording.stdoutForEntryAt(0), stdout);
-      expect(recording.stderrForEntryAt(0), stderr);
-    });
-
-    test('canRun', () async {
-      String executable = p.join(tmp.path, 'bla.exe');
-      fs.file(executable).createSync();
-
-      bool result = manager.canRun(executable);
-
-      // Force the recording to be written to disk.
-      await manager.flush(finishRunningProcesses: true);
-
-      _Recording recording = _Recording(tmp);
-      expect(recording.manifest, hasLength(1));
-      Map<String, dynamic> entry = recording.manifest.first;
-      expect(entry['type'], 'can_run');
-      Map<String, dynamic> body = entry['body'] as Map<String, dynamic>;
-      expect(body['executable'], executable);
-      expect(body['result'], result);
-    });
-  });
-}
-
-/// A testing utility class that encapsulates a recording.
-class _Recording {
-  _Recording(this.dir);
-  final Directory dir;
-
-  List<Map<String, dynamic>> get manifest {
-    return (json.decoder
-                .convert(_getFileContent('MANIFEST.txt', utf8) as String)
-            as List<dynamic>)
-        .cast<Map<String, dynamic>>();
-  }
-
-  dynamic stdoutForEntryAt(int index) => _getStdioContent(
-      manifest[index]['body'] as Map<String, dynamic>, 'stdout');
-
-  dynamic stderrForEntryAt(int index) => _getStdioContent(
-      manifest[index]['body'] as Map<String, dynamic>, 'stderr');
-
-  dynamic _getFileContent(String name, Encoding encoding) {
-    File file = dir.fileSystem.file('${dir.path}/$name');
-    return encoding == null
-        ? file.readAsBytesSync()
-        : file.readAsStringSync(encoding: encoding);
-  }
-
-  dynamic _getStdioContent(Map<String, dynamic> entry, String type) {
-    String basename = entry['basename'] as String;
-    String encodingName = entry['${type}Encoding'] as String;
-    Encoding encoding;
-    if (encodingName != null)
-      encoding = encodingName == 'system'
-          ? systemEncoding
-          : Encoding.getByName(encodingName);
-    return _getFileContent('$basename.$type', encoding);
-  }
-}
diff --git a/test/replay_test.dart b/test/replay_test.dart
deleted file mode 100644
index 045f72d..0000000
--- a/test/replay_test.dart
+++ /dev/null
@@ -1,60 +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:io' show Process, ProcessResult;
-
-import 'package:file/file.dart';
-import 'package:file/local.dart';
-import 'package:process/process.dart';
-import 'package:process/record_replay.dart';
-import 'package:test/test.dart';
-
-import 'utils.dart';
-
-void main() {
-  FileSystem fs = LocalFileSystem();
-
-  group('ReplayProcessManager', () {
-    ProcessManager manager;
-
-    setUp(() async {
-      Directory dir = fs.directory('test/data/replay');
-      manager = await ReplayProcessManager.create(dir);
-    });
-
-    test('start', () async {
-      Process process = await manager.start(<String>['sing', 'ppap']);
-      int exitCode = await process.exitCode;
-      List<int> stdout = await consume(process.stdout);
-      List<int> stderr = await consume(process.stderr);
-      expect(process.pid, 100);
-      expect(exitCode, 0);
-      expect(decode(stdout), <String>['I have a pen', 'I have a pineapple']);
-      expect(decode(stderr), <String>['Uh, pineapple pen']);
-    });
-
-    test('run', () async {
-      ProcessResult result =
-          await manager.run(<String>['dance', 'gangnam-style']);
-      expect(result.pid, 101);
-      expect(result.exitCode, 2);
-      expect(result.stdout, '');
-      expect(result.stderr, 'No one can dance like Psy\n');
-    });
-
-    test('runSync', () {
-      ProcessResult result =
-          manager.runSync(<String>['dance', 'gangnam-style']);
-      expect(result.pid, 101);
-      expect(result.exitCode, 2);
-      expect(result.stdout, '');
-      expect(result.stderr, 'No one can dance like Psy\n');
-    });
-
-    test('canRun', () {
-      bool result = manager.canRun('marathon');
-      expect(result, true);
-    });
-  });
-}
