private void completeExecuteArc(GraphProcess process, Node targetNode, List<ArcToken> tokens) {
    NodeToken nodeToken = getFactory().newNodeToken(process, targetNode, tokens);
    process.addNodeToken(nodeToken);

    // Add new node token to add the token sets which its generating arc tokens are members of
    Set<TokenSet> tokenSets = new HashSet<TokenSet>();

    for (ArcToken token : tokens) {
      for (ArcTokenSetMember setMember : token.getTokenSetMemberships()) {
        TokenSet tokenSet = setMember.getTokenSet();
        if (!tokenSet.isComplete() && !tokenSets.contains(tokenSet)) {
          tokenSets.add(tokenSet);
          NodeTokenSetMember newSetMember =
              getFactory().newNodeTokenSetMember(tokenSet, nodeToken, setMember.getMemberIndex());
          tokenSet.getActiveNodeTokens(this).add(nodeToken);
          nodeToken.getTokenSetMemberships().add(newSetMember);
        }
      }
    }

    fireEvent(NodeTokenEvent.newCreatedEvent(this, nodeToken));

    for (ArcToken token : tokens) {
      process.removeActiveArcToken(token);
      if (token.isPending()) {
        token.markProcessed(this);
      }
      token.markComplete(this, nodeToken);
      fireEvent(ArcTokenEvent.newCompletedEvent(this, token));
    }

    executeNode(process, nodeToken);
  }
 private void reactivateTokenSets() {
   for (TokenSet tokenSet : tokenSets) {
     if (tokenSet.isComplete()
         && (!tokenSet.getActiveArcTokens(engine).isEmpty()
             || !tokenSet.getActiveNodeTokens(engine).isEmpty())) {
       tokenSet.reactivateForBacktrack(engine);
     }
   }
 }
 private void shareTokenSets(final ArcToken newToken, final ArcToken origToken) {
   for (ArcTokenSetMember setMember : origToken.getTokenSetMemberships()) {
     TokenSet tokenSet = setMember.getTokenSet();
     ArcTokenSetMember newSetMember =
         engine.getFactory().newArcTokenSetMember(tokenSet, newToken, setMember.getMemberIndex());
     newToken.getTokenSetMemberships().add(newSetMember);
     tokenSet.getActiveArcTokens(engine).add(newToken);
     tokenSets.add(tokenSet);
   }
 }
  private ArcToken generateArcToken(
      final GraphProcess process, final Arc arc, final NodeToken token) {
    ArcToken arcToken = getFactory().newArcToken(process, arc, ExecutionType.Forward, token);
    token.getChildTokens().add(arcToken);

    for (NodeTokenSetMember setMember : token.getTokenSetMemberships()) {
      TokenSet tokenSet = setMember.getTokenSet();
      if (!tokenSet.isComplete()) {
        ArcTokenSetMember newSetMember =
            getFactory().newArcTokenSetMember(tokenSet, arcToken, setMember.getMemberIndex());
        tokenSet.getActiveArcTokens(this).add(arcToken);
        arcToken.getTokenSetMemberships().add(newSetMember);
      }
    }

    return arcToken;
  }
  public void completeWithNewTokenSet(
      final NodeToken token,
      final String arcName,
      final String tokenSetName,
      final int numberOfTokens,
      final boolean asynchronous,
      final Env initialEnv,
      final Map<String, List<?>> initialMemberEnv) {
    GraphProcess process = token.getProcess();

    if (!process.isExecuting() || token.isComplete()) {
      return;
    }

    completeNodeToken(process, token, arcName);

    List<? extends Arc> outArcs = process.getGraph().getOutputArcs(token.getNode(), arcName);

    if (!outArcs.isEmpty()) {
      TokenSet tokenSet = getFactory().newTokenSet(process, tokenSetName, numberOfTokens);

      if (initialEnv != null) {
        tokenSet.getEnv().importEnv(initialEnv);
      }

      if (initialMemberEnv != null) {
        TokenSetMemberEnv memberEnv = tokenSet.getMemberEnv();
        for (Map.Entry<String, List<?>> entry : initialMemberEnv.entrySet()) {
          memberEnv.setAttribute(entry.getKey(), entry.getValue());
        }
      }

      for (int memberIndex = 0; memberIndex < numberOfTokens; memberIndex++) {
        for (Arc arc : outArcs) {
          ArcToken arcToken = generateArcToken(process, arc, token);

          ArcTokenSetMember setMember =
              getFactory().newArcTokenSetMember(tokenSet, arcToken, memberIndex);
          tokenSet.getActiveArcTokens(this).add(arcToken);
          arcToken.getTokenSetMemberships().add(setMember);

          finishNewArcTokenProcessing(process, arcToken, asynchronous);
        }
      }
    }
  }