/**
   * Checks to see if there is a check point. If so, and the checkpoint phaseId does not equal,
   * NO_PHASE_ID, call the necessary opertions to move to the current checkpoint.
   *
   * @param splitter the splitter to see if it implments the interface CheckpointHandler.
   * @param checkpoint the checkpoint object associated with the given feed file.
   * @return true if a move to check point was initiated.
   */
  private Boolean performCheckpoint(Splitter splitter, FeedCheckpoint checkpoint) {
    // Move to checkpoint if splitter is instance of checkpoint
    if (splitter instanceof Checkpointable) {
      // Determine if a checkpoint has been created.
      if (checkpoint != null && !checkpoint.getPhaseId().equals(CheckpointHelper.NO_PHASE_ID)) {
        if (checkpointService != null) checkpointService.beforeCheckpoint();

        ((Checkpointable) splitter).moveToCheckpoint(checkpoint);

        if (checkpointService != null) checkpointService.afterCheckpoint();

        return true;
      }
    }
    return false;
  }
  protected void traversDetailWithCheckpoint(FeedCheckpoint checkpoint) {
    final List<Phase> phases = batchPhaseList;

    // Determine if a checkpoint has been created and if so, move to it.
    Boolean movingToCheckpoint = performCheckpoint(detailSplitter, checkpoint);

    while (detailSplitter.hasNextRow()) {
      for (Phase phase : phases) {
        // Bypass phases processing when restart from a checkpoint.
        if (!movingToCheckpoint) {
          context.setCurrentPhaseId(phase.getName());
          feedJobManager.startPhaseStats(phase, context);
          phase.execute();
          feedJobManager.endPhaseStats(phase, context);
        }

        // Checkpoint restart has be reached.
        if (movingToCheckpoint && checkpoint.getPhaseId().equals(phase.getName())) {
          movingToCheckpoint = false;
        }
      }
    }
  }