/**
  * Template method for step execution logic
  *
  * @param StepExecution $stepExecution
  *
  * @throws JobInterruptedException
  */
 public final function execute(StepExecution $stepExecution)
 {
     $this->dispatchStepExecutionEvent(EventInterface::BEFORE_STEP_EXECUTION, $stepExecution);
     $stepExecution->setStartTime(new \DateTime());
     $stepExecution->setStatus(new BatchStatus(BatchStatus::STARTED));
     $this->jobRepository->updateStepExecution($stepExecution);
     // Start with a default value that will be trumped by anything
     $exitStatus = new ExitStatus(ExitStatus::EXECUTING);
     try {
         $this->doExecute($stepExecution);
         $exitStatus = new ExitStatus(ExitStatus::COMPLETED);
         $exitStatus->logicalAnd($stepExecution->getExitStatus());
         $this->jobRepository->updateStepExecution($stepExecution);
         // Check if someone is trying to stop us
         if ($stepExecution->isTerminateOnly()) {
             throw new JobInterruptedException("JobExecution interrupted.");
         }
         // Need to upgrade here not set, in case the execution was stopped
         $stepExecution->upgradeStatus(BatchStatus::COMPLETED);
         $this->dispatchStepExecutionEvent(EventInterface::STEP_EXECUTION_SUCCEEDED, $stepExecution);
     } catch (\Exception $e) {
         $stepExecution->upgradeStatus($this->determineBatchStatus($e));
         $exitStatus = $exitStatus->logicalAnd($this->getDefaultExitStatusForFailure($e));
         $stepExecution->addFailureException($e);
         $this->jobRepository->updateStepExecution($stepExecution);
         if ($stepExecution->getStatus()->getValue() == BatchStatus::STOPPED) {
             $this->dispatchStepExecutionEvent(EventInterface::STEP_EXECUTION_INTERRUPTED, $stepExecution);
         } else {
             $this->dispatchStepExecutionEvent(EventInterface::STEP_EXECUTION_ERRORED, $stepExecution);
         }
     }
     $this->dispatchStepExecutionEvent(EventInterface::STEP_EXECUTION_COMPLETED, $stepExecution);
     $stepExecution->setEndTime(new \DateTime());
     $stepExecution->setExitStatus($exitStatus);
     $this->jobRepository->updateStepExecution($stepExecution);
 }