/**
   * Method should be called when finalizing the command. The execution step is being ended with
   * success and the finalization step is started.
   *
   * @param executionContext The context of the job
   * @return A created instance of the Finalizing step
   */
  public static Step startFinalizingStep(ExecutionContext executionContext) {
    if (executionContext == null) {
      return null;
    }
    Step step = null;

    try {
      if (executionContext.getExecutionMethod() == ExecutionMethod.AsJob) {
        Job job = executionContext.getJob();
        if (job != null) {
          Step executingStep = job.getStep(StepEnum.EXECUTING);
          Step finalizingStep =
              job.addStep(
                  StepEnum.FINALIZING,
                  ExecutionMessageDirector.getInstance().getStepMessage(StepEnum.FINALIZING));

          if (executingStep != null) {
            executingStep.markStepEnded(true);
            JobRepositoryFactory.getJobRepository()
                .updateExistingStepAndSaveNewStep(executingStep, finalizingStep);
          } else {
            JobRepositoryFactory.getJobRepository().saveStep(finalizingStep);
          }
        }
      } else if (executionContext.getExecutionMethod() == ExecutionMethod.AsStep) {
        Step parentStep = executionContext.getStep();
        if (parentStep != null) {
          Step executingStep = parentStep.getStep(StepEnum.EXECUTING);
          Step finalizingStep =
              parentStep.addStep(
                  StepEnum.FINALIZING,
                  ExecutionMessageDirector.getInstance().getStepMessage(StepEnum.FINALIZING));
          if (executingStep != null) {
            executingStep.markStepEnded(true);
            JobRepositoryFactory.getJobRepository()
                .updateExistingStepAndSaveNewStep(executingStep, finalizingStep);
          } else {
            JobRepositoryFactory.getJobRepository().saveStep(finalizingStep);
          }
        }
      }
    } catch (Exception e) {
      log.error(e);
    }
    return step;
  }
  /**
   * Finalizes Job with VDSM tasks, as this case requires verification that no other steps are
   * running in order to close the entire Job
   *
   * @param executionContext The context of the execution which defines how the job should be ended
   * @param exitStatus Indicates if the execution described by the job ended successfully or not.
   */
  public static void endTaskJob(ExecutionContext context, boolean exitStatus) {
    if (context == null) {
      return;
    }

    try {
      if (context.getExecutionMethod() == ExecutionMethod.AsJob && context.getJob() != null) {
        endJob(context, exitStatus);
      } else {
        Step parentStep = context.getStep();
        if (context.getExecutionMethod() == ExecutionMethod.AsStep && parentStep != null) {
          Step finalizingStep = parentStep.getStep(StepEnum.FINALIZING);
          if (finalizingStep != null) {
            finalizingStep.markStepEnded(exitStatus);
            JobRepositoryFactory.getJobRepository().updateStep(finalizingStep);
          }
          parentStep.markStepEnded(exitStatus);
          JobRepositoryFactory.getJobRepository().updateStep(parentStep);

          List<Step> steps =
              DbFacade.getInstance().getStepDao().getStepsByJobId(parentStep.getJobId());
          boolean hasChildStepsRunning = false;
          for (Step step : steps) {
            if (step.getStatus() == JobExecutionStatus.STARTED && step.getParentStepId() != null) {
              hasChildStepsRunning = true;
              break;
            }
          }
          if (!hasChildStepsRunning) {
            endJob(
                exitStatus, JobRepositoryFactory.getJobRepository().getJob(parentStep.getJobId()));
          }
        }
      }
    } catch (RuntimeException e) {
      log.error(e);
    }
  }