/* Helper method to reschedule waiting jobs */
  protected void rescheduleJobs() {
    Collections.sort(waitingQueue, comparator);
    boolean success = true;
    Iterator<Job> it = this.waitingQueue.iterator();
    while (it.hasNext() && success) {
      Job j = it.next();
      if (j.hasReserved()) {
        continue;
      }

      success = super.startJob(j);
      if (success) {
        this.runningQueue.add(j);
        it.remove();
      } else {
        enqueueJob(j);
      }
    }
  }
  @Override
  public void doJobCompletion(Job job) {
    log.trace("Completing job #" + job.getId() + " at " + super.currentTime());

    super.setJobStatus(job, WorkUnit.Status.COMPLETE);
    this.runningQueue.remove(job);

    if (log.isTraceEnabled()) {
      log.trace("Completed job: \n" + job);
    }
    sendJobToOwner(job);
  }
  /**
   * This method iterates the waiting jobs list and for each job, it returns the allocated time slot
   * and resources to the pool.
   *
   * @param time consider jobs whose start time is further than time
   * @return a collection with the IDs of the affected jobs
   */
  protected Collection<Integer> compressSchedule(long time) {
    Collection<Integer> jobIds = new LinkedList<Integer>();
    // jobs with reservation cannot be moved
    ResourcePool rlist = super.serverAttributes().getResourcePool();
    Iterator<Job> it = this.waitingQueue.iterator();
    while (it.hasNext()) {
      Job j = it.next();

      // Skip as it cannot get better than this.
      if (j.getStartTime() <= time || j.hasReserved()) {
        continue;
      }

      long startTime = Math.max(0, j.getStartTime());
      long finishTime = j.getStartTime() + j.getDuration();
      RangeList res = j.getResourceRanges();
      rlist.releaseResources(startTime, finishTime, res);
      jobIds.add(j.getId());
    }

    return jobIds;
  }