diff --git a/pkg/analyzer_cli/bin/fix.dart b/pkg/analyzer_cli/bin/fix.dart
new file mode 100644
index 0000000..2ef38e4
--- /dev/null
+++ b/pkg/analyzer_cli/bin/fix.dart
@@ -0,0 +1,14 @@
+#!/usr/bin/env dart
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_cli/src/fix/driver.dart';
+
+/// The entry point for dartfix.
+main(List<String> args) async {
+  Driver starter = new Driver();
+
+  // Wait for the starter to complete.
+  await starter.start(args);
+}
diff --git a/pkg/analyzer_cli/lib/src/fix/driver.dart b/pkg/analyzer_cli/lib/src/fix/driver.dart
new file mode 100644
index 0000000..5bbf033
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/fix/driver.dart
@@ -0,0 +1,209 @@
+import 'dart:async';
+
+import 'package:analyzer_cli/src/fix/options.dart';
+import 'package:analyzer_cli/src/fix/server.dart';
+import 'package:analysis_server/src/protocol/protocol_internal.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+
+class Driver {
+  static const timeout = const Duration(seconds: 5);
+
+  final Server server = new Server();
+
+  Completer serverConnected;
+  Completer analysisComplete;
+  bool verbose;
+
+  Future start(List<String> args) async {
+    final options = Options.parse(args);
+
+    /// Only happens in testing.
+    if (options == null) {
+      return null;
+    }
+    verbose = options.verbose;
+
+    serverConnected = new Completer();
+    analysisComplete = new Completer();
+
+    await startServer(options);
+    outSink.writeln('Analyzing...');
+    await setupAnalysis(options);
+
+    // TODO(danrubel): Request fixes rather than waiting for analysis complete
+    await analysisComplete.future;
+
+    outSink.writeln('Analysis complete.');
+    await stopServer(server);
+  }
+
+  Future startServer(Options options) async {
+    if (options.verbose) {
+      server.debugStdio();
+    }
+    verboseOut('Starting...');
+    await server.start(sdkPath: options.sdkPath);
+    server.listenToOutput(dispatchNotification);
+    return serverConnected.future.timeout(timeout, onTimeout: () {
+      printAndFail('Failed to connect to server');
+    });
+  }
+
+  Future setupAnalysis(Options options) async {
+    verboseOut('Setup analysis');
+
+    await server.send("server.setSubscriptions",
+        new ServerSetSubscriptionsParams([ServerService.STATUS]).toJson());
+
+    await server.send(
+        "analysis.setAnalysisRoots",
+        new AnalysisSetAnalysisRootsParams(
+          options.analysisRoots,
+          const [],
+        ).toJson());
+  }
+
+  Future stopServer(Server server) async {
+    verboseOut('Stopping...');
+    await server.send("server.shutdown", null);
+    await server.exitCode.timeout(const Duration(seconds: 5), onTimeout: () {
+      return server.kill('server failed to exit');
+    });
+  }
+
+  /**
+   * Dispatch the notification named [event], and containing parameters
+   * [params], to the appropriate stream.
+   */
+  void dispatchNotification(String event, params) {
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    switch (event) {
+      case "server.connected":
+        onServerConnected(
+            new ServerConnectedParams.fromJson(decoder, 'params', params));
+        break;
+//      case "server.error":
+//        outOfTestExpect(params, isServerErrorParams);
+//        _onServerError
+//            .add(new ServerErrorParams.fromJson(decoder, 'params', params));
+//        break;
+      case "server.status":
+        onServerStatus(
+            new ServerStatusParams.fromJson(decoder, 'params', params));
+        break;
+//      case "analysis.analyzedFiles":
+//        outOfTestExpect(params, isAnalysisAnalyzedFilesParams);
+//        _onAnalysisAnalyzedFiles.add(new AnalysisAnalyzedFilesParams.fromJson(
+//            decoder, 'params', params));
+//        break;
+//      case "analysis.closingLabels":
+//        outOfTestExpect(params, isAnalysisClosingLabelsParams);
+//        _onAnalysisClosingLabels.add(new AnalysisClosingLabelsParams.fromJson(
+//            decoder, 'params', params));
+//        break;
+      case "analysis.errors":
+        onAnalysisErrors(
+            new AnalysisErrorsParams.fromJson(decoder, 'params', params));
+        break;
+//      case "analysis.flushResults":
+//        outOfTestExpect(params, isAnalysisFlushResultsParams);
+//        _onAnalysisFlushResults.add(
+//            new AnalysisFlushResultsParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "analysis.folding":
+//        outOfTestExpect(params, isAnalysisFoldingParams);
+//        _onAnalysisFolding
+//            .add(new AnalysisFoldingParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "analysis.highlights":
+//        outOfTestExpect(params, isAnalysisHighlightsParams);
+//        _onAnalysisHighlights.add(
+//            new AnalysisHighlightsParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "analysis.implemented":
+//        outOfTestExpect(params, isAnalysisImplementedParams);
+//        _onAnalysisImplemented.add(
+//            new AnalysisImplementedParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "analysis.invalidate":
+//        outOfTestExpect(params, isAnalysisInvalidateParams);
+//        _onAnalysisInvalidate.add(
+//            new AnalysisInvalidateParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "analysis.navigation":
+//        outOfTestExpect(params, isAnalysisNavigationParams);
+//        _onAnalysisNavigation.add(
+//            new AnalysisNavigationParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "analysis.occurrences":
+//        outOfTestExpect(params, isAnalysisOccurrencesParams);
+//        _onAnalysisOccurrences.add(
+//            new AnalysisOccurrencesParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "analysis.outline":
+//        outOfTestExpect(params, isAnalysisOutlineParams);
+//        _onAnalysisOutline
+//            .add(new AnalysisOutlineParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "analysis.overrides":
+//        outOfTestExpect(params, isAnalysisOverridesParams);
+//        _onAnalysisOverrides.add(
+//            new AnalysisOverridesParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "completion.results":
+//        outOfTestExpect(params, isCompletionResultsParams);
+//        _onCompletionResults.add(
+//            new CompletionResultsParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "search.results":
+//        outOfTestExpect(params, isSearchResultsParams);
+//        _onSearchResults
+//            .add(new SearchResultsParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "execution.launchData":
+//        outOfTestExpect(params, isExecutionLaunchDataParams);
+//        _onExecutionLaunchData.add(
+//            new ExecutionLaunchDataParams.fromJson(decoder, 'params', params));
+//        break;
+//      case "flutter.outline":
+//        outOfTestExpect(params, isFlutterOutlineParams);
+//        _onFlutterOutline
+//            .add(new FlutterOutlineParams.fromJson(decoder, 'params', params));
+//        break;
+//      default:
+//        printAndFail('Unexpected notification: $event');
+//        break;
+    }
+  }
+
+  void onAnalysisErrors(AnalysisErrorsParams params) {
+    List<AnalysisError> errors = params.errors;
+    if (errors.isNotEmpty) {
+      outSink.writeln(params.file);
+      for (AnalysisError error in errors) {
+        Location loc = error.location;
+        outSink.writeln('  ${error.message}'
+            ' at ${loc.startLine}:${loc.startColumn}');
+      }
+    }
+  }
+
+  void onServerConnected(ServerConnectedParams params) {
+    verboseOut('Connected to server');
+    serverConnected.complete();
+  }
+
+  void onServerStatus(ServerStatusParams params) {
+    if (params.analysis != null && !params.analysis.isAnalyzing) {
+      verboseOut('Analysis complete');
+      analysisComplete.complete();
+    }
+  }
+
+  void verboseOut(String message) {
+    if (verbose) {
+      outSink.writeln(message);
+    }
+  }
+}
diff --git a/pkg/analyzer_cli/lib/src/fix/options.dart b/pkg/analyzer_cli/lib/src/fix/options.dart
new file mode 100644
index 0000000..802eac1
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/fix/options.dart
@@ -0,0 +1,107 @@
+import 'dart:io';
+
+import 'package:analyzer/src/util/sdk.dart';
+import 'package:args/args.dart';
+import 'package:meta/meta.dart';
+
+@visibleForTesting
+StringSink errorSink = stderr;
+
+@visibleForTesting
+StringSink outSink = stdout;
+
+@visibleForTesting
+ExitHandler exitHandler = exit;
+
+@visibleForTesting
+typedef void ExitHandler(int code);
+
+/// Command line options for `dartfix`.
+class Options {
+  String sdkPath;
+  List<String> analysisRoots;
+  bool verbose;
+
+  static Options parse(List<String> args,
+      {printAndFail(String msg) = printAndFail}) {
+    final parser = new ArgParser(allowTrailingOptions: true);
+
+    parser
+      ..addOption(_sdkPathOption, help: 'The path to the Dart SDK.')
+      ..addFlag(_helpOption,
+          abbr: 'h',
+          help:
+              'Display this help message. Add --verbose to show hidden options.',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag(_verboseOption,
+          abbr: 'v',
+          defaultsTo: false,
+          help: 'Verbose output.',
+          negatable: false);
+
+    ArgResults results;
+    try {
+      results = parser.parse(args);
+    } on FormatException catch (e) {
+      errorSink.writeln(e.message);
+      _showUsage(parser);
+      exitHandler(15);
+      return null; // Only reachable in testing.
+    }
+
+    if (results[_helpOption] as bool) {
+      _showUsage(parser);
+      exitHandler(0);
+      return null; // Only reachable in testing.
+    }
+
+    Options options = new Options._fromArgs(results);
+
+    // Check Dart SDK, and infer if unspecified.
+    options.sdkPath ??= getSdkPath(args);
+    String sdkPath = options.sdkPath;
+    if (sdkPath == null) {
+      errorSink.writeln('No Dart SDK found.');
+      _showUsage(parser);
+      return null; // Only reachable in testing.
+    }
+    if (!(new Directory(sdkPath)).existsSync()) {
+      printAndFail('Invalid Dart SDK path: $sdkPath');
+      return null; // Only reachable in testing.
+    }
+
+    // Check for files and/or directories to analyze.
+    if (options.analysisRoots == null || options.analysisRoots.isEmpty) {
+      errorSink.writeln('Expected at least one file or directory to analyze.');
+      _showUsage(parser);
+      exitHandler(15);
+      return null; // Only reachable in testing.
+    }
+
+    return options;
+  }
+
+  Options._fromArgs(ArgResults results)
+      : analysisRoots = results.rest,
+        sdkPath = results[_sdkPathOption] as String,
+        verbose = results[_verboseOption] as bool;
+
+  static _showUsage(ArgParser parser) {
+    errorSink.writeln(
+        'Usage: $_binaryName [options...] <directory or list of files>');
+    errorSink.writeln('');
+    errorSink.writeln(parser.usage);
+  }
+}
+
+const _binaryName = 'dartfix';
+const _helpOption = 'help';
+const _sdkPathOption = 'dart-sdk';
+const _verboseOption = 'verbose';
+
+/// Print the given [message] to stderr and exit with the given [exitCode].
+void printAndFail(String message, {int exitCode: 15}) {
+  errorSink.writeln(message);
+  exitHandler(exitCode);
+}
diff --git a/pkg/analyzer_cli/lib/src/fix/server.dart b/pkg/analyzer_cli/lib/src/fix/server.dart
new file mode 100644
index 0000000..31467ab
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/fix/server.dart
@@ -0,0 +1,342 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:path/path.dart';
+
+/**
+ * Type of callbacks used to process notifications.
+ */
+typedef void NotificationProcessor(String event, params);
+
+/**
+ * Instances of the class [Server] manage a connection to a server process, and
+ * facilitate communication to and from the server.
+ */
+class Server {
+  /**
+   * Server process object, or null if server hasn't been started yet.
+   */
+  Process _process;
+
+  /**
+   * Commands that have been sent to the server but not yet acknowledged, and
+   * the [Completer] objects which should be completed when acknowledgement is
+   * received.
+   */
+  final Map<String, Completer<Map<String, dynamic>>> _pendingCommands =
+      <String, Completer<Map<String, dynamic>>>{};
+
+  /**
+   * Number which should be used to compute the 'id' to send in the next command
+   * sent to the server.
+   */
+  int _nextId = 0;
+
+  /**
+   * Messages which have been exchanged with the server; we buffer these
+   * up until the test finishes, so that they can be examined in the debugger
+   * or printed out in response to a call to [debugStdio].
+   */
+  final List<String> _recordedStdio = <String>[];
+
+  /**
+   * True if we are currently printing out messages exchanged with the server.
+   */
+  bool _debuggingStdio = false;
+
+  /**
+   * True if we've received bad data from the server, and we are aborting the
+   * test.
+   */
+  bool _receivedBadDataFromServer = false;
+
+  /**
+   * Stopwatch that we use to generate timing information for debug output.
+   */
+  Stopwatch _time = new Stopwatch();
+
+  /**
+   * The [currentElapseTime] at which the last communication was received from the server
+   * or `null` if no communication has been received.
+   */
+  double lastCommunicationTime;
+
+  /**
+   * The current elapse time (seconds) since the server was started.
+   */
+  double get currentElapseTime => _time.elapsedTicks / _time.frequency;
+
+  /**
+   * Future that completes when the server process exits.
+   */
+  Future<int> get exitCode => _process.exitCode;
+
+  /**
+   * Print out any messages exchanged with the server.  If some messages have
+   * already been exchanged with the server, they are printed out immediately.
+   */
+  void debugStdio() {
+    if (_debuggingStdio) {
+      return;
+    }
+    _debuggingStdio = true;
+    for (String line in _recordedStdio) {
+      print(line);
+    }
+  }
+
+  /**
+   * Find the root directory of the analysis_server package by proceeding
+   * upward to the 'test' dir, and then going up one more directory.
+   */
+  String findRoot(String pathname) {
+    while (!['benchmark', 'test'].contains(basename(pathname))) {
+      String parent = dirname(pathname);
+      if (parent.length >= pathname.length) {
+        throw new Exception("Can't find root directory");
+      }
+      pathname = parent;
+    }
+    return dirname(pathname);
+  }
+
+  /**
+   * Return a future that will complete when all commands that have been sent
+   * to the server so far have been flushed to the OS buffer.
+   */
+  Future flushCommands() {
+    return _process.stdin.flush();
+  }
+
+  /**
+   * Stop the server.
+   */
+  Future<int> kill(String reason) {
+    debugStdio();
+    _recordStdio('FORCIBLY TERMINATING PROCESS: $reason');
+    _process.kill();
+    return _process.exitCode;
+  }
+
+  /**
+   * Start listening to output from the server, and deliver notifications to
+   * [notificationProcessor].
+   */
+  void listenToOutput(NotificationProcessor notificationProcessor) {
+    _process.stdout
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((String line) {
+      lastCommunicationTime = currentElapseTime;
+      String trimmedLine = line.trim();
+
+      // Guard against lines like:
+      //   {"event":"server.connected","params":{...}}Observatory listening on ...
+      final String observatoryMessage = 'Observatory listening on ';
+      if (trimmedLine.contains(observatoryMessage)) {
+        trimmedLine = trimmedLine
+            .substring(0, trimmedLine.indexOf(observatoryMessage))
+            .trim();
+      }
+      if (trimmedLine.isEmpty) {
+        return;
+      }
+
+      _recordStdio('<== $trimmedLine');
+      var message;
+      try {
+        message = json.decoder.convert(trimmedLine);
+      } catch (exception) {
+        _badDataFromServer('JSON decode failure: $exception');
+        return;
+      }
+      Map messageAsMap = message;
+      if (messageAsMap.containsKey('id')) {
+        String id = message['id'];
+        Completer<Map<String, dynamic>> completer = _pendingCommands[id];
+        if (completer == null) {
+          throw 'Unexpected response from server: id=$id';
+        } else {
+          _pendingCommands.remove(id);
+        }
+        if (messageAsMap.containsKey('error')) {
+          completer.completeError(new ServerErrorMessage(messageAsMap));
+        } else {
+          Map<String, dynamic> result = messageAsMap['result'];
+          completer.complete(result);
+        }
+      } else {
+        String event = messageAsMap['event'];
+        notificationProcessor(event, messageAsMap['params']);
+      }
+    });
+    _process.stderr
+        .transform((new Utf8Codec()).decoder)
+        .transform(new LineSplitter())
+        .listen((String line) {
+      String trimmedLine = line.trim();
+      _recordStdio('ERR:  $trimmedLine');
+      _badDataFromServer('Message received on stderr', silent: true);
+    });
+  }
+
+  /**
+   * Send a command to the server.  An 'id' will be automatically assigned.
+   * The returned [Future] will be completed when the server acknowledges the
+   * command with a response.  If the server acknowledges the command with a
+   * normal (non-error) response, the future will be completed with the 'result'
+   * field from the response.  If the server acknowledges the command with an
+   * error response, the future will be completed with an error.
+   */
+  Future<Map<String, dynamic>> send(
+      String method, Map<String, dynamic> params) {
+    String id = '${_nextId++}';
+    Map<String, dynamic> command = <String, dynamic>{
+      'id': id,
+      'method': method
+    };
+    if (params != null) {
+      command['params'] = params;
+    }
+    Completer<Map<String, dynamic>> completer =
+        new Completer<Map<String, dynamic>>();
+    _pendingCommands[id] = completer;
+    String line = json.encode(command);
+    _recordStdio('==> $line');
+    _process.stdin.add(utf8.encoder.convert("$line\n"));
+    return completer.future;
+  }
+
+  /**
+   * Start the server. If [profileServer] is `true`, the server will be started
+   * with "--observe" and "--pause-isolates-on-exit", allowing the observatory
+   * to be used.
+   */
+  Future start({
+    int diagnosticPort,
+    String instrumentationLogFile,
+    bool profileServer: false,
+    String sdkPath,
+    int servicesPort,
+    bool useAnalysisHighlight2: false,
+  }) async {
+    if (_process != null) {
+      throw new Exception('Process already started');
+    }
+    _time.start();
+    String dartBinary = Platform.executable;
+
+    // The integration tests run 3x faster when run from snapshots (you need to
+    // run test.py with --use-sdk).
+    final bool useSnapshot = true;
+    String serverPath;
+
+    if (useSnapshot) {
+      // Look for snapshots/analysis_server.dart.snapshot.
+      serverPath = normalize(join(dirname(Platform.resolvedExecutable),
+          'snapshots', 'analysis_server.dart.snapshot'));
+
+      if (!FileSystemEntity.isFileSync(serverPath)) {
+        // Look for dart-sdk/bin/snapshots/analysis_server.dart.snapshot.
+        serverPath = normalize(join(dirname(Platform.resolvedExecutable),
+            'dart-sdk', 'bin', 'snapshots', 'analysis_server.dart.snapshot'));
+      }
+    } else {
+      String rootDir =
+          findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
+      serverPath = normalize(join(rootDir, 'bin', 'server.dart'));
+    }
+
+    List<String> arguments = [];
+    //
+    // Add VM arguments.
+    //
+    if (profileServer) {
+      if (servicesPort == null) {
+        arguments.add('--observe');
+      } else {
+        arguments.add('--observe=$servicesPort');
+      }
+      arguments.add('--pause-isolates-on-exit');
+    } else if (servicesPort != null) {
+      arguments.add('--enable-vm-service=$servicesPort');
+    }
+    if (Platform.packageConfig != null) {
+      arguments.add('--packages=${Platform.packageConfig}');
+    }
+    //
+    // Add the server executable.
+    //
+    arguments.add(serverPath);
+    //
+    // Add server arguments.
+    //
+    arguments.add('--suppress-analytics');
+    if (diagnosticPort != null) {
+      arguments.add('--port');
+      arguments.add(diagnosticPort.toString());
+    }
+    if (instrumentationLogFile != null) {
+      arguments.add('--instrumentation-log-file=$instrumentationLogFile');
+    }
+    if (sdkPath != null) {
+      arguments.add('--sdk=$sdkPath');
+    }
+    if (useAnalysisHighlight2) {
+      arguments.add('--useAnalysisHighlight2');
+    }
+    _process = await Process.start(dartBinary, arguments);
+    _process.exitCode.then((int code) {
+      if (code != 0) {
+        _badDataFromServer('server terminated with exit code $code');
+      }
+    });
+  }
+
+  /**
+   * Deal with bad data received from the server.
+   */
+  void _badDataFromServer(String details, {bool silent: false}) {
+    if (!silent) {
+      _recordStdio('BAD DATA FROM SERVER: $details');
+    }
+    if (_receivedBadDataFromServer) {
+      // We're already dealing with it.
+      return;
+    }
+    _receivedBadDataFromServer = true;
+    debugStdio();
+    // Give the server 1 second to continue outputting bad data
+    // such as outputting a stacktrace.
+    new Future.delayed(new Duration(seconds: 1), () {
+      throw 'Bad data received from server: $details';
+    });
+  }
+
+  /**
+   * Record a message that was exchanged with the server, and print it out if
+   * [debugStdio] has been called.
+   */
+  void _recordStdio(String line) {
+    double elapsedTime = currentElapseTime;
+    line = "$elapsedTime: $line";
+    if (_debuggingStdio) {
+      print(line);
+    }
+    _recordedStdio.add(line);
+  }
+}
+
+/**
+ * An error result from a server request.
+ */
+class ServerErrorMessage {
+  final Map message;
+
+  ServerErrorMessage(this.message);
+
+  dynamic get error => message['error'];
+
+  String toString() => message.toString();
+}
