class SaltJobIdTracker implements OrchestratorBootstrap {

    @Override
    public Boolean call() throws Exception {
        if (JobState.NOT_STARTED.equals(saltJobRunner.getJobState())) {
            LOGGER.debug("Job has not started in the cluster. Starting for first time.");
            saltJobRunner.setJid(jobId(saltJobRunner.submit(saltConnector)));
            checkIsFinished(saltJobRunner.getJid().getJobId());
        } else if (JobState.IN_PROGRESS.equals(saltJobRunner.getJobState())) {
            String jobId = saltJobRunner.getJid().getJobId();
            LOGGER.debug("Job: {} is running currently checking the current state.", jobId);
            checkIsFinished(jobId);
        } else if (!retryOnFail && JobState.FAILED == saltJobRunner.getJobState()) {
            String jobId = saltJobRunner.getJid().getJobId();
            LOGGER.info("Job: {} failed. Terminate execution on these targets: {}", jobId, saltJobRunner.getTargetHostnames());
            throw new CloudbreakOrchestratorTerminateException(buildErrorMessage(), saltJobRunner.getNodesWithError());
        } else if (JobState.FAILED == saltJobRunner.getJobState() || JobState.AMBIGUOUS == saltJobRunner.getJobState()) {
            String jobId = saltJobRunner.getJid().getJobId();
            LOGGER.debug("Job: {} failed in the previous time. Trigger again with these targets: {}", jobId, saltJobRunner.getTargetHostnames());
            saltJobRunner.setJid(jobId(saltJobRunner.submit(saltConnector)));
            saltJobRunner.setJobState(JobState.IN_PROGRESS);
            return call();
        }
        if (JobState.IN_PROGRESS.equals(saltJobRunner.getJobState())) {
            String errorMessage = buildErrorMessage();
            LOGGER.warn(String.format("Job: %s is running currently. Details: %s", saltJobRunner.getJid(), errorMessage));
            throw new CloudbreakOrchestratorInProgressException(errorMessage, saltJobRunner.getNodesWithError());
        }
        if (JobState.FAILED == saltJobRunner.getJobState() || JobState.AMBIGUOUS == saltJobRunner.getJobState()) {
            throw new CloudbreakOrchestratorFailedException(buildErrorMessage(), saltJobRunner.getNodesWithError());
        }
        LOGGER.debug("Job (jid: {}) was finished. Triggering next salt event.", saltJobRunner.getJid().getJobId());
        return true;
    }

    public  SaltJobIdTracker(SaltConnector saltConnector, SaltJobRunner saltJobRunner);
    public  SaltJobIdTracker(SaltConnector saltConnector, SaltJobRunner saltJobRunner, boolean retryOnFail);

}