diff --git a/packages/flutter_migrate/analysis_options.yaml b/packages/flutter_migrate/analysis_options.yaml
new file mode 100644
index 0000000..9d4b822
--- /dev/null
+++ b/packages/flutter_migrate/analysis_options.yaml
@@ -0,0 +1,7 @@
+# Specify analysis options.
+
+include: ../../analysis_options.yaml
+
+linter:
+  rules:
+    public_member_api_docs: false # Standalone executable, no public API
diff --git a/packages/flutter_migrate/lib/src/base/command.dart b/packages/flutter_migrate/lib/src/base/command.dart
new file mode 100644
index 0000000..18604d7
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/command.dart
@@ -0,0 +1,74 @@
+// Copyright 2013 The Flutter 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 'package:args/command_runner.dart';
+
+enum ExitStatus {
+  success,
+  warning,
+  fail,
+  killed,
+}
+
+class CommandResult {
+  const CommandResult(this.exitStatus);
+
+  /// A command that succeeded. It is used to log the result of a command invocation.
+  factory CommandResult.success() {
+    return const CommandResult(ExitStatus.success);
+  }
+
+  /// A command that exited with a warning. It is used to log the result of a command invocation.
+  factory CommandResult.warning() {
+    return const CommandResult(ExitStatus.warning);
+  }
+
+  /// A command that failed. It is used to log the result of a command invocation.
+  factory CommandResult.fail() {
+    return const CommandResult(ExitStatus.fail);
+  }
+
+  final ExitStatus exitStatus;
+
+  @override
+  String toString() {
+    switch (exitStatus) {
+      case ExitStatus.success:
+        return 'success';
+      case ExitStatus.warning:
+        return 'warning';
+      case ExitStatus.fail:
+        return 'fail';
+      case ExitStatus.killed:
+        return 'killed';
+    }
+  }
+}
+
+abstract class MigrateCommand extends Command<void> {
+  @override
+  Future<void> run() async {
+    await runCommand();
+  }
+
+  Future<CommandResult> runCommand();
+
+  /// Gets the parsed command-line option named [name] as a `bool?`.
+  bool? boolArg(String name) {
+    if (!argParser.options.containsKey(name)) {
+      return null;
+    }
+    return argResults == null ? null : argResults![name] as bool;
+  }
+
+  String? stringArg(String name) {
+    if (!argParser.options.containsKey(name)) {
+      return null;
+    }
+    return argResults == null ? null : argResults![name] as String?;
+  }
+
+  /// Gets the parsed command-line option named [name] as an `int`.
+  int? intArg(String name) => argResults?[name] as int?;
+}
diff --git a/packages/flutter_migrate/lib/src/base/common.dart b/packages/flutter_migrate/lib/src/base/common.dart
new file mode 100644
index 0000000..70804f5
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/common.dart
@@ -0,0 +1,287 @@
+// Copyright 2013 The Flutter 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';
+
+import 'file_system.dart';
+
+/// Throw a specialized exception for expected situations
+/// where the tool should exit with a clear message to the user
+/// and no stack trace unless the --verbose option is specified.
+/// For example: network errors.
+Never throwToolExit(String? message, {int? exitCode}) {
+  throw ToolExit(message, exitCode: exitCode);
+}
+
+/// Specialized exception for expected situations
+/// where the tool should exit with a clear message to the user
+/// and no stack trace unless the --verbose option is specified.
+/// For example: network errors.
+class ToolExit implements Exception {
+  ToolExit(this.message, {this.exitCode});
+
+  final String? message;
+  final int? exitCode;
+
+  @override
+  String toString() => 'Error: $message';
+}
+
+/// Return the name of an enum item.
+String getEnumName(dynamic enumItem) {
+  final String name = '$enumItem';
+  final int index = name.indexOf('.');
+  return index == -1 ? name : name.substring(index + 1);
+}
+
+/// Runs [fn] with special handling of asynchronous errors.
+///
+/// If the execution of [fn] does not throw a synchronous exception, and if the
+/// [Future] returned by [fn] is completed with a value, then the [Future]
+/// returned by [asyncGuard] is completed with that value if it has not already
+/// been completed with an error.
+///
+/// If the execution of [fn] throws a synchronous exception, and no [onError]
+/// callback is provided, then the [Future] returned by [asyncGuard] is
+/// completed with an error whose object and stack trace are given by the
+/// synchronous exception. If an [onError] callback is provided, then the
+/// [Future] returned by [asyncGuard] is completed with its result when passed
+/// the error object and stack trace.
+///
+/// If the execution of [fn] results in an asynchronous exception that would
+/// otherwise be unhandled, and no [onError] callback is provided, then the
+/// [Future] returned by [asyncGuard] is completed with an error whose object
+/// and stack trace are given by the asynchronous exception. If an [onError]
+/// callback is provided, then the [Future] returned by [asyncGuard] is
+/// completed with its result when passed the error object and stack trace.
+///
+/// After the returned [Future] is completed, whether it be with a value or an
+/// error, all further errors resulting from the execution of [fn] are ignored.
+///
+/// Rationale:
+///
+/// Consider the following snippet:
+/// ```
+/// try {
+///   await foo();
+///   ...
+/// } catch (e) {
+///   ...
+/// }
+/// ```
+/// If the [Future] returned by `foo` is completed with an error, that error is
+/// handled by the catch block. However, if `foo` spawns an asynchronous
+/// operation whose errors are unhandled, those errors will not be caught by
+/// the catch block, and will instead propagate to the containing [Zone]. This
+/// behavior is non-intuitive to programmers expecting the `catch` to catch all
+/// the errors resulting from the code under the `try`.
+///
+/// As such, it would be convenient if the `try {} catch {}` here could handle
+/// not only errors completing the awaited [Future]s it contains, but also
+/// any otherwise unhandled asynchronous errors occurring as a result of awaited
+/// expressions. This is how `await` is often assumed to work, which leads to
+/// unexpected unhandled exceptions.
+///
+/// [asyncGuard] is intended to wrap awaited expressions occurring in a `try`
+/// block. The behavior described above gives the behavior that users
+/// intuitively expect from `await`. Consider the snippet:
+/// ```
+/// try {
+///   await asyncGuard(() async {
+///     var c = Completer();
+///     c.completeError('Error');
+///   });
+/// } catch (e) {
+///   // e is 'Error';
+/// }
+/// ```
+/// Without the [asyncGuard] the error 'Error' would be propagated to the
+/// error handler of the containing [Zone]. With the [asyncGuard], the error
+/// 'Error' is instead caught by the `catch`.
+///
+/// [asyncGuard] also accepts an [onError] callback for situations in which
+/// completing the returned [Future] with an error is not appropriate.
+/// For example, it is not always possible to immediately await the returned
+/// [Future]. In these cases, an [onError] callback is needed to prevent an
+/// error from propagating to the containing [Zone].
+///
+/// [onError] must have type `FutureOr<T> Function(Object error)` or
+/// `FutureOr<T> Function(Object error, StackTrace stackTrace)` otherwise an
+/// [ArgumentError] will be thrown synchronously.
+Future<T> asyncGuard<T>(
+  Future<T> Function() fn, {
+  Function? onError,
+}) {
+  if (onError != null &&
+      onError is! _UnaryOnError<T> &&
+      onError is! _BinaryOnError<T>) {
+    throw ArgumentError('onError must be a unary function accepting an Object, '
+        'or a binary function accepting an Object and '
+        'StackTrace. onError must return a T');
+  }
+  final Completer<T> completer = Completer<T>();
+
+  void handleError(Object e, StackTrace s) {
+    if (completer.isCompleted) {
+      return;
+    }
+    if (onError == null) {
+      completer.completeError(e, s);
+      return;
+    }
+    if (onError is _BinaryOnError<T>) {
+      completer.complete(onError(e, s));
+    } else if (onError is _UnaryOnError<T>) {
+      completer.complete(onError(e));
+    }
+  }
+
+  runZoned<void>(() async {
+    try {
+      final T result = await fn();
+      if (!completer.isCompleted) {
+        completer.complete(result);
+      }
+      // This catches all exceptions so that they can be propagated to the
+      // caller-supplied error handling or the completer.
+    } catch (e, s) {
+      // ignore: avoid_catches_without_on_clauses, forwards to Future
+      handleError(e, s);
+    }
+    // ignore: deprecated_member_use
+  }, onError: (Object e, StackTrace s) {
+    handleError(e, s);
+  });
+
+  return completer.future;
+}
+
+typedef _UnaryOnError<T> = FutureOr<T> Function(Object error);
+typedef _BinaryOnError<T> = FutureOr<T> Function(
+    Object error, StackTrace stackTrace);
+
+/// Whether the test is running in a web browser compiled to JavaScript.
+///
+/// See also:
+///
+///  * [kIsWeb], the equivalent constant in the `foundation` library.
+const bool isBrowser = identical(0, 0.0);
+
+/// Whether the test is running on the Windows operating system.
+///
+/// This does not include tests compiled to JavaScript running in a browser on
+/// the Windows operating system.
+///
+/// See also:
+///
+///  * [isBrowser], which reports true for tests running in browsers.
+bool get isWindows {
+  if (isBrowser) {
+    return false;
+  }
+  return Platform.isWindows;
+}
+
+/// Whether the test is running on the macOS operating system.
+///
+/// This does not include tests compiled to JavaScript running in a browser on
+/// the macOS operating system.
+///
+/// See also:
+///
+///  * [isBrowser], which reports true for tests running in browsers.
+bool get isMacOS {
+  if (isBrowser) {
+    return false;
+  }
+  return Platform.isMacOS;
+}
+
+/// Whether the test is running on the Linux operating system.
+///
+/// This does not include tests compiled to JavaScript running in a browser on
+/// the Linux operating system.
+///
+/// See also:
+///
+///  * [isBrowser], which reports true for tests running in browsers.
+bool get isLinux {
+  if (isBrowser) {
+    return false;
+  }
+  return Platform.isLinux;
+}
+
+String? flutterRoot;
+
+/// Determine the absolute and normalized path for the root of the current
+/// Flutter checkout.
+///
+/// This method has a series of fallbacks for determining the repo location. The
+/// first success will immediately return the root without further checks.
+///
+/// The order of these tests is:
+///   1. FLUTTER_ROOT environment variable contains the path.
+///   2. Platform script is a data URI scheme, returning `../..` to support
+///      tests run from `packages/flutter_tools`.
+///   3. Platform script is package URI scheme, returning the grandparent directory
+///      of the package config file location from `packages/flutter_tools/.packages`.
+///   4. Platform script file path is the snapshot path generated by `bin/flutter`,
+///      returning the grandparent directory from `bin/cache`.
+///   5. Platform script file name is the entrypoint in `packages/flutter_tools/bin/flutter_tools.dart`,
+///      returning the 4th parent directory.
+///   6. The current directory
+///
+/// If an exception is thrown during any of these checks, an error message is
+/// printed and `.` is returned by default (6).
+String defaultFlutterRoot({
+  required FileSystem fileSystem,
+}) {
+  const String kFlutterRootEnvironmentVariableName =
+      'FLUTTER_ROOT'; // should point to //flutter/ (root of flutter/flutter repo)
+  const String kSnapshotFileName =
+      'flutter_tools.snapshot'; // in //flutter/bin/cache/
+  const String kFlutterToolsScriptFileName =
+      'flutter_tools.dart'; // in //flutter/packages/flutter_tools/bin/
+  String normalize(String path) {
+    return fileSystem.path.normalize(fileSystem.path.absolute(path));
+  }
+
+  if (Platform.environment.containsKey(kFlutterRootEnvironmentVariableName)) {
+    return normalize(
+        Platform.environment[kFlutterRootEnvironmentVariableName]!);
+  }
+  try {
+    if (Platform.script.scheme == 'data') {
+      return normalize('../..'); // The tool is running as a test.
+    }
+    final String Function(String) dirname = fileSystem.path.dirname;
+
+    if (Platform.script.scheme == 'package') {
+      final String packageConfigPath =
+          Uri.parse(Platform.packageConfig!).toFilePath(
+        windows: isWindows,
+      );
+      return normalize(dirname(dirname(dirname(packageConfigPath))));
+    }
+
+    if (Platform.script.scheme == 'file') {
+      final String script = Platform.script.toFilePath(
+        windows: isWindows,
+      );
+      if (fileSystem.path.basename(script) == kSnapshotFileName) {
+        return normalize(dirname(dirname(fileSystem.path.dirname(script))));
+      }
+      if (fileSystem.path.basename(script) == kFlutterToolsScriptFileName) {
+        return normalize(dirname(dirname(dirname(dirname(script)))));
+      }
+    }
+  } on Exception catch (error) {
+    // There is currently no logger attached since this is computed at startup.
+    // ignore: avoid_print
+    print('$error');
+  }
+  return normalize('.');
+}
diff --git a/packages/flutter_migrate/lib/src/base/context.dart b/packages/flutter_migrate/lib/src/base/context.dart
new file mode 100644
index 0000000..ea1dd4d
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/context.dart
@@ -0,0 +1,199 @@
+// Copyright 2013 The Flutter 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:collection';
+
+import 'package:meta/meta.dart';
+
+/// Generates an [AppContext] value.
+///
+/// Generators are allowed to return `null`, in which case the context will
+/// store the `null` value as the value for that type.
+typedef Generator = dynamic Function();
+
+/// An exception thrown by [AppContext] when you try to get a [Type] value from
+/// the context, and the instantiation of the value results in a dependency
+/// cycle.
+class ContextDependencyCycleException implements Exception {
+  ContextDependencyCycleException._(this.cycle);
+
+  /// The dependency cycle (last item depends on first item).
+  final List<Type> cycle;
+
+  @override
+  String toString() => 'Dependency cycle detected: ${cycle.join(' -> ')}';
+}
+
+/// The Zone key used to look up the [AppContext].
+@visibleForTesting
+const Object contextKey = _Key.key;
+
+/// The current [AppContext], as determined by the [Zone] hierarchy.
+///
+/// This will be the first context found as we scan up the zone hierarchy, or
+/// the "root" context if a context cannot be found in the hierarchy. The root
+/// context will not have any values associated with it.
+///
+/// This is guaranteed to never return `null`.
+AppContext get context =>
+    Zone.current[contextKey] as AppContext? ?? AppContext._root;
+
+/// A lookup table (mapping types to values) and an implied scope, in which
+/// code is run.
+///
+/// [AppContext] is used to define a singleton injection context for code that
+/// is run within it. Each time you call [run], a child context (and a new
+/// scope) is created.
+///
+/// Child contexts are created and run using zones. To read more about how
+/// zones work, see https://api.dart.dev/stable/dart-async/Zone-class.html.
+class AppContext {
+  AppContext._(
+    this._parent,
+    this.name, [
+    this._overrides = const <Type, Generator>{},
+    this._fallbacks = const <Type, Generator>{},
+  ]);
+
+  final String? name;
+  final AppContext? _parent;
+  final Map<Type, Generator> _overrides;
+  final Map<Type, Generator> _fallbacks;
+  final Map<Type, dynamic> _values = <Type, dynamic>{};
+
+  List<Type>? _reentrantChecks;
+
+  /// Bootstrap context.
+  static final AppContext _root = AppContext._(null, 'ROOT');
+
+  dynamic _boxNull(dynamic value) => value ?? _BoxedNull.instance;
+
+  dynamic _unboxNull(dynamic value) =>
+      value == _BoxedNull.instance ? null : value;
+
+  /// Returns the generated value for [type] if such a generator exists.
+  ///
+  /// If [generators] does not contain a mapping for the specified [type], this
+  /// returns `null`.
+  ///
+  /// If a generator existed and generated a `null` value, this will return a
+  /// boxed value indicating null.
+  ///
+  /// If a value for [type] has already been generated by this context, the
+  /// existing value will be returned, and the generator will not be invoked.
+  ///
+  /// If the generator ends up triggering a reentrant call, it signals a
+  /// dependency cycle, and a [ContextDependencyCycleException] will be thrown.
+  dynamic _generateIfNecessary(Type type, Map<Type, Generator> generators) {
+    if (!generators.containsKey(type)) {
+      return null;
+    }
+
+    return _values.putIfAbsent(type, () {
+      _reentrantChecks ??= <Type>[];
+
+      final int index = _reentrantChecks!.indexOf(type);
+      if (index >= 0) {
+        // We're already in the process of trying to generate this type.
+        throw ContextDependencyCycleException._(
+            UnmodifiableListView<Type>(_reentrantChecks!.sublist(index)));
+      }
+
+      _reentrantChecks!.add(type);
+      try {
+        return _boxNull(generators[type]!());
+      } finally {
+        _reentrantChecks!.removeLast();
+        if (_reentrantChecks!.isEmpty) {
+          _reentrantChecks = null;
+        }
+      }
+    });
+  }
+
+  /// Gets the value associated with the specified [type], or `null` if no
+  /// such value has been associated.
+  T? get<T>() {
+    dynamic value = _generateIfNecessary(T, _overrides);
+    if (value == null && _parent != null) {
+      value = _parent!.get<T>();
+    }
+    return _unboxNull(value ?? _generateIfNecessary(T, _fallbacks)) as T?;
+  }
+
+  /// Runs [body] in a child context and returns the value returned by [body].
+  ///
+  /// If [overrides] is specified, the child context will return corresponding
+  /// values when consulted via [operator[]].
+  ///
+  /// If [fallbacks] is specified, the child context will return corresponding
+  /// values when consulted via [operator[]] only if its parent context didn't
+  /// return such a value.
+  ///
+  /// If [name] is specified, the child context will be assigned the given
+  /// name. This is useful for debugging purposes and is analogous to naming a
+  /// thread in Java.
+  Future<V> run<V>({
+    required FutureOr<V> Function() body,
+    String? name,
+    Map<Type, Generator>? overrides,
+    Map<Type, Generator>? fallbacks,
+    ZoneSpecification? zoneSpecification,
+  }) async {
+    final AppContext child = AppContext._(
+      this,
+      name,
+      Map<Type, Generator>.unmodifiable(overrides ?? const <Type, Generator>{}),
+      Map<Type, Generator>.unmodifiable(fallbacks ?? const <Type, Generator>{}),
+    );
+    return runZoned<Future<V>>(
+      () async => await body(),
+      zoneValues: <_Key, AppContext>{_Key.key: child},
+      zoneSpecification: zoneSpecification,
+    );
+  }
+
+  @override
+  String toString() {
+    final StringBuffer buf = StringBuffer();
+    String indent = '';
+    AppContext? ctx = this;
+    while (ctx != null) {
+      buf.write('AppContext');
+      if (ctx.name != null) {
+        buf.write('[${ctx.name}]');
+      }
+      if (ctx._overrides.isNotEmpty) {
+        buf.write('\n$indent  overrides: [${ctx._overrides.keys.join(', ')}]');
+      }
+      if (ctx._fallbacks.isNotEmpty) {
+        buf.write('\n$indent  fallbacks: [${ctx._fallbacks.keys.join(', ')}]');
+      }
+      if (ctx._parent != null) {
+        buf.write('\n$indent  parent: ');
+      }
+      ctx = ctx._parent;
+      indent += '  ';
+    }
+    return buf.toString();
+  }
+}
+
+/// Private key used to store the [AppContext] in the [Zone].
+class _Key {
+  const _Key();
+
+  static const _Key key = _Key();
+
+  @override
+  String toString() => 'context';
+}
+
+/// Private object that denotes a generated `null` value.
+class _BoxedNull {
+  const _BoxedNull();
+
+  static const _BoxedNull instance = _BoxedNull();
+}
diff --git a/packages/flutter_migrate/lib/src/base/file_system.dart b/packages/flutter_migrate/lib/src/base/file_system.dart
new file mode 100644
index 0000000..ee5eaf8
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/file_system.dart
@@ -0,0 +1,178 @@
+// Copyright 2013 The Flutter 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:file/file.dart';
+import 'package:file/local.dart' as local_fs;
+import 'package:meta/meta.dart';
+
+import 'common.dart';
+import 'io.dart';
+import 'logger.dart';
+import 'signals.dart';
+
+// package:file/local.dart must not be exported. This exposes LocalFileSystem,
+// which we override to ensure that temporary directories are cleaned up when
+// the tool is killed by a signal.
+export 'package:file/file.dart';
+
+/// Exception indicating that a file that was expected to exist was not found.
+class FileNotFoundException implements IOException {
+  const FileNotFoundException(this.path);
+
+  final String path;
+
+  @override
+  String toString() => 'File not found: $path';
+}
+
+/// Return a relative path if [fullPath] is contained by the cwd, else return an
+/// absolute path.
+String getDisplayPath(String fullPath, FileSystem fileSystem) {
+  final String cwd =
+      fileSystem.currentDirectory.path + fileSystem.path.separator;
+  return fullPath.startsWith(cwd) ? fullPath.substring(cwd.length) : fullPath;
+}
+
+/// This class extends [local_fs.LocalFileSystem] in order to clean up
+/// directories and files that the tool creates under the system temporary
+/// directory when the tool exits either normally or when killed by a signal.
+class LocalFileSystem extends local_fs.LocalFileSystem {
+  LocalFileSystem(this._signals, this._fatalSignals, this.shutdownHooks);
+
+  @visibleForTesting
+  LocalFileSystem.test({
+    required Signals signals,
+    List<ProcessSignal> fatalSignals = Signals.defaultExitSignals,
+  }) : this(signals, fatalSignals, ShutdownHooks());
+
+  Directory? _systemTemp;
+  final Map<ProcessSignal, Object> _signalTokens = <ProcessSignal, Object>{};
+
+  final ShutdownHooks shutdownHooks;
+
+  Future<void> dispose() async {
+    _tryToDeleteTemp();
+    for (final MapEntry<ProcessSignal, Object> signalToken
+        in _signalTokens.entries) {
+      await _signals.removeHandler(signalToken.key, signalToken.value);
+    }
+    _signalTokens.clear();
+  }
+
+  final Signals _signals;
+  final List<ProcessSignal> _fatalSignals;
+
+  void _tryToDeleteTemp() {
+    try {
+      if (_systemTemp?.existsSync() ?? false) {
+        _systemTemp?.deleteSync(recursive: true);
+      }
+    } on FileSystemException {
+      // ignore
+    }
+    _systemTemp = null;
+  }
+
+  // This getter returns a fresh entry under /tmp, like
+  // /tmp/flutter_tools.abcxyz, then the rest of the tool creates /tmp entries
+  // under that, like /tmp/flutter_tools.abcxyz/flutter_build_stuff.123456.
+  // Right before exiting because of a signal or otherwise, we delete
+  // /tmp/flutter_tools.abcxyz, not the whole of /tmp.
+  @override
+  Directory get systemTempDirectory {
+    if (_systemTemp == null) {
+      if (!superSystemTempDirectory.existsSync()) {
+        throwToolExit(
+            'Your system temp directory (${superSystemTempDirectory.path}) does not exist. '
+            'Did you set an invalid override in your environment? See issue https://github.com/flutter/flutter/issues/74042 for more context.');
+      }
+      _systemTemp = superSystemTempDirectory.createTempSync('flutter_tools.')
+        ..createSync(recursive: true);
+      // Make sure that the temporary directory is cleaned up if the tool is
+      // killed by a signal.
+      for (final ProcessSignal signal in _fatalSignals) {
+        final Object token = _signals.addHandler(
+          signal,
+          (ProcessSignal _) {
+            _tryToDeleteTemp();
+          },
+        );
+        _signalTokens[signal] = token;
+      }
+      // Make sure that the temporary directory is cleaned up when the tool
+      // exits normally.
+      shutdownHooks.addShutdownHook(
+        _tryToDeleteTemp,
+      );
+    }
+    return _systemTemp!;
+  }
+
+  // This only exist because the memory file system does not support a systemTemp that does not exists #74042
+  @visibleForTesting
+  Directory get superSystemTempDirectory => super.systemTempDirectory;
+}
+
+/// A function that will be run before the VM exits.
+typedef ShutdownHook = FutureOr<void> Function();
+
+abstract class ShutdownHooks {
+  factory ShutdownHooks() => _DefaultShutdownHooks();
+
+  /// Registers a [ShutdownHook] to be executed before the VM exits.
+  void addShutdownHook(ShutdownHook shutdownHook);
+
+  @visibleForTesting
+  List<ShutdownHook> get registeredHooks;
+
+  /// Runs all registered shutdown hooks and returns a future that completes when
+  /// all such hooks have finished.
+  ///
+  /// Shutdown hooks will be run in groups by their [ShutdownStage]. All shutdown
+  /// hooks within a given stage will be started in parallel and will be
+  /// guaranteed to run to completion before shutdown hooks in the next stage are
+  /// started.
+  ///
+  /// This class is constructed before the [Logger], so it cannot be direct
+  /// injected in the constructor.
+  Future<void> runShutdownHooks(Logger logger);
+}
+
+class _DefaultShutdownHooks implements ShutdownHooks {
+  _DefaultShutdownHooks();
+
+  @override
+  final List<ShutdownHook> registeredHooks = <ShutdownHook>[];
+
+  bool _shutdownHooksRunning = false;
+
+  @override
+  void addShutdownHook(ShutdownHook shutdownHook) {
+    assert(!_shutdownHooksRunning);
+    registeredHooks.add(shutdownHook);
+  }
+
+  @override
+  Future<void> runShutdownHooks(Logger logger) async {
+    logger.printTrace(
+      'Running ${registeredHooks.length} shutdown hook${registeredHooks.length == 1 ? '' : 's'}',
+    );
+    _shutdownHooksRunning = true;
+    try {
+      final List<Future<dynamic>> futures = <Future<dynamic>>[];
+      for (final ShutdownHook shutdownHook in registeredHooks) {
+        final FutureOr<dynamic> result = shutdownHook();
+        if (result is Future<dynamic>) {
+          futures.add(result);
+        }
+      }
+      await Future.wait<dynamic>(futures);
+    } finally {
+      _shutdownHooksRunning = false;
+    }
+    logger.printTrace('Shutdown hooks complete');
+  }
+}
diff --git a/packages/flutter_migrate/lib/src/base/io.dart b/packages/flutter_migrate/lib/src/base/io.dart
new file mode 100644
index 0000000..8ae2813
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/io.dart
@@ -0,0 +1,340 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/// This file serves as the single point of entry into the `dart:io` APIs
+/// within Flutter tools.
+///
+/// In order to make Flutter tools more testable, we use the `FileSystem` APIs
+/// in `package:file` rather than using the `dart:io` file APIs directly (see
+/// `file_system.dart`). Doing so allows us to swap out local file system
+/// access with mockable (or in-memory) file systems, making our tests hermetic
+/// vis-a-vis file system access.
+///
+/// We also use `package:platform` to provide an abstraction away from the
+/// static methods in the `dart:io` `Platform` class (see `platform.dart`). As
+/// such, do not export Platform from this file!
+///
+/// To ensure that all file system and platform API access within Flutter tools
+/// goes through the proper APIs, we forbid direct imports of `dart:io` (via a
+/// test), forcing all callers to instead import this file, which exports the
+/// blessed subset of `dart:io` that is legal to use in Flutter tools.
+///
+/// Because of the nature of this file, it is important that **platform and file
+/// APIs not be exported from `dart:io` in this file**! Moreover, be careful
+/// about any additional exports that you add to this file, as doing so will
+/// increase the API surface that we have to test in Flutter tools, and the APIs
+/// in `dart:io` can sometimes be hard to use in tests.
+
+// We allow `print()` in this file as a fallback for writing to the terminal via
+// regular stdout/stderr/stdio paths. Everything else in the flutter_tools
+// library should route terminal I/O through the [Stdio] class defined below.
+// ignore_for_file: avoid_print
+
+import 'dart:async';
+import 'dart:io' as io
+    show
+        IOSink,
+        Process,
+        ProcessSignal,
+        Stdin,
+        StdinException,
+        Stdout,
+        StdoutException,
+        stderr,
+        stdin,
+        stdout;
+
+import 'package:meta/meta.dart';
+
+import 'common.dart';
+
+export 'dart:io'
+    show
+        BytesBuilder,
+        CompressionOptions,
+        // Directory,         NO! Use `file_system.dart`
+        // File,              NO! Use `file_system.dart`
+        // FileSystemEntity,  NO! Use `file_system.dart`
+        GZipCodec,
+        HandshakeException,
+        HttpClient,
+        HttpClientRequest,
+        HttpClientResponse,
+        HttpClientResponseCompressionState,
+        HttpException,
+        HttpHeaders,
+        HttpRequest,
+        HttpResponse,
+        HttpServer,
+        HttpStatus,
+        IOException,
+        IOSink,
+        InternetAddress,
+        InternetAddressType,
+        // Link              NO! Use `file_system.dart`
+        // NetworkInterface  NO! Use `io.dart`
+        OSError,
+        Platform,
+        Process,
+        ProcessException,
+        // ProcessInfo,      NO! use `io.dart`
+        ProcessResult,
+        // ProcessSignal     NO! Use [ProcessSignal] below.
+        ProcessStartMode,
+        // RandomAccessFile  NO! Use `file_system.dart`
+        ServerSocket,
+        SignalException,
+        Socket,
+        SocketException,
+        Stdin,
+        StdinException,
+        Stdout,
+        WebSocket,
+        WebSocketException,
+        WebSocketTransformer,
+        ZLibEncoder,
+        exitCode,
+        gzip,
+        pid,
+        // stderr,           NO! Use `io.dart`
+        // stdin,            NO! Use `io.dart`
+        // stdout,           NO! Use `io.dart`
+        systemEncoding;
+
+/// A class that wraps stdout, stderr, and stdin, and exposes the allowed
+/// operations.
+///
+/// In particular, there are three ways that writing to stdout and stderr
+/// can fail. A call to stdout.write() can fail:
+///   * by throwing a regular synchronous exception,
+///   * by throwing an exception asynchronously, and
+///   * by completing the Future stdout.done with an error.
+///
+/// This class enapsulates all three so that we don't have to worry about it
+/// anywhere else.
+class Stdio {
+  Stdio();
+
+  /// Tests can provide overrides to use instead of the stdout and stderr from
+  /// dart:io.
+  @visibleForTesting
+  Stdio.test({
+    required io.Stdout stdout,
+    required io.IOSink stderr,
+  })  : _stdoutOverride = stdout,
+        _stderrOverride = stderr;
+
+  io.Stdout? _stdoutOverride;
+  io.IOSink? _stderrOverride;
+
+  // These flags exist to remember when the done Futures on stdout and stderr
+  // complete to avoid trying to write to a closed stream sink, which would
+  // generate a [StateError].
+  bool _stdoutDone = false;
+  bool _stderrDone = false;
+
+  Stream<List<int>> get stdin => io.stdin;
+
+  io.Stdout get stdout {
+    if (_stdout != null) {
+      return _stdout!;
+    }
+    _stdout = _stdoutOverride ?? io.stdout;
+    _stdout!.done.then(
+      (void _) {
+        _stdoutDone = true;
+      },
+      onError: (Object err, StackTrace st) {
+        _stdoutDone = true;
+      },
+    );
+    return _stdout!;
+  }
+
+  io.Stdout? _stdout;
+
+  @visibleForTesting
+  io.IOSink get stderr {
+    if (_stderr != null) {
+      return _stderr!;
+    }
+    _stderr = _stderrOverride ?? io.stderr;
+    _stderr!.done.then(
+      (void _) {
+        _stderrDone = true;
+      },
+      onError: (Object err, StackTrace st) {
+        _stderrDone = true;
+      },
+    );
+    return _stderr!;
+  }
+
+  io.IOSink? _stderr;
+
+  bool get hasTerminal => io.stdout.hasTerminal;
+
+  static bool? _stdinHasTerminal;
+
+  /// Determines whether there is a terminal attached.
+  ///
+  /// [io.Stdin.hasTerminal] only covers a subset of cases. In this check the
+  /// echoMode is toggled on and off to catch cases where the tool running in
+  /// a docker container thinks there is an attached terminal. This can cause
+  /// runtime errors such as "inappropriate ioctl for device" if not handled.
+  bool get stdinHasTerminal {
+    if (_stdinHasTerminal != null) {
+      return _stdinHasTerminal!;
+    }
+    if (stdin is! io.Stdin) {
+      return _stdinHasTerminal = false;
+    }
+    final io.Stdin ioStdin = stdin as io.Stdin;
+    if (!ioStdin.hasTerminal) {
+      return _stdinHasTerminal = false;
+    }
+    try {
+      final bool currentEchoMode = ioStdin.echoMode;
+      ioStdin.echoMode = !currentEchoMode;
+      ioStdin.echoMode = currentEchoMode;
+    } on io.StdinException {
+      return _stdinHasTerminal = false;
+    }
+    return _stdinHasTerminal = true;
+  }
+
+  int? get terminalColumns => hasTerminal ? stdout.terminalColumns : null;
+  int? get terminalLines => hasTerminal ? stdout.terminalLines : null;
+  bool get supportsAnsiEscapes => hasTerminal && stdout.supportsAnsiEscapes;
+
+  /// Writes [message] to [stderr], falling back on [fallback] if the write
+  /// throws any exception. The default fallback calls [print] on [message].
+  void stderrWrite(
+    String message, {
+    void Function(String, dynamic, StackTrace)? fallback,
+  }) {
+    if (!_stderrDone) {
+      _stdioWrite(stderr, message, fallback: fallback);
+      return;
+    }
+    fallback == null
+        ? print(message)
+        : fallback(
+            message,
+            const io.StdoutException('stderr is done'),
+            StackTrace.current,
+          );
+  }
+
+  /// Writes [message] to [stdout], falling back on [fallback] if the write
+  /// throws any exception. The default fallback calls [print] on [message].
+  void stdoutWrite(
+    String message, {
+    void Function(String, dynamic, StackTrace)? fallback,
+  }) {
+    if (!_stdoutDone) {
+      _stdioWrite(stdout, message, fallback: fallback);
+      return;
+    }
+    fallback == null
+        ? print(message)
+        : fallback(
+            message,
+            const io.StdoutException('stdout is done'),
+            StackTrace.current,
+          );
+  }
+
+  // Helper for [stderrWrite] and [stdoutWrite].
+  void _stdioWrite(
+    io.IOSink sink,
+    String message, {
+    void Function(String, dynamic, StackTrace)? fallback,
+  }) {
+    asyncGuard<void>(() async {
+      sink.write(message);
+    }, onError: (Object error, StackTrace stackTrace) {
+      if (fallback == null) {
+        print(message);
+      } else {
+        fallback(message, error, stackTrace);
+      }
+    });
+  }
+
+  /// Adds [stream] to [stdout].
+  Future<void> addStdoutStream(Stream<List<int>> stream) =>
+      stdout.addStream(stream);
+
+  /// Adds [stream] to [stderr].
+  Future<void> addStderrStream(Stream<List<int>> stream) =>
+      stderr.addStream(stream);
+}
+
+/// A portable version of [io.ProcessSignal].
+///
+/// Listening on signals that don't exist on the current platform is just a
+/// no-op. This is in contrast to [io.ProcessSignal], where listening to
+/// non-existent signals throws an exception.
+///
+/// This class does NOT implement io.ProcessSignal, because that class uses
+/// private fields. This means it cannot be used with, e.g., [Process.killPid].
+/// Alternative implementations of the relevant methods that take
+/// [ProcessSignal] instances are available on this class (e.g. "send").
+class ProcessSignal {
+  @visibleForTesting
+  const ProcessSignal(this._delegate);
+
+  static const ProcessSignal sigwinch =
+      PosixProcessSignal(io.ProcessSignal.sigwinch);
+  static const ProcessSignal sigterm =
+      PosixProcessSignal(io.ProcessSignal.sigterm);
+  static const ProcessSignal sigusr1 =
+      PosixProcessSignal(io.ProcessSignal.sigusr1);
+  static const ProcessSignal sigusr2 =
+      PosixProcessSignal(io.ProcessSignal.sigusr2);
+  static const ProcessSignal sigint = ProcessSignal(io.ProcessSignal.sigint);
+  static const ProcessSignal sigkill = ProcessSignal(io.ProcessSignal.sigkill);
+
+  final io.ProcessSignal _delegate;
+
+  Stream<ProcessSignal> watch() {
+    return _delegate
+        .watch()
+        .map<ProcessSignal>((io.ProcessSignal signal) => this);
+  }
+
+  /// Sends the signal to the given process (identified by pid).
+  ///
+  /// Returns true if the signal was delivered, false otherwise.
+  ///
+  /// On Windows, this can only be used with [ProcessSignal.sigterm], which
+  /// terminates the process.
+  ///
+  /// This is implemented by sending the signal using [Process.killPid].
+  bool send(int pid) {
+    assert(!isWindows || this == ProcessSignal.sigterm);
+    return io.Process.killPid(pid, _delegate);
+  }
+
+  @override
+  String toString() => _delegate.toString();
+}
+
+/// A [ProcessSignal] that is only available on Posix platforms.
+///
+/// Listening to a [_PosixProcessSignal] is a no-op on Windows.
+@visibleForTesting
+class PosixProcessSignal extends ProcessSignal {
+  const PosixProcessSignal(super.wrappedSignal);
+
+  @override
+  Stream<ProcessSignal> watch() {
+    // This uses the real platform since it invokes dart:io functionality directly.
+    if (isWindows) {
+      return const Stream<ProcessSignal>.empty();
+    }
+    return super.watch();
+  }
+}
diff --git a/packages/flutter_migrate/lib/src/base/logger.dart b/packages/flutter_migrate/lib/src/base/logger.dart
new file mode 100644
index 0000000..c84f098
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/logger.dart
@@ -0,0 +1,1395 @@
+// Copyright 2013 The Flutter 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';
+import 'dart:math' as math;
+import 'dart:math';
+
+import 'package:intl/intl.dart';
+import 'package:meta/meta.dart';
+
+import 'common.dart';
+import 'io.dart';
+import 'terminal.dart' show OutputPreferences, Terminal, TerminalColor;
+
+const int kDefaultStatusPadding = 59;
+final NumberFormat kSecondsFormat = NumberFormat('0.0');
+final NumberFormat kMillisecondsFormat = NumberFormat.decimalPattern();
+
+/// Smallest column that will be used for text wrapping. If the requested column
+/// width is smaller than this, then this is what will be used.
+const int kMinColumnWidth = 10;
+
+/// A factory for generating [Stopwatch] instances for [Status] instances.
+class StopwatchFactory {
+  /// const constructor so that subclasses may be const.
+  const StopwatchFactory();
+
+  /// Create a new [Stopwatch] instance.
+  ///
+  /// The optional [name] parameter is useful in tests when there are multiple
+  /// instances being created.
+  Stopwatch createStopwatch([String name = '']) => Stopwatch();
+}
+
+typedef VoidCallback = void Function();
+
+abstract class Logger {
+  /// Whether or not this logger should print [printTrace] messages.
+  bool get isVerbose => false;
+
+  /// If true, silences the logger output.
+  bool quiet = false;
+
+  /// If true, this logger supports color output.
+  bool get supportsColor;
+
+  /// If true, this logger is connected to a terminal.
+  bool get hasTerminal;
+
+  /// If true, then [printError] has been called at least once for this logger
+  /// since the last time it was set to false.
+  bool hadErrorOutput = false;
+
+  /// If true, then [printWarning] has been called at least once for this logger
+  /// since the last time it was reset to false.
+  bool hadWarningOutput = false;
+
+  /// Causes [checkForFatalLogs] to call [throwToolExit] when it is called if
+  /// [hadWarningOutput] is true.
+  bool fatalWarnings = false;
+
+  /// Returns the terminal attached to this logger.
+  Terminal get terminal;
+
+  /// Display an error `message` to the user. Commands should use this if they
+  /// fail in some way. Errors are typically followed shortly by a call to
+  /// [throwToolExit] to terminate the run.
+  ///
+  /// The `message` argument is printed to the stderr in [TerminalColor.red] by
+  /// default.
+  ///
+  /// The `stackTrace` argument is the stack trace that will be printed if
+  /// supplied.
+  ///
+  /// The `emphasis` argument will cause the output message be printed in bold text.
+  ///
+  /// The `color` argument will print the message in the supplied color instead
+  /// of the default of red. Colors will not be printed if the output terminal
+  /// doesn't support them.
+  ///
+  /// The `indent` argument specifies the number of spaces to indent the overall
+  /// message. If wrapping is enabled in [outputPreferences], then the wrapped
+  /// lines will be indented as well.
+  ///
+  /// If `hangingIndent` is specified, then any wrapped lines will be indented
+  /// by this much more than the first line, if wrapping is enabled in
+  /// [outputPreferences].
+  ///
+  /// If `wrap` is specified, then it overrides the
+  /// `outputPreferences.wrapText` setting.
+  void printError(
+    String message, {
+    StackTrace? stackTrace,
+    bool? emphasis,
+    TerminalColor? color,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  });
+
+  /// Display a warning `message` to the user. Commands should use this if they
+  /// important information to convey to the user that is not fatal.
+  ///
+  /// The `message` argument is printed to the stderr in [TerminalColor.cyan] by
+  /// default.
+  ///
+  /// The `emphasis` argument will cause the output message be printed in bold text.
+  ///
+  /// The `color` argument will print the message in the supplied color instead
+  /// of the default of cyan. Colors will not be printed if the output terminal
+  /// doesn't support them.
+  ///
+  /// The `indent` argument specifies the number of spaces to indent the overall
+  /// message. If wrapping is enabled in [outputPreferences], then the wrapped
+  /// lines will be indented as well.
+  ///
+  /// If `hangingIndent` is specified, then any wrapped lines will be indented
+  /// by this much more than the first line, if wrapping is enabled in
+  /// [outputPreferences].
+  ///
+  /// If `wrap` is specified, then it overrides the
+  /// `outputPreferences.wrapText` setting.
+  void printWarning(
+    String message, {
+    bool? emphasis,
+    TerminalColor? color,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  });
+
+  /// Display normal output of the command. This should be used for things like
+  /// progress messages, success messages, or just normal command output.
+  ///
+  /// The `message` argument is printed to the stdout.
+  ///
+  /// The `stackTrace` argument is the stack trace that will be printed if
+  /// supplied.
+  ///
+  /// If the `emphasis` argument is true, it will cause the output message be
+  /// printed in bold text. Defaults to false.
+  ///
+  /// The `color` argument will print the message in the supplied color instead
+  /// of the default of red. Colors will not be printed if the output terminal
+  /// doesn't support them.
+  ///
+  /// If `newline` is true, then a newline will be added after printing the
+  /// status. Defaults to true.
+  ///
+  /// The `indent` argument specifies the number of spaces to indent the overall
+  /// message. If wrapping is enabled in [outputPreferences], then the wrapped
+  /// lines will be indented as well.
+  ///
+  /// If `hangingIndent` is specified, then any wrapped lines will be indented
+  /// by this much more than the first line, if wrapping is enabled in
+  /// [outputPreferences].
+  ///
+  /// If `wrap` is specified, then it overrides the
+  /// `outputPreferences.wrapText` setting.
+  void printStatus(
+    String message, {
+    bool? emphasis,
+    TerminalColor? color,
+    bool? newline,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  });
+
+  /// Display the [message] inside a box.
+  ///
+  /// For example, this is the generated output:
+  ///
+  ///   ┌─ [title] ─┐
+  ///   │ [message] │
+  ///   └───────────┘
+  ///
+  /// If a terminal is attached, the lines in [message] are automatically wrapped based on
+  /// the available columns.
+  ///
+  /// Use this utility only to highlight a message in the logs.
+  ///
+  /// This is particularly useful when the message can be easily missed because of clutter
+  /// generated by other commands invoked by the tool.
+  ///
+  /// One common use case is to provide actionable steps in a Flutter app when a Gradle
+  /// error is printed.
+  ///
+  /// In the future, this output can be integrated with an IDE like VS Code to display a
+  /// notification, and allow the user to trigger an action. e.g. run a migration.
+  void printBox(
+    String message, {
+    String? title,
+  });
+
+  /// Use this for verbose tracing output. Users can turn this output on in order
+  /// to help diagnose issues with the toolchain or with their setup.
+  void printTrace(String message);
+
+  /// Start an indeterminate progress display.
+  ///
+  /// The `message` argument is the message to display to the user.
+  ///
+  /// The `progressId` argument provides an ID that can be used to identify
+  /// this type of progress (e.g. `hot.reload`, `hot.restart`).
+  ///
+  /// The `progressIndicatorPadding` can optionally be used to specify the width
+  /// of the space into which the `message` is placed before the progress
+  /// indicator, if any. It is ignored if the message is longer.
+  Status startProgress(
+    String message, {
+    String? progressId,
+    int progressIndicatorPadding = kDefaultStatusPadding,
+  });
+
+  /// A [SilentStatus] or an [AnonymousSpinnerStatus] (depending on whether the
+  /// terminal is fancy enough), already started.
+  Status startSpinner({
+    VoidCallback? onFinish,
+    Duration? timeout,
+    SlowWarningCallback? slowWarningCallback,
+  });
+
+  /// Clears all output.
+  void clear();
+
+  /// If [fatalWarnings] is set, causes the logger to check if
+  /// [hadWarningOutput] is true, and then to call [throwToolExit] if so.
+  ///
+  /// The [fatalWarnings] flag can be set from the command line with the
+  /// "--fatal-warnings" option on commands that support it.
+  void checkForFatalLogs() {
+    if (fatalWarnings && (hadWarningOutput || hadErrorOutput)) {
+      throwToolExit(
+          'Logger received ${hadErrorOutput ? 'error' : 'warning'} output '
+          'during the run, and "--fatal-warnings" is enabled.');
+    }
+  }
+}
+
+class StdoutLogger extends Logger {
+  StdoutLogger({
+    required this.terminal,
+    required Stdio stdio,
+    required OutputPreferences outputPreferences,
+    StopwatchFactory stopwatchFactory = const StopwatchFactory(),
+  })  : _stdio = stdio,
+        _outputPreferences = outputPreferences,
+        _stopwatchFactory = stopwatchFactory;
+
+  @override
+  final Terminal terminal;
+  final OutputPreferences _outputPreferences;
+  final Stdio _stdio;
+  final StopwatchFactory _stopwatchFactory;
+
+  Status? _status;
+
+  @override
+  bool get isVerbose => false;
+
+  @override
+  bool get supportsColor => terminal.supportsColor;
+
+  @override
+  bool get hasTerminal => _stdio.stdinHasTerminal;
+
+  @override
+  void printError(
+    String message, {
+    StackTrace? stackTrace,
+    bool? emphasis,
+    TerminalColor? color,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  }) {
+    hadErrorOutput = true;
+    _status?.pause();
+    message = wrapText(
+      message,
+      indent: indent,
+      hangingIndent: hangingIndent,
+      shouldWrap: wrap ?? _outputPreferences.wrapText,
+      columnWidth: _outputPreferences.wrapColumn,
+    );
+    if (emphasis ?? false) {
+      message = terminal.bolden(message);
+    }
+    message = terminal.color(message, color ?? TerminalColor.red);
+    writeToStdErr('$message\n');
+    if (stackTrace != null) {
+      writeToStdErr('$stackTrace\n');
+    }
+    _status?.resume();
+  }
+
+  @override
+  void printWarning(
+    String message, {
+    bool? emphasis,
+    TerminalColor? color,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  }) {
+    hadWarningOutput = true;
+    _status?.pause();
+    message = wrapText(
+      message,
+      indent: indent,
+      hangingIndent: hangingIndent,
+      shouldWrap: wrap ?? _outputPreferences.wrapText,
+      columnWidth: _outputPreferences.wrapColumn,
+    );
+    if (emphasis ?? false) {
+      message = terminal.bolden(message);
+    }
+    message = terminal.color(message, color ?? TerminalColor.cyan);
+    writeToStdErr('$message\n');
+    _status?.resume();
+  }
+
+  @override
+  void printStatus(
+    String message, {
+    bool? emphasis,
+    TerminalColor? color,
+    bool? newline,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  }) {
+    _status?.pause();
+    message = wrapText(
+      message,
+      indent: indent,
+      hangingIndent: hangingIndent,
+      shouldWrap: wrap ?? _outputPreferences.wrapText,
+      columnWidth: _outputPreferences.wrapColumn,
+    );
+    if (emphasis ?? false) {
+      message = terminal.bolden(message);
+    }
+    if (color != null) {
+      message = terminal.color(message, color);
+    }
+    if (newline ?? true) {
+      message = '$message\n';
+    }
+    writeToStdOut(message);
+    _status?.resume();
+  }
+
+  @override
+  void printBox(
+    String message, {
+    String? title,
+  }) {
+    _status?.pause();
+    _generateBox(
+      title: title,
+      message: message,
+      wrapColumn: _outputPreferences.wrapColumn,
+      terminal: terminal,
+      write: writeToStdOut,
+    );
+    _status?.resume();
+  }
+
+  @protected
+  void writeToStdOut(String message) => _stdio.stdoutWrite(message);
+
+  @protected
+  void writeToStdErr(String message) => _stdio.stderrWrite(message);
+
+  @override
+  void printTrace(String message) {}
+
+  @override
+  Status startProgress(
+    String message, {
+    String? progressId,
+    int progressIndicatorPadding = kDefaultStatusPadding,
+  }) {
+    if (_status != null) {
+      // Ignore nested progresses; return a no-op status object.
+      return SilentStatus(
+        stopwatch: _stopwatchFactory.createStopwatch(),
+      )..start();
+    }
+    if (supportsColor) {
+      _status = SpinnerStatus(
+        message: message,
+        padding: progressIndicatorPadding,
+        onFinish: _clearStatus,
+        stdio: _stdio,
+        stopwatch: _stopwatchFactory.createStopwatch(),
+        terminal: terminal,
+      )..start();
+    } else {
+      _status = SummaryStatus(
+        message: message,
+        padding: progressIndicatorPadding,
+        onFinish: _clearStatus,
+        stdio: _stdio,
+        stopwatch: _stopwatchFactory.createStopwatch(),
+      )..start();
+    }
+    return _status!;
+  }
+
+  @override
+  Status startSpinner({
+    VoidCallback? onFinish,
+    Duration? timeout,
+    SlowWarningCallback? slowWarningCallback,
+  }) {
+    if (_status != null || !supportsColor) {
+      return SilentStatus(
+        onFinish: onFinish,
+        stopwatch: _stopwatchFactory.createStopwatch(),
+      )..start();
+    }
+    _status = AnonymousSpinnerStatus(
+      onFinish: () {
+        if (onFinish != null) {
+          onFinish();
+        }
+        _clearStatus();
+      },
+      stdio: _stdio,
+      stopwatch: _stopwatchFactory.createStopwatch(),
+      terminal: terminal,
+      timeout: timeout,
+      slowWarningCallback: slowWarningCallback,
+    )..start();
+    return _status!;
+  }
+
+  void _clearStatus() {
+    _status = null;
+  }
+
+  @override
+  void clear() {
+    _status?.pause();
+    writeToStdOut('${terminal.clearScreen()}\n');
+    _status?.resume();
+  }
+}
+
+/// A [StdoutLogger] which replaces Unicode characters that cannot be printed to
+/// the Windows console with alternative symbols.
+///
+/// By default, Windows uses either "Consolas" or "Lucida Console" as fonts to
+/// render text in the console. Both fonts only have a limited character set.
+/// Unicode characters, that are not available in either of the two default
+/// fonts, should be replaced by this class with printable symbols. Otherwise,
+/// they will show up as the unrepresentable character symbol '�'.
+class WindowsStdoutLogger extends StdoutLogger {
+  WindowsStdoutLogger({
+    required super.terminal,
+    required super.stdio,
+    required super.outputPreferences,
+    super.stopwatchFactory,
+  });
+
+  @override
+  void writeToStdOut(String message) {
+    final String windowsMessage = terminal.supportsEmoji
+        ? message
+        : message
+            .replaceAll('🔥', '')
+            .replaceAll('🖼️', '')
+            .replaceAll('✗', 'X')
+            .replaceAll('✓', '√')
+            .replaceAll('🔨', '')
+            .replaceAll('💪', '')
+            .replaceAll('⚠️', '!')
+            .replaceAll('✏️', '');
+    _stdio.stdoutWrite(windowsMessage);
+  }
+}
+
+typedef _Writter = void Function(String message);
+
+/// Wraps the message in a box, and writes the bytes by calling [write].
+///
+///  Example output:
+///
+///   ┌─ [title] ─┐
+///   │ [message] │
+///   └───────────┘
+///
+/// When [title] is provided, the box will have a title above it.
+///
+/// The box width never exceeds [wrapColumn].
+///
+/// If [wrapColumn] is not provided, the default value is 100.
+void _generateBox({
+  required String message,
+  required int wrapColumn,
+  required _Writter write,
+  required Terminal terminal,
+  String? title,
+}) {
+  const int kPaddingLeftRight = 1;
+  const int kEdges = 2;
+
+  final int maxTextWidthPerLine = wrapColumn - kEdges - kPaddingLeftRight * 2;
+  final List<String> lines =
+      wrapText(message, shouldWrap: true, columnWidth: maxTextWidthPerLine)
+          .split('\n');
+  final List<int> lineWidth =
+      lines.map((String line) => _getColumnSize(line)).toList();
+  final int maxColumnSize =
+      lineWidth.reduce((int currLen, int maxLen) => max(currLen, maxLen));
+  final int textWidth = min(maxColumnSize, maxTextWidthPerLine);
+  final int textWithPaddingWidth = textWidth + kPaddingLeftRight * 2;
+
+  write('\n');
+
+  // Write `┌─ [title] ─┐`.
+  write('┌');
+  write('─');
+  if (title == null) {
+    write('─' * (textWithPaddingWidth - 1));
+  } else {
+    write(' ${terminal.bolden(title)} ');
+    write('─' * (textWithPaddingWidth - title.length - 3));
+  }
+  write('┐');
+  write('\n');
+
+  // Write `│ [message] │`.
+  for (int lineIdx = 0; lineIdx < lines.length; lineIdx++) {
+    write('│');
+    write(' ' * kPaddingLeftRight);
+    write(lines[lineIdx]);
+    final int remainingSpacesToEnd = textWidth - lineWidth[lineIdx];
+    write(' ' * (remainingSpacesToEnd + kPaddingLeftRight));
+    write('│');
+    write('\n');
+  }
+
+  // Write `└───────────┘`.
+  write('└');
+  write('─' * textWithPaddingWidth);
+  write('┘');
+  write('\n');
+}
+
+final RegExp _ansiEscapePattern =
+    RegExp('\x1B\\[[\x30-\x3F]*[\x20-\x2F]*[\x40-\x7E]');
+
+int _getColumnSize(String line) {
+  // Remove ANSI escape characters from the string.
+  return line.replaceAll(_ansiEscapePattern, '').length;
+}
+
+class BufferLogger extends Logger {
+  BufferLogger({
+    required this.terminal,
+    required OutputPreferences outputPreferences,
+    StopwatchFactory stopwatchFactory = const StopwatchFactory(),
+    bool verbose = false,
+  })  : _outputPreferences = outputPreferences,
+        _stopwatchFactory = stopwatchFactory,
+        _verbose = verbose;
+
+  /// Create a [BufferLogger] with test preferences.
+  BufferLogger.test({
+    Terminal? terminal,
+    OutputPreferences? outputPreferences,
+    bool verbose = false,
+  })  : terminal = terminal ?? Terminal.test(),
+        _outputPreferences = outputPreferences ?? OutputPreferences.test(),
+        _stopwatchFactory = const StopwatchFactory(),
+        _verbose = verbose;
+
+  final OutputPreferences _outputPreferences;
+
+  @override
+  final Terminal terminal;
+
+  final StopwatchFactory _stopwatchFactory;
+
+  final bool _verbose;
+
+  @override
+  bool get isVerbose => _verbose;
+
+  @override
+  bool get supportsColor => terminal.supportsColor;
+
+  final StringBuffer _error = StringBuffer();
+  final StringBuffer _warning = StringBuffer();
+  final StringBuffer _status = StringBuffer();
+  final StringBuffer _trace = StringBuffer();
+  final StringBuffer _events = StringBuffer();
+
+  String get errorText => _error.toString();
+  String get warningText => _warning.toString();
+  String get statusText => _status.toString();
+  String get traceText => _trace.toString();
+  String get eventText => _events.toString();
+
+  @override
+  bool get hasTerminal => false;
+
+  @override
+  void printError(
+    String message, {
+    StackTrace? stackTrace,
+    bool? emphasis,
+    TerminalColor? color,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  }) {
+    hadErrorOutput = true;
+    _error.writeln(terminal.color(
+      wrapText(
+        message,
+        indent: indent,
+        hangingIndent: hangingIndent,
+        shouldWrap: wrap ?? _outputPreferences.wrapText,
+        columnWidth: _outputPreferences.wrapColumn,
+      ),
+      color ?? TerminalColor.red,
+    ));
+  }
+
+  @override
+  void printWarning(
+    String message, {
+    bool? emphasis,
+    TerminalColor? color,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  }) {
+    hadWarningOutput = true;
+    _warning.writeln(terminal.color(
+      wrapText(
+        message,
+        indent: indent,
+        hangingIndent: hangingIndent,
+        shouldWrap: wrap ?? _outputPreferences.wrapText,
+        columnWidth: _outputPreferences.wrapColumn,
+      ),
+      color ?? TerminalColor.cyan,
+    ));
+  }
+
+  @override
+  void printStatus(
+    String message, {
+    bool? emphasis,
+    TerminalColor? color,
+    bool? newline,
+    int? indent,
+    int? hangingIndent,
+    bool? wrap,
+  }) {
+    if (newline ?? true) {
+      _status.writeln(wrapText(
+        message,
+        indent: indent,
+        hangingIndent: hangingIndent,
+        shouldWrap: wrap ?? _outputPreferences.wrapText,
+        columnWidth: _outputPreferences.wrapColumn,
+      ));
+    } else {
+      _status.write(wrapText(
+        message,
+        indent: indent,
+        hangingIndent: hangingIndent,
+        shouldWrap: wrap ?? _outputPreferences.wrapText,
+        columnWidth: _outputPreferences.wrapColumn,
+      ));
+    }
+  }
+
+  @override
+  void printBox(
+    String message, {
+    String? title,
+  }) {
+    _generateBox(
+      title: title,
+      message: message,
+      wrapColumn: _outputPreferences.wrapColumn,
+      terminal: terminal,
+      write: _status.write,
+    );
+  }
+
+  @override
+  void printTrace(String message) => _trace.writeln(message);
+
+  @override
+  Status startProgress(
+    String message, {
+    String? progressId,
+    int progressIndicatorPadding = kDefaultStatusPadding,
+  }) {
+    assert(progressIndicatorPadding != null);
+    printStatus(message);
+    return SilentStatus(
+      stopwatch: _stopwatchFactory.createStopwatch(),
+    )..start();
+  }
+
+  @override
+  Status startSpinner({
+    VoidCallback? onFinish,
+    Duration? timeout,
+    SlowWarningCallback? slowWarningCallback,
+  }) {
+    return SilentStatus(
+      stopwatch: _stopwatchFactory.createStopwatch(),
+      onFinish: onFinish,
+    )..start();
+  }
+
+  @override
+  void clear() {
+    _error.clear();
+    _status.clear();
+    _trace.clear();
+    _events.clear();
+  }
+}
+
+typedef SlowWarningCallback = String Function();
+
+/// A [Status] class begins when start is called, and may produce progress
+/// information asynchronously.
+///
+/// The [SilentStatus] class never has any output.
+///
+/// The [SpinnerStatus] subclass shows a message with a spinner, and replaces it
+/// with timing information when stopped. When canceled, the information isn't
+/// shown. In either case, a newline is printed.
+///
+/// The [AnonymousSpinnerStatus] subclass just shows a spinner.
+///
+/// The [SummaryStatus] subclass shows only a static message (without an
+/// indicator), then updates it when the operation ends.
+///
+/// Generally, consider `logger.startProgress` instead of directly creating
+/// a [Status] or one of its subclasses.
+abstract class Status {
+  Status({
+    this.onFinish,
+    required Stopwatch stopwatch,
+    this.timeout,
+  }) : _stopwatch = stopwatch;
+
+  final VoidCallback? onFinish;
+  final Duration? timeout;
+
+  @protected
+  final Stopwatch _stopwatch;
+
+  @protected
+  String get elapsedTime {
+    if (_stopwatch.elapsed.inSeconds > 2) {
+      return _getElapsedAsSeconds(_stopwatch.elapsed);
+    }
+    return _getElapsedAsMilliseconds(_stopwatch.elapsed);
+  }
+
+  String _getElapsedAsSeconds(Duration duration) {
+    final double seconds =
+        duration.inMilliseconds / Duration.millisecondsPerSecond;
+    return '${kSecondsFormat.format(seconds)}s';
+  }
+
+  String _getElapsedAsMilliseconds(Duration duration) {
+    return '${kMillisecondsFormat.format(duration.inMilliseconds)}ms';
+  }
+
+  @visibleForTesting
+  bool get seemsSlow => timeout != null && _stopwatch.elapsed > timeout!;
+
+  /// Call to start spinning.
+  void start() {
+    assert(!_stopwatch.isRunning);
+    _stopwatch.start();
+  }
+
+  /// Call to stop spinning after success.
+  void stop() {
+    finish();
+  }
+
+  /// Call to cancel the spinner after failure or cancellation.
+  void cancel() {
+    finish();
+  }
+
+  /// Call to clear the current line but not end the progress.
+  void pause() {}
+
+  /// Call to resume after a pause.
+  void resume() {}
+
+  @protected
+  void finish() {
+    assert(_stopwatch.isRunning);
+    _stopwatch.stop();
+    onFinish?.call();
+  }
+}
+
+/// A [Status] that shows nothing.
+class SilentStatus extends Status {
+  SilentStatus({
+    required super.stopwatch,
+    super.onFinish,
+  });
+
+  @override
+  void finish() {
+    onFinish?.call();
+  }
+}
+
+/// Constructor writes [message] to [stdout]. On [cancel] or [stop], will call
+/// [onFinish]. On [stop], will additionally print out summary information.
+class SummaryStatus extends Status {
+  SummaryStatus({
+    this.message = '',
+    required super.stopwatch,
+    this.padding = kDefaultStatusPadding,
+    super.onFinish,
+    required Stdio stdio,
+  }) : _stdio = stdio;
+
+  final String message;
+  final int padding;
+  final Stdio _stdio;
+
+  bool _messageShowingOnCurrentLine = false;
+
+  @override
+  void start() {
+    _printMessage();
+    super.start();
+  }
+
+  void _writeToStdOut(String message) => _stdio.stdoutWrite(message);
+
+  void _printMessage() {
+    assert(!_messageShowingOnCurrentLine);
+    _writeToStdOut('${message.padRight(padding)}     ');
+    _messageShowingOnCurrentLine = true;
+  }
+
+  @override
+  void stop() {
+    if (!_messageShowingOnCurrentLine) {
+      _printMessage();
+    }
+    super.stop();
+    assert(_messageShowingOnCurrentLine);
+    _writeToStdOut(elapsedTime.padLeft(_kTimePadding));
+    _writeToStdOut('\n');
+  }
+
+  @override
+  void cancel() {
+    super.cancel();
+    if (_messageShowingOnCurrentLine) {
+      _writeToStdOut('\n');
+    }
+  }
+
+  @override
+  void pause() {
+    super.pause();
+    if (_messageShowingOnCurrentLine) {
+      _writeToStdOut('\n');
+      _messageShowingOnCurrentLine = false;
+    }
+  }
+}
+
+const int _kTimePadding = 8; // should fit "99,999ms"
+
+/// A kind of animated [Status] that has no message.
+///
+/// Call [pause] before outputting any text while this is running.
+class AnonymousSpinnerStatus extends Status {
+  AnonymousSpinnerStatus({
+    super.onFinish,
+    required super.stopwatch,
+    required Stdio stdio,
+    required Terminal terminal,
+    this.slowWarningCallback,
+    super.timeout,
+  })  : _stdio = stdio,
+        _terminal = terminal,
+        _animation = _selectAnimation(terminal);
+
+  final Stdio _stdio;
+  final Terminal _terminal;
+  String _slowWarning = '';
+  final SlowWarningCallback? slowWarningCallback;
+
+  static const String _backspaceChar = '\b';
+  static const String _clearChar = ' ';
+
+  static const List<String> _emojiAnimations = <String>[
+    '⣾⣽⣻⢿⡿⣟⣯⣷', // counter-clockwise
+    '⣾⣷⣯⣟⡿⢿⣻⣽', // clockwise
+    '⣾⣷⣯⣟⡿⢿⣻⣽⣷⣾⣽⣻⢿⡿⣟⣯⣷', // bouncing clockwise and counter-clockwise
+    '⣾⣷⣯⣽⣻⣟⡿⢿⣻⣟⣯⣽', // snaking
+    '⣾⣽⣻⢿⣿⣷⣯⣟⡿⣿', // alternating rain
+    '⣀⣠⣤⣦⣶⣾⣿⡿⠿⠻⠛⠋⠉⠙⠛⠟⠿⢿⣿⣷⣶⣴⣤⣄', // crawl up and down, large
+    '⠙⠚⠖⠦⢤⣠⣄⡤⠴⠲⠓⠋', // crawl up and down, small
+    '⣀⡠⠤⠔⠒⠊⠉⠑⠒⠢⠤⢄', // crawl up and down, tiny
+    '⡀⣄⣦⢷⠻⠙⠈⠀⠁⠋⠟⡾⣴⣠⢀⠀', // slide up and down
+    '⠙⠸⢰⣠⣄⡆⠇⠋', // clockwise line
+    '⠁⠈⠐⠠⢀⡀⠄⠂', // clockwise dot
+    '⢇⢣⢱⡸⡜⡎', // vertical wobble up
+    '⡇⡎⡜⡸⢸⢱⢣⢇', // vertical wobble down
+    '⡀⣀⣐⣒⣖⣶⣾⣿⢿⠿⠯⠭⠩⠉⠁⠀', // swirl
+    '⠁⠐⠄⢀⢈⢂⢠⣀⣁⣐⣄⣌⣆⣤⣥⣴⣼⣶⣷⣿⣾⣶⣦⣤⣠⣀⡀⠀⠀', // snowing and melting
+    '⠁⠋⠞⡴⣠⢀⠀⠈⠙⠻⢷⣦⣄⡀⠀⠉⠛⠲⢤⢀⠀', // falling water
+    '⠄⡢⢑⠈⠀⢀⣠⣤⡶⠞⠋⠁⠀⠈⠙⠳⣆⡀⠀⠆⡷⣹⢈⠀⠐⠪⢅⡀⠀', // fireworks
+    '⠐⢐⢒⣒⣲⣶⣷⣿⡿⡷⡧⠧⠇⠃⠁⠀⡀⡠⡡⡱⣱⣳⣷⣿⢿⢯⢧⠧⠣⠃⠂⠀⠈⠨⠸⠺⡺⡾⡿⣿⡿⡷⡗⡇⡅⡄⠄⠀⡀⡐⣐⣒⣓⣳⣻⣿⣾⣼⡼⡸⡘⡈⠈⠀', // fade
+    '⢸⡯⠭⠅⢸⣇⣀⡀⢸⣇⣸⡇⠈⢹⡏⠁⠈⢹⡏⠁⢸⣯⣭⡅⢸⡯⢕⡂⠀⠀', // text crawl
+  ];
+
+  static const List<String> _asciiAnimations = <String>[
+    r'-\|/',
+  ];
+
+  static List<String> _selectAnimation(Terminal terminal) {
+    final List<String> animations =
+        terminal.supportsEmoji ? _emojiAnimations : _asciiAnimations;
+    return animations[terminal.preferredStyle % animations.length]
+        .runes
+        .map<String>((int scalar) => String.fromCharCode(scalar))
+        .toList();
+  }
+
+  final List<String> _animation;
+
+  Timer? timer;
+  int ticks = 0;
+  int _lastAnimationFrameLength = 0;
+  bool timedOut = false;
+
+  String get _currentAnimationFrame => _animation[ticks % _animation.length];
+  int get _currentLineLength => _lastAnimationFrameLength + _slowWarning.length;
+
+  void _writeToStdOut(String message) => _stdio.stdoutWrite(message);
+
+  void _clear(int length) {
+    _writeToStdOut('${_backspaceChar * length}'
+        '${_clearChar * length}'
+        '${_backspaceChar * length}');
+  }
+
+  @override
+  void start() {
+    super.start();
+    assert(timer == null);
+    _startSpinner();
+  }
+
+  void _startSpinner() {
+    timer = Timer.periodic(const Duration(milliseconds: 100), _callback);
+    _callback(timer!);
+  }
+
+  void _callback(Timer timer) {
+    assert(this.timer == timer);
+    assert(timer != null);
+    assert(timer.isActive);
+    _writeToStdOut(_backspaceChar * _lastAnimationFrameLength);
+    ticks += 1;
+    if (seemsSlow) {
+      if (!timedOut) {
+        timedOut = true;
+        _clear(_currentLineLength);
+      }
+      if (_slowWarning == '' && slowWarningCallback != null) {
+        _slowWarning = slowWarningCallback!();
+        _writeToStdOut(_slowWarning);
+      }
+    }
+    final String newFrame = _currentAnimationFrame;
+    _lastAnimationFrameLength = newFrame.runes.length;
+    _writeToStdOut(newFrame);
+  }
+
+  @override
+  void pause() {
+    assert(timer != null);
+    assert(timer!.isActive);
+    if (_terminal.supportsColor) {
+      _writeToStdOut('\r\x1B[K'); // go to start of line and clear line
+    } else {
+      _clear(_currentLineLength);
+    }
+    _lastAnimationFrameLength = 0;
+    timer?.cancel();
+  }
+
+  @override
+  void resume() {
+    assert(timer != null);
+    assert(!timer!.isActive);
+    _startSpinner();
+  }
+
+  @override
+  void finish() {
+    assert(timer != null);
+    assert(timer!.isActive);
+    timer?.cancel();
+    timer = null;
+    _clear(_lastAnimationFrameLength);
+    _lastAnimationFrameLength = 0;
+    super.finish();
+  }
+}
+
+/// An animated version of [Status].
+///
+/// The constructor writes [message] to [stdout] with padding, then starts an
+/// indeterminate progress indicator animation.
+///
+/// On [cancel] or [stop], will call [onFinish]. On [stop], will
+/// additionally print out summary information.
+///
+/// Call [pause] before outputting any text while this is running.
+class SpinnerStatus extends AnonymousSpinnerStatus {
+  SpinnerStatus({
+    required this.message,
+    this.padding = kDefaultStatusPadding,
+    super.onFinish,
+    required super.stopwatch,
+    required super.stdio,
+    required super.terminal,
+  });
+
+  final String message;
+  final int padding;
+
+  static final String _margin =
+      AnonymousSpinnerStatus._clearChar * (5 + _kTimePadding - 1);
+
+  int _totalMessageLength = 0;
+
+  @override
+  int get _currentLineLength => _totalMessageLength + super._currentLineLength;
+
+  @override
+  void start() {
+    _printStatus();
+    super.start();
+  }
+
+  void _printStatus() {
+    final String line = '${message.padRight(padding)}$_margin';
+    _totalMessageLength = line.length;
+    _writeToStdOut(line);
+  }
+
+  @override
+  void pause() {
+    super.pause();
+    _totalMessageLength = 0;
+  }
+
+  @override
+  void resume() {
+    _printStatus();
+    super.resume();
+  }
+
+  @override
+  void stop() {
+    super.stop(); // calls finish, which clears the spinner
+    assert(_totalMessageLength > _kTimePadding);
+    _writeToStdOut(AnonymousSpinnerStatus._backspaceChar * (_kTimePadding - 1));
+    _writeToStdOut(elapsedTime.padLeft(_kTimePadding));
+    _writeToStdOut('\n');
+  }
+
+  @override
+  void cancel() {
+    super.cancel(); // calls finish, which clears the spinner
+    assert(_totalMessageLength > 0);
+    _writeToStdOut('\n');
+  }
+}
+
+/// Wraps a block of text into lines no longer than [columnWidth].
+///
+/// Tries to split at whitespace, but if that's not good enough to keep it under
+/// the limit, then it splits in the middle of a word. If [columnWidth] (minus
+/// any indent) is smaller than [kMinColumnWidth], the text is wrapped at that
+/// [kMinColumnWidth] instead.
+///
+/// Preserves indentation (leading whitespace) for each line (delimited by '\n')
+/// in the input, and will indent wrapped lines that same amount, adding
+/// [indent] spaces in addition to any existing indent.
+///
+/// If [hangingIndent] is supplied, then that many additional spaces will be
+/// added to each line, except for the first line. The [hangingIndent] is added
+/// to the specified [indent], if any. This is useful for wrapping
+/// text with a heading prefix (e.g. "Usage: "):
+///
+/// ```dart
+/// String prefix = "Usage: ";
+/// print(prefix + wrapText(invocation, indent: 2, hangingIndent: prefix.length, columnWidth: 40));
+/// ```
+///
+/// yields:
+/// ```
+///   Usage: app main_command <subcommand>
+///          [arguments]
+/// ```
+///
+/// If [outputPreferences.wrapText] is false, then the text will be returned
+/// unchanged. If [shouldWrap] is specified, then it overrides the
+/// [outputPreferences.wrapText] setting.
+///
+/// If the amount of indentation (from the text, [indent], and [hangingIndent])
+/// is such that less than [kMinColumnWidth] characters can fit in the
+/// [columnWidth], then the indent is truncated to allow the text to fit.
+String wrapText(
+  String text, {
+  required int columnWidth,
+  required bool shouldWrap,
+  int? hangingIndent,
+  int? indent,
+}) {
+  assert(columnWidth >= 0);
+  if (text == null || text.isEmpty) {
+    return '';
+  }
+  indent ??= 0;
+  hangingIndent ??= 0;
+  final List<String> splitText = text.split('\n');
+  final List<String> result = <String>[];
+  for (final String line in splitText) {
+    String trimmedText = line.trimLeft();
+    final String leadingWhitespace =
+        line.substring(0, line.length - trimmedText.length);
+    List<String> notIndented;
+    if (hangingIndent != 0) {
+      // When we have a hanging indent, we want to wrap the first line at one
+      // width, and the rest at another (offset by hangingIndent), so we wrap
+      // them twice and recombine.
+      final List<String> firstLineWrap = _wrapTextAsLines(
+        trimmedText,
+        columnWidth: columnWidth - leadingWhitespace.length - indent,
+        shouldWrap: shouldWrap,
+      );
+      notIndented = <String>[firstLineWrap.removeAt(0)];
+      trimmedText = trimmedText.substring(notIndented[0].length).trimLeft();
+      if (trimmedText.isNotEmpty) {
+        notIndented.addAll(_wrapTextAsLines(
+          trimmedText,
+          columnWidth:
+              columnWidth - leadingWhitespace.length - indent - hangingIndent,
+          shouldWrap: shouldWrap,
+        ));
+      }
+    } else {
+      notIndented = _wrapTextAsLines(
+        trimmedText,
+        columnWidth: columnWidth - leadingWhitespace.length - indent,
+        shouldWrap: shouldWrap,
+      );
+    }
+    String? hangingIndentString;
+    final String indentString = ' ' * indent;
+    result.addAll(notIndented.map<String>(
+      (String line) {
+        // Don't return any lines with just whitespace on them.
+        if (line.isEmpty) {
+          return '';
+        }
+        String truncatedIndent =
+            '$indentString${hangingIndentString ?? ''}$leadingWhitespace';
+        if (truncatedIndent.length > columnWidth - kMinColumnWidth) {
+          truncatedIndent = truncatedIndent.substring(
+              0, math.max(columnWidth - kMinColumnWidth, 0));
+        }
+        final String result = '$truncatedIndent$line';
+        hangingIndentString ??= ' ' * hangingIndent!;
+        return result;
+      },
+    ));
+  }
+  return result.join('\n');
+}
+
+/// Wraps a block of text into lines no longer than [columnWidth], starting at the
+/// [start] column, and returning the result as a list of strings.
+///
+/// Tries to split at whitespace, but if that's not good enough to keep it
+/// under the limit, then splits in the middle of a word. Preserves embedded
+/// newlines, but not indentation (it trims whitespace from each line).
+///
+/// If [columnWidth] is not specified, then the column width will be the width of the
+/// terminal window by default. If the stdout is not a terminal window, then the
+/// default will be [outputPreferences.wrapColumn].
+///
+/// The [columnWidth] is clamped to [kMinColumnWidth] at minimum (so passing negative
+/// widths is fine, for instance).
+///
+/// If [outputPreferences.wrapText] is false, then the text will be returned
+/// simply split at the newlines, but not wrapped. If [shouldWrap] is specified,
+/// then it overrides the [outputPreferences.wrapText] setting.
+List<String> _wrapTextAsLines(
+  String text, {
+  int start = 0,
+  required int columnWidth,
+  required bool shouldWrap,
+}) {
+  if (text == null || text.isEmpty) {
+    return <String>[''];
+  }
+  assert(start >= 0);
+
+  // Splits a string so that the resulting list has the same number of elements
+  // as there are visible characters in the string, but elements may include one
+  // or more adjacent ANSI sequences. Joining the list elements again will
+  // reconstitute the original string. This is useful for manipulating "visible"
+  // characters in the presence of ANSI control codes.
+  List<_AnsiRun> splitWithCodes(String input) {
+    final RegExp characterOrCode =
+        RegExp('(\u001b\\[[0-9;]*m|.)', multiLine: true);
+    List<_AnsiRun> result = <_AnsiRun>[];
+    final StringBuffer current = StringBuffer();
+    for (final Match match in characterOrCode.allMatches(input)) {
+      current.write(match[0]);
+      if (match[0]!.length < 4) {
+        // This is a regular character, write it out.
+        result.add(_AnsiRun(current.toString(), match[0]!));
+        current.clear();
+      }
+    }
+    // If there's something accumulated, then it must be an ANSI sequence, so
+    // add it to the end of the last entry so that we don't lose it.
+    if (current.isNotEmpty) {
+      if (result.isNotEmpty) {
+        result.last.original += current.toString();
+      } else {
+        // If there is nothing in the string besides control codes, then just
+        // return them as the only entry.
+        result = <_AnsiRun>[_AnsiRun(current.toString(), '')];
+      }
+    }
+    return result;
+  }
+
+  String joinRun(List<_AnsiRun> list, int start, [int? end]) {
+    return list
+        .sublist(start, end)
+        .map<String>((_AnsiRun run) => run.original)
+        .join()
+        .trim();
+  }
+
+  final List<String> result = <String>[];
+  final int effectiveLength = math.max(columnWidth - start, kMinColumnWidth);
+  for (final String line in text.split('\n')) {
+    // If the line is short enough, even with ANSI codes, then we can just add
+    // add it and move on.
+    if (line.length <= effectiveLength || !shouldWrap) {
+      result.add(line);
+      continue;
+    }
+    final List<_AnsiRun> splitLine = splitWithCodes(line);
+    if (splitLine.length <= effectiveLength) {
+      result.add(line);
+      continue;
+    }
+
+    int currentLineStart = 0;
+    int? lastWhitespace;
+    // Find the start of the current line.
+    for (int index = 0; index < splitLine.length; ++index) {
+      if (splitLine[index].character.isNotEmpty &&
+          _isWhitespace(splitLine[index])) {
+        lastWhitespace = index;
+      }
+
+      if (index - currentLineStart >= effectiveLength) {
+        // Back up to the last whitespace, unless there wasn't any, in which
+        // case we just split where we are.
+        if (lastWhitespace != null) {
+          index = lastWhitespace;
+        }
+
+        result.add(joinRun(splitLine, currentLineStart, index));
+
+        // Skip any intervening whitespace.
+        while (index < splitLine.length && _isWhitespace(splitLine[index])) {
+          index++;
+        }
+
+        currentLineStart = index;
+        lastWhitespace = null;
+      }
+    }
+    result.add(joinRun(splitLine, currentLineStart));
+  }
+  return result;
+}
+
+// Used to represent a run of ANSI control sequences next to a visible
+// character.
+class _AnsiRun {
+  _AnsiRun(this.original, this.character);
+
+  String original;
+  String character;
+}
+
+/// Returns true if the code unit at [index] in [text] is a whitespace
+/// character.
+///
+/// Based on: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
+bool _isWhitespace(_AnsiRun run) {
+  final int rune = run.character.isNotEmpty ? run.character.codeUnitAt(0) : 0x0;
+  return rune >= 0x0009 && rune <= 0x000D ||
+      rune == 0x0020 ||
+      rune == 0x0085 ||
+      rune == 0x1680 ||
+      rune == 0x180E ||
+      rune >= 0x2000 && rune <= 0x200A ||
+      rune == 0x2028 ||
+      rune == 0x2029 ||
+      rune == 0x202F ||
+      rune == 0x205F ||
+      rune == 0x3000 ||
+      rune == 0xFEFF;
+}
+
+/// An abstraction for instantiation of the correct logger type.
+///
+/// Our logger class hierarchy and runtime requirements are overly complicated.
+class LoggerFactory {
+  LoggerFactory({
+    required Terminal terminal,
+    required Stdio stdio,
+    required OutputPreferences outputPreferences,
+    StopwatchFactory stopwatchFactory = const StopwatchFactory(),
+  })  : _terminal = terminal,
+        _stdio = stdio,
+        _stopwatchFactory = stopwatchFactory,
+        _outputPreferences = outputPreferences;
+
+  final Terminal _terminal;
+  final Stdio _stdio;
+  final StopwatchFactory _stopwatchFactory;
+  final OutputPreferences _outputPreferences;
+
+  /// Create the appropriate logger for the current platform and configuration.
+  Logger createLogger({
+    required bool windows,
+  }) {
+    Logger logger;
+    if (windows) {
+      logger = WindowsStdoutLogger(
+        terminal: _terminal,
+        stdio: _stdio,
+        outputPreferences: _outputPreferences,
+        stopwatchFactory: _stopwatchFactory,
+      );
+    } else {
+      logger = StdoutLogger(
+          terminal: _terminal,
+          stdio: _stdio,
+          outputPreferences: _outputPreferences,
+          stopwatchFactory: _stopwatchFactory);
+    }
+    return logger;
+  }
+}
diff --git a/packages/flutter_migrate/lib/src/base/project.dart b/packages/flutter_migrate/lib/src/base/project.dart
new file mode 100644
index 0000000..a8924d7
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/project.dart
@@ -0,0 +1,91 @@
+// Copyright 2013 The Flutter 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 'package:meta/meta.dart';
+
+import 'file_system.dart';
+import 'logger.dart';
+
+/// Emum for each officially supported platform.
+enum SupportedPlatform {
+  android,
+  ios,
+  linux,
+  macos,
+  web,
+  windows,
+  fuchsia,
+  root, // Special platform to represent the root project directory
+}
+
+class FlutterProjectFactory {
+  FlutterProjectFactory();
+
+  @visibleForTesting
+  final Map<String, FlutterProject> projects = <String, FlutterProject>{};
+
+  /// Returns a [FlutterProject] view of the given directory or a ToolExit error,
+  /// if `pubspec.yaml` or `example/pubspec.yaml` is invalid.
+  FlutterProject fromDirectory(Directory directory) {
+    assert(directory != null);
+    return projects.putIfAbsent(directory.path, () {
+      return FlutterProject(directory);
+    });
+  }
+}
+
+/// Represents the contents of a Flutter project at the specified [directory].
+class FlutterProject {
+  FlutterProject(this.directory) : assert(directory != null);
+
+  /// Returns a [FlutterProject] view of the current directory or a ToolExit error,
+  /// if `pubspec.yaml` or `example/pubspec.yaml` is invalid.
+  static FlutterProject current(FileSystem fs) =>
+      FlutterProject(fs.currentDirectory);
+
+  /// Create a [FlutterProject] and bypass the project caching.
+  @visibleForTesting
+  static FlutterProject fromDirectoryTest(Directory directory,
+      [Logger? logger]) {
+    logger ??= BufferLogger.test();
+    return FlutterProject(directory);
+  }
+
+  Directory directory;
+
+  /// The `pubspec.yaml` file of this project.
+  File get pubspecFile => directory.childFile('pubspec.yaml');
+
+  /// The `.metadata` file of this project.
+  File get metadataFile => directory.childFile('.metadata');
+
+  /// Returns a list of platform names that are supported by the project.
+  List<SupportedPlatform> getSupportedPlatforms({bool includeRoot = false}) {
+    final List<SupportedPlatform> platforms = includeRoot
+        ? <SupportedPlatform>[SupportedPlatform.root]
+        : <SupportedPlatform>[];
+    if (directory.childDirectory('android').existsSync()) {
+      platforms.add(SupportedPlatform.android);
+    }
+    if (directory.childDirectory('ios').existsSync()) {
+      platforms.add(SupportedPlatform.ios);
+    }
+    if (directory.childDirectory('web').existsSync()) {
+      platforms.add(SupportedPlatform.web);
+    }
+    if (directory.childDirectory('macos').existsSync()) {
+      platforms.add(SupportedPlatform.macos);
+    }
+    if (directory.childDirectory('linux').existsSync()) {
+      platforms.add(SupportedPlatform.linux);
+    }
+    if (directory.childDirectory('windows').existsSync()) {
+      platforms.add(SupportedPlatform.windows);
+    }
+    if (directory.childDirectory('fuchsia').existsSync()) {
+      platforms.add(SupportedPlatform.fuchsia);
+    }
+    return platforms;
+  }
+}
diff --git a/packages/flutter_migrate/lib/src/base/signals.dart b/packages/flutter_migrate/lib/src/base/signals.dart
new file mode 100644
index 0000000..265f00f
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/signals.dart
@@ -0,0 +1,154 @@
+// Copyright 2013 The Flutter 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';
+
+import 'package:meta/meta.dart';
+
+import 'common.dart';
+import 'io.dart';
+
+typedef SignalHandler = FutureOr<void> Function(ProcessSignal signal);
+
+/// A class that manages signal handlers.
+///
+/// Signal handlers are run in the order that they were added.
+abstract class Signals {
+  @visibleForTesting
+  factory Signals.test({
+    List<ProcessSignal> exitSignals = defaultExitSignals,
+  }) =>
+      LocalSignals._(exitSignals);
+
+  // The default list of signals that should cause the process to exit.
+  static const List<ProcessSignal> defaultExitSignals = <ProcessSignal>[
+    ProcessSignal.sigterm,
+    ProcessSignal.sigint,
+  ];
+
+  /// Adds a signal handler to run on receipt of signal.
+  ///
+  /// The handler will run after all handlers that were previously added for the
+  /// signal. The function returns an abstract token that should be provided to
+  /// removeHandler to remove the handler.
+  Object addHandler(ProcessSignal signal, SignalHandler handler);
+
+  /// Removes a signal handler.
+  ///
+  /// Removes the signal handler for the signal identified by the abstract
+  /// token parameter. Returns true if the handler was removed and false
+  /// otherwise.
+  Future<bool> removeHandler(ProcessSignal signal, Object token);
+
+  /// If a [SignalHandler] throws an error, either synchronously or
+  /// asynchronously, it will be added to this stream instead of propagated.
+  Stream<Object> get errors;
+}
+
+/// A class that manages the real dart:io signal handlers.
+///
+/// We use a singleton instance of this class to ensure that all handlers for
+/// fatal signals run before this class calls exit().
+class LocalSignals implements Signals {
+  LocalSignals._(this.exitSignals);
+
+  static LocalSignals instance = LocalSignals._(
+    Signals.defaultExitSignals,
+  );
+
+  final List<ProcessSignal> exitSignals;
+
+  // A table mapping (signal, token) -> signal handler.
+  final Map<ProcessSignal, Map<Object, SignalHandler>> _handlersTable =
+      <ProcessSignal, Map<Object, SignalHandler>>{};
+
+  // A table mapping (signal) -> signal handler list. The list is in the order
+  // that the signal handlers should be run.
+  final Map<ProcessSignal, List<SignalHandler>> _handlersList =
+      <ProcessSignal, List<SignalHandler>>{};
+
+  // A table mapping (signal) -> low-level signal event stream.
+  final Map<ProcessSignal, StreamSubscription<ProcessSignal>>
+      _streamSubscriptions =
+      <ProcessSignal, StreamSubscription<ProcessSignal>>{};
+
+  // The stream controller for errors coming from signal handlers.
+  final StreamController<Object> _errorStreamController =
+      StreamController<Object>.broadcast();
+
+  @override
+  Stream<Object> get errors => _errorStreamController.stream;
+
+  @override
+  Object addHandler(ProcessSignal signal, SignalHandler handler) {
+    final Object token = Object();
+    _handlersTable.putIfAbsent(signal, () => <Object, SignalHandler>{});
+    _handlersTable[signal]![token] = handler;
+
+    _handlersList.putIfAbsent(signal, () => <SignalHandler>[]);
+    _handlersList[signal]!.add(handler);
+
+    // If we added the first one, then call signal.watch(), listen, and cache
+    // the stream controller.
+    if (_handlersList[signal]!.length == 1) {
+      _streamSubscriptions[signal] = signal.watch().listen(
+        _handleSignal,
+        onError: (Object e) {
+          _handlersTable[signal]?.remove(token);
+          _handlersList[signal]?.remove(handler);
+        },
+      );
+    }
+    return token;
+  }
+
+  @override
+  Future<bool> removeHandler(ProcessSignal signal, Object token) async {
+    // We don't know about this signal.
+    if (!_handlersTable.containsKey(signal)) {
+      return false;
+    }
+    // We don't know about this token.
+    if (!_handlersTable[signal]!.containsKey(token)) {
+      return false;
+    }
+    final SignalHandler? handler = _handlersTable[signal]!.remove(token);
+    if (handler == null) {
+      return false;
+    }
+    final bool removed = _handlersList[signal]!.remove(handler);
+    if (!removed) {
+      return false;
+    }
+
+    // If _handlersList[signal] is empty, then lookup the cached stream
+    // controller and unsubscribe from the stream.
+    if (_handlersList.isEmpty) {
+      await _streamSubscriptions[signal]?.cancel();
+    }
+    return true;
+  }
+
+  Future<void> _handleSignal(ProcessSignal s) async {
+    final List<SignalHandler>? handlers = _handlersList[s];
+    if (handlers != null) {
+      final List<SignalHandler> handlersCopy = handlers.toList();
+      for (final SignalHandler handler in handlersCopy) {
+        try {
+          await asyncGuard<void>(() async => handler(s));
+        } on Exception catch (e) {
+          if (_errorStreamController.hasListener) {
+            _errorStreamController.add(e);
+          }
+        }
+      }
+    }
+    // If this was a signal that should cause the process to go down, then
+    // call exit();
+    if (exitSignals.contains(s)) {
+      exit(0);
+    }
+  }
+}
diff --git a/packages/flutter_migrate/lib/src/base/terminal.dart b/packages/flutter_migrate/lib/src/base/terminal.dart
new file mode 100644
index 0000000..07976aa
--- /dev/null
+++ b/packages/flutter_migrate/lib/src/base/terminal.dart
@@ -0,0 +1,418 @@
+// Copyright 2013 The Flutter 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:convert';
+import 'dart:io';
+
+import 'common.dart';
+import 'io.dart' as io;
+import 'logger.dart';
+
+enum TerminalColor {
+  red,
+  green,
+  blue,
+  cyan,
+  yellow,
+  magenta,
+  grey,
+}
+
+/// A class that contains the context settings for command text output to the
+/// console.
+class OutputPreferences {
+  OutputPreferences({
+    bool? wrapText,
+    int? wrapColumn,
+    bool? showColor,
+    io.Stdio? stdio,
+  })  : _stdio = stdio,
+        wrapText = wrapText ?? stdio?.hasTerminal ?? false,
+        _overrideWrapColumn = wrapColumn,
+        showColor = showColor ?? false;
+
+  /// A version of this class for use in tests.
+  OutputPreferences.test(
+      {this.wrapText = false,
+      int wrapColumn = kDefaultTerminalColumns,
+      this.showColor = false})
+      : _overrideWrapColumn = wrapColumn,
+        _stdio = null;
+
+  final io.Stdio? _stdio;
+
+  /// If [wrapText] is true, then any text sent to the context's [Logger]
+  /// instance (e.g. from the [printError] or [printStatus] functions) will be
+  /// wrapped (newlines added between words) to be no longer than the
+  /// [wrapColumn] specifies. Defaults to true if there is a terminal. To
+  /// determine if there's a terminal, [OutputPreferences] asks the context's
+  /// stdio.
+  final bool wrapText;
+
+  /// The terminal width used by the [wrapText] function if there is no terminal
+  /// attached to [io.Stdio], --wrap is on, and --wrap-columns was not specified.
+  static const int kDefaultTerminalColumns = 100;
+
+  /// The column at which output sent to the context's [Logger] instance
+  /// (e.g. from the [printError] or [printStatus] functions) will be wrapped.
+  /// Ignored if [wrapText] is false. Defaults to the width of the output
+  /// terminal, or to [kDefaultTerminalColumns] if not writing to a terminal.
+  final int? _overrideWrapColumn;
+  int get wrapColumn {
+    return _overrideWrapColumn ??
+        _stdio?.terminalColumns ??
+        kDefaultTerminalColumns;
+  }
+
+  /// Whether or not to output ANSI color codes when writing to the output
+  /// terminal. Defaults to whatever [platform.stdoutSupportsAnsi] says if
+  /// writing to a terminal, and false otherwise.
+  final bool showColor;
+
+  @override
+  String toString() {
+    return '$runtimeType[wrapText: $wrapText, wrapColumn: $wrapColumn, showColor: $showColor]';
+  }
+}
+
+/// The command line terminal, if available.
+abstract class Terminal {
+  /// Create a new test [Terminal].
+  ///
+  /// If not specified, [supportsColor] defaults to `false`.
+  factory Terminal.test({bool supportsColor, bool supportsEmoji}) =
+      _TestTerminal;
+
+  /// Whether the current terminal supports color escape codes.
+  bool get supportsColor;
+
+  /// Whether the current terminal can display emoji.
+  bool get supportsEmoji;
+
+  /// When we have a choice of styles (e.g. animated spinners), this selects the
+  /// style to use.
+  int get preferredStyle;
+
+  /// Whether we are interacting with the flutter tool via the terminal.
+  ///
+  /// If not set, defaults to false.
+  bool get usesTerminalUi;
+  set usesTerminalUi(bool value);
+
+  /// Whether there is a terminal attached to stdin.
+  ///
+  /// If true, this usually indicates that a user is using the CLI as
+  /// opposed to using an IDE. This can be used to determine
+  /// whether it is appropriate to show a terminal prompt,
+  /// or whether an automatic selection should be made instead.
+  bool get stdinHasTerminal;
+
+  /// Warning mark to use in stdout or stderr.
+  String get warningMark;
+
+  /// Success mark to use in stdout.
+  String get successMark;
+
+  String bolden(String message);
+
+  String color(String message, TerminalColor color);
+
+  String clearScreen();
+
+  bool get singleCharMode;
+  set singleCharMode(bool value);
+
+  /// Return keystrokes from the console.
+  ///
+  /// This is a single-subscription stream. This stream may be closed before
+  /// the application exits.
+  ///
+  /// Useful when the console is in [singleCharMode].
+  Stream<String> get keystrokes;
+
+  /// Prompts the user to input a character within a given list. Re-prompts if
+  /// entered character is not in the list.
+  ///
+  /// The `prompt`, if non-null, is the text displayed prior to waiting for user
+  /// input each time. If `prompt` is non-null and `displayAcceptedCharacters`
+  /// is true, the accepted keys are printed next to the `prompt`.
+  ///
+  /// The returned value is the user's input; if `defaultChoiceIndex` is not
+  /// null, and the user presses enter without any other input, the return value
+  /// will be the character in `acceptedCharacters` at the index given by
+  /// `defaultChoiceIndex`.
+  ///
+  /// The accepted characters must be a String with a length of 1, excluding any
+  /// whitespace characters such as `\t`, `\n`, or ` `.
+  ///
+  /// If [usesTerminalUi] is false, throws a [StateError].
+  Future<String> promptForCharInput(
+    List<String> acceptedCharacters, {
+    required Logger logger,
+    String? prompt,
+    int? defaultChoiceIndex,
+    bool displayAcceptedCharacters = true,
+  });
+}
+
+class AnsiTerminal implements Terminal {
+  AnsiTerminal({
+    required io.Stdio stdio,
+    DateTime?
+        now, // Time used to determine preferredStyle. Defaults to 0001-01-01 00:00.
+    bool? supportsColor,
+  })  : _stdio = stdio,
+        _now = now ?? DateTime(1),
+        _supportsColor = supportsColor;
+
+  final io.Stdio _stdio;
+  final DateTime _now;
+
+  static const String bold = '\u001B[1m';
+  static const String resetAll = '\u001B[0m';
+  static const String resetColor = '\u001B[39m';
+  static const String resetBold = '\u001B[22m';
+  static const String clear = '\u001B[2J\u001B[H';
+
+  static const String red = '\u001b[31m';
+  static const String green = '\u001b[32m';
+  static const String blue = '\u001b[34m';
+  static const String cyan = '\u001b[36m';
+  static const String magenta = '\u001b[35m';
+  static const String yellow = '\u001b[33m';
+  static const String grey = '\u001b[90m';
+
+  static const Map<TerminalColor, String> _colorMap = <TerminalColor, String>{
+    TerminalColor.red: red,
+    TerminalColor.green: green,
+    TerminalColor.blue: blue,
+    TerminalColor.cyan: cyan,
+    TerminalColor.magenta: magenta,
+    TerminalColor.yellow: yellow,
+    TerminalColor.grey: grey,
+  };
+
+  static String colorCode(TerminalColor color) => _colorMap[color]!;
+
+  @override
+  bool get supportsColor => _supportsColor ?? stdout.supportsAnsiEscapes;
+  final bool? _supportsColor;
+
+  // Assume unicode emojis are supported when not on Windows.
+  // If we are on Windows, unicode emojis are supported in Windows Terminal,
+  // which sets the WT_SESSION environment variable. See:
+  // https://github.com/microsoft/terminal/blob/master/doc/user-docs/index.md#tips-and-tricks
+  @override
+  bool get supportsEmoji =>
+      !isWindows || Platform.environment.containsKey('WT_SESSION');
+
+  @override
+  int get preferredStyle {
+    const int workdays = DateTime.friday;
+    if (_now.weekday <= workdays) {
+      return _now.weekday - 1;
+    }
+    return _now.hour + workdays;
+  }
+
+  final RegExp _boldControls = RegExp(
+    '(${RegExp.escape(resetBold)}|${RegExp.escape(bold)})',
+  );
+
+  @override
+  bool usesTerminalUi = false;
+
+  @override
+  String get warningMark {
+    return bolden(color('[!]', TerminalColor.red));
+  }
+
+  @override
+  String get successMark {
+    return bolden(color('✓', TerminalColor.green));
+  }
+
+  @override
+  String bolden(String message) {
+    assert(message != null);
+    if (!supportsColor || message.isEmpty) {
+      return message;
+    }
+    final StringBuffer buffer = StringBuffer();
+    for (String line in message.split('\n')) {
+      // If there were bolds or resetBolds in the string before, then nuke them:
+      // they're redundant. This prevents previously embedded resets from
+      // stopping the boldness.
+      line = line.replaceAll(_boldControls, '');
+      buffer.writeln('$bold$line$resetBold');
+    }
+    final String result = buffer.toString();
+    // avoid introducing a new newline to the emboldened text
+    return (!message.endsWith('\n') && result.endsWith('\n'))
+        ? result.substring(0, result.length - 1)
+        : result;
+  }
+
+  @override
+  String color(String message, TerminalColor color) {
+    assert(message != null);
+    if (!supportsColor || color == null || message.isEmpty) {
+      return message;
+    }
+    final StringBuffer buffer = StringBuffer();
+    final String colorCodes = _colorMap[color]!;
+    for (String line in message.split('\n')) {
+      // If there were resets in the string before, then keep them, but
+      // restart the color right after. This prevents embedded resets from
+      // stopping the colors, and allows nesting of colors.
+      line = line.replaceAll(resetColor, '$resetColor$colorCodes');
+      buffer.writeln('$colorCodes$line$resetColor');
+    }
+    final String result = buffer.toString();
+    // avoid introducing a new newline to the colored text
+    return (!message.endsWith('\n') && result.endsWith('\n'))
+        ? result.substring(0, result.length - 1)
+        : result;
+  }
+
+  @override
+  String clearScreen() => supportsColor ? clear : '\n\n';
+
+  @override
+  bool get singleCharMode {
+    if (!_stdio.stdinHasTerminal) {
+      return false;
+    }
+    final io.Stdin stdin = _stdio.stdin as io.Stdin;
+    return stdin.lineMode && stdin.echoMode;
+  }
+
+  @override
+  set singleCharMode(bool value) {
+    if (!_stdio.stdinHasTerminal) {
+      return;
+    }
+    final io.Stdin stdin = _stdio.stdin as io.Stdin;
+    // The order of setting lineMode and echoMode is important on Windows.
+    if (value) {
+      stdin.echoMode = false;
+      stdin.lineMode = false;
+    } else {
+      stdin.lineMode = true;
+      stdin.echoMode = true;
+    }
+  }
+
+  @override
+  bool get stdinHasTerminal => _stdio.stdinHasTerminal;
+
+  Stream<String>? _broadcastStdInString;
+
+  @override
+  Stream<String> get keystrokes {
+    return _broadcastStdInString ??= _stdio.stdin
+        .transform<String>(const AsciiDecoder(allowInvalid: true))
+        .asBroadcastStream();
+  }
+
+  @override
+  Future<String> promptForCharInput(
+    List<String> acceptedCharacters, {
+    required Logger logger,
+    String? prompt,
+    int? defaultChoiceIndex,
+    bool displayAcceptedCharacters = true,
+  }) async {
+    assert(acceptedCharacters.isNotEmpty);
+    assert(prompt == null || prompt.isNotEmpty);
+    if (!usesTerminalUi) {
+      throw StateError('cannot prompt without a terminal ui');
+    }
+    List<String> charactersToDisplay = acceptedCharacters;
+    if (defaultChoiceIndex != null) {
+      assert(defaultChoiceIndex >= 0 &&
+          defaultChoiceIndex < acceptedCharacters.length);
+      charactersToDisplay = List<String>.of(charactersToDisplay);
+      charactersToDisplay[defaultChoiceIndex] =
+          bolden(charactersToDisplay[defaultChoiceIndex]);
+      acceptedCharacters.add('');
+    }
+    String? choice;
+    singleCharMode = true;
+    while (choice == null ||
+        choice.length > 1 ||
+        !acceptedCharacters.contains(choice)) {
+      if (prompt != null) {
+        logger.printStatus(prompt, emphasis: true, newline: false);
+        if (displayAcceptedCharacters) {
+          logger.printStatus(' [${charactersToDisplay.join("|")}]',
+              newline: false);
+        }
+        // prompt ends with ': '
+        logger.printStatus(': ', emphasis: true, newline: false);
+      }
+      choice = (await keystrokes.first).trim();
+      logger.printStatus(choice);
+    }
+    singleCharMode = false;
+    if (defaultChoiceIndex != null && choice == '') {
+      choice = acceptedCharacters[defaultChoiceIndex];
+    }
+    return choice;
+  }
+}
+
+class _TestTerminal implements Terminal {
+  _TestTerminal({this.supportsColor = false, this.supportsEmoji = false});
+
+  @override
+  bool usesTerminalUi = false;
+
+  @override
+  String bolden(String message) => message;
+
+  @override
+  String clearScreen() => '\n\n';
+
+  @override
+  String color(String message, TerminalColor color) => message;
+
+  @override
+  Stream<String> get keystrokes => const Stream<String>.empty();
+
+  @override
+  Future<String> promptForCharInput(
+    List<String> acceptedCharacters, {
+    required Logger logger,
+    String? prompt,
+    int? defaultChoiceIndex,
+    bool displayAcceptedCharacters = true,
+  }) {
+    throw UnsupportedError(
+        'promptForCharInput not supported in the test terminal.');
+  }
+
+  @override
+  bool get singleCharMode => false;
+  @override
+  set singleCharMode(bool value) {}
+
+  @override
+  final bool supportsColor;
+
+  @override
+  final bool supportsEmoji;
+
+  @override
+  int get preferredStyle => 0;
+
+  @override
+  bool get stdinHasTerminal => false;
+
+  @override
+  String get successMark => '✓';
+
+  @override
+  String get warningMark => '[!]';
+}
diff --git a/packages/flutter_migrate/pubspec.yaml b/packages/flutter_migrate/pubspec.yaml
index 28f180b..3704d5b 100644
--- a/packages/flutter_migrate/pubspec.yaml
+++ b/packages/flutter_migrate/pubspec.yaml
@@ -10,5 +10,20 @@
 
 dependencies:
   args: ^2.3.1
+  convert: 3.0.2
+  file: 6.1.4
+  intl: 0.17.0
+  meta: 1.8.0
+  path: ^1.8.0
+  process: 4.2.4
+  test_api: 0.4.13
+  test_core: 0.4.17
+  vm_service: 9.3.0
+  xml: ^6.1.0
+  yaml: 3.1.1
 
 dev_dependencies:
+  collection: 1.16.0
+  file_testing: ^3.0.0
+  lints: ^2.0.0
+  test: ^1.16.0
diff --git a/packages/flutter_migrate/test/base/context_test.dart b/packages/flutter_migrate/test/base/context_test.dart
new file mode 100644
index 0000000..53f8e8f
--- /dev/null
+++ b/packages/flutter_migrate/test/base/context_test.dart
@@ -0,0 +1,296 @@
+// Copyright 2013 The Flutter 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:flutter_migrate/src/base/context.dart';
+
+import '../src/common.dart';
+
+void main() {
+  group('AppContext', () {
+    group('global getter', () {
+      late bool called;
+
+      setUp(() {
+        called = false;
+      });
+
+      test('returns non-null context in the root zone', () {
+        expect(context, isNotNull);
+      });
+
+      test(
+          'returns root context in child of root zone if zone was manually created',
+          () {
+        final Zone rootZone = Zone.current;
+        final AppContext rootContext = context;
+        runZoned<void>(() {
+          expect(Zone.current, isNot(rootZone));
+          expect(Zone.current.parent, rootZone);
+          expect(context, rootContext);
+          called = true;
+        });
+        expect(called, isTrue);
+      });
+
+      test('returns child context after run', () async {
+        final AppContext rootContext = context;
+        await rootContext.run<void>(
+            name: 'child',
+            body: () {
+              expect(context, isNot(rootContext));
+              expect(context.name, 'child');
+              called = true;
+            });
+        expect(called, isTrue);
+      });
+
+      test('returns grandchild context after nested run', () async {
+        final AppContext rootContext = context;
+        await rootContext.run<void>(
+            name: 'child',
+            body: () async {
+              final AppContext childContext = context;
+              await childContext.run<void>(
+                  name: 'grandchild',
+                  body: () {
+                    expect(context, isNot(rootContext));
+                    expect(context, isNot(childContext));
+                    expect(context.name, 'grandchild');
+                    called = true;
+                  });
+            });
+        expect(called, isTrue);
+      });
+
+      test('scans up zone hierarchy for first context', () async {
+        final AppContext rootContext = context;
+        await rootContext.run<void>(
+            name: 'child',
+            body: () {
+              final AppContext childContext = context;
+              runZoned<void>(() {
+                expect(context, isNot(rootContext));
+                expect(context, same(childContext));
+                expect(context.name, 'child');
+                called = true;
+              });
+            });
+        expect(called, isTrue);
+      });
+    });
+
+    group('operator[]', () {
+      test('still finds values if async code runs after body has finished',
+          () async {
+        final Completer<void> outer = Completer<void>();
+        final Completer<void> inner = Completer<void>();
+        String? value;
+        await context.run<void>(
+          body: () {
+            outer.future.then<void>((_) {
+              value = context.get<String>();
+              inner.complete();
+            });
+          },
+          fallbacks: <Type, Generator>{
+            String: () => 'value',
+          },
+        );
+        expect(value, isNull);
+        outer.complete();
+        await inner.future;
+        expect(value, 'value');
+      });
+
+      test('caches generated override values', () async {
+        int consultationCount = 0;
+        String? value;
+        await context.run<void>(
+          body: () async {
+            final StringBuffer buf = StringBuffer(context.get<String>()!);
+            buf.write(context.get<String>());
+            await context.run<void>(body: () {
+              buf.write(context.get<String>());
+            });
+            value = buf.toString();
+          },
+          overrides: <Type, Generator>{
+            String: () {
+              consultationCount++;
+              return 'v';
+            },
+          },
+        );
+        expect(value, 'vvv');
+        expect(consultationCount, 1);
+      });
+
+      test('caches generated fallback values', () async {
+        int consultationCount = 0;
+        String? value;
+        await context.run(
+          body: () async {
+            final StringBuffer buf = StringBuffer(context.get<String>()!);
+            buf.write(context.get<String>());
+            await context.run<void>(body: () {
+              buf.write(context.get<String>());
+            });
+            value = buf.toString();
+          },
+          fallbacks: <Type, Generator>{
+            String: () {
+              consultationCount++;
+              return 'v';
+            },
+          },
+        );
+        expect(value, 'vvv');
+        expect(consultationCount, 1);
+      });
+
+      test('returns null if generated value is null', () async {
+        final String? value = await context.run<String?>(
+          body: () => context.get<String>(),
+          overrides: <Type, Generator>{
+            String: () => null,
+          },
+        );
+        expect(value, isNull);
+      });
+
+      test('throws if generator has dependency cycle', () async {
+        final Future<String?> value = context.run<String?>(
+          body: () async {
+            return context.get<String>();
+          },
+          fallbacks: <Type, Generator>{
+            int: () => int.parse(context.get<String>() ?? ''),
+            String: () => '${context.get<double>()}',
+            double: () => context.get<int>()! * 1.0,
+          },
+        );
+        expect(
+          () => value,
+          throwsA(
+            isA<ContextDependencyCycleException>().having(
+                (ContextDependencyCycleException error) => error.cycle,
+                'cycle',
+                <Type>[String, double, int]).having(
+              (ContextDependencyCycleException error) => error.toString(),
+              'toString()',
+              'Dependency cycle detected: String -> double -> int',
+            ),
+          ),
+        );
+      });
+    });
+
+    group('run', () {
+      test('returns the value returned by body', () async {
+        expect(await context.run<int>(body: () => 123), 123);
+        expect(await context.run<String>(body: () => 'value'), 'value');
+        expect(await context.run<int>(body: () async => 456), 456);
+      });
+
+      test('passes name to child context', () async {
+        await context.run<void>(
+            name: 'child',
+            body: () {
+              expect(context.name, 'child');
+            });
+      });
+
+      group('fallbacks', () {
+        late bool called;
+
+        setUp(() {
+          called = false;
+        });
+
+        test('are applied after parent context is consulted', () async {
+          final String? value = await context.run<String?>(
+            body: () {
+              return context.run<String?>(
+                body: () {
+                  called = true;
+                  return context.get<String>();
+                },
+                fallbacks: <Type, Generator>{
+                  String: () => 'child',
+                },
+              );
+            },
+          );
+          expect(called, isTrue);
+          expect(value, 'child');
+        });
+
+        test('are not applied if parent context supplies value', () async {
+          bool childConsulted = false;
+          final String? value = await context.run<String?>(
+            body: () {
+              return context.run<String?>(
+                body: () {
+                  called = true;
+                  return context.get<String>();
+                },
+                fallbacks: <Type, Generator>{
+                  String: () {
+                    childConsulted = true;
+                    return 'child';
+                  },
+                },
+              );
+            },
+            fallbacks: <Type, Generator>{
+              String: () => 'parent',
+            },
+          );
+          expect(called, isTrue);
+          expect(value, 'parent');
+          expect(childConsulted, isFalse);
+        });
+
+        test('may depend on one another', () async {
+          final String? value = await context.run<String?>(
+            body: () {
+              return context.get<String>();
+            },
+            fallbacks: <Type, Generator>{
+              int: () => 123,
+              String: () => '-${context.get<int>()}-',
+            },
+          );
+          expect(value, '-123-');
+        });
+      });
+
+      group('overrides', () {
+        test('intercept consultation of parent context', () async {
+          bool parentConsulted = false;
+          final String? value = await context.run<String?>(
+            body: () {
+              return context.run<String?>(
+                body: () => context.get<String>(),
+                overrides: <Type, Generator>{
+                  String: () => 'child',
+                },
+              );
+            },
+            fallbacks: <Type, Generator>{
+              String: () {
+                parentConsulted = true;
+                return 'parent';
+              },
+            },
+          );
+          expect(value, 'child');
+          expect(parentConsulted, isFalse);
+        });
+      });
+    });
+  });
+}
diff --git a/packages/flutter_migrate/test/base/file_system_test.dart b/packages/flutter_migrate/test/base/file_system_test.dart
new file mode 100644
index 0000000..b7a6424
--- /dev/null
+++ b/packages/flutter_migrate/test/base/file_system_test.dart
@@ -0,0 +1,357 @@
+// Copyright 2013 The Flutter 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' as io;
+
+import 'package:file/memory.dart';
+import 'package:file_testing/file_testing.dart';
+import 'package:flutter_migrate/src/base/common.dart';
+import 'package:flutter_migrate/src/base/file_system.dart';
+import 'package:flutter_migrate/src/base/io.dart';
+import 'package:flutter_migrate/src/base/logger.dart';
+import 'package:flutter_migrate/src/base/signals.dart';
+import 'package:test/fake.dart';
+
+import '../src/common.dart';
+
+class LocalFileSystemFake extends LocalFileSystem {
+  LocalFileSystemFake.test({required super.signals}) : super.test();
+
+  @override
+  Directory get superSystemTempDirectory => directory('/does_not_exist');
+}
+
+void main() {
+  group('fsUtils', () {
+    late MemoryFileSystem fs;
+    late FileSystemUtils fsUtils;
+
+    setUp(() {
+      fs = MemoryFileSystem.test();
+      fsUtils = FileSystemUtils(
+        fileSystem: fs,
+      );
+    });
+
+    testWithoutContext('getUniqueFile creates a unique file name', () async {
+      final File fileA = fsUtils.getUniqueFile(
+          fs.currentDirectory, 'foo', 'json')
+        ..createSync();
+      final File fileB =
+          fsUtils.getUniqueFile(fs.currentDirectory, 'foo', 'json');
+
+      expect(fileA.path, '/foo_01.json');
+      expect(fileB.path, '/foo_02.json');
+    });
+
+    testWithoutContext('getUniqueDirectory creates a unique directory name',
+        () async {
+      final Directory directoryA =
+          fsUtils.getUniqueDirectory(fs.currentDirectory, 'foo')..createSync();
+      final Directory directoryB =
+          fsUtils.getUniqueDirectory(fs.currentDirectory, 'foo');
+
+      expect(directoryA.path, '/foo_01');
+      expect(directoryB.path, '/foo_02');
+    });
+  });
+
+  group('copyDirectorySync', () {
+    /// Test file_systems.copyDirectorySync() using MemoryFileSystem.
+    /// Copies between 2 instances of file systems which is also supported by copyDirectorySync().
+    testWithoutContext('test directory copy', () async {
+      final MemoryFileSystem sourceMemoryFs = MemoryFileSystem.test();
+      const String sourcePath = '/some/origin';
+      final Directory sourceDirectory =
+          await sourceMemoryFs.directory(sourcePath).create(recursive: true);
+      sourceMemoryFs.currentDirectory = sourcePath;
+      final File sourceFile1 = sourceMemoryFs.file('some_file.txt')
+        ..writeAsStringSync('bleh');
+      final DateTime writeTime = sourceFile1.lastModifiedSync();
+      sourceMemoryFs
+          .file('sub_dir/another_file.txt')
+          .createSync(recursive: true);
+      sourceMemoryFs.directory('empty_directory').createSync();
+
+      // Copy to another memory file system instance.
+      final MemoryFileSystem targetMemoryFs = MemoryFileSystem.test();
+      const String targetPath = '/some/non-existent/target';
+      final Directory targetDirectory = targetMemoryFs.directory(targetPath);
+
+      copyDirectory(sourceDirectory, targetDirectory);
+
+      expect(targetDirectory.existsSync(), true);
+      targetMemoryFs.currentDirectory = targetPath;
+      expect(targetMemoryFs.directory('empty_directory').existsSync(), true);
+      expect(
+          targetMemoryFs.file('sub_dir/another_file.txt').existsSync(), true);
+      expect(targetMemoryFs.file('some_file.txt').readAsStringSync(), 'bleh');
+
+      // Assert that the copy operation hasn't modified the original file in some way.
+      expect(
+          sourceMemoryFs.file('some_file.txt').lastModifiedSync(), writeTime);
+      // There's still 3 things in the original directory as there were initially.
+      expect(sourceMemoryFs.directory(sourcePath).listSync().length, 3);
+    });
+
+    testWithoutContext('Skip files if shouldCopyFile returns false', () {
+      final MemoryFileSystem fileSystem = MemoryFileSystem.test();
+      final Directory origin = fileSystem.directory('/origin');
+      origin.createSync();
+      fileSystem
+          .file(fileSystem.path.join('origin', 'a.txt'))
+          .writeAsStringSync('irrelevant');
+      fileSystem.directory('/origin/nested').createSync();
+      fileSystem
+          .file(fileSystem.path.join('origin', 'nested', 'a.txt'))
+          .writeAsStringSync('irrelevant');
+      fileSystem
+          .file(fileSystem.path.join('origin', 'nested', 'b.txt'))
+          .writeAsStringSync('irrelevant');
+
+      final Directory destination = fileSystem.directory('/destination');
+      copyDirectory(origin, destination,
+          shouldCopyFile: (File origin, File dest) {
+        return origin.basename == 'b.txt';
+      });
+
+      expect(destination.existsSync(), isTrue);
+      expect(destination.childDirectory('nested').existsSync(), isTrue);
+      expect(
+          destination.childDirectory('nested').childFile('b.txt').existsSync(),
+          isTrue);
+
+      expect(destination.childFile('a.txt').existsSync(), isFalse);
+      expect(
+          destination.childDirectory('nested').childFile('a.txt').existsSync(),
+          isFalse);
+    });
+
+    testWithoutContext('Skip directories if shouldCopyDirectory returns false',
+        () {
+      final MemoryFileSystem fileSystem = MemoryFileSystem.test();
+      final Directory origin = fileSystem.directory('/origin');
+      origin.createSync();
+      fileSystem
+          .file(fileSystem.path.join('origin', 'a.txt'))
+          .writeAsStringSync('irrelevant');
+      fileSystem.directory('/origin/nested').createSync();
+      fileSystem
+          .file(fileSystem.path.join('origin', 'nested', 'a.txt'))
+          .writeAsStringSync('irrelevant');
+      fileSystem
+          .file(fileSystem.path.join('origin', 'nested', 'b.txt'))
+          .writeAsStringSync('irrelevant');
+
+      final Directory destination = fileSystem.directory('/destination');
+      copyDirectory(origin, destination,
+          shouldCopyDirectory: (Directory directory) {
+        return !directory.path.endsWith('nested');
+      });
+
+      expect(destination, exists);
+      expect(destination.childDirectory('nested'), isNot(exists));
+      expect(destination.childDirectory('nested').childFile('b.txt'),
+          isNot(exists));
+    });
+  });
+
+  group('LocalFileSystem', () {
+    late FakeProcessSignal fakeSignal;
+    late ProcessSignal signalUnderTest;
+
+    setUp(() {
+      fakeSignal = FakeProcessSignal();
+      signalUnderTest = ProcessSignal(fakeSignal);
+    });
+
+    testWithoutContext('runs shutdown hooks', () async {
+      final Signals signals = Signals.test();
+      final LocalFileSystem localFileSystem = LocalFileSystem.test(
+        signals: signals,
+      );
+      final Directory temp = localFileSystem.systemTempDirectory;
+
+      expect(temp.existsSync(), isTrue);
+      expect(localFileSystem.shutdownHooks.registeredHooks, hasLength(1));
+      final BufferLogger logger = BufferLogger.test();
+      await localFileSystem.shutdownHooks.runShutdownHooks(logger);
+      expect(temp.existsSync(), isFalse);
+      expect(logger.traceText, contains('Running 1 shutdown hook'));
+    });
+
+    testWithoutContext('deletes system temp entry on a fatal signal', () async {
+      final Completer<void> completer = Completer<void>();
+      final Signals signals = Signals.test();
+      final LocalFileSystem localFileSystem = LocalFileSystem.test(
+        signals: signals,
+        fatalSignals: <ProcessSignal>[signalUnderTest],
+      );
+      final Directory temp = localFileSystem.systemTempDirectory;
+
+      signals.addHandler(signalUnderTest, (ProcessSignal s) {
+        completer.complete();
+      });
+
+      expect(temp.existsSync(), isTrue);
+
+      fakeSignal.controller.add(fakeSignal);
+      await completer.future;
+
+      expect(temp.existsSync(), isFalse);
+    });
+
+    testWithoutContext('throwToolExit when temp not found', () async {
+      final Signals signals = Signals.test();
+      final LocalFileSystemFake localFileSystem = LocalFileSystemFake.test(
+        signals: signals,
+      );
+
+      try {
+        localFileSystem.systemTempDirectory;
+        fail('expected tool exit');
+      } on ToolExit catch (e) {
+        expect(
+            e.message,
+            'Your system temp directory (/does_not_exist) does not exist. '
+            'Did you set an invalid override in your environment? '
+            'See issue https://github.com/flutter/flutter/issues/74042 for more context.');
+      }
+    });
+  });
+}
+
+class FakeProcessSignal extends Fake implements io.ProcessSignal {
+  final StreamController<io.ProcessSignal> controller =
+      StreamController<io.ProcessSignal>();
+
+  @override
+  Stream<io.ProcessSignal> watch() => controller.stream;
+}
+
+/// Various convenience file system methods.
+class FileSystemUtils {
+  FileSystemUtils({
+    required FileSystem fileSystem,
+  }) : _fileSystem = fileSystem;
+
+  final FileSystem _fileSystem;
+
+  /// Appends a number to a filename in order to make it unique under a
+  /// directory.
+  File getUniqueFile(Directory dir, String baseName, String ext) {
+    final FileSystem fs = dir.fileSystem;
+    int i = 1;
+
+    while (true) {
+      final String name = '${baseName}_${i.toString().padLeft(2, '0')}.$ext';
+      final File file = fs.file(dir.fileSystem.path.join(dir.path, name));
+      if (!file.existsSync()) {
+        file.createSync(recursive: true);
+        return file;
+      }
+      i += 1;
+    }
+  }
+
+  // /// Appends a number to a filename in order to make it unique under a
+  // /// directory.
+  // File getUniqueFile(Directory dir, String baseName, String ext) {
+  //   return _getUniqueFile(dir, baseName, ext);
+  // }
+
+  /// Appends a number to a directory name in order to make it unique under a
+  /// directory.
+  Directory getUniqueDirectory(Directory dir, String baseName) {
+    final FileSystem fs = dir.fileSystem;
+    int i = 1;
+
+    while (true) {
+      final String name = '${baseName}_${i.toString().padLeft(2, '0')}';
+      final Directory directory =
+          fs.directory(_fileSystem.path.join(dir.path, name));
+      if (!directory.existsSync()) {
+        return directory;
+      }
+      i += 1;
+    }
+  }
+
+  /// Escapes [path].
+  ///
+  /// On Windows it replaces all '\' with '\\'. On other platforms, it returns the
+  /// path unchanged.
+  String escapePath(String path) =>
+      isWindows ? path.replaceAll(r'\', r'\\') : path;
+
+  /// Returns true if the file system [entity] has not been modified since the
+  /// latest modification to [referenceFile].
+  ///
+  /// Returns true, if [entity] does not exist.
+  ///
+  /// Returns false, if [entity] exists, but [referenceFile] does not.
+  bool isOlderThanReference({
+    required FileSystemEntity entity,
+    required File referenceFile,
+  }) {
+    if (!entity.existsSync()) {
+      return true;
+    }
+    return referenceFile.existsSync() &&
+        referenceFile.statSync().modified.isAfter(entity.statSync().modified);
+  }
+}
+
+/// Creates `destDir` if needed, then recursively copies `srcDir` to
+/// `destDir`, invoking [onFileCopied], if specified, for each
+/// source/destination file pair.
+///
+/// Skips files if [shouldCopyFile] returns `false`.
+/// Does not recurse over directories if [shouldCopyDirectory] returns `false`.
+void copyDirectory(
+  Directory srcDir,
+  Directory destDir, {
+  bool Function(File srcFile, File destFile)? shouldCopyFile,
+  bool Function(Directory)? shouldCopyDirectory,
+  void Function(File srcFile, File destFile)? onFileCopied,
+}) {
+  if (!srcDir.existsSync()) {
+    throw Exception(
+        'Source directory "${srcDir.path}" does not exist, nothing to copy');
+  }
+
+  if (!destDir.existsSync()) {
+    destDir.createSync(recursive: true);
+  }
+
+  for (final FileSystemEntity entity in srcDir.listSync()) {
+    final String newPath =
+        destDir.fileSystem.path.join(destDir.path, entity.basename);
+    if (entity is Link) {
+      final Link newLink = destDir.fileSystem.link(newPath);
+      newLink.createSync(entity.targetSync());
+    } else if (entity is File) {
+      final File newFile = destDir.fileSystem.file(newPath);
+      if (shouldCopyFile != null && !shouldCopyFile(entity, newFile)) {
+        continue;
+      }
+      newFile.writeAsBytesSync(entity.readAsBytesSync());
+      onFileCopied?.call(entity, newFile);
+    } else if (entity is Directory) {
+      if (shouldCopyDirectory != null && !shouldCopyDirectory(entity)) {
+        continue;
+      }
+      copyDirectory(
+        entity,
+        destDir.fileSystem.directory(newPath),
+        shouldCopyFile: shouldCopyFile,
+        onFileCopied: onFileCopied,
+      );
+    } else {
+      throw Exception(
+          '${entity.path} is neither File nor Directory, was ${entity.runtimeType}');
+    }
+  }
+}
diff --git a/packages/flutter_migrate/test/base/io_test.dart b/packages/flutter_migrate/test/base/io_test.dart
new file mode 100644
index 0000000..608715e
--- /dev/null
+++ b/packages/flutter_migrate/test/base/io_test.dart
@@ -0,0 +1,86 @@
+// Copyright 2013 The Flutter 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' as io;
+
+import 'package:file/memory.dart';
+import 'package:flutter_migrate/src/base/io.dart';
+import 'package:test/fake.dart';
+
+import '../src/common.dart';
+import '../src/io.dart';
+
+void main() {
+  testWithoutContext('IOOverrides can inject a memory file system', () async {
+    final MemoryFileSystem memoryFileSystem = MemoryFileSystem.test();
+    final FlutterIOOverrides flutterIOOverrides =
+        FlutterIOOverrides(fileSystem: memoryFileSystem);
+    await io.IOOverrides.runWithIOOverrides(() async {
+      // statics delegate correctly.
+      expect(io.FileSystemEntity.isWatchSupported,
+          memoryFileSystem.isWatchSupported);
+      expect(io.Directory.systemTemp.path,
+          memoryFileSystem.systemTempDirectory.path);
+
+      // can create and write to files/directories sync.
+      final io.File file = io.File('abc');
+      file.writeAsStringSync('def');
+      final io.Directory directory = io.Directory('foobar');
+      directory.createSync();
+
+      expect(memoryFileSystem.file('abc').existsSync(), true);
+      expect(memoryFileSystem.file('abc').readAsStringSync(), 'def');
+      expect(memoryFileSystem.directory('foobar').existsSync(), true);
+
+      // can create and write to files/directories async.
+      final io.File fileB = io.File('xyz');
+      await fileB.writeAsString('def');
+      final io.Directory directoryB = io.Directory('barfoo');
+      await directoryB.create();
+
+      expect(memoryFileSystem.file('xyz').existsSync(), true);
+      expect(memoryFileSystem.file('xyz').readAsStringSync(), 'def');
+      expect(memoryFileSystem.directory('barfoo').existsSync(), true);
+
+      // Links
+      final io.Link linkA = io.Link('hhh');
+      final io.Link linkB = io.Link('ggg');
+      io.File('jjj').createSync();
+      io.File('lll').createSync();
+      await linkA.create('jjj');
+      linkB.createSync('lll');
+
+      expect(await memoryFileSystem.link('hhh').resolveSymbolicLinks(),
+          await linkA.resolveSymbolicLinks());
+      expect(memoryFileSystem.link('ggg').resolveSymbolicLinksSync(),
+          linkB.resolveSymbolicLinksSync());
+    }, flutterIOOverrides);
+  });
+
+  testWithoutContext('ProcessSignal signals are properly delegated', () async {
+    final FakeProcessSignal signal = FakeProcessSignal();
+    final ProcessSignal signalUnderTest = ProcessSignal(signal);
+
+    signal.controller.add(signal);
+
+    expect(signalUnderTest, await signalUnderTest.watch().first);
+  });
+
+  testWithoutContext('ProcessSignal toString() works', () async {
+    expect(io.ProcessSignal.sigint.toString(), ProcessSignal.sigint.toString());
+  });
+
+  testWithoutContext('test_api defines the Declarer in a known place', () {
+    expect(Zone.current[#test.declarer], isNotNull);
+  });
+}
+
+class FakeProcessSignal extends Fake implements io.ProcessSignal {
+  final StreamController<io.ProcessSignal> controller =
+      StreamController<io.ProcessSignal>();
+
+  @override
+  Stream<io.ProcessSignal> watch() => controller.stream;
+}
diff --git a/packages/flutter_migrate/test/base/logger_test.dart b/packages/flutter_migrate/test/base/logger_test.dart
new file mode 100644
index 0000000..da05522
--- /dev/null
+++ b/packages/flutter_migrate/test/base/logger_test.dart
@@ -0,0 +1,679 @@
+// Copyright 2013 The Flutter 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:flutter_migrate/src/base/io.dart';
+import 'package:flutter_migrate/src/base/logger.dart';
+import 'package:flutter_migrate/src/base/terminal.dart';
+import 'package:test/fake.dart';
+
+import '../src/common.dart';
+import '../src/fakes.dart';
+
+// final Platform _kNoAnsiPlatform = FakePlatform();
+final String red = RegExp.escape(AnsiTerminal.red);
+final String bold = RegExp.escape(AnsiTerminal.bold);
+final String resetBold = RegExp.escape(AnsiTerminal.resetBold);
+final String resetColor = RegExp.escape(AnsiTerminal.resetColor);
+
+void main() {
+  testWithoutContext('correct logger instance is created', () {
+    final LoggerFactory loggerFactory = LoggerFactory(
+      terminal: Terminal.test(),
+      stdio: FakeStdio(),
+      outputPreferences: OutputPreferences.test(),
+    );
+
+    expect(
+        loggerFactory.createLogger(
+          windows: false,
+        ),
+        isA<StdoutLogger>());
+    expect(
+        loggerFactory.createLogger(
+          windows: true,
+        ),
+        isA<WindowsStdoutLogger>());
+  });
+
+  testWithoutContext(
+      'WindowsStdoutLogger rewrites emojis when terminal does not support emoji',
+      () {
+    final FakeStdio stdio = FakeStdio();
+    final WindowsStdoutLogger logger = WindowsStdoutLogger(
+      outputPreferences: OutputPreferences.test(),
+      stdio: stdio,
+      terminal: Terminal.test(supportsColor: false, supportsEmoji: false),
+    );
+
+    logger.printStatus('🔥🖼️✗✓🔨💪✏️');
+
+    expect(stdio.writtenToStdout, <String>['X√\n']);
+  });
+
+  testWithoutContext(
+      'WindowsStdoutLogger does not rewrite emojis when terminal does support emoji',
+      () {
+    final FakeStdio stdio = FakeStdio();
+    final WindowsStdoutLogger logger = WindowsStdoutLogger(
+      outputPreferences: OutputPreferences.test(),
+      stdio: stdio,
+      terminal: Terminal.test(supportsColor: true, supportsEmoji: true),
+    );
+
+    logger.printStatus('🔥🖼️✗✓🔨💪✏️');
+
+    expect(stdio.writtenToStdout, <String>['🔥🖼️✗✓🔨💪✏️\n']);
+  });
+  testWithoutContext(
+      'Logger does not throw when stdio write throws synchronously', () async {
+    final FakeStdout stdout = FakeStdout(syncError: true);
+    final FakeStdout stderr = FakeStdout(syncError: true);
+    final Stdio stdio = Stdio.test(stdout: stdout, stderr: stderr);
+    final Logger logger = StdoutLogger(
+      terminal: AnsiTerminal(
+        stdio: stdio,
+      ),
+      stdio: stdio,
+      outputPreferences: OutputPreferences.test(),
+    );
+
+    logger.printStatus('message');
+    logger.printError('error message');
+  });
+
+  testWithoutContext(
+      'Logger does not throw when stdio write throws asynchronously', () async {
+    final FakeStdout stdout = FakeStdout(syncError: false);
+    final FakeStdout stderr = FakeStdout(syncError: false);
+    final Stdio stdio = Stdio.test(stdout: stdout, stderr: stderr);
+    final Logger logger = StdoutLogger(
+      terminal: AnsiTerminal(
+        stdio: stdio,
+      ),
+      stdio: stdio,
+      outputPreferences: OutputPreferences.test(),
+    );
+    logger.printStatus('message');
+    logger.printError('error message');
+
+    await stdout.done;
+    await stderr.done;
+  });
+
+  testWithoutContext(
+      'Logger does not throw when stdio completes done with an error',
+      () async {
+    final FakeStdout stdout =
+        FakeStdout(syncError: false, completeWithError: true);
+    final FakeStdout stderr =
+        FakeStdout(syncError: false, completeWithError: true);
+    final Stdio stdio = Stdio.test(stdout: stdout, stderr: stderr);
+    final Logger logger = StdoutLogger(
+      terminal: AnsiTerminal(
+        stdio: stdio,
+      ),
+      stdio: stdio,
+      outputPreferences: OutputPreferences.test(),
+    );
+    logger.printStatus('message');
+    logger.printError('error message');
+
+    expect(() async => stdout.done, throwsException);
+    expect(() async => stderr.done, throwsException);
+  });
+
+  group('Output format', () {
+    late FakeStdio fakeStdio;
+    late SummaryStatus summaryStatus;
+    late int called;
+
+    setUp(() {
+      fakeStdio = FakeStdio();
+      called = 0;
+      summaryStatus = SummaryStatus(
+        message: 'Hello world',
+        padding: 20,
+        onFinish: () => called++,
+        stdio: fakeStdio,
+        stopwatch: FakeStopwatch(),
+      );
+    });
+
+    List<String> outputStdout() => fakeStdio.writtenToStdout.join().split('\n');
+    List<String> outputStderr() => fakeStdio.writtenToStderr.join().split('\n');
+
+    testWithoutContext('Error logs are wrapped', () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(wrapText: true, wrapColumn: 40),
+      );
+      logger.printError('0123456789' * 15);
+      final List<String> lines = outputStderr();
+
+      expect(outputStdout().length, equals(1));
+      expect(outputStdout().first, isEmpty);
+      expect(lines[0], equals('0123456789' * 4));
+      expect(lines[1], equals('0123456789' * 4));
+      expect(lines[2], equals('0123456789' * 4));
+      expect(lines[3], equals('0123456789' * 3));
+    });
+
+    testWithoutContext('Error logs are wrapped and can be indented.', () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(wrapText: true, wrapColumn: 40),
+      );
+      logger.printError('0123456789' * 15, indent: 5);
+      final List<String> lines = outputStderr();
+
+      expect(outputStdout().length, equals(1));
+      expect(outputStdout().first, isEmpty);
+      expect(lines.length, equals(6));
+      expect(lines[0], equals('     01234567890123456789012345678901234'));
+      expect(lines[1], equals('     56789012345678901234567890123456789'));
+      expect(lines[2], equals('     01234567890123456789012345678901234'));
+      expect(lines[3], equals('     56789012345678901234567890123456789'));
+      expect(lines[4], equals('     0123456789'));
+      expect(lines[5], isEmpty);
+    });
+
+    testWithoutContext('Error logs are wrapped and can have hanging indent.',
+        () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(wrapText: true, wrapColumn: 40),
+      );
+      logger.printError('0123456789' * 15, hangingIndent: 5);
+      final List<String> lines = outputStderr();
+
+      expect(outputStdout().length, equals(1));
+      expect(outputStdout().first, isEmpty);
+      expect(lines.length, equals(6));
+      expect(lines[0], equals('0123456789012345678901234567890123456789'));
+      expect(lines[1], equals('     01234567890123456789012345678901234'));
+      expect(lines[2], equals('     56789012345678901234567890123456789'));
+      expect(lines[3], equals('     01234567890123456789012345678901234'));
+      expect(lines[4], equals('     56789'));
+      expect(lines[5], isEmpty);
+    });
+
+    testWithoutContext(
+        'Error logs are wrapped, indented, and can have hanging indent.',
+        () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(wrapText: true, wrapColumn: 40),
+      );
+      logger.printError('0123456789' * 15, indent: 4, hangingIndent: 5);
+      final List<String> lines = outputStderr();
+
+      expect(outputStdout().length, equals(1));
+      expect(outputStdout().first, isEmpty);
+      expect(lines.length, equals(6));
+      expect(lines[0], equals('    012345678901234567890123456789012345'));
+      expect(lines[1], equals('         6789012345678901234567890123456'));
+      expect(lines[2], equals('         7890123456789012345678901234567'));
+      expect(lines[3], equals('         8901234567890123456789012345678'));
+      expect(lines[4], equals('         901234567890123456789'));
+      expect(lines[5], isEmpty);
+    });
+
+    testWithoutContext('Stdout logs are wrapped', () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(wrapText: true, wrapColumn: 40),
+      );
+      logger.printStatus('0123456789' * 15);
+      final List<String> lines = outputStdout();
+
+      expect(outputStderr().length, equals(1));
+      expect(outputStderr().first, isEmpty);
+      expect(lines[0], equals('0123456789' * 4));
+      expect(lines[1], equals('0123456789' * 4));
+      expect(lines[2], equals('0123456789' * 4));
+      expect(lines[3], equals('0123456789' * 3));
+    });
+
+    testWithoutContext('Stdout logs are wrapped and can be indented.',
+        () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(wrapText: true, wrapColumn: 40),
+      );
+      logger.printStatus('0123456789' * 15, indent: 5);
+      final List<String> lines = outputStdout();
+
+      expect(outputStderr().length, equals(1));
+      expect(outputStderr().first, isEmpty);
+      expect(lines.length, equals(6));
+      expect(lines[0], equals('     01234567890123456789012345678901234'));
+      expect(lines[1], equals('     56789012345678901234567890123456789'));
+      expect(lines[2], equals('     01234567890123456789012345678901234'));
+      expect(lines[3], equals('     56789012345678901234567890123456789'));
+      expect(lines[4], equals('     0123456789'));
+      expect(lines[5], isEmpty);
+    });
+
+    testWithoutContext('Stdout logs are wrapped and can have hanging indent.',
+        () async {
+      final Logger logger = StdoutLogger(
+          terminal: AnsiTerminal(
+            stdio: fakeStdio,
+          ),
+          stdio: fakeStdio,
+          outputPreferences:
+              OutputPreferences.test(wrapText: true, wrapColumn: 40));
+      logger.printStatus('0123456789' * 15, hangingIndent: 5);
+      final List<String> lines = outputStdout();
+
+      expect(outputStderr().length, equals(1));
+      expect(outputStderr().first, isEmpty);
+      expect(lines.length, equals(6));
+      expect(lines[0], equals('0123456789012345678901234567890123456789'));
+      expect(lines[1], equals('     01234567890123456789012345678901234'));
+      expect(lines[2], equals('     56789012345678901234567890123456789'));
+      expect(lines[3], equals('     01234567890123456789012345678901234'));
+      expect(lines[4], equals('     56789'));
+      expect(lines[5], isEmpty);
+    });
+
+    testWithoutContext(
+        'Stdout logs are wrapped, indented, and can have hanging indent.',
+        () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(wrapText: true, wrapColumn: 40),
+      );
+      logger.printStatus('0123456789' * 15, indent: 4, hangingIndent: 5);
+      final List<String> lines = outputStdout();
+
+      expect(outputStderr().length, equals(1));
+      expect(outputStderr().first, isEmpty);
+      expect(lines.length, equals(6));
+      expect(lines[0], equals('    012345678901234567890123456789012345'));
+      expect(lines[1], equals('         6789012345678901234567890123456'));
+      expect(lines[2], equals('         7890123456789012345678901234567'));
+      expect(lines[3], equals('         8901234567890123456789012345678'));
+      expect(lines[4], equals('         901234567890123456789'));
+      expect(lines[5], isEmpty);
+    });
+
+    testWithoutContext('Error logs are red', () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+          supportsColor: true,
+        ),
+        stdio: fakeStdio,
+        outputPreferences: OutputPreferences.test(showColor: true),
+      );
+      logger.printError('Pants on fire!');
+      final List<String> lines = outputStderr();
+
+      expect(outputStdout().length, equals(1));
+      expect(outputStdout().first, isEmpty);
+      expect(
+          lines[0],
+          equals(
+              '${AnsiTerminal.red}Pants on fire!${AnsiTerminal.resetColor}'));
+    });
+
+    testWithoutContext('Stdout logs are not colored', () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences: OutputPreferences.test(showColor: true),
+      );
+      logger.printStatus('All good.');
+
+      final List<String> lines = outputStdout();
+      expect(outputStderr().length, equals(1));
+      expect(outputStderr().first, isEmpty);
+      expect(lines[0], equals('All good.'));
+    });
+
+    testWithoutContext('Stdout printBox puts content inside a box', () {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences: OutputPreferences.test(showColor: true),
+      );
+      logger.printBox('Hello world', title: 'Test title');
+      final String stdout = fakeStdio.writtenToStdout.join();
+      expect(
+        stdout,
+        contains('\n'
+            '┌─ Test title ┐\n'
+            '│ Hello world │\n'
+            '└─────────────┘\n'),
+      );
+    });
+
+    testWithoutContext('Stdout printBox does not require title', () {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences: OutputPreferences.test(showColor: true),
+      );
+      logger.printBox('Hello world');
+      final String stdout = fakeStdio.writtenToStdout.join();
+      expect(
+        stdout,
+        contains('\n'
+            '┌─────────────┐\n'
+            '│ Hello world │\n'
+            '└─────────────┘\n'),
+      );
+    });
+
+    testWithoutContext('Stdout printBox handles new lines', () {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences: OutputPreferences.test(showColor: true),
+      );
+      logger.printBox('Hello world\nThis is a new line', title: 'Test title');
+      final String stdout = fakeStdio.writtenToStdout.join();
+      expect(
+        stdout,
+        contains('\n'
+            '┌─ Test title ───────┐\n'
+            '│ Hello world        │\n'
+            '│ This is a new line │\n'
+            '└────────────────────┘\n'),
+      );
+    });
+
+    testWithoutContext(
+        'Stdout printBox handles content with ANSI escape characters', () {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences: OutputPreferences.test(showColor: true),
+      );
+      const String bold = '\u001B[1m';
+      const String clear = '\u001B[2J\u001B[H';
+      logger.printBox('${bold}Hello world$clear', title: 'Test title');
+      final String stdout = fakeStdio.writtenToStdout.join();
+      expect(
+        stdout,
+        contains('\n'
+            '┌─ Test title ┐\n'
+            '│ ${bold}Hello world$clear │\n'
+            '└─────────────┘\n'),
+      );
+    });
+
+    testWithoutContext('Stdout printBox handles column limit', () {
+      const int columnLimit = 14;
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(showColor: true, wrapColumn: columnLimit),
+      );
+      logger.printBox('This line is longer than $columnLimit characters',
+          title: 'Test');
+      final String stdout = fakeStdio.writtenToStdout.join();
+      final List<String> stdoutLines = stdout.split('\n');
+
+      expect(stdoutLines.length, greaterThan(1));
+      expect(stdoutLines[1].length, equals(columnLimit));
+      expect(
+        stdout,
+        contains('\n'
+            '┌─ Test ─────┐\n'
+            '│ This line  │\n'
+            '│ is longer  │\n'
+            '│ than 14    │\n'
+            '│ characters │\n'
+            '└────────────┘\n'),
+      );
+    });
+
+    testWithoutContext(
+        'Stdout printBox handles column limit and respects new lines', () {
+      const int columnLimit = 14;
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(showColor: true, wrapColumn: columnLimit),
+      );
+      logger.printBox('This\nline is longer than\n\n$columnLimit characters',
+          title: 'Test');
+      final String stdout = fakeStdio.writtenToStdout.join();
+      final List<String> stdoutLines = stdout.split('\n');
+
+      expect(stdoutLines.length, greaterThan(1));
+      expect(stdoutLines[1].length, equals(columnLimit));
+      expect(
+        stdout,
+        contains('\n'
+            '┌─ Test ─────┐\n'
+            '│ This       │\n'
+            '│ line is    │\n'
+            '│ longer     │\n'
+            '│ than       │\n'
+            '│            │\n'
+            '│ 14         │\n'
+            '│ characters │\n'
+            '└────────────┘\n'),
+      );
+    });
+
+    testWithoutContext(
+        'Stdout printBox breaks long words that exceed the column limit', () {
+      const int columnLimit = 14;
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences:
+            OutputPreferences.test(showColor: true, wrapColumn: columnLimit),
+      );
+      logger.printBox('Thiswordislongerthan${columnLimit}characters',
+          title: 'Test');
+      final String stdout = fakeStdio.writtenToStdout.join();
+      final List<String> stdoutLines = stdout.split('\n');
+
+      expect(stdoutLines.length, greaterThan(1));
+      expect(stdoutLines[1].length, equals(columnLimit));
+      expect(
+        stdout,
+        contains('\n'
+            '┌─ Test ─────┐\n'
+            '│ Thiswordis │\n'
+            '│ longerthan │\n'
+            '│ 14characte │\n'
+            '│ rs         │\n'
+            '└────────────┘\n'),
+      );
+    });
+
+    testWithoutContext('Stdout startProgress on non-color terminal', () async {
+      final FakeStopwatch fakeStopwatch = FakeStopwatch();
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences: OutputPreferences.test(),
+        stopwatchFactory: FakeStopwatchFactory(stopwatch: fakeStopwatch),
+      );
+      final Status status = logger.startProgress(
+        'Hello',
+        progressIndicatorPadding:
+            20, // this minus the "Hello" equals the 15 below.
+      );
+      expect(outputStderr().length, equals(1));
+      expect(outputStderr().first, isEmpty);
+      // the 5 below is the margin that is always included between the message and the time.
+      expect(outputStdout().join('\n'), matches(r'^Hello {15} {5}$'));
+
+      fakeStopwatch.elapsed = const Duration(seconds: 4, milliseconds: 123);
+      status.stop();
+
+      expect(outputStdout(), <String>['Hello                        4.1s', '']);
+    });
+
+    testWithoutContext('SummaryStatus works when canceled', () async {
+      final SummaryStatus summaryStatus = SummaryStatus(
+        message: 'Hello world',
+        padding: 20,
+        onFinish: () => called++,
+        stdio: fakeStdio,
+        stopwatch: FakeStopwatch(),
+      );
+      summaryStatus.start();
+      final List<String> lines = outputStdout();
+      expect(lines[0], startsWith('Hello world              '));
+      expect(lines.length, equals(1));
+      expect(lines[0].endsWith('\n'), isFalse);
+
+      // Verify a cancel does _not_ print the time and prints a newline.
+      summaryStatus.cancel();
+      expect(outputStdout(), <String>[
+        'Hello world              ',
+        '',
+      ]);
+
+      // Verify that stopping or canceling multiple times throws.
+      expect(summaryStatus.cancel, throwsAssertionError);
+      expect(summaryStatus.stop, throwsAssertionError);
+    });
+
+    testWithoutContext('SummaryStatus works when stopped', () async {
+      summaryStatus.start();
+      final List<String> lines = outputStdout();
+      expect(lines[0], startsWith('Hello world              '));
+      expect(lines.length, equals(1));
+
+      // Verify a stop prints the time.
+      summaryStatus.stop();
+      expect(outputStdout(), <String>[
+        'Hello world                   0ms',
+        '',
+      ]);
+
+      // Verify that stopping or canceling multiple times throws.
+      expect(summaryStatus.stop, throwsAssertionError);
+      expect(summaryStatus.cancel, throwsAssertionError);
+    });
+
+    testWithoutContext('sequential startProgress calls with StdoutLogger',
+        () async {
+      final Logger logger = StdoutLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        stdio: fakeStdio,
+        outputPreferences: OutputPreferences.test(),
+      );
+      logger.startProgress('AAA').stop();
+      logger.startProgress('BBB').stop();
+      final List<String> output = outputStdout();
+
+      expect(output.length, equals(3));
+
+      // There's 61 spaces at the start: 59 (padding default) - 3 (length of AAA) + 5 (margin).
+      // Then there's a left-padded "0ms" 8 characters wide, so 5 spaces then "0ms"
+      // (except sometimes it's randomly slow so we handle up to "99,999ms").
+      expect(output[0], matches(RegExp(r'AAA[ ]{61}[\d, ]{5}[\d]ms')));
+      expect(output[1], matches(RegExp(r'BBB[ ]{61}[\d, ]{5}[\d]ms')));
+    });
+
+    testWithoutContext('sequential startProgress calls with BufferLogger',
+        () async {
+      final BufferLogger logger = BufferLogger(
+        terminal: AnsiTerminal(
+          stdio: fakeStdio,
+        ),
+        outputPreferences: OutputPreferences.test(),
+      );
+      logger.startProgress('AAA').stop();
+      logger.startProgress('BBB').stop();
+
+      expect(logger.statusText, 'AAA\nBBB\n');
+    });
+  });
+}
+
+/// A fake [Logger] that throws the [Invocation] for any method call.
+class FakeLogger implements Logger {
+  @override
+  dynamic noSuchMethod(Invocation invocation) =>
+      throw invocation; // ignore: only_throw_errors
+}
+
+class FakeStdout extends Fake implements Stdout {
+  FakeStdout({required this.syncError, this.completeWithError = false});
+
+  final bool syncError;
+  final bool completeWithError;
+  final Completer<void> _completer = Completer<void>();
+
+  @override
+  void write(Object? object) {
+    if (syncError) {
+      throw Exception('Error!');
+    }
+    Zone.current.runUnaryGuarded<void>((_) {
+      if (completeWithError) {
+        _completer.completeError(Exception('Some pipe error'));
+      } else {
+        _completer.complete();
+        throw Exception('Error!');
+      }
+    }, null);
+  }
+
+  @override
+  Future<void> get done => _completer.future;
+}
diff --git a/packages/flutter_migrate/test/base/signals_test.dart b/packages/flutter_migrate/test/base/signals_test.dart
new file mode 100644
index 0000000..87f0d04
--- /dev/null
+++ b/packages/flutter_migrate/test/base/signals_test.dart
@@ -0,0 +1,181 @@
+// Copyright 2013 The Flutter 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' as io;
+
+import 'package:flutter_migrate/src/base/io.dart';
+import 'package:flutter_migrate/src/base/signals.dart';
+import 'package:test/fake.dart';
+
+import '../src/common.dart';
+
+void main() {
+  group('Signals', () {
+    late Signals signals;
+    late FakeProcessSignal fakeSignal;
+    late ProcessSignal signalUnderTest;
+
+    setUp(() {
+      signals = Signals.test();
+      fakeSignal = FakeProcessSignal();
+      signalUnderTest = ProcessSignal(fakeSignal);
+    });
+
+    testWithoutContext('signal handler runs', () async {
+      final Completer<void> completer = Completer<void>();
+      signals.addHandler(signalUnderTest, (ProcessSignal s) {
+        expect(s, signalUnderTest);
+        completer.complete();
+      });
+
+      fakeSignal.controller.add(fakeSignal);
+      await completer.future;
+    });
+
+    testWithoutContext('signal handlers run in order', () async {
+      final Completer<void> completer = Completer<void>();
+
+      bool first = false;
+
+      signals.addHandler(signalUnderTest, (ProcessSignal s) {
+        expect(s, signalUnderTest);
+        first = true;
+      });
+
+      signals.addHandler(signalUnderTest, (ProcessSignal s) {
+        expect(s, signalUnderTest);
+        expect(first, isTrue);
+        completer.complete();
+      });
+
+      fakeSignal.controller.add(fakeSignal);
+      await completer.future;
+    });
+
+    testWithoutContext(
+        'signal handlers do not cause concurrent modification errors when removing handlers in a signal callback',
+        () async {
+      final Completer<void> completer = Completer<void>();
+      late Object token;
+      Future<void> handle(ProcessSignal s) async {
+        expect(s, signalUnderTest);
+        expect(await signals.removeHandler(signalUnderTest, token), true);
+        completer.complete();
+      }
+
+      token = signals.addHandler(signalUnderTest, handle);
+
+      fakeSignal.controller.add(fakeSignal);
+      await completer.future;
+    });
+
+    testWithoutContext('signal handler error goes on error stream', () async {
+      final Exception exn = Exception('Error');
+      signals.addHandler(signalUnderTest, (ProcessSignal s) async {
+        throw exn;
+      });
+
+      final Completer<void> completer = Completer<void>();
+      final List<Object> errList = <Object>[];
+      final StreamSubscription<Object> errSub = signals.errors.listen(
+        (Object err) {
+          errList.add(err);
+          completer.complete();
+        },
+      );
+
+      fakeSignal.controller.add(fakeSignal);
+      await completer.future;
+      await errSub.cancel();
+      expect(errList, contains(exn));
+    });
+
+    testWithoutContext('removed signal handler does not run', () async {
+      final Object token = signals.addHandler(
+        signalUnderTest,
+        (ProcessSignal s) async {
+          fail('Signal handler should have been removed.');
+        },
+      );
+
+      await signals.removeHandler(signalUnderTest, token);
+
+      final List<Object> errList = <Object>[];
+      final StreamSubscription<Object> errSub = signals.errors.listen(
+        (Object err) {
+          errList.add(err);
+        },
+      );
+
+      fakeSignal.controller.add(fakeSignal);
+
+      await errSub.cancel();
+      expect(errList, isEmpty);
+    });
+
+    testWithoutContext('non-removed signal handler still runs', () async {
+      final Completer<void> completer = Completer<void>();
+      signals.addHandler(signalUnderTest, (ProcessSignal s) {
+        expect(s, signalUnderTest);
+        completer.complete();
+      });
+
+      final Object token = signals.addHandler(
+        signalUnderTest,
+        (ProcessSignal s) async {
+          fail('Signal handler should have been removed.');
+        },
+      );
+      await signals.removeHandler(signalUnderTest, token);
+
+      final List<Object> errList = <Object>[];
+      final StreamSubscription<Object> errSub = signals.errors.listen(
+        (Object err) {
+          errList.add(err);
+        },
+      );
+
+      fakeSignal.controller.add(fakeSignal);
+      await completer.future;
+      await errSub.cancel();
+      expect(errList, isEmpty);
+    });
+
+    testWithoutContext('only handlers for the correct signal run', () async {
+      final FakeProcessSignal mockSignal2 = FakeProcessSignal();
+      final ProcessSignal otherSignal = ProcessSignal(mockSignal2);
+
+      final Completer<void> completer = Completer<void>();
+      signals.addHandler(signalUnderTest, (ProcessSignal s) {
+        expect(s, signalUnderTest);
+        completer.complete();
+      });
+
+      signals.addHandler(otherSignal, (ProcessSignal s) async {
+        fail('Wrong signal!.');
+      });
+
+      final List<Object> errList = <Object>[];
+      final StreamSubscription<Object> errSub = signals.errors.listen(
+        (Object err) {
+          errList.add(err);
+        },
+      );
+
+      fakeSignal.controller.add(fakeSignal);
+      await completer.future;
+      await errSub.cancel();
+      expect(errList, isEmpty);
+    });
+  });
+}
+
+class FakeProcessSignal extends Fake implements io.ProcessSignal {
+  final StreamController<io.ProcessSignal> controller =
+      StreamController<io.ProcessSignal>();
+
+  @override
+  Stream<io.ProcessSignal> watch() => controller.stream;
+}
diff --git a/packages/flutter_migrate/test/base/terminal_test.dart b/packages/flutter_migrate/test/base/terminal_test.dart
new file mode 100644
index 0000000..6686ec2
--- /dev/null
+++ b/packages/flutter_migrate/test/base/terminal_test.dart
@@ -0,0 +1,331 @@
+// Copyright 2013 The Flutter 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 'package:flutter_migrate/src/base/io.dart';
+import 'package:flutter_migrate/src/base/logger.dart';
+import 'package:flutter_migrate/src/base/terminal.dart';
+import 'package:test/fake.dart';
+
+import '../src/common.dart';
+
+void main() {
+  group('output preferences', () {
+    testWithoutContext('can wrap output', () async {
+      final BufferLogger bufferLogger = BufferLogger(
+        outputPreferences:
+            OutputPreferences.test(wrapText: true, wrapColumn: 40),
+        terminal: TestTerminal(),
+      );
+      bufferLogger.printStatus('0123456789' * 8);
+
+      expect(bufferLogger.statusText, equals(('${'0123456789' * 4}\n') * 2));
+    });
+
+    testWithoutContext('can turn off wrapping', () async {
+      final BufferLogger bufferLogger = BufferLogger(
+        outputPreferences: OutputPreferences.test(),
+        terminal: TestTerminal(),
+      );
+      final String testString = '0123456789' * 20;
+      bufferLogger.printStatus(testString);
+
+      expect(bufferLogger.statusText, equals('$testString\n'));
+    });
+  });
+
+  group('ANSI coloring and bold', () {
+    late AnsiTerminal terminal;
+
+    setUp(() {
+      terminal = AnsiTerminal(
+        stdio: Stdio(), // Danger, using real stdio.
+        supportsColor: true,
+      );
+    });
+
+    testWithoutContext('adding colors works', () {
+      for (final TerminalColor color in TerminalColor.values) {
+        expect(
+          terminal.color('output', color),
+          equals(
+              '${AnsiTerminal.colorCode(color)}output${AnsiTerminal.resetColor}'),
+        );
+      }
+    });
+
+    testWithoutContext('adding bold works', () {
+      expect(
+        terminal.bolden('output'),
+        equals('${AnsiTerminal.bold}output${AnsiTerminal.resetBold}'),
+      );
+    });
+
+    testWithoutContext('nesting bold within color works', () {
+      expect(
+        terminal.color(terminal.bolden('output'), TerminalColor.blue),
+        equals(
+            '${AnsiTerminal.blue}${AnsiTerminal.bold}output${AnsiTerminal.resetBold}${AnsiTerminal.resetColor}'),
+      );
+      expect(
+        terminal.color('non-bold ${terminal.bolden('output')} also non-bold',
+            TerminalColor.blue),
+        equals(
+            '${AnsiTerminal.blue}non-bold ${AnsiTerminal.bold}output${AnsiTerminal.resetBold} also non-bold${AnsiTerminal.resetColor}'),
+      );
+    });
+
+    testWithoutContext('nesting color within bold works', () {
+      expect(
+        terminal.bolden(terminal.color('output', TerminalColor.blue)),
+        equals(
+            '${AnsiTerminal.bold}${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.resetBold}'),
+      );
+      expect(
+        terminal.bolden(
+            'non-color ${terminal.color('output', TerminalColor.blue)} also non-color'),
+        equals(
+            '${AnsiTerminal.bold}non-color ${AnsiTerminal.blue}output${AnsiTerminal.resetColor} also non-color${AnsiTerminal.resetBold}'),
+      );
+    });
+
+    testWithoutContext('nesting color within color works', () {
+      expect(
+        terminal.color(terminal.color('output', TerminalColor.blue),
+            TerminalColor.magenta),
+        equals(
+            '${AnsiTerminal.magenta}${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.magenta}${AnsiTerminal.resetColor}'),
+      );
+      expect(
+        terminal.color(
+            'magenta ${terminal.color('output', TerminalColor.blue)} also magenta',
+            TerminalColor.magenta),
+        equals(
+            '${AnsiTerminal.magenta}magenta ${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.magenta} also magenta${AnsiTerminal.resetColor}'),
+      );
+    });
+
+    testWithoutContext('nesting bold within bold works', () {
+      expect(
+        terminal.bolden(terminal.bolden('output')),
+        equals('${AnsiTerminal.bold}output${AnsiTerminal.resetBold}'),
+      );
+      expect(
+        terminal.bolden('bold ${terminal.bolden('output')} still bold'),
+        equals(
+            '${AnsiTerminal.bold}bold output still bold${AnsiTerminal.resetBold}'),
+      );
+    });
+  });
+
+  group('character input prompt', () {
+    late AnsiTerminal terminalUnderTest;
+
+    setUp(() {
+      terminalUnderTest = TestTerminal(stdio: FakeStdio());
+    });
+
+    testWithoutContext('character prompt throws if usesTerminalUi is false',
+        () async {
+      expect(
+          terminalUnderTest.promptForCharInput(
+            <String>['a', 'b', 'c'],
+            prompt: 'Please choose something',
+            logger: BufferLogger.test(),
+          ),
+          throwsStateError);
+    });
+
+    testWithoutContext('character prompt', () async {
+      final BufferLogger bufferLogger = BufferLogger(
+        terminal: terminalUnderTest,
+        outputPreferences: OutputPreferences.test(),
+      );
+      terminalUnderTest.usesTerminalUi = true;
+      mockStdInStream = Stream<String>.fromFutures(<Future<String>>[
+        Future<String>.value('d'), // Not in accepted list.
+        Future<String>.value('\n'), // Not in accepted list
+        Future<String>.value('b'),
+      ]).asBroadcastStream();
+      final String choice = await terminalUnderTest.promptForCharInput(
+        <String>['a', 'b', 'c'],
+        prompt: 'Please choose something',
+        logger: bufferLogger,
+      );
+      expect(choice, 'b');
+      expect(
+          bufferLogger.statusText,
+          'Please choose something [a|b|c]: d\n'
+          'Please choose something [a|b|c]: \n'
+          'Please choose something [a|b|c]: b\n');
+    });
+
+    testWithoutContext(
+        'default character choice without displayAcceptedCharacters', () async {
+      final BufferLogger bufferLogger = BufferLogger(
+        terminal: terminalUnderTest,
+        outputPreferences: OutputPreferences.test(),
+      );
+      terminalUnderTest.usesTerminalUi = true;
+      mockStdInStream = Stream<String>.fromFutures(<Future<String>>[
+        Future<String>.value('\n'), // Not in accepted list
+      ]).asBroadcastStream();
+      final String choice = await terminalUnderTest.promptForCharInput(
+        <String>['a', 'b', 'c'],
+        prompt: 'Please choose something',
+        displayAcceptedCharacters: false,
+        defaultChoiceIndex: 1, // which is b.
+        logger: bufferLogger,
+      );
+
+      expect(choice, 'b');
+      expect(bufferLogger.statusText, 'Please choose something: \n');
+    });
+
+    testWithoutContext(
+        'Does not set single char mode when a terminal is not attached', () {
+      final Stdio stdio = FakeStdio()..stdinHasTerminal = false;
+      final AnsiTerminal ansiTerminal = AnsiTerminal(
+        stdio: stdio,
+      );
+
+      expect(() => ansiTerminal.singleCharMode = true, returnsNormally);
+    });
+  });
+
+  testWithoutContext('AnsiTerminal.preferredStyle', () {
+    final Stdio stdio = FakeStdio();
+    expect(AnsiTerminal(stdio: stdio).preferredStyle,
+        0); // Defaults to 0 for backwards compatibility.
+
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018)).preferredStyle, 0);
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 2)).preferredStyle,
+        1);
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 3)).preferredStyle,
+        2);
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 4)).preferredStyle,
+        3);
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 5)).preferredStyle,
+        4);
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 6)).preferredStyle,
+        5);
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 7)).preferredStyle,
+        5);
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 8)).preferredStyle,
+        0);
+    expect(AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 9)).preferredStyle,
+        1);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 10)).preferredStyle,
+        2);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 11)).preferredStyle,
+        3);
+
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 1, 1)).preferredStyle,
+        0);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 2, 1)).preferredStyle,
+        1);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 3, 1)).preferredStyle,
+        2);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 4, 1)).preferredStyle,
+        3);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 5, 1)).preferredStyle,
+        4);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 6, 1)).preferredStyle,
+        6);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 7, 1)).preferredStyle,
+        6);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 8, 1)).preferredStyle,
+        0);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 9, 1)).preferredStyle,
+        1);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 10, 1))
+            .preferredStyle,
+        2);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 11, 1))
+            .preferredStyle,
+        3);
+
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 1, 23))
+            .preferredStyle,
+        0);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 2, 23))
+            .preferredStyle,
+        1);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 3, 23))
+            .preferredStyle,
+        2);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 4, 23))
+            .preferredStyle,
+        3);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 5, 23))
+            .preferredStyle,
+        4);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 6, 23))
+            .preferredStyle,
+        28);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 7, 23))
+            .preferredStyle,
+        28);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 8, 23))
+            .preferredStyle,
+        0);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 9, 23))
+            .preferredStyle,
+        1);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 10, 23))
+            .preferredStyle,
+        2);
+    expect(
+        AnsiTerminal(stdio: stdio, now: DateTime(2018, 1, 11, 23))
+            .preferredStyle,
+        3);
+  });
+}
+
+late Stream<String> mockStdInStream;
+
+class TestTerminal extends AnsiTerminal {
+  TestTerminal({
+    Stdio? stdio,
+    DateTime? now,
+  }) : super(stdio: stdio ?? Stdio(), now: now ?? DateTime(2018));
+
+  @override
+  Stream<String> get keystrokes {
+    return mockStdInStream;
+  }
+
+  @override
+  bool singleCharMode = false;
+
+  @override
+  int get preferredStyle => 0;
+}
+
+class FakeStdio extends Fake implements Stdio {
+  @override
+  bool stdinHasTerminal = false;
+}
diff --git a/packages/flutter_migrate/test/src/common.dart b/packages/flutter_migrate/test/src/common.dart
new file mode 100644
index 0000000..40e55b0
--- /dev/null
+++ b/packages/flutter_migrate/test/src/common.dart
@@ -0,0 +1,200 @@
+// Copyright 2013 The Flutter 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' as io;
+
+import 'package:flutter_migrate/src/base/context.dart';
+import 'package:flutter_migrate/src/base/file_system.dart';
+import 'package:flutter_migrate/src/base/io.dart';
+import 'package:meta/meta.dart';
+import 'package:path/path.dart' as path; // flutter_ignore: package_path_import
+import 'package:test_api/test_api.dart' // ignore: deprecated_member_use
+    as test_package show test;
+import 'package:test_api/test_api.dart' // ignore: deprecated_member_use
+    hide
+        test;
+
+import 'test_utils.dart';
+
+export 'package:test_api/test_api.dart' // ignore: deprecated_member_use
+    hide
+        isInstanceOf,
+        test;
+
+void tryToDelete(FileSystemEntity fileEntity) {
+  // This should not be necessary, but it turns out that
+  // on Windows it's common for deletions to fail due to
+  // bogus (we think) "access denied" errors.
+  try {
+    if (fileEntity.existsSync()) {
+      fileEntity.deleteSync(recursive: true);
+    }
+  } on FileSystemException catch (error) {
+    // We print this so that it's visible in the logs, to get an idea of how
+    // common this problem is, and if any patterns are ever noticed by anyone.
+    // ignore: avoid_print
+    print('Failed to delete ${fileEntity.path}: $error');
+  }
+}
+
+/// Gets the path to the root of the Flutter repository.
+///
+/// This will first look for a `FLUTTER_ROOT` environment variable. If the
+/// environment variable is set, it will be returned. Otherwise, this will
+/// deduce the path from `platform.script`.
+String getFlutterRoot() {
+  if (io.Platform.environment.containsKey('FLUTTER_ROOT')) {
+    return io.Platform.environment['FLUTTER_ROOT']!;
+  }
+
+  Error invalidScript() => StateError(
+      'Could not determine flutter_tools/ path from script URL (${io.Platform.script}); consider setting FLUTTER_ROOT explicitly.');
+
+  Uri scriptUri;
+  switch (io.Platform.script.scheme) {
+    case 'file':
+      scriptUri = io.Platform.script;
+      break;
+    case 'data':
+      final RegExp flutterTools = RegExp(
+          r'(file://[^"]*[/\\]flutter_tools[/\\][^"]+\.dart)',
+          multiLine: true);
+      final Match? match =
+          flutterTools.firstMatch(Uri.decodeFull(io.Platform.script.path));
+      if (match == null) {
+        throw invalidScript();
+      }
+      scriptUri = Uri.parse(match.group(1)!);
+      break;
+    default:
+      throw invalidScript();
+  }
+
+  final List<String> parts = path.split(fileSystem.path.fromUri(scriptUri));
+  final int toolsIndex = parts.indexOf('flutter_tools');
+  if (toolsIndex == -1) {
+    throw invalidScript();
+  }
+  final String toolsPath = path.joinAll(parts.sublist(0, toolsIndex + 1));
+  return path.normalize(path.join(toolsPath, '..', '..'));
+}
+
+String getMigratePackageRoot() {
+  return io.Directory.current.path;
+}
+
+String getMigrateMain() {
+  return fileSystem.path
+      .join(getMigratePackageRoot(), 'bin', 'flutter_migrate.dart');
+}
+
+Future<ProcessResult> runMigrateCommand(List<String> args,
+    {String? workingDirectory}) {
+  final List<String> commandArgs = <String>['dart', 'run', getMigrateMain()];
+  commandArgs.addAll(args);
+  return processManager.run(commandArgs, workingDirectory: workingDirectory);
+}
+
+/// The tool overrides `test` to ensure that files created under the
+/// system temporary directory are deleted after each test by calling
+/// `LocalFileSystem.dispose()`.
+@isTest
+void test(
+  String description,
+  FutureOr<void> Function() body, {
+  String? testOn,
+  dynamic skip,
+  List<String>? tags,
+  Map<String, dynamic>? onPlatform,
+  int? retry,
+}) {
+  test_package.test(
+    description,
+    () async {
+      addTearDown(() async {
+        await fileSystem.dispose();
+      });
+
+      return body();
+    },
+    skip: skip,
+    tags: tags,
+    onPlatform: onPlatform,
+    retry: retry,
+    testOn: testOn,
+    // We don't support "timeout"; see ../../dart_test.yaml which
+    // configures all tests to have a 15 minute timeout which should
+    // definitely be enough.
+  );
+}
+
+/// Executes a test body in zone that does not allow context-based injection.
+///
+/// For classes which have been refactored to exclude context-based injection
+/// or globals like [fs] or [platform], prefer using this test method as it
+/// will prevent accidentally including these context getters in future code
+/// changes.
+///
+/// For more information, see https://github.com/flutter/flutter/issues/47161
+@isTest
+void testWithoutContext(
+  String description,
+  FutureOr<void> Function() body, {
+  String? testOn,
+  dynamic skip,
+  List<String>? tags,
+  Map<String, dynamic>? onPlatform,
+  int? retry,
+}) {
+  return test(
+    description,
+    () async {
+      return runZoned(body, zoneValues: <Object, Object>{
+        contextKey: const _NoContext(),
+      });
+    },
+    skip: skip,
+    tags: tags,
+    onPlatform: onPlatform,
+    retry: retry,
+    testOn: testOn,
+    // We don't support "timeout"; see ../../dart_test.yaml which
+    // configures all tests to have a 15 minute timeout which should
+    // definitely be enough.
+  );
+}
+
+/// An implementation of [AppContext] that throws if context.get is called in the test.
+///
+/// The intention of the class is to ensure we do not accidentally regress when
+/// moving towards more explicit dependency injection by accidentally using
+/// a Zone value in place of a constructor parameter.
+class _NoContext implements AppContext {
+  const _NoContext();
+
+  @override
+  T get<T>() {
+    throw UnsupportedError('context.get<$T> is not supported in test methods. '
+        'Use Testbed or testUsingContext if accessing Zone injected '
+        'values.');
+  }
+
+  @override
+  String get name => 'No Context';
+
+  @override
+  Future<V> run<V>({
+    required FutureOr<V> Function() body,
+    String? name,
+    Map<Type, Generator>? overrides,
+    Map<Type, Generator>? fallbacks,
+    ZoneSpecification? zoneSpecification,
+  }) async {
+    return body();
+  }
+}
+
+/// Matcher for functions that throw [AssertionError].
+final Matcher throwsAssertionError = throwsA(isA<AssertionError>());
diff --git a/packages/flutter_migrate/test/src/context.dart b/packages/flutter_migrate/test/src/context.dart
new file mode 100644
index 0000000..4f43b48
--- /dev/null
+++ b/packages/flutter_migrate/test/src/context.dart
@@ -0,0 +1,125 @@
+// Copyright 2013 The Flutter 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:flutter_migrate/src/base/context.dart';
+import 'package:flutter_migrate/src/base/file_system.dart';
+import 'package:flutter_migrate/src/base/logger.dart';
+import 'package:flutter_migrate/src/base/terminal.dart';
+import 'package:meta/meta.dart';
+import 'package:process/process.dart';
+
+import 'common.dart';
+import 'fakes.dart';
+
+/// Return the test logger. This assumes that the current Logger is a BufferLogger.
+BufferLogger get testLogger => context.get<Logger>()! as BufferLogger;
+
+@isTest
+void testUsingContext(
+  String description,
+  dynamic Function() testMethod, {
+  Map<Type, Generator> overrides = const <Type, Generator>{},
+  bool initializeFlutterRoot = true,
+  String? testOn,
+  bool?
+      skip, // should default to `false`, but https://github.com/dart-lang/test/issues/545 doesn't allow this
+}) {
+  if (overrides[FileSystem] != null && overrides[ProcessManager] == null) {
+    throw StateError(
+        'If you override the FileSystem context you must also provide a ProcessManager, '
+        'otherwise the processes you launch will not be dealing with the same file system '
+        'that you are dealing with in your test.');
+  }
+
+  // Ensure we don't rely on the default [Config] constructor which will
+  // leak a sticky $HOME/.flutter_settings behind!
+  Directory? configDir;
+  tearDown(() {
+    if (configDir != null) {
+      tryToDelete(configDir!);
+      configDir = null;
+    }
+  });
+
+  test(description, () async {
+    await runInContext<dynamic>(() {
+      return context.run<dynamic>(
+        name: 'mocks',
+        overrides: <Type, Generator>{
+          AnsiTerminal: () => AnsiTerminal(stdio: FakeStdio()),
+          OutputPreferences: () => OutputPreferences.test(),
+          Logger: () => BufferLogger.test(),
+          ProcessManager: () => const LocalProcessManager(),
+        },
+        body: () {
+          return runZonedGuarded<Future<dynamic>>(() {
+            try {
+              return context.run<dynamic>(
+                // Apply the overrides to the test context in the zone since their
+                // instantiation may reference items already stored on the context.
+                overrides: overrides,
+                name: 'test-specific overrides',
+                body: () async {
+                  if (initializeFlutterRoot) {
+                    // Provide a sane default for the flutterRoot directory. Individual
+                    // tests can override this either in the test or during setup.
+                    // Cache.flutterRoot ??= flutterRoot;
+                  }
+                  return await testMethod();
+                },
+              );
+              // This catch rethrows, so doesn't need to catch only Exception.
+            } catch (error) {
+              // ignore: avoid_catches_without_on_clauses
+              _printBufferedErrors(context);
+              rethrow;
+            }
+          }, (Object error, StackTrace stackTrace) {
+            // When things fail, it's ok to print to the console!
+            print(error); // ignore: avoid_print
+            print(stackTrace); // ignore: avoid_print
+            _printBufferedErrors(context);
+            throw error; //ignore: only_throw_errors
+          });
+        },
+      );
+    }, overrides: <Type, Generator>{});
+  }, testOn: testOn, skip: skip);
+  // We don't support "timeout"; see ../../dart_test.yaml which
+  // configures all tests to have a 15 minute timeout which should
+  // definitely be enough.
+}
+
+void _printBufferedErrors(AppContext testContext) {
+  if (testContext.get<Logger>() is BufferLogger) {
+    final BufferLogger bufferLogger =
+        testContext.get<Logger>()! as BufferLogger;
+    if (bufferLogger.errorText.isNotEmpty) {
+      // This is where the logger outputting errors is implemented, so it has
+      // to use `print`.
+      print(bufferLogger.errorText); // ignore: avoid_print
+    }
+    bufferLogger.clear();
+  }
+}
+
+Future<T> runInContext<T>(
+  FutureOr<T> Function() runner, {
+  Map<Type, Generator>? overrides,
+}) async {
+  // Wrap runner with any asynchronous initialization that should run with the
+  // overrides and callbacks.
+  // late bool runningOnBot;
+  FutureOr<T> runnerWrapper() async {
+    return runner();
+  }
+
+  return context.run<T>(
+      name: 'global fallbacks',
+      body: runnerWrapper,
+      overrides: overrides,
+      fallbacks: <Type, Generator>{});
+}
diff --git a/packages/flutter_migrate/test/src/fakes.dart b/packages/flutter_migrate/test/src/fakes.dart
new file mode 100644
index 0000000..3e6b072
--- /dev/null
+++ b/packages/flutter_migrate/test/src/fakes.dart
@@ -0,0 +1,285 @@
+// Copyright 2013 The Flutter 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:convert';
+import 'dart:io' as io show IOSink, Stdout, StdoutException;
+
+import 'package:flutter_migrate/src/base/io.dart';
+import 'package:flutter_migrate/src/base/logger.dart';
+import 'package:test/fake.dart';
+
+/// An IOSink that completes a future with the first line written to it.
+class CompleterIOSink extends MemoryIOSink {
+  CompleterIOSink({
+    this.throwOnAdd = false,
+  });
+
+  final bool throwOnAdd;
+
+  final Completer<List<int>> _completer = Completer<List<int>>();
+
+  Future<List<int>> get future => _completer.future;
+
+  @override
+  void add(List<int> data) {
+    if (!_completer.isCompleted) {
+      // When throwOnAdd is true, complete with empty so any expected output
+      // doesn't appear.
+      _completer.complete(throwOnAdd ? <int>[] : data);
+    }
+    if (throwOnAdd) {
+      throw Exception('CompleterIOSink Error');
+    }
+    super.add(data);
+  }
+}
+
+/// An IOSink that collects whatever is written to it.
+class MemoryIOSink implements IOSink {
+  @override
+  Encoding encoding = utf8;
+
+  final List<List<int>> writes = <List<int>>[];
+
+  @override
+  void add(List<int> data) {
+    writes.add(data);
+  }
+
+  @override
+  Future<void> addStream(Stream<List<int>> stream) {
+    final Completer<void> completer = Completer<void>();
+    late StreamSubscription<List<int>> sub;
+    sub = stream.listen(
+      (List<int> data) {
+        try {
+          add(data);
+          // Catches all exceptions to propagate them to the completer.
+        } catch (err, stack) {
+          // ignore: avoid_catches_without_on_clauses
+          sub.cancel();
+          completer.completeError(err, stack);
+        }
+      },
+      onError: completer.completeError,
+      onDone: completer.complete,
+      cancelOnError: true,
+    );
+    return completer.future;
+  }
+
+  @override
+  void writeCharCode(int charCode) {
+    add(<int>[charCode]);
+  }
+
+  @override
+  void write(Object? obj) {
+    add(encoding.encode('$obj'));
+  }
+
+  @override
+  void writeln([Object? obj = '']) {
+    add(encoding.encode('$obj\n'));
+  }
+
+  @override
+  void writeAll(Iterable<dynamic> objects, [String separator = '']) {
+    bool addSeparator = false;
+    for (final dynamic object in objects) {
+      if (addSeparator) {
+        write(separator);
+      }
+      write(object);
+      addSeparator = true;
+    }
+  }
+
+  @override
+  void addError(dynamic error, [StackTrace? stackTrace]) {
+    throw UnimplementedError();
+  }
+
+  @override
+  Future<void> get done => close();
+
+  @override
+  Future<void> close() async {}
+
+  @override
+  Future<void> flush() async {}
+
+  void clear() {
+    writes.clear();
+  }
+
+  String getAndClear() {
+    final String result =
+        utf8.decode(writes.expand((List<int> l) => l).toList());
+    clear();
+    return result;
+  }
+}
+
+class MemoryStdout extends MemoryIOSink implements io.Stdout {
+  @override
+  bool get hasTerminal => _hasTerminal;
+  set hasTerminal(bool value) {
+    assert(value != null);
+    _hasTerminal = value;
+  }
+
+  bool _hasTerminal = true;
+
+  @override
+  io.IOSink get nonBlocking => this;
+
+  @override
+  bool get supportsAnsiEscapes => _supportsAnsiEscapes;
+  set supportsAnsiEscapes(bool value) {
+    assert(value != null);
+    _supportsAnsiEscapes = value;
+  }
+
+  bool _supportsAnsiEscapes = true;
+
+  @override
+  int get terminalColumns {
+    if (_terminalColumns != null) {
+      return _terminalColumns!;
+    }
+    throw const io.StdoutException('unspecified mock value');
+  }
+
+  set terminalColumns(int value) => _terminalColumns = value;
+  int? _terminalColumns;
+
+  @override
+  int get terminalLines {
+    if (_terminalLines != null) {
+      return _terminalLines!;
+    }
+    throw const io.StdoutException('unspecified mock value');
+  }
+
+  set terminalLines(int value) => _terminalLines = value;
+  int? _terminalLines;
+}
+
+/// A Stdio that collects stdout and supports simulated stdin.
+class FakeStdio extends Stdio {
+  final MemoryStdout _stdout = MemoryStdout()..terminalColumns = 80;
+  final MemoryIOSink _stderr = MemoryIOSink();
+  final FakeStdin _stdin = FakeStdin();
+
+  @override
+  MemoryStdout get stdout => _stdout;
+
+  @override
+  MemoryIOSink get stderr => _stderr;
+
+  @override
+  Stream<List<int>> get stdin => _stdin;
+
+  void simulateStdin(String line) {
+    _stdin.controller.add(utf8.encode('$line\n'));
+  }
+
+  @override
+  bool hasTerminal = true;
+
+  List<String> get writtenToStdout =>
+      _stdout.writes.map<String>(_stdout.encoding.decode).toList();
+  List<String> get writtenToStderr =>
+      _stderr.writes.map<String>(_stderr.encoding.decode).toList();
+}
+
+class FakeStdin extends Fake implements Stdin {
+  final StreamController<List<int>> controller = StreamController<List<int>>();
+
+  @override
+  bool echoMode = true;
+
+  @override
+  bool hasTerminal = true;
+
+  @override
+  bool echoNewlineMode = true;
+
+  @override
+  bool lineMode = true;
+
+  @override
+  Stream<S> transform<S>(StreamTransformer<List<int>, S> transformer) {
+    return controller.stream.transform(transformer);
+  }
+
+  @override
+  StreamSubscription<List<int>> listen(
+    void Function(List<int> event)? onData, {
+    Function? onError,
+    void Function()? onDone,
+    bool? cancelOnError,
+  }) {
+    return controller.stream.listen(
+      onData,
+      onError: onError,
+      onDone: onDone,
+      cancelOnError: cancelOnError,
+    );
+  }
+}
+
+class FakeStopwatch implements Stopwatch {
+  @override
+  bool get isRunning => _isRunning;
+  bool _isRunning = false;
+
+  @override
+  void start() => _isRunning = true;
+
+  @override
+  void stop() => _isRunning = false;
+
+  @override
+  Duration elapsed = Duration.zero;
+
+  @override
+  int get elapsedMicroseconds => elapsed.inMicroseconds;
+
+  @override
+  int get elapsedMilliseconds => elapsed.inMilliseconds;
+
+  @override
+  int get elapsedTicks => elapsed.inMilliseconds;
+
+  @override
+  int get frequency => 1000;
+
+  @override
+  void reset() {
+    _isRunning = false;
+    elapsed = Duration.zero;
+  }
+
+  @override
+  String toString() => '$runtimeType $elapsed $isRunning';
+}
+
+class FakeStopwatchFactory implements StopwatchFactory {
+  FakeStopwatchFactory(
+      {Stopwatch? stopwatch, Map<String, Stopwatch>? stopwatches})
+      : stopwatches = <String, Stopwatch>{
+          if (stopwatches != null) ...stopwatches,
+          if (stopwatch != null) '': stopwatch,
+        };
+
+  Map<String, Stopwatch> stopwatches;
+
+  @override
+  Stopwatch createStopwatch([String name = '']) {
+    return stopwatches[name] ?? FakeStopwatch();
+  }
+}
diff --git a/packages/flutter_migrate/test/src/io.dart b/packages/flutter_migrate/test/src/io.dart
new file mode 100644
index 0000000..c7e6bf3
--- /dev/null
+++ b/packages/flutter_migrate/test/src/io.dart
@@ -0,0 +1,138 @@
+// Copyright 2013 The Flutter 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' as io show Directory, File, IOOverrides, Link;
+
+import 'package:flutter_migrate/src/base/file_system.dart';
+
+/// An [IOOverrides] that can delegate to [FileSystem] implementation if provided.
+///
+/// Does not override any of the socket facilities.
+///
+/// Do not provide a [LocalFileSystem] as a delegate. Since internally this calls
+/// out to `dart:io` classes, it will result in a stack overflow error as the
+/// IOOverrides and LocalFileSystem call each other endlessly.
+///
+/// The only safe delegate types are those that do not call out to `dart:io`,
+/// like the [MemoryFileSystem].
+class FlutterIOOverrides extends io.IOOverrides {
+  FlutterIOOverrides({FileSystem? fileSystem})
+      : _fileSystemDelegate = fileSystem;
+
+  final FileSystem? _fileSystemDelegate;
+
+  @override
+  io.Directory createDirectory(String path) {
+    if (_fileSystemDelegate == null) {
+      return super.createDirectory(path);
+    }
+    return _fileSystemDelegate!.directory(path);
+  }
+
+  @override
+  io.File createFile(String path) {
+    if (_fileSystemDelegate == null) {
+      return super.createFile(path);
+    }
+    return _fileSystemDelegate!.file(path);
+  }
+
+  @override
+  io.Link createLink(String path) {
+    if (_fileSystemDelegate == null) {
+      return super.createLink(path);
+    }
+    return _fileSystemDelegate!.link(path);
+  }
+
+  @override
+  Stream<FileSystemEvent> fsWatch(String path, int events, bool recursive) {
+    if (_fileSystemDelegate == null) {
+      return super.fsWatch(path, events, recursive);
+    }
+    return _fileSystemDelegate!
+        .file(path)
+        .watch(events: events, recursive: recursive);
+  }
+
+  @override
+  bool fsWatchIsSupported() {
+    if (_fileSystemDelegate == null) {
+      return super.fsWatchIsSupported();
+    }
+    return _fileSystemDelegate!.isWatchSupported;
+  }
+
+  @override
+  Future<FileSystemEntityType> fseGetType(String path, bool followLinks) {
+    if (_fileSystemDelegate == null) {
+      return super.fseGetType(path, followLinks);
+    }
+    return _fileSystemDelegate!.type(path, followLinks: followLinks);
+  }
+
+  @override
+  FileSystemEntityType fseGetTypeSync(String path, bool followLinks) {
+    if (_fileSystemDelegate == null) {
+      return super.fseGetTypeSync(path, followLinks);
+    }
+    return _fileSystemDelegate!.typeSync(path, followLinks: followLinks);
+  }
+
+  @override
+  Future<bool> fseIdentical(String path1, String path2) {
+    if (_fileSystemDelegate == null) {
+      return super.fseIdentical(path1, path2);
+    }
+    return _fileSystemDelegate!.identical(path1, path2);
+  }
+
+  @override
+  bool fseIdenticalSync(String path1, String path2) {
+    if (_fileSystemDelegate == null) {
+      return super.fseIdenticalSync(path1, path2);
+    }
+    return _fileSystemDelegate!.identicalSync(path1, path2);
+  }
+
+  @override
+  io.Directory getCurrentDirectory() {
+    if (_fileSystemDelegate == null) {
+      return super.getCurrentDirectory();
+    }
+    return _fileSystemDelegate!.currentDirectory;
+  }
+
+  @override
+  io.Directory getSystemTempDirectory() {
+    if (_fileSystemDelegate == null) {
+      return super.getSystemTempDirectory();
+    }
+    return _fileSystemDelegate!.systemTempDirectory;
+  }
+
+  @override
+  void setCurrentDirectory(String path) {
+    if (_fileSystemDelegate == null) {
+      return super.setCurrentDirectory(path);
+    }
+    _fileSystemDelegate!.currentDirectory = path;
+  }
+
+  @override
+  Future<FileStat> stat(String path) {
+    if (_fileSystemDelegate == null) {
+      return super.stat(path);
+    }
+    return _fileSystemDelegate!.stat(path);
+  }
+
+  @override
+  FileStat statSync(String path) {
+    if (_fileSystemDelegate == null) {
+      return super.statSync(path);
+    }
+    return _fileSystemDelegate!.statSync(path);
+  }
+}
diff --git a/packages/flutter_migrate/test/src/test_flutter_command_runner.dart b/packages/flutter_migrate/test/src/test_flutter_command_runner.dart
new file mode 100644
index 0000000..8e4d36b
--- /dev/null
+++ b/packages/flutter_migrate/test/src/test_flutter_command_runner.dart
@@ -0,0 +1,40 @@
+// Copyright 2013 The Flutter 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 'package:args/command_runner.dart';
+import 'package:flutter_migrate/src/base/command.dart';
+
+export 'package:test_api/test_api.dart' // ignore: deprecated_member_use
+    hide
+        isInstanceOf,
+        test;
+
+CommandRunner<void> createTestCommandRunner([MigrateCommand? command]) {
+  final CommandRunner<void> runner = TestCommandRunner();
+  if (command != null) {
+    runner.addCommand(command);
+  }
+  return runner;
+}
+
+class TestCommandRunner extends CommandRunner<void> {
+  TestCommandRunner()
+      : super(
+          'flutter',
+          'Manage your Flutter app development.\n'
+              '\n'
+              'Common commands:\n'
+              '\n'
+              '  flutter create <output directory>\n'
+              '    Create a new Flutter project in the specified directory.\n'
+              '\n'
+              '  flutter run [options]\n'
+              '    Run your Flutter application on an attached device or in an emulator.',
+        );
+
+  @override
+  Future<void> run(Iterable<String> args) {
+    return super.run(args);
+  }
+}
diff --git a/packages/flutter_migrate/test/src/test_utils.dart b/packages/flutter_migrate/test/src/test_utils.dart
new file mode 100644
index 0000000..b51e127
--- /dev/null
+++ b/packages/flutter_migrate/test/src/test_utils.dart
@@ -0,0 +1,62 @@
+// Copyright 2013 The Flutter 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_migrate/src/base/file_system.dart';
+import 'package:flutter_migrate/src/base/io.dart';
+import 'package:flutter_migrate/src/base/signals.dart';
+import 'package:process/process.dart';
+
+import 'common.dart';
+
+/// The [FileSystem] for the integration test environment.
+LocalFileSystem fileSystem =
+    LocalFileSystem.test(signals: LocalSignals.instance);
+
+/// The [ProcessManager] for the integration test environment.
+const ProcessManager processManager = LocalProcessManager();
+
+/// Creates a temporary directory but resolves any symlinks to return the real
+/// underlying path to avoid issues with breakpoints/hot reload.
+/// https://github.com/flutter/flutter/pull/21741
+Directory createResolvedTempDirectorySync(String prefix) {
+  assert(prefix.endsWith('.'));
+  final Directory tempDirectory =
+      fileSystem.systemTempDirectory.createTempSync('flutter_$prefix');
+  return fileSystem.directory(tempDirectory.resolveSymbolicLinksSync());
+}
+
+void writeFile(String path, String content,
+    {bool writeFutureModifiedDate = false}) {
+  final File file = fileSystem.file(path)
+    ..createSync(recursive: true)
+    ..writeAsStringSync(content, flush: true);
+  // Some integration tests on Windows to not see this file as being modified
+  // recently enough for the hot reload to pick this change up unless the
+  // modified time is written in the future.
+  if (writeFutureModifiedDate) {
+    file.setLastModifiedSync(DateTime.now().add(const Duration(seconds: 5)));
+  }
+}
+
+void writePackages(String folder) {
+  writeFile(fileSystem.path.join(folder, '.packages'), '''
+test:${fileSystem.path.join(fileSystem.currentDirectory.path, 'lib')}/
+''');
+}
+
+Future<void> getPackages(String folder) async {
+  final List<String> command = <String>[
+    fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'),
+    'pub',
+    'get',
+  ];
+  final ProcessResult result =
+      await processManager.run(command, workingDirectory: folder);
+  if (result.exitCode != 0) {
+    throw Exception(
+        'flutter pub get failed: ${result.stderr}\n${result.stdout}');
+  }
+}
diff --git a/script/configs/custom_analysis.yaml b/script/configs/custom_analysis.yaml
index 1ad0f64..a281f3c 100644
--- a/script/configs/custom_analysis.yaml
+++ b/script/configs/custom_analysis.yaml
@@ -8,10 +8,13 @@
 
 # Deliberately uses flutter_lints, as that's what it is demonstrating.
 - flutter_lints/example
+# Adopts some flutter_tools rules regarding public api docs due to being an
+# extension of the tool and using tools base code.
+- flutter_migrate
 # Adds unawaited_futures. We should investigating adding this to the root
 # options instead.
 - metrics_center
 # Has some constructions that are currently handled poorly by dart format.
 - rfw/example
 # Disables docs requirements, as it is test code.
-- web_benchmarks/testing/test_app
+- web_benchmarks/testing/test_app
\ No newline at end of file
