/**
   * Scan all output dirs for artifacts and remove those files (artifacts?) that are not recognized
   * as such, in the javac_state file.
   */
  public void removeUnidentifiedArtifacts() {
    Set<File> allKnownArtifacts = new HashSet<>();
    for (Package pkg : prev.packages().values()) {
      for (File f : pkg.artifacts().values()) {
        allKnownArtifacts.add(f);
      }
    }
    // Do not forget about javac_state....
    allKnownArtifacts.add(javacState);

    for (File f : binArtifacts) {
      if (!allKnownArtifacts.contains(f)) {
        Log.debug("Removing " + f.getPath() + " since it is unknown to the javac_state.");
        f.delete();
      }
    }
    for (File f : headerArtifacts) {
      if (!allKnownArtifacts.contains(f)) {
        Log.debug("Removing " + f.getPath() + " since it is unknown to the javac_state.");
        f.delete();
      }
    }
    for (File f : gensrcArtifacts) {
      if (!allKnownArtifacts.contains(f)) {
        Log.debug("Removing " + f.getPath() + " since it is unknown to the javac_state.");
        f.delete();
      }
    }
  }
 /** Lookup the artifacts generated for this package in the previous build. */
 private Map<String, File> fetchPrevArtifacts(String pkg) {
   Package p = prev.packages().get(pkg);
   if (p != null) {
     return p.artifacts();
   }
   return new HashMap<>();
 }
 /**
  * Propagate recompilation through the dependency chains. Avoid re-tainting packages that have
  * already been compiled.
  */
 public void taintPackagesDependingOnChangedPackages(
     Set<String> pkgs, Set<String> recentlyCompiled) {
   for (Package pkg : prev.packages().values()) {
     for (String dep : pkg.dependencies()) {
       if (pkgs.contains(dep) && !recentlyCompiled.contains(pkg.name())) {
         taintPackage(pkg.name(), " its depending on " + dep);
       }
     }
   }
 }
 /** If artifacts have gone missing, force a recompile of the packages they belong to. */
 public void taintPackagesThatMissArtifacts() {
   for (Package pkg : prev.packages().values()) {
     for (File f : pkg.artifacts().values()) {
       if (!f.exists()) {
         // Hmm, the artifact on disk does not exist! Someone has removed it....
         // Lets rebuild the package.
         taintPackage(pkg.name(), "" + f + " is missing.");
       }
     }
   }
 }
 /** Mark a java package as tainted, ie it needs recompilation. */
 public void taintPackage(String name, String because) {
   if (!taintedPackages.contains(name)) {
     if (because != null)
       Log.debug("Tainting " + Util.justPackageName(name) + " because " + because);
     // It has not been tainted before.
     taintedPackages.add(name);
     needsSaving();
     Package nowp = now.packages().get(name);
     if (nowp != null) {
       for (String d : nowp.dependents()) {
         taintPackage(d, because);
       }
     }
   }
 }
  /** Remove artifacts that are no longer produced when compiling! */
  public void removeSuperfluousArtifacts(Set<String> recentlyCompiled) {
    // Nothing to do, if nothing was recompiled.
    if (recentlyCompiled.size() == 0) return;

    for (String pkg : now.packages().keySet()) {
      // If this package has not been recompiled, skip the check.
      if (!recentlyCompiled.contains(pkg)) continue;
      Collection<File> arts = now.artifacts().values();
      for (File f : fetchPrevArtifacts(pkg).values()) {
        if (!arts.contains(f)) {
          Log.debug("Removing " + f.getPath() + " since it is now superfluous!");
          if (f.exists()) f.delete();
        }
      }
    }
  }