/**
   * @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 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);
 }
  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;
  }