private NodeToken backtrackCompletedToken(
      final NodeToken token, final ExecutionType executionType) {
    token.markBacktracked();
    NodeTokenEvent.fireBacktrackedEvent(engine, token);

    List<ArcToken> parents = new ArrayList<ArcToken>(token.getChildTokens().size());
    for (ArcToken childToken : token.getChildTokens()) {
      ArcToken parent = arcTokenMap.get(childToken);
      if (parent == null) {
        throw new RuntimeException("No backtrack found for: " + childToken);
      }
      parents.add(parent);
    }

    NodeToken backtrackToken =
        engine
            .getFactory()
            .newNodeToken(token.getProcess(), token.getNode(), executionType, parents, token);
    NodeTokenEvent.fireCreatedEvent(engine, backtrackToken);
    token.getProcess().addNodeToken(backtrackToken);
    shareTokenSets(backtrackToken, token);

    for (ArcToken parent : parents) {
      token.getProcess().removeActiveArcToken(parent);

      parent.markBacktracked();
      ArcTokenEvent.fireBacktrackedEvent(engine, parent);

      parent.markComplete(backtrackToken);
      ArcTokenEvent.fireCompletedEvent(engine, parent);
    }

    return backtrackToken;
  }
  public NodeToken backtrackDeadEnd(final NodeToken token) {
    token.markBacktracked();
    NodeTokenEvent.fireBacktrackedEvent(engine, token);

    List<ArcToken> parents = new ArrayList<ArcToken>(token.getParentTokens().size());
    for (ArcToken parent : token.getParentTokens()) {
      parent.markBacktracked();
      ArcTokenEvent.fireBacktrackedEvent(engine, parent);

      ArcToken backtrackArcToken =
          engine
              .getFactory()
              .newArcToken(token.getProcess(), parent.getArc(), ExecutionType.UTurn, token);
      ArcTokenEvent.fireCreatedEvent(engine, backtrackArcToken);
      token.getChildTokens().add(backtrackArcToken);
      parents.add(backtrackArcToken);
      shareTokenSets(backtrackArcToken, parent);
    }

    NodeToken backtrackToken =
        engine
            .getFactory()
            .newNodeToken(
                token.getProcess(), token.getNode(), ExecutionType.Forward, parents, token);
    NodeTokenEvent.fireCreatedEvent(engine, backtrackToken);
    token.getProcess().addNodeToken(backtrackToken);
    shareTokenSets(backtrackToken, token);

    for (ArcToken parent : parents) {
      parent.markProcessed();
      ArcTokenEvent.fireProcessedEvent(engine, parent);

      parent.markComplete(backtrackToken);
      ArcTokenEvent.fireCompletedEvent(engine, parent);
    }

    reactivateTokenSets();

    return backtrackToken;
  }