diff --git a/pkg/frontend_server/lib/compute_kernel.dart b/pkg/frontend_server/lib/compute_kernel.dart
new file mode 100644
index 0000000..b6c5616
--- /dev/null
+++ b/pkg/frontend_server/lib/compute_kernel.dart
@@ -0,0 +1,426 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.8
+
+/// A library to invoke the CFE to compute kernel summary files.
+///
+/// Used by `utils/bazel/kernel_worker.dart`.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:build_integration/file_system/multi_root.dart';
+import 'package:compiler/src/kernel/dart2js_target.dart';
+import 'package:dev_compiler/src/kernel/target.dart';
+import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe;
+import 'package:kernel/ast.dart' show Component, Library, Reference;
+import 'package:kernel/target/targets.dart';
+import 'package:vm/target/flutter.dart';
+import 'package:vm/target/flutter_runner.dart';
+import 'package:vm/target/vm.dart';
+
+/// If the last arg starts with `@`, this reads the file it points to and treats
+/// each line as an additional arg.
+///
+/// This is how individual work request args are differentiated from startup
+/// args in bazel (individual work request args go in that file).
+List<String> preprocessArgs(List<String> args) {
+  args = new List.from(args);
+  if (args.isEmpty) {
+    return args;
+  }
+  String lastArg = args.last;
+  if (lastArg.startsWith('@')) {
+    File argsFile = new File(lastArg.substring(1));
+    try {
+      args.removeLast();
+      args.addAll(argsFile.readAsLinesSync());
+    } on FileSystemException catch (e) {
+      throw new Exception('Failed to read file specified by $lastArg : $e');
+    }
+  }
+  return args;
+}
+
+/// An [ArgParser] for generating kernel summaries.
+final summaryArgsParser = new ArgParser()
+  ..addFlag('help', negatable: false, abbr: 'h')
+  ..addFlag('exclude-non-sources',
+      negatable: false,
+      help: 'Whether source files loaded implicitly should be included as '
+          'part of the summary.')
+  ..addFlag('summary-only',
+      defaultsTo: true,
+      negatable: true,
+      help: 'Whether to only build summary files.')
+  ..addOption('target',
+      allowed: const [
+        'vm',
+        'flutter',
+        'flutter_runner',
+        'dart2js',
+        'ddc',
+      ],
+      help: 'Build kernel for the vm, flutter, flutter_runner, dart2js or ddc')
+  ..addOption('dart-sdk-summary')
+  ..addMultiOption('input-summary')
+  ..addMultiOption('input-linked')
+  ..addMultiOption('multi-root')
+  ..addOption('multi-root-scheme', defaultsTo: 'org-dartlang-multi-root')
+  ..addOption('libraries-file')
+  ..addOption('packages-file')
+  ..addMultiOption('source')
+  ..addOption('output')
+  ..addFlag('reuse-compiler-result', defaultsTo: false)
+  ..addFlag('use-incremental-compiler', defaultsTo: false)
+  ..addOption('used-inputs')
+  ..addFlag('track-widget-creation', defaultsTo: false)
+  ..addMultiOption('enable-experiment',
+      help: 'Enable a language experiment when invoking the CFE.')
+  ..addMultiOption('define', abbr: 'D')
+  ..addFlag('verbose', defaultsTo: false)
+  ..addFlag('sound-null-safety', defaultsTo: false)
+  ..addOption('verbosity',
+      defaultsTo: fe.Verbosity.defaultValue,
+      help: 'Sets the verbosity level used for filtering messages during '
+          'compilation.',
+      allowed: fe.Verbosity.allowedValues,
+      allowedHelp: fe.Verbosity.allowedValuesHelp);
+
+class ComputeKernelResult {
+  final bool succeeded;
+  final fe.InitializedCompilerState previousState;
+
+  ComputeKernelResult(this.succeeded, this.previousState);
+}
+
+/// Computes a kernel file based on [args].
+///
+/// If [isWorker] is true then exit codes will not be set on failure.
+///
+/// If [outputBuffer] is provided then messages will be written to that buffer
+/// instead of printed to the console.
+///
+/// Returns whether or not the summary was successfully output.
+Future<ComputeKernelResult> computeKernel(List<String> args,
+    {bool isWorker: false,
+    StringBuffer outputBuffer,
+    Map<Uri, List<int>> inputDigests,
+    fe.InitializedCompilerState previousState}) async {
+  inputDigests ??= <Uri, List<int>>{};
+  dynamic out = outputBuffer ?? stderr;
+  bool succeeded = true;
+
+  var parsedArgs = summaryArgsParser.parse(args);
+
+  if (parsedArgs['help']) {
+    out.writeln(summaryArgsParser.usage);
+    if (!isWorker) exit(0);
+    return new ComputeKernelResult(false, previousState);
+  }
+
+  // Bazel creates an overlay file system where some files may be located in the
+  // source tree, some in a gendir, and some in a bindir. The multi-root file
+  // system hides this from the front end.
+  var multiRoots = parsedArgs['multi-root'].map(Uri.base.resolve).toList();
+  if (multiRoots.isEmpty) multiRoots.add(Uri.base);
+  var fileSystem = new MultiRootFileSystem(parsedArgs['multi-root-scheme'],
+      multiRoots, fe.StandardFileSystem.instance);
+  var sources = (parsedArgs['source'] as List<String>).map(toUri).toList();
+  var excludeNonSources = parsedArgs['exclude-non-sources'] as bool;
+
+  var nnbdMode = parsedArgs['sound-null-safety'] as bool
+      ? fe.NnbdMode.Strong
+      : fe.NnbdMode.Weak;
+  var summaryOnly = parsedArgs['summary-only'] as bool;
+  var trackWidgetCreation = parsedArgs['track-widget-creation'] as bool;
+
+  // TODO(sigmund,jakemac): make target mandatory. We allow null to be backwards
+  // compatible while we migrate existing clients of this tool.
+  var targetName =
+      (parsedArgs['target'] as String) ?? (summaryOnly ? 'ddc' : 'vm');
+  var targetFlags = new TargetFlags(
+      trackWidgetCreation: trackWidgetCreation,
+      enableNullSafety: nnbdMode == fe.NnbdMode.Strong);
+  Target target;
+  switch (targetName) {
+    case 'vm':
+      target = new VmTarget(targetFlags);
+      if (summaryOnly) {
+        out.writeln('error: --summary-only not supported for the vm target');
+      }
+      break;
+    case 'flutter':
+      target = new FlutterTarget(targetFlags);
+      if (summaryOnly) {
+        throw new ArgumentError(
+            'error: --summary-only not supported for the flutter target');
+      }
+      break;
+    case 'flutter_runner':
+      target = new FlutterRunnerTarget(targetFlags);
+      if (summaryOnly) {
+        throw new ArgumentError('error: --summary-only not supported for the '
+            'flutter_runner target');
+      }
+      break;
+    case 'dart2js':
+      target = new Dart2jsTarget('dart2js', targetFlags);
+      if (summaryOnly) {
+        out.writeln(
+            'error: --summary-only not supported for the dart2js target');
+      }
+      break;
+    case 'ddc':
+      // TODO(jakemac):If `generateKernel` changes to return a summary
+      // component, process the component instead.
+      target =
+          new DevCompilerSummaryTarget(sources, excludeNonSources, targetFlags);
+      if (!summaryOnly) {
+        out.writeln('error: --no-summary-only not supported for the '
+            'ddc target');
+      }
+      break;
+    default:
+      out.writeln('error: unsupported target: $targetName');
+  }
+
+  List<Uri> linkedInputs =
+      (parsedArgs['input-linked'] as List<String>).map(toUri).toList();
+
+  List<Uri> summaryInputs =
+      (parsedArgs['input-summary'] as List<String>).map(toUri).toList();
+
+  fe.InitializedCompilerState state;
+  bool usingIncrementalCompiler = false;
+  bool recordUsedInputs = parsedArgs["used-inputs"] != null;
+  var environmentDefines = _parseEnvironmentDefines(parsedArgs['define']);
+  var verbose = parsedArgs['verbose'] as bool;
+  var verbosity = fe.Verbosity.parseArgument(parsedArgs['verbosity']);
+
+  if (parsedArgs['use-incremental-compiler']) {
+    usingIncrementalCompiler = true;
+
+    // If digests weren't given and if not in worker mode, create fake data and
+    // ensure we don't have a previous state (as that wouldn't be safe with
+    // fake input digests).
+    if (!isWorker && inputDigests.isEmpty) {
+      previousState = null;
+      inputDigests[toUri(parsedArgs['dart-sdk-summary'])] = const [0];
+      for (Uri uri in summaryInputs) {
+        inputDigests[uri] = const [0];
+      }
+      for (Uri uri in linkedInputs) {
+        inputDigests[uri] = const [0];
+      }
+    }
+
+    state = await fe.initializeIncrementalCompiler(
+        previousState,
+        {
+          "target=$targetName",
+          "trackWidgetCreation=$trackWidgetCreation",
+          "multiRootScheme=${fileSystem.markerScheme}",
+          "multiRootRoots=${fileSystem.roots}",
+        },
+        toUri(parsedArgs['dart-sdk-summary']),
+        toUri(parsedArgs['packages-file']),
+        toUri(parsedArgs['libraries-file']),
+        [...summaryInputs, ...linkedInputs],
+        inputDigests,
+        target,
+        fileSystem,
+        (parsedArgs['enable-experiment'] as List<String>),
+        summaryOnly,
+        environmentDefines,
+        trackNeededDillLibraries: recordUsedInputs,
+        verbose: verbose,
+        nnbdMode: nnbdMode);
+  } else {
+    state = await fe.initializeCompiler(
+        // TODO(sigmund): pass an old state once we can make use of it.
+        null,
+        toUri(parsedArgs['dart-sdk-summary']),
+        toUri(parsedArgs['libraries-file']),
+        toUri(parsedArgs['packages-file']),
+        [...summaryInputs, ...linkedInputs],
+        target,
+        fileSystem,
+        parsedArgs['enable-experiment'] as List<String>,
+        environmentDefines,
+        verbose: verbose,
+        nnbdMode: nnbdMode);
+  }
+
+  void onDiagnostic(fe.DiagnosticMessage message) {
+    if (fe.Verbosity.shouldPrint(verbosity, message)) {
+      fe.printDiagnosticMessage(message, out.writeln);
+    }
+    if (message.severity == fe.Severity.error) {
+      succeeded = false;
+    }
+  }
+
+  List<int> kernel;
+  bool wroteUsedDills = false;
+  if (usingIncrementalCompiler) {
+    state.options.onDiagnostic = onDiagnostic;
+    Component incrementalComponent = await state.incrementalCompiler
+        .computeDelta(entryPoints: sources, fullComponent: true);
+
+    if (recordUsedInputs) {
+      Set<Uri> usedOutlines = {};
+      for (Library lib in state.incrementalCompiler.neededDillLibraries) {
+        if (lib.importUri.scheme == "dart") continue;
+        Uri uri = state.libraryToInputDill[lib.importUri];
+        if (uri == null) {
+          throw new StateError("Library ${lib.importUri} was recorded as used, "
+              "but was not in the list of known libraries.");
+        }
+        usedOutlines.add(uri);
+      }
+      var outputUsedFile = new File(parsedArgs["used-inputs"]);
+      outputUsedFile.createSync(recursive: true);
+      outputUsedFile.writeAsStringSync(usedOutlines.join("\n"));
+      wroteUsedDills = true;
+    }
+
+    kernel = await state.incrementalCompiler.context.runInContext((_) {
+      if (summaryOnly) {
+        incrementalComponent.uriToSource.clear();
+        incrementalComponent.problemsAsJson = null;
+        incrementalComponent.setMainMethodAndMode(
+            null, true, incrementalComponent.mode);
+        target.performOutlineTransformations(incrementalComponent);
+        makeStable(incrementalComponent);
+        return Future.value(fe.serializeComponent(incrementalComponent,
+            includeSources: false, includeOffsets: false));
+      }
+
+      makeStable(incrementalComponent);
+
+      return Future.value(fe.serializeComponent(incrementalComponent,
+          filter: excludeNonSources
+              ? (library) => sources.contains(library.importUri)
+              : null,
+          includeOffsets: true));
+    });
+  } else if (summaryOnly) {
+    kernel = await fe.compileSummary(state, sources, onDiagnostic,
+        includeOffsets: false);
+  } else {
+    Component component =
+        await fe.compileComponent(state, sources, onDiagnostic);
+    kernel = fe.serializeComponent(component,
+        filter: excludeNonSources
+            ? (library) => sources.contains(library.importUri)
+            : null,
+        includeOffsets: true);
+  }
+  state.options.onDiagnostic = null; // See http://dartbug.com/36983.
+
+  if (!wroteUsedDills && recordUsedInputs) {
+    // The path taken didn't record inputs used: Say we used everything.
+    var outputUsedFile = new File(parsedArgs["used-inputs"]);
+    outputUsedFile.createSync(recursive: true);
+    Set<Uri> allFiles = {...summaryInputs, ...linkedInputs};
+    outputUsedFile.writeAsStringSync(allFiles.join("\n"));
+    wroteUsedDills = true;
+  }
+
+  if (kernel != null) {
+    var outputFile = new File(parsedArgs['output']);
+    outputFile.createSync(recursive: true);
+    outputFile.writeAsBytesSync(kernel);
+  } else {
+    assert(!succeeded);
+  }
+
+  return new ComputeKernelResult(succeeded, state);
+}
+
+/// Make sure the output is stable by sorting libraries and additional exports.
+void makeStable(Component c) {
+  // Make sure the output is stable.
+  c.libraries.sort((l1, l2) {
+    return "${l1.fileUri}".compareTo("${l2.fileUri}");
+  });
+  c.problemsAsJson?.sort();
+  c.computeCanonicalNames();
+  for (Library library in c.libraries) {
+    library.additionalExports.sort((Reference r1, Reference r2) {
+      return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
+    });
+    library.problemsAsJson?.sort();
+  }
+}
+
+/// Extends the DevCompilerTarget to transform outlines to meet the requirements
+/// of summaries in bazel and package-build.
+///
+/// Build systems like package-build may provide the same input file twice to
+/// the summary worker, but only intends to have it in one output summary.  The
+/// convention is that if it is listed as a source, it is intended to be part of
+/// the output, if the source file was loaded as a dependency, then it was
+/// already included in a different summary.  The transformation below ensures
+/// that the output summary doesn't include those implicit inputs.
+///
+/// Note: this transformation is destructive and is only intended to be used
+/// when generating summaries.
+class DevCompilerSummaryTarget extends DevCompilerTarget {
+  final List<Uri> sources;
+  final bool excludeNonSources;
+
+  DevCompilerSummaryTarget(
+      this.sources, this.excludeNonSources, TargetFlags targetFlags)
+      : super(targetFlags);
+
+  @override
+  void performOutlineTransformations(Component component) {
+    super.performOutlineTransformations(component);
+    if (!excludeNonSources) return;
+
+    List<Library> libraries = new List.from(component.libraries);
+    component.libraries.clear();
+    Set<Uri> include = sources.toSet();
+    for (var lib in libraries) {
+      if (include.contains(lib.importUri)) {
+        component.libraries.add(lib);
+      } else {
+        // Excluding the library also means that their canonical names will not
+        // be computed as part of serialization, so we need to do that
+        // preemtively here to avoid errors when serializing references to
+        // elements of these libraries.
+        component.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
+        lib.computeCanonicalNames();
+      }
+    }
+  }
+}
+
+Uri toUri(String uriString) {
+  if (uriString == null) return null;
+  // Windows-style paths use '\', so convert them to '/' in case they've been
+  // concatenated with Unix-style paths.
+  return Uri.base.resolve(uriString.replaceAll("\\", "/"));
+}
+
+Map<String, String> _parseEnvironmentDefines(List<String> args) {
+  var environment = <String, String>{};
+
+  for (var arg in args) {
+    var eq = arg.indexOf('=');
+    if (eq <= 0) {
+      var kind = eq == 0 ? 'name' : 'value';
+      throw FormatException('no $kind given to -D option `$arg`');
+    }
+    var name = arg.substring(0, eq);
+    var value = arg.substring(eq + 1);
+    environment[name] = value;
+  }
+
+  return environment;
+}
diff --git a/pkg/frontend_server/pubspec.yaml b/pkg/frontend_server/pubspec.yaml
index 7932dab..504c493 100644
--- a/pkg/frontend_server/pubspec.yaml
+++ b/pkg/frontend_server/pubspec.yaml
@@ -8,6 +8,10 @@
 
 dependencies:
   args: ^1.4.4
+  build_integration:
+    path: ../build_integration
+  compiler:
+    path: ../compiler
   dev_compiler:
     path: ../dev_compiler
   front_end:
diff --git a/pkg/frontend_server/test/frontend_server_flutter.dart b/pkg/frontend_server/test/frontend_server_flutter.dart
index d238293..efcfe51 100644
--- a/pkg/frontend_server/test/frontend_server_flutter.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter.dart
@@ -6,6 +6,12 @@
 import 'package:kernel/kernel.dart' show loadComponentFromBytes;
 import 'package:kernel/verifier.dart' show verifyComponent;
 
+import 'package:front_end/src/api_prototype/language_version.dart'
+    show uriUsesLegacyLanguageVersion;
+
+import 'package:front_end/src/api_unstable/vm.dart'
+    show CompilerOptions, NnbdMode, StandardFileSystem;
+
 import '../lib/frontend_server.dart';
 
 main(List<String> args) async {
@@ -22,6 +28,20 @@
   await compileTests(flutterDir, flutterPlatformDir, new StdoutLogger());
 }
 
+Future<NnbdMode> _getNNBDMode(Uri script, Uri packagesFileUri) async {
+  final CompilerOptions compilerOptions = new CompilerOptions()
+    ..sdkRoot = null
+    ..fileSystem = StandardFileSystem.instance
+    ..packagesFileUri = packagesFileUri
+    ..sdkSummary = null
+    ..nnbdMode = NnbdMode.Weak;
+
+  if (await uriUsesLegacyLanguageVersion(script, compilerOptions)) {
+    return NnbdMode.Weak;
+  }
+  return NnbdMode.Strong;
+}
+
 Future compileTests(String flutterDir, String flutterPlatformDir, Logger logger,
     {String filter}) async {
   if (flutterDir == null || !(new Directory(flutterDir).existsSync())) {
@@ -68,34 +88,63 @@
 
   List<String> allCompilationErrors = [];
   for (File dotPackage in dotPackagesFiles) {
-    Directory tempDir;
     Directory systemTempDir = Directory.systemTemp;
-    tempDir = systemTempDir.createTempSync('flutter_frontend_test');
-    try {
-      Directory testDir =
-          new Directory.fromUri(dotPackage.parent.uri.resolve("test/"));
-      if (!testDir.existsSync()) continue;
-      if (testDir.toString().contains("packages/flutter_web_plugins/test/")) {
-        // TODO(jensj): Figure out which tests are web-tests, and compile those
-        // in a setup that can handle that.
-        continue;
+    Directory tempDir;
+    Directory testDir =
+        new Directory.fromUri(dotPackage.parent.uri.resolve("test/"));
+    if (!testDir.existsSync()) continue;
+    if (testDir.toString().contains("packages/flutter_web_plugins/test/")) {
+      // TODO(jensj): Figure out which tests are web-tests, and compile those
+      // in a setup that can handle that.
+      continue;
+    }
+    logger.notice("Go for $testDir");
+    List<File> testFiles =
+        new List<File>.from(testDir.listSync(recursive: true).where((f) {
+      if (!f.path.endsWith("_test.dart")) return false;
+      if (filter != null) {
+        String testName = f.path.substring(flutterDirectory.path.length);
+        if (!testName.startsWith(filter)) return false;
       }
-      logger.notice("Go for $testDir");
-      List<String> compilationErrors = await attemptStuff(
-          tempDir,
-          flutterPlatformDirectory,
-          dotPackage,
-          testDir,
-          flutterDirectory,
-          logger,
-          filter);
-      if (compilationErrors.isNotEmpty) {
-        logger.notice("Notice that we had ${compilationErrors.length} "
-            "compilation errors for $testDir");
-        allCompilationErrors.addAll(compilationErrors);
+      return true;
+    }));
+
+    // Split into NNBD Strong and Weak so only the ones that match are
+    // compiled togeher. If mixing-and-matching the first file (which could
+    // be either) will setup the compiler which can lead to compilation errors
+    // for another file, for instance if the first one is strong but a
+    // subsequent one tries to opt out (i.e. is weak) an error is issued that
+    // that's not possible.
+    List<File> weak = [];
+    List<File> strong = [];
+    for (File file in testFiles) {
+      if (await _getNNBDMode(file.uri, dotPackage.uri) == NnbdMode.Weak) {
+        weak.add(file);
+      } else {
+        strong.add(file);
       }
-    } finally {
-      tempDir.delete(recursive: true);
+    }
+    for (List<File> files in [weak, strong]) {
+      if (files.isEmpty) continue;
+      tempDir = systemTempDir.createTempSync('flutter_frontend_test');
+      try {
+        List<String> compilationErrors = await attemptStuff(
+            files,
+            tempDir,
+            flutterPlatformDirectory,
+            dotPackage,
+            testDir,
+            flutterDirectory,
+            logger,
+            filter);
+        if (compilationErrors.isNotEmpty) {
+          logger.notice("Notice that we had ${compilationErrors.length} "
+              "compilation errors for $testDir");
+          allCompilationErrors.addAll(compilationErrors);
+        }
+      } finally {
+        tempDir.delete(recursive: true);
+      }
     }
   }
   if (allCompilationErrors.isNotEmpty) {
@@ -107,6 +156,7 @@
 }
 
 Future<List<String>> attemptStuff(
+    List<File> testFiles,
     Directory tempDir,
     Directory flutterPlatformDirectory,
     File dotPackage,
@@ -114,15 +164,6 @@
     Directory flutterDirectory,
     Logger logger,
     String filter) async {
-  List<File> testFiles =
-      new List<File>.from(testDir.listSync(recursive: true).where((f) {
-    if (!f.path.endsWith("_test.dart")) return false;
-    if (filter != null) {
-      String testName = f.path.substring(flutterDirectory.path.length);
-      if (!testName.startsWith(filter)) return false;
-    }
-    return true;
-  }));
   if (testFiles.isEmpty) return [];
 
   File dillFile = new File('${tempDir.path}/dill.dill');
diff --git a/tools/VERSION b/tools/VERSION
index 97d190e..2d5a96a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 167
+PRERELEASE 168
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index 96f1e9a..3e68ac6 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -15,17 +15,9 @@
 import 'dart:io';
 import 'dart:isolate';
 
-import 'package:args/args.dart';
 import 'package:bazel_worker/bazel_worker.dart';
-import 'package:build_integration/file_system/multi_root.dart';
-import 'package:dev_compiler/src/kernel/target.dart';
 import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe;
-import 'package:kernel/ast.dart' show Component, Library, Reference;
-import 'package:kernel/target/targets.dart';
-import 'package:vm/target/vm.dart';
-import 'package:vm/target/flutter.dart';
-import 'package:vm/target/flutter_runner.dart';
-import 'package:compiler/src/kernel/dart2js_target.dart';
+import 'package:frontend_server/compute_kernel.dart';
 
 /// [sendPort] may be passed in when started in an isolate. If provided, it is
 /// used for bazel worker communication instead of stdin/stdout.
@@ -68,10 +60,17 @@
       } else {
         previousState = null;
       }
+
+      /// Build a map of uris to digests.
+      final inputDigests = <Uri, List<int>>{};
+      for (var input in request.inputs) {
+        inputDigests[toUri(input.path)] = input.digest;
+      }
+
       var result = await computeKernel(request.arguments,
           isWorker: true,
           outputBuffer: outputBuffer,
-          inputs: request.inputs,
+          inputDigests: inputDigests,
           previousState: previousStateToPass);
       previousState = result.previousState;
       if (!result.succeeded) {
@@ -86,413 +85,3 @@
     return response;
   }
 }
-
-/// If the last arg starts with `@`, this reads the file it points to and treats
-/// each line as an additional arg.
-///
-/// This is how individual work request args are differentiated from startup
-/// args in bazel (inidividual work request args go in that file).
-List<String> preprocessArgs(List<String> args) {
-  args = new List.from(args);
-  if (args.isEmpty) {
-    return args;
-  }
-  String lastArg = args.last;
-  if (lastArg.startsWith('@')) {
-    File argsFile = new File(lastArg.substring(1));
-    try {
-      args.removeLast();
-      args.addAll(argsFile.readAsLinesSync());
-    } on FileSystemException catch (e) {
-      throw new Exception('Failed to read file specified by $lastArg : $e');
-    }
-  }
-  return args;
-}
-
-/// An [ArgParser] for generating kernel summaries.
-final summaryArgsParser = new ArgParser()
-  ..addFlag('help', negatable: false, abbr: 'h')
-  ..addFlag('exclude-non-sources',
-      negatable: false,
-      help: 'Whether source files loaded implicitly should be included as '
-          'part of the summary.')
-  ..addFlag('summary-only',
-      defaultsTo: true,
-      negatable: true,
-      help: 'Whether to only build summary files.')
-  ..addOption('target',
-      allowed: const [
-        'vm',
-        'flutter',
-        'flutter_runner',
-        'dart2js',
-        'ddc',
-      ],
-      help: 'Build kernel for the vm, flutter, flutter_runner, dart2js or ddc')
-  ..addOption('dart-sdk-summary')
-  ..addMultiOption('input-summary')
-  ..addMultiOption('input-linked')
-  ..addMultiOption('multi-root')
-  ..addOption('multi-root-scheme', defaultsTo: 'org-dartlang-multi-root')
-  ..addOption('libraries-file')
-  ..addOption('packages-file')
-  ..addMultiOption('source')
-  ..addOption('output')
-  ..addFlag('reuse-compiler-result', defaultsTo: false)
-  ..addFlag('use-incremental-compiler', defaultsTo: false)
-  ..addOption('used-inputs')
-  ..addFlag('track-widget-creation', defaultsTo: false)
-  ..addMultiOption('enable-experiment',
-      help: 'Enable a language experiment when invoking the CFE.')
-  ..addMultiOption('define', abbr: 'D')
-  ..addFlag('verbose', defaultsTo: false)
-  ..addFlag('sound-null-safety', defaultsTo: false)
-  ..addOption('verbosity',
-      defaultsTo: fe.Verbosity.defaultValue,
-      help: 'Sets the verbosity level used for filtering messages during '
-          'compilation.',
-      allowed: fe.Verbosity.allowedValues,
-      allowedHelp: fe.Verbosity.allowedValuesHelp);
-
-class ComputeKernelResult {
-  final bool succeeded;
-  final fe.InitializedCompilerState previousState;
-
-  ComputeKernelResult(this.succeeded, this.previousState);
-}
-
-/// Computes a kernel file based on [args].
-///
-/// If [isWorker] is true then exit codes will not be set on failure.
-///
-/// If [outputBuffer] is provided then messages will be written to that buffer
-/// instead of printed to the console.
-///
-/// Returns whether or not the summary was successfully output.
-Future<ComputeKernelResult> computeKernel(List<String> args,
-    {bool isWorker: false,
-    StringBuffer outputBuffer,
-    Iterable<Input> inputs,
-    fe.InitializedCompilerState previousState}) async {
-  dynamic out = outputBuffer ?? stderr;
-  bool succeeded = true;
-
-  var parsedArgs = summaryArgsParser.parse(args);
-
-  if (parsedArgs['help']) {
-    out.writeln(summaryArgsParser.usage);
-    if (!isWorker) exit(0);
-    return new ComputeKernelResult(false, previousState);
-  }
-
-  // Bazel creates an overlay file system where some files may be located in the
-  // source tree, some in a gendir, and some in a bindir. The multi-root file
-  // system hides this from the front end.
-  var multiRoots = parsedArgs['multi-root'].map(Uri.base.resolve).toList();
-  if (multiRoots.isEmpty) multiRoots.add(Uri.base);
-  var fileSystem = new MultiRootFileSystem(parsedArgs['multi-root-scheme'],
-      multiRoots, fe.StandardFileSystem.instance);
-  var sources = (parsedArgs['source'] as List<String>).map(_toUri).toList();
-  var excludeNonSources = parsedArgs['exclude-non-sources'] as bool;
-
-  var nnbdMode = parsedArgs['sound-null-safety'] as bool
-      ? fe.NnbdMode.Strong
-      : fe.NnbdMode.Weak;
-  var summaryOnly = parsedArgs['summary-only'] as bool;
-  var trackWidgetCreation = parsedArgs['track-widget-creation'] as bool;
-
-  // TODO(sigmund,jakemac): make target mandatory. We allow null to be backwards
-  // compatible while we migrate existing clients of this tool.
-  var targetName =
-      (parsedArgs['target'] as String) ?? (summaryOnly ? 'ddc' : 'vm');
-  var targetFlags = new TargetFlags(
-      trackWidgetCreation: trackWidgetCreation,
-      enableNullSafety: nnbdMode == fe.NnbdMode.Strong);
-  Target target;
-  switch (targetName) {
-    case 'vm':
-      target = new VmTarget(targetFlags);
-      if (summaryOnly) {
-        out.writeln('error: --summary-only not supported for the vm target');
-      }
-      break;
-    case 'flutter':
-      target = new FlutterTarget(targetFlags);
-      if (summaryOnly) {
-        throw new ArgumentError(
-            'error: --summary-only not supported for the flutter target');
-      }
-      break;
-    case 'flutter_runner':
-      target = new FlutterRunnerTarget(targetFlags);
-      if (summaryOnly) {
-        throw new ArgumentError('error: --summary-only not supported for the '
-            'flutter_runner target');
-      }
-      break;
-    case 'dart2js':
-      target = new Dart2jsTarget('dart2js', targetFlags);
-      if (summaryOnly) {
-        out.writeln(
-            'error: --summary-only not supported for the dart2js target');
-      }
-      break;
-    case 'ddc':
-      // TODO(jakemac):If `generateKernel` changes to return a summary
-      // component, process the component instead.
-      target =
-          new DevCompilerSummaryTarget(sources, excludeNonSources, targetFlags);
-      if (!summaryOnly) {
-        out.writeln('error: --no-summary-only not supported for the '
-            'ddc target');
-      }
-      break;
-    default:
-      out.writeln('error: unsupported target: $targetName');
-  }
-
-  List<Uri> linkedInputs =
-      (parsedArgs['input-linked'] as List<String>).map(_toUri).toList();
-
-  List<Uri> summaryInputs =
-      (parsedArgs['input-summary'] as List<String>).map(_toUri).toList();
-
-  fe.InitializedCompilerState state;
-  bool usingIncrementalCompiler = false;
-  bool recordUsedInputs = parsedArgs["used-inputs"] != null;
-  var environmentDefines = _parseEnvironmentDefines(parsedArgs['define']);
-  var verbose = parsedArgs['verbose'] as bool;
-  var verbosity = fe.Verbosity.parseArgument(parsedArgs['verbosity']);
-
-  if (parsedArgs['use-incremental-compiler']) {
-    usingIncrementalCompiler = true;
-
-    /// Build a map of uris to digests.
-    final inputDigests = <Uri, List<int>>{};
-    if (inputs != null) {
-      for (var input in inputs) {
-        inputDigests[_toUri(input.path)] = input.digest;
-      }
-    }
-
-    // If digests weren't given and if not in worker mode, create fake data and
-    // ensure we don't have a previous state (as that wouldn't be safe with
-    // fake input digests).
-    if (!isWorker && inputDigests.isEmpty) {
-      previousState = null;
-      inputDigests[_toUri(parsedArgs['dart-sdk-summary'])] = const [0];
-      for (Uri uri in summaryInputs) {
-        inputDigests[uri] = const [0];
-      }
-      for (Uri uri in linkedInputs) {
-        inputDigests[uri] = const [0];
-      }
-    }
-
-    state = await fe.initializeIncrementalCompiler(
-        previousState,
-        {
-          "target=$targetName",
-          "trackWidgetCreation=$trackWidgetCreation",
-          "multiRootScheme=${fileSystem.markerScheme}",
-          "multiRootRoots=${fileSystem.roots}",
-        },
-        _toUri(parsedArgs['dart-sdk-summary']),
-        _toUri(parsedArgs['packages-file']),
-        _toUri(parsedArgs['libraries-file']),
-        [...summaryInputs, ...linkedInputs],
-        inputDigests,
-        target,
-        fileSystem,
-        (parsedArgs['enable-experiment'] as List<String>),
-        summaryOnly,
-        environmentDefines,
-        trackNeededDillLibraries: recordUsedInputs,
-        verbose: verbose,
-        nnbdMode: nnbdMode);
-  } else {
-    state = await fe.initializeCompiler(
-        // TODO(sigmund): pass an old state once we can make use of it.
-        null,
-        _toUri(parsedArgs['dart-sdk-summary']),
-        _toUri(parsedArgs['libraries-file']),
-        _toUri(parsedArgs['packages-file']),
-        [...summaryInputs, ...linkedInputs],
-        target,
-        fileSystem,
-        parsedArgs['enable-experiment'] as List<String>,
-        environmentDefines,
-        verbose: verbose,
-        nnbdMode: nnbdMode);
-  }
-
-  void onDiagnostic(fe.DiagnosticMessage message) {
-    if (fe.Verbosity.shouldPrint(verbosity, message)) {
-      fe.printDiagnosticMessage(message, out.writeln);
-    }
-    if (message.severity == fe.Severity.error) {
-      succeeded = false;
-    }
-  }
-
-  List<int> kernel;
-  bool wroteUsedDills = false;
-  if (usingIncrementalCompiler) {
-    state.options.onDiagnostic = onDiagnostic;
-    Component incrementalComponent = await state.incrementalCompiler
-        .computeDelta(entryPoints: sources, fullComponent: true);
-
-    if (recordUsedInputs) {
-      Set<Uri> usedOutlines = {};
-      for (Library lib in state.incrementalCompiler.neededDillLibraries) {
-        if (lib.importUri.scheme == "dart") continue;
-        Uri uri = state.libraryToInputDill[lib.importUri];
-        if (uri == null) {
-          throw new StateError("Library ${lib.importUri} was recorded as used, "
-              "but was not in the list of known libraries.");
-        }
-        usedOutlines.add(uri);
-      }
-      var outputUsedFile = new File(parsedArgs["used-inputs"]);
-      outputUsedFile.createSync(recursive: true);
-      outputUsedFile.writeAsStringSync(usedOutlines.join("\n"));
-      wroteUsedDills = true;
-    }
-
-    kernel = await state.incrementalCompiler.context.runInContext((_) {
-      if (summaryOnly) {
-        incrementalComponent.uriToSource.clear();
-        incrementalComponent.problemsAsJson = null;
-        incrementalComponent.setMainMethodAndMode(
-            null, true, incrementalComponent.mode);
-        target.performOutlineTransformations(incrementalComponent);
-        makeStable(incrementalComponent);
-        return Future.value(fe.serializeComponent(incrementalComponent,
-            includeSources: false, includeOffsets: false));
-      }
-
-      makeStable(incrementalComponent);
-
-      return Future.value(fe.serializeComponent(incrementalComponent,
-          filter: excludeNonSources
-              ? (library) => sources.contains(library.importUri)
-              : null,
-          includeOffsets: true));
-    });
-  } else if (summaryOnly) {
-    kernel = await fe.compileSummary(state, sources, onDiagnostic,
-        includeOffsets: false);
-  } else {
-    Component component =
-        await fe.compileComponent(state, sources, onDiagnostic);
-    kernel = fe.serializeComponent(component,
-        filter: excludeNonSources
-            ? (library) => sources.contains(library.importUri)
-            : null,
-        includeOffsets: true);
-  }
-  state.options.onDiagnostic = null; // See http://dartbug.com/36983.
-
-  if (!wroteUsedDills && recordUsedInputs) {
-    // The path taken didn't record inputs used: Say we used everything.
-    var outputUsedFile = new File(parsedArgs["used-inputs"]);
-    outputUsedFile.createSync(recursive: true);
-    Set<Uri> allFiles = {...summaryInputs, ...linkedInputs};
-    outputUsedFile.writeAsStringSync(allFiles.join("\n"));
-    wroteUsedDills = true;
-  }
-
-  if (kernel != null) {
-    var outputFile = new File(parsedArgs['output']);
-    outputFile.createSync(recursive: true);
-    outputFile.writeAsBytesSync(kernel);
-  } else {
-    assert(!succeeded);
-  }
-
-  return new ComputeKernelResult(succeeded, state);
-}
-
-/// Make sure the output is stable by sorting libraries and additional exports.
-void makeStable(Component c) {
-  // Make sure the output is stable.
-  c.libraries.sort((l1, l2) {
-    return "${l1.fileUri}".compareTo("${l2.fileUri}");
-  });
-  c.problemsAsJson?.sort();
-  c.computeCanonicalNames();
-  for (Library library in c.libraries) {
-    library.additionalExports.sort((Reference r1, Reference r2) {
-      return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
-    });
-    library.problemsAsJson?.sort();
-  }
-}
-
-/// Extends the DevCompilerTarget to transform outlines to meet the requirements
-/// of summaries in bazel and package-build.
-///
-/// Build systems like package-build may provide the same input file twice to
-/// the summary worker, but only intends to have it in one output summary.  The
-/// convention is that if it is listed as a source, it is intended to be part of
-/// the output, if the source file was loaded as a dependency, then it was
-/// already included in a different summary.  The transformation below ensures
-/// that the output summary doesn't include those implicit inputs.
-///
-/// Note: this transformation is destructive and is only intended to be used
-/// when generating summaries.
-class DevCompilerSummaryTarget extends DevCompilerTarget {
-  final List<Uri> sources;
-  final bool excludeNonSources;
-
-  DevCompilerSummaryTarget(
-      this.sources, this.excludeNonSources, TargetFlags targetFlags)
-      : super(targetFlags);
-
-  @override
-  void performOutlineTransformations(Component component) {
-    super.performOutlineTransformations(component);
-    if (!excludeNonSources) return;
-
-    List<Library> libraries = new List.from(component.libraries);
-    component.libraries.clear();
-    Set<Uri> include = sources.toSet();
-    for (var lib in libraries) {
-      if (include.contains(lib.importUri)) {
-        component.libraries.add(lib);
-      } else {
-        // Excluding the library also means that their canonical names will not
-        // be computed as part of serialization, so we need to do that
-        // preemtively here to avoid errors when serializing references to
-        // elements of these libraries.
-        component.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
-        lib.computeCanonicalNames();
-      }
-    }
-  }
-}
-
-Uri _toUri(String uriString) {
-  if (uriString == null) return null;
-  // Windows-style paths use '\', so convert them to '/' in case they've been
-  // concatenated with Unix-style paths.
-  return Uri.base.resolve(uriString.replaceAll("\\", "/"));
-}
-
-Map<String, String> _parseEnvironmentDefines(List<String> args) {
-  var environment = <String, String>{};
-
-  for (var arg in args) {
-    var eq = arg.indexOf('=');
-    if (eq <= 0) {
-      var kind = eq == 0 ? 'name' : 'value';
-      throw FormatException('no $kind given to -D option `$arg`');
-    }
-    var name = arg.substring(0, eq);
-    var value = arg.substring(eq + 1);
-    environment[name] = value;
-  }
-
-  return environment;
-}
