private boolean hasJobEnded(Job job) {
    GridProcessState state = job.getState();

    return state.equals(GridProcessState.FAILED)
        || state.equals(GridProcessState.CANCELLED)
        || state.equals(GridProcessState.FINISHED);
  }
  private void updateExecution(
      GridProcess execution, GridProcessState state, List<IResponseTO> responses) {
    try {
      execution
          .getJob()
          .newReplicaResult(
              execution.getResult(),
              state,
              verifyFailure(execution.getTask(), state),
              canReplicate(execution.getTask()));
    } catch (IllegalResultException e) {

      responses.add(
          new LoggerResponseTO(
              "Illegal result on replicaEnded: " + e.getMessage(), LoggerResponseTO.ERROR));
    }

    if (state.equals(GridProcessState.FINISHED)) {
      abortReplicaSisters(execution, responses);
    }

    WorkerEntry workerEntry = execution.getWorkerEntry();
    workerEntry.deallocate();

    if (!isWorkerNeeded(workerEntry, execution)) {
      disposeWorker(workerEntry, responses);
    }
  }
  /* (non-Javadoc)
   * @see org.ourgrid.broker.heuristic.Heuristic#verifyFailure(org.ourgrid.common.job.Task)
   */
  public boolean verifyFailure(Task task, GridProcessState state) {

    int actualFails = task.getActualFails();

    if (state.equals(GridProcessState.FAILED)) {
      actualFails++;
    }

    return actualFails >= maxFails && !task.hasGridProcessInExecution();
  }