class SimpleJobExplorer implements JobExplorer {

	private JobInstanceDao jobInstanceDao;

	private JobExecutionDao jobExecutionDao;

	private StepExecutionDao stepExecutionDao;

	private ExecutionContextDao ecDao;

	/**
	 * Provides a default constructor with low visibility in case you want to use
	 * aop:proxy-target-class="true" for the AOP interceptor.
	 */
	SimpleJobExplorer() {
	}

	/**
	 * Constructor to initialize the job {@link SimpleJobExplorer}.
	 * @param jobInstanceDao The {@link JobInstanceDao} to be used by the repository.
	 * @param jobExecutionDao The {@link JobExecutionDao} to be used by the repository.
	 * @param stepExecutionDao The {@link StepExecutionDao} to be used by the repository.
	 * @param ecDao The {@link ExecutionContextDao} to be used by the repository.
	 */
	public SimpleJobExplorer(JobInstanceDao jobInstanceDao, JobExecutionDao jobExecutionDao,
			StepExecutionDao stepExecutionDao, ExecutionContextDao ecDao) {
		super();
		this.jobInstanceDao = jobInstanceDao;
		this.jobExecutionDao = jobExecutionDao;
		this.stepExecutionDao = stepExecutionDao;
		this.ecDao = ecDao;
	}

	@Override
	public List<JobExecution> getJobExecutions(JobInstance jobInstance) {
		List<JobExecution> executions = jobExecutionDao.findJobExecutions(jobInstance);
		for (JobExecution jobExecution : executions) {
			getJobExecutionDependencies(jobExecution);
			for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
				getStepExecutionDependencies(stepExecution);
			}
		}
		return executions;
	}

	@Nullable
	@Override
	public JobExecution getLastJobExecution(JobInstance jobInstance) {
		JobExecution lastJobExecution = jobExecutionDao.getLastJobExecution(jobInstance);
		if (lastJobExecution != null) {
			getJobExecutionDependencies(lastJobExecution);
			for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
				getStepExecutionDependencies(stepExecution);
			}
		}
		return lastJobExecution;
	}

	@Override
	public Set<JobExecution> findRunningJobExecutions(@Nullable String jobName) {
		Set<JobExecution> executions = jobExecutionDao.findRunningJobExecutions(jobName);
		for (JobExecution jobExecution : executions) {
			getJobExecutionDependencies(jobExecution);
			for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
				getStepExecutionDependencies(stepExecution);
			}
		}
		return executions;
	}

	@Nullable
	@Override
	public JobExecution getJobExecution(@Nullable Long executionId) {
		if (executionId == null) {
			return null;
		}
		JobExecution jobExecution = jobExecutionDao.getJobExecution(executionId);
		if (jobExecution == null) {
			return null;
		}
		getJobExecutionDependencies(jobExecution);
		for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
			getStepExecutionDependencies(stepExecution);
		}
		return jobExecution;
	}

	@Nullable
	@Override
	public StepExecution getStepExecution(@Nullable Long jobExecutionId, @Nullable Long executionId) {<FILL_FUNCTION_BODY>}

	@Nullable
	@Override
	public JobInstance getJobInstance(@Nullable Long instanceId) {
		return jobInstanceDao.getJobInstance(instanceId);
	}

	@Nullable
	@Override
	public JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
		return jobInstanceDao.getJobInstance(jobName, jobParameters);
	}

	@Nullable
	@Override
	public JobInstance getLastJobInstance(String jobName) {
		return jobInstanceDao.getLastJobInstance(jobName);
	}

	@Override
	public List<JobInstance> getJobInstances(String jobName, int start, int count) {
		return jobInstanceDao.getJobInstances(jobName, start, count);
	}

	@Override
	public List<String> getJobNames() {
		return jobInstanceDao.getJobNames();
	}

	@Override
	public long getJobInstanceCount(@Nullable String jobName) throws NoSuchJobException {
		return jobInstanceDao.getJobInstanceCount(jobName);
	}

	/**
	 * @return instance of {@link JobInstanceDao}.
	 * @since 5.1
	 */
	protected JobInstanceDao getJobInstanceDao() {
		return jobInstanceDao;
	}

	/**
	 * @return instance of {@link JobExecutionDao}.
	 * @since 5.1
	 */
	protected JobExecutionDao getJobExecutionDao() {
		return jobExecutionDao;
	}

	/**
	 * @return instance of {@link StepExecutionDao}.
	 * @since 5.1
	 */
	protected StepExecutionDao getStepExecutionDao() {
		return stepExecutionDao;
	}

	/**
	 * @return instance of {@link ExecutionContextDao}.
	 * @since 5.1
	 */
	protected ExecutionContextDao getEcDao() {
		return ecDao;
	}

	/*
	 * Find all dependencies for a JobExecution, including JobInstance (which requires
	 * JobParameters) plus StepExecutions
	 */
	private void getJobExecutionDependencies(JobExecution jobExecution) {
		JobInstance jobInstance = jobInstanceDao.getJobInstance(jobExecution);
		stepExecutionDao.addStepExecutions(jobExecution);
		jobExecution.setJobInstance(jobInstance);
		jobExecution.setExecutionContext(ecDao.getExecutionContext(jobExecution));

	}

	private void getStepExecutionDependencies(StepExecution stepExecution) {
		if (stepExecution != null) {
			stepExecution.setExecutionContext(ecDao.getExecutionContext(stepExecution));
		}
	}

	@Override
	public List<JobInstance> findJobInstancesByJobName(String jobName, int start, int count) {
		return jobInstanceDao.findJobInstancesByName(jobName, start, count);
	}

}

		JobExecution jobExecution = jobExecutionDao.getJobExecution(jobExecutionId);
		if (jobExecution == null) {
			return null;
		}
		getJobExecutionDependencies(jobExecution);
		StepExecution stepExecution = stepExecutionDao.getStepExecution(jobExecution, executionId);
		getStepExecutionDependencies(stepExecution);
		return stepExecution;
	
<no_super_class>