@Override
  public Transition getNextTransition(ExecutionElement currentElem, String currentExitStatus) {
    final String method = "getNextTransition";
    if (logger.isLoggable(Level.FINE))
      logger.fine(method + " ,currentExitStatus=" + currentExitStatus);

    String nextAttrId = null;
    ExecutionElement nextExecutionElement = null;
    Transition returnTransition = new TransitionImpl();

    if (currentElem instanceof Step) {
      nextAttrId = ((Step) currentElem).getNextFromAttribute();
      nextExecutionElement = getExecutionElementByID(nextAttrId);
    } else if (currentElem instanceof Split) {
      nextAttrId = ((Split) currentElem).getNextFromAttribute();
      nextExecutionElement = getExecutionElementByID(nextAttrId);
    } else if (currentElem instanceof Flow) {
      nextAttrId = ((Flow) currentElem).getNextFromAttribute();
      nextExecutionElement = getExecutionElementByID(nextAttrId);
    } else if (currentElem instanceof Decision) {
      // Nothing special to do in this case.
    }

    List<ControlElement> controlElements = currentElem.getControlElements();

    if (nextExecutionElement == null && controlElements.isEmpty()) {
      if (logger.isLoggable(Level.FINE))
        logger.fine(method + " return null, there is no next step");
      // Don't set anything special on return transition.
      return returnTransition;
    } else if (nextExecutionElement != null) {
      if (logger.isLoggable(Level.FINE))
        logger.fine(method + " return execution element:" + nextExecutionElement);
      returnTransition.setNextExecutionElement(nextExecutionElement);
      return returnTransition;
    } else if (controlElements.size() > 0) {

      Iterator<ControlElement> iterator = controlElements.iterator();
      while (iterator.hasNext()) {

        ControlElement elem = iterator.next();

        if (logger.isLoggable(Level.FINE)) {
          logger.fine(method + " Trying to match next control element: " + elem);
        }

        if (elem instanceof Stop) {
          String exitStatusToMatch = ((Stop) elem).getOn();
          boolean isMatched = matchSpecifiedExitStatus(currentExitStatus, exitStatusToMatch);
          if (isMatched == true) {
            if (logger.isLoggable(Level.FINE))
              logger.fine(method + " , Stop element matches to " + exitStatusToMatch);

            returnTransition.setControlElement(elem);
            return returnTransition;
          }
        } else if (elem instanceof End) {
          String exitStatusToMatch = ((End) elem).getOn();
          boolean isMatched = matchSpecifiedExitStatus(currentExitStatus, exitStatusToMatch);
          if (isMatched == true) {
            if (logger.isLoggable(Level.FINE))
              logger.fine(method + " , End element matches to " + exitStatusToMatch);
            returnTransition.setControlElement(elem);
            return returnTransition;
          }
        } else if (elem instanceof Fail) {
          String exitStatusToMatch = ((Fail) elem).getOn();
          boolean isMatched = matchSpecifiedExitStatus(currentExitStatus, exitStatusToMatch);
          if (isMatched == true) {
            if (logger.isLoggable(Level.FINE))
              logger.fine(method + " , Fail element matches to " + exitStatusToMatch);
            returnTransition.setControlElement(elem);
            return returnTransition;
          }
        } else if (elem instanceof Next) {
          String exitStatusToMatch = ((Next) elem).getOn();
          boolean isMatched = matchSpecifiedExitStatus(currentExitStatus, exitStatusToMatch);
          if (isMatched == true) {
            // go to next executionElement
            nextExecutionElement = getExecutionElementByID(((Next) elem).getTo());

            if (logger.isLoggable(Level.FINE))
              logger.fine(
                  method
                      + " , match to "
                      + exitStatusToMatch
                      + ". Continue to step "
                      + nextExecutionElement.getId());

            // No point setting the ControlElement in the transition.
            returnTransition.setNextExecutionElement(nextExecutionElement);
            return returnTransition;
          }
        } else {
          throw new IllegalStateException(
              "Shouldn't be possible to get here. Unknown control element,  " + elem.toString());
        }
      }
    }

    // TODO - Is this an error case or a valid end/completion case?
    return null;
  }