anchor.diff:      print("Selected bot: $bot");
     }
   
  +  // Error out if any of the requested try runs are incomplete.
  +  bool anyIncomplete = false;
  +  for (final bot in bots) {
  +    if (options["preapprove"] != null &&
  +        changelistBuilds[bot]["status"] != "COMPLETED") {
  +      stderr.writeln("error: The try run for $bot isn't complete yet" +
  +          changelistBuilds[bot]["status"]);
  +      anyIncomplete = true;
  +    }
  +  }
  +  if (anyIncomplete) {
  +    exitCode = 1;
  +    return;
  +  }
  +
     // Load all the latest results for the selected bots, as well as flakiness
     // data, and the set of currently approved results. Each bot's latest build
     // is downloaded in parallel to make this phase faster.
     final testListFutures = <Future>[];
     for (final String bot in bots) {
  -    testListFutures.add(loadResultsFromBot(bot, options));
  +    testListFutures
  +        .add(loadResultsFromBot(bot, options, changelistBuilds[bot]));
     }
   
     // Collect all the tests from the synchronous downloads.
  
positive.code:       abbr: "n",
        help: "Show changed results but don't approve.",
        negatable: false);
    parser.addFlag("verbose",
        abbr: "v", help: "Describe asynchronous operations.", negatable: false);
    parser.addFlag("yes",
        abbr: "y", help: "Approve the results.", negatable: false);
  
    final options = parser.parse(args);
    if ((options["bot"].isEmpty && !options["list"]) || options["help"]) {
      print("""
  Usage: approve_results.dart [OPTION]...
  List tests whose results are different from the previously approved results, and
  
negative.code:       final result = results[key];
        final approvedResult = approvedResults[key];
        final flakiness = flaky[key];
        // If preapproving results, allow new non-matching results that are
        // different from the baseline. The approved results will be the current
        // approved results, plus the difference between the tryrun's baseline and
        // the tryrun's results.
        if (tryResults.containsKey(key)) {
          final tryResult = tryResults[key];
          final wasFlake = flakiness != null &&
              (flakiness["outcomes"] as List<dynamic>)
                  .contains(tryResult["result"]);
          // Pick the try run result if the try result was not a flake and it's a
          // non-matching result that's different than the approved result. If
          // there is no approved result yet, use the latest result from the
          // builder instead.
          final baseResult = approvedResult ?? result;
          if ((!wasFlake &&
              !tryResult["matches"] &&
              tryResult["result"] != result["result"])) {
            // The approved_results.json format currently does not natively
            // support preapproval, so preapproving turning one failure into
            // another will turn the builder in question red until the CL lands.
            if (!baseResult["matches"]) {
              print("Warning: Preapproving changed failure modes will turn the "
                  "CI red until the CL is submitted: $bot: $key: "
                  "${baseResult["result"]} -> ${tryResult["result"]}");
            }
            result.clear();
            result.addAll(tryResult);
          } else {
            if (approvedResult != null) {
              result.clear();
              result.addAll(approvedResult);
            }
          }
        } else if (tryResults.isNotEmpty && approvedResult != null) {
          result.clear();
          result.addAll(approvedResult);
        }
        final name = result["name"];
        final test = new Test(bot, name, result, approvedResult, flakiness);
        tests.add(test);
      }
      // If preapproving and the CL has introduced new tests, add the new tests
      // as well to the approved data.
      final newTestKeys = new Set<String>.from(tryResults.keys)
          .difference(new Set<String>.from(results.keys));
      for (final key in newTestKeys) {
        final result = tryResults[key];
        final flakiness = flaky[key];
        final name = result["name"];
        final test = new Test(bot, name, result, null, flakiness);
        tests.add(test);
      }
      if (options["verbose"]) {
  