diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index c4ff40d..5924d4a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -301,7 +301,15 @@
           "No member computed for index ${index} in ${members}");
       candidateType = _computeMemberType(thisType, target);
       if (!classBuilder.library.isNonNullableByDefault) {
-        DartType legacyErasure = rawLegacyErasure(candidateType);
+        DartType legacyErasure;
+        if (target == hierarchy.coreTypes.objectEquals) {
+          // In legacy code we special case `Object.==` to infer `dynamic`
+          // instead `Object!`.
+          legacyErasure = new FunctionType([const DynamicType()],
+              hierarchy.coreTypes.boolLegacyRawType, Nullability.legacy);
+        } else {
+          legacyErasure = rawLegacyErasure(candidateType);
+        }
         if (legacyErasure != null) {
           _neededLegacyErasureIndices ??= {};
           _neededLegacyErasureIndices.add(index);
@@ -611,11 +619,6 @@
     for (int i = 0; i < function.positionalParameters.length; i++) {
       VariableDeclaration parameter = function.positionalParameters[i];
       DartType parameterType = functionType.positionalParameters[i];
-      if (i == 0 && procedure == hierarchy.coreTypes.objectEquals) {
-        // In legacy code we special case `Object.==` to infer `dynamic`
-        // instead `Object!`.
-        parameterType = const DynamicType();
-      }
       positionalParameters.add(new VariableDeclaration(parameter.name,
           type: parameterType, isCovariant: parameter.isCovariant)
         ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
index 8caaedc..f10419d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
@@ -53,6 +53,18 @@
         entries = spread.entries;
       } else if (spread is SetConstant) {
         entries = spread.entries;
+      } else if (evaluator.backend.isLoweredListConstant(spread)) {
+        entries = <Constant>[];
+        evaluator.backend.forEachLoweredListConstantElement(spread,
+            (Constant element) {
+          entries.add(element);
+        });
+      } else if (evaluator.backend.isLoweredSetConstant(constant)) {
+        entries = <Constant>[];
+        evaluator.backend.forEachLoweredSetConstantElement(spread,
+            (Constant element) {
+          entries.add(element);
+        });
       } else {
         // Not list or set in spread
         return evaluator.createErrorConstant(
@@ -176,26 +188,7 @@
       // Fully evaluated
       List<Constant> entries = parts.single;
       SetConstant result = new SetConstant(elementType, entries);
-      if (evaluator.desugarSets) {
-        final List<ConstantMapEntry> mapEntries =
-            new List<ConstantMapEntry>.filled(entries.length, null);
-        for (int i = 0; i < entries.length; ++i) {
-          mapEntries[i] =
-              new ConstantMapEntry(entries[i], evaluator.nullConstant);
-        }
-        Constant map = evaluator.lowerMapConstant(
-            new MapConstant(elementType, const NullType(), mapEntries));
-        return evaluator.lower(
-            result,
-            new InstanceConstant(
-                evaluator.unmodifiableSetMap.enclosingClass.reference, [
-              elementType
-            ], <Reference, Constant>{
-              evaluator.unmodifiableSetMap.getterReference: map
-            }));
-      } else {
-        return evaluator.lowerSetConstant(result);
-      }
+      return evaluator.lowerSetConstant(result);
     }
     List<Expression> sets = <Expression>[];
     for (Object part in parts) {
@@ -271,6 +264,13 @@
               entry.key, entry.value, spreadExpression, spreadExpression);
           if (error != null) return error;
         }
+      } else if (evaluator.backend.isLoweredMapConstant(spread)) {
+        AbortConstant error;
+        evaluator.backend.forEachLoweredMapConstantEntry(spread,
+            (Constant key, Constant value) {
+          error ??= addConstant(key, value, spreadExpression, spreadExpression);
+        });
+        if (error != null) return error;
       } else {
         // Not map in spread
         return evaluator.createErrorConstant(
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index c0c6a16..a92f302 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -97,7 +97,6 @@
 
   transformLibraries(component.libraries, backend, environmentDefines,
       typeEnvironment, errorReporter, evaluationMode,
-      desugarSets: desugarSets,
       enableTripleShift: enableTripleShift,
       errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
       evaluateAnnotations: evaluateAnnotations);
@@ -112,18 +111,15 @@
     ErrorReporter errorReporter,
     EvaluationMode evaluationMode,
     {bool evaluateAnnotations,
-    bool desugarSets,
     bool enableTripleShift,
     bool errorOnUnevaluatedConstant}) {
   assert(evaluateAnnotations != null);
-  assert(desugarSets != null);
   assert(enableTripleShift != null);
   assert(errorOnUnevaluatedConstant != null);
   final ConstantsTransformer constantsTransformer = new ConstantsTransformer(
       backend,
       environmentDefines,
       evaluateAnnotations,
-      desugarSets,
       enableTripleShift,
       errorOnUnevaluatedConstant,
       typeEnvironment,
@@ -143,18 +139,15 @@
     ErrorReporter errorReporter,
     EvaluationMode evaluationMode,
     {bool evaluateAnnotations: true,
-    bool desugarSets: false,
     bool enableTripleShift: false,
     bool errorOnUnevaluatedConstant: false}) {
   assert(evaluateAnnotations != null);
-  assert(desugarSets != null);
   assert(enableTripleShift != null);
   assert(errorOnUnevaluatedConstant != null);
   final ConstantsTransformer constantsTransformer = new ConstantsTransformer(
       backend,
       environmentDefines,
       evaluateAnnotations,
-      desugarSets,
       enableTripleShift,
       errorOnUnevaluatedConstant,
       typeEnvironment,
@@ -326,7 +319,6 @@
   StaticTypeContext _staticTypeContext;
 
   final bool evaluateAnnotations;
-  final bool desugarSets;
   final bool enableTripleShift;
   final bool errorOnUnevaluatedConstant;
 
@@ -334,7 +326,6 @@
       this.backend,
       Map<String, String> environmentDefines,
       this.evaluateAnnotations,
-      this.desugarSets,
       this.enableTripleShift,
       this.errorOnUnevaluatedConstant,
       this.typeEnvironment,
@@ -342,7 +333,6 @@
       EvaluationMode evaluationMode)
       : constantEvaluator = new ConstantEvaluator(
             backend, environmentDefines, typeEnvironment, errorReporter,
-            desugarSets: desugarSets,
             enableTripleShift: enableTripleShift,
             errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
             evaluationMode: evaluationMode);
@@ -759,9 +749,6 @@
   final ErrorReporter errorReporter;
   final EvaluationMode evaluationMode;
 
-  final bool desugarSets;
-  final Field unmodifiableSetMap;
-
   final bool enableTripleShift;
 
   final bool Function(DartType) isInstantiated =
@@ -796,19 +783,14 @@
 
   ConstantEvaluator(this.backend, this.environmentDefines, this.typeEnvironment,
       this.errorReporter,
-      {this.desugarSets = false,
-      this.enableTripleShift = false,
+      {this.enableTripleShift = false,
       this.errorOnUnevaluatedConstant = false,
       this.evaluationMode: EvaluationMode.weak})
       : numberSemantics = backend.numberSemantics,
         coreTypes = typeEnvironment.coreTypes,
         canonicalizationCache = <Constant, Constant>{},
         nodeCache = <Node, Constant>{},
-        env = new EvaluationEnvironment(),
-        unmodifiableSetMap = desugarSets
-            ? typeEnvironment.coreTypes.index
-                .getMember('dart:collection', '_UnmodifiableSet', '_map')
-            : null {
+        env = new EvaluationEnvironment() {
     if (environmentDefines == null && !backend.supportsUnevaluatedConstants) {
       throw new ArgumentError(
           "No 'environmentDefines' passed to the constant evaluator but the "
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index de75625..5f55924 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1247,7 +1247,6 @@
         new KernelConstantErrorReporter(loader),
         evaluationMode,
         evaluateAnnotations: true,
-        desugarSets: !backendTarget.supportsSetLiterals,
         enableTripleShift:
             isExperimentEnabledGlobally(ExperimentalFlag.tripleShift),
         errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
@@ -1297,7 +1296,6 @@
         new KernelConstantErrorReporter(loader),
         evaluationMode,
         evaluateAnnotations: true,
-        desugarSets: !backendTarget.supportsSetLiterals,
         enableTripleShift:
             isExperimentEnabledGlobally(ExperimentalFlag.tripleShift),
         errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
diff --git a/pkg/front_end/test/constant_evaluator_benchmark.dart b/pkg/front_end/test/constant_evaluator_benchmark.dart
index c152aa2..f0e722c 100644
--- a/pkg/front_end/test/constant_evaluator_benchmark.dart
+++ b/pkg/front_end/test/constant_evaluator_benchmark.dart
@@ -99,7 +99,6 @@
             new SilentErrorReporter(),
             evaluationMode,
             evaluateAnnotations: true,
-            desugarSets: !target.backendTarget.supportsSetLiterals,
             enableTripleShift: target
                 .isExperimentEnabledGlobally(ExperimentalFlag.tripleShift),
             errorOnUnevaluatedConstant:
diff --git a/pkg/front_end/test/crashing_test_case_minimizer.dart b/pkg/front_end/test/crashing_test_case_minimizer.dart
index 8d0fcc6..ea8ac64 100644
--- a/pkg/front_end/test/crashing_test_case_minimizer.dart
+++ b/pkg/front_end/test/crashing_test_case_minimizer.dart
@@ -2,90 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async' show Future, StreamSubscription;
+import 'dart:convert' show jsonDecode;
 
-import 'dart:convert' show JsonEncoder, jsonDecode, utf8;
+import 'dart:io' show File;
 
-import 'dart:io' show BytesBuilder, File, stdin, stdout;
-import 'dart:math' show max;
-
-import 'dart:typed_data' show Uint8List;
-
-import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;
-
-import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
-    show ErrorToken, ScannerConfiguration, Token;
-
-import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
-import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
-
-import 'package:front_end/src/api_prototype/compiler_options.dart'
-    show CompilerOptions, DiagnosticMessage;
-
-import 'package:front_end/src/api_prototype/experimental_flags.dart'
-    show ExperimentalFlag;
-
-import 'package:front_end/src/api_prototype/file_system.dart'
-    show FileSystem, FileSystemEntity, FileSystemException;
-
-import 'package:front_end/src/base/processed_options.dart'
-    show ProcessedOptions;
-
-import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
-
-import 'package:front_end/src/fasta/incremental_compiler.dart'
-    show IncrementalCompiler;
-
-import 'package:front_end/src/fasta/kernel/utils.dart' show ByteSink;
-import 'package:front_end/src/fasta/util/direct_parser_ast.dart';
-import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
-
-import 'package:front_end/src/fasta/util/textual_outline.dart'
-    show textualOutline;
-
-import 'package:kernel/ast.dart' show Component;
-
-import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
-
-import 'package:kernel/target/targets.dart' show Target, TargetFlags;
-import 'package:package_config/package_config.dart';
-
-import "package:vm/target/flutter.dart" show FlutterTarget;
-
-import "package:vm/target/vm.dart" show VmTarget;
-
-import 'incremental_load_from_dill_suite.dart' show getOptions;
-
-import 'parser_test_listener.dart' show ParserTestListener;
-
-import 'parser_suite.dart' as parser_suite;
-
-final FakeFileSystem fs = new FakeFileSystem();
-Uri mainUri;
-Uri platformUri;
-bool noPlatform = false;
-bool nnbd = false;
-bool experimentalInvalidation = false;
-bool serialize = false;
-bool widgetTransformation = false;
-List<Uri> invalidate = [];
-String targetString = "VM";
-String expectedCrashLine;
-bool oldBlockDelete = false;
-bool lineDelete = false;
-bool byteDelete = false;
-bool askAboutRedirectCrashTarget = false;
-int stackTraceMatches = 1;
-Set<String> askedAboutRedirect = {};
-bool _quit = false;
-bool skip = false;
-
-Future<bool> shouldQuit() async {
-  // allow some time for stdin.listen to process data.
-  await new Future.delayed(new Duration(milliseconds: 5));
-  return _quit;
-}
+import 'crashing_test_case_minimizer_impl.dart';
 
 // TODO(jensj): Option to automatically find and search for _all_ crashes that
 // it uncovers --- i.e. it currently has an option to ask if we want to search
@@ -93,1727 +14,94 @@
 // for everything it sees. One can possibly just make a copy of the state of
 // the file system and save that for later...
 
+// TODO(jensj): Add asserts or similar where - after each rewrite - we run the
+// parser on it and verifies that no syntax errors have been introduced.
+
 main(List<String> arguments) async {
   String filename;
-  Uri loadFsJson;
+  Uri loadJson;
   for (String arg in arguments) {
-    if (arg.startsWith("--")) {
-      if (arg == "--nnbd") {
-        nnbd = true;
-      } else if (arg == "--experimental-invalidation") {
-        experimentalInvalidation = true;
-      } else if (arg == "--serialize") {
-        serialize = true;
-      } else if (arg.startsWith("--fsJson=")) {
-        String jsJson = arg.substring("--fsJson=".length);
-        loadFsJson = Uri.base.resolve(jsJson);
-      } else if (arg.startsWith("--platform=")) {
-        String platform = arg.substring("--platform=".length);
-        platformUri = Uri.base.resolve(platform);
-      } else if (arg == "--no-platform") {
-        noPlatform = true;
-      } else if (arg.startsWith("--invalidate=")) {
-        for (String s in arg.substring("--invalidate=".length).split(",")) {
-          invalidate.add(Uri.base.resolve(s));
-        }
-      } else if (arg.startsWith("--widgetTransformation")) {
-        widgetTransformation = true;
-      } else if (arg.startsWith("--target=VM")) {
-        targetString = "VM";
-      } else if (arg.startsWith("--target=flutter")) {
-        targetString = "flutter";
-      } else if (arg.startsWith("--target=ddc")) {
-        targetString = "ddc";
-      } else if (arg == "--oldBlockDelete") {
-        oldBlockDelete = true;
-      } else if (arg == "--lineDelete") {
-        lineDelete = true;
-      } else if (arg == "--byteDelete") {
-        byteDelete = true;
-      } else if (arg == "--ask-redirect-target") {
-        askAboutRedirectCrashTarget = true;
-      } else if (arg.startsWith("--stack-matches=")) {
-        String stackMatches = arg.substring("--stack-matches=".length);
-        stackTraceMatches = int.parse(stackMatches);
-      } else {
-        throw "Unknown option $arg";
-      }
-    } else if (filename != null) {
-      throw "Already got '$filename', '$arg' is also a filename; "
-          "can only get one";
-    } else {
-      filename = arg;
-    }
-  }
-  if (noPlatform) {
-    int i = 0;
-    while (platformUri == null || new File.fromUri(platformUri).existsSync()) {
-      platformUri = Uri.base.resolve("nonexisting_$i");
-      i++;
-    }
-  } else {
-    if (platformUri == null) {
-      throw "No platform given. Use --platform=/path/to/platform.dill";
-    }
-    if (!new File.fromUri(platformUri).existsSync()) {
-      throw "The platform file '$platformUri' doesn't exist";
-    }
-  }
-  if (filename == null) {
-    throw "Need file to operate on";
-  }
-  File file = new File(filename);
-  if (!file.existsSync()) throw "File $filename doesn't exist.";
-  mainUri = file.absolute.uri;
-
-  try {
-    await tryToMinimize(loadFsJson);
-  } catch (e) {
-    print("\n\n\nABOUT TO CRASH. DUMPING FS.");
-    dumpFsToJson();
-    print("\n\n\nABOUT TO CRASH. FS DUMPED.");
-    rethrow;
-  }
-}
-
-Future tryToMinimize(Uri loadFsJson) async {
-  // Set main to be basically empty up front.
-  fs.data[mainUri] = utf8.encode("main() {}");
-  Component initialComponent = await getInitialComponent();
-  print("Compiled initially (without data)");
-  // Remove fake cache.
-  fs.data.remove(mainUri);
-
-  if (loadFsJson != null) {
-    File f = new File.fromUri(loadFsJson);
-    fs.initializeFromJson((jsonDecode(f.readAsStringSync())));
-  }
-
-  // First assure it actually crash on the input.
-  if (!await crashesOnCompile(initialComponent)) {
-    throw "Input doesn't crash the compiler.";
-  }
-  print("Step #1: We did crash on the input!");
-
-  // All file should now be cached.
-  fs._redirectAndRecord = false;
-
-  try {
-    stdin.echoMode = false;
-    stdin.lineMode = false;
-  } catch (e) {
-    print("error setting settings on stdin");
-  }
-  StreamSubscription<List<int>> stdinSubscription =
-      stdin.listen((List<int> event) {
-    if (event.length == 1 && event.single == "q".codeUnits.single) {
-      print("\n\nGot told to quit!\n\n");
-      _quit = true;
-    } else if (event.length == 1 && event.single == "s".codeUnits.single) {
-      print("\n\nGot told to skip!\n\n");
-      skip = true;
-    } else if (event.length == 1 && event.single == "i".codeUnits.single) {
-      print("\n\n--- STATUS INFORMATION START ---\n\n");
-      int totalFiles = 0;
-      int emptyFiles = 0;
-      int combinedSize = 0;
-      for (Uri uri in fs.data.keys) {
-        final Uint8List originalBytes = fs.data[uri];
-        if (originalBytes == null) continue;
-        totalFiles++;
-        if (originalBytes.isEmpty) emptyFiles++;
-        combinedSize += originalBytes.length;
-      }
-      print("Total files left: $totalFiles.");
-      print("Of which empty: $emptyFiles.");
-      print("Combined size left: $combinedSize bytes.");
-      print("\n\n--- STATUS INFORMATION END ---\n\n");
-      skip = true;
-    } else {
-      print("\n\nGot stdin input: $event\n\n");
-    }
-  });
-
-  // For all dart files: Parse them as set their source as the parsed source
-  // to "get around" any encoding issues when printing later.
-  Map<Uri, Uint8List> copy = new Map.from(fs.data);
-  for (Uri uri in fs.data.keys) {
-    if (await shouldQuit()) break;
-    String uriString = uri.toString();
-    if (uriString.endsWith(".json") ||
-        uriString.endsWith(".packages") ||
-        uriString.endsWith(".dill") ||
-        fs.data[uri] == null ||
-        fs.data[uri].isEmpty) {
-      // skip
-    } else {
-      try {
-        String parsedString = getFileAsStringContent(fs.data[uri], nnbd);
-        fs.data[uri] = utf8.encode(parsedString);
-      } catch (e) {
-        // crash in scanner/parser --- keep original file. This crash might
-        // be what we're looking for!
-      }
-    }
-  }
-  if (!await crashesOnCompile(initialComponent)) {
-    // Now - for whatever reason - we didn't crash. Restore.
-    fs.data.clear();
-    fs.data.addAll(copy);
-  }
-
-  // Operate on one file at a time: Try to delete all content in file.
-  List<Uri> uris = new List<Uri>.from(fs.data.keys);
-
-  // TODO(jensj): Can we "thread" this?
-  bool changedSome = true;
-  while (changedSome) {
-    if (await shouldQuit()) break;
-    while (changedSome) {
-      if (await shouldQuit()) break;
-      changedSome = false;
-      for (int i = 0; i < uris.length; i++) {
-        if (await shouldQuit()) break;
-        Uri uri = uris[i];
-        if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-        print("About to work on file $i of ${uris.length}");
-        await deleteContent(uris, i, false, initialComponent);
-        if (fs.data[uri] == null || fs.data[uri].isEmpty) changedSome = true;
-      }
-    }
-
-    // Try to delete empty files.
-    bool changedSome2 = true;
-    while (changedSome2) {
-      if (await shouldQuit()) break;
-      changedSome2 = false;
-      for (int i = 0; i < uris.length; i++) {
-        if (await shouldQuit()) break;
-        Uri uri = uris[i];
-        if (fs.data[uri] == null || fs.data[uri].isNotEmpty) continue;
-        print("About to work on file $i of ${uris.length}");
-        await deleteContent(uris, i, false, initialComponent, deleteFile: true);
-        if (fs.data[uri] == null) {
-          changedSome = true;
-          changedSome2 = true;
-        }
-      }
-    }
-
-    int left = 0;
-    for (Uri uri in uris) {
-      if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-      left++;
-    }
-    print("There's now $left files of ${fs.data.length} files left");
-
-    // Operate on one file at a time.
-    for (Uri uri in fs.data.keys) {
-      if (await shouldQuit()) break;
-      if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-
-      print("Now working on $uri");
-
-      int prevLength = fs.data[uri].length;
-
-      await deleteBlocks(uri, initialComponent);
-      await deleteEmptyLines(uri, initialComponent);
-
-      if (oldBlockDelete) {
-        // Try to delete blocks.
-        await deleteBlocksOld(uri, initialComponent);
-      }
-
-      if (lineDelete) {
-        // Try to delete lines.
-        await deleteLines(uri, initialComponent);
-      }
-
-      print("We're now at ${fs.data[uri].length} bytes for $uri "
-          "(was $prevLength).");
-      if (prevLength != fs.data[uri].length) changedSome = true;
-      if (fs.data[uri].isEmpty) continue;
-
-      if (byteDelete) {
-        // Now try to delete 'arbitrarily' (for any given start offset do an
-        // exponential binary search).
-        int prevLength = fs.data[uri].length;
-        while (true) {
-          if (await shouldQuit()) break;
-          await binarySearchDeleteData(uri, initialComponent);
-
-          if (fs.data[uri].length == prevLength) {
-            // No progress.
-            break;
-          } else {
-            print("We're now at ${fs.data[uri].length} bytes");
-            prevLength = fs.data[uri].length;
-            changedSome = true;
-          }
-        }
-      }
-    }
-    for (Uri uri in fs.data.keys) {
-      if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-      if (await shouldQuit()) break;
-      if (await attemptInline(uri, initialComponent)) {
-        changedSome = true;
-      }
-    }
-  }
-
-  if (await shouldQuit()) {
-    print("\n\nASKED TO QUIT\n\n");
-  } else {
-    print("\n\nDONE\n\n");
-  }
-
-  Uri jsonFsOut = dumpFsToJson();
-
-  await stdinSubscription.cancel();
-
-  if (!await shouldQuit()) {
-    // Test converting to incremental compiler yaml test.
-    outputIncrementalCompilerYamlTest();
-    print("\n\n\n");
-
-    for (Uri uri in uris) {
-      if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
-      print("Uri $uri has this content:");
-
-      try {
-        String utfDecoded = utf8.decode(fs.data[uri], allowMalformed: true);
-        print(utfDecoded);
-      } catch (e) {
-        print(fs.data[uri]);
-        print("(which crashes when trying to decode as utf8)");
-      }
-      print("\n\n====================\n\n");
-    }
-
-    print("Wrote json file system to $jsonFsOut");
-  }
-}
-
-Uri dumpFsToJson() {
-  JsonEncoder jsonEncoder = new JsonEncoder.withIndent("  ");
-  String jsonFs = jsonEncoder.convert(fs);
-  int i = 0;
-  Uri jsonFsOut;
-  while (jsonFsOut == null || new File.fromUri(jsonFsOut).existsSync()) {
-    jsonFsOut = Uri.base.resolve("crash_minimizer_result_$i");
-    i++;
-  }
-  new File.fromUri(jsonFsOut).writeAsStringSync(jsonFs);
-  print("Wrote json file system to $jsonFsOut");
-  return jsonFsOut;
-}
-
-/// Attempts to inline small files in other files.
-/// Returns true if anything was changed, i.e. if at least one inlining was a
-/// success.
-Future<bool> attemptInline(Uri uri, Component initialComponent) async {
-  // Don't attempt to inline the main uri --- that's our entry!
-  if (uri == mainUri) return false;
-
-  Uint8List inlineData = fs.data[uri];
-  bool hasMultipleLines = false;
-  for (int i = 0; i < inlineData.length; i++) {
-    if (inlineData[i] == $LF) {
-      hasMultipleLines = true;
+    if (arg.startsWith("--json=")) {
+      String json = arg.substring("--json=".length);
+      loadJson = Uri.base.resolve(json);
       break;
     }
   }
-  // TODO(jensj): Maybe inline slightly bigger files too?
-  if (hasMultipleLines) {
-    return false;
-  }
+  TestMinimizerSettings settings = new TestMinimizerSettings();
 
-  Uri inlinableUri = uri;
-
-  int compileTry = 0;
-  bool changed = false;
-
-  for (Uri uri in fs.data.keys) {
-    final Uint8List originalBytes = fs.data[uri];
-    if (originalBytes == null || originalBytes.isEmpty) continue;
-    DirectParserASTContentCompilationUnitEnd ast = getAST(originalBytes,
-        includeBody: false,
-        includeComments: false,
-        enableExtensionMethods: true,
-        enableNonNullable: nnbd);
-    // Find all imports/exports of this file (if any).
-    // If finding any:
-    // * remove all of them, then
-    // * find the end of the last import/export, and
-    // * insert the content of the file there.
-    // * if that *doesn't* work and we've inserted an export,
-    //   try converting that to an import instead.
-    List<Replacement> replacements = [];
-    for (DirectParserASTContentImportEnd import in ast.getImports()) {
-      Token importUriToken = import.importKeyword.next;
-      Uri importUri = _getUri(importUriToken, uri);
-      if (inlinableUri == importUri) {
-        replacements.add(new Replacement(
-            import.importKeyword.offset - 1, import.semicolon.offset + 1));
-      }
-    }
-    for (DirectParserASTContentExportEnd export in ast.getExports()) {
-      Token exportUriToken = export.exportKeyword.next;
-      Uri exportUri = _getUri(exportUriToken, uri);
-      if (inlinableUri == exportUri) {
-        replacements.add(new Replacement(
-            export.exportKeyword.offset - 1, export.semicolon.offset + 1));
-      }
-    }
-    if (replacements.isEmpty) continue;
-
-    // Step 1: Remove all imports/exports of this file.
-    Uint8List candidate = _replaceRange(replacements, originalBytes);
-
-    // Step 2: Find the last import/export.
-    int offsetOfLast = 0;
-    ast = getAST(candidate,
-        includeBody: false,
-        includeComments: false,
-        enableExtensionMethods: true,
-        enableNonNullable: nnbd);
-    for (DirectParserASTContentImportEnd import in ast.getImports()) {
-      offsetOfLast = max(offsetOfLast, import.semicolon.offset + 1);
-    }
-    for (DirectParserASTContentExportEnd export in ast.getExports()) {
-      offsetOfLast = max(offsetOfLast, export.semicolon.offset + 1);
-    }
-
-    // Step 3: Insert the content of the file there. Note, though,
-    // that any imports/exports in _that_ file should be changed to be valid
-    // in regards to the new placement.
-    BytesBuilder builder = new BytesBuilder();
-    for (int i = 0; i < offsetOfLast; i++) {
-      builder.addByte(candidate[i]);
-    }
-    builder.addByte($LF);
-    builder.add(_rewriteImportsExportsToUri(inlineData, uri, inlinableUri));
-    builder.addByte($LF);
-    for (int i = offsetOfLast; i < candidate.length; i++) {
-      builder.addByte(candidate[i]);
-    }
-    candidate = builder.takeBytes();
-
-    // Step 4: Try it out.
-    if (await shouldQuit()) break;
-    if (skip) {
-      skip = false;
-      break;
-    }
-    stdout.write(".");
-    compileTry++;
-    if (compileTry % 50 == 0) {
-      stdout.write("(at $compileTry)\n");
-    }
-    fs.data[uri] = candidate;
-    if (await crashesOnCompile(initialComponent)) {
-      print("Could inline $inlinableUri into $uri.");
-      changed = true;
-      // File was already updated.
-    } else {
-      // Couldn't replace that.
-      // Insert the original again.
-      fs.data[uri] = originalBytes;
-
-      // If we've inlined an export, try changing that to an import.
-      builder = new BytesBuilder();
-      for (int i = 0; i < offsetOfLast; i++) {
-        builder.addByte(candidate[i]);
-      }
-      // TODO(jensj): Only try compile again, if export was actually converted
-      // to import.
-      builder.addByte($LF);
-      builder.add(_rewriteImportsExportsToUri(inlineData, uri, inlinableUri,
-          convertExportToImport: true));
-      builder.addByte($LF);
-      for (int i = offsetOfLast; i < candidate.length; i++) {
-        builder.addByte(candidate[i]);
-      }
-      candidate = builder.takeBytes();
-
-      // Step 4: Try it out.
-      if (await shouldQuit()) break;
-      if (skip) {
-        skip = false;
-        break;
-      }
-      stdout.write(".");
-      compileTry++;
-      if (compileTry % 50 == 0) {
-        stdout.write("(at $compileTry)\n");
-      }
-      fs.data[uri] = candidate;
-      if (await crashesOnCompile(initialComponent)) {
-        print("Could inline $inlinableUri into $uri "
-            "(by converting export to import).");
-        changed = true;
-        // File was already updated.
-      } else {
-        // Couldn't replace that.
-        // Insert the original again.
-        fs.data[uri] = originalBytes;
-      }
-    }
-  }
-
-  return changed;
-}
-
-Uint8List _rewriteImportsExportsToUri(Uint8List oldData, Uri newUri, Uri oldUri,
-    {bool convertExportToImport: false}) {
-  DirectParserASTContentCompilationUnitEnd ast = getAST(oldData,
-      includeBody: false,
-      includeComments: false,
-      enableExtensionMethods: true,
-      enableNonNullable: nnbd);
-  List<Replacement> replacements = [];
-  for (DirectParserASTContentImportEnd import in ast.getImports()) {
-    _rewriteImportsExportsToUriInternal(
-        import.importKeyword.next, oldUri, replacements, newUri);
-  }
-  for (DirectParserASTContentExportEnd export in ast.getExports()) {
-    if (convertExportToImport) {
-      replacements.add(new Replacement(
-        export.exportKeyword.offset - 1,
-        export.exportKeyword.offset + export.exportKeyword.length,
-        nullOrReplacement: utf8.encode('import'),
-      ));
-    }
-    _rewriteImportsExportsToUriInternal(
-        export.exportKeyword.next, oldUri, replacements, newUri);
-  }
-  if (replacements.isNotEmpty) {
-    Uint8List candidate = _replaceRange(replacements, oldData);
-    return candidate;
-  }
-  return oldData;
-}
-
-void _rewriteImportsExportsToUriInternal(
-    Token uriToken, Uri oldUri, List<Replacement> replacements, Uri newUri) {
-  Uri tokenUri = _getUri(uriToken, oldUri, resolvePackage: false);
-  if (tokenUri.scheme == "package" || tokenUri.scheme == "dart") return;
-  Uri asPackageUri = _getImportUri(tokenUri);
-  if (asPackageUri.scheme == "package") {
-    // Just replace with this package uri.
-    replacements.add(new Replacement(
-      uriToken.offset - 1,
-      uriToken.offset + uriToken.length,
-      nullOrReplacement: utf8.encode('"${asPackageUri.toString()}"'),
-    ));
+  if (loadJson != null) {
+    File f = new File.fromUri(loadJson);
+    settings.initializeFromJson((jsonDecode(f.readAsStringSync())));
   } else {
-    // TODO(jensj): Rewrite relative path to be correct.
-    throw "Rewrite $oldUri importing/exporting $tokenUri as $uriToken "
-        "for $newUri (notice $asPackageUri)";
-  }
-}
-
-Uri _getUri(Token uriToken, Uri uri, {bool resolvePackage: true}) {
-  String uriString = uriToken.lexeme;
-  uriString = uriString.substring(1, uriString.length - 1);
-  Uri uriTokenUri = uri.resolve(uriString);
-  if (resolvePackage && uriTokenUri.scheme == "package") {
-    Package package = _latestIncrementalCompiler
-        .currentPackagesMap[uriTokenUri.pathSegments.first];
-    uriTokenUri = package.packageUriRoot
-        .resolve(uriTokenUri.pathSegments.skip(1).join("/"));
-  }
-  return uriTokenUri;
-}
-
-Uri _getImportUri(Uri uri) {
-  return _latestIncrementalCompiler.userCode
-      .getEntryPointUri(uri, issueProblem: false);
-}
-
-void outputIncrementalCompilerYamlTest() {
-  int dartFiles = 0;
-  for (MapEntry<Uri, Uint8List> entry in fs.data.entries) {
-    if (entry.key.pathSegments.last.endsWith(".dart")) {
-      if (entry.value != null) dartFiles++;
-    }
-  }
-
-  print("------ Reproduction as semi-done incremental yaml test file ------");
-
-  // TODO(jensj): don't use full uris.
-  print("""
-# Copyright (c) 2020, 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.md file.
-
-# Reproduce a crash.
-
-type: newworld""");
-  if (widgetTransformation) {
-    print("trackWidgetCreation: true");
-    print("target: DDC # basically needed for widget creation to be run");
-  }
-  print("""
-worlds:
-  - entry: $mainUri""");
-  if (experimentalInvalidation) {
-    print("    experiments: alternative-invalidation-strategy");
-  }
-  print("    sources:");
-  for (MapEntry<Uri, Uint8List> entry in fs.data.entries) {
-    if (entry.value == null) continue;
-    print("      ${entry.key}: |");
-    String string = utf8.decode(entry.value);
-    List<String> lines = string.split("\n");
-    for (String line in lines) {
-      print("        $line");
-    }
-  }
-  print("    expectedLibraryCount: $dartFiles "
-      "# with parts this is not right");
-  print("");
-
-  for (Uri uri in invalidate) {
-    print("  - entry: $mainUri");
-    if (experimentalInvalidation) {
-      print("    experiments: alternative-invalidation-strategy");
-    }
-    print("    worldType: updated");
-    print("    expectInitializeFromDill: false # or true?");
-    print("    invalidate:");
-    print("      - $uri");
-    print("    expectedLibraryCount: $dartFiles "
-        "# with parts this is not right");
-    print("    expectsRebuildBodiesOnly: true # or false?");
-    print("");
-  }
-
-  print("------------------------------------------------------------------");
-}
-
-Uint8List sublist(Uint8List data, int start, int end) {
-  Uint8List result = new Uint8List(end - start);
-  result.setRange(0, result.length, data, start);
-  return result;
-}
-
-String dataToText(Uint8List data) {
-  StringBuffer sb = new StringBuffer();
-  String comma = "[";
-  for (int i = 0; i < data.length; i++) {
-    sb.write(comma);
-    sb.write(data[i]);
-    comma = ", ";
-    if (i > 100) break;
-  }
-  if (data.length > 100) {
-    sb.write("...");
-  }
-  sb.write("]");
-  return sb.toString();
-}
-
-void binarySearchDeleteData(Uri uri, Component initialComponent) async {
-  Uint8List latestCrashData = fs.data[uri];
-  int offset = 0;
-  while (offset < latestCrashData.length) {
-    print("Working at offset $offset of ${latestCrashData.length}");
-    BytesBuilder builder = new BytesBuilder();
-    builder.add(sublist(latestCrashData, 0, offset));
-    builder.add(sublist(latestCrashData, offset + 1, latestCrashData.length));
-    Uint8List candidate = builder.takeBytes();
-    fs.data[uri] = candidate;
-    if (!await crashesOnCompile(initialComponent)) {
-      // Deleting 1 char didn't crash; don't try to delete anymore starting
-      // here.
-      offset++;
-      continue;
-    }
-
-    // Find how long we can go.
-    int crashingAt = 1;
-    int noLongerCrashingAt;
-    while (true) {
-      int deleteChars = 2 * crashingAt;
-      if (offset + deleteChars > latestCrashData.length) {
-        deleteChars = latestCrashData.length - offset;
-      }
-      builder = new BytesBuilder();
-      builder.add(sublist(latestCrashData, 0, offset));
-      builder.add(sublist(
-          latestCrashData, offset + deleteChars, latestCrashData.length));
-      candidate = builder.takeBytes();
-      fs.data[uri] = candidate;
-      if (!await crashesOnCompile(initialComponent)) {
-        noLongerCrashingAt = deleteChars;
-        break;
-      }
-      crashingAt = deleteChars;
-      if (crashingAt + offset == latestCrashData.length) break;
-    }
-
-    if (noLongerCrashingAt == null) {
-      // We can delete the rest.
-      latestCrashData = candidate;
-      continue;
-    }
-
-    // Binary search between [crashingAt] and [noLongerCrashingAt].
-    while (crashingAt < noLongerCrashingAt) {
-      int mid = noLongerCrashingAt -
-          ((noLongerCrashingAt - crashingAt) >> 1); // Get middle, rounding up.
-      builder = new BytesBuilder();
-      builder.add(sublist(latestCrashData, 0, offset));
-      builder
-          .add(sublist(latestCrashData, offset + mid, latestCrashData.length));
-      candidate = builder.takeBytes();
-      fs.data[uri] = candidate;
-      if (await crashesOnCompile(initialComponent)) {
-        crashingAt = mid;
-      } else {
-        // [noLongerCrashingAt] might actually crash now.
-        noLongerCrashingAt = mid - 1;
-      }
-    }
-
-    // This is basically an assert.
-    builder = new BytesBuilder();
-    builder.add(sublist(latestCrashData, 0, offset));
-    builder.add(
-        sublist(latestCrashData, offset + crashingAt, latestCrashData.length));
-    candidate = builder.takeBytes();
-    fs.data[uri] = candidate;
-    if (!await crashesOnCompile(initialComponent)) {
-      throw "Error in binary search.";
-    }
-    latestCrashData = candidate;
-  }
-
-  fs.data[uri] = latestCrashData;
-}
-
-void _tryToRemoveUnreferencedFileContent(Component initialComponent,
-    {bool deleteFile: false}) async {
-  // Check if there now are any unused files.
-  if (_latestComponent == null) return;
-  Set<Uri> neededUris = _latestComponent.uriToSource.keys.toSet();
-  Map<Uri, Uint8List> copy = new Map.from(fs.data);
-  bool removedSome = false;
-  if (await shouldQuit()) return;
-  for (MapEntry<Uri, Uint8List> entry in fs.data.entries) {
-    if (entry.value == null || entry.value.isEmpty) continue;
-    if (!entry.key.toString().endsWith(".dart")) continue;
-    if (!neededUris.contains(entry.key) && fs.data[entry.key].length != 0) {
-      if (deleteFile) {
-        fs.data[entry.key] = null;
-      } else {
-        fs.data[entry.key] = new Uint8List(0);
-      }
-      print(" => Can probably also delete ${entry.key}");
-      removedSome = true;
-    }
-  }
-  if (removedSome) {
-    if (await crashesOnCompile(initialComponent)) {
-      print(" => Yes; Could remove those too!");
-    } else {
-      print(" => No; Couldn't remove those too!");
-      fs.data.clear();
-      fs.data.addAll(copy);
-    }
-  }
-}
-
-void deleteContent(
-    List<Uri> uris, int uriIndex, bool limitTo1, Component initialComponent,
-    {bool deleteFile: false}) async {
-  String extraMessageText = "all content of ";
-  if (deleteFile) extraMessageText = "";
-
-  if (!limitTo1) {
-    if (await shouldQuit()) return;
-    Map<Uri, Uint8List> copy = new Map.from(fs.data);
-    // Try to remove content of i and the next 9 (10 files in total).
-    for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
-      Uri uri = uris[j];
-      if (deleteFile) {
-        fs.data[uri] = null;
-      } else {
-        fs.data[uri] = new Uint8List(0);
-      }
-    }
-    if (!await crashesOnCompile(initialComponent)) {
-      // Couldn't delete all 10 files. Restore and try the single one.
-      fs.data.clear();
-      fs.data.addAll(copy);
-    } else {
-      for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
-        Uri uri = uris[j];
-        print("Can delete ${extraMessageText}file $uri");
-      }
-      await _tryToRemoveUnreferencedFileContent(initialComponent,
-          deleteFile: deleteFile);
-      return;
-    }
-  }
-
-  if (await shouldQuit()) return;
-  Uri uri = uris[uriIndex];
-  Uint8List data = fs.data[uri];
-  if (deleteFile) {
-    fs.data[uri] = null;
-  } else {
-    fs.data[uri] = new Uint8List(0);
-  }
-  if (!await crashesOnCompile(initialComponent)) {
-    print("Can't delete ${extraMessageText}file $uri -- keeping it (for now)");
-    fs.data[uri] = data;
-
-    // For dart files we can't truncate completely try to "outline" them
-    // instead.
-    if (uri.toString().endsWith(".dart")) {
-      String textualOutlined =
-          textualOutline(data)?.replaceAll(RegExp(r'\n+'), "\n");
-
-      bool outlined = false;
-      if (textualOutlined != null) {
-        Uint8List candidate = utf8.encode(textualOutlined);
-        if (candidate.length != fs.data[uri].length) {
-          if (await shouldQuit()) return;
-          fs.data[uri] = candidate;
-          if (!await crashesOnCompile(initialComponent)) {
-            print("Can't outline the file $uri -- keeping it (for now)");
-            fs.data[uri] = data;
-          } else {
-            outlined = true;
-            print(
-                "Can outline the file $uri (now ${fs.data[uri].length} bytes)");
+    for (String arg in arguments) {
+      if (arg.startsWith("--")) {
+        if (arg == "--experimental-invalidation") {
+          settings.experimentalInvalidation = true;
+        } else if (arg == "--serialize") {
+          settings.serialize = true;
+        } else if (arg.startsWith("--platform=")) {
+          String platform = arg.substring("--platform=".length);
+          settings.platformUri = Uri.base.resolve(platform);
+        } else if (arg == "--no-platform") {
+          settings.noPlatform = true;
+        } else if (arg.startsWith("--invalidate=")) {
+          for (String s in arg.substring("--invalidate=".length).split(",")) {
+            settings.invalidate.add(Uri.base.resolve(s));
           }
-        }
-      }
-      if (!outlined) {
-        // We can probably at least remove all comments then...
-        try {
-          List<String> strings = utf8.decode(fs.data[uri]).split("\n");
-          List<String> stringsLeft = [];
-          for (String string in strings) {
-            if (!string.trim().startsWith("//")) stringsLeft.add(string);
-          }
-
-          Uint8List candidate = utf8.encode(stringsLeft.join("\n"));
-          if (candidate.length != fs.data[uri].length) {
-            if (await shouldQuit()) return;
-            fs.data[uri] = candidate;
-            if (!await crashesOnCompile(initialComponent)) {
-              print("Can't remove comments for file $uri -- "
-                  "keeping it (for now)");
-              fs.data[uri] = data;
-            } else {
-              print("Removed comments for the file $uri");
-            }
-          }
-        } catch (e) {
-          // crash in scanner/parser --- keep original file. This crash might
-          // be what we're looking for!
-        }
-      }
-    }
-  } else {
-    print("Can delete ${extraMessageText}file $uri");
-    await _tryToRemoveUnreferencedFileContent(initialComponent);
-  }
-}
-
-void deleteBlocksOld(Uri uri, Component initialComponent) async {
-  if (uri.toString().endsWith(".json")) {
-    // Try to find annoying
-    //
-    //    },
-    //    {
-    //    }
-    //
-    // part of json and remove it.
-    Uint8List data = fs.data[uri];
-    String string = utf8.decode(data);
-    List<String> lines = string.split("\n");
-    for (int i = 0; i < lines.length - 2; i++) {
-      if (lines[i].trim() == "}," &&
-          lines[i + 1].trim() == "{" &&
-          lines[i + 2].trim() == "}") {
-        // This is the pattern we wanted to find. Remove it.
-        lines.removeRange(i, i + 2);
-        i--;
-      }
-    }
-    string = lines.join("\n");
-    fs.data[uri] = utf8.encode(string);
-    if (!await crashesOnCompile(initialComponent)) {
-      // For some reason that didn't work.
-      fs.data[uri] = data;
-    }
-  }
-  if (!uri.toString().endsWith(".dart")) return;
-
-  Uint8List data = fs.data[uri];
-  Uint8List latestCrashData = data;
-
-  List<int> lineStarts = <int>[];
-
-  Token firstToken = parser_suite.scanRawBytes(data,
-      nnbd ? scannerConfiguration : scannerConfigurationNonNNBD, lineStarts);
-
-  if (firstToken == null) {
-    print("Got null token from scanner for $uri");
-    return;
-  }
-
-  int compileTry = 0;
-  Token token = firstToken;
-  while (token is ErrorToken) {
-    token = token.next;
-  }
-  List<Replacement> replacements = [];
-  while (token != null && !token.isEof) {
-    bool tryCompile = false;
-    Token skipToToken = token;
-    // Skip very small blocks (e.g. "{}" or "{\n}");
-    if (token.endGroup != null && token.offset + 3 < token.endGroup.offset) {
-      replacements.add(new Replacement(token.offset, token.endGroup.offset));
-      tryCompile = true;
-      skipToToken = token.endGroup;
-    } else if (token.lexeme == "@") {
-      if (token.next.next.endGroup != null) {
-        int end = token.next.next.endGroup.offset;
-        skipToToken = token.next.next.endGroup;
-        replacements.add(new Replacement(token.offset - 1, end + 1));
-        tryCompile = true;
-      }
-    } else if (token.lexeme == "assert") {
-      if (token.next.endGroup != null) {
-        int end = token.next.endGroup.offset;
-        skipToToken = token.next.endGroup;
-        if (token.next.endGroup.next.lexeme == ",") {
-          end = token.next.endGroup.next.offset;
-          skipToToken = token.next.endGroup.next;
-        }
-        // +/- 1 to not include the start and the end character.
-        replacements.add(new Replacement(token.offset - 1, end + 1));
-        tryCompile = true;
-      }
-    } else if ((token.lexeme == "abstract" && token.next.lexeme == "class") ||
-        token.lexeme == "class" ||
-        token.lexeme == "enum" ||
-        token.lexeme == "mixin" ||
-        token.lexeme == "static" ||
-        token.next.lexeme == "get" ||
-        token.next.lexeme == "set" ||
-        token.next.next.lexeme == "(" ||
-        (token.next.lexeme == "<" &&
-            token.next.endGroup != null &&
-            token.next.endGroup.next.next.lexeme == "(")) {
-      // Try to find and remove the entire class/enum/mixin/
-      // static procedure/getter/setter/simple procedure.
-      Token bracket = token;
-      for (int i = 0; i < 20; i++) {
-        // Find "{", but only go a maximum of 20 tokens to do that.
-        bracket = bracket.next;
-        if (bracket.lexeme == "{" && bracket.endGroup != null) {
-          break;
-        } else if ((bracket.lexeme == "(" || bracket.lexeme == "<") &&
-            bracket.endGroup != null) {
-          bracket = bracket.endGroup;
-        }
-      }
-      if (bracket.lexeme == "{" && bracket.endGroup != null) {
-        int end = bracket.endGroup.offset;
-        skipToToken = bracket.endGroup;
-        // +/- 1 to not include the start and the end character.
-        replacements.add(new Replacement(token.offset - 1, end + 1));
-        tryCompile = true;
-      }
-    }
-
-    if (tryCompile) {
-      if (await shouldQuit()) break;
-      if (skip) {
-        skip = false;
-        break;
-      }
-      stdout.write(".");
-      compileTry++;
-      if (compileTry % 50 == 0) {
-        stdout.write("(at $compileTry)\n");
-      }
-      Uint8List candidate = _replaceRange(replacements, data);
-      fs.data[uri] = candidate;
-      if (await crashesOnCompile(initialComponent)) {
-        print("Found block from "
-            "${replacements.last.from} to "
-            "${replacements.last.to} "
-            "that can be removed.");
-        latestCrashData = candidate;
-        token = skipToToken;
-      } else {
-        // Couldn't delete that.
-        replacements.removeLast();
-      }
-    }
-    token = token.next;
-  }
-  fs.data[uri] = latestCrashData;
-}
-
-void deleteBlocks(final Uri uri, Component initialComponent) async {
-  if (uri.toString().endsWith(".json")) {
-    // Try to find annoying
-    //
-    //    },
-    //    {
-    //    }
-    //
-    // part of json and remove it.
-    Uint8List data = fs.data[uri];
-    String string = utf8.decode(data);
-    List<String> lines = string.split("\n");
-    for (int i = 0; i < lines.length - 2; i++) {
-      if (lines[i].trim() == "}," &&
-          lines[i + 1].trim() == "{" &&
-          lines[i + 2].trim() == "}") {
-        // This is the pattern we wanted to find. Remove it.
-        lines.removeRange(i, i + 2);
-        i--;
-      }
-    }
-    string = lines.join("\n");
-    Uint8List candidate = utf8.encode(string);
-    if (candidate.length != data.length) {
-      fs.data[uri] = candidate;
-      if (!await crashesOnCompile(initialComponent)) {
-        // For some reason that didn't work.
-        fs.data[uri] = data;
-      }
-    }
-
-    // Try to load json and remove blocks.
-    try {
-      Map json = jsonDecode(utf8.decode(data));
-      Map jsonModified = new Map.from(json);
-      List packages = json["packages"];
-      List packagesModified = new List.from(packages);
-      jsonModified["packages"] = packagesModified;
-      int i = 0;
-      print("Note there's ${packagesModified.length} packages in .json");
-      JsonEncoder jsonEncoder = new JsonEncoder.withIndent("  ");
-      while (i < packagesModified.length) {
-        var oldEntry = packagesModified.removeAt(i);
-        String jsonString = jsonEncoder.convert(jsonModified);
-        candidate = utf8.encode(jsonString);
-        Uint8List previous = fs.data[uri];
-        fs.data[uri] = candidate;
-        if (!await crashesOnCompile(initialComponent)) {
-          // Couldn't remove that part.
-          fs.data[uri] = previous;
-          packagesModified.insert(i, oldEntry);
-          i++;
+        } else if (arg.startsWith("--widgetTransformation")) {
+          settings.widgetTransformation = true;
+        } else if (arg.startsWith("--target=VM")) {
+          settings.targetString = "VM";
+        } else if (arg.startsWith("--target=flutter")) {
+          settings.targetString = "flutter";
+        } else if (arg.startsWith("--target=ddc")) {
+          settings.targetString = "ddc";
+        } else if (arg == "--oldBlockDelete") {
+          settings.oldBlockDelete = true;
+        } else if (arg == "--lineDelete") {
+          settings.lineDelete = true;
+        } else if (arg == "--byteDelete") {
+          settings.byteDelete = true;
+        } else if (arg == "--ask-redirect-target") {
+          settings.askAboutRedirectCrashTarget = true;
+        } else if (arg == "--auto-uncover-all-crashes") {
+          settings.autoUncoverAllCrashes = true;
+        } else if (arg.startsWith("--stack-matches=")) {
+          String stackMatches = arg.substring("--stack-matches=".length);
+          settings.stackTraceMatches = int.parse(stackMatches);
         } else {
-          print(
-              "Removed package from .json (${packagesModified.length} left).");
+          throw "Unknown option $arg";
         }
-      }
-    } catch (e) {
-      // Couldn't decode it, so don't try to do anything.
-    }
-    return;
-  }
-  if (!uri.toString().endsWith(".dart")) return;
-
-  Uint8List data = fs.data[uri];
-  DirectParserASTContentCompilationUnitEnd ast = getAST(data,
-      includeBody: true,
-      includeComments: false,
-      enableExtensionMethods: true,
-      enableNonNullable: nnbd);
-
-  CompilationHelperClass helper = new CompilationHelperClass(data);
-
-  // Try to remove top level things on at a time.
-  for (DirectParserASTContent child in ast.children) {
-    bool shouldCompile = false;
-    String what = "";
-    if (child.isClass()) {
-      DirectParserASTContentClassDeclarationEnd cls = child.asClass();
-      helper.replacements.add(
-          new Replacement(cls.beginToken.offset - 1, cls.endToken.offset + 1));
-      shouldCompile = true;
-      what = "class";
-    } else if (child.isMixinDeclaration()) {
-      DirectParserASTContentMixinDeclarationEnd decl =
-          child.asMixinDeclaration();
-      helper.replacements.add(new Replacement(
-          decl.mixinKeyword.offset - 1, decl.endToken.offset + 1));
-      shouldCompile = true;
-      what = "mixin";
-    } else if (child.isNamedMixinDeclaration()) {
-      DirectParserASTContentNamedMixinApplicationEnd decl =
-          child.asNamedMixinDeclaration();
-      helper.replacements.add(
-          new Replacement(decl.begin.offset - 1, decl.endToken.offset + 1));
-      shouldCompile = true;
-      what = "named mixin";
-    } else if (child.isExtension()) {
-      DirectParserASTContentExtensionDeclarationEnd decl = child.asExtension();
-      helper.replacements.add(new Replacement(
-          decl.extensionKeyword.offset - 1, decl.endToken.offset + 1));
-      shouldCompile = true;
-      what = "extension";
-    } else if (child.isTopLevelFields()) {
-      DirectParserASTContentTopLevelFieldsEnd decl = child.asTopLevelFields();
-      helper.replacements.add(new Replacement(
-          decl.beginToken.offset - 1, decl.endToken.offset + 1));
-      shouldCompile = true;
-      what = "toplevel fields";
-    } else if (child.isTopLevelMethod()) {
-      DirectParserASTContentTopLevelMethodEnd decl = child.asTopLevelMethod();
-      helper.replacements.add(new Replacement(
-          decl.beginToken.offset - 1, decl.endToken.offset + 1));
-      shouldCompile = true;
-      what = "toplevel method";
-    } else if (child.isEnum()) {
-      DirectParserASTContentEnumEnd decl = child.asEnum();
-      helper.replacements.add(new Replacement(
-          decl.enumKeyword.offset - 1, decl.leftBrace.endGroup.offset + 1));
-      shouldCompile = true;
-      what = "enum";
-    } else if (child.isTypedef()) {
-      DirectParserASTContentFunctionTypeAliasEnd decl = child.asTypedef();
-      helper.replacements.add(new Replacement(
-          decl.typedefKeyword.offset - 1, decl.endToken.offset + 1));
-      shouldCompile = true;
-      what = "typedef";
-    } else if (child.isMetadata()) {
-      DirectParserASTContentMetadataStarEnd decl = child.asMetadata();
-      List<DirectParserASTContentMetadataEnd> metadata =
-          decl.getMetadataEntries();
-      if (metadata.isNotEmpty) {
-        helper.replacements.add(new Replacement(
-            metadata.first.beginToken.offset - 1,
-            metadata.last.endToken.offset));
-        shouldCompile = true;
-      }
-      what = "metadata";
-    } else if (child.isImport()) {
-      DirectParserASTContentImportEnd decl = child.asImport();
-      helper.replacements.add(new Replacement(
-          decl.importKeyword.offset - 1, decl.semicolon.offset + 1));
-      shouldCompile = true;
-      what = "import";
-    } else if (child.isExport()) {
-      DirectParserASTContentExportEnd decl = child.asExport();
-      helper.replacements.add(new Replacement(
-          decl.exportKeyword.offset - 1, decl.semicolon.offset + 1));
-      shouldCompile = true;
-      what = "export";
-    } else if (child.isLibraryName()) {
-      DirectParserASTContentLibraryNameEnd decl = child.asLibraryName();
-      helper.replacements.add(new Replacement(
-          decl.libraryKeyword.offset - 1, decl.semicolon.offset + 1));
-      shouldCompile = true;
-      what = "library name";
-    } else if (child.isPart()) {
-      DirectParserASTContentPartEnd decl = child.asPart();
-      helper.replacements.add(new Replacement(
-          decl.partKeyword.offset - 1, decl.semicolon.offset + 1));
-      shouldCompile = true;
-      what = "part";
-    } else if (child.isPartOf()) {
-      DirectParserASTContentPartOfEnd decl = child.asPartOf();
-      helper.replacements.add(new Replacement(
-          decl.partKeyword.offset - 1, decl.semicolon.offset + 1));
-      shouldCompile = true;
-      what = "part of";
-    } else if (child.isScript()) {
-      var decl = child.asScript();
-      helper.replacements.add(new Replacement(
-          decl.token.offset - 1, decl.token.offset + decl.token.length));
-      shouldCompile = true;
-      what = "script";
-    }
-
-    if (shouldCompile) {
-      bool success =
-          await _tryReplaceAndCompile(helper, uri, initialComponent, what);
-      if (helper.shouldQuit) return;
-      if (!success) {
-        if (child.isClass()) {
-          // Also try to remove all content of the class.
-          DirectParserASTContentClassDeclarationEnd decl = child.asClass();
-          DirectParserASTContentClassOrMixinBodyEnd body =
-              decl.getClassOrMixinBody();
-          if (body.beginToken.offset + 2 < body.endToken.offset) {
-            helper.replacements.add(
-                new Replacement(body.beginToken.offset, body.endToken.offset));
-            what = "class body";
-            success = await _tryReplaceAndCompile(
-                helper, uri, initialComponent, what);
-            if (helper.shouldQuit) return;
-          }
-
-          if (!success) {
-            // Also try to remove members one at a time.
-            for (DirectParserASTContent child in body.children) {
-              shouldCompile = false;
-              if (child is DirectParserASTContentMemberEnd) {
-                if (child.isClassConstructor()) {
-                  DirectParserASTContentClassConstructorEnd memberDecl =
-                      child.getClassConstructor();
-                  helper.replacements.add(new Replacement(
-                      memberDecl.beginToken.offset - 1,
-                      memberDecl.endToken.offset + 1));
-                  what = "class constructor";
-                  shouldCompile = true;
-                } else if (child.isClassFields()) {
-                  DirectParserASTContentClassFieldsEnd memberDecl =
-                      child.getClassFields();
-                  helper.replacements.add(new Replacement(
-                      memberDecl.beginToken.offset - 1,
-                      memberDecl.endToken.offset + 1));
-                  what = "class fields";
-                  shouldCompile = true;
-                } else if (child.isClassMethod()) {
-                  DirectParserASTContentClassMethodEnd memberDecl =
-                      child.getClassMethod();
-                  helper.replacements.add(new Replacement(
-                      memberDecl.beginToken.offset - 1,
-                      memberDecl.endToken.offset + 1));
-                  what = "class method";
-                  shouldCompile = true;
-                } else if (child.isClassFactoryMethod()) {
-                  DirectParserASTContentClassFactoryMethodEnd memberDecl =
-                      child.getClassFactoryMethod();
-                  helper.replacements.add(new Replacement(
-                      memberDecl.beginToken.offset - 1,
-                      memberDecl.endToken.offset + 1));
-                  what = "class factory method";
-                  shouldCompile = true;
-                } else {
-                  // throw "$child --- ${child.children}";
-                  continue;
-                }
-              } else if (child.isMetadata()) {
-                DirectParserASTContentMetadataStarEnd decl = child.asMetadata();
-                List<DirectParserASTContentMetadataEnd> metadata =
-                    decl.getMetadataEntries();
-                if (metadata.isNotEmpty) {
-                  helper.replacements.add(new Replacement(
-                      metadata.first.beginToken.offset - 1,
-                      metadata.last.endToken.offset));
-                  shouldCompile = true;
-                }
-                what = "metadata";
-              }
-              if (shouldCompile) {
-                success = await _tryReplaceAndCompile(
-                    helper, uri, initialComponent, what);
-                if (helper.shouldQuit) return;
-                if (!success) {
-                  DirectParserASTContentBlockFunctionBodyEnd decl;
-                  if (child is DirectParserASTContentMemberEnd) {
-                    if (child.isClassMethod()) {
-                      decl = child.getClassMethod().getBlockFunctionBody();
-                    } else if (child.isClassConstructor()) {
-                      decl = child.getClassConstructor().getBlockFunctionBody();
-                    }
-                  }
-                  if (decl != null &&
-                      decl.beginToken.offset + 2 < decl.endToken.offset) {
-                    helper.replacements.add(new Replacement(
-                        decl.beginToken.offset, decl.endToken.offset));
-                    what = "class member content";
-                    await _tryReplaceAndCompile(
-                        helper, uri, initialComponent, what);
-                    if (helper.shouldQuit) return;
-                  }
-                }
-              }
-            }
-          }
-
-          // Try to remove "extends", "implements" etc.
-          if (decl.getClassExtends().extendsKeyword != null) {
-            helper.replacements.add(new Replacement(
-                decl.getClassExtends().extendsKeyword.offset - 1,
-                body.beginToken.offset));
-            what = "class extends";
-            success = await _tryReplaceAndCompile(
-                helper, uri, initialComponent, what);
-            if (helper.shouldQuit) return;
-          }
-          if (decl.getClassImplements().implementsKeyword != null) {
-            helper.replacements.add(new Replacement(
-                decl.getClassImplements().implementsKeyword.offset - 1,
-                body.beginToken.offset));
-            what = "class implements";
-            success = await _tryReplaceAndCompile(
-                helper, uri, initialComponent, what);
-            if (helper.shouldQuit) return;
-          }
-          if (decl.getClassWithClause() != null) {
-            helper.replacements.add(new Replacement(
-                decl.getClassWithClause().withKeyword.offset - 1,
-                body.beginToken.offset));
-            what = "class with clause";
-            success = await _tryReplaceAndCompile(
-                helper, uri, initialComponent, what);
-            if (helper.shouldQuit) return;
-          }
-        }
-      }
-    }
-  }
-}
-
-class CompilationHelperClass {
-  int compileTry = 0;
-  bool shouldQuit = false;
-  List<Replacement> replacements = [];
-  Uint8List latestCrashData;
-  final Uint8List originalData;
-
-  CompilationHelperClass(this.originalData) : latestCrashData = originalData;
-}
-
-Future<bool> _tryReplaceAndCompile(CompilationHelperClass data, Uri uri,
-    Component initialComponent, String what) async {
-  if (await shouldQuit()) {
-    data.shouldQuit = true;
-    return false;
-  }
-  stdout.write(".");
-  data.compileTry++;
-  if (data.compileTry % 50 == 0) {
-    stdout.write("(at ${data.compileTry})\n");
-  }
-  Uint8List candidate = _replaceRange(data.replacements, data.originalData);
-
-  fs.data[uri] = candidate;
-  if (await crashesOnCompile(initialComponent)) {
-    print("Found $what from "
-        "${data.replacements.last.from} to "
-        "${data.replacements.last.to} "
-        "that can be removed.");
-    data.latestCrashData = candidate;
-    return true;
-  } else {
-    // Couldn't delete that.
-    data.replacements.removeLast();
-    fs.data[uri] = data.latestCrashData;
-    return false;
-  }
-}
-
-class Replacement implements Comparable<Replacement> {
-  final int from;
-  final int to;
-  final Uint8List nullOrReplacement;
-
-  Replacement(this.from, this.to, {this.nullOrReplacement});
-
-  @override
-  int compareTo(Replacement other) {
-    return from - other.from;
-  }
-}
-
-Uint8List _replaceRange(
-    List<Replacement> unsortedReplacements, Uint8List data) {
-  // The below assumes these are sorted.
-  List<Replacement> sortedReplacements =
-      new List<Replacement>.from(unsortedReplacements)..sort();
-  final BytesBuilder builder = new BytesBuilder();
-  int prev = 0;
-  for (int i = 0; i < sortedReplacements.length; i++) {
-    Replacement replacement = sortedReplacements[i];
-    for (int j = prev; j <= replacement.from; j++) {
-      builder.addByte(data[j]);
-    }
-    if (replacement.nullOrReplacement != null) {
-      builder.add(replacement.nullOrReplacement);
-    }
-    prev = replacement.to;
-  }
-  for (int j = prev; j < data.length; j++) {
-    builder.addByte(data[j]);
-  }
-  Uint8List candidate = builder.takeBytes();
-  return candidate;
-}
-
-const int $LF = 10;
-
-void deleteEmptyLines(Uri uri, Component initialComponent) async {
-  Uint8List data = fs.data[uri];
-  List<Uint8List> lines = [];
-  int start = 0;
-  for (int i = 0; i < data.length; i++) {
-    if (data[i] == $LF) {
-      if (i - start > 0) {
-        lines.add(sublist(data, start, i));
-      }
-      start = i + 1;
-    }
-  }
-  if (data.length - start > 0) {
-    lines.add(sublist(data, start, data.length));
-  }
-
-  final BytesBuilder builder = new BytesBuilder();
-  for (int j = 0; j < lines.length; j++) {
-    if (builder.isNotEmpty) {
-      builder.addByte($LF);
-    }
-    builder.add(lines[j]);
-  }
-  Uint8List candidate = builder.takeBytes();
-  if (candidate.length == data.length) return;
-
-  if (await shouldQuit()) return;
-  fs.data[uri] = candidate;
-  if (!await crashesOnCompile(initialComponent)) {
-    // For some reason the empty lines are important.
-    fs.data[uri] = data;
-  } else {
-    print("\nDeleted empty lines.");
-  }
-}
-
-void deleteLines(Uri uri, Component initialComponent) async {
-  // Try to delete "lines".
-  Uint8List data = fs.data[uri];
-  List<Uint8List> lines = [];
-  int start = 0;
-  for (int i = 0; i < data.length; i++) {
-    if (data[i] == $LF) {
-      lines.add(sublist(data, start, i));
-      start = i + 1;
-    }
-  }
-  lines.add(sublist(data, start, data.length));
-  List<bool> include = new List.filled(lines.length, true);
-  Uint8List latestCrashData = data;
-  int length = 1;
-  int i = 0;
-  while (i < lines.length) {
-    if (await shouldQuit()) break;
-    if (skip) {
-      skip = false;
-      break;
-    }
-    stdout.write(".");
-    if (i % 50 == 0) {
-      stdout.write("(at $i of ${lines.length})\n");
-    }
-    if (i + length > lines.length) {
-      length = lines.length - i;
-    }
-    for (int j = i; j < i + length; j++) {
-      include[j] = false;
-    }
-    final BytesBuilder builder = new BytesBuilder();
-    for (int j = 0; j < lines.length; j++) {
-      if (include[j]) {
-        if (builder.isNotEmpty) {
-          builder.addByte($LF);
-        }
-        builder.add(lines[j]);
-      }
-    }
-    Uint8List candidate = builder.takeBytes();
-    fs.data[uri] = candidate;
-    if (!await crashesOnCompile(initialComponent)) {
-      // Didn't crash => Can't remove line i-j.
-      for (int j = i; j < i + length; j++) {
-        include[j] = true;
-      }
-      if (length > 2) {
-        // Retry with length 2 at same i.
-        // The idea here is that for instance formatted json might have lines
-        // looking like
-        // {
-        // }
-        // where deleting just one line makes it invalid.
-        length = 2;
-      } else if (length > 1) {
-        // Retry with length 1 at same i.
-        length = 1;
+      } else if (filename != null) {
+        throw "Already got '$filename', '$arg' is also a filename; "
+            "can only get one";
       } else {
-        // Couldn't with length 1 either.
+        filename = arg;
+      }
+    }
+    if (settings.noPlatform) {
+      int i = 0;
+      while (settings.platformUri == null ||
+          new File.fromUri(settings.platformUri).existsSync()) {
+        settings.platformUri = Uri.base.resolve("nonexisting_$i");
         i++;
       }
     } else {
-      print("\nCan delete line $i (inclusive) - ${i + length} (exclusive) "
-          "(of ${lines.length})");
-      latestCrashData = candidate;
-      i += length;
-      length *= 2;
-    }
-  }
-  fs.data[uri] = latestCrashData;
-}
-
-Component _latestComponent;
-IncrementalCompiler _latestIncrementalCompiler;
-
-Future<bool> crashesOnCompile(Component initialComponent) async {
-  IncrementalCompiler incrementalCompiler;
-  if (noPlatform) {
-    incrementalCompiler = new IncrementalCompiler(setupCompilerContext());
-  } else {
-    incrementalCompiler = new IncrementalCompiler.fromComponent(
-        setupCompilerContext(), initialComponent);
-  }
-  _latestIncrementalCompiler = incrementalCompiler;
-  incrementalCompiler.invalidate(mainUri);
-  try {
-    _latestComponent = await incrementalCompiler.computeDelta();
-    if (serialize) {
-      ByteSink sink = new ByteSink();
-      BinaryPrinter printer = new BinaryPrinter(sink);
-      printer.writeComponentFile(_latestComponent);
-      sink.builder.takeBytes();
-    }
-    for (Uri uri in invalidate) {
-      incrementalCompiler.invalidate(uri);
-      Component delta = await incrementalCompiler.computeDelta();
-      if (serialize) {
-        ByteSink sink = new ByteSink();
-        BinaryPrinter printer = new BinaryPrinter(sink);
-        printer.writeComponentFile(delta);
-        sink.builder.takeBytes();
+      if (settings.platformUri == null) {
+        throw "No platform given. Use --platform=/path/to/platform.dill";
+      }
+      if (!new File.fromUri(settings.platformUri).existsSync()) {
+        throw "The platform file '${settings.platformUri}' doesn't exist";
       }
     }
-    _latestComponent = null; // if it didn't crash this isn't relevant.
-    return false;
-  } catch (e, st) {
-    // Find line with #0 in it.
-    String eWithSt = "$e\n\n$st";
-    List<String> lines = eWithSt.split("\n");
-    String foundLine = "";
-    int lookFor = 0;
-    for (String line in lines) {
-      if (line.startsWith("#$lookFor")) {
-        foundLine += line;
-        lookFor++;
-        if (lookFor >= stackTraceMatches) {
-          break;
-        } else {
-          foundLine += "\n";
-        }
-      }
+    if (filename == null) {
+      throw "Need file to operate on";
     }
-    if (foundLine == null) throw "Unexpected crash without stacktrace: $e";
-    if (expectedCrashLine == null) {
-      print("Got '$foundLine'");
-      expectedCrashLine = foundLine;
-      return true;
-    } else if (foundLine == expectedCrashLine) {
-      return true;
-    } else {
-      if (askAboutRedirectCrashTarget &&
-          !askedAboutRedirect.contains(foundLine)) {
-        print("Crashed, but another place: $foundLine");
-        while (true) {
-          askedAboutRedirect.add(foundLine);
-          print(eWithSt);
-          print("Should we redirect to searching for that? (y/n)");
-          String answer = stdin.readLineSync();
-          if (answer == "yes" || answer == "y") {
-            expectedCrashLine = foundLine;
-            return true;
-          } else if (answer == "no" || answer == "n") {
-            break;
-          } else {
-            print("Didn't get that answer. "
-                "Please answer 'yes, 'y', 'no' or 'n'");
-          }
-        }
-      }
-      return false;
-    }
-  }
-}
-
-Future<Component> getInitialComponent() async {
-  IncrementalCompiler incrementalCompiler =
-      new IncrementalCompiler(setupCompilerContext());
-  Component originalComponent = await incrementalCompiler.computeDelta();
-  return originalComponent;
-}
-
-CompilerContext setupCompilerContext() {
-  CompilerOptions options = getOptions();
-
-  if (nnbd) {
-    options.explicitExperimentalFlags = {ExperimentalFlag.nonNullable: true};
-  }
-  if (experimentalInvalidation) {
-    options.explicitExperimentalFlags ??= {};
-    options.explicitExperimentalFlags[
-        ExperimentalFlag.alternativeInvalidationStrategy] = true;
+    File file = new File(filename);
+    if (!file.existsSync()) throw "File $filename doesn't exist.";
+    settings.mainUri = file.absolute.uri;
   }
 
-  TargetFlags targetFlags = new TargetFlags(
-      enableNullSafety: nnbd, trackWidgetCreation: widgetTransformation);
-  Target target;
-  switch (targetString) {
-    case "VM":
-      target = new VmTarget(targetFlags);
-      break;
-    case "flutter":
-      target = new FlutterTarget(targetFlags);
-      break;
-    case "ddc":
-      target = new DevCompilerTarget(targetFlags);
-      break;
-    default:
-      throw "Unknown target '$target'";
-  }
-  options.target = target;
-  options.fileSystem = fs;
-  options.sdkRoot = null;
-  options.sdkSummary = platformUri;
-  options.omitPlatform = false;
-  options.onDiagnostic = (DiagnosticMessage message) {
-    // don't care.
-  };
-  if (noPlatform) {
-    options.librariesSpecificationUri = null;
-  }
-
-  CompilerContext compilerContext = new CompilerContext(
-      new ProcessedOptions(options: options, inputs: [mainUri]));
-  return compilerContext;
-}
-
-String getFileAsStringContent(Uint8List rawBytes, bool nnbd) {
-  List<int> lineStarts = <int>[];
-
-  Token firstToken = parser_suite.scanRawBytes(rawBytes,
-      nnbd ? scannerConfiguration : scannerConfigurationNonNNBD, lineStarts);
-
-  if (firstToken == null) {
-    throw "Got null token from scanner";
-  }
-
-  ParserTestListener parserTestListener = new ParserTestListener(false);
-  Parser parser = new Parser(parserTestListener);
-  parser.parseUnit(firstToken);
-  String parsedString =
-      parser_suite.tokenStreamToString(firstToken, lineStarts).toString();
-  return parsedString;
-}
-
-ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
-    enableTripleShift: true,
-    enableExtensionMethods: true,
-    enableNonNullable: true);
-
-ScannerConfiguration scannerConfigurationNonNNBD = new ScannerConfiguration(
-    enableTripleShift: true,
-    enableExtensionMethods: true,
-    enableNonNullable: false);
-
-class FakeFileSystem extends FileSystem {
-  bool _redirectAndRecord = true;
-  bool _initialized = false;
-  final Map<Uri, Uint8List> data = {};
-
-  @override
-  FileSystemEntity entityForUri(Uri uri) {
-    return new FakeFileSystemEntity(this, uri);
-  }
-
-  initializeFromJson(Map<String, dynamic> json) {
-    _initialized = true;
-    _redirectAndRecord = json['_redirectAndRecord'];
-    data.clear();
-    List tmp = json['data'];
-    for (int i = 0; i < tmp.length; i += 2) {
-      Uri key = tmp[i] == null ? null : Uri.parse(tmp[i]);
-      if (tmp[i + 1] == null) {
-        data[key] = null;
-      } else if (tmp[i + 1] is String) {
-        data[key] = utf8.encode(tmp[i + 1]);
-      } else {
-        data[key] = Uint8List.fromList(new List<int>.from(tmp[i + 1]));
-      }
-    }
-  }
-
-  Map<String, dynamic> toJson() {
-    List tmp = [];
-    for (var entry in data.entries) {
-      if (entry.value == null) continue;
-      tmp.add(entry.key == null ? null : entry.key.toString());
-      dynamic out = entry.value;
-      if (entry.value != null && entry.value.isNotEmpty) {
-        try {
-          String string = utf8.decode(entry.value);
-          out = string;
-        } catch (e) {
-          // not a string...
-        }
-      }
-      tmp.add(out);
-    }
-    return {
-      '_redirectAndRecord': _redirectAndRecord,
-      'data': tmp,
-    };
-  }
-}
-
-class FakeFileSystemEntity extends FileSystemEntity {
-  final FakeFileSystem fs;
-  final Uri uri;
-  FakeFileSystemEntity(this.fs, this.uri);
-
-  void _ensureCachedIfOk() {
-    if (fs.data.containsKey(uri)) return;
-    if (fs._initialized) return;
-    if (!fs._redirectAndRecord) {
-      throw "Asked for file in non-recording mode that wasn't known";
-    }
-    File f = new File.fromUri(uri);
-    if (!f.existsSync()) {
-      fs.data[uri] = null;
-      return;
-    }
-    fs.data[uri] = f.readAsBytesSync();
-  }
-
-  @override
-  Future<bool> exists() {
-    _ensureCachedIfOk();
-    Uint8List data = fs.data[uri];
-    if (data == null) return Future.value(false);
-    return Future.value(true);
-  }
-
-  @override
-  Future<List<int>> readAsBytes() {
-    _ensureCachedIfOk();
-    Uint8List data = fs.data[uri];
-    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
-    return Future.value(data);
-  }
-
-  @override
-  Future<String> readAsString() {
-    _ensureCachedIfOk();
-    Uint8List data = fs.data[uri];
-    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
-    return Future.value(utf8.decode(data));
-  }
+  TestMinimizer testMinimizer = new TestMinimizer(settings);
+  await testMinimizer.tryToMinimize();
 }
diff --git a/pkg/front_end/test/crashing_test_case_minimizer_impl.dart b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
new file mode 100644
index 0000000..8bda7f4
--- /dev/null
+++ b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
@@ -0,0 +1,2102 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async' show Future, StreamSubscription;
+
+import 'dart:convert' show JsonEncoder, jsonDecode, utf8;
+
+import 'dart:io' show BytesBuilder, File, stdin, stdout;
+
+import 'dart:math' show max;
+
+import 'dart:typed_data' show Uint8List;
+
+import 'package:_fe_analyzer_shared/src/util/relativize.dart'
+    show relativizeUri, isWindows;
+
+import 'package:_fe_analyzer_shared/src/parser/parser.dart'
+    show Listener, Parser;
+
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+    show ErrorToken, ScannerConfiguration, Token;
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+
+import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
+
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+    show CompilerOptions, DiagnosticMessage;
+
+import 'package:front_end/src/api_prototype/experimental_flags.dart'
+    show ExperimentalFlag;
+
+import 'package:front_end/src/api_prototype/file_system.dart'
+    show FileSystem, FileSystemEntity, FileSystemException;
+
+import 'package:front_end/src/base/processed_options.dart'
+    show ProcessedOptions;
+import 'package:front_end/src/fasta/builder/library_builder.dart';
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+    show IncrementalCompiler;
+
+import 'package:front_end/src/fasta/kernel/utils.dart' show ByteSink;
+import 'package:front_end/src/fasta/messages.dart' show Message;
+import 'package:front_end/src/fasta/util/direct_parser_ast.dart';
+import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
+
+import 'package:front_end/src/fasta/util/textual_outline.dart'
+    show textualOutline;
+
+import 'package:kernel/ast.dart' show Component;
+
+import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
+
+import 'package:kernel/target/targets.dart' show Target, TargetFlags;
+import 'package:package_config/package_config.dart';
+
+import "package:vm/target/flutter.dart" show FlutterTarget;
+
+import "package:vm/target/vm.dart" show VmTarget;
+
+import 'incremental_load_from_dill_suite.dart' show getOptions;
+
+import 'parser_test_listener.dart' show ParserTestListener;
+
+import 'parser_suite.dart' as parser_suite;
+
+class TestMinimizerSettings {
+  final _FakeFileSystem _fsInitial = new _FakeFileSystem();
+  final _FakeFileSystem _fsNotInitial = new _FakeFileSystem();
+  _FakeFileSystem get _fs {
+    if (_useInitialFs) return _fsInitial;
+    return _fsNotInitial;
+  }
+
+  bool _useInitialFs = true;
+  Uri mainUri;
+  Uri platformUri;
+  bool noPlatform = false;
+  bool experimentalInvalidation = false;
+  bool serialize = false;
+  bool widgetTransformation = false;
+  final List<Uri> invalidate = [];
+  String targetString = "VM";
+  bool oldBlockDelete = false;
+  bool lineDelete = false;
+  bool byteDelete = false;
+  bool askAboutRedirectCrashTarget = false;
+  bool autoUncoverAllCrashes = false;
+  int stackTraceMatches = 1;
+  final Set<String> askedAboutRedirect = {};
+  final List<Map<String, dynamic>> fileSystems = [];
+  final Set<String> allAutoRedirects = {};
+
+  void goToFileSystem(int i) {
+    Map<String, dynamic> fileSystem = fileSystems[i];
+    fileSystems[i] = _fsNotInitial.toJson();
+    _fsNotInitial.initializeFromJson(fileSystem);
+  }
+
+  Map<String, dynamic> toJson() {
+    List<Map<String, dynamic>> fileSystems =
+        new List<Map<String, dynamic>>.from(this.fileSystems);
+    fileSystems.add(_fsNotInitial.toJson());
+    return {
+      'mainUri': mainUri.toString(),
+      'platformUri': platformUri.toString(),
+      'noPlatform': noPlatform,
+      'experimentalInvalidation': experimentalInvalidation,
+      'serialize': serialize,
+      'widgetTransformation': widgetTransformation,
+      'invalidate': invalidate.map((uri) => uri.toString()).toList(),
+      'targetString': targetString,
+      'oldBlockDelete': oldBlockDelete,
+      'lineDelete': lineDelete,
+      'byteDelete': byteDelete,
+      'askAboutRedirectCrashTarget': askAboutRedirectCrashTarget,
+      'autoUncoverAllCrashes': autoUncoverAllCrashes,
+      'stackTraceMatches': stackTraceMatches,
+      'askedAboutRedirect': askedAboutRedirect.toList(),
+      'fileSystems': fileSystems,
+      'allAutoRedirects': allAutoRedirects.toList(),
+    };
+  }
+
+  initializeFromJson(Map<String, dynamic> json) {
+    mainUri = Uri.parse(json["mainUri"]);
+    platformUri = Uri.parse(json["platformUri"]);
+    noPlatform = json["noPlatform"];
+    experimentalInvalidation = json["experimentalInvalidation"];
+    serialize = json["serialize"];
+    widgetTransformation = json["widgetTransformation"];
+    invalidate.clear();
+    invalidate.addAll(
+        (json["invalidate"] as List).map((uriString) => Uri.parse(uriString)));
+    targetString = json["targetString"];
+    oldBlockDelete = json["oldBlockDelete"];
+    lineDelete = json["lineDelete"];
+    byteDelete = json["byteDelete"];
+    askAboutRedirectCrashTarget = json["askAboutRedirectCrashTarget"];
+    autoUncoverAllCrashes = json["autoUncoverAllCrashes"];
+    stackTraceMatches = json["stackTraceMatches"];
+    askedAboutRedirect.clear();
+    askedAboutRedirect.addAll((json["askedAboutRedirect"] as List).cast());
+    fileSystems.clear();
+    fileSystems.addAll((json["fileSystems"] as List).cast());
+    allAutoRedirects.clear();
+    allAutoRedirects.addAll((json["allAutoRedirects"] as List).cast());
+
+    _fsNotInitial.initializeFromJson(fileSystems.removeLast());
+  }
+}
+
+class TestMinimizer {
+  final TestMinimizerSettings _settings;
+  _FakeFileSystem get _fs => _settings._fs;
+  Uri get _mainUri => _settings.mainUri;
+  String _expectedCrashLine;
+  bool _quit = false;
+  bool _skip = false;
+  bool _check = false;
+  int _currentFsNum = -1;
+
+  Component _latestComponent;
+  IncrementalCompiler _latestCrashingIncrementalCompiler;
+  StreamSubscription<List<int>> _stdinSubscription;
+
+  static const int _$LF = 10;
+
+  TestMinimizer(this._settings);
+
+  void _setupStdin() {
+    try {
+      stdin.echoMode = false;
+      stdin.lineMode = false;
+    } catch (e) {
+      print("error setting settings on stdin");
+    }
+    _stdinSubscription = stdin.listen((List<int> event) {
+      if (event.length == 1 && event.single == "q".codeUnits.single) {
+        print("\n\nGot told to quit!\n\n");
+        _quit = true;
+      } else if (event.length == 1 && event.single == "s".codeUnits.single) {
+        print("\n\nGot told to skip!\n\n");
+        _skip = true;
+      } else if (event.length == 1 && event.single == "c".codeUnits.single) {
+        print("\n\nGot told to check!\n\n");
+        _check = true;
+      } else if (event.length == 1 && event.single == "i".codeUnits.single) {
+        print("\n\n--- STATUS INFORMATION START ---\n\n");
+        print("Currently looking for this crash: $_expectedCrashLine\n\n");
+        print("Currently on filesystem #$_currentFsNum out of "
+            "${_settings.fileSystems.length}\n\n");
+
+        int totalFiles = 0;
+        int emptyFiles = 0;
+        int combinedSize = 0;
+        for (Uri uri in _fs.data.keys) {
+          final Uint8List originalBytes = _fs.data[uri];
+          if (originalBytes == null) continue;
+          totalFiles++;
+          if (originalBytes.isEmpty) emptyFiles++;
+          combinedSize += originalBytes.length;
+        }
+        print("Total files left: $totalFiles.");
+        print("Of which empty: $emptyFiles.");
+        print("Combined size left: $combinedSize bytes.");
+        print("\n\n--- STATUS INFORMATION END ---\n\n");
+      } else {
+        print("\n\nGot stdin input: $event\n\n");
+      }
+    });
+  }
+
+  Future tryToMinimize() async {
+    _setupStdin();
+    while (_currentFsNum < _settings.fileSystems.length) {
+      try {
+        if (_currentFsNum >= 0) {
+          print("Replacing filesystem!");
+          _settings.goToFileSystem(_currentFsNum);
+          _expectedCrashLine = null;
+          _latestComponent = null;
+          _latestCrashingIncrementalCompiler = null;
+        }
+        await _tryToMinimizeImpl();
+        if (_currentFsNum + 1 < _settings.fileSystems.length) {
+          // We have more to do --- but we just printed something the user might
+          // want to read. So wait a little before continuing.
+          print("Waiting for 5 seconds before continuing.");
+          await Future.delayed(new Duration(seconds: 5));
+        }
+      } catch (e) {
+        if (e is _DoesntCrashOnInput) {
+          print("Currently doesn't crash (or no longer crashes) the compiler.");
+        } else {
+          print("About to crash. Dumping settings including the filesystem so "
+              "we can (hopefully) continue later.");
+          _dumpToJson();
+          rethrow;
+        }
+      }
+      _currentFsNum++;
+    }
+
+    await _stdinSubscription.cancel();
+  }
+
+  Future _tryToMinimizeImpl() async {
+    // Set main to be basically empty up front.
+    _settings._useInitialFs = true;
+    _fs.data[_mainUri] = utf8.encode("main() {}");
+    Component initialComponent = await _getInitialComponent();
+    print("Compiled initially (without data)");
+    // Remove fake cache.
+    _fs.data.remove(_mainUri);
+    _settings._useInitialFs = false;
+
+    // First assure it actually crash on the input.
+    if (!await _crashesOnCompile(initialComponent)) {
+      throw new _DoesntCrashOnInput();
+    }
+    print("Step #1: We did crash on the input!");
+
+    // All file should now be cached.
+    _fs._redirectAndRecord = false;
+
+    // For all dart files: Parse them as set their source as the parsed source
+    // to "get around" any encoding issues when printing later.
+    Map<Uri, Uint8List> copy = new Map.from(_fs.data);
+    for (Uri uri in _fs.data.keys) {
+      if (await _shouldQuit()) break;
+      String uriString = uri.toString();
+      if (uriString.endsWith(".json") ||
+          uriString.endsWith(".packages") ||
+          uriString.endsWith(".dill") ||
+          _fs.data[uri] == null ||
+          _fs.data[uri].isEmpty) {
+        // skip
+      } else {
+        try {
+          if (_knownByCompiler(uri)) {
+            String parsedString =
+                _getFileAsStringContent(_fs.data[uri], _isUriNnbd(uri));
+            _fs.data[uri] = utf8.encode(parsedString);
+          }
+        } catch (e) {
+          // crash in scanner/parser --- keep original file. This crash might
+          // be what we're looking for!
+        }
+      }
+    }
+    if (!await _crashesOnCompile(initialComponent)) {
+      // Now - for whatever reason - we didn't crash. Restore.
+      _fs.data.clear();
+      _fs.data.addAll(copy);
+    }
+
+    // Operate on one file at a time: Try to delete all content in file.
+    List<Uri> uris = new List<Uri>.from(_fs.data.keys);
+
+    // TODO(jensj): Can we "thread" this?
+    bool changedSome = true;
+    while (changedSome) {
+      if (await _shouldQuit()) break;
+      while (changedSome) {
+        if (await _shouldQuit()) break;
+        changedSome = false;
+        for (int i = 0; i < uris.length; i++) {
+          if (await _shouldQuit()) break;
+          Uri uri = uris[i];
+          if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+          print("About to work on file $i of ${uris.length}");
+          await _deleteContent(uris, i, false, initialComponent);
+          if (_fs.data[uri] == null || _fs.data[uri].isEmpty) {
+            changedSome = true;
+          }
+        }
+      }
+
+      // Try to delete empty files.
+      bool changedSome2 = true;
+      while (changedSome2) {
+        if (await _shouldQuit()) break;
+        changedSome2 = false;
+        for (int i = 0; i < uris.length; i++) {
+          if (await _shouldQuit()) break;
+          Uri uri = uris[i];
+          if (_fs.data[uri] == null || _fs.data[uri].isNotEmpty) continue;
+          print("About to work on file $i of ${uris.length}");
+          await _deleteContent(uris, i, false, initialComponent,
+              deleteFile: true);
+          if (_fs.data[uri] == null) {
+            changedSome = true;
+            changedSome2 = true;
+          }
+        }
+      }
+
+      int left = 0;
+      for (Uri uri in uris) {
+        if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+        left++;
+      }
+      print("There's now $left files of ${_fs.data.length} files left");
+
+      // Operate on one file at a time.
+      for (Uri uri in _fs.data.keys) {
+        if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+        if (await _shouldQuit()) break;
+
+        if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
+          if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+          if (await _shouldQuit()) break;
+        }
+
+        if (_check) {
+          _check = false;
+          if (!await _crashesOnCompile(initialComponent)) {
+            throw "Check revealed that the current file system doesn't crash.";
+          } else {
+            print("Check OK!");
+          }
+        }
+
+        print("Now working on $uri");
+
+        int prevLength = _fs.data[uri].length;
+
+        await _deleteBlocks(uri, initialComponent);
+        await _deleteEmptyLines(uri, initialComponent);
+
+        if (_settings.oldBlockDelete) {
+          // Try to delete blocks.
+          await _deleteBlocksOld(uri, initialComponent);
+        }
+
+        if (_settings.lineDelete) {
+          // Try to delete lines.
+          await _deleteLines(uri, initialComponent);
+        }
+
+        print("We're now at ${_fs.data[uri].length} bytes for $uri "
+            "(was $prevLength).");
+        if (prevLength != _fs.data[uri].length) changedSome = true;
+        if (_fs.data[uri].isEmpty) continue;
+
+        if (_settings.byteDelete) {
+          // Now try to delete 'arbitrarily' (for any given start offset do an
+          // exponential binary search).
+          int prevLength = _fs.data[uri].length;
+          while (true) {
+            if (await _shouldQuit()) break;
+            await _binarySearchDeleteData(uri, initialComponent);
+
+            if (_fs.data[uri].length == prevLength) {
+              // No progress.
+              break;
+            } else {
+              print("We're now at ${_fs.data[uri].length} bytes");
+              prevLength = _fs.data[uri].length;
+              changedSome = true;
+            }
+          }
+        }
+      }
+      for (Uri uri in _fs.data.keys) {
+        if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+        if (await _shouldQuit()) break;
+
+        if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
+          if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+          if (await _shouldQuit()) break;
+        }
+
+        if (await _attemptInline(uri, initialComponent)) {
+          changedSome = true;
+
+          if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
+            if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+            if (await _shouldQuit()) break;
+          }
+        }
+      }
+    }
+
+    if (await _shouldQuit()) {
+      print("\n\nASKED TO QUIT\n\n");
+    } else {
+      print("\n\nDONE\n\n");
+    }
+
+    Uri jsonOut = _dumpToJson();
+
+    if (!await _shouldQuit()) {
+      // Test converting to incremental compiler yaml test.
+      _outputIncrementalCompilerYamlTest();
+      print("\n\n\n");
+
+      for (Uri uri in uris) {
+        if (_fs.data[uri] == null || _fs.data[uri].isEmpty) continue;
+        print("Uri $uri has this content:");
+
+        try {
+          String utfDecoded = utf8.decode(_fs.data[uri], allowMalformed: true);
+          print(utfDecoded);
+        } catch (e) {
+          print(_fs.data[uri]);
+          print("(which crashes when trying to decode as utf8)");
+        }
+        print("\n\n====================\n\n");
+      }
+
+      print("Wrote json dump to $jsonOut");
+    }
+  }
+
+  Future<bool> _shouldQuit() async {
+    // allow some time for stdin.listen to process data.
+    await new Future.delayed(new Duration(milliseconds: 5));
+    return _quit;
+  }
+
+  Uri _dumpToJson() {
+    JsonEncoder jsonEncoder = new JsonEncoder.withIndent("  ");
+    String json = jsonEncoder.convert(_settings);
+    int i = 0;
+    Uri jsonOut;
+    while (jsonOut == null || new File.fromUri(jsonOut).existsSync()) {
+      jsonOut = Uri.base.resolve("crash_minimizer_result_$i");
+      i++;
+    }
+    new File.fromUri(jsonOut).writeAsStringSync(json);
+    print("Wrote json dump to $jsonOut");
+    return jsonOut;
+  }
+
+  /// Attempts to inline small files in other files.
+  /// Returns true if anything was changed, i.e. if at least one inlining was a
+  /// success.
+  Future<bool> _attemptInline(Uri uri, Component initialComponent) async {
+    // Don't attempt to inline the main uri --- that's our entry!
+    if (uri == _mainUri) return false;
+
+    Uint8List inlineData = _fs.data[uri];
+    bool hasMultipleLines = false;
+    for (int i = 0; i < inlineData.length; i++) {
+      if (inlineData[i] == _$LF) {
+        hasMultipleLines = true;
+        break;
+      }
+    }
+    // TODO(jensj): Maybe inline slightly bigger files too?
+    if (hasMultipleLines) {
+      return false;
+    }
+
+    Uri inlinableUri = uri;
+
+    int compileTry = 0;
+    bool changed = false;
+
+    for (Uri uri in _fs.data.keys) {
+      if (!uri.toString().endsWith(".dart")) continue;
+      if (inlinableUri == uri) continue;
+      final Uint8List originalBytes = _fs.data[uri];
+      if (originalBytes == null || originalBytes.isEmpty) continue;
+      DirectParserASTContentCompilationUnitEnd ast = getAST(originalBytes,
+          includeBody: false,
+          includeComments: false,
+          enableExtensionMethods: true,
+          enableNonNullable: _isUriNnbd(uri));
+      // Find all imports/exports of this file (if any).
+      // If finding any:
+      // * remove all of them, then
+      // * find the end of the last import/export, and
+      // * insert the content of the file there.
+      // * if that *doesn't* work and we've inserted an export,
+      //   try converting that to an import instead.
+      List<_Replacement> replacements = [];
+      for (DirectParserASTContentImportEnd import in ast.getImports()) {
+        Token importUriToken = import.importKeyword.next;
+        Uri importUri = _getUri(importUriToken, uri);
+        if (inlinableUri == importUri) {
+          replacements.add(new _Replacement(
+              import.importKeyword.offset - 1, import.semicolon.offset + 1));
+        }
+      }
+      for (DirectParserASTContentExportEnd export in ast.getExports()) {
+        Token exportUriToken = export.exportKeyword.next;
+        Uri exportUri = _getUri(exportUriToken, uri);
+        if (inlinableUri == exportUri) {
+          replacements.add(new _Replacement(
+              export.exportKeyword.offset - 1, export.semicolon.offset + 1));
+        }
+      }
+      if (replacements.isEmpty) continue;
+
+      // Step 1: Remove all imports/exports *of* this file (the inlinable file).
+      final Uint8List withoutInlineable =
+          _replaceRange(replacements, originalBytes);
+
+      // Step 2: Find the last import/export.
+      int offsetOfLast = 0;
+      ast = getAST(withoutInlineable,
+          includeBody: false,
+          includeComments: false,
+          enableExtensionMethods: true,
+          enableNonNullable: _isUriNnbd(uri));
+      for (DirectParserASTContentImportEnd import in ast.getImports()) {
+        offsetOfLast = max(offsetOfLast, import.semicolon.offset + 1);
+      }
+      for (DirectParserASTContentExportEnd export in ast.getExports()) {
+        offsetOfLast = max(offsetOfLast, export.semicolon.offset + 1);
+      }
+
+      // Step 3: Insert the content of the file there. Note, though,
+      // that any imports/exports in _that_ file should be changed to be valid
+      // in regards to the new placement.
+      final String withoutInlineableString = utf8.decode(withoutInlineable);
+      StringBuffer builder = new StringBuffer();
+      for (int i = 0; i < offsetOfLast; i++) {
+        builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
+      }
+      builder.write("\n");
+      builder.write(utf8.decode(_rewriteImportsExportsToUri(
+          inlineData, uri, inlinableUri, _isUriNnbd(inlinableUri))));
+      builder.write("\n");
+      for (int i = offsetOfLast; i < withoutInlineableString.length; i++) {
+        builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
+      }
+      final Uint8List inlinedWithoutChange = utf8.encode(builder.toString());
+
+      if (!_parsesWithoutError(inlinedWithoutChange, _isUriNnbd(uri))) {
+        print("WARNING: Parser error after stuff at ${StackTrace.current}");
+      }
+
+      // Step 4: Try it out.
+      if (await _shouldQuit()) break;
+      if (_skip) {
+        _skip = false;
+        break;
+      }
+      stdout.write(".");
+      compileTry++;
+      if (compileTry % 50 == 0) {
+        stdout.write("(at $compileTry)\n");
+      }
+      _fs.data[uri] = inlinedWithoutChange;
+      if (await _crashesOnCompile(initialComponent)) {
+        print("Could inline $inlinableUri into $uri.");
+        changed = true;
+        // File was already updated.
+      } else {
+        // Couldn't replace that.
+        // Insert the original again.
+        _fs.data[uri] = originalBytes;
+
+        // If we've inlined an export, try changing that to an import.
+        builder = new StringBuffer();
+        for (int i = 0; i < offsetOfLast; i++) {
+          builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
+        }
+        builder.write("\n");
+        builder.write(utf8.decode(_rewriteImportsExportsToUri(
+            inlineData, uri, inlinableUri, _isUriNnbd(inlinableUri),
+            convertExportToImport: true)));
+        builder.write("\n");
+        for (int i = offsetOfLast; i < withoutInlineableString.length; i++) {
+          builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
+        }
+        Uint8List inlinedWithChange = utf8.encode(builder.toString());
+
+        if (!_parsesWithoutError(inlinedWithChange, _isUriNnbd(uri))) {
+          print("WARNING: Parser error after stuff at ${StackTrace.current}");
+        }
+
+        // Step 4: Try it out.
+        if (await _shouldQuit()) break;
+        if (_skip) {
+          _skip = false;
+          break;
+        }
+        stdout.write(".");
+        compileTry++;
+        if (compileTry % 50 == 0) {
+          stdout.write("(at $compileTry)\n");
+        }
+        _fs.data[uri] = inlinedWithChange;
+        if (await _crashesOnCompile(initialComponent)) {
+          print("Could inline $inlinableUri into $uri "
+              "(by converting export to import).");
+          changed = true;
+          // File was already updated.
+        } else {
+          // Couldn't replace that.
+          // Insert the original again.
+          _fs.data[uri] = originalBytes;
+        }
+      }
+    }
+
+    return changed;
+  }
+
+  Uint8List _rewriteImportsExportsToUri(
+      Uint8List oldData, Uri newUri, Uri oldUri, bool nnbd,
+      {bool convertExportToImport: false}) {
+    DirectParserASTContentCompilationUnitEnd ast = getAST(oldData,
+        includeBody: false,
+        includeComments: false,
+        enableExtensionMethods: true,
+        enableNonNullable: nnbd);
+    List<_Replacement> replacements = [];
+    for (DirectParserASTContentImportEnd import in ast.getImports()) {
+      _rewriteImportsExportsToUriInternal(
+          import.importKeyword.next, oldUri, replacements, newUri);
+    }
+    for (DirectParserASTContentExportEnd export in ast.getExports()) {
+      if (convertExportToImport) {
+        replacements.add(new _Replacement(
+          export.exportKeyword.offset - 1,
+          export.exportKeyword.offset + export.exportKeyword.length,
+          nullOrReplacement: "import",
+        ));
+      }
+      _rewriteImportsExportsToUriInternal(
+          export.exportKeyword.next, oldUri, replacements, newUri);
+    }
+    if (replacements.isNotEmpty) {
+      Uint8List candidate = _replaceRange(replacements, oldData);
+      return candidate;
+    }
+    return oldData;
+  }
+
+  void _outputIncrementalCompilerYamlTest() {
+    int dartFiles = 0;
+    for (MapEntry<Uri, Uint8List> entry in _fs.data.entries) {
+      if (entry.key.pathSegments.last.endsWith(".dart")) {
+        if (entry.value != null) dartFiles++;
+      }
+    }
+
+    print("------ Reproduction as semi-done incremental yaml test file ------");
+
+    // TODO(jensj): don't use full uris.
+    print("""
+        # Copyright (c) 2020, 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.md file.
+        
+        # Reproduce a crash.
+        
+        type: newworld""");
+    if (_settings.widgetTransformation) {
+      print("trackWidgetCreation: true");
+      print("target: DDC # basically needed for widget creation to be run");
+    }
+    print("""
+        worlds:
+          - entry: $_mainUri""");
+    if (_settings.experimentalInvalidation) {
+      print("    experiments: alternative-invalidation-strategy");
+    }
+    print("    sources:");
+    for (MapEntry<Uri, Uint8List> entry in _fs.data.entries) {
+      if (entry.value == null) continue;
+      print("      ${entry.key}: |");
+      String string = utf8.decode(entry.value);
+      List<String> lines = string.split("\n");
+      for (String line in lines) {
+        print("        $line");
+      }
+    }
+    print("    expectedLibraryCount: $dartFiles "
+        "# with parts this is not right");
+    print("");
+
+    for (Uri uri in _settings.invalidate) {
+      print("  - entry: $_mainUri");
+      if (_settings.experimentalInvalidation) {
+        print("    experiments: alternative-invalidation-strategy");
+      }
+      print("    worldType: updated");
+      print("    expectInitializeFromDill: false # or true?");
+      print("    invalidate:");
+      print("      - $uri");
+      print("    expectedLibraryCount: $dartFiles "
+          "# with parts this is not right");
+      print("    expectsRebuildBodiesOnly: true # or false?");
+      print("");
+    }
+
+    print("------------------------------------------------------------------");
+  }
+
+  void _rewriteImportsExportsToUriInternal(
+      Token uriToken, Uri oldUri, List<_Replacement> replacements, Uri newUri) {
+    Uri tokenUri = _getUri(uriToken, oldUri, resolvePackage: false);
+    if (tokenUri.scheme == "package" || tokenUri.scheme == "dart") return;
+    Uri asPackageUri = _getImportUri(tokenUri);
+    if (asPackageUri.scheme == "package") {
+      // Just replace with this package uri.
+      replacements.add(new _Replacement(
+        uriToken.offset - 1,
+        uriToken.offset + uriToken.length,
+        nullOrReplacement: '"${asPackageUri.toString()}"',
+      ));
+    } else {
+      String relative = relativizeUri(newUri, tokenUri, isWindows);
+      // TODO(jensj): Maybe if the relative uri becomes too long or has to many
+      // "../../" etc we should just use the absolute uri instead.
+      replacements.add(new _Replacement(
+        uriToken.offset - 1,
+        uriToken.offset + uriToken.length,
+        nullOrReplacement: '"${relative}"',
+      ));
+    }
+  }
+
+  Uri _getUri(Token uriToken, Uri uri, {bool resolvePackage: true}) {
+    String uriString = uriToken.lexeme;
+    uriString = uriString.substring(1, uriString.length - 1);
+    Uri uriTokenUri = uri.resolve(uriString);
+    if (resolvePackage && uriTokenUri.scheme == "package") {
+      Package package = _latestCrashingIncrementalCompiler
+          .currentPackagesMap[uriTokenUri.pathSegments.first];
+      uriTokenUri = package.packageUriRoot
+          .resolve(uriTokenUri.pathSegments.skip(1).join("/"));
+    }
+    return uriTokenUri;
+  }
+
+  Uri _getImportUri(Uri uri) {
+    return _latestCrashingIncrementalCompiler.userCode
+        .getEntryPointUri(uri, issueProblem: false);
+  }
+
+  Uint8List _sublist(Uint8List data, int start, int end) {
+    Uint8List result = new Uint8List(end - start);
+    result.setRange(0, result.length, data, start);
+    return result;
+  }
+
+  void _binarySearchDeleteData(Uri uri, Component initialComponent) async {
+    Uint8List latestCrashData = _fs.data[uri];
+    int offset = 0;
+    while (offset < latestCrashData.length) {
+      print("Working at offset $offset of ${latestCrashData.length}");
+      BytesBuilder builder = new BytesBuilder();
+      builder.add(_sublist(latestCrashData, 0, offset));
+      builder
+          .add(_sublist(latestCrashData, offset + 1, latestCrashData.length));
+      Uint8List candidate = builder.takeBytes();
+      _fs.data[uri] = candidate;
+      if (!await _crashesOnCompile(initialComponent)) {
+        // Deleting 1 char didn't crash; don't try to delete anymore starting
+        // here.
+        offset++;
+        continue;
+      }
+
+      // Find how long we can go.
+      int crashingAt = 1;
+      int noLongerCrashingAt;
+      while (true) {
+        int deleteChars = 2 * crashingAt;
+        if (offset + deleteChars > latestCrashData.length) {
+          deleteChars = latestCrashData.length - offset;
+        }
+        builder = new BytesBuilder();
+        builder.add(_sublist(latestCrashData, 0, offset));
+        builder.add(_sublist(
+            latestCrashData, offset + deleteChars, latestCrashData.length));
+        candidate = builder.takeBytes();
+        _fs.data[uri] = candidate;
+        if (!await _crashesOnCompile(initialComponent)) {
+          noLongerCrashingAt = deleteChars;
+          break;
+        }
+        crashingAt = deleteChars;
+        if (crashingAt + offset == latestCrashData.length) break;
+      }
+
+      if (noLongerCrashingAt == null) {
+        // We can delete the rest.
+        latestCrashData = candidate;
+        continue;
+      }
+
+      // Binary search between [crashingAt] and [noLongerCrashingAt].
+      while (crashingAt < noLongerCrashingAt) {
+        int mid = noLongerCrashingAt -
+            ((noLongerCrashingAt - crashingAt) >>
+                1); // Get middle, rounding up.
+        builder = new BytesBuilder();
+        builder.add(_sublist(latestCrashData, 0, offset));
+        builder.add(
+            _sublist(latestCrashData, offset + mid, latestCrashData.length));
+        candidate = builder.takeBytes();
+        _fs.data[uri] = candidate;
+        if (await _crashesOnCompile(initialComponent)) {
+          crashingAt = mid;
+        } else {
+          // [noLongerCrashingAt] might actually crash now.
+          noLongerCrashingAt = mid - 1;
+        }
+      }
+
+      // This is basically an assert.
+      builder = new BytesBuilder();
+      builder.add(_sublist(latestCrashData, 0, offset));
+      builder.add(_sublist(
+          latestCrashData, offset + crashingAt, latestCrashData.length));
+      candidate = builder.takeBytes();
+      _fs.data[uri] = candidate;
+      if (!await _crashesOnCompile(initialComponent)) {
+        throw "Error in binary search.";
+      }
+      latestCrashData = candidate;
+    }
+
+    _fs.data[uri] = latestCrashData;
+  }
+
+  void _tryToRemoveUnreferencedFileContent(Component initialComponent,
+      {bool deleteFile: false}) async {
+    // Check if there now are any unused files.
+    if (_latestComponent == null) return;
+    Set<Uri> neededUris = _latestComponent.uriToSource.keys.toSet();
+    Map<Uri, Uint8List> copy = new Map.from(_fs.data);
+    bool removedSome = false;
+    if (await _shouldQuit()) return;
+    for (MapEntry<Uri, Uint8List> entry in _fs.data.entries) {
+      if (entry.value == null || entry.value.isEmpty) continue;
+      if (!entry.key.toString().endsWith(".dart")) continue;
+      if (!neededUris.contains(entry.key) && _fs.data[entry.key].length != 0) {
+        if (deleteFile) {
+          _fs.data[entry.key] = null;
+        } else {
+          _fs.data[entry.key] = new Uint8List(0);
+        }
+        print(" => Can probably also delete ${entry.key}");
+        removedSome = true;
+      }
+    }
+    if (removedSome) {
+      if (await _crashesOnCompile(initialComponent)) {
+        print(" => Yes; Could remove those too!");
+      } else {
+        print(" => No; Couldn't remove those too!");
+        _fs.data.clear();
+        _fs.data.addAll(copy);
+      }
+    }
+  }
+
+  void _deleteContent(
+      List<Uri> uris, int uriIndex, bool limitTo1, Component initialComponent,
+      {bool deleteFile: false}) async {
+    String extraMessageText = "all content of ";
+    if (deleteFile) extraMessageText = "";
+
+    if (!limitTo1) {
+      if (await _shouldQuit()) return;
+      Map<Uri, Uint8List> copy = new Map.from(_fs.data);
+      // Try to remove content of i and the next 9 (10 files in total).
+      for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
+        Uri uri = uris[j];
+        if (deleteFile) {
+          _fs.data[uri] = null;
+        } else {
+          _fs.data[uri] = new Uint8List(0);
+        }
+      }
+      if (!await _crashesOnCompile(initialComponent)) {
+        // Couldn't delete all 10 files. Restore and try the single one.
+        _fs.data.clear();
+        _fs.data.addAll(copy);
+      } else {
+        for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
+          Uri uri = uris[j];
+          print("Can delete ${extraMessageText}file $uri");
+        }
+        await _tryToRemoveUnreferencedFileContent(initialComponent,
+            deleteFile: deleteFile);
+        return;
+      }
+    }
+
+    if (await _shouldQuit()) return;
+    Uri uri = uris[uriIndex];
+    Uint8List data = _fs.data[uri];
+    if (deleteFile) {
+      _fs.data[uri] = null;
+    } else {
+      _fs.data[uri] = new Uint8List(0);
+    }
+    if (!await _crashesOnCompile(initialComponent)) {
+      print(
+          "Can't delete ${extraMessageText}file $uri -- keeping it (for now)");
+      _fs.data[uri] = data;
+
+      // For dart files we can't truncate completely try to "outline" them
+      // instead.
+      if (uri.toString().endsWith(".dart")) {
+        String textualOutlined =
+            textualOutline(data)?.replaceAll(RegExp(r'\n+'), "\n");
+
+        bool outlined = false;
+        if (textualOutlined != null) {
+          Uint8List candidate = utf8.encode(textualOutlined);
+          // Because textual outline doesn't do the right thing for nnbd, only
+          // replace if it's syntactically valid.
+          if (candidate.length != _fs.data[uri].length &&
+              _parsesWithoutError(candidate, _isUriNnbd(uri))) {
+            if (await _shouldQuit()) return;
+            _fs.data[uri] = candidate;
+            if (!await _crashesOnCompile(initialComponent)) {
+              print("Can't outline the file $uri -- keeping it (for now)");
+              _fs.data[uri] = data;
+            } else {
+              outlined = true;
+              print("Can outline the file $uri "
+                  "(now ${_fs.data[uri].length} bytes)");
+            }
+          }
+        }
+        if (!outlined) {
+          // We can probably at least remove all comments then...
+          try {
+            List<String> strings = utf8.decode(_fs.data[uri]).split("\n");
+            List<String> stringsLeft = [];
+            for (String string in strings) {
+              if (!string.trim().startsWith("//")) stringsLeft.add(string);
+            }
+
+            Uint8List candidate = utf8.encode(stringsLeft.join("\n"));
+            if (candidate.length != _fs.data[uri].length) {
+              if (await _shouldQuit()) return;
+              _fs.data[uri] = candidate;
+              if (!await _crashesOnCompile(initialComponent)) {
+                print("Can't remove comments for file $uri -- "
+                    "keeping it (for now)");
+                _fs.data[uri] = data;
+              } else {
+                print("Removed comments for the file $uri");
+              }
+            }
+          } catch (e) {
+            // crash in scanner/parser --- keep original file. This crash might
+            // be what we're looking for!
+          }
+        }
+      }
+    } else {
+      print("Can delete ${extraMessageText}file $uri");
+      await _tryToRemoveUnreferencedFileContent(initialComponent);
+    }
+  }
+
+  void _deleteBlocksOld(Uri uri, Component initialComponent) async {
+    if (uri.toString().endsWith(".json")) {
+      // Try to find annoying
+      //
+      //    },
+      //    {
+      //    }
+      //
+      // part of json and remove it.
+      Uint8List data = _fs.data[uri];
+      String string = utf8.decode(data);
+      List<String> lines = string.split("\n");
+      for (int i = 0; i < lines.length - 2; i++) {
+        if (lines[i].trim() == "}," &&
+            lines[i + 1].trim() == "{" &&
+            lines[i + 2].trim() == "}") {
+          // This is the pattern we wanted to find. Remove it.
+          lines.removeRange(i, i + 2);
+          i--;
+        }
+      }
+      string = lines.join("\n");
+      _fs.data[uri] = utf8.encode(string);
+      if (!await _crashesOnCompile(initialComponent)) {
+        // For some reason that didn't work.
+        _fs.data[uri] = data;
+      }
+    }
+    if (!uri.toString().endsWith(".dart")) return;
+
+    Uint8List data = _fs.data[uri];
+    Uint8List latestCrashData = data;
+
+    List<int> lineStarts = [];
+
+    Token firstToken = parser_suite.scanRawBytes(
+        data,
+        _isUriNnbd(uri) ? _scannerConfiguration : _scannerConfigurationNonNNBD,
+        lineStarts);
+
+    if (firstToken == null) {
+      print("Got null token from scanner for $uri");
+      return;
+    }
+
+    int compileTry = 0;
+    Token token = firstToken;
+    while (token is ErrorToken) {
+      token = token.next;
+    }
+    List<_Replacement> replacements = [];
+    while (token != null && !token.isEof) {
+      bool tryCompile = false;
+      Token skipToToken = token;
+      // Skip very small blocks (e.g. "{}" or "{\n}");
+      if (token.endGroup != null && token.offset + 3 < token.endGroup.offset) {
+        replacements.add(new _Replacement(token.offset, token.endGroup.offset));
+        tryCompile = true;
+        skipToToken = token.endGroup;
+      } else if (token.lexeme == "@") {
+        if (token.next.next.endGroup != null) {
+          int end = token.next.next.endGroup.offset;
+          skipToToken = token.next.next.endGroup;
+          replacements.add(new _Replacement(token.offset - 1, end + 1));
+          tryCompile = true;
+        }
+      } else if (token.lexeme == "assert") {
+        if (token.next.endGroup != null) {
+          int end = token.next.endGroup.offset;
+          skipToToken = token.next.endGroup;
+          if (token.next.endGroup.next.lexeme == ",") {
+            end = token.next.endGroup.next.offset;
+            skipToToken = token.next.endGroup.next;
+          }
+          // +/- 1 to not include the start and the end character.
+          replacements.add(new _Replacement(token.offset - 1, end + 1));
+          tryCompile = true;
+        }
+      } else if ((token.lexeme == "abstract" && token.next.lexeme == "class") ||
+          token.lexeme == "class" ||
+          token.lexeme == "enum" ||
+          token.lexeme == "mixin" ||
+          token.lexeme == "static" ||
+          token.next.lexeme == "get" ||
+          token.next.lexeme == "set" ||
+          token.next.next.lexeme == "(" ||
+          (token.next.lexeme == "<" &&
+              token.next.endGroup != null &&
+              token.next.endGroup.next.next.lexeme == "(")) {
+        // Try to find and remove the entire class/enum/mixin/
+        // static procedure/getter/setter/simple procedure.
+        Token bracket = token;
+        for (int i = 0; i < 20; i++) {
+          // Find "{", but only go a maximum of 20 tokens to do that.
+          bracket = bracket.next;
+          if (bracket.lexeme == "{" && bracket.endGroup != null) {
+            break;
+          } else if ((bracket.lexeme == "(" || bracket.lexeme == "<") &&
+              bracket.endGroup != null) {
+            bracket = bracket.endGroup;
+          }
+        }
+        if (bracket.lexeme == "{" && bracket.endGroup != null) {
+          int end = bracket.endGroup.offset;
+          skipToToken = bracket.endGroup;
+          // +/- 1 to not include the start and the end character.
+          replacements.add(new _Replacement(token.offset - 1, end + 1));
+          tryCompile = true;
+        }
+      }
+
+      if (tryCompile) {
+        if (await _shouldQuit()) break;
+        if (_skip) {
+          _skip = false;
+          break;
+        }
+        stdout.write(".");
+        compileTry++;
+        if (compileTry % 50 == 0) {
+          stdout.write("(at $compileTry)\n");
+        }
+        Uint8List candidate = _replaceRange(replacements, data);
+        _fs.data[uri] = candidate;
+        if (await _crashesOnCompile(initialComponent)) {
+          print("Found block from "
+              "${replacements.last.from} to "
+              "${replacements.last.to} "
+              "that can be removed.");
+          latestCrashData = candidate;
+          token = skipToToken;
+        } else {
+          // Couldn't delete that.
+          replacements.removeLast();
+        }
+      }
+      token = token.next;
+    }
+    _fs.data[uri] = latestCrashData;
+  }
+
+  void _deleteBlocks(final Uri uri, Component initialComponent) async {
+    if (uri.toString().endsWith(".json")) {
+      // Try to find annoying
+      //
+      //    },
+      //    {
+      //    }
+      //
+      // part of json and remove it.
+      Uint8List data = _fs.data[uri];
+      String string = utf8.decode(data);
+      List<String> lines = string.split("\n");
+      for (int i = 0; i < lines.length - 2; i++) {
+        if (lines[i].trim() == "}," &&
+            lines[i + 1].trim() == "{" &&
+            lines[i + 2].trim() == "}") {
+          // This is the pattern we wanted to find. Remove it.
+          lines.removeRange(i, i + 2);
+          i--;
+        }
+      }
+      string = lines.join("\n");
+      Uint8List candidate = utf8.encode(string);
+      if (candidate.length != data.length) {
+        _fs.data[uri] = candidate;
+        if (!await _crashesOnCompile(initialComponent)) {
+          // For some reason that didn't work.
+          _fs.data[uri] = data;
+        }
+      }
+
+      // Try to load json and remove blocks.
+      try {
+        Map json = jsonDecode(utf8.decode(data));
+        Map jsonModified = new Map.from(json);
+        List packages = json["packages"];
+        List packagesModified = new List.from(packages);
+        jsonModified["packages"] = packagesModified;
+        int i = 0;
+        print("Note there's ${packagesModified.length} packages in .json");
+        JsonEncoder jsonEncoder = new JsonEncoder.withIndent("  ");
+        while (i < packagesModified.length) {
+          var oldEntry = packagesModified.removeAt(i);
+          String jsonString = jsonEncoder.convert(jsonModified);
+          candidate = utf8.encode(jsonString);
+          Uint8List previous = _fs.data[uri];
+          _fs.data[uri] = candidate;
+          if (!await _crashesOnCompile(initialComponent)) {
+            // Couldn't remove that part.
+            _fs.data[uri] = previous;
+            packagesModified.insert(i, oldEntry);
+            i++;
+          } else {
+            print("Removed package from .json "
+                "(${packagesModified.length} left).");
+          }
+        }
+      } catch (e) {
+        // Couldn't decode it, so don't try to do anything.
+      }
+      return;
+    }
+    if (!uri.toString().endsWith(".dart")) return;
+
+    Uint8List data = _fs.data[uri];
+    DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+        includeBody: true,
+        includeComments: false,
+        enableExtensionMethods: true,
+        enableNonNullable: _isUriNnbd(uri));
+
+    _CompilationHelperClass helper = new _CompilationHelperClass(data);
+
+    // Try to remove top level things one at a time.
+    for (DirectParserASTContent child in ast.children) {
+      bool shouldCompile = false;
+      String what = "";
+      if (child.isClass()) {
+        DirectParserASTContentClassDeclarationEnd cls = child.asClass();
+        helper.replacements.add(new _Replacement(
+            cls.beginToken.offset - 1, cls.endToken.offset + 1));
+        shouldCompile = true;
+        what = "class";
+      } else if (child.isMixinDeclaration()) {
+        DirectParserASTContentMixinDeclarationEnd decl =
+            child.asMixinDeclaration();
+        helper.replacements.add(new _Replacement(
+            decl.mixinKeyword.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "mixin";
+      } else if (child.isNamedMixinDeclaration()) {
+        DirectParserASTContentNamedMixinApplicationEnd decl =
+            child.asNamedMixinDeclaration();
+        helper.replacements.add(
+            new _Replacement(decl.begin.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "named mixin";
+      } else if (child.isExtension()) {
+        DirectParserASTContentExtensionDeclarationEnd decl =
+            child.asExtension();
+        helper.replacements.add(new _Replacement(
+            decl.extensionKeyword.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "extension";
+      } else if (child.isTopLevelFields()) {
+        DirectParserASTContentTopLevelFieldsEnd decl = child.asTopLevelFields();
+        helper.replacements.add(new _Replacement(
+            decl.beginToken.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "toplevel fields";
+      } else if (child.isTopLevelMethod()) {
+        DirectParserASTContentTopLevelMethodEnd decl = child.asTopLevelMethod();
+        helper.replacements.add(new _Replacement(
+            decl.beginToken.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "toplevel method";
+      } else if (child.isEnum()) {
+        DirectParserASTContentEnumEnd decl = child.asEnum();
+        helper.replacements.add(new _Replacement(
+            decl.enumKeyword.offset - 1, decl.leftBrace.endGroup.offset + 1));
+        shouldCompile = true;
+        what = "enum";
+      } else if (child.isTypedef()) {
+        DirectParserASTContentFunctionTypeAliasEnd decl = child.asTypedef();
+        helper.replacements.add(new _Replacement(
+            decl.typedefKeyword.offset - 1, decl.endToken.offset + 1));
+        shouldCompile = true;
+        what = "typedef";
+      } else if (child.isMetadata()) {
+        DirectParserASTContentMetadataStarEnd decl = child.asMetadata();
+        List<DirectParserASTContentMetadataEnd> metadata =
+            decl.getMetadataEntries();
+        if (metadata.isNotEmpty) {
+          helper.replacements.add(new _Replacement(
+              metadata.first.beginToken.offset - 1,
+              metadata.last.endToken.offset));
+          shouldCompile = true;
+        }
+        what = "metadata";
+      } else if (child.isImport()) {
+        DirectParserASTContentImportEnd decl = child.asImport();
+        helper.replacements.add(new _Replacement(
+            decl.importKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "import";
+      } else if (child.isExport()) {
+        DirectParserASTContentExportEnd decl = child.asExport();
+        helper.replacements.add(new _Replacement(
+            decl.exportKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "export";
+      } else if (child.isLibraryName()) {
+        DirectParserASTContentLibraryNameEnd decl = child.asLibraryName();
+        helper.replacements.add(new _Replacement(
+            decl.libraryKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "library name";
+      } else if (child.isPart()) {
+        DirectParserASTContentPartEnd decl = child.asPart();
+        helper.replacements.add(new _Replacement(
+            decl.partKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "part";
+      } else if (child.isPartOf()) {
+        DirectParserASTContentPartOfEnd decl = child.asPartOf();
+        helper.replacements.add(new _Replacement(
+            decl.partKeyword.offset - 1, decl.semicolon.offset + 1));
+        shouldCompile = true;
+        what = "part of";
+      } else if (child.isScript()) {
+        var decl = child.asScript();
+        helper.replacements.add(new _Replacement(
+            decl.token.offset - 1, decl.token.offset + decl.token.length));
+        shouldCompile = true;
+        what = "script";
+      }
+
+      if (shouldCompile) {
+        bool success =
+            await _tryReplaceAndCompile(helper, uri, initialComponent, what);
+        if (helper.shouldQuit) return;
+        if (!success) {
+          if (child.isClass()) {
+            // Also try to remove all content of the class.
+            DirectParserASTContentClassDeclarationEnd decl = child.asClass();
+            DirectParserASTContentClassOrMixinBodyEnd body =
+                decl.getClassOrMixinBody();
+            if (body.beginToken.offset + 2 < body.endToken.offset) {
+              helper.replacements.add(new _Replacement(
+                  body.beginToken.offset, body.endToken.offset));
+              what = "class body";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+
+            if (!success) {
+              // Also try to remove members one at a time.
+              for (DirectParserASTContent child in body.children) {
+                shouldCompile = false;
+                if (child is DirectParserASTContentMemberEnd) {
+                  if (child.isClassConstructor()) {
+                    DirectParserASTContentClassConstructorEnd memberDecl =
+                        child.getClassConstructor();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "class constructor";
+                    shouldCompile = true;
+                  } else if (child.isClassFields()) {
+                    DirectParserASTContentClassFieldsEnd memberDecl =
+                        child.getClassFields();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "class fields";
+                    shouldCompile = true;
+                  } else if (child.isClassMethod()) {
+                    DirectParserASTContentClassMethodEnd memberDecl =
+                        child.getClassMethod();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "class method";
+                    shouldCompile = true;
+                  } else if (child.isClassFactoryMethod()) {
+                    DirectParserASTContentClassFactoryMethodEnd memberDecl =
+                        child.getClassFactoryMethod();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "class factory method";
+                    shouldCompile = true;
+                  } else {
+                    // throw "$child --- ${child.children}";
+                    continue;
+                  }
+                } else if (child.isMetadata()) {
+                  DirectParserASTContentMetadataStarEnd decl =
+                      child.asMetadata();
+                  List<DirectParserASTContentMetadataEnd> metadata =
+                      decl.getMetadataEntries();
+                  if (metadata.isNotEmpty) {
+                    helper.replacements.add(new _Replacement(
+                        metadata.first.beginToken.offset - 1,
+                        metadata.last.endToken.offset));
+                    shouldCompile = true;
+                  }
+                  what = "metadata";
+                }
+                if (shouldCompile) {
+                  success = await _tryReplaceAndCompile(
+                      helper, uri, initialComponent, what);
+                  if (helper.shouldQuit) return;
+                  if (!success) {
+                    DirectParserASTContentBlockFunctionBodyEnd decl;
+                    if (child is DirectParserASTContentMemberEnd) {
+                      if (child.isClassMethod()) {
+                        decl = child.getClassMethod().getBlockFunctionBody();
+                      } else if (child.isClassConstructor()) {
+                        decl =
+                            child.getClassConstructor().getBlockFunctionBody();
+                      }
+                    }
+                    if (decl != null &&
+                        decl.beginToken.offset + 2 < decl.endToken.offset) {
+                      helper.replacements.add(new _Replacement(
+                          decl.beginToken.offset, decl.endToken.offset));
+                      what = "class member content";
+                      await _tryReplaceAndCompile(
+                          helper, uri, initialComponent, what);
+                      if (helper.shouldQuit) return;
+                    }
+                  }
+                }
+              }
+            }
+
+            // Try to remove "extends", "implements" etc.
+            if (decl.getClassExtends().extendsKeyword != null) {
+              helper.replacements.add(new _Replacement(
+                  decl.getClassExtends().extendsKeyword.offset - 1,
+                  body.beginToken.offset));
+              what = "class extends";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+            if (decl.getClassImplements().implementsKeyword != null) {
+              helper.replacements.add(new _Replacement(
+                  decl.getClassImplements().implementsKeyword.offset - 1,
+                  body.beginToken.offset));
+              what = "class implements";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+            if (decl.getClassWithClause() != null) {
+              helper.replacements.add(new _Replacement(
+                  decl.getClassWithClause().withKeyword.offset - 1,
+                  body.beginToken.offset));
+              what = "class with clause";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+          } else if (child.isMixinDeclaration()) {
+            // Also try to remove all content of the mixin.
+            DirectParserASTContentMixinDeclarationEnd decl =
+                child.asMixinDeclaration();
+            DirectParserASTContentClassOrMixinBodyEnd body =
+                decl.getClassOrMixinBody();
+            if (body.beginToken.offset + 2 < body.endToken.offset) {
+              helper.replacements.add(new _Replacement(
+                  body.beginToken.offset, body.endToken.offset));
+              what = "mixin body";
+              success = await _tryReplaceAndCompile(
+                  helper, uri, initialComponent, what);
+              if (helper.shouldQuit) return;
+            }
+
+            if (!success) {
+              // Also try to remove members one at a time.
+              for (DirectParserASTContent child in body.children) {
+                shouldCompile = false;
+                if (child is DirectParserASTContentMemberEnd) {
+                  if (child.isMixinConstructor()) {
+                    DirectParserASTContentMixinConstructorEnd memberDecl =
+                        child.getMixinConstructor();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "mixin constructor";
+                    shouldCompile = true;
+                  } else if (child.isMixinFields()) {
+                    DirectParserASTContentMixinFieldsEnd memberDecl =
+                        child.getMixinFields();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "mixin fields";
+                    shouldCompile = true;
+                  } else if (child.isMixinMethod()) {
+                    DirectParserASTContentMixinMethodEnd memberDecl =
+                        child.getMixinMethod();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "mixin method";
+                    shouldCompile = true;
+                  } else if (child.isMixinFactoryMethod()) {
+                    DirectParserASTContentMixinFactoryMethodEnd memberDecl =
+                        child.getMixinFactoryMethod();
+                    helper.replacements.add(new _Replacement(
+                        memberDecl.beginToken.offset - 1,
+                        memberDecl.endToken.offset + 1));
+                    what = "mixin factory method";
+                    shouldCompile = true;
+                  } else {
+                    // throw "$child --- ${child.children}";
+                    continue;
+                  }
+                } else if (child.isMetadata()) {
+                  DirectParserASTContentMetadataStarEnd decl =
+                      child.asMetadata();
+                  List<DirectParserASTContentMetadataEnd> metadata =
+                      decl.getMetadataEntries();
+                  if (metadata.isNotEmpty) {
+                    helper.replacements.add(new _Replacement(
+                        metadata.first.beginToken.offset - 1,
+                        metadata.last.endToken.offset));
+                    shouldCompile = true;
+                  }
+                  what = "metadata";
+                }
+                if (shouldCompile) {
+                  success = await _tryReplaceAndCompile(
+                      helper, uri, initialComponent, what);
+                  if (helper.shouldQuit) return;
+                  if (!success) {
+                    DirectParserASTContentBlockFunctionBodyEnd decl;
+                    if (child is DirectParserASTContentMemberEnd) {
+                      if (child.isClassMethod()) {
+                        decl = child.getClassMethod().getBlockFunctionBody();
+                      } else if (child.isClassConstructor()) {
+                        decl =
+                            child.getClassConstructor().getBlockFunctionBody();
+                      }
+                    }
+                    if (decl != null &&
+                        decl.beginToken.offset + 2 < decl.endToken.offset) {
+                      helper.replacements.add(new _Replacement(
+                          decl.beginToken.offset, decl.endToken.offset));
+                      what = "class member content";
+                      await _tryReplaceAndCompile(
+                          helper, uri, initialComponent, what);
+                      if (helper.shouldQuit) return;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  Future<bool> _tryReplaceAndCompile(_CompilationHelperClass data, Uri uri,
+      Component initialComponent, String what) async {
+    if (await _shouldQuit()) {
+      data.shouldQuit = true;
+      return false;
+    }
+    stdout.write(".");
+    data.compileTry++;
+    if (data.compileTry % 50 == 0) {
+      stdout.write("(at ${data.compileTry})\n");
+    }
+    Uint8List candidate = _replaceRange(data.replacements, data.originalData);
+
+    if (!_parsesWithoutError(candidate, _isUriNnbd(uri))) {
+      print("WARNING: Parser error after stuff at ${StackTrace.current}");
+      _parsesWithoutError(candidate, _isUriNnbd(uri));
+      _parsesWithoutError(data.originalData, _isUriNnbd(uri));
+    }
+
+    _fs.data[uri] = candidate;
+    if (await _crashesOnCompile(initialComponent)) {
+      print("Found $what from "
+          "${data.replacements.last.from} to "
+          "${data.replacements.last.to} "
+          "that can be removed.");
+      data.latestCrashData = candidate;
+      return true;
+    } else {
+      // Couldn't delete that.
+      data.replacements.removeLast();
+      _fs.data[uri] = data.latestCrashData;
+      return false;
+    }
+  }
+
+  void _deleteEmptyLines(Uri uri, Component initialComponent) async {
+    Uint8List data = _fs.data[uri];
+    List<Uint8List> lines = [];
+    int start = 0;
+    for (int i = 0; i < data.length; i++) {
+      if (data[i] == _$LF) {
+        if (i - start > 0) {
+          lines.add(_sublist(data, start, i));
+        }
+        start = i + 1;
+      }
+    }
+    if (data.length - start > 0) {
+      lines.add(_sublist(data, start, data.length));
+    }
+
+    final BytesBuilder builder = new BytesBuilder();
+    for (int j = 0; j < lines.length; j++) {
+      if (builder.isNotEmpty) {
+        builder.addByte(_$LF);
+      }
+      builder.add(lines[j]);
+    }
+    Uint8List candidate = builder.takeBytes();
+    if (candidate.length == data.length) return;
+
+    if (!_parsesWithoutError(candidate, _isUriNnbd(uri))) {
+      print("WARNING: Parser error after stuff at ${StackTrace.current}");
+    }
+
+    if (await _shouldQuit()) return;
+    _fs.data[uri] = candidate;
+    if (!await _crashesOnCompile(initialComponent)) {
+      // For some reason the empty lines are important.
+      _fs.data[uri] = data;
+    } else {
+      print("\nDeleted empty lines.");
+    }
+  }
+
+  void _deleteLines(Uri uri, Component initialComponent) async {
+    // Try to delete "lines".
+    Uint8List data = _fs.data[uri];
+    List<Uint8List> lines = [];
+    int start = 0;
+    for (int i = 0; i < data.length; i++) {
+      if (data[i] == _$LF) {
+        lines.add(_sublist(data, start, i));
+        start = i + 1;
+      }
+    }
+    lines.add(_sublist(data, start, data.length));
+    List<bool> include = new List.filled(lines.length, true);
+    Uint8List latestCrashData = data;
+    int length = 1;
+    int i = 0;
+    while (i < lines.length) {
+      if (await _shouldQuit()) break;
+      if (_skip) {
+        _skip = false;
+        break;
+      }
+      stdout.write(".");
+      if (i % 50 == 0) {
+        stdout.write("(at $i of ${lines.length})\n");
+      }
+      if (i + length > lines.length) {
+        length = lines.length - i;
+      }
+      for (int j = i; j < i + length; j++) {
+        include[j] = false;
+      }
+      final BytesBuilder builder = new BytesBuilder();
+      for (int j = 0; j < lines.length; j++) {
+        if (include[j]) {
+          if (builder.isNotEmpty) {
+            builder.addByte(_$LF);
+          }
+          builder.add(lines[j]);
+        }
+      }
+      Uint8List candidate = builder.takeBytes();
+      _fs.data[uri] = candidate;
+      if (!await _crashesOnCompile(initialComponent)) {
+        // Didn't crash => Can't remove line i-j.
+        for (int j = i; j < i + length; j++) {
+          include[j] = true;
+        }
+        if (length > 2) {
+          // Retry with length 2 at same i.
+          // The idea here is that for instance formatted json might have lines
+          // looking like
+          // {
+          // }
+          // where deleting just one line makes it invalid.
+          length = 2;
+        } else if (length > 1) {
+          // Retry with length 1 at same i.
+          length = 1;
+        } else {
+          // Couldn't with length 1 either.
+          i++;
+        }
+      } else {
+        print("\nCan delete line $i (inclusive) - ${i + length} (exclusive) "
+            "(of ${lines.length})");
+        latestCrashData = candidate;
+        i += length;
+        length *= 2;
+      }
+    }
+    _fs.data[uri] = latestCrashData;
+  }
+
+  Future<bool> _tryRemoveIfNotKnownByCompiler(Uri uri, initialComponent) async {
+    if (_fs.data[uri] == null || _fs.data[uri].isEmpty) return false;
+    if (!uri.toString().endsWith(".dart")) return false;
+
+    if (_knownByCompiler(uri)) return false;
+
+    // Compiler might not know this. Can we delete it?
+    await _deleteContent([uri], 0, true, initialComponent);
+    if (_fs.data[uri] == null || _fs.data[uri].isEmpty) {
+      await _deleteContent([uri], 0, true, initialComponent, deleteFile: true);
+      return true;
+    }
+
+    return false;
+  }
+
+  bool _knownByCompiler(Uri uri) {
+    LibraryBuilder libraryBuilder = _latestCrashingIncrementalCompiler
+        .userCode.loader.builders[_getImportUri(uri)];
+    if (libraryBuilder != null) {
+      return true;
+    }
+    // TODO(jensj): Parts.
+    return false;
+  }
+
+  bool _isUriNnbd(Uri uri) {
+    LibraryBuilder libraryBuilder = _latestCrashingIncrementalCompiler
+        .userCode.loader.builders[_getImportUri(uri)];
+    if (libraryBuilder != null) {
+      return libraryBuilder.isNonNullableByDefault;
+    }
+    print("Couldn't lookup $uri");
+    for (LibraryBuilder libraryBuilder
+        in _latestCrashingIncrementalCompiler.userCode.loader.builders.values) {
+      if (libraryBuilder.importUri == uri) {
+        print("Found $uri as ${libraryBuilder.importUri} "
+            "(!= ${_getImportUri(uri)})");
+        return libraryBuilder.isNonNullableByDefault;
+      }
+    }
+    // This might be parts?
+    throw "Couldn't lookup $uri at all!";
+  }
+
+  Future<bool> _crashesOnCompile(Component initialComponent) async {
+    IncrementalCompiler incrementalCompiler;
+    if (_settings.noPlatform) {
+      incrementalCompiler = new IncrementalCompiler(_setupCompilerContext());
+    } else {
+      incrementalCompiler = new IncrementalCompiler.fromComponent(
+          _setupCompilerContext(), initialComponent);
+    }
+    incrementalCompiler.invalidate(_mainUri);
+    try {
+      _latestComponent = await incrementalCompiler.computeDelta();
+      if (_settings.serialize) {
+        ByteSink sink = new ByteSink();
+        BinaryPrinter printer = new BinaryPrinter(sink);
+        printer.writeComponentFile(_latestComponent);
+        sink.builder.takeBytes();
+      }
+      for (Uri uri in _settings.invalidate) {
+        incrementalCompiler.invalidate(uri);
+        Component delta = await incrementalCompiler.computeDelta();
+        if (_settings.serialize) {
+          ByteSink sink = new ByteSink();
+          BinaryPrinter printer = new BinaryPrinter(sink);
+          printer.writeComponentFile(delta);
+          sink.builder.takeBytes();
+        }
+      }
+      _latestComponent = null; // if it didn't crash this isn't relevant.
+      return false;
+    } catch (e, st) {
+      // Find line with #0 in it.
+      String eWithSt = "$e\n\n$st";
+      List<String> lines = eWithSt.split("\n");
+      String foundLine = "";
+      int lookFor = 0;
+      for (String line in lines) {
+        if (line.startsWith("#$lookFor")) {
+          foundLine += line;
+          lookFor++;
+          if (lookFor >= _settings.stackTraceMatches) {
+            break;
+          } else {
+            foundLine += "\n";
+          }
+        }
+      }
+      if (foundLine == null) throw "Unexpected crash without stacktrace: $e";
+      if (_expectedCrashLine == null) {
+        print("Got '$foundLine'");
+        _expectedCrashLine = foundLine;
+        _latestCrashingIncrementalCompiler = incrementalCompiler;
+        return true;
+      } else if (foundLine == _expectedCrashLine) {
+        _latestCrashingIncrementalCompiler = incrementalCompiler;
+        return true;
+      } else {
+        if (_settings.autoUncoverAllCrashes &&
+            !_settings.allAutoRedirects.contains(foundLine)) {
+          print("Crashed, but another place: $foundLine");
+          print(" ==> Adding to auto redirects!");
+          // Add the current one too, so we don't rediscover that one once we
+          // try minimizing the new ones.
+          _settings.allAutoRedirects.add(_expectedCrashLine);
+          _settings.allAutoRedirects.add(foundLine);
+          _settings.fileSystems.add(_fs.toJson());
+        } else if (_settings.askAboutRedirectCrashTarget &&
+            !_settings.askedAboutRedirect.contains(foundLine)) {
+          print("Crashed, but another place: $foundLine");
+          while (true) {
+            // Add the current one too, so we don't rediscover that again
+            // and asks about going back to it.
+            _settings.askedAboutRedirect.add(_expectedCrashLine);
+            _settings.askedAboutRedirect.add(foundLine);
+            print(eWithSt);
+            print("Should we redirect to searching for that? (y/n)");
+            String answer = stdin.readLineSync();
+            if (answer == "yes" || answer == "y") {
+              _expectedCrashLine = foundLine;
+              _latestCrashingIncrementalCompiler = incrementalCompiler;
+              return true;
+            } else if (answer == "no" || answer == "n") {
+              break;
+            } else {
+              print("Didn't get that answer. "
+                  "Please answer 'yes, 'y', 'no' or 'n'");
+            }
+          }
+        }
+        return false;
+      }
+    }
+  }
+
+  Future<Component> _getInitialComponent() async {
+    IncrementalCompiler incrementalCompiler =
+        new IncrementalCompiler(_setupCompilerContext());
+    Component originalComponent = await incrementalCompiler.computeDelta();
+    return originalComponent;
+  }
+
+  CompilerContext _setupCompilerContext() {
+    CompilerOptions options = getOptions();
+
+    if (_settings.experimentalInvalidation) {
+      options.explicitExperimentalFlags ??= {};
+      options.explicitExperimentalFlags[
+          ExperimentalFlag.alternativeInvalidationStrategy] = true;
+    }
+
+    TargetFlags targetFlags = new TargetFlags(
+        enableNullSafety: false,
+        trackWidgetCreation: _settings.widgetTransformation);
+    Target target;
+    switch (_settings.targetString) {
+      case "VM":
+        target = new VmTarget(targetFlags);
+        break;
+      case "flutter":
+        target = new FlutterTarget(targetFlags);
+        break;
+      case "ddc":
+        target = new DevCompilerTarget(targetFlags);
+        break;
+      default:
+        throw "Unknown target '$target'";
+    }
+    options.target = target;
+    options.fileSystem = _fs;
+    options.sdkRoot = null;
+    options.sdkSummary = _settings.platformUri;
+    options.omitPlatform = false;
+    options.onDiagnostic = (DiagnosticMessage message) {
+      // don't care.
+    };
+    if (_settings.noPlatform) {
+      options.librariesSpecificationUri = null;
+    }
+
+    CompilerContext compilerContext = new CompilerContext(
+        new ProcessedOptions(options: options, inputs: [_mainUri]));
+    return compilerContext;
+  }
+
+  String _getFileAsStringContent(Uint8List rawBytes, bool nnbd) {
+    List<int> lineStarts = [];
+
+    Token firstToken = parser_suite.scanRawBytes(
+        rawBytes,
+        nnbd ? _scannerConfiguration : _scannerConfigurationNonNNBD,
+        lineStarts);
+
+    if (firstToken == null) {
+      throw "Got null token from scanner";
+    }
+
+    ParserTestListener parserTestListener = new ParserTestListener(false);
+    Parser parser = new Parser(parserTestListener);
+    parser.parseUnit(firstToken);
+    String parsedString =
+        parser_suite.tokenStreamToString(firstToken, lineStarts).toString();
+    return parsedString;
+  }
+
+  bool _parsesWithoutError(Uint8List rawBytes, bool nnbd) {
+    Token firstToken = parser_suite.scanRawBytes(rawBytes,
+        nnbd ? _scannerConfiguration : _scannerConfigurationNonNNBD, null);
+
+    if (firstToken == null) {
+      return false;
+    }
+
+    ParserErrorListener parserErrorListener = new ParserErrorListener();
+    Parser parser = new Parser(parserErrorListener);
+    parser.parseUnit(firstToken);
+    return !parserErrorListener.gotError;
+  }
+
+  ScannerConfiguration _scannerConfiguration = new ScannerConfiguration(
+      enableTripleShift: true,
+      enableExtensionMethods: true,
+      enableNonNullable: true);
+
+  ScannerConfiguration _scannerConfigurationNonNNBD = new ScannerConfiguration(
+      enableTripleShift: true,
+      enableExtensionMethods: true,
+      enableNonNullable: false);
+
+  List<int> _dataCache;
+  String _dataCacheString;
+  Uint8List _replaceRange(
+      List<_Replacement> unsortedReplacements, Uint8List rawData) {
+    // The offsets are character offsets, not byte offsets, so for non-ascii
+    // they are not the same so we need to work on the string, not the bytes.
+    if (identical(rawData, _dataCache)) {
+      // cache up to date.
+    } else {
+      _dataCache = rawData;
+      _dataCacheString = utf8.decode(rawData);
+    }
+
+    // The below assumes these are sorted.
+    List<_Replacement> sortedReplacements =
+        new List<_Replacement>.from(unsortedReplacements)..sort();
+    final StringBuffer builder = new StringBuffer();
+    int prev = 0;
+    for (int i = 0; i < sortedReplacements.length; i++) {
+      _Replacement replacement = sortedReplacements[i];
+      for (int j = prev; j <= replacement.from; j++) {
+        builder.writeCharCode(_dataCacheString.codeUnitAt(j));
+      }
+      if (replacement.nullOrReplacement != null) {
+        builder.write(replacement.nullOrReplacement);
+      }
+      prev = replacement.to;
+    }
+    for (int j = prev; j < _dataCacheString.length; j++) {
+      builder.writeCharCode(_dataCacheString.codeUnitAt(j));
+    }
+
+    Uint8List candidate = utf8.encode(builder.toString());
+    return candidate;
+  }
+}
+
+class ParserErrorListener extends Listener {
+  bool gotError = false;
+  List<Message> messages = [];
+  void handleRecoverableError(
+      Message message, Token startToken, Token endToken) {
+    gotError = true;
+    messages.add(message);
+  }
+}
+
+class _CompilationHelperClass {
+  int compileTry = 0;
+  bool shouldQuit = false;
+  List<_Replacement> replacements = [];
+  Uint8List latestCrashData;
+  final Uint8List originalData;
+
+  _CompilationHelperClass(this.originalData) : latestCrashData = originalData;
+}
+
+class _Replacement implements Comparable<_Replacement> {
+  final int from;
+  final int to;
+  final String nullOrReplacement;
+
+  _Replacement(this.from, this.to, {this.nullOrReplacement});
+
+  @override
+  int compareTo(_Replacement other) {
+    return from - other.from;
+  }
+}
+
+class _FakeFileSystem extends FileSystem {
+  bool _redirectAndRecord = true;
+  bool _initialized = false;
+  final Map<Uri, Uint8List> data = {};
+
+  @override
+  FileSystemEntity entityForUri(Uri uri) {
+    return new _FakeFileSystemEntity(this, uri);
+  }
+
+  initializeFromJson(Map<String, dynamic> json) {
+    _initialized = true;
+    _redirectAndRecord = json['_redirectAndRecord'];
+    data.clear();
+    List tmp = json['data'];
+    for (int i = 0; i < tmp.length; i += 2) {
+      Uri key = tmp[i] == null ? null : Uri.parse(tmp[i]);
+      if (tmp[i + 1] == null) {
+        data[key] = null;
+      } else if (tmp[i + 1] is String) {
+        data[key] = utf8.encode(tmp[i + 1]);
+      } else {
+        data[key] = Uint8List.fromList(new List<int>.from(tmp[i + 1]));
+      }
+    }
+  }
+
+  Map<String, dynamic> toJson() {
+    List tmp = [];
+    for (var entry in data.entries) {
+      if (entry.value == null) continue;
+      tmp.add(entry.key == null ? null : entry.key.toString());
+      dynamic out = entry.value;
+      if (entry.value != null && entry.value.isNotEmpty) {
+        try {
+          String string = utf8.decode(entry.value);
+          out = string;
+        } catch (e) {
+          // not a string...
+        }
+      }
+      tmp.add(out);
+    }
+    return {
+      '_redirectAndRecord': _redirectAndRecord,
+      'data': tmp,
+    };
+  }
+}
+
+class _FakeFileSystemEntity extends FileSystemEntity {
+  final _FakeFileSystem fs;
+  final Uri uri;
+  _FakeFileSystemEntity(this.fs, this.uri);
+
+  void _ensureCachedIfOk() {
+    if (fs.data.containsKey(uri)) return;
+    if (fs._initialized) return;
+    if (!fs._redirectAndRecord) {
+      throw "Asked for file in non-recording mode that wasn't known";
+    }
+    File f = new File.fromUri(uri);
+    if (!f.existsSync()) {
+      fs.data[uri] = null;
+      return;
+    }
+    fs.data[uri] = f.readAsBytesSync();
+  }
+
+  @override
+  Future<bool> exists() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) return Future.value(false);
+    return Future.value(true);
+  }
+
+  @override
+  Future<List<int>> readAsBytes() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
+    return Future.value(data);
+  }
+
+  @override
+  Future<String> readAsString() {
+    _ensureCachedIfOk();
+    Uint8List data = fs.data[uri];
+    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
+    return Future.value(utf8.decode(data));
+  }
+}
+
+class _DoesntCrashOnInput {
+  _DoesntCrashOnInput();
+}
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 64099f8..44c9145 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -838,13 +838,11 @@
       EvaluationMode evaluationMode) {
     constantEvaluator = new ConstantEvaluator(
         backend, environmentDefines, typeEnvironment, this,
-        desugarSets: desugarSets,
         enableTripleShift: enableTripleShift,
         errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
         evaluationMode: evaluationMode);
     constantEvaluatorWithEmptyEnvironment = new ConstantEvaluator(
         backend, {}, typeEnvironment, this,
-        desugarSets: desugarSets,
         enableTripleShift: enableTripleShift,
         errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
         evaluationMode: evaluationMode);
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index ef0b0df..49cac17 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -349,6 +349,7 @@
 indents
 initializer2
 inlinable
+inlineable
 instance2
 insufficient
 intdiv
@@ -451,6 +452,7 @@
 micro
 minimize
 minimizer
+minimizing
 mintty
 minutes
 mismatched
@@ -559,6 +561,7 @@
 recompiles
 redir
 redirections
+rediscover
 reducer
 referring
 reflectee
@@ -583,6 +586,7 @@
 retainingpath
 retains
 rev
+revealed
 risky
 rk
 row
@@ -702,6 +706,7 @@
 unawaited
 unbreak
 unconverted
+uncover
 uncovers
 underline
 unpacked
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart b/pkg/front_end/testcases/general/constants/from_lib/main.dart
new file mode 100644
index 0000000..b301857
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, 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 'main_lib.dart' as a;
+
+const map = <int, String>{
+  ...a.map,
+};
+
+const set = <int>{
+  ...a.set,
+  ...a.list,
+};
+
+const list = <int>[
+  ...a.list,
+  ...a.set,
+];
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.outline.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.outline.expect
new file mode 100644
index 0000000..280c0fe
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.outline.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart" as a;
+
+static const field core::Map<core::int*, core::String*>* map = mai::map;
+static const field core::Set<core::int*>* set = mai::set + mai::list;
+static const field core::List<core::int*>* list = mai::list + mai::set;
+static method main() → dynamic
+  ;
+
+library;
+import self as mai;
+import "dart:core" as core;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C9;
+static const field core::List<core::int*>* list = #C11;
+
+constants  {
+  #C1 = 1
+  #C2 = "a"
+  #C3 = <dynamic>[#C1, #C2]
+  #C4 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C3}
+  #C5 = 2
+  #C6 = null
+  #C7 = <dynamic>[#C5, #C6]
+  #C8 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C7}
+  #C9 = col::_UnmodifiableSet<core::int*> {_map:#C8}
+  #C10 = 3
+  #C11 = <core::int*>[#C10]
+}
+
+Extra constant evaluation status:
+Evaluated: MapConcatenation @ org-dartlang-testcase:///main.dart:7:7 -> InstanceConstant(const _ImmutableMap<int*, String*>{_ImmutableMap._kvPairs: const <dynamic>[1, "a"]})
+Evaluated: SetConcatenation @ org-dartlang-testcase:///main.dart:11:18 -> InstanceConstant(const _UnmodifiableSet<int*>{_UnmodifiableSet._map: const _ImmutableMap<int*, Null>{_ImmutableMap._kvPairs: const <dynamic>[2, null, 3, null]}})
+Evaluated: ListConcatenation @ org-dartlang-testcase:///main.dart:16:19 -> ListConstant(const <int*>[3, 2])
+Extra constant evaluation: evaluated: 3, effectively constant: 3
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.expect
new file mode 100644
index 0000000..c76837e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart" as a;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C10;
+static const field core::List<core::int*>* list = #C11;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C14;
+static const field core::List<core::int*>* list = #C15;
+
+constants  {
+  #C1 = 1
+  #C2 = "a"
+  #C3 = <dynamic>[#C1, #C2]
+  #C4 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C3}
+  #C5 = 2
+  #C6 = null
+  #C7 = 3
+  #C8 = <dynamic>[#C5, #C6, #C7, #C6]
+  #C9 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C8}
+  #C10 = col::_UnmodifiableSet<core::int*> {_map:#C9}
+  #C11 = <core::int*>[#C7, #C5]
+  #C12 = <dynamic>[#C5, #C6]
+  #C13 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C12}
+  #C14 = col::_UnmodifiableSet<core::int*> {_map:#C13}
+  #C15 = <core::int*>[#C7]
+}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..c76837e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart" as a;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C10;
+static const field core::List<core::int*>* list = #C11;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+static const field core::Map<core::int*, core::String*>* map = #C4;
+static const field core::Set<core::int*>* set = #C14;
+static const field core::List<core::int*>* list = #C15;
+
+constants  {
+  #C1 = 1
+  #C2 = "a"
+  #C3 = <dynamic>[#C1, #C2]
+  #C4 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C3}
+  #C5 = 2
+  #C6 = null
+  #C7 = 3
+  #C8 = <dynamic>[#C5, #C6, #C7, #C6]
+  #C9 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C8}
+  #C10 = col::_UnmodifiableSet<core::int*> {_map:#C9}
+  #C11 = <core::int*>[#C7, #C5]
+  #C12 = <dynamic>[#C5, #C6]
+  #C13 = core::_ImmutableMap<core::int*, Null> {_kvPairs:#C12}
+  #C14 = col::_UnmodifiableSet<core::int*> {_map:#C13}
+  #C15 = <core::int*>[#C7]
+}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline.expect
new file mode 100644
index 0000000..ecc271e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import 'main_lib.dart' as a;
+
+const map = <int, String>{
+  ...a.map,
+};
+const set = <int>{
+  ...a.set,
+  ...a.list,
+};
+const list = <int>[
+  ...a.list,
+  ...a.set,
+];
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b817c1c
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import 'main_lib.dart' as a;
+
+const list = <int>[
+  ...a.list,
+  ...a.set,
+];
+const map = <int, String>{
+  ...a.map,
+};
+const set = <int>{
+  ...a.set,
+  ...a.list,
+};
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/from_lib/main_lib.dart b/pkg/front_end/testcases/general/constants/from_lib/main_lib.dart
new file mode 100644
index 0000000..eccfc0b
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/main_lib.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, 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.
+
+const map = <int, String>{
+  1: 'a',
+};
+
+const set = <int>{
+  2,
+};
+
+const list = <int>[
+  3,
+];
diff --git a/pkg/front_end/testcases/general/constants/from_lib/test.options b/pkg/front_end/testcases/general/constants/from_lib/test.options
new file mode 100644
index 0000000..bfe6dc8
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/from_lib/test.options
@@ -0,0 +1 @@
+main_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/infer_equals.dart b/pkg/front_end/testcases/general/infer_equals.dart
new file mode 100644
index 0000000..5ef9b93
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, 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.6
+
+class Class {
+  var field;
+
+  operator ==(o) {
+    if (o is! Class) return false;
+    return field == o.field;
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.outline.expect b/pkg/front_end/testcases/general/infer_equals.dart.outline.expect
new file mode 100644
index 0000000..1e4df77
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.outline.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field;
+  synthetic constructor •() → self::Class*
+    ;
+  operator ==(dynamic o) → core::bool*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.strong.expect b/pkg/front_end/testcases/general/infer_equals.dart.strong.expect
new file mode 100644
index 0000000..f1fea95
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.strong.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  operator ==(dynamic o) → core::bool* {
+    if(!(o is self::Class*))
+      return false;
+    return this.{self::Class::field}.{core::Object::==}(o.field);
+  }
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.strong.transformed.expect b/pkg/front_end/testcases/general/infer_equals.dart.strong.transformed.expect
new file mode 100644
index 0000000..f1fea95
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+  operator ==(dynamic o) → core::bool* {
+    if(!(o is self::Class*))
+      return false;
+    return this.{self::Class::field}.{core::Object::==}(o.field);
+  }
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..f3b19e7
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Class {
+  var field;
+  operator ==(o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..00f7d50
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Class {
+  operator ==(o) {}
+  var field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 8ddb02d..259a2e3 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -14,7 +14,6 @@
 general_nnbd_opt_out/override_setter_with_field: TypeCheckError
 general/abstract_members: TypeCheckError
 general/bug30695: TypeCheckError
-general/constants/const_collections: TypeCheckError
 general/covariant_field: TypeCheckError
 general/getter_vs_setter_type: TypeCheckError
 general/infer_field_from_multiple: TypeCheckError
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 62f7def..be01ba0 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -90,12 +90,42 @@
   /// Lowering of a list constant to a backend-specific representation.
   Constant lowerListConstant(ListConstant constant) => constant;
 
+  /// Returns `true` if [constant] is lowered list constant created by
+  /// [lowerListConstant].
+  bool isLoweredListConstant(Constant constant) => false;
+
+  /// Calls `f` for each element in the lowered list [constant].
+  ///
+  /// This assumes that `isLoweredListConstant(constant)` is true.
+  void forEachLoweredListConstantElement(
+      Constant constant, void Function(Constant element) f) {}
+
   /// Lowering of a set constant to a backend-specific representation.
   Constant lowerSetConstant(SetConstant constant) => constant;
 
+  /// Returns `true` if [constant] is lowered set constant created by
+  /// [lowerSetConstant].
+  bool isLoweredSetConstant(Constant constant) => false;
+
+  /// Calls `f` for each element in the lowered set [constant].
+  ///
+  /// This assumes that `isLoweredSetConstant(constant)` is true.
+  void forEachLoweredSetConstantElement(
+      Constant constant, void Function(Constant element) f) {}
+
   /// Lowering of a map constant to a backend-specific representation.
   Constant lowerMapConstant(MapConstant constant) => constant;
 
+  /// Returns `true` if [constant] is lowered map constant created by
+  /// [lowerMapConstant].
+  bool isLoweredMapConstant(Constant constant) => false;
+
+  /// Calls `f` for each key/value pair in the lowered map [constant].
+  ///
+  /// This assumes that `lowerMapConstant(constant)` is true.
+  void forEachLoweredMapConstantEntry(
+      Constant constant, void Function(Constant key, Constant value) f) {}
+
   /// Number semantics to use for this backend.
   NumberSemantics get numberSemantics => NumberSemantics.vm;
 
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 1b79258..0e24e6f 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -706,7 +706,7 @@
   @override
   DartType visitListConcatenation(ListConcatenation node) {
     DartType type =
-        environment.listType(node.typeArgument, currentLibrary.nonNullable);
+        environment.iterableType(node.typeArgument, currentLibrary.nonNullable);
     for (Expression part in node.lists) {
       DartType partType = visitExpression(part);
       checkAssignable(node, type, partType);
@@ -717,7 +717,7 @@
   @override
   DartType visitSetConcatenation(SetConcatenation node) {
     DartType type =
-        environment.setType(node.typeArgument, currentLibrary.nonNullable);
+        environment.iterableType(node.typeArgument, currentLibrary.nonNullable);
     for (Expression part in node.sets) {
       DartType partType = visitExpression(part);
       checkAssignable(node, type, partType);
diff --git a/pkg/kernel/lib/vm/constants_native_effects.dart b/pkg/kernel/lib/vm/constants_native_effects.dart
index 444c44b..8bb1bac 100644
--- a/pkg/kernel/lib/vm/constants_native_effects.dart
+++ b/pkg/kernel/lib/vm/constants_native_effects.dart
@@ -10,8 +10,11 @@
 
 class VmConstantsBackend extends ConstantsBackend {
   final Class immutableMapClass;
+  final Class unmodifiableSetClass;
+  final Field unmodifiableSetMap;
 
-  VmConstantsBackend._(this.immutableMapClass);
+  VmConstantsBackend._(this.immutableMapClass, this.unmodifiableSetMap,
+      this.unmodifiableSetClass);
 
   /// If [defines] is not `null` it will be used for handling
   /// `const {bool,...}.fromEnvironment()` otherwise the current VM's values
@@ -21,8 +24,11 @@
     final Class immutableMapClass = coreLibrary.classes
         .firstWhere((Class klass) => klass.name == '_ImmutableMap');
     assert(immutableMapClass != null);
+    Field unmodifiableSetMap = coreTypes.index
+        .getMember('dart:collection', '_UnmodifiableSet', '_map');
 
-    return new VmConstantsBackend._(immutableMapClass);
+    return new VmConstantsBackend._(immutableMapClass, unmodifiableSetMap,
+        unmodifiableSetMap.enclosingClass);
   }
 
   @override
@@ -50,4 +56,63 @@
       kvPairListField.getterReference: kvListConstant,
     });
   }
+
+  @override
+  bool isLoweredMapConstant(Constant constant) {
+    return constant is InstanceConstant &&
+        constant.classNode == immutableMapClass;
+  }
+
+  @override
+  void forEachLoweredMapConstantEntry(
+      Constant constant, void Function(Constant key, Constant value) f) {
+    assert(isLoweredMapConstant(constant));
+    final InstanceConstant instance = constant;
+    assert(immutableMapClass.fields.length == 1);
+    final Field kvPairListField = immutableMapClass.fields[0];
+    final ListConstant kvListConstant =
+        instance.fieldValues[kvPairListField.getterReference];
+    assert(kvListConstant.entries.length % 2 == 0);
+    for (int index = 0; index < kvListConstant.entries.length; index += 2) {
+      f(kvListConstant.entries[index], kvListConstant.entries[index + 1]);
+    }
+  }
+
+  @override
+  Constant lowerSetConstant(SetConstant constant) {
+    final DartType elementType = constant.typeArgument;
+    final List<Constant> entries = constant.entries;
+    final List<ConstantMapEntry> mapEntries =
+        new List<ConstantMapEntry>.filled(entries.length, null);
+    for (int i = 0; i < entries.length; ++i) {
+      mapEntries[i] = new ConstantMapEntry(entries[i], new NullConstant());
+    }
+    Constant map = lowerMapConstant(
+        new MapConstant(elementType, const NullType(), mapEntries));
+    return new InstanceConstant(unmodifiableSetClass.reference, [elementType],
+        <Reference, Constant>{unmodifiableSetMap.getterReference: map});
+  }
+
+  @override
+  bool isLoweredSetConstant(Constant constant) {
+    if (constant is InstanceConstant &&
+        constant.classNode == unmodifiableSetClass) {
+      InstanceConstant instance = constant;
+      return isLoweredMapConstant(
+          instance.fieldValues[unmodifiableSetMap.getterReference]);
+    }
+    return false;
+  }
+
+  @override
+  void forEachLoweredSetConstantElement(
+      Constant constant, void Function(Constant element) f) {
+    assert(isLoweredSetConstant(constant));
+    final InstanceConstant instance = constant;
+    final Constant mapConstant =
+        instance.fieldValues[unmodifiableSetMap.getterReference];
+    forEachLoweredMapConstantEntry(mapConstant, (Constant key, Constant value) {
+      f(key);
+    });
+  }
 }
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index 00a1a1c..179c37b 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -134,7 +134,9 @@
   /// If [getAllSources] is false it will ask specifically for report
   /// (and thus hits) for "lib1.dart" only.
   Future<Set<int>> collectAndCheckCoverageData(int port, bool getAllSources,
-      {bool resume: true}) async {
+      {bool resume: true,
+      bool onGetAllVerifyCount: true,
+      Set<int> coverageForLines}) async {
     RemoteVm remoteVm = new RemoteVm(port);
 
     // Wait for the script to have finished.
@@ -189,7 +191,7 @@
         }
         i++;
       }
-      if (getAllSources) {
+      if (getAllSources && onGetAllVerifyCount) {
         expect(scriptIdToIndex.length >= 2, isTrue);
       }
 
@@ -226,12 +228,16 @@
             }
           }
           for (int pos in coverage["misses"]) positions.add(pos);
-          for (int pos in range["possibleBreakpoints"]) positions.add(pos);
+          if (range["possibleBreakpoints"] != null) {
+            for (int pos in range["possibleBreakpoints"]) positions.add(pos);
+          }
           Map script = scriptIndexToScript[range["scriptIndex"]];
           Set<int> knownPositions = new Set<int>();
+          Map<int, int> tokenPosToLine = {};
           if (script["tokenPosTable"] != null) {
             for (List tokenPosTableLine in script["tokenPosTable"]) {
               for (int i = 1; i < tokenPosTableLine.length; i += 2) {
+                tokenPosToLine[tokenPosTableLine[i]] = tokenPosTableLine[0];
                 knownPositions.add(tokenPosTableLine[i]);
               }
             }
@@ -244,6 +250,14 @@
                   "line and column.");
             }
           }
+
+          if (coverageForLines != null) {
+            for (int pos in coverage["hits"]) {
+              if (lib1scriptIndices.contains(range["scriptIndex"])) {
+                coverageForLines.add(tokenPosToLine[pos]);
+              }
+            }
+          }
         }
       }
     }
@@ -486,6 +500,243 @@
     });
   });
 
+  group('multiple kernels constant coverage', () {
+    Directory mytest;
+    File main;
+    File lib1;
+    int lineForUnnamedConstructor;
+    int lineForNamedConstructor;
+    Process vm;
+    setUpAll(() {
+      mytest = Directory.systemTemp.createTempSync('incremental');
+      main = new File('${mytest.path}/main.dart')..createSync();
+      main.writeAsStringSync("""
+        // This file - combined with the lib - should have coverage for both
+        // constructors of Foo.
+        import 'lib1.dart' as lib1;
+
+        void testFunction() {
+          const foo = lib1.Foo.named();
+          const foo2 = lib1.Foo.named();
+          if (!identical(foo, foo2)) throw "what?";
+        }
+
+        main() {
+          lib1.testFunction();
+          testFunction();
+          print("main");
+        }
+      """);
+      lib1 = new File('${mytest.path}/lib1.dart')..createSync();
+      lib1.writeAsStringSync("""
+        // Compiling this file should mark the default constructor - but not the
+        // named constructor - as having coverage.
+        class Foo {
+          final int x;
+          const Foo([int? x]) : this.x = x ?? 42;
+          const Foo.named([int? x]) : this.x = x ?? 42;
+        }
+
+        void testFunction() {
+          const foo = Foo();
+          const foo2 = Foo();
+          if (!identical(foo, foo2)) throw "what?";
+        }
+
+        main() {
+          testFunction();
+          print("lib1");
+        }
+      """);
+      lineForUnnamedConstructor = 5;
+      lineForNamedConstructor = 6;
+    });
+
+    tearDownAll(() {
+      try {
+        mytest.deleteSync(recursive: true);
+      } catch (_) {
+        // Ignore errors;
+      }
+      try {
+        vm.kill();
+      } catch (_) {
+        // Ignore errors;
+      }
+    });
+
+    Future<Set<int>> runAndGetLineCoverage(
+        File list, String expectStdoutContains) async {
+      vm = await Process.start(Platform.resolvedExecutable, <String>[
+        "--pause-isolates-on-exit",
+        "--enable-vm-service:0",
+        "--disable-service-auth-codes",
+        "--disable-dart-dev",
+        list.path
+      ]);
+
+      const kObservatoryListening = 'Observatory listening on ';
+      final RegExp observatoryPortRegExp =
+          new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)");
+      int port;
+      final splitter = new LineSplitter();
+      Completer<String> portLineCompleter = new Completer<String>();
+      Set<int> coverageLines = {};
+      bool foundExpectedString = false;
+      vm.stdout
+          .transform(utf8.decoder)
+          .transform(splitter)
+          .listen((String s) async {
+        if (s == expectStdoutContains) {
+          foundExpectedString = true;
+        }
+        if (s.startsWith(kObservatoryListening)) {
+          expect(observatoryPortRegExp.hasMatch(s), isTrue);
+          final match = observatoryPortRegExp.firstMatch(s);
+          port = int.parse(match.group(1));
+          await collectAndCheckCoverageData(port, true,
+              onGetAllVerifyCount: false, coverageForLines: coverageLines);
+          if (!portLineCompleter.isCompleted) {
+            portLineCompleter.complete("done");
+          }
+        }
+        print("vm stdout: $s");
+      });
+      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
+        print("vm stderr: $s");
+      });
+      await portLineCompleter.future;
+      print("Compiler terminated with ${await vm.exitCode} exit code");
+      expect(foundExpectedString, isTrue);
+      return coverageLines;
+    }
+
+    test('compile seperatly, check coverage', () async {
+      Directory dir = mytest.createTempSync();
+
+      // First compile lib, run and verify coverage (un-named constructor
+      // covered, but not the named constructor).
+      // Note that it's called 'lib1' to match with expectations from coverage
+      // collector helper in this file.
+      File libDill = File(p.join(dir.path, p.basename(lib1.path + ".dill")));
+      IncrementalCompiler compiler = new IncrementalCompiler(options, lib1.uri);
+      Component component = await compiler.compile();
+      expect(component.libraries.length, equals(1));
+      expect(component.libraries.single.fileUri, equals(lib1.uri));
+      IOSink sink = libDill.openWrite();
+      BinaryPrinter printer = new BinaryPrinter(sink);
+      printer.writeComponentFile(component);
+      await sink.flush();
+      await sink.close();
+      File list = new File(p.join(dir.path, 'dill.list'))..createSync();
+      list.writeAsStringSync("#@dill\n${libDill.path}\n");
+      Set<int> lineCoverage = await runAndGetLineCoverage(list, "lib1");
+      // Expect coverage for unnamed constructor but not for the named one.
+      expect(
+          lineCoverage.intersection(
+              {lineForUnnamedConstructor, lineForNamedConstructor}),
+          equals({lineForUnnamedConstructor}));
+
+      try {
+        vm.kill();
+      } catch (_) {
+        // Ignore errors;
+      }
+      // Accept the compile to not include the lib again.
+      compiler.accept();
+
+      // Then compile lib, run and verify coverage (un-named constructor
+      // covered, and the named constructor coveraged too).
+      File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
+      component = await compiler.compile(entryPoint: main.uri);
+      expect(component.libraries.length, equals(1));
+      expect(component.libraries.single.fileUri, equals(main.uri));
+      sink = mainDill.openWrite();
+      printer = new BinaryPrinter(sink);
+      printer.writeComponentFile(component);
+      await sink.flush();
+      await sink.close();
+      list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
+      lineCoverage = await runAndGetLineCoverage(list, "main");
+
+      // Expect coverage for both unnamed constructor and for the named one.
+      expect(
+          lineCoverage.intersection(
+              {lineForUnnamedConstructor, lineForNamedConstructor}),
+          equals({lineForUnnamedConstructor, lineForNamedConstructor}));
+
+      try {
+        vm.kill();
+      } catch (_) {
+        // Ignore errors;
+      }
+      // Accept the compile to not include the lib again.
+      compiler.accept();
+
+      // Finally, change lib to shift the constructors so the old line numbers
+      // doesn't match. Compile lib by itself, compile lib, run with the old
+      // main and verify coverage is still correct (both un-named constructor
+      // and named constructor (at new line numbers) are covered, and the old
+      // line numbers are not coverage.
+
+      lib1.writeAsStringSync("""
+        //
+        // Shift lines down by five
+        // lines so the original
+        // lines can't be coverred
+        //
+        class Foo {
+          final int x;
+          const Foo([int? x]) : this.x = x ?? 42;
+          const Foo.named([int? x]) : this.x = x ?? 42;
+        }
+
+        void testFunction() {
+          const foo = Foo();
+          const foo2 = Foo();
+          if (!identical(foo, foo2)) throw "what?";
+        }
+
+        main() {
+          testFunction();
+          print("lib1");
+        }
+      """);
+      int newLineForUnnamedConstructor = 8;
+      int newLineForNamedConstructor = 9;
+      compiler.invalidate(lib1.uri);
+      component = await compiler.compile(entryPoint: lib1.uri);
+      expect(component.libraries.length, equals(1));
+      expect(component.libraries.single.fileUri, equals(lib1.uri));
+      sink = libDill.openWrite();
+      printer = new BinaryPrinter(sink);
+      printer.writeComponentFile(component);
+      await sink.flush();
+      await sink.close();
+      list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
+      lineCoverage = await runAndGetLineCoverage(list, "main");
+
+      // Expect coverage for both unnamed constructor and for the named one on
+      // the new positions, but no coverage on the old positions.
+      expect(
+          lineCoverage.intersection({
+            lineForUnnamedConstructor,
+            lineForNamedConstructor,
+            newLineForUnnamedConstructor,
+            newLineForNamedConstructor
+          }),
+          equals({newLineForUnnamedConstructor, newLineForNamedConstructor}));
+
+      try {
+        vm.kill();
+      } catch (_) {
+        // Ignore errors;
+      }
+      // Accept the compile to not include the lib again.
+      compiler.accept();
+    });
+  });
+
   group('multiple kernels 2', () {
     Directory mytest;
     File main;
diff --git a/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart b/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart
new file mode 100644
index 0000000..b0f078d
--- /dev/null
+++ b/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, 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 "get_source_report_const_coverage_test.dart";
+
+void testFunction() {
+  const namedFoo = Foo.named3();
+  const namedFoo2 = Foo.named3();
+  const namedIdentical = identical(namedFoo, namedFoo2);
+  print("namedIdentical: $namedIdentical");
+}
diff --git a/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart b/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart
new file mode 100644
index 0000000..32cb035
--- /dev/null
+++ b/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2020, 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:observatory/service_io.dart';
+import 'package:test/test.dart';
+import 'test_helper.dart';
+import 'service_test_common.dart';
+import 'dart:developer';
+
+import 'get_source_report_const_coverage_lib.dart' as lib;
+
+const String filename = "get_source_report_const_coverage_test";
+const Set<int> expectedLinesHit = {20, 22, 26};
+const Set<int> expectedLinesNotHit = {24};
+
+class Foo {
+  final int x;
+  // Expect this constructor to be coverage by coverage.
+  const Foo([int? x]) : this.x = x ?? 42;
+  // Expect this constructor to be coverage by coverage too.
+  const Foo.named1([int? x]) : this.x = x ?? 42;
+  // Expect this constructor to *NOT* be coverage by coverage.
+  const Foo.named2([int? x]) : this.x = x ?? 42;
+  // Expect this constructor to be coverage by coverage too (from lib).
+  const Foo.named3([int? x]) : this.x = x ?? 42;
+}
+
+void testFunction() {
+  const foo = Foo();
+  const foo2 = Foo();
+  const fooIdentical = identical(foo, foo2);
+  print(fooIdentical);
+
+  const namedFoo = Foo.named1();
+  const namedFoo2 = Foo.named1();
+  const namedIdentical = identical(namedFoo, namedFoo2);
+  print(fooIdentical);
+
+  debugger();
+
+  // That this is called after (or at all) is not relevent for the code
+  // coverage of constants.
+  lib.testFunction();
+
+  print("Done");
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    final stack = await isolate.getStack();
+
+    // Make sure we are in the right place.
+    expect(stack.type, equals('Stack'));
+    expect(stack['frames'].length, greaterThanOrEqualTo(1));
+    expect(stack['frames'][0].function.name, equals('testFunction'));
+
+    final List<Script> scripts = await isolate.getScripts();
+    Script? foundScript;
+    for (Script script in scripts) {
+      if (script.uri.contains(filename)) {
+        foundScript = script;
+        break;
+      }
+    }
+
+    Set<int> hits;
+    {
+      // Get report for everything; then collect for this library.
+      final Map<String, Object> params = {
+        'reports': ['Coverage'],
+      };
+      final coverage =
+          await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+      hits = getHitsFor(coverage, filename);
+      await foundScript!.load();
+      final Set<int> lines = {};
+      for (int hit in hits) {
+        // We expect every hit to be translatable to line
+        // (i.e. tokenToLine to return non-null).
+        lines.add(foundScript.tokenToLine(hit)!);
+      }
+      print("Token position hits: $hits --- line hits: $lines");
+      expect(lines.intersection(expectedLinesHit), equals(expectedLinesHit));
+      expect(lines.intersection(expectedLinesNotHit), isEmpty);
+    }
+    {
+      // Now get report for the this file only.
+      final Map<String, Object> params = {
+        'reports': ['Coverage'],
+        'scriptId': foundScript.id!
+      };
+      final coverage =
+          await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+      final Set<int> localHits = getHitsFor(coverage, filename);
+      expect(localHits.length, equals(hits.length));
+      expect(hits.toList()..sort(), equals(localHits.toList()..sort()));
+      print(localHits);
+    }
+  },
+];
+
+Set<int> getHitsFor(Map coverage, String uriContains) {
+  final List scripts = coverage["scripts"];
+  final Set<int> scriptIdsWanted = {};
+  for (int i = 0; i < scripts.length; i++) {
+    final Map script = scripts[i];
+    final String scriptUri = script["uri"];
+    if (scriptUri.contains(uriContains)) {
+      scriptIdsWanted.add(i);
+    }
+  }
+  final List ranges = coverage["ranges"];
+  final Set<int> hits = {};
+  for (int i = 0; i < ranges.length; i++) {
+    final Map range = ranges[i];
+    if (scriptIdsWanted.contains(range["scriptIndex"])) {
+      if (range["coverage"] != null) {
+        for (int hit in range["coverage"]["hits"]) {
+          hits.add(hit);
+        }
+      }
+    }
+  }
+  return hits;
+}
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index adea481..a1d5206 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -91,7 +91,7 @@
     final numRanges = coverage['ranges'].length;
     expect(coverage['type'], equals('SourceReport'));
 
-    expect(numRanges, equals(10));
+    expect(numRanges, equals(11));
     expect(coverage['ranges'][0], equals(expectedRange));
     expect(coverage['scripts'].length, 1);
     expect(
@@ -106,7 +106,7 @@
     };
     coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
     expect(coverage['type'], equals('SourceReport'));
-    expect(coverage['ranges'].length, 11);
+    expect(coverage['ranges'].length, 12);
     expect(allRangesCompiled(coverage), isTrue);
 
     // One function
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index b62a6e9..59145d2 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -109,6 +109,7 @@
 get_allocation_samples_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_isolate_after_language_error_test: CompileTimeError
 get_object_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_source_report_const_coverage_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_source_report_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_source_report_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_stack_limit_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart
new file mode 100644
index 0000000..b0f078d
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, 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 "get_source_report_const_coverage_test.dart";
+
+void testFunction() {
+  const namedFoo = Foo.named3();
+  const namedFoo2 = Foo.named3();
+  const namedIdentical = identical(namedFoo, namedFoo2);
+  print("namedIdentical: $namedIdentical");
+}
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart
new file mode 100644
index 0000000..7c6af16
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2020, 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:observatory_2/service_io.dart';
+import 'package:test/test.dart';
+import 'test_helper.dart';
+import 'service_test_common.dart';
+import 'dart:developer';
+
+import 'get_source_report_const_coverage_lib.dart' as lib;
+
+const String filename = "get_source_report_const_coverage_test";
+const Set<int> expectedLinesHit = {20, 22, 26};
+const Set<int> expectedLinesNotHit = {24};
+
+class Foo {
+  final int x;
+  // Expect this constructor to be coverage by coverage.
+  const Foo([int x]) : this.x = x ?? 42;
+  // Expect this constructor to be coverage by coverage too.
+  const Foo.named1([int x]) : this.x = x ?? 42;
+  // Expect this constructor to *NOT* be coverage by coverage.
+  const Foo.named2([int x]) : this.x = x ?? 42;
+  // Expect this constructor to be coverage by coverage too (from lib).
+  const Foo.named3([int x]) : this.x = x ?? 42;
+}
+
+void testFunction() {
+  const foo = Foo();
+  const foo2 = Foo();
+  const fooIdentical = identical(foo, foo2);
+  print(fooIdentical);
+
+  const namedFoo = Foo.named1();
+  const namedFoo2 = Foo.named1();
+  const namedIdentical = identical(namedFoo, namedFoo2);
+  print(fooIdentical);
+
+  debugger();
+
+  // That this is called after (or at all) is not relevent for the code
+  // coverage of constants.
+  lib.testFunction();
+
+  print("Done");
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    final stack = await isolate.getStack();
+
+    // Make sure we are in the right place.
+    expect(stack.type, equals('Stack'));
+    expect(stack['frames'].length, greaterThanOrEqualTo(1));
+    expect(stack['frames'][0].function.name, equals('testFunction'));
+
+    final List<Script> scripts = await isolate.getScripts();
+    Script foundScript;
+    for (Script script in scripts) {
+      if (script.uri.contains(filename)) {
+        foundScript = script;
+        break;
+      }
+    }
+
+    Set<int> hits;
+    {
+      // Get report for everything; then collect for this library.
+      final Map<String, Object> params = {
+        'reports': ['Coverage'],
+      };
+      final coverage =
+          await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+      hits = getHitsFor(coverage, filename);
+      await foundScript.load();
+      final Set<int> lines = {};
+      for (int hit in hits) {
+        // We expect every hit to be translatable to line
+        // (i.e. tokenToLine to return non-null).
+        lines.add(foundScript.tokenToLine(hit));
+      }
+      print("Token position hits: $hits --- line hits: $lines");
+      expect(lines.intersection(expectedLinesHit), equals(expectedLinesHit));
+      expect(lines.intersection(expectedLinesNotHit), isEmpty);
+    }
+    {
+      // Now get report for the this file only.
+      final Map<String, Object> params = {
+        'reports': ['Coverage'],
+        'scriptId': foundScript.id
+      };
+      final coverage =
+          await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+      final Set<int> localHits = getHitsFor(coverage, filename);
+      expect(localHits.length, equals(hits.length));
+      expect(hits.toList()..sort(), equals(localHits.toList()..sort()));
+      print(localHits);
+    }
+  },
+];
+
+Set<int> getHitsFor(Map coverage, String uriContains) {
+  final List scripts = coverage["scripts"];
+  final Set<int> scriptIdsWanted = {};
+  for (int i = 0; i < scripts.length; i++) {
+    final Map script = scripts[i];
+    final String scriptUri = script["uri"];
+    if (scriptUri.contains(uriContains)) {
+      scriptIdsWanted.add(i);
+    }
+  }
+  final List ranges = coverage["ranges"];
+  final Set<int> hits = {};
+  for (int i = 0; i < ranges.length; i++) {
+    final Map range = ranges[i];
+    if (scriptIdsWanted.contains(range["scriptIndex"])) {
+      if (range["coverage"] != null) {
+        for (int hit in range["coverage"]["hits"]) {
+          hits.add(hit);
+        }
+      }
+    }
+  }
+  return hits;
+}
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_test.dart b/runtime/observatory_2/tests/service_2/get_source_report_test.dart
index 97606de..78ea471 100644
--- a/runtime/observatory_2/tests/service_2/get_source_report_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_source_report_test.dart
@@ -91,7 +91,7 @@
     final numRanges = coverage['ranges'].length;
     expect(coverage['type'], equals('SourceReport'));
 
-    expect(numRanges, equals(10));
+    expect(numRanges, equals(11));
     expect(coverage['ranges'][0], equals(expectedRange));
     expect(coverage['scripts'].length, 1);
     expect(
@@ -106,7 +106,7 @@
     };
     coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
     expect(coverage['type'], equals('SourceReport'));
-    expect(coverage['ranges'].length, 11);
+    expect(coverage['ranges'].length, 12);
     expect(allRangesCompiled(coverage), isTrue);
 
     // One function
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index 2b6e18b..5522831 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -109,6 +109,7 @@
 get_allocation_samples_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_isolate_after_language_error_test: CompileTimeError
 get_object_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
+get_source_report_const_coverage_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_source_report_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_source_report_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
 get_stack_limit_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index a90b40d..794f917 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2807,6 +2807,33 @@
   return H.DartString(reader_.BufferAt(ReaderOffset()), size, Heap::kOld);
 }
 
+ExternalTypedDataPtr KernelReaderHelper::GetConstantCoverageFor(
+    intptr_t index) {
+  AlternativeReadingScope alt(&reader_);
+  SetOffset(GetOffsetForSourceInfo(index));
+  SkipBytes(ReadUInt());                         // skip uri.
+  SkipBytes(ReadUInt());                         // skip source.
+  const intptr_t line_start_count = ReadUInt();  // read number of line start
+                                                 // entries.
+  for (intptr_t i = 0; i < line_start_count; ++i) {
+    ReadUInt();
+  }
+
+  SkipBytes(ReadUInt());  // skip import uri.
+
+  intptr_t start_offset = ReaderOffset();
+
+  // Read past "constant coverage constructors".
+  const intptr_t constant_coverage_constructors = ReadUInt();
+  for (intptr_t i = 0; i < constant_coverage_constructors; ++i) {
+    ReadUInt();
+  }
+
+  intptr_t end_offset = ReaderOffset();
+
+  return reader_.ExternalDataFromTo(start_offset, end_offset);
+}
+
 intptr_t ActiveClass::MemberTypeParameterCount(Zone* zone) {
   ASSERT(member != NULL);
   if (member->IsFactory()) {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 0bb8141..b60884c2 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -1257,6 +1257,7 @@
   const String& GetSourceFor(intptr_t index);
   TypedDataPtr GetLineStartsFor(intptr_t index);
   String& SourceTableImportUriFor(intptr_t index, uint32_t binaryVersion);
+  ExternalTypedDataPtr GetConstantCoverageFor(intptr_t index);
 
   Zone* zone_;
   TranslationHelper& translation_helper_;
@@ -1295,6 +1296,8 @@
   friend class ObfuscationProhibitionsMetadataHelper;
   friend class LoadingUnitsMetadataHelper;
   friend bool NeedsDynamicInvocationForwarder(const Function& function);
+  friend ArrayPtr CollectConstConstructorCoverageFrom(
+      const Script& interesting_script);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(KernelReaderHelper);
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 2c54ec6..3e142f4 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -211,17 +211,15 @@
 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
   ASSERT(thread->IsMutatorThread());
   const Function& function = Function::CheckedHandle(zone, arguments.ArgAt(0));
-  Object& result = Object::Handle(zone);
-  ASSERT(!function.HasCode());
 
-  result = Compiler::CompileFunction(thread, function);
-  if (result.IsError()) {
-    if (result.IsLanguageError()) {
-      Exceptions::ThrowCompileTimeError(LanguageError::Cast(result));
-      UNREACHABLE();
-    }
-    Exceptions::PropagateError(Error::Cast(result));
-  }
+  // In single-isolate scenarios the lazy compile stub is only invoked if
+  // there's no existing code. In multi-isolate scenarios with shared JITed code
+  // we can end up in the lazy compile runtime entry here with code being
+  // installed.
+  ASSERT(!function.HasCode() || FLAG_enable_isolate_groups);
+
+  // Will throw if compilation failed (e.g. with compile-time error).
+  function.EnsureHasCode();
 }
 
 bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index b2ff3da..63c13d4 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -503,7 +503,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word Script_InstanceSize = 56;
+static constexpr dart::compiler::target::word Script_InstanceSize = 64;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 12;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -1026,7 +1026,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 104;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -1540,7 +1540,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word Script_InstanceSize = 56;
+static constexpr dart::compiler::target::word Script_InstanceSize = 64;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 12;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -2064,7 +2064,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 104;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -3094,7 +3094,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -4120,7 +4120,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -5266,7 +5266,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_SignatureData_InstanceSize =
     24;
@@ -5847,7 +5847,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_SignatureData_InstanceSize =
     24;
@@ -6985,7 +6985,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_SignatureData_InstanceSize =
     24;
@@ -7559,7 +7559,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_SignatureData_InstanceSize =
     24;
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 952e41a..ed49742 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -347,6 +347,36 @@
   script.set_debug_positions(array_object);
 }
 
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+ArrayPtr CollectConstConstructorCoverageFrom(const Script& interesting_script) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  interesting_script.LookupSourceAndLineStarts(zone);
+  TranslationHelper helper(thread);
+  helper.InitFromScript(interesting_script);
+
+  ExternalTypedData& data =
+      ExternalTypedData::Handle(zone, interesting_script.constant_coverage());
+
+  KernelReaderHelper kernel_reader(zone, &helper, interesting_script, data, 0);
+
+  // Read "constant coverage constructors".
+  const intptr_t constant_coverage_constructors = kernel_reader.ReadUInt();
+  const Array& constructors =
+      Array::Handle(Array::New(constant_coverage_constructors));
+  for (intptr_t i = 0; i < constant_coverage_constructors; ++i) {
+    NameIndex kernel_name = kernel_reader.ReadCanonicalNameReference();
+    Class& klass = Class::ZoneHandle(
+        zone,
+        helper.LookupClassByKernelClass(helper.EnclosingName(kernel_name)));
+    const Function& target = Function::ZoneHandle(
+        zone, helper.LookupConstructorByKernelConstructor(klass, kernel_name));
+    constructors.SetAt(i, target);
+  }
+  return constructors.raw();
+}
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
 ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field) {
   ASSERT(field.is_static() && field.is_const());
 
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index ed66e25..79c5670 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -195,6 +195,10 @@
 
 void CollectTokenPositionsFor(const Script& script);
 
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+ArrayPtr CollectConstConstructorCoverageFrom(const Script& interesting_script);
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
 ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field);
 ObjectPtr EvaluateMetadata(const Library& library,
                            intptr_t kernel_offset,
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 4dbcfb6..878582b 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -2093,6 +2093,10 @@
   const String& uri_string = helper_.SourceTableUriFor(index);
   const String& import_uri_string =
       helper_.SourceTableImportUriFor(index, program_->binary_version());
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  ExternalTypedData& constant_coverage =
+      ExternalTypedData::Handle(Z, helper_.GetConstantCoverageFor(index));
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
   String& sources = String::Handle(Z);
   TypedData& line_starts = TypedData::Handle(Z);
@@ -2138,6 +2142,9 @@
   script.set_kernel_script_index(index);
   script.set_kernel_program_info(kernel_program_info_);
   script.set_line_starts(line_starts);
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  script.set_constant_coverage(constant_coverage);
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   script.set_debug_positions(Array::null_array());
   return script.raw();
 }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 927cfef..1347673 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11161,6 +11161,16 @@
   raw_ptr()->set_line_starts(value.raw());
 }
 
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+void Script::set_constant_coverage(const ExternalTypedData& value) const {
+  raw_ptr()->set_constant_coverage(value.raw());
+}
+
+ExternalTypedDataPtr Script::constant_coverage() const {
+  return raw_ptr()->constant_coverage();
+}
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
 void Script::set_debug_positions(const Array& value) const {
   raw_ptr()->set_debug_positions(value.raw());
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 8ea8ae0..960f3f1 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4522,6 +4522,12 @@
 
   TypedDataPtr line_starts() const;
 
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  ExternalTypedDataPtr constant_coverage() const;
+
+  void set_constant_coverage(const ExternalTypedData& value) const;
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
   void set_line_starts(const TypedData& value) const;
 
   void set_debug_positions(const Array& value) const;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index b6e04fc..15af026 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1315,7 +1315,7 @@
   friend class StoreInstanceFieldInstr;  // For sizeof(guarded_cid_/...)
 };
 
-class ScriptLayout : public ObjectLayout {
+class alignas(8) ScriptLayout : public ObjectLayout {
  public:
   enum {
     kLazyLookupSourceAndLineStartsPos = 0,
@@ -1330,6 +1330,9 @@
   POINTER_FIELD(StringPtr, resolved_url)
   POINTER_FIELD(ArrayPtr, compile_time_constants)
   POINTER_FIELD(TypedDataPtr, line_starts)
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  POINTER_FIELD(ExternalTypedDataPtr, constant_coverage)
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   POINTER_FIELD(ArrayPtr, debug_positions)
   POINTER_FIELD(KernelProgramInfoPtr, kernel_program_info)
   POINTER_FIELD(StringPtr, source)
@@ -1361,8 +1364,13 @@
                kLazyLookupSourceAndLineStartsSize>;
   uint8_t flags_;
 
-  intptr_t kernel_script_index_;
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   int64_t load_timestamp_;
+  int32_t kernel_script_index_;
+#else
+  int32_t kernel_script_index_;
+  int64_t load_timestamp_;
+#endif
 };
 
 class LibraryLayout : public ObjectLayout {
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 0a13543..23f05e8 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1153,9 +1153,15 @@
   return result.raw();
 }
 
-static void TrySwitchInstanceCall(const ICData& ic_data,
-                                  const Function& target_function) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
+static void TrySwitchInstanceCall(Thread* thread,
+                                  StackFrame* caller_frame,
+                                  const Code& caller_code,
+                                  const Function& caller_function,
+                                  const ICData& ic_data,
+                                  const Function& target_function) {
+  auto zone = thread->zone();
+
   // Monomorphic/megamorphic calls only check the receiver CID.
   if (ic_data.NumArgsTested() != 1) return;
 
@@ -1169,24 +1175,14 @@
   if (Isolate::Current()->has_attempted_stepping()) return;
 #endif
 
-  Thread* thread = Thread::Current();
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  StackFrame* caller_frame = iterator.NextFrame();
-  ASSERT(caller_frame->IsDartFrame());
-
   // Monomorphic/megamorphic calls are only for unoptimized code.
-  Zone* zone = thread->zone();
-  const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
-  if (caller_code.is_optimized()) return;
+  ASSERT(!caller_code.is_optimized());
 
   // Code is detached from its function. This will prevent us from resetting
   // the switchable call later because resets are function based and because
   // the ic_data_array belongs to the function instead of the code. This should
   // only happen because of reload, but it sometimes happens with KBC mixed mode
   // probably through a race between foreground and background compilation.
-  const Function& caller_function =
-      Function::Handle(zone, caller_code.function());
   if (caller_function.unoptimized_code() != caller_code.raw()) {
     return;
   }
@@ -1237,9 +1233,8 @@
     }
     return;  // Success.
   }
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 // Perform the subtype and return constant function based on the result.
 static FunctionPtr ComputeTypeCheckTarget(const Instance& receiver,
@@ -1255,151 +1250,38 @@
   return target.raw();
 }
 
-static FunctionPtr InlineCacheMissHandlerGivenTargetFunction(
-    const GrowableArray<const Instance*>& args,  // Checked arguments only.
-    const ICData& ic_data,
-    intptr_t count,
-    const Function& target_function) {
-  if (target_function.IsNull()) {
-    return target_function.raw();
-  }
+static FunctionPtr Resolve(
+    Thread* thread,
+    Zone* zone,
+    const GrowableArray<const Instance*>& caller_arguments,
+    const Class& receiver_class,
+    const String& name,
+    const Array& descriptor) {
+  ASSERT(name.IsSymbol());
+  auto& target_function = Function::Handle(zone);
+  ArgumentsDescriptor args_desc(descriptor);
 
-  const Instance& receiver = *args[0];
-
-  if (args.length() == 1) {
-    auto exactness = StaticTypeExactnessState::NotTracking();
-    if (ic_data.is_tracking_exactness()) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-      exactness = receiver.IsNull() ? StaticTypeExactnessState::NotExact()
-                                    : StaticTypeExactnessState::Compute(
-                                          Type::Cast(AbstractType::Handle(
-                                              ic_data.receivers_static_type())),
-                                          receiver);
-#else
-      UNREACHABLE();
-#endif
-    }
-    ic_data.EnsureHasReceiverCheck(receiver.GetClassId(), target_function,
-                                   count, exactness);
-  } else {
-    GrowableArray<intptr_t> class_ids(args.length());
-    ASSERT(ic_data.NumArgsTested() == args.length());
-    for (intptr_t i = 0; i < args.length(); i++) {
-      class_ids.Add(args[i]->GetClassId());
-    }
-    ic_data.EnsureHasCheck(class_ids, target_function, count);
-  }
-  if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) {
-    DartFrameIterator iterator(Thread::Current(),
-                               StackFrameIterator::kNoCrossThreadIteration);
-    StackFrame* caller_frame = iterator.NextFrame();
-    ASSERT(caller_frame != NULL);
-    if (FLAG_trace_ic_miss_in_optimized) {
-      const Code& caller = Code::Handle(Code::LookupCode(caller_frame->pc()));
-      if (caller.is_optimized()) {
-        OS::PrintErr("IC miss in optimized code; call %s -> %s\n",
-                     Function::Handle(caller.function()).ToCString(),
-                     target_function.ToCString());
-      }
-    }
-    if (FLAG_trace_ic) {
-      OS::PrintErr("InlineCacheMissHandler %" Pd " call at %#" Px
-                   "' "
-                   "adding <%s> id:%" Pd " -> <%s>\n",
-                   args.length(), caller_frame->pc(),
-                   Class::Handle(receiver.clazz()).ToCString(),
-                   receiver.GetClassId(), target_function.ToCString());
-    }
-  }
-
-  TrySwitchInstanceCall(ic_data, target_function);
-
-  return target_function.raw();
-}
-
-static FunctionPtr InlineCacheMissHandler(
-    const GrowableArray<const Instance*>& args,  // Checked arguments only.
-    const ICData& ic_data) {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-
-  const Instance& receiver = *args[0];
-  ArgumentsDescriptor arguments_descriptor(
-      Array::Handle(zone, ic_data.arguments_descriptor()));
-  String& function_name = String::Handle(zone, ic_data.target_name());
-  ASSERT(function_name.IsSymbol());
-
-  const Class& receiver_class = Class::Handle(zone, receiver.clazz());
-  Function& target_function = Function::Handle(zone);
   if (receiver_class.EnsureIsFinalized(thread) == Error::null()) {
-    target_function = Resolver::ResolveDynamicForReceiverClass(
-        receiver_class, function_name, arguments_descriptor);
+    target_function = Resolver::ResolveDynamicForReceiverClass(receiver_class,
+                                                               name, args_desc);
+  }
+  if (caller_arguments.length() == 2 &&
+      target_function.raw() ==
+          thread->isolate()->object_store()->simple_instance_of_function()) {
+    // Replace the target function with constant function.
+    const AbstractType& type = AbstractType::Cast(*caller_arguments[1]);
+    target_function =
+        ComputeTypeCheckTarget(*caller_arguments[0], type, args_desc);
   }
 
-  ObjectStore* store = thread->isolate()->object_store();
-  if (target_function.raw() == store->simple_instance_of_function()) {
-    // Replace the target function with constant function.
-    ASSERT(args.length() == 2);
-    const AbstractType& type = AbstractType::Cast(*args[1]);
-    target_function =
-        ComputeTypeCheckTarget(receiver, type, arguments_descriptor);
-  }
   if (target_function.IsNull()) {
-    if (FLAG_trace_ic) {
-      OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n",
-                   String::Handle(zone, ic_data.target_name()).ToCString(),
-                   receiver.ToCString());
-    }
-    const Array& args_descriptor =
-        Array::Handle(zone, ic_data.arguments_descriptor());
-    const String& target_name = String::Handle(zone, ic_data.target_name());
-    target_function =
-        InlineCacheMissHelper(receiver_class, args_descriptor, target_name);
+    target_function = InlineCacheMissHelper(receiver_class, descriptor, name);
   }
   if (target_function.IsNull()) {
     ASSERT(!FLAG_lazy_dispatchers);
-    return target_function.raw();
   }
 
-  SafepointMutexLocker ml(thread->isolate_group()->patchable_call_mutex());
-
-  return InlineCacheMissHandlerGivenTargetFunction(args, ic_data, 1,
-                                                   target_function);
-}
-
-// Handles inline cache misses by updating the IC data array of the call site.
-//   Arg0: Receiver object.
-//   Arg1: IC data object.
-//   Returns: target function with compiled code or null.
-// Modifies the instance call to hold the updated IC data array.
-DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) {
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
-  const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(1));
-  RELEASE_ASSERT(!FLAG_precompiled_mode);
-  GrowableArray<const Instance*> args(1);
-  args.Add(&receiver);
-  const Function& result =
-      Function::Handle(zone, InlineCacheMissHandler(args, ic_data));
-  arguments.SetReturn(result);
-}
-
-// Handles inline cache misses by updating the IC data array of the call site.
-//   Arg0: Receiver object.
-//   Arg1: Argument after receiver.
-//   Arg2: IC data object.
-//   Returns: target function with compiled code or null.
-// Modifies the instance call to hold the updated IC data array.
-DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) {
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
-  const Instance& other = Instance::CheckedHandle(zone, arguments.ArgAt(1));
-  const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(2));
-  RELEASE_ASSERT(!FLAG_precompiled_mode);
-  GrowableArray<const Instance*> args(2);
-  args.Add(&receiver);
-  args.Add(&other);
-  const Function& result =
-      Function::Handle(zone, InlineCacheMissHandler(args, ic_data));
-  arguments.SetReturn(result);
+  return target_function.raw();
 }
 
 // Handles a static call in unoptimized code that has one argument type not
@@ -1554,26 +1436,39 @@
 
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-// We use two different instance calls in JIT vs AOT but both are patchable. A
-// subset of the patching cases are handled by [PatchableCallHandler].
+enum class MissHandler {
+  kInlineCacheMiss,
+  kSwitchableCallMiss,
+};
+
+// Handles updating of type feedback and possible patching of instance calls.
+//
+// It works in 3 separate steps:
+//   - resolve the actual target
+//   - update type feedback & (optionally) perform call site transition
+//   - return the right values
+//
+// Depending on the JIT/AOT mode we obtain current and patch new (target, data)
+// differently:
 //
 //   - JIT calls must be patched with CodePatcher::PatchInstanceCallAt()
 //   - AOT calls must be patched with CodePatcher::PatchSwitchableCallAt()
 //
-// In the JIT it is possible that a call site will use two different miss
-// handlers:
+// Independent of which miss handler was used or how we will return, we look at
+// current (target, data) and see if we need to transition the call site to a
+// new (target, data). We do this while holding `IG->patchable_call_mutex()`.
 //
-//   - InlineCacheMissHandlerOneArg (which patches callsite to be monomorphic)
-//   - SwitchableCallMiss (which patches callsite to be polymorphic)
-//   - InlineCacheMissHandlerOneArg (which patches it to be megamorphic)
-//   - SwitchableCallMiss (which updates megamorphic cache)
+// Depending on which miss handler got called we might need to return
+// differently:
 //
-// Once we share JITed code across isolates there are more possible sequences
-// which we need to consider.
+//   - SwitchableCallMiss will get get (stub, data) return value
+//   - InlineCache*Miss will get get function as return value
+//
 class PatchableCallHandler {
  public:
   PatchableCallHandler(Thread* thread,
-                       const Instance& receiver,
+                       const GrowableArray<const Instance*>& caller_arguments,
+                       MissHandler miss_handler,
                        NativeArguments arguments,
                        StackFrame* caller_frame,
                        const Code& caller_code,
@@ -1581,20 +1476,26 @@
       : isolate_(thread->isolate()),
         thread_(thread),
         zone_(thread->zone()),
-        receiver_(receiver),
+        caller_arguments_(caller_arguments),
+        miss_handler_(miss_handler),
         arguments_(arguments),
         caller_frame_(caller_frame),
         caller_code_(caller_code),
         caller_function_(caller_function),
         name_(String::Handle()),
-        args_descriptor_(Array::Handle()) {}
+        args_descriptor_(Array::Handle()) {
+    // We only have two arg IC calls in JIT mode.
+    ASSERT(caller_arguments_.length() == 1 || !FLAG_precompiled_mode);
+  }
 
+  void ResolveSwitchAndReturn(const Object& data);
+
+ private:
   FunctionPtr ResolveTargetFunction(const Object& data);
   void HandleMiss(const Object& old_data,
                   const Code& old_target,
                   const Function& target_function);
 
- private:
 #if defined(DART_PRECOMPILED_RUNTIME)
   void DoUnlinkedCallAOT(const UnlinkedCall& unlinked,
                          const Function& target_function);
@@ -1611,17 +1512,48 @@
 #else
   void DoMonomorphicMissJIT(const Object& data,
                             const Function& target_function);
+  void DoICDataMissJIT(const ICData& data,
+                       const Object& old_data,
+                       const Function& target_function);
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
   void DoMegamorphicMiss(const MegamorphicCache& data,
                          const Function& target_function);
 
+  void UpdateICDataWithTarget(const ICData& ic_data,
+                              const Function& target_function);
+  void TrySwitch(const ICData& ic_data, const Function& target_function);
+
+  void ReturnAOT(const Code& stub, const Object& data);
+  void ReturnJIT(const Code& stub, const Object& data, const Function& target);
+  void ReturnJITorAOT(const Code& stub,
+                      const Object& data,
+                      const Function& target);
+
+  const Instance& receiver() { return *caller_arguments_[0]; }
+
+  bool should_consider_patching() {
+    // In AOT we use switchable calls.
+    if (FLAG_precompiled_mode) return true;
+
+    // In JIT instance calls use a different calling sequence in unoptimized vs
+    // optimized code (see [FlowGraphCompiler::EmitInstanceCallJIT] vs
+    // [FlowGraphCompiler::EmitOptimizedInstanceCall]).
+    //
+    // The [CodePatcher::GetInstanceCallAt], [CodePatcher::PatchInstanceCallAt]
+    // only recognize unoptimized call pattern.
+    //
+    // So we will not try to switch optimized instance calls.
+    return !caller_code_.is_optimized();
+  }
+
   ICDataPtr NewICData();
   ICDataPtr NewICDataWithTarget(intptr_t cid, const Function& target);
 
   Isolate* isolate_;
   Thread* thread_;
   Zone* zone_;
-  const Instance& receiver_;
+  const GrowableArray<const Instance*>& caller_arguments_;
+  MissHandler miss_handler_;
   NativeArguments arguments_;
   StackFrame* caller_frame_;
   const Code& caller_code_;
@@ -1640,7 +1572,7 @@
       zone_,
       target_function.IsNull()
           ? NewICData()
-          : NewICDataWithTarget(receiver_.GetClassId(), target_function));
+          : NewICDataWithTarget(receiver().GetClassId(), target_function));
 
   Object& object = Object::Handle(zone_, ic_data.raw());
   Code& code = Code::Handle(zone_, StubCode::ICCallThroughCode().raw());
@@ -1659,7 +1591,7 @@
     const Code& target_code =
         Code::Handle(zone_, target_function.CurrentCode());
     const Smi& expected_cid =
-        Smi::Handle(zone_, Smi::New(receiver_.GetClassId()));
+        Smi::Handle(zone_, Smi::New(receiver().GetClassId()));
 
     if (unlinked.can_patch_to_monomorphic()) {
       object = expected_cid.raw();
@@ -1675,8 +1607,7 @@
 
   // Return the ICData. The miss stub will jump to continue in the IC lookup
   // stub.
-  arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-  arguments_.SetReturn(ic_data);
+  ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
 }
 
 bool PatchableCallHandler::CanExtendSingleTargetRange(
@@ -1689,14 +1620,14 @@
     return false;
   }
   intptr_t unchecked_lower, unchecked_upper;
-  if (receiver_.GetClassId() < *lower) {
-    unchecked_lower = receiver_.GetClassId();
+  if (receiver().GetClassId() < *lower) {
+    unchecked_lower = receiver().GetClassId();
     unchecked_upper = *lower - 1;
-    *lower = receiver_.GetClassId();
+    *lower = receiver().GetClassId();
   } else {
-    unchecked_upper = receiver_.GetClassId();
+    unchecked_upper = receiver().GetClassId();
     unchecked_lower = *upper + 1;
-    *upper = receiver_.GetClassId();
+    *upper = receiver().GetClassId();
   }
 
   return IsSingleTarget(isolate_, zone_, unchecked_lower, unchecked_upper,
@@ -1724,30 +1655,6 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-static FunctionPtr Resolve(Thread* thread,
-                           Zone* zone,
-                           const Class& receiver_class,
-                           const String& name,
-                           const Array& descriptor) {
-  ASSERT(name.IsSymbol());
-  Function& target_function = Function::Handle(zone);
-
-  if (receiver_class.EnsureIsFinalized(thread) == Error::null()) {
-    ArgumentsDescriptor args_desc(descriptor);
-    target_function = Resolver::ResolveDynamicForReceiverClass(receiver_class,
-                                                               name, args_desc);
-  }
-
-  if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(receiver_class, descriptor, name);
-    if (target_function.IsNull()) {
-      ASSERT(!FLAG_lazy_dispatchers);
-    }
-  }
-
-  return target_function.raw();
-}
-
 #if defined(DART_PRECOMPILED_RUNTIME)
 void PatchableCallHandler::DoMonomorphicMissAOT(
     const Object& data,
@@ -1759,12 +1666,12 @@
     RELEASE_ASSERT(data.IsMonomorphicSmiableCall());
     old_expected_cid = MonomorphicSmiableCall::Cast(data).expected_cid();
   }
-  const bool is_monomorphic_hit = old_expected_cid == receiver_.GetClassId();
+  const bool is_monomorphic_hit = old_expected_cid == receiver().GetClassId();
   const auto& old_receiver_class =
       Class::Handle(zone_, isolate_->class_table()->At(old_expected_cid));
   const auto& old_target = Function::Handle(
-      zone_,
-      Resolve(thread_, zone_, old_receiver_class, name_, args_descriptor_));
+      zone_, Resolve(thread_, zone_, caller_arguments_, old_receiver_class,
+                     name_, args_descriptor_));
 
   const auto& ic_data = ICData::Handle(
       zone_, old_target.IsNull()
@@ -1774,8 +1681,7 @@
   if (is_monomorphic_hit) {
     // The site just have been updated to monomorphic state with same
     // exact class id - do nothing in that case: stub will call through ic data.
-    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-    arguments_.SetReturn(ic_data);
+    ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
     return;
   }
 
@@ -1795,8 +1701,7 @@
                                        stub);
     // Return the ICData. The miss stub will jump to continue in the IC call
     // stub.
-    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-    arguments_.SetReturn(ic_data);
+    ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
     return;
   }
 
@@ -1807,8 +1712,7 @@
 
   // Return the ICData. The miss stub will jump to continue in the IC lookup
   // stub.
-  arguments_.SetArgAt(0, stub);
-  arguments_.SetReturn(ic_data);
+  ReturnAOT(stub, ic_data);
 }
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
@@ -1833,15 +1737,12 @@
                  caller_frame_->pc(), ic_data.ToCString());
   }
 
-  // Don't count during insertion because the IC stub we continue through will
-  // do an increment.
-  GrowableArray<const Instance*> args(1);
-  args.Add(&receiver_);
-  InlineCacheMissHandlerGivenTargetFunction(args, ic_data, /*count=*/0,
-                                            target_function);
-
-  arguments_.SetArgAt(0, stub);
-  arguments_.SetReturn(ic_data);
+  ASSERT(caller_arguments_.length() == 1);
+  UpdateICDataWithTarget(ic_data, target_function);
+  ASSERT(should_consider_patching());
+  TrySwitchInstanceCall(thread_, caller_frame_, caller_code_, caller_function_,
+                        ic_data, target_function);
+  ReturnJIT(stub, ic_data, target_function);
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
@@ -1858,7 +1759,7 @@
       zone_,
       target_function.IsNull()
           ? NewICData()
-          : NewICDataWithTarget(receiver_.GetClassId(), target_function));
+          : NewICDataWithTarget(receiver().GetClassId(), target_function));
 
   intptr_t lower = data.lower_limit();
   intptr_t upper = data.upper_limit();
@@ -1868,8 +1769,7 @@
     data.set_upper_limit(upper);
     // Return the ICData. The single target stub will jump to continue in the
     // IC call stub.
-    arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-    arguments_.SetReturn(ic_data);
+    ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
     return;
   }
 
@@ -1880,8 +1780,7 @@
 
   // Return the ICData. The single target stub will jump to continue in the
   // IC call stub.
-  arguments_.SetArgAt(0, stub);
-  arguments_.SetReturn(ic_data);
+  ReturnAOT(stub, ic_data);
 }
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
@@ -1889,7 +1788,7 @@
 void PatchableCallHandler::DoICDataMissAOT(const ICData& ic_data,
                                            const Function& target_function) {
   const String& name = String::Handle(zone_, ic_data.target_name());
-  const Class& cls = Class::Handle(zone_, receiver_.clazz());
+  const Class& cls = Class::Handle(zone_, receiver().clazz());
   ASSERT(!cls.IsNull());
   const Array& descriptor =
       Array::CheckedHandle(zone_, ic_data.arguments_descriptor());
@@ -1900,8 +1799,7 @@
   }
 
   if (target_function.IsNull()) {
-    arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
-    arguments_.SetReturn(ic_data);
+    ReturnAOT(StubCode::NoSuchMethodDispatcher(), ic_data);
     return;
   }
 
@@ -1919,14 +1817,13 @@
     const Code& target_code =
         Code::Handle(zone_, target_function.EnsureHasCode());
     const Smi& expected_cid =
-        Smi::Handle(zone_, Smi::New(receiver_.GetClassId()));
+        Smi::Handle(zone_, Smi::New(receiver().GetClassId()));
     ASSERT(target_code.HasMonomorphicEntry());
     CodePatcher::PatchSwitchableCallAt(caller_frame_->pc(), caller_code_,
                                        expected_cid, target_code);
-    arguments_.SetArgAt(0, target_code);
-    arguments_.SetReturn(expected_cid);
+    ReturnAOT(target_code, expected_cid);
   } else {
-    ic_data.EnsureHasReceiverCheck(receiver_.GetClassId(), target_function);
+    ic_data.EnsureHasReceiverCheck(receiver().GetClassId(), target_function);
     if (number_of_checks > FLAG_max_polymorphic_checks) {
       // Switch to megamorphic call.
       const MegamorphicCache& cache = MegamorphicCache::Handle(
@@ -1935,20 +1832,60 @@
 
       CodePatcher::PatchSwitchableCallAt(caller_frame_->pc(), caller_code_,
                                          cache, stub);
-      arguments_.SetArgAt(0, stub);
-      arguments_.SetReturn(cache);
+      ReturnAOT(stub, cache);
     } else {
-      arguments_.SetArgAt(0, StubCode::ICCallThroughCode());
-      arguments_.SetReturn(ic_data);
+      ReturnAOT(StubCode::ICCallThroughCode(), ic_data);
     }
   }
 }
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+void PatchableCallHandler::DoICDataMissJIT(const ICData& ic_data,
+                                           const Object& old_code,
+                                           const Function& target_function) {
+  ASSERT(ic_data.NumArgsTested() == caller_arguments_.length());
+
+  if (ic_data.NumArgsTested() == 1) {
+    ASSERT(old_code.raw() == StubCode::OneArgCheckInlineCache().raw() ||
+           old_code.raw() ==
+               StubCode::OneArgCheckInlineCacheWithExactnessCheck().raw() ||
+           old_code.raw() ==
+               StubCode::OneArgOptimizedCheckInlineCache().raw() ||
+           old_code.raw() ==
+               StubCode::OneArgOptimizedCheckInlineCacheWithExactnessCheck()
+                   .raw() ||
+           old_code.raw() == StubCode::ICCallBreakpoint().raw() ||
+           (old_code.IsNull() && !should_consider_patching()));
+    UpdateICDataWithTarget(ic_data, target_function);
+    if (should_consider_patching()) {
+      TrySwitchInstanceCall(thread_, caller_frame_, caller_code_,
+                            caller_function_, ic_data, target_function);
+    }
+    const Code& stub = Code::Handle(
+        zone_, ic_data.is_tracking_exactness()
+                   ? StubCode::OneArgCheckInlineCacheWithExactnessCheck().raw()
+                   : StubCode::OneArgCheckInlineCache().raw());
+    ReturnJIT(stub, ic_data, target_function);
+  } else {
+    ASSERT(old_code.raw() == StubCode::TwoArgsCheckInlineCache().raw() ||
+           old_code.raw() == StubCode::SmiAddInlineCache().raw() ||
+           old_code.raw() == StubCode::SmiLessInlineCache().raw() ||
+           old_code.raw() == StubCode::SmiEqualInlineCache().raw() ||
+           old_code.raw() ==
+               StubCode::TwoArgsOptimizedCheckInlineCache().raw() ||
+           old_code.raw() == StubCode::ICCallBreakpoint().raw() ||
+           (old_code.IsNull() && !should_consider_patching()));
+    UpdateICDataWithTarget(ic_data, target_function);
+    ReturnJIT(StubCode::TwoArgsCheckInlineCache(), ic_data, target_function);
+  }
+}
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 void PatchableCallHandler::DoMegamorphicMiss(const MegamorphicCache& data,
                                              const Function& target_function) {
   const String& name = String::Handle(zone_, data.target_name());
-  const Class& cls = Class::Handle(zone_, receiver_.clazz());
+  const Class& cls = Class::Handle(zone_, receiver().clazz());
   ASSERT(!cls.IsNull());
   const Array& descriptor =
       Array::CheckedHandle(zone_, data.arguments_descriptor());
@@ -1958,18 +1895,83 @@
                  cls.ToCString(), args_desc.TypeArgsLen(), name.ToCString());
   }
   if (target_function.IsNull()) {
-    arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
-    arguments_.SetReturn(data);
+    ReturnJITorAOT(StubCode::NoSuchMethodDispatcher(), data, target_function);
     return;
   }
 
   // Insert function found into cache.
   const Smi& class_id = Smi::Handle(zone_, Smi::New(cls.id()));
   data.EnsureContains(class_id, target_function);
-  arguments_.SetArgAt(0, StubCode::MegamorphicCall());
+  ReturnJITorAOT(StubCode::MegamorphicCall(), data, target_function);
+}
+
+void PatchableCallHandler::UpdateICDataWithTarget(
+    const ICData& ic_data,
+    const Function& target_function) {
+  if (target_function.IsNull()) return;
+
+  // If, upon return of the runtime, we will invoke the target directly we have
+  // to increment the call count here in the ICData.
+  // If we instead only insert a new ICData entry and will return to the IC stub
+  // which will call the target, the stub will take care of the increment.
+  const bool call_target_directly =
+      miss_handler_ == MissHandler::kInlineCacheMiss;
+  const intptr_t invocation_count = call_target_directly ? 1 : 0;
+
+  if (caller_arguments_.length() == 1) {
+    auto exactness = StaticTypeExactnessState::NotTracking();
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    if (ic_data.is_tracking_exactness()) {
+      exactness = receiver().IsNull()
+                      ? StaticTypeExactnessState::NotExact()
+                      : StaticTypeExactnessState::Compute(
+                            Type::Cast(AbstractType::Handle(
+                                ic_data.receivers_static_type())),
+                            receiver());
+    }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+    ic_data.EnsureHasReceiverCheck(receiver().GetClassId(), target_function,
+                                   invocation_count, exactness);
+  } else {
+    GrowableArray<intptr_t> class_ids(caller_arguments_.length());
+    ASSERT(ic_data.NumArgsTested() == caller_arguments_.length());
+    for (intptr_t i = 0; i < caller_arguments_.length(); i++) {
+      class_ids.Add(caller_arguments_[i]->GetClassId());
+    }
+    ic_data.EnsureHasCheck(class_ids, target_function, invocation_count);
+  }
+}
+
+void PatchableCallHandler::ReturnAOT(const Code& stub, const Object& data) {
+  ASSERT(miss_handler_ == MissHandler::kSwitchableCallMiss);
+  arguments_.SetArgAt(0, stub);  // Second return value.
   arguments_.SetReturn(data);
 }
 
+void PatchableCallHandler::ReturnJIT(const Code& stub,
+                                     const Object& data,
+                                     const Function& target) {
+  // In JIT we can have two different miss handlers to which we return slightly
+  // differently.
+  if (miss_handler_ == MissHandler::kSwitchableCallMiss) {
+    arguments_.SetArgAt(0, stub);  // Second return value.
+    arguments_.SetReturn(data);
+  } else {
+    ASSERT(miss_handler_ == MissHandler::kInlineCacheMiss);
+    arguments_.SetReturn(target);
+  }
+}
+
+void PatchableCallHandler::ReturnJITorAOT(const Code& stub,
+                                          const Object& data,
+                                          const Function& target) {
+#if defined(DART_PRECOMPILED_MODE)
+  ReturnAOT(stub, data);
+#else
+  ReturnJIT(stub, data, target);
+#endif
+}
+
 ICDataPtr PatchableCallHandler::NewICData() {
   return ICData::New(caller_function_, name_, args_descriptor_, DeoptId::kNone,
                      /*num_args_tested=*/1, ICData::kInstance);
@@ -2045,8 +2047,43 @@
     default:
       UNREACHABLE();
   }
-  const Class& cls = Class::Handle(zone_, receiver_.clazz());
-  return Resolve(thread_, zone_, cls, name_, args_descriptor_);
+  const Class& cls = Class::Handle(zone_, receiver().clazz());
+  return Resolve(thread_, zone_, caller_arguments_, cls, name_,
+                 args_descriptor_);
+}
+
+void PatchableCallHandler::ResolveSwitchAndReturn(const Object& old_data) {
+  // Find out actual target (which can be time consuminmg) without holding any
+  // locks.
+  const auto& target_function =
+      Function::Handle(zone_, ResolveTargetFunction(old_data));
+
+  auto& code = Code::Handle(zone_);
+  auto& data = Object::Handle(zone_);
+
+  // We ensure any transition in a patchable calls are done in an atomic
+  // manner, we ensure we always transition forward (e.g. Monomorphic ->
+  // Polymorphic).
+  //
+  // Mutators are only stopped if we actually need to patch a patchable call.
+  // We may not do that if we e.g. just add one more check to an ICData.
+  SafepointMutexLocker ml(thread_->isolate_group()->patchable_call_mutex());
+
+#if defined(DART_PRECOMPILED_RUNTIME)
+  data =
+      CodePatcher::GetSwitchableCallDataAt(caller_frame_->pc(), caller_code_);
+  DEBUG_ONLY(code = CodePatcher::GetSwitchableCallTargetAt(caller_frame_->pc(),
+                                                           caller_code_));
+#else
+  if (should_consider_patching()) {
+    code ^= CodePatcher::GetInstanceCallAt(caller_frame_->pc(), caller_code_,
+                                           &data);
+  } else {
+    ASSERT(old_data.IsICData() || old_data.IsMegamorphicCache());
+    data = old_data.raw();
+  }
+#endif
+  HandleMiss(data, code, target_function);
 }
 
 void PatchableCallHandler::HandleMiss(const Object& old_data,
@@ -2079,13 +2116,12 @@
       DoMonomorphicMissJIT(old_data, target_function);
       break;
     case kICDataCid:
-      // Right now ICData misses wil go to the normal ICData miss handler, not
-      // to SwitchableCall miss handler.
-      UNREACHABLE();
+      DoICDataMissJIT(ICData::Cast(old_data), old_code, target_function);
       break;
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
     case kMegamorphicCacheCid:
-      ASSERT(old_code.raw() == StubCode::MegamorphicCall().raw());
+      ASSERT(old_code.raw() == StubCode::MegamorphicCall().raw() ||
+             (old_code.IsNull() && !should_consider_patching()));
       DoMegamorphicMiss(MegamorphicCache::Cast(old_data), target_function);
       break;
     default:
@@ -2093,6 +2129,60 @@
   }
 }
 
+static void InlineCacheMissHandler(Thread* thread,
+                                   Zone* zone,
+                                   const GrowableArray<const Instance*>& args,
+                                   const ICData& ic_data,
+                                   NativeArguments native_arguments) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  DartFrameIterator iterator(thread,
+                             StackFrameIterator::kNoCrossThreadIteration);
+  StackFrame* caller_frame = iterator.NextFrame();
+  const auto& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
+  const auto& caller_function =
+      Function::Handle(zone, caller_frame->LookupDartFunction());
+
+  PatchableCallHandler handler(thread, args, MissHandler::kInlineCacheMiss,
+                               native_arguments, caller_frame, caller_code,
+                               caller_function);
+
+  handler.ResolveSwitchAndReturn(ic_data);
+#else
+  UNREACHABLE();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+}
+
+// Handles inline cache misses by updating the IC data array of the call site.
+//   Arg0: Receiver object.
+//   Arg1: IC data object.
+//   Returns: target function with compiled code or null.
+// Modifies the instance call to hold the updated IC data array.
+DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) {
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+  const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(1));
+  RELEASE_ASSERT(!FLAG_precompiled_mode);
+  GrowableArray<const Instance*> args(1);
+  args.Add(&receiver);
+  InlineCacheMissHandler(thread, zone, args, ic_data, arguments);
+}
+
+// Handles inline cache misses by updating the IC data array of the call site.
+//   Arg0: Receiver object.
+//   Arg1: Argument after receiver.
+//   Arg2: IC data object.
+//   Returns: target function with compiled code or null.
+// Modifies the instance call to hold the updated IC data array.
+DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) {
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+  const Instance& other = Instance::CheckedHandle(zone, arguments.ArgAt(1));
+  const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(2));
+  RELEASE_ASSERT(!FLAG_precompiled_mode);
+  GrowableArray<const Instance*> args(2);
+  args.Add(&receiver);
+  args.Add(&other);
+  InlineCacheMissHandler(thread, zone, args, ic_data, arguments);
+}
+
 // Handle the first use of an instance call
 //   Arg1: Receiver.
 //   Arg0: Stub out.
@@ -2116,42 +2206,20 @@
   const Function& caller_function =
       Function::Handle(zone, caller_frame->LookupDartFunction());
 
-  PatchableCallHandler handler(thread, receiver, arguments, caller_frame,
-                               caller_code, caller_function);
-
-  // Find out actual target (which can be time consuminmg) without holding any
-  // locks.
-  Object& old_data = Object::Handle(zone);
+  auto& old_data = Object::Handle(zone);
 #if defined(DART_PRECOMPILED_RUNTIME)
   old_data =
       CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code);
 #else
   CodePatcher::GetInstanceCallAt(caller_frame->pc(), caller_code, &old_data);
 #endif
-  const Function& target_function =
-      Function::Handle(zone, handler.ResolveTargetFunction(old_data));
 
-  {
-    // We ensure any transition in a patchable calls are done in an atomic
-    // manner, we ensure we always transition forward (e.g. Monomorphic ->
-    // Polymorphic).
-    //
-    // Mutators are only stopped if we actually need to patch a patchable call.
-    // We may not do that if we e.g. just add one more check to an ICData.
-    SafepointMutexLocker ml(thread->isolate_group()->patchable_call_mutex());
-
-    auto& old_code = Code::Handle(zone);
-#if defined(DART_PRECOMPILED_RUNTIME)
-    old_data =
-        CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code);
-    DEBUG_ONLY(old_code = CodePatcher::GetSwitchableCallTargetAt(
-                   caller_frame->pc(), caller_code));
-#else
-    old_code ^= CodePatcher::GetInstanceCallAt(caller_frame->pc(), caller_code,
-                                               &old_data);
-#endif
-    handler.HandleMiss(old_data, old_code, target_function);
-  }
+  GrowableArray<const Instance*> caller_arguments(1);
+  caller_arguments.Add(&receiver);
+  PatchableCallHandler handler(thread, caller_arguments,
+                               MissHandler::kSwitchableCallMiss, arguments,
+                               caller_frame, caller_code, caller_function);
+  handler.ResolveSwitchAndReturn(old_data);
 }
 
 // Used to find the correct receiver and function to invoke or to fall back to
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 84f5495..3f074ff 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -565,6 +565,19 @@
 
     // Visit all closures for this isolate.
     VisitClosures(&ranges);
+
+    // Output constant coverage if coverage is requested.
+    if (IsReportRequested(kCoverage)) {
+      // Find all scripts. We need to go though all scripts because a script
+      // (even one we don't want) can add coverage to another library (i.e.
+      // potentially one we want).
+      DirectChainedHashMap<ScriptTableTrait> local_script_table;
+      GrowableArray<ScriptTableEntry*> local_script_table_entries;
+      CollectAllScripts(&local_script_table, &local_script_table_entries);
+      CollectConstConstructorCoverageFromScripts(&local_script_table_entries,
+                                                 &ranges);
+      CleanupCollectedScripts(&local_script_table, &local_script_table_entries);
+    }
   }
 
   // Print the script table.
@@ -572,5 +585,102 @@
   PrintScriptTable(&scripts);
 }
 
+void SourceReport::CollectAllScripts(
+    DirectChainedHashMap<ScriptTableTrait>* local_script_table,
+    GrowableArray<ScriptTableEntry*>* local_script_table_entries) {
+  ScriptTableEntry wrapper;
+  const GrowableObjectArray& libs = GrowableObjectArray::Handle(
+      zone(), thread()->isolate()->object_store()->libraries());
+  Library& lib = Library::Handle(zone());
+  Script& scriptRef = Script::Handle(zone());
+  for (int i = 0; i < libs.Length(); i++) {
+    lib ^= libs.At(i);
+    const Array& scripts = Array::Handle(zone(), lib.LoadedScripts());
+    for (intptr_t j = 0; j < scripts.Length(); j++) {
+      scriptRef ^= scripts.At(j);
+      const String& url = String::Handle(zone(), scriptRef.url());
+      wrapper.key = &url;
+      wrapper.script = &Script::Handle(zone(), scriptRef.raw());
+      ScriptTableEntry* pair = local_script_table->LookupValue(&wrapper);
+      if (pair != NULL) {
+        // Existing one.
+        continue;
+      }
+      // New one. Insert.
+      ScriptTableEntry* tmp = new ScriptTableEntry();
+      tmp->key = &url;
+      tmp->index = next_script_index_++;
+      tmp->script = wrapper.script;
+      local_script_table_entries->Add(tmp);
+      local_script_table->Insert(tmp);
+    }
+  }
+}
+
+void SourceReport::CleanupCollectedScripts(
+    DirectChainedHashMap<ScriptTableTrait>* local_script_table,
+    GrowableArray<ScriptTableEntry*>* local_script_table_entries) {
+  for (intptr_t i = 0; i < local_script_table_entries->length(); i++) {
+    delete local_script_table_entries->operator[](i);
+    local_script_table_entries->operator[](i) = NULL;
+  }
+  local_script_table_entries->Clear();
+  local_script_table->Clear();
+}
+
+void SourceReport::CollectConstConstructorCoverageFromScripts(
+    GrowableArray<ScriptTableEntry*>* local_script_table_entries,
+    JSONArray* ranges) {
+  // Now output the wanted constant coverage.
+  for (intptr_t i = 0; i < local_script_table_entries->length(); i++) {
+    const Script* script = local_script_table_entries->At(i)->script;
+    bool script_ok = true;
+    if (script_ != NULL && !script_->IsNull()) {
+      if (script->raw() != script_->raw()) {
+        // This is the wrong script.
+        script_ok = false;
+      }
+    }
+
+    // Whether we want *this* script or not we need to look at the constant
+    // constructor coverage. Any of those could be in a script we *do* want.
+    {
+      Script& scriptRef = Script::Handle(zone());
+      const Array& constructors =
+          Array::Handle(kernel::CollectConstConstructorCoverageFrom(*script));
+      intptr_t constructors_count = constructors.Length();
+      Function& constructor = Function::Handle(zone());
+      Code& code = Code::Handle(zone());
+      for (intptr_t i = 0; i < constructors_count; i++) {
+        constructor ^= constructors.At(i);
+        // Check if we want coverage for this constructor.
+        if (ShouldSkipFunction(constructor)) {
+          continue;
+        }
+        scriptRef ^= constructor.script();
+        code ^= constructor.unoptimized_code();
+        const TokenPosition begin_pos = constructor.token_pos();
+        const TokenPosition end_pos = constructor.end_token_pos();
+        JSONObject range(ranges);
+        range.AddProperty("scriptIndex", GetScriptIndex(scriptRef));
+        range.AddProperty("compiled",
+                          !code.IsNull());  // Does this make a difference?
+        range.AddProperty("startPos", begin_pos);
+        range.AddProperty("endPos", end_pos);
+
+        JSONObject cov(&range, "coverage");
+        {
+          JSONArray hits(&cov, "hits");
+          hits.AddValue(begin_pos);
+        }
+        {
+          JSONArray misses(&cov, "misses");
+          // No misses
+        }
+      }
+    }
+  }
+}
+
 }  // namespace dart
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 0a3ddb1..4ec20c9 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -112,6 +112,18 @@
     }
   };
 
+  void CollectAllScripts(
+      DirectChainedHashMap<ScriptTableTrait>* local_script_table,
+      GrowableArray<ScriptTableEntry*>* local_script_table_entries);
+
+  void CleanupCollectedScripts(
+      DirectChainedHashMap<ScriptTableTrait>* local_script_table,
+      GrowableArray<ScriptTableEntry*>* local_script_table_entries);
+
+  void CollectConstConstructorCoverageFromScripts(
+      GrowableArray<ScriptTableEntry*>* local_script_table_entries,
+      JSONArray* ranges);
+
   intptr_t report_set_;
   CompileMode compile_mode_;
   Thread* thread_;
diff --git a/tools/VERSION b/tools/VERSION
index aa43b14..679ae2d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 131
+PRERELEASE 132
 PRERELEASE_PATCH 0
\ No newline at end of file
