private String determineFutureNodeName(
     RouteNode node, MovePoint movePoint, int currentStep, Set nodesProcessed)
     throws InvalidActionTakenException {
   if (nodesProcessed.contains(node.getRouteNodeId())) {
     throw new InvalidActionTakenException(
         "Detected a cycle at node "
             + node.getRouteNodeName()
             + " when attempting to move document.");
   }
   nodesProcessed.add(node.getRouteNodeId());
   if (currentStep == movePoint.getStepsToMove()) {
     return node.getRouteNodeName();
   }
   List nextNodes = node.getNextNodes();
   if (nextNodes.size() == 0) {
     throw new InvalidActionTakenException(
         "Could not proceed forward, there are no more nodes in the route.  Halted on step "
             + currentStep);
   }
   if (nextNodes.size() != 1) {
     throw new InvalidActionTakenException(
         "Cannot move forward in a multi-branch path.  Located "
             + nextNodes.size()
             + " branches.  Halted on step "
             + currentStep);
   }
   return determineFutureNodeName(
       (RouteNode) nextNodes.get(0), movePoint, currentStep + 1, nodesProcessed);
 }
 @Override
 public List<String> getNextNodeIds() {
   List<String> nextNodeIds = new ArrayList<String>();
   if (nextNodeIds != null) {
     for (RouteNode nextNode : nextNodes) {
       nextNodeIds.add(nextNode.getRouteNodeId().toString());
     }
   }
   return nextNodeIds;
 }
 @Override
 public List<String> getPreviousNodeIds() {
   List<String> previousNodeIds = new ArrayList<String>();
   if (previousNodes != null) {
     for (RouteNode previousNode : previousNodes) {
       previousNodeIds.add(previousNode.getRouteNodeId().toString());
     }
   }
   return previousNodeIds;
 }
  protected RouteNode flattenSplitNode(RouteNode splitNode, Map<String, RouteNode> nodes) {
    nodes.put(splitNode.getRouteNodeName(), splitNode);
    RouteNode joinNode = null;

    for (RouteNode nextNode : splitNode.getNextNodes()) {
      joinNode = flattenRouteNodes(nextNode, nodes);
    }

    if (joinNode != null) {
      nodes.put(joinNode.getRouteNodeName(), joinNode);
    }
    return joinNode;
  }
  /**
   * @param node
   * @param nodes
   * @return The last node processed by this method.
   */
  protected RouteNode flattenRouteNodes(RouteNode node, Map<String, RouteNode> nodes) {
    RouteNode lastProcessedNode = null;
    if (node != null) {
      // if we've seen the node before - skip, avoids infinite loop
      if (nodes.containsKey(node.getRouteNodeName())) {
        return node;
      }

      if (node.getNodeType()
          .contains(
              "SplitNode")) { // Hacky - but only way when the class may not be present in the KEW
                              // JVM
        lastProcessedNode =
            flattenSplitNode(
                node, nodes); // special handling to process all split children before continuing
        // now, process the join node's children
        if (lastProcessedNode != null) {
          for (RouteNode nextNode : lastProcessedNode.getNextNodes()) {
            lastProcessedNode = flattenRouteNodes(nextNode, nodes);
          }
        }
      } else if (node.getNodeType().contains("JoinNode")) {
        lastProcessedNode = node; // skip, handled by the split node
      } else {
        // normal node, add to list and process all children
        nodes.put(node.getRouteNodeName(), node);
        for (RouteNode nextNode : node.getNextNodes()) {
          lastProcessedNode = flattenRouteNodes(nextNode, nodes);
        }
      }
    }
    return lastProcessedNode;
  }
 private String determineReturnNodeName(RouteNode node, MovePoint movePoint, int currentStep)
     throws InvalidActionTakenException {
   if (currentStep == movePoint.getStepsToMove()) {
     return node.getRouteNodeName();
   }
   List previousNodes = node.getPreviousNodes();
   if (previousNodes.size() == 0) {
     throw new InvalidActionTakenException(
         "Could not locate the named target node in the document's past route.  Halted on step "
             + currentStep);
   }
   if (previousNodes.size() != 1) {
     throw new InvalidActionTakenException(
         "Located a multi-branch path, could not proceed backward past this point.  Halted on step "
             + currentStep);
   }
   return determineReturnNodeName((RouteNode) previousNodes.get(0), movePoint, currentStep - 1);
 }
 public void addNextNode(RouteNode nextNode) {
   getNextNodes().add(nextNode);
   nextNode.getPreviousNodes().add(this);
 }