anchor.diff:        filename = arg;
       }
     }
  +  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.";
  -
  -  await tryToMinimize(file, nnbd);
  -}
  -
  -Future tryToMinimize(File file, bool nnbd) async {
  -  Uint8List data;
  -  try {
  -    String parsedString = getFileAsStringContent(file, nnbd);
  -    data = utf8.encode(parsedString);
  -  } catch (e) {
  -    // If this crash it's a crash in the scanner/parser. It's good to minimize
  -    // that too.
  -    data = file.readAsBytesSync();
  -  }
  -
  -  print("Got data");
  -
  -  Uri main = base.resolve("main.dart");
  -
  -  CompilerContext compilerContext = setupCompilerContext(main);
  -  Component initialComponent = await getInitialComponent(compilerContext);
  -  MemoryFileSystem fs = compilerContext.options.fileSystem;
  -
  +  mainUri = file.absolute.uri;
  +
  +  await tryToMinimize();
  +}
  +
  +Future tryToMinimize() 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);
   
     // First assure it actually crash on the input.
  -  if (!await crashesOnCompile(
  -      fs, main, data, compilerContext, initialComponent)) {
  -    throw "Input doesn't crash the compiler: ${dataToText(data)}";
  +  if (!await crashesOnCompile(initialComponent)) {
  +    throw "Input doesn't crash the compiler.";
     }
     print("Step #1: We did crash on the input!");
   
  -  // Try to delete lines.
  -  Uint8List latestCrashData =
  -      await deleteLines(data, fs, main, compilerContext, initialComponent);
  -  print("We're now at ${latestCrashData.length} bytes.");
  -
  -  // Now try to delete 'arbitrarily' (for any given start offset do an
  -  // exponential binary search).
  -  int prevLength = latestCrashData.length;
  -  while (true) {
  -    latestCrashData = await binarySearchDeleteData(
  -        latestCrashData, fs, main, compilerContext, initialComponent);
  -
  -    if (latestCrashData.length == prevLength) {
  -      // No progress.
  -      break;
  +  // 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) {
  +    String uriString = uri.toString();
  +    if (uriString.endsWith(".json") ||
  +        uriString.endsWith(".json") ||
  +        uriString.endsWith(".packages") ||
  +        uriString.endsWith(".dill") ||
  +        fs.data[uri] == null ||
  +        fs.data[uri].isEmpty) {
  +      // skip
       } else {
  -      print("We're now at ${latestCrashData.length} bytes");
  -      prevLength = latestCrashData.length;
  -    }
  -  }
  -
  -  print("Got it down to ${latestCrashData.length} bytes: "
  -      "${dataToText(latestCrashData)}");
  -  try {
  -    String utfDecoded = utf8.decode(latestCrashData, allowMalformed: true);
  -    print("That's '$utfDecoded' as text");
  -  } catch (e) {
  -    print("(which crashes when trying to decode as utf8)");
  +      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);
  +
  +  bool removedSome = true;
  +  while (removedSome) {
  +    while (removedSome) {
  +      removedSome = false;
  +      for (int i = 0; i < uris.length; i++) {
  +        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) removedSome = 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;
  +
  +      print("Now working on $uri");
  +
  +      // Try to delete lines.
  +      int prevLength = fs.data[uri].length;
  +      await deleteLines(uri, initialComponent);
  +      print("We're now at ${fs.data[uri].length} bytes for $uri.");
  +      if (prevLength != fs.data[uri].length) removedSome = 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) {
  +          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;
  +            removedSome = true;
  +          }
  +        }
  +      }
  +    }
  +  }
  +
  +  print("\n\nDONE\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");
     }
   }
   
  
positive.code:   }
    lines.add(sublist(data, start, data.length));
    List<bool> include = new List.filled(lines.length, true);
    for (int i = 0; i < lines.length; i++) {
      include[i] = false;
      final BytesBuilder builder = new BytesBuilder();
      for (int j = 0; j < lines.length; j++) {
        if (include[j]) {
  
negative.code:     enableTripleShift: true,
      enableExtensionMethods: true,
      enableNonNullable: false);
  
  class FakeFileSystem extends FileSystem {
    bool _redirectAndRecord = true;
    final Map<Uri, Uint8List> data = {};
  
    @override
    FileSystemEntity entityForUri(Uri uri) {
      return new FakeFileSystemEntity(this, uri);
    }
  }
  
  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._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));
    }
  }
  