/** Handle a successful job. */
  private void succeedJob(Job job, long filesSucceeded, long filesFailed) throws IOException {
    String jobName = job.getJobName();
    LOG.info("Job " + job.getID() + "(" + jobName + ") finished (succeeded)");

    if (filesFailed == 0) {
      // no files have failed
      for (CorruptFileInfo fileInfo : jobIndex.get(job)) {
        boolean failed = false;
        fileInfo.finishJob(jobName, failed);
      }
    } else {
      // we have to look at the output to check which files have failed
      Set<String> failedFiles = getFailedFiles(job);

      for (CorruptFileInfo fileInfo : jobIndex.get(job)) {
        if (failedFiles.contains(fileInfo.getFile().toString())) {
          boolean failed = true;
          fileInfo.finishJob(jobName, failed);
        } else {
          // call succeed for files that have succeeded or for which no action
          // was taken
          boolean failed = false;
          fileInfo.finishJob(jobName, failed);
        }
      }
    }
    // report succeeded files to metrics
    incrFilesFixed(filesSucceeded);
    incrFileFixFailures(filesFailed);
    numJobsRunning--;
  }
 /** Handle a failed job. */
 private void failJob(Job job) throws IOException {
   // assume no files have been fixed
   LOG.error("Job " + job.getID() + "(" + job.getJobName() + ") finished (failed)");
   // We do not change metrics here since we do not know for sure if file
   // fixing failed.
   for (CorruptFileInfo fileInfo : jobIndex.get(job)) {
     boolean failed = true;
     fileInfo.finishJob(job.getJobName(), failed);
   }
   numJobsRunning--;
 }