docs: public ExecutionStatus doExecutionLoop() {
  
  		final String methodName = "doExecutionLoop";
  		
  		// Before we do anything else, see if we're already in STOPPING state.
  		if (runtimeExecution.getBatchStatus().equals(BatchStatus.STOPPING)) {
  			logger.fine(methodName + " Exiting execution loop as job is now in stopping state.");
  			return new ExecutionStatus(ExtendedBatchStatus.JOB_OPERATOR_STOPPING);
  		}
  
  		try {
  			currentExecutionElement = modelNavigator.getFirstExecutionElement(runtimeExecution.getRestartOnForThisExecution());
  		} catch (IllegalTransitionException e) {
  			String errorMsg = "Could not transition to first execution element within job.";
  			throw new IllegalArgumentException(errorMsg, e);
  		}
  
  		if (logger.isLoggable(Level.FINE)) {
  			logger.fine("First execution element = " + currentExecutionElement.getId());
  		}
  
  		while (true) {
  
  			IExecutionElementController currentElementController = getNextElementController();
  			currentStoppableElementController = currentElementController;
  			
  			// Now that we've re-established a stoppable element controller, check to see if we missed a stop
  			if (runtimeExecution.getBatchStatus().equals(BatchStatus.STOPPING)) {
  				logger.fine(methodName + " Exiting execution loop as job is now in stopping state.");
  				return new ExecutionStatus(ExtendedBatchStatus.JOB_OPERATOR_STOPPING);
  			}
  			
  			// Restarting after a failure up until this point would cause you to restart at the previous restartOn value.  
  			// Now we will reset this to 'null'.   Another alternative would be to only 'null' this out when something actually executed.
  			// This could have spec implications..maybe let's think of it more.  Or maybe no one cares even.
  			ServicesManagerStaticAnchor.getServicesManager().getPersistenceManagerService().updateJobInstanceNullOutRestartOn(runtimeExecution.getTopLevelInstanceId());
  
  			ExecutionStatus status = currentElementController.execute();
  
  			// Nothing special for decision or step except to get exit status.  For flow and split we want to bubble up though.
  			if ((currentExecutionElement instanceof Split) || (currentExecutionElement instanceof Flow)) {
  				// Exit status and restartOn should both be in the job context.
  				if (!status.getExtendedBatchStatus().equals(ExtendedBatchStatus.NORMAL_COMPLETION)) {
  					logger.fine("Breaking out of loop with return status = " + status.getExtendedBatchStatus().name());
  					return status;
  				}
  			} 
  
  			// Seems like this should only happen if an Error is thrown at the step level, since normally a step-level
  			// exception is caught and the fact that it was thrown capture in the ExecutionStatus
  			if (runtimeExecution.getBatchStatus().equals(BatchStatus.FAILED)) {
  				String errorMsg = "Sub-execution returned its own BatchStatus of FAILED.  Deal with this by throwing exception to the next layer.";
  				throw new BatchContainerRuntimeException(errorMsg);
  			}
  
  			// set the execution element controller to null so we don't try to call stop on it after the element has finished executing
  			currentStoppableElementController = null;
  			
  			if (logger.isLoggable(Level.FINE)) {
  				logger.fine("Done executing element=" + currentExecutionElement.getId() + ", exitStatus=" + status.getExitStatus());
  			}
  
  			if (runtimeExecution.getBatchStatus().equals(BatchStatus.STOPPING)) {
  				logger.fine(methodName + " Exiting as job has been stopped");
  				return new ExecutionStatus(ExtendedBatchStatus.JOB_OPERATOR_STOPPING);
  			}
  
  			Transition nextTransition = null;
  			try {
  				nextTransition = modelNavigator.getNextTransition(currentExecutionElement, status);
  			} catch (IllegalTransitionException e) {
  				String errorMsg = "Problem transitioning to next execution element.";
  				throw new BatchContainerRuntimeException(errorMsg, e);
  			} 
  
  			//
  			// We will find ourselves in one of four states now.  
  			// 
  			// 1. Finished transitioning after a normal execution, but nothing to do 'next'.
  			// 2. We just executed a step which through an exception, but didn't match a transition element.
  			// 3. We are going to 'next' to another execution element (and jump back to the top of this '
  			//    'while'-loop.
  			// 4. We matched a terminating transition element (<end>, <stop> or <fail).
  			//
  			
  			// 1.
  			if (nextTransition.isFinishedTransitioning()) {
  				logger.fine(methodName + " , No next execution element, and no transition element found either.  Looks like we're done and ready for COMPLETED state.");
  				this.stepExecIds =  currentElementController.getLastRunStepExecutions();
  				// Consider just passing the last 'status' back, but let's unwrap the exit status and pass a new NORMAL_COMPLETION
  				// status back instead.
  				return new ExecutionStatus(ExtendedBatchStatus.NORMAL_COMPLETION, status.getExitStatus());
  			// 2.
  			} else if (nextTransition.noTransitionElementMatchedAfterException()) {
  				return new ExecutionStatus(ExtendedBatchStatus.EXCEPTION_THROWN, status.getExitStatus());
  			// 3.
  			} else if (nextTransition.getNextExecutionElement() != null) {
  				// hold on to the previous execution element for the decider
  				// we need it because we need to inject the context of the
  				// previous execution element into the decider
  				previousExecutionElement = currentExecutionElement;
  				previousElementController = currentElementController;
  				currentExecutionElement = nextTransition.getNextExecutionElement();
  			// 4.
  			} else if (nextTransition.getTransitionElement() != null) {
  				ExecutionStatus terminatingStatus = handleTerminatingTransitionElement(nextTransition.getTransitionElement());
  				logger.finer(methodName + " , Breaking out of execution loop after processing terminating transition element.");
  				return terminatingStatus;
  			} else {
  				throw new IllegalStateException("Not sure how we'd end up in this state...aborting rather than looping.");
  			}
  		}
  	}