diff --git a/README.md b/README.md
index f222e59..73a089b 100644
--- a/README.md
+++ b/README.md
@@ -37,3 +37,4 @@
 * topaz/public/lib/config: f489f45e6883df6e3be578342b4e739928adcf77
 * topaz/public/lib/context: f489f45e6883df6e3be578342b4e739928adcf77
 * topaz/public/lib/mod: 75067a620790d76515c3824321eca335a6aa6bab
+* topaz/public/lib/app_driver: 0196bf704f
diff --git a/bin/system_dashboard/BUILD.gn b/bin/system_dashboard/BUILD.gn
index eff7539..e33f25a 100644
--- a/bin/system_dashboard/BUILD.gn
+++ b/bin/system_dashboard/BUILD.gn
@@ -23,7 +23,6 @@
     "//third_party/dart-pkg/pub/flutter_staggered_grid_view",
     "//topaz/public/dart/widgets:lib.widgets",
     "//topaz/public/lib/app/dart",
-    "//topaz/public/lib/app_driver/dart",
     "//topaz/public/lib/schemas/dart",
   ]
 }
diff --git a/bin/ui/text_input_mod/BUILD.gn b/bin/ui/text_input_mod/BUILD.gn
index 64aa08f..73425f0 100644
--- a/bin/ui/text_input_mod/BUILD.gn
+++ b/bin/ui/text_input_mod/BUILD.gn
@@ -20,7 +20,6 @@
     "//topaz/public/dart/widgets:lib.widgets",
     "//topaz/public/dart/widgets:lib.widgets",
     "//topaz/public/lib/app/dart",
-    "//topaz/public/lib/app_driver/dart",
     "//topaz/public/lib/module/dart",
     "//topaz/public/lib/module_resolver/dart",
     "//topaz/public/lib/widgets/dart",
diff --git a/examples/test/driver_example_mod/BUILD.gn b/examples/test/driver_example_mod/BUILD.gn
index cceceae..d26b621 100644
--- a/examples/test/driver_example_mod/BUILD.gn
+++ b/examples/test/driver_example_mod/BUILD.gn
@@ -33,7 +33,6 @@
     "//topaz/public/dart/fuchsia_modular",
     "//topaz/public/dart/fuchsia_services",
     "//topaz/public/lib/app/dart",
-    "//topaz/public/lib/app_driver/dart",
     "//topaz/public/lib/widgets/dart",
   ]
 }
diff --git a/examples/ui/localized_mod/BUILD.gn b/examples/ui/localized_mod/BUILD.gn
index 349186c..c00e961 100644
--- a/examples/ui/localized_mod/BUILD.gn
+++ b/examples/ui/localized_mod/BUILD.gn
@@ -18,7 +18,6 @@
     "//third_party/dart-pkg/git/flutter/packages/flutter_localizations",
     "//third_party/dart/third_party/pkg/intl",
     "//topaz/public/dart/widgets:lib.widgets",
-    "//topaz/public/lib/app_driver/dart",
   ]
 
   meta = [
diff --git a/packages/tests/BUILD.gn b/packages/tests/BUILD.gn
index 479b244..578baf4 100644
--- a/packages/tests/BUILD.gn
+++ b/packages/tests/BUILD.gn
@@ -42,7 +42,6 @@
     "//topaz/public/lib/app/dart:dart_app_tests($host_toolchain)",
     "//topaz/public/lib/display/flutter:display_test($host_toolchain)",
     "//topaz/public/lib/schemas/dart:dart_schema_tests($host_toolchain)",
-    "//topaz/public/lib/testing/app_driver/dart:fake_module_driver_test($host_toolchain)",
     "//topaz/shell/mondrian_story_shell:mondrian_story_shell_tests($host_toolchain)",
   ]
 }
diff --git a/packages/tests/dart_unittests b/packages/tests/dart_unittests
index c9547c5..c5efb47 100644
--- a/packages/tests/dart_unittests
+++ b/packages/tests/dart_unittests
@@ -20,7 +20,6 @@
       "//topaz/public/lib/app/dart:dart_app_tests",
       "//topaz/public/lib/display/flutter:display_test",
       "//topaz/public/lib/schemas/dart:dart_schema_tests",
-      "//topaz/public/lib/testing/app_driver/dart:fake_module_driver_test",
       "//topaz/shell/mondrian_story_shell:mondrian_story_shell_tests"
     ]
 }
diff --git a/public/lib/app_driver/dart/BUILD.gn b/public/lib/app_driver/dart/BUILD.gn
deleted file mode 100644
index 24cfddd..0000000
--- a/public/lib/app_driver/dart/BUILD.gn
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/dart/dart_library.gni")
-
-dart_library("dart") {
-  package_name = "lib.app_driver.dart"
-
-  sdk_category = "partner"
-
-  sources = [
-    "app_driver.dart",
-    "module_driver.dart",
-    "src/intent_parameters.dart",
-    "src/module_driver.dart",
-    "src/service_client.dart",
-    "intent_parameters.dart",
-  ]
-
-  deps = [
-    "//sdk/fidl/fuchsia.modular",
-    "//topaz/public/lib/app/dart",
-    "//topaz/public/lib/component/dart",
-    "//topaz/public/lib/entity/dart",
-    "//topaz/public/lib/intent_handler/dart",
-    "//topaz/public/lib/lifecycle/dart",
-    "//topaz/public/lib/module/dart",
-    "//topaz/public/lib/module_resolver/dart",
-    "//topaz/public/lib/schemas/dart",
-    "//topaz/public/lib/story/dart",
-  ]
-}
diff --git a/public/lib/app_driver/dart/analysis_options.yaml b/public/lib/app_driver/dart/analysis_options.yaml
deleted file mode 100644
index 28306ea..0000000
--- a/public/lib/app_driver/dart/analysis_options.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-include: ../../../analysis_options.yaml
diff --git a/public/lib/app_driver/dart/lib/app_driver.dart b/public/lib/app_driver/dart/lib/app_driver.dart
deleted file mode 100644
index a89bd0e..0000000
--- a/public/lib/app_driver/dart/lib/app_driver.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export 'src/module_driver.dart';
diff --git a/public/lib/app_driver/dart/lib/intent_parameters.dart b/public/lib/app_driver/dart/lib/intent_parameters.dart
deleted file mode 100644
index 22bbcbb..0000000
--- a/public/lib/app_driver/dart/lib/intent_parameters.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export 'src/intent_parameters.dart';
diff --git a/public/lib/app_driver/dart/lib/module_driver.dart b/public/lib/app_driver/dart/lib/module_driver.dart
deleted file mode 100644
index ef81053..0000000
--- a/public/lib/app_driver/dart/lib/module_driver.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(MS-1239): delete this file once dependants use the main app_driver.dart
-// import.
-export 'src/module_driver.dart';
-export 'src/service_client.dart';
diff --git a/public/lib/app_driver/dart/lib/src/intent_parameters.dart b/public/lib/app_driver/dart/lib/src/intent_parameters.dart
deleted file mode 100644
index 27d8b2d..0000000
--- a/public/lib/app_driver/dart/lib/src/intent_parameters.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'package:fidl_fuchsia_mem/fidl.dart' as fuchsia_mem;
-import 'package:fidl_fuchsia_modular/fidl.dart';
-import 'package:lib.app_driver.dart/module_driver.dart';
-import 'package:lib.app.dart/logging.dart';
-import 'package:lib.schemas.dart/entity_codec.dart';
-import 'package:zircon/zircon.dart';
-
-/// A class which wraps parameters delivered to a module via the
-/// [IntentHandler] interface. It provides access to the parameter
-/// data in a uniform way, regardless of how the [Intent.parameters]
-/// was constructed.
-///
-/// If a parameter was created with a link, it's possible for the
-/// parameter data to change over time. In this case it's better to
-/// use [IntentParameters.watchParameterData], which allows modules
-/// to observe changes to the parameter. If the module does not care
-/// about potential future updates, [IntentParameters.getParameterData]
-/// will provide the data directly.
-class IntentParameters {
-  final Map<String, IntentParameterData> _parameters = {};
-  // TODO: Refactor this class to use the new SDK instead of deprecated API
-  // ignore: deprecated_member_use_from_same_package
-  ModuleDriver _driver;
-
-  /// [moduleDriver] is used to access Entity and Link parameters.
-  /// [parameters] are the parmeters from an [Intent].
-  IntentParameters({
-    // ignore: deprecated_member_use_from_same_package
-    ModuleDriver moduleDriver,
-    List<IntentParameter> parameters,
-  }) {
-    _driver = moduleDriver;
-    for (var parameter in parameters ?? []) {
-      _parameters[parameter.name] = parameter.data;
-    }
-  }
-
-  /// Returns the data for the parameter with name [parameterName].
-  Future<T> getParameterData<T>(
-      String parameterName, EntityCodec<T> codec) async {
-    IntentParameterData data = _parameters[parameterName];
-    if (data == null) {
-      throw Exception('Invalid parameter name: $parameterName');
-    }
-
-    switch (data.tag) {
-      case IntentParameterDataTag.json:
-        return _getJsonData(data.json, codec);
-      case IntentParameterDataTag.entityReference:
-        return _getEntityData(data.entityReference, codec);
-      default:
-        throw Exception('Unsupported parameter type.');
-    }
-  }
-
-  T _getJsonData<T>(fuchsia_mem.Buffer json, EntityCodec<T> codec) {
-    final vmo = SizedVmo(json.vmo.handle, json.size);
-    final data = vmo.read(json.size);
-    if (data.status != 0) {
-      throw Exception('Failed to read VMO');
-    }
-    vmo.close();
-    return codec.decode(jsonDecode(utf8.decode(data.bytesAsUint8List())));
-  }
-
-  Future<T> _getEntityData<T>(
-      String entityReference, EntityCodec<T> codec) async {
-    final resolver = await _driver.getResolver();
-    final entity = await resolver.resolveEntity(entityReference);
-    final types = await entity.getTypes();
-
-    if (!types.contains(codec.type)) {
-      throw EntityTypeException(codec.type);
-    }
-
-    var data = await entity.getData(codec.type);
-    return codec.decode(data);
-  }
-
-  /// Returns a stream of data. If the parameter is JSON, or an Entity the data
-  /// will be added to the stream and the stream will then be closed. If the
-  /// parameter is a Link, any observed updates to the Link will also be added
-  /// to the stream.
-  Stream<T> watchParameterData<T>(String parameterName, EntityCodec<T> codec) {
-    IntentParameterData data = _parameters[parameterName];
-    if (data == null) {
-      throw Exception('Invalid parameter name');
-    }
-
-    StreamController<T> controller = new StreamController<T>(
-      onListen: () => log.info('watch stream ($parameterName): listening'),
-      onPause: () => log.info('watch stream ($parameterName): paused'),
-      onResume: () => log.info('watch stream ($parameterName): resuming'),
-      onCancel: () => log.info('watch stream ($parameterName): cancelled'),
-    );
-
-    switch (data.tag) {
-      case IntentParameterDataTag.json:
-        controller.add(_getJsonData(data.json, codec));
-        controller.close();
-        break;
-      case IntentParameterDataTag.entityReference:
-        _getEntityData(data.entityReference, codec).then((entityData) {
-          controller
-            ..add(entityData)
-            ..close();
-        });
-        break;
-      default:
-        throw Exception('Unsupported parameter type: ${data.tag}');
-    }
-    return controller.stream;
-  }
-}
diff --git a/public/lib/app_driver/dart/lib/src/module_driver.dart b/public/lib/app_driver/dart/lib/src/module_driver.dart
deleted file mode 100644
index b72e0b1..0000000
--- a/public/lib/app_driver/dart/lib/src/module_driver.dart
+++ /dev/null
@@ -1,618 +0,0 @@
-// Copyright 2018 The Fuchsia 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:typed_data';
-
-import 'package:fidl/fidl.dart';
-import 'package:fidl_fuchsia_mem/fidl.dart' as fuchsia_mem;
-import 'package:fidl_fuchsia_sys/fidl.dart';
-import 'package:lib.app.dart/app.dart';
-import 'package:lib.app.dart/logging.dart';
-import 'package:lib.app_driver.dart/intent_parameters.dart';
-import 'package:lib.component.dart/component.dart';
-import 'package:lib.entity.dart/entity.dart';
-import 'package:lib.intent_handler.dart/intent_handler.dart';
-import 'package:lib.lifecycle.dart/lifecycle.dart';
-import 'package:lib.module.dart/module.dart';
-import 'package:lib.schemas.dart/entity_codec.dart';
-import 'package:lib.story.dart/story.dart';
-import 'package:meta/meta.dart';
-import 'package:zircon/zircon.dart';
-
-import 'service_client.dart';
-
-export 'package:lib.component.dart/component.dart'
-    show MessageQueueError, MessageSenderError;
-export 'package:fidl_fuchsia_modular/fidl.dart' show Intent;
-export 'package:lib.app_driver.dart/intent_parameters.dart'
-    show IntentParameters;
-export 'package:lib.module_resolver.dart/intent_builder.dart'
-    show IntentBuilder;
-export 'package:lib.module.dart/module.dart'
-    show ModuleControllerClient, EmbeddedModule;
-export 'package:lib.story.dart/story.dart' show LinkClient;
-
-/// Function definition to handle [data] that is received from a message queue.
-typedef OnReceiveMessage = void Function(Uint8List data, void Function() ack);
-
-/// Function to run when the module terminates
-typedef OnTerminate = void Function();
-
-/// Function to run when the module terminates asynchronously
-typedef OnTerminateAsync = Future<Null> Function();
-
-typedef OnHandleIntent = void Function(
-    String action, IntentParameters parameters);
-
-/// The [ModuleDriver] provides a high-level API for running a module in Dart
-/// code. The name and structure of this library is based on the peridot layer's
-/// [AppDriver][app-driver]. A Module has two primary events:
-///
-/// * initialize: managed by the constructor.
-/// * terminate: managed by the internal [LifecycleHost].
-///
-/// Initialization
-///
-/// Module initialization is triggered by calling [startSync]. Once the module
-/// has successfully initialized additional service clients are connected
-/// providing access to The Module's Link and ModuleContext services.
-///
-/// Termination
-///
-/// Module termination is triggered by the system, all service hosts and clients
-/// will automatically have their underlying connections closed including any
-/// added by making calls to exposed APIs (e.g. [link], [moduleContext]).
-@Deprecated('Use package:fuchsia_modular/module.dart instead')
-class ModuleDriver {
-  final StartupContext _startupContext = new StartupContext.fromStartupInfo();
-
-  /// A [LinkClient] for this module's default Link. Async results for
-  /// LinkClient methods will resolve once the Module has been initialized
-  /// successfully. If access to more links is required use
-  /// [moduleContext#getLink()].
-  final LinkClient link = new LinkClient();
-
-  /// Called when a new intent is received from the framework. When set the
-  /// module driver will call [onHandleIntent] with the latest intent
-  /// received, if such an intent is available.
-  OnHandleIntent _onHandleIntent;
-
-  /// Stores the latest intent received from the framework so it can be passed to
-  /// [onHandleIntent] when it is set.
-  Intent _intent;
-
-  /// The [ModuleContextClient] for this module. Async results for method calls
-  /// will resolve once the Module has been initialized successfully.
-  final ModuleContextClient moduleContext = new ModuleContextClient();
-
-  // Message queue proxies for receiving updates from the content provider
-  // TODO(meiyili): update to handle creating to multiple message queues MS-1288
-  MessageQueueClient _messageQueue;
-
-  final Set<String> _firstObservationSent = <String>{};
-  LifecycleHost _lifecycle;
-  IntentHandlerImpl _intentHandler;
-
-  /// Shadow async completion of [startSync].
-  final _start = Completer<ModuleDriver>();
-
-  /// A flag indicating if the user has called [startSync] yet.
-  var _hasCalledStart = false;
-
-  // Methods to run when the module is being torn down
-  final List<OnTerminateAsync> _onTerminatesAsync = <OnTerminateAsync>[];
-
-  /// Deprecated: Use package:fuchsia_modular/module.dart instead
-  ///
-  /// Create a new [ModuleDriver].
-  ///
-  ///     ModuleDriver module = new ModuleDriver();
-  ///
-  /// [onTerminate] lets the caller specify a function to run in the
-  /// onTerminate call.
-  ///
-  /// Register for link updates:
-  ///
-  ///     module.link.watch()
-  ///         .listen((Object json) => print('Link data: $json'));
-  ///
-  /// Start the module:
-  ///
-  ///     module.startSync();
-  ///
-  ModuleDriver({
-    // TODO(MS-1521): consider removing
-    OnTerminate onTerminate,
-  }) {
-    if (onTerminate != null) {
-      _onTerminatesAsync.add(() async {
-        onTerminate();
-        return null;
-      });
-    }
-    _lifecycle = new LifecycleHost(
-      onTerminate: _handleTerminate,
-    );
-    _intentHandler = IntentHandlerImpl(onHandleIntent: _handleIntent);
-
-    // Observe time to default link
-    // TODO(meiyili): remove once default link is deprecated
-    link.watch().listen((String data) => _observeLinkData('default', data));
-  }
-
-  /// Sets the intent handler.
-  set onHandleIntent(OnHandleIntent onHandleIntent) {
-    _onHandleIntent = onHandleIntent;
-    _handleIntent(_intent);
-  }
-
-  String _moduleName;
-
-  /// Module name to use for metrics, if it is not set will use default package
-  /// name for the module
-  String get moduleName => _moduleName;
-  set moduleName(String name) => _moduleName = name.trim();
-
-  /// Add other methods to run on terminate
-  void addOnTerminateHandler(OnTerminate onTerminate) => _onTerminatesAsync.add(
-        () async {
-          onTerminate();
-          return null;
-        },
-      );
-
-  /// Add a method to run on terminate asynchronously
-  void addOnTerminateAsyncHandler(OnTerminateAsync onTerminate) =>
-      _onTerminatesAsync.add(onTerminate);
-
-  /// Deprecated use [#startSync] instead.
-  ///
-  /// Start the module and connect to dependent services on module
-  /// initialization
-  // @Deprecated('use startSync instead') can't add this because of linter
-  Future<ModuleDriver> start() async {
-    log.fine('#start(...)');
-    startSync();
-    return _start.future;
-  }
-
-  /// Start the module and connect to dependent services on module
-  /// initialization.
-  void startSync() {
-    log.fine('#startSync()');
-
-    // Fail fast on subsequent (accidental) calls to #start() instead of
-    // triggering deeper errors by re-binding the impl.
-    if (_hasCalledStart) {
-      throw Exception('moduleDrive.startSync()) should only be called once.');
-    }
-    _hasCalledStart = true;
-
-    _lifecycle.addService(startupContext: _startupContext);
-    _intentHandler.addService(startupContext: _startupContext);
-    connectToService(environmentServices, moduleContext.proxy.ctrl);
-    moduleContext.getLink(linkClient: link);
-
-    // Still complete the future since the rest of the login in this class
-    // awaiting on it.
-    _start.complete(this);
-  }
-
-  /// Creates a message queue and returns a [Future] with the message queue
-  /// token that should be passed to agents we want to connect to. If a
-  /// message queue has already been created, it will return the token for the
-  /// token for the already created queue and ignore the new [onMessage] method.
-  ///
-  /// [name] is the name of the message queue.
-  /// [onMessage] should be supplied to handle the data from the message queue.
-  // TODO(meiyili): Update to allow creating multiple message queues MS-1288
-  Future<String> createMessageQueue({
-    @required String name,
-    @required OnReceiveMessage onMessage,
-    @required MessageQueueErrorCallback onConnectionError,
-  }) async {
-    assert(name != null && name.isNotEmpty);
-    assert(onMessage != null);
-    log.fine('#createMessageQueue($name)');
-
-    // Create a message queue that the module can pass to agents only if we
-    // haven't already created one
-    ComponentContextClient componentContext =
-        await moduleContext.getComponentContext();
-    _messageQueue = componentContext.obtainMessageQueue(
-        name: name, onMessage: onMessage, onConnectionError: onConnectionError);
-    return _messageQueue.getToken();
-  }
-
-  /// Connect to the service specified by [client] and implemented by the
-  /// agent at [url].
-  ///
-  /// The [url] is required as multiple agents can implement the same
-  /// service interface.
-  Future<void> connectToAgentService<T>(
-    String url,
-    ServiceClient<T> client,
-  ) async {
-    await _start.future.timeout(Duration(seconds: 5));
-    await connectToAgentServiceWithProxy(url, client.proxy);
-  }
-
-  /// Connect to the service specified by [proxy] and implemented by the
-  /// agent at [url].
-  /// DEPRECATED: please write a client for your service and use
-  /// connectToAgentService
-  Future<void> connectToAgentServiceWithProxy(
-    String url,
-    Proxy<dynamic> proxy,
-  ) async {
-    log.fine('#connectToAgentService(...)');
-    assert(proxy.ctrl.$serviceName != null,
-        'controller.\$serviceName must not be null. Check the FIDL file for a missing [Discoverable]');
-    ComponentContextClient componentContext = await getComponentContext();
-
-    ServiceProviderProxy serviceProviderProxy =
-        await componentContext.connectToAgent(url);
-    connectToService(serviceProviderProxy, proxy.ctrl);
-
-    // Close all unnecessary bindings
-    serviceProviderProxy.ctrl.close();
-  }
-
-  /// Connect to an agent using a new-style async proxy.
-  Future<void> connectToAgentServiceWithAsyncProxy(
-    String url,
-    AsyncProxy<dynamic> proxy,
-  ) async {
-    log.fine('#connectToAgentService(...)');
-    assert(proxy.ctrl.$serviceName != null,
-        'controller.\$serviceName must not be null. Check the FIDL file for a missing [Discoverable]');
-
-    final serviceName = proxy.ctrl.$serviceName;
-    ComponentContextClient componentContext = await getComponentContext();
-
-    await componentContext.connectToAgent(url)
-      ..connectToService(serviceName, proxy.ctrl.request().passChannel())
-      // Close all unnecessary bindings
-      ..ctrl.close();
-  }
-
-  /// Retrieve the story id of the story this module lives in
-  Future<String> getStoryId() {
-    log.fine('#getStoryId(...)');
-    return moduleContext.getStoryId();
-  }
-
-  Future<Null> _handleTerminate() {
-    log.info('closing service connections');
-
-    _messageQueue?.close();
-
-    List<Future<Null>> futures = <Future<Null>>[
-      moduleContext.terminate(),
-      _lifecycle.terminate(),
-    ]..addAll(
-        _onTerminatesAsync.map((OnTerminateAsync onTerminate) => onTerminate()),
-      );
-
-    return Future.wait(futures).then((_) {
-      log.info('successfully closed all service connections');
-    }, onError: (Error err, StackTrace stackTrace) {
-      log.warning('failed to close all service connections');
-      throw err;
-    });
-  }
-
-  /// Save when the link data first becomes non-null.
-  void _observeLinkData(String linkName, String data) {
-    if (!_firstObservationSent.contains(linkName) && data != null) {
-      _firstObservationSent.add(linkName);
-    }
-  }
-
-  void _handleIntent(Intent intent) {
-    log.info('Received intent from framework');
-    _intent = intent;
-    if (_onHandleIntent != null && intent != null) {
-      _onHandleIntent(intent.action,
-          IntentParameters(moduleDriver: this, parameters: intent.parameters));
-    }
-  }
-
-  /// Watch for Entity updates from Link with the name [key] and automatically
-  /// decode values using [codec].
-  Stream<T> watch<T>(String key, EntityCodec<T> codec, {bool all = false}) {
-    StreamController<String> controller = new StreamController<String>(
-      onListen: () => log.info('watch stream ($key): listening'),
-      onPause: () => log.info('watch stream ($key): paused'),
-      onResume: () => log.info('watch stream ($key): resuming'),
-      onCancel: () => log.info('watch stream ($key): cancelled'),
-    );
-
-    Future<String> convert(_) async {
-      // The String data will be null but signals that Link#setEntity(..) was
-      // called and a new value should be retrieved.
-      LinkClient link = await getLink(key);
-      log.fine('getting Entity ref for "$key" via $link');
-      // QUESTION: can the ref value change between updates to the same entity
-      // values set by ComponentContext#createEntityWithData(...)?
-      String ref = await link.getEntity();
-      // If the link does not contain an entity, attempt to get it as json
-      // before returning an error.
-      if (ref == null) {
-        fuchsia_mem.Buffer buffer = await link.get();
-        if (buffer == null) {
-          return null;
-        }
-        var dataVmo = new SizedVmo(buffer.vmo.handle, buffer.size);
-        var data = dataVmo.read(buffer.size);
-        dataVmo.close();
-        return jsonDecode(utf8.decode(data.bytesAsUint8List()));
-      }
-      EntityResolverClient resolver = await getResolver();
-      EntityClient entity = await resolver.resolveEntity(ref);
-      List<String> types = await entity.getTypes();
-
-      if (!types.contains(codec.type)) {
-        // This exception will be caught and the pending future will be resolved
-        // with this error.
-        throw new EntityTypeException(codec.type);
-      }
-
-      return await entity.getData(codec.type);
-    }
-
-    // NOTE: do not use await, the controller.stream needs to be returned
-    // synchronously so listeners can be attached without extra async book
-    // keeping.
-    getLink(key).then((LinkClient link) {
-      log.info('watching link "${link.name}" for Entity updates');
-
-      Stream<String> source = link.watch(all: all).asyncMap(convert);
-
-      controller.addStream(source, cancelOnError: true).then((_) {
-        log.info('link stream is "done"');
-        controller.close();
-      });
-    }, onError: controller.addError).catchError(controller.addError);
-
-    Stream<T> stream = controller.stream.transform(codec.decoder);
-
-    return stream;
-  }
-
-  /// Watch for Entity updates from Link with the name [key] and return the
-  /// raw bytes in the Link's value.
-  /// decode values using [codec].
-  Stream<Uint8List> watchRaw(String key, {bool all = false}) {
-    StreamController<Uint8List> controller = new StreamController<Uint8List>(
-      onListen: () => log.info('watchRaw stream ($key): listening'),
-      onPause: () => log.info('watchRaw stream ($key): paused'),
-      onResume: () => log.info('watchRaw stream ($key): resuming'),
-      onCancel: () => log.info('watchRaw stream ($key): cancelled'),
-    );
-
-    Future<Uint8List> convert(_) async {
-      fuchsia_mem.Buffer buffer = await link.get();
-      if (buffer == null) {
-        return null;
-      }
-      var dataVmo = new SizedVmo(buffer.vmo.handle, buffer.size);
-      var data = dataVmo.read(buffer.size);
-      dataVmo.close();
-      return data.bytesAsUint8List();
-    }
-
-    // NOTE: do not use await, the controller.stream needs to be returned
-    // synchronously so listeners can be attached without extra async book
-    // keeping.
-    getLink(key).then((LinkClient link) {
-      log.info('watching link "${link.name}" for Entity updates');
-
-      Stream<Uint8List> source = link.watch(all: all).asyncMap(convert);
-      controller.addStream(source, cancelOnError: true).then((_) {
-        log.info('link stream is "done"');
-        controller.close();
-      });
-    }, onError: controller.addError).catchError(controller.addError);
-
-    return controller.stream;
-  }
-
-  /// Create or update the Entity's value (translated per [codec]) and persist
-  /// it to a Link with name [key].
-  Future<String> put<T>(String key, T value, EntityCodec<T> codec) async {
-    Completer<String> completer = new Completer<String>();
-
-    try {
-      ComponentContextClient componentContext = await getComponentContext();
-      String ref =
-          await componentContext.createEntityWithData(<TypeToDataEntry>[
-        new TypeToDataEntry(type: codec.type, data: codec.encode(value)),
-      ]);
-      LinkClient link = await getLink(key);
-      await link.setEntity(ref);
-      completer.complete(ref);
-    } on Exception catch (err, stackTrace) {
-      completer.completeError(err, stackTrace);
-    }
-
-    return completer.future;
-  }
-
-  /// Retrieve the current value stored on the Link with the name [key].
-  /// The value is converted from an Entity and decoded using [codec].
-  Future<T> get<T>(String key, EntityCodec<T> codec) async {
-    Completer<T> completer = new Completer<T>();
-
-    try {
-      LinkClient link = await getLink(key);
-      String entityRef = await link.getEntity();
-      if (entityRef == null) {
-        return null;
-      }
-      EntityResolverClient resolver = await getResolver();
-      EntityClient entity = await resolver.resolveEntity(entityRef);
-      List<String> types = await entity.getTypes();
-      if (!types.contains(codec.type)) {
-        throw new EntityTypeException(codec.type);
-      }
-
-      String data = await entity.getData(codec.type);
-      completer.complete(codec.decoder.convert(data));
-    } on Exception catch (err, stackTrace) {
-      completer.completeError(err, stackTrace);
-    }
-
-    return completer.future;
-  }
-
-  final Map<String, LinkClient> _links = <String, LinkClient>{};
-
-  /// Async access to the underlying [LinkClient] with the name [name].
-  Future<LinkClient> getLink(String name) async {
-    assert(name != null);
-    assert(name.isNotEmpty);
-
-    Completer<LinkClient> completer = new Completer<LinkClient>();
-
-    if (_links.containsKey(name)) {
-      completer.complete(_links[name]);
-    } else {
-      try {
-        LinkClient client = _links[name] = new LinkClient(name: name);
-        await moduleContext.getLink(linkClient: client);
-        client.watch().listen((String data) => _observeLinkData(name, data));
-        completer.complete(client);
-      } on Exception catch (err, stackTrace) {
-        completer.completeError(err, stackTrace);
-      }
-    }
-
-    return completer.future;
-  }
-
-  /// Report that this module is active even without user interaction. This
-  /// is used by the story shell to allow long running modules to avoid
-  /// timeout due to user inactivity.
-  void active() {
-    log.fine('#active(...)');
-    moduleContext.active();
-  }
-
-  /// When a module calls [done] the framework will stop the module. If there
-  /// are no more running modules in the story the story will be stopped.
-  Future<void> done() {
-    return moduleContext.done();
-  }
-
-  /// Cache for [getComponentContext].
-  Completer<ComponentContextClient> _componentContext;
-
-  /// Async access to the [ComponentContextClient].
-  Future<ComponentContextClient> getComponentContext() async {
-    if (_componentContext == null) {
-      _componentContext = new Completer<ComponentContextClient>();
-      try {
-        _componentContext.complete(await moduleContext.getComponentContext());
-      } on Exception catch (err, stackTrace) {
-        _componentContext.completeError(err, stackTrace);
-      }
-    }
-
-    return _componentContext.future;
-  }
-
-  /// Shadow cache for [getResolver].
-  Completer<EntityResolverClient> _resolver;
-
-  /// Async access to the [EntityResolverClient].
-  Future<EntityResolverClient> getResolver() async {
-    if (_resolver == null) {
-      _resolver = new Completer<EntityResolverClient>();
-      try {
-        ComponentContextClient context = await getComponentContext();
-        _resolver.complete(await context.getEntityResolver());
-      } on Exception catch (err, stackTrace) {
-        _resolver.completeError(err, stackTrace);
-      }
-    }
-
-    return _resolver.future;
-  }
-
-  /// # Start Module
-  ///
-  /// Start a module and display it based on the passed in [surfaceRelation].
-  ///
-  /// On successful resolution the Future completes with a
-  /// [ModuleControllerClient] that allows the parent module (the one calling
-  /// this method) to access methods for observing and controlling the Module.
-  ///
-  /// Related FIDL APIs:
-  ///
-  /// * [ModuleContext#StartModule](https://goo.gl/9T8Gkv).
-  /// * [ModuleController](https://goo.gl/ZXcYW3).
-  ///
-  /// TODO(MS-1714): collapse name params or clearly document their differences.
-  Future<ModuleControllerClient> startModule({
-    @required Intent intent,
-    String name,
-    String module,
-    SurfaceRelation surfaceRelation = const SurfaceRelation(
-      arrangement: SurfaceArrangement.copresent,
-      dependency: SurfaceDependency.dependent,
-      emphasis: 0.5,
-    ),
-  }) async {
-    name ??= module;
-    assert(name != null && name.isNotEmpty);
-    assert(intent != null);
-
-    if (module != null) {
-      // TODO(MS-1443): remove deprecation notice once client usage has been
-      // updated.
-      log.warning('param "module" is deprecated, use "name" instead');
-    }
-
-    return moduleContext.addModuleToStory(
-      module: name,
-      intent: intent,
-      surfaceRelation: surfaceRelation,
-    );
-  }
-
-  /// # Embed Module
-  ///
-  /// Calls underlying framework APIs to start and configure a module instance
-  /// for embedding within a Flutter Widget tree.
-  ///
-  /// On successful resolution the Future completes with an [EmbeddedModule]
-  /// instance providing access to a [ChildView] Flutter Widget and a
-  /// [ModuleControllerClient].
-  ///
-  /// Related FIDL APIs:
-  ///
-  /// * [ModuleContext#EmbedModule](https://goo.gl/9T8Gkv).
-  /// * [ModuleController](https://goo.gl/ZXcYW3).
-  ///
-  Future<EmbeddedModule> embedModule({
-    @required String name,
-    @required Intent intent,
-  }) async {
-    assert(name != null && name.isNotEmpty);
-    assert(intent != null);
-
-    log.fine('resolving module ("$name") for embedding...');
-    return moduleContext.embedModule(name: name, intent: intent);
-  }
-
-  /// Made available for video module to access MediaPlayer.
-  /// TODO(MS-1287): Determine whether this should be refactored
-  ServiceProviderProxy get environmentServices =>
-      _startupContext.environmentServices;
-}
-
-/// [app-driver]: https://fuchsia.googlesource.com/peridot/+/master/public/lib/app_driver/cpp?autodive=0/
diff --git a/public/lib/app_driver/dart/lib/src/service_client.dart b/public/lib/app_driver/dart/lib/src/service_client.dart
deleted file mode 100644
index 0b309d0..0000000
--- a/public/lib/app_driver/dart/lib/src/service_client.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:fidl/fidl.dart';
-import 'package:lib.app.dart/logging.dart';
-import 'package:meta/meta.dart';
-
-/// A client wrapper class for fidl service proxies that extend [Proxy<T>] where
-/// [T] is a FIDL interface.
-abstract class ServiceClient<T> {
-  final Completer<Null> _bind = new Completer<Null>();
-  final Proxy<T> _proxy;
-
-  /// Creates a new instance of [ServiceClient]
-  ServiceClient(Proxy<T> proxy)
-      : assert(proxy != null),
-        _proxy = proxy {
-    _proxy.ctrl
-      ..onBind = handleBind
-      ..onUnbind = handleUnbind
-      ..onClose = handleClose
-      ..onConnectionError = handleConnectionError;
-  }
-
-  /// The fidl [Proxy] for the service we want to connect to
-  Proxy<T> get proxy => _proxy;
-
-  /// Whether or not the service proxy has connected
-  bool get bound => _bind.isCompleted;
-
-  /// Called when the client is bound to the service implementation, override
-  /// this method to add more functionality
-  @mustCallSuper
-  void handleBind() {
-    log.fine('Bound');
-    _bind.complete(null);
-  }
-
-  /// Called when the client is unbound from the service implementation,
-  /// override this method to add more functionality
-  void handleUnbind() {
-    log.fine('Unbound');
-  }
-
-  /// Called when the client connection to the service implementation is closed,
-  /// override this method to add more functionality
-  void handleClose() {
-    log.fine('Close');
-  }
-
-  /// Called when an error is propagated along the service connection channel,
-  /// override this method to add more functionality
-  void handleConnectionError() {
-    log.fine('Error');
-    throw new Exception('binding connection failed');
-  }
-
-  /// Handles tear down operations and closes open channels
-  @mustCallSuper
-  Future<Null> terminate() async {
-    if (_bind.isCompleted && proxy.ctrl.isBound) {
-      proxy.ctrl.close();
-    }
-  }
-}
diff --git a/public/lib/app_driver/dart/pubspec.yaml b/public/lib/app_driver/dart/pubspec.yaml
deleted file mode 100644
index 001dc22..0000000
--- a/public/lib/app_driver/dart/pubspec.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-name: app_driver
\ No newline at end of file
diff --git a/public/lib/testing/app_driver/dart/BUILD.gn b/public/lib/testing/app_driver/dart/BUILD.gn
deleted file mode 100644
index aafca40..0000000
--- a/public/lib/testing/app_driver/dart/BUILD.gn
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2018 The Fuchsia 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("//build/dart/dart_library.gni")
-import("//topaz/runtime/dart/flutter_test.gni")
-
-dart_library("dart") {
-  package_name = "lib.testing.app_driver.dart"
-
-  sources = [
-    "fake_module_driver.dart",
-    "src/fake_module_driver.dart",
-  ]
-
-  deps = [
-    "//topaz/public/lib/app_driver/dart",
-  ]
-}
-
-flutter_test("fake_module_driver_test") {
-  sources = [
-    "fake_module_driver_test.dart",
-  ]
-
-  deps = [
-    ":dart",
-    "//third_party/dart-pkg/pub/async",
-    "//third_party/dart-pkg/pub/test",
-    "//topaz/public/lib/app_driver/dart",
-  ]
-}
diff --git a/public/lib/testing/app_driver/dart/README.md b/public/lib/testing/app_driver/dart/README.md
deleted file mode 100644
index c343fb6..0000000
--- a/public/lib/testing/app_driver/dart/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-This is an incomplete fake implementation of [ModuleDriver] to be used for mod
-tests. Not all methods are implemented, and the existing method implementations
-are still incomplete.
-
-Currently put, get, and watch are implemented and startModule is partly
-implemented.
-
-Please complete the implementation as needed, but for each new behavior added,
-please add a new test to test/fake_module_driver_test.dart.
-
-To run tests, make sure you've fx set correctly and then run:
-  `fx run-host-tests fake_module_driver_test`
diff --git a/public/lib/testing/app_driver/dart/analysis_options.yaml b/public/lib/testing/app_driver/dart/analysis_options.yaml
deleted file mode 100644
index 76b5c99..0000000
--- a/public/lib/testing/app_driver/dart/analysis_options.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-include: ../../../../../tools/analysis_options.yaml
diff --git a/public/lib/testing/app_driver/dart/lib/fake_module_driver.dart b/public/lib/testing/app_driver/dart/lib/fake_module_driver.dart
deleted file mode 100644
index 015e0e5..0000000
--- a/public/lib/testing/app_driver/dart/lib/fake_module_driver.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export 'src/fake_module_driver.dart';
diff --git a/public/lib/testing/app_driver/dart/lib/src/fake_module_driver.dart b/public/lib/testing/app_driver/dart/lib/src/fake_module_driver.dart
deleted file mode 100644
index e3afa1f..0000000
--- a/public/lib/testing/app_driver/dart/lib/src/fake_module_driver.dart
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// ignore_for_file: avoid_as
-
-import 'dart:async';
-
-import 'package:lib.schemas.dart/entity_codec.dart';
-import 'package:lib.app.dart/logging.dart';
-import 'package:lib.app_driver.dart/module_driver.dart';
-import 'package:lib.module.dart/module.dart';
-import 'package:fidl_fuchsia_modular/fidl.dart'
-    show SurfaceRelation, SurfaceArrangement, SurfaceDependency;
-import 'package:flutter/material.dart';
-
-class FakeIntentParameters implements IntentParameters {
-  FakeModuleDriver _driver;
-
-  FakeIntentParameters({
-    // TODO: Refactor this class to use the new SDK instead of deprecated API
-    // ignore: deprecated_member_use
-    ModuleDriver moduleDriver,
-  }) {
-    _driver = moduleDriver;
-  }
-
-  @override
-  Future<T> getParameterData<T>(
-      String parameterName, EntityCodec<T> codec) async {
-    return _driver.getTestLinkCurrentValue(parameterName, codec);
-  }
-
-  @override
-  Stream<T> watchParameterData<T>(String parameterName, EntityCodec<T> codec) {
-    StreamController<T> controller = new StreamController<T>(
-      onListen: () {},
-      onPause: () {},
-      onResume: () {},
-      onCancel: () {},
-    )
-      ..add(_driver.getTestLinkCurrentValue(parameterName, codec))
-      ..close();
-    return controller.stream;
-  }
-}
-
-class LinkStreamController {
-  final StreamController<String> controller;
-  final bool watchAll;
-
-  LinkStreamController({@required this.controller, @required this.watchAll});
-}
-
-// TODO: Refactor this class to use the new SDK instead of deprecated API
-// ignore: deprecated_member_use
-class FakeModuleDriver implements ModuleDriver {
-  final _linkValue = {};
-  final _linkStreamControllers = {};
-  final _startModuleIntents = [];
-  final _fakeModuleContext = FakeModuleContext();
-  final _fakeModuleControllerClient = FakeModuleControllerClient();
-  OnHandleIntent _onHandleIntent;
-  FakeIntentParameters _parameters;
-
-  @override
-  // ignore: use_to_and_as_if_applicable, deprecated_member_use
-  Future<ModuleDriver> start() {
-    return Future.value(this);
-  }
-
-  @override
-  set onHandleIntent(OnHandleIntent onHandleIntent) {
-    _onHandleIntent = onHandleIntent;
-  }
-
-  // Tells the module driver to create fake intent parameters which map to
-  // all the values which have been |putTestValue|'d and send it to the module.
-  void handleIntent() {
-    _parameters = FakeIntentParameters(moduleDriver: this);
-    _onHandleIntent('', _parameters);
-  }
-
-  // Value is only send to watchers registered with all = true.
-  @override
-  Future<String> put<T>(String key, T value, EntityCodec<T> codec) async {
-    _linkValue[key] = codec.encode(value);
-    List<LinkStreamController> streamContollerList =
-        _getLinkStreamControllerList(key);
-    for (var linkStreamController in streamContollerList) {
-      if (linkStreamController.watchAll) {
-        /// Encode and decode to tests codec.
-        linkStreamController.controller.add(codec.encode(value));
-      }
-    }
-    return null;
-  }
-
-  @override
-  ModuleContextClient get moduleContext => _fakeModuleContext;
-
-  @override
-  Future<T> get<T>(String linkName, EntityCodec<T> codec) async {
-    return codec.decode(_linkValue[linkName]);
-  }
-
-  @override
-  Stream<T> watch<T>(String key, EntityCodec<T> codec, {bool all = false}) {
-    // Do not combine the next two lines or dart gets confused about types.
-    // ignore: close_sinks
-    StreamController streamController = _createNewStreamController(key, all);
-    return streamController.stream.map(codec.decode);
-  }
-
-  @override
-  Future<ModuleControllerClient> startModule(
-      {@required Intent intent,
-      String name,
-      String module,
-      SurfaceRelation surfaceRelation = const SurfaceRelation(
-        arrangement: SurfaceArrangement.copresent,
-        dependency: SurfaceDependency.dependent,
-        emphasis: 0.5,
-      )}) {
-    _startModuleIntents.add(intent);
-    return Future.value(_fakeModuleControllerClient);
-  }
-
-  /// Puts a value on a link from a test. Value is sent to all watcher of the
-  /// link.
-  void putTestValue<T>(String key, T value, EntityCodec<T> codec) {
-    _linkValue[key] = codec.encode(value);
-    List<LinkStreamController> streamContollerList =
-        _getLinkStreamControllerList(key);
-    for (var linkStreamController in streamContollerList) {
-      linkStreamController.controller.add(codec.encode(value));
-    }
-  }
-
-  /// Returns the most recent value put on a link or null if no value has been
-  /// put on the link.
-  T getTestLinkCurrentValue<T>(String key, EntityCodec<T> codec) {
-    return codec.decode(_linkValue[key]);
-  }
-
-  /// Returns a list of intents that have been sent to [startModule].
-  List<Intent> getTestStartModuleIntents() {
-    return List.unmodifiable(_startModuleIntents);
-  }
-
-  void cleanUp() {
-    _linkStreamControllers.forEach((_, controllerList) =>
-        // ignore: avoid_function_literals_in_foreach_calls
-        controllerList.forEach((contoller) => contoller.controller.close()));
-  }
-
-  StreamController<String> _createNewStreamController<T>(
-      String key, bool watchAll) {
-    // Do not combine the lines in this method or dart gets confused about
-    // types.
-    StreamController<String> newController = StreamController();
-    LinkStreamController newLinkController =
-        LinkStreamController(controller: newController, watchAll: watchAll);
-    List<LinkStreamController> linkStreamControllerList =
-        _getLinkStreamControllerList(key);
-    // ignore: cascade_invocations
-    linkStreamControllerList.add(newLinkController);
-    return newController;
-  }
-
-  List<LinkStreamController> _getLinkStreamControllerList(String key) {
-    // Do not combine the lines in this method or dart gets confused about
-    // types.
-    if (!_linkStreamControllers.containsKey(key)) {
-      // ignore: close_sinks
-      List<LinkStreamController> controllerList = [];
-      _linkStreamControllers.putIfAbsent(key, () => controllerList);
-    }
-
-    return _linkStreamControllers[key];
-  }
-
-  @override
-  dynamic noSuchMethod(Invocation invocation) {
-    log.warning(
-        'Method ${invocation.memberName} not implemented in FakeModuleDriver');
-  }
-}
-
-class FakeModuleContext implements ModuleContextClient {
-  @override
-  dynamic noSuchMethod(Invocation invocation) {
-    log.warning(
-        'Method ${invocation.memberName} not implemented in FakeModuleContext');
-  }
-}
-
-class FakeModuleControllerClient implements ModuleControllerClient {
-  @override
-  dynamic noSuchMethod(Invocation invocation) {
-    log.warning(
-        'Method ${invocation.memberName} not implemented in FakeModuleControllerClient');
-  }
-}
diff --git a/public/lib/testing/app_driver/dart/pubspec.yaml b/public/lib/testing/app_driver/dart/pubspec.yaml
deleted file mode 100644
index fb3471d..0000000
--- a/public/lib/testing/app_driver/dart/pubspec.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-name: fake_module_driver
\ No newline at end of file
diff --git a/public/lib/testing/app_driver/dart/test/fake_module_driver_test.dart b/public/lib/testing/app_driver/dart/test/fake_module_driver_test.dart
deleted file mode 100644
index 6306bda..0000000
--- a/public/lib/testing/app_driver/dart/test/fake_module_driver_test.dart
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2018 The Fuchsia 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:async/async.dart';
-import 'package:lib.schemas.dart/entity_codec.dart';
-import 'package:lib.testing.app_driver.dart/fake_module_driver.dart';
-import 'package:lib.app_driver.dart/module_driver.dart';
-import 'package:test/test.dart';
-
-const _action = 'action';
-
-const _key1 = 'key1';
-const _value1 = 'value1';
-const _value2 = 'value2';
-const _value3 = 3;
-
-class _StringCodec extends EntityCodec<String> {
-  _StringCodec()
-      : super(
-          type: 'com.fuchsia.string',
-          encode: (String s) => s,
-          decode: (String s) => s,
-        );
-}
-
-class _IntCodec extends EntityCodec<int> {
-  _IntCodec()
-      : super(
-          type: 'com.fuchsia.int',
-          encode: (int i) => i.toString(),
-          decode: int.parse,
-        );
-}
-
-void main() async {
-  FakeModuleDriver moduleDriver;
-
-  setUp(() {
-    // TODO: Refactor this class to use the new SDK instead of deprecated API
-    // ignore: deprecated_member_use
-    moduleDriver = FakeModuleDriver();
-  });
-
-  test('test start', () {
-    expect(moduleDriver.start(), completion(moduleDriver));
-  });
-
-  test('put() and get() put and retrieve a Link value', () {
-    moduleDriver.put(_key1, _value1, _StringCodec());
-    moduleDriver.get(_key1, _StringCodec()).then((String key) {
-      expect(key, _value1);
-    });
-  });
-
-  test('test put and getTestLinkValue', () {
-    moduleDriver.put(_key1, _value1, _StringCodec());
-    expect(
-        moduleDriver.getTestLinkCurrentValue(_key1, _StringCodec()), _value1);
-  });
-
-  test('test put and getTestLinkValue with multiple types', () {
-    moduleDriver.put(_key1, _value1, _StringCodec());
-    expect(
-        moduleDriver.getTestLinkCurrentValue(_key1, _StringCodec()), _value1);
-
-    moduleDriver.put(_key1, _value3, _IntCodec());
-    expect(moduleDriver.getTestLinkCurrentValue(_key1, _IntCodec()), _value3);
-  });
-
-  test('test putTestValue and getTestLinkValue', () {
-    moduleDriver.putTestValue(_key1, _value1, _StringCodec());
-
-    expect(
-        moduleDriver.getTestLinkCurrentValue(_key1, _StringCodec()), _value1);
-  });
-
-  test('test putTestValue and getTestLinkValue with multiple codec types', () {
-    moduleDriver.putTestValue(_key1, _value1, _StringCodec());
-    expect(
-        moduleDriver.getTestLinkCurrentValue(_key1, _StringCodec()), _value1);
-
-    moduleDriver.putTestValue(_key1, _value3, _IntCodec());
-    expect(moduleDriver.getTestLinkCurrentValue(_key1, _IntCodec()), _value3);
-  });
-
-  test('test startModule and intent history', () {
-    Intent intent = Intent(action: _action);
-
-    moduleDriver.startModule(intent: intent);
-
-    expect(moduleDriver.getTestStartModuleIntents(), containsAll([intent]));
-  });
-
-  test('test putTestValue and watch', () {
-    StreamQueue<String> watchQueue =
-        StreamQueue<String>(moduleDriver.watch(_key1, _StringCodec()));
-    StreamQueue<String> watchQueue2 =
-        StreamQueue<String>(moduleDriver.watch(_key1, _StringCodec()));
-
-    moduleDriver
-      ..putTestValue(_key1, _value1, _StringCodec())
-      ..putTestValue(_key1, _value2, _StringCodec())
-      ..cleanUp();
-
-    expect(watchQueue, emitsInOrder([_value1, _value2]));
-    expect(watchQueue2, emitsInOrder([_value1, _value2]));
-  });
-
-  test('test putTestValue and watch with multiple codec types', () {
-    StreamQueue<String> watchQueueString =
-        StreamQueue<String>(moduleDriver.watch(_key1, _StringCodec()));
-    StreamQueue<int> watchQueueInt =
-        StreamQueue<int>(moduleDriver.watch(_key1, _IntCodec()));
-
-    moduleDriver
-      ..putTestValue(_key1, _value1, _StringCodec())
-      ..putTestValue(_key1, _value2, _StringCodec())
-      ..putTestValue(_key1, _value3, _IntCodec())
-      ..cleanUp();
-
-    expect(
-        watchQueueString, emitsInOrder([_value1, _value2, _value3.toString()]));
-    expect(watchQueueInt,
-        emitsInOrder([emitsError(anything), emitsError(anything), _value3]));
-  });
-
-  test('test put and watch', () {
-    StreamQueue<String> watchQueue = StreamQueue<String>(
-        moduleDriver.watch(_key1, _StringCodec(), all: false));
-    StreamQueue<String> watchAllQueue = StreamQueue<String>(
-        moduleDriver.watch(_key1, _StringCodec(), all: true));
-
-    moduleDriver
-      ..put(_key1, _value1, _StringCodec())
-      ..put(_key1, _value2, _StringCodec())
-      ..cleanUp();
-
-    expect(watchQueue, emitsDone);
-    expect(watchQueue.eventsDispatched, 0);
-    expect(watchAllQueue, emitsInOrder([_value1, _value2]));
-  });
-
-  test('test putTestValue and watch with multiple codec types', () {
-    StreamQueue<String> watchQueueString = StreamQueue<String>(
-        moduleDriver.watch(_key1, _StringCodec(), all: true));
-    StreamQueue<int> watchQueueInt =
-        StreamQueue<int>(moduleDriver.watch(_key1, _IntCodec(), all: true));
-
-    moduleDriver
-      ..put(_key1, _value1, _StringCodec())
-      ..put(_key1, _value2, _StringCodec())
-      ..put(_key1, _value3, _IntCodec())
-      ..cleanUp();
-
-    expect(
-        watchQueueString, emitsInOrder([_value1, _value2, _value3.toString()]));
-    expect(watchQueueInt,
-        emitsInOrder([emitsError(anything), emitsError(anything), _value3]));
-  });
-
-  tearDown(() {
-    moduleDriver.cleanUp();
-  });
-}
diff --git a/shell/ermine/BUILD.gn b/shell/ermine/BUILD.gn
index 91f6ed9..f52619e 100644
--- a/shell/ermine/BUILD.gn
+++ b/shell/ermine/BUILD.gn
@@ -87,7 +87,6 @@
     "//sdk/fidl/fuchsia.modular",
     "//third_party/dart-pkg/git/flutter/packages/flutter",
     "//topaz/public/dart/widgets:lib.widgets",
-    "//topaz/public/lib/app_driver/dart",
     "//topaz/public/lib/widgets/dart",
   ]
 }
