/** Load a javac_state file. */
  public static JavacState load(
      String[] args,
      File binDir,
      File gensrcDir,
      File headerDir,
      boolean permitUnidentifiedArtifacts,
      PrintStream out,
      PrintStream err) {
    JavacState db =
        new JavacState(
            args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, false, out, err);
    Module lastModule = null;
    Package lastPackage = null;
    Source lastSource = null;
    boolean noFileFound = false;
    boolean foundCorrectVerNr = false;
    boolean newCommandLine = false;
    boolean syntaxError = false;

    try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) {
      for (; ; ) {
        String l = in.readLine();
        if (l == null) break;
        if (l.length() >= 3 && l.charAt(1) == ' ') {
          char c = l.charAt(0);
          if (c == 'M') {
            lastModule = db.prev.loadModule(l);
          } else if (c == 'P') {
            if (lastModule == null) {
              syntaxError = true;
              break;
            }
            lastPackage = db.prev.loadPackage(lastModule, l);
          } else if (c == 'D') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastPackage.loadDependency(l);
          } else if (c == 'I') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastPackage.loadPubapi(l);
          } else if (c == 'A') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastPackage.loadArtifact(l);
          } else if (c == 'S') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastSource = db.prev.loadSource(lastPackage, l, false);
          } else if (c == 'G') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastSource = db.prev.loadSource(lastPackage, l, true);
          } else if (c == 'R') {
            String ncmdl = "R " + db.theArgs;
            if (!l.equals(ncmdl)) {
              newCommandLine = true;
            }
          } else if (c == '#') {
            if (l.startsWith("# javac_state ver ")) {
              int sp = l.indexOf(" ", 18);
              if (sp != -1) {
                String ver = l.substring(18, sp);
                if (!ver.equals("0.3")) {
                  break;
                }
                foundCorrectVerNr = true;
              }
            }
          }
        }
      }
    } catch (FileNotFoundException e) {
      // Silently create a new javac_state file.
      noFileFound = true;
    } catch (IOException e) {
      Log.info("Dropping old javac_state because of errors when reading it.");
      db =
          new JavacState(
              args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
      foundCorrectVerNr = true;
      newCommandLine = false;
      syntaxError = false;
    }
    if (foundCorrectVerNr == false && !noFileFound) {
      Log.info("Dropping old javac_state since it is of an old version.");
      db =
          new JavacState(
              args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
    } else if (newCommandLine == true && !noFileFound) {
      Log.info("Dropping old javac_state since a new command line is used!");
      db =
          new JavacState(
              args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
    } else if (syntaxError == true) {
      Log.info("Dropping old javac_state since it contains syntax errors.");
      db =
          new JavacState(
              args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
    }
    db.prev.calculateDependents();
    return db;
  }