public void informActionDone(AID agent, ActionNode action)
        {
            bool foundAndRemoved = false;

            //remove from "running" list
            for (int i = 0; i < actionsRunning.Count; ++i)
            {
                if ((actionsRunning[i].Key == agent.toString()) && (actionsRunning[i].Value.getFullName() == action.getFullName()))
                {
                    actionsRunning.RemoveAt(i);
                    foundAndRemoved = true;
                    break;
                }
            }

            //Debug.Log(" IAD : " + activeTokens.Count);
            if (foundAndRemoved)
            {
                ActionNode doneAction = action;
                if (doneAction != null)
                {
                    bool advancedToken = false;

                    for (int i = 0; i < activeTokens.Count; i++)
                    {
                        ActivityExecutionToken token = activeTokens[i];
                        if (tryToAdvanceToken(token, doneAction, true))
                        {
                            advancedToken = true;
                        }
                    }

                    if (advancedToken)
                    {
                        //add to "done" list
                        actionsDone.Add(doneAction);
                        allActionsDone[agent.toString()].Add(doneAction);
                        allActionsDoneTimestamps[agent.toString()].Add(doneAction.CurrentExecution.Finish);
                    }
                    else
                    {
                        //if (ACTIVATE_GENERAL_DEBUG) cerr << "HUSTON, WE'VE GOT A PROBLEM... no token was advanced for " << doneAction->getName() << endl;
                    }
                }
            }
        }
        protected bool tryToAdvanceToken(ActivityExecutionToken token, ActionNode doneAction, bool gotTicketToUseAction)
        {
            //TODO : current implementation will fail if the loop node has branches which are not joined together at the end

            //TODO : setup part of loop nodes not implemented
            //TODO : careful if the loop node contains only an initial node :: ENDLESS LOOP

            //		Debug.Log(" current token : " + token.currentLocation.name);

            if (token.currentLocation.Kind == "action")
            {
                ActionNode aNode = (ActionNode)(token.currentLocation);
                if (actionIsCurrentlyRunning(aNode))
                {
                    System.Console.WriteLine(" ACTION is RUNNING : " + aNode.Action.name);
                    //token busy...
                    return false;
                }
            }

            if (token.outgoingEdge == null)
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null" << endl;
                //Debug.Log(" NO OUTGOING EDGES....");
                //my work here is done *flies away*
                return false;
            }

            //evaluate guard(s). Normal behavior for fork, but I treat decision nodes here, if there are more paths going out, I will take the first one.
            if (token.currentLocation.Kind == "fork")
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: fork" << endl;

                //normal behavior for fork (should not have guard, but hell... it doesn't hurt to check)
                if (token.outgoingEdge.Guard != null && (!(token.outgoingEdge.Guard.eval(procedure.Activity.Context))))
                {
                    return false; //eval failed
                }
            }
            else
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: no fork" << endl;

                List<ActivityEdge> outgoingNormal = token.currentLocation.getOutgoingControlFlowEdges();
                bool foundWayOut = false;
                for (int i = 0; i < outgoingNormal.Count; ++i)
                {
                    //if <no guard> or <guard but evaluates ok>
                    if ((outgoingNormal[i].Guard == null) || (outgoingNormal[i].Guard != null && (outgoingNormal[i].Guard.eval(procedure.Activity.Context))))
                    {
                        foundWayOut = true;
                        token.outgoingEdge = outgoingNormal[i]; //set new direction, we take the first possible one, remember ?
                    }
                }

                if (!foundWayOut)
                {
                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: didn't find way out" << endl;

                    return false; //no way out... leave for later
                }
            }

            ActivityNode nextLocation = token.outgoingEdge.Target;

            //test allowed action
            if (nextLocation.Kind == "action")
            {
                if ((nextLocation != doneAction) || (!gotTicketToUseAction))
                {
                    //not allowed to advance to this action

                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: action not allowed" << endl;

                    return false;
                }

                gotTicketToUseAction = false;
            }

            //Debug.Log("Next Location : " + nextLocation);

            //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "adv tok from '" << token->currentLocation->getName() << "' to '" << nextLocation->getName() << "'" << endl;

            //Advance
            ActivityEdge dummyActivityEdge = null;
            token.currentLocation = nextLocation;
            token.outgoingEdge = dummyActivityEdge;

            List<ActivityEdge> outgoingAfterAdvance = token.currentLocation.getOutgoingControlFlowEdges();

            List<ActivityExecutionToken> nextTokens = new List<ActivityExecutionToken>();

            if (token.currentLocation.Kind == "fork")
            {
                //time to split token into pieces, in order to follow all fork branches

                token.forkStack.Add(token.currentLocation); //push this fork to the stack

                //remove this token from the active list
                for (int i = 0; i < activeTokens.Count; ++i)
                {
                    if (activeTokens[i].ToString() == token.ToString())
                    {
                        activeTokens.RemoveAt(i);
                        break;
                    }
                }

                for (int i = 0; i < outgoingAfterAdvance.Count; ++i)
                {
                    ActivityExecutionToken tok = new ActivityExecutionToken();
                    tok.currentLocation = token.currentLocation;
                    tok.forkStack = token.forkStack;
                    tok.loopNodeStack = token.loopNodeStack;
                    tok.outgoingEdge = outgoingAfterAdvance[i]; //set outgoing, to know which branch to follow

                    //push to active list
                    activeTokens.Add(tok);

                    //save for further use
                    nextTokens.Add(tok);
                }
            }
            else if (token.currentLocation.Kind == "join")
            {
                //we can only pass by a join, if all other branched tokens have arrived in this join
                //the point is that the number of tokens which have the same last fork as this one, should be the same as the nr of incoming links to this join
                //i hope i understand this next time i read it

                List<ActivityEdge> incoming = token.currentLocation.Incoming; //so get the incoming

                //see which is the last fork of this token
                ActivityNode lastFork = null;
                if (token.forkStack.Count > 0)
                {
                    lastFork = token.forkStack[token.forkStack.Count-1];
                }

                if (lastFork != null)
                {
                    //find all tokens that have this fork and see if they all finished their branch // TODO: remember that actually, the forkStacks should be identical for paired tokens... if they're not, we've got a problem....
                    List<ActivityExecutionToken> finishedTokens = new List<ActivityExecutionToken>() ;
                    for (int i=0; i<activeTokens.Count; ++i)
                    {
                        //if found a token with this last fork
                        if ((activeTokens[i].forkStack.Count > 0) && (activeTokens[i].forkStack[activeTokens[i].forkStack.Count-1] == lastFork))
                        {
                            //check to see if it's finished (arrived at the same join)
                            if (activeTokens[i].currentLocation == token.currentLocation)
                            {
                                //add to finished tokens list
                                finishedTokens.Add(activeTokens[i]);
                            }
                        }
                    }

                    //now check to see if the number of found tokens equals the number of incoming links to this join
                    if (finishedTokens.Count == incoming.Count)
                    {
                        //then all should be great.... we can merge all tokens into a single one
                        for (int i=0; i<finishedTokens.Count; ++i)
                        {
                            //skip the current token, this one will remain
                            if (finishedTokens[i].ToString() == token.ToString()) continue;

                            //seek and destroy
                            for (int j=0; j<activeTokens.Count; ++j)
                            {
                                if (finishedTokens[i].ToString() == activeTokens[j].ToString())
                                {
                                    //destroy
                                    activeTokens.RemoveAt( j);
                                }
                            }
                        }

                        if (outgoingAfterAdvance.Count == 1)
                        {
                            token.outgoingEdge = outgoingAfterAdvance[0];
                            token.forkStack.RemoveAt(token.forkStack.Count - 1);//pop last fork
                            nextTokens.Add(token);
                        }
                        else if (outgoingAfterAdvance.Count > 1)
                        {
                        }
                    }
                }
                else
                {
                }
            }
            else if (token.currentLocation.Kind == "loop")
            {
                LoopNode loopNode = (LoopNode)(token.currentLocation);

                bool skipThisLoopNode = false;

                if (loopNode.TestedFirst)
                {
                    if (loopNode.eval()) //thou shall pass
                    {
                        skipThisLoopNode = true;
                    }
                }

                ActivityNode initLoop = loopNode.Initial;
                List<ActivityEdge> outgoingFromInitLoop = null;

                if (initLoop != null)
                {
                    outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges();
                }

                if ( skipThisLoopNode || (initLoop == null) || (outgoingFromInitLoop.Count < 1) )
                {
                    //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any
                    if (outgoingAfterAdvance.Count >= 1)
                    {
                        token.outgoingEdge = outgoingAfterAdvance[0];
                        nextTokens.Add(token);
                    }

                }
                else
                {
                    //enter the loop node, we'll get the edge which exits the loopnode's initial node

                    token.currentLocation = initLoop;
                    token.outgoingEdge = outgoingFromInitLoop[0];
                    token.loopNodeStack.Add(loopNode);
                }
            }
            else
            {
                //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any
                if (outgoingAfterAdvance.Count >= 1)
                {
                    token.outgoingEdge = outgoingAfterAdvance[0];
                    nextTokens.Add(token);
                }
                else if (token.loopNodeStack.Count != 0) //check if we're in a loop node
                {
                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null, but in loop node" << endl;

                    while (((token.outgoingEdge == null)) && (token.loopNodeStack.Count != 0)) //while we are still in a loopnode and it is finished
                    {
                        LoopNode lastLoop = token.loopNodeStack[token.loopNodeStack.Count - 1];
                        if (lastLoop.eval()) //test exit condition
                        {
                            //exiting loop node

                            List<ActivityEdge> outgoingFromLoop = lastLoop.getOutgoingControlFlowEdges();

                            if (outgoingFromLoop.Count != 0)
                            {
                                token.currentLocation = lastLoop;
                                token.outgoingEdge = outgoingFromLoop[0];
                            }

                            token.loopNodeStack.RemoveAt(token.loopNodeStack.Count -1); //remove last loop from stack (exit)
                        }
                        else
                        {
                            //restarting loop node

                            ActivityNode initLoop = lastLoop.Initial;
                            List<ActivityEdge> outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges();

                            token.currentLocation = initLoop;
                            token.outgoingEdge = outgoingFromInitLoop[0]; //it should exist, given the fact that we've entered this loop node already
                        }
                    }

                    if (token.outgoingEdge != null)
                    {
                        nextTokens.Add(token);
                    }
                }
            }

            //continue to advance
            for (int i=0; i<nextTokens.Count; ++i)
            {
                tryToAdvanceToken(nextTokens[i], doneAction, gotTicketToUseAction);
            }

            return true;
        }
        public ProcedureExecution(Procedure procedure, OrganisationalEntity organisation, Agent agent)
        {
            this.procedure = procedure;
            this.organisation = organisation;
            this.agent = agent;

            agentToPartition = new Dictionary<string, ActivityPartition>();
            partitionToAgent = new Dictionary<ActivityPartition, AID>();
            activeTokens = new List<ActivityExecutionToken>();
            affectations = new Dictionary<string, InstanceSpecification>();
            activityParams = new Dictionary<string, ValueSpecification>();
            actionsRunning = new List<KeyValuePair<string, ActionNode>>();
            actionsDone = new List<ActionNode>();
            allActionsDone = new Dictionary<string, List<ActionNode>>(); // key: AID
            allActionsDoneTimestamps = new Dictionary<string, List<TimeExpression>>();

            for (int i = 0; i < procedure.Activity.Partitions.Count; i++)
            {
                ActivityPartition partition = procedure.Activity.Partitions[i];
                List<RoleAssignement> assignements = organisation.RoleAssignement;
                for (int j = 0; j < assignements.Count; j++)
                {
                    if (partition.name == assignements[j].Role.name)
                    {
                        agentToPartition.Add(assignements[j].Agent.toString(), partition);
                        partitionToAgent.Add(partition, assignements[j].Agent);
                        Agent agt = MascaretApplication.Instance.AgentPlateform.Agents[assignements[j].Agent.toString()];
                        if (agt == null) MascaretApplication.Instance.VRComponentFactory.Log("CA VA TRANCHER");
                        affectations.Add(partition.name, agt);
                    }
                }
            }

            ActivityExecutionToken initialToken = new ActivityExecutionToken();
            initialToken.currentLocation = procedure.Activity.Initial;

            if (initialToken.currentLocation == null)
            {
                System.Console.WriteLine("ERROR: no initial node found, not allowed");
                System.Console.WriteLine("Procedure will not start.");
                return;
            }

            List<ActivityEdge> controlFlows = procedure.Activity.Initial.getOutgoingControlFlowEdges();

            if (controlFlows.Count == 1)
            {
                initialToken.outgoingEdge = controlFlows[0];
                activeTokens.Add(initialToken);

                ActionNode dummyActionVariable = null;
                tryToAdvanceToken(initialToken, dummyActionVariable,true); //first advancement
            }
            else
            {
                if (controlFlows.Count == 0)
                {
                    System.Console.WriteLine("WARNING: initial node has no outgoing edges");
                }
                else
                {
                    System.Console.WriteLine("ERROR: multiple outgoing edges for the initial node, not allowed");
                }
                System.Console.WriteLine("Procedure will not start.");
            }
        }
        public List<ActionNode> getActionToExecuteForAll()
        {
            //this function simulates token advancement to provide the list of actions that can be executed
            //an action can be executed if it makes a difference in the procedure (if it enables a token to advance)

            //prepare output vector
            List<ActionNode> toExec = new List<ActionNode>();
            // StreamWriter file = MascaretApplication.Instance.logfile;

            //build list of all reachable actions (this list is a super-set which includes the actions to execute). we will filter this list
            List<ActionNode> allPossibleActionsToExecute = getAllActions();

            //backup current activeTokens
            List<ActivityExecutionToken> activeTokensBackup = new List<ActivityExecutionToken>();
            for (int i = 0; i < activeTokens.Count; i++)
                activeTokensBackup.Add(activeTokens[i]);

            //now filter the list by creating dummy tokens and simulate their advancement
            for (int i=0; i<allPossibleActionsToExecute.Count; ++i)
            {
                //create dummy list
                activeTokens.Clear();

                for (int j=0; j<activeTokensBackup.Count; ++j)
                {
                    //copy the token into a dummy
                    ActivityExecutionToken dummyToken = new ActivityExecutionToken();
                    dummyToken.currentLocation = activeTokensBackup[j].currentLocation;
                    dummyToken.forkStack = activeTokensBackup[j].forkStack;
                    dummyToken.loopNodeStack = activeTokensBackup[j].loopNodeStack;
                    dummyToken.outgoingEdge = activeTokensBackup[j].outgoingEdge;

                    activeTokens.Add(dummyToken);
                }

                //test to see if this action is able to advance a token
                //file.WriteLine(" NB ACTIVE TOKENS : " + activeTokens.Count); file.Flush();

                for (int j = 0; j < activeTokens.Count; ++j)
                {
                    // file.WriteLine(activeTokens[j].currentLocation.name); file.Flush();
                    //advance token without the action (just to be sure we don't get fooled into thinking it advanced because of the action when it advances because of some other conditions that came true)
                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "advancing with dummy action" << endl;
                    ActionNode dummyActionNode = null;
                    tryToAdvanceToken(activeTokens[j], dummyActionNode, true); //care not about the result //TODO .... check this out

                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "advancing dummy token" << endl;

                    //see if the dummy advances with the current action
                    ActivityExecutionToken token = activeTokens[j];
                    //Debug.Log("CURRENT ACTIVE TOKEN : " + token.currentLocation.name);
                    if (tryToAdvanceToken(token, allPossibleActionsToExecute[i], true))
                    {
                        //dummy token advanced, so this action is an action to execute
                        activeTokens[j] = token;

                        toExec.Add(allPossibleActionsToExecute[i]);
                        //Debug.Log("New Current Location : " + activeTokens[j].currentLocation.name);
                        //if (ACTIVATE_GENERAL_DEBUG) cerr << "allPossibleActionsToExecute[" << i << "] = " << allPossibleActionsToExecute[i]->getName() << endl;
                        //break;
                    }
                }
            }

            //reinstate backed up activeTokens
            activeTokens.Clear();
            for (int i = 0; i < activeTokensBackup.Count; i ++ )
                activeTokens.Add(activeTokensBackup[i]);

            //remove already running nodes :: TODO : check if we should allow this or not....
            // file.WriteLine("Action Running : " + actionsRunning.Count); file.Flush();
            for (int i = 0; i < actionsRunning.Count; ++i)
            {
                for (int j = 0; j < toExec.Count; ++j)
                {
                    if (actionsRunning[i].Value == toExec[j])
                    {
                        toExec.RemoveAt(j);
                        j--;
                    }
                }
            }

            return toExec;
        }
        protected bool tryToAdvanceToken(ActivityExecutionToken token, ActionNode doneAction, bool gotTicketToUseAction)
        {
            //TODO : current implementation will fail if the loop node has branches which are not joined together at the end

            //TODO : setup part of loop nodes not implemented
            //TODO : careful if the loop node contains only an initial node :: ENDLESS LOOP

            //		Debug.Log(" current token : " + token.currentLocation.name);

            if (token.currentLocation.Kind == "action")
            {
                ActionNode aNode = (ActionNode)(token.currentLocation);
                if (actionIsCurrentlyRunning(aNode))
                {
                    System.Console.WriteLine(" ACTION is RUNNING : " + aNode.Action.name);
                    //token busy...
                    return(false);
                }
            }


            if (token.outgoingEdge == null)
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null" << endl;
                //Debug.Log(" NO OUTGOING EDGES....");
                //my work here is done *flies away*
                return(false);
            }

            //evaluate guard(s). Normal behavior for fork, but I treat decision nodes here, if there are more paths going out, I will take the first one.
            if (token.currentLocation.Kind == "fork")
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: fork" << endl;

                //normal behavior for fork (should not have guard, but hell... it doesn't hurt to check)
                if (token.outgoingEdge.Guard != null && (!(token.outgoingEdge.Guard.eval(procedure.Activity.Context))))
                {
                    return(false); //eval failed
                }
            }
            else
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: no fork" << endl;

                List <ActivityEdge> outgoingNormal = token.currentLocation.getOutgoingControlFlowEdges();
                bool foundWayOut = false;
                for (int i = 0; i < outgoingNormal.Count; ++i)
                {
                    //if <no guard> or <guard but evaluates ok>
                    if ((outgoingNormal[i].Guard == null) || (outgoingNormal[i].Guard != null && (outgoingNormal[i].Guard.eval(procedure.Activity.Context))))
                    {
                        foundWayOut        = true;
                        token.outgoingEdge = outgoingNormal[i]; //set new direction, we take the first possible one, remember ?
                    }
                }

                if (!foundWayOut)
                {
                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: didn't find way out" << endl;

                    return(false); //no way out... leave for later
                }
            }

            ActivityNode nextLocation = token.outgoingEdge.Target;

            //test allowed action
            if (nextLocation.Kind == "action")
            {
                if ((nextLocation != doneAction) || (!gotTicketToUseAction))
                {
                    //not allowed to advance to this action

                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: action not allowed" << endl;

                    return(false);
                }

                gotTicketToUseAction = false;
            }


            //Debug.Log("Next Location : " + nextLocation);

            //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "adv tok from '" << token->currentLocation->getName() << "' to '" << nextLocation->getName() << "'" << endl;

            //Advance
            ActivityEdge dummyActivityEdge = null;

            token.currentLocation = nextLocation;
            token.outgoingEdge    = dummyActivityEdge;

            List <ActivityEdge> outgoingAfterAdvance = token.currentLocation.getOutgoingControlFlowEdges();

            List <ActivityExecutionToken> nextTokens = new List <ActivityExecutionToken>();

            if (token.currentLocation.Kind == "fork")
            {
                //time to split token into pieces, in order to follow all fork branches

                token.forkStack.Add(token.currentLocation); //push this fork to the stack

                //remove this token from the active list
                for (int i = 0; i < activeTokens.Count; ++i)
                {
                    if (activeTokens[i].ToString() == token.ToString())
                    {
                        activeTokens.RemoveAt(i);
                        break;
                    }
                }

                for (int i = 0; i < outgoingAfterAdvance.Count; ++i)
                {
                    ActivityExecutionToken tok = new ActivityExecutionToken();
                    tok.currentLocation = token.currentLocation;
                    tok.forkStack       = token.forkStack;
                    tok.loopNodeStack   = token.loopNodeStack;
                    tok.outgoingEdge    = outgoingAfterAdvance[i]; //set outgoing, to know which branch to follow

                    //push to active list
                    activeTokens.Add(tok);

                    //save for further use
                    nextTokens.Add(tok);
                }
            }
            else if (token.currentLocation.Kind == "join")
            {
                //we can only pass by a join, if all other branched tokens have arrived in this join
                //the point is that the number of tokens which have the same last fork as this one, should be the same as the nr of incoming links to this join
                //i hope i understand this next time i read it

                List <ActivityEdge> incoming = token.currentLocation.Incoming;        //so get the incoming

                //see which is the last fork of this token
                ActivityNode lastFork = null;
                if (token.forkStack.Count > 0)
                {
                    lastFork = token.forkStack[token.forkStack.Count - 1];
                }

                if (lastFork != null)
                {
                    //find all tokens that have this fork and see if they all finished their branch // TODO: remember that actually, the forkStacks should be identical for paired tokens... if they're not, we've got a problem....
                    List <ActivityExecutionToken> finishedTokens = new List <ActivityExecutionToken>();
                    for (int i = 0; i < activeTokens.Count; ++i)
                    {
                        //if found a token with this last fork
                        if ((activeTokens[i].forkStack.Count > 0) && (activeTokens[i].forkStack[activeTokens[i].forkStack.Count - 1] == lastFork))
                        {
                            //check to see if it's finished (arrived at the same join)
                            if (activeTokens[i].currentLocation == token.currentLocation)
                            {
                                //add to finished tokens list
                                finishedTokens.Add(activeTokens[i]);
                            }
                        }
                    }

                    //now check to see if the number of found tokens equals the number of incoming links to this join
                    if (finishedTokens.Count == incoming.Count)
                    {
                        //then all should be great.... we can merge all tokens into a single one
                        for (int i = 0; i < finishedTokens.Count; ++i)
                        {
                            //skip the current token, this one will remain
                            if (finishedTokens[i].ToString() == token.ToString())
                            {
                                continue;
                            }

                            //seek and destroy
                            for (int j = 0; j < activeTokens.Count; ++j)
                            {
                                if (finishedTokens[i].ToString() == activeTokens[j].ToString())
                                {
                                    //destroy
                                    activeTokens.RemoveAt(j);
                                }
                            }
                        }

                        if (outgoingAfterAdvance.Count == 1)
                        {
                            token.outgoingEdge = outgoingAfterAdvance[0];
                            token.forkStack.RemoveAt(token.forkStack.Count - 1);//pop last fork
                            nextTokens.Add(token);
                        }
                        else if (outgoingAfterAdvance.Count > 1)
                        {
                        }
                    }
                }
                else
                {
                }
            }
            else if (token.currentLocation.Kind == "loop")
            {
                LoopNode loopNode = (LoopNode)(token.currentLocation);

                bool skipThisLoopNode = false;

                if (loopNode.TestedFirst)
                {
                    if (loopNode.eval())             //thou shall pass
                    {
                        skipThisLoopNode = true;
                    }
                }

                ActivityNode        initLoop             = loopNode.Initial;
                List <ActivityEdge> outgoingFromInitLoop = null;

                if (initLoop != null)
                {
                    outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges();
                }

                if (skipThisLoopNode || (initLoop == null) || (outgoingFromInitLoop.Count < 1))
                {
                    //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any
                    if (outgoingAfterAdvance.Count >= 1)
                    {
                        token.outgoingEdge = outgoingAfterAdvance[0];
                        nextTokens.Add(token);
                    }
                }
                else
                {
                    //enter the loop node, we'll get the edge which exits the loopnode's initial node

                    token.currentLocation = initLoop;
                    token.outgoingEdge    = outgoingFromInitLoop[0];
                    token.loopNodeStack.Add(loopNode);
                }
            }
            else
            {
                //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any
                if (outgoingAfterAdvance.Count >= 1)
                {
                    token.outgoingEdge = outgoingAfterAdvance[0];
                    nextTokens.Add(token);
                }
                else if (token.loopNodeStack.Count != 0) //check if we're in a loop node
                {
                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null, but in loop node" << endl;

                    while (((token.outgoingEdge == null)) && (token.loopNodeStack.Count != 0)) //while we are still in a loopnode and it is finished
                    {
                        LoopNode lastLoop = token.loopNodeStack[token.loopNodeStack.Count - 1];
                        if (lastLoop.eval()) //test exit condition
                        {
                            //exiting loop node

                            List <ActivityEdge> outgoingFromLoop = lastLoop.getOutgoingControlFlowEdges();

                            if (outgoingFromLoop.Count != 0)
                            {
                                token.currentLocation = lastLoop;
                                token.outgoingEdge    = outgoingFromLoop[0];
                            }

                            token.loopNodeStack.RemoveAt(token.loopNodeStack.Count - 1); //remove last loop from stack (exit)
                        }
                        else
                        {
                            //restarting loop node

                            ActivityNode        initLoop             = lastLoop.Initial;
                            List <ActivityEdge> outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges();

                            token.currentLocation = initLoop;
                            token.outgoingEdge    = outgoingFromInitLoop[0]; //it should exist, given the fact that we've entered this loop node already
                        }
                    }

                    if (token.outgoingEdge != null)
                    {
                        nextTokens.Add(token);
                    }
                }
            }


            //continue to advance
            for (int i = 0; i < nextTokens.Count; ++i)
            {
                tryToAdvanceToken(nextTokens[i], doneAction, gotTicketToUseAction);
            }

            return(true);
        }
        public void informActionRunning(AID agent, ActionNode action)
        {
            //check if procedure will advance if this action is made
            bool canAdvance = true;

            ActionNode actionToRun = null;

            MascaretApplication.Instance.VRComponentFactory.Log("Start : " + action.getFullName());

            // Test if action owned by agent
            if (action.Partitions[0].name == agentToPartition[agent.toString()].name)
            {
                actionToRun = action;
            }
            else
            {
                MascaretApplication.Instance.VRComponentFactory.Log("This action " + action.getFullName() + " doesn't belong to agent " + agent.toString());
            }
            if (actionToRun != null)
            {
                //check if procedure can advance (action is reachable from the previous done actions)
                List <ActionNode> possibleNextActions = getActionToExecuteFor(agent);

                for (int i = 0; i < possibleNextActions.Count; ++i)
                {
                    if (actionToRun == possibleNextActions[i])
                    {
                        canAdvance = true;
                        break;
                    }
                }
            }

            if (canAdvance)
            {
                //save the running action in the list
                actionsRunning.Add(new KeyValuePair <string, ActionNode>(agent.toString(), action));

                //TODO: appologise because the hack is not so beautiful. the good part is that it works fine :)
                //update next reachable nodes list, if their current location is not a dead end (this caused problems with loopnodes for example...)
                //-- the problem was that loopnodes must not be restarted/skipped until the effect of its actions is understood. this is not the case with decision nodes for example
                ActionNode doneAction = action;

                if (doneAction != null)
                {
                    bool advancedToken = false;
                    for (int i = 0; i < activeTokens.Count; ++i)
                    {
                        if ((activeTokens[i].outgoingEdge == null) ||
                            (activeTokens[i].outgoingEdge.Target.getOutgoingControlFlowEdges().Count == 0))
                        {
                            continue; //skip deadends
                        }
                        //try to advance
                        //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "> trying to advance token " << (i+1) << "/" << _activeTokens.size() << " from " << _activeTokens[i]->currentLocation->getName() << endl;

                        ActivityExecutionToken token = activeTokens[i];
                        if (tryToAdvanceToken(token, doneAction, true))
                        {
                            //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "   >>  advanced token " << (i+1) << "/" << _activeTokens.size() << " to " << _activeTokens[i]->currentLocation->getName() << endl;

                            activeTokens[i] = token;
                            advancedToken   = true;
                        }
                    }

                    if (advancedToken)
                    {
                        //add to "done" list
                        actionsDone.Add(doneAction);

                        MascaretApplication.Instance.VRComponentFactory.Log("AllActionsDone : " + agent.toString());
                        if (!allActionsDone.ContainsKey(agent.toString()))
                        {
                            allActionsDone.Add(agent.toString(), new List <ActionNode>());
                        }
                        allActionsDone[agent.toString()].Add(doneAction);

                        MascaretApplication.Instance.VRComponentFactory.Log("allActionsDoneTimestamps : " + agent.toString());
                        if (!allActionsDoneTimestamps.ContainsKey(agent.toString()))
                        {
                            allActionsDoneTimestamps.Add(agent.toString(), new List <TimeExpression>());
                        }
                        allActionsDoneTimestamps[agent.toString()].Add(doneAction.CurrentExecution.Finish);
                        MascaretApplication.Instance.VRComponentFactory.Log("Done");
                    }
                    else
                    {
                        //if (ACTIVATE_GENERAL_DEBUG) cerr << "HUSTON, WE'VE GOT A PROBLEM... no token was advanced for " << doneAction->getName() << endl;
                    }
                }
            }
        }
        public List <ActionNode> getActionToExecuteForAll()
        {
            //this function simulates token advancement to provide the list of actions that can be executed
            //an action can be executed if it makes a difference in the procedure (if it enables a token to advance)

            //prepare output vector
            List <ActionNode> toExec = new List <ActionNode>();
            // StreamWriter file = MascaretApplication.Instance.logfile;

            //build list of all reachable actions (this list is a super-set which includes the actions to execute). we will filter this list
            List <ActionNode> allPossibleActionsToExecute = getAllActions();

            //backup current activeTokens
            List <ActivityExecutionToken> activeTokensBackup = new List <ActivityExecutionToken>();

            for (int i = 0; i < activeTokens.Count; i++)
            {
                activeTokensBackup.Add(activeTokens[i]);
            }


            //now filter the list by creating dummy tokens and simulate their advancement
            for (int i = 0; i < allPossibleActionsToExecute.Count; ++i)
            {
                //create dummy list
                activeTokens.Clear();

                for (int j = 0; j < activeTokensBackup.Count; ++j)
                {
                    //copy the token into a dummy
                    ActivityExecutionToken dummyToken = new ActivityExecutionToken();
                    dummyToken.currentLocation = activeTokensBackup[j].currentLocation;
                    dummyToken.forkStack       = activeTokensBackup[j].forkStack;
                    dummyToken.loopNodeStack   = activeTokensBackup[j].loopNodeStack;
                    dummyToken.outgoingEdge    = activeTokensBackup[j].outgoingEdge;

                    activeTokens.Add(dummyToken);
                }

                //test to see if this action is able to advance a token
                //file.WriteLine(" NB ACTIVE TOKENS : " + activeTokens.Count); file.Flush();

                for (int j = 0; j < activeTokens.Count; ++j)
                {
                    // file.WriteLine(activeTokens[j].currentLocation.name); file.Flush();
                    //advance token without the action (just to be sure we don't get fooled into thinking it advanced because of the action when it advances because of some other conditions that came true)
                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "advancing with dummy action" << endl;
                    ActionNode dummyActionNode = null;
                    tryToAdvanceToken(activeTokens[j], dummyActionNode, true); //care not about the result //TODO .... check this out

                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "advancing dummy token" << endl;

                    //see if the dummy advances with the current action
                    ActivityExecutionToken token = activeTokens[j];
                    //Debug.Log("CURRENT ACTIVE TOKEN : " + token.currentLocation.name);
                    if (tryToAdvanceToken(token, allPossibleActionsToExecute[i], true))
                    {
                        //dummy token advanced, so this action is an action to execute
                        activeTokens[j] = token;

                        toExec.Add(allPossibleActionsToExecute[i]);
                        //Debug.Log("New Current Location : " + activeTokens[j].currentLocation.name);
                        //if (ACTIVATE_GENERAL_DEBUG) cerr << "allPossibleActionsToExecute[" << i << "] = " << allPossibleActionsToExecute[i]->getName() << endl;
                        //break;
                    }
                }
            }

            //reinstate backed up activeTokens
            activeTokens.Clear();
            for (int i = 0; i < activeTokensBackup.Count; i++)
            {
                activeTokens.Add(activeTokensBackup[i]);
            }

            //remove already running nodes :: TODO : check if we should allow this or not....
            // file.WriteLine("Action Running : " + actionsRunning.Count); file.Flush();
            for (int i = 0; i < actionsRunning.Count; ++i)
            {
                for (int j = 0; j < toExec.Count; ++j)
                {
                    if (actionsRunning[i].Value == toExec[j])
                    {
                        toExec.RemoveAt(j);
                        j--;
                    }
                }
            }

            return(toExec);
        }
        public ProcedureExecution(Procedure procedure, OrganisationalEntity organisation, Agent agent)
        {
            this.procedure    = procedure;
            this.organisation = organisation;
            this.agent        = agent;

            agentToPartition         = new Dictionary <string, ActivityPartition>();
            partitionToAgent         = new Dictionary <ActivityPartition, AID>();
            activeTokens             = new List <ActivityExecutionToken>();
            affectations             = new Dictionary <string, InstanceSpecification>();
            activityParams           = new Dictionary <string, ValueSpecification>();
            actionsRunning           = new List <KeyValuePair <string, ActionNode> >();
            actionsDone              = new List <ActionNode>();
            allActionsDone           = new Dictionary <string, List <ActionNode> >(); // key: AID
            allActionsDoneTimestamps = new Dictionary <string, List <TimeExpression> >();

            for (int i = 0; i < procedure.Activity.Partitions.Count; i++)
            {
                ActivityPartition      partition    = procedure.Activity.Partitions[i];
                List <RoleAssignement> assignements = organisation.RoleAssignement;
                for (int j = 0; j < assignements.Count; j++)
                {
                    if (partition.name == assignements[j].Role.name)
                    {
                        agentToPartition.Add(assignements[j].Agent.toString(), partition);
                        partitionToAgent.Add(partition, assignements[j].Agent);
                        Agent agt = MascaretApplication.Instance.AgentPlateform.Agents[assignements[j].Agent.toString()];
                        if (agt == null)
                        {
                            MascaretApplication.Instance.VRComponentFactory.Log("CA VA TRANCHER");
                        }
                        affectations.Add(partition.name, agt);
                    }
                }
            }

            ActivityExecutionToken initialToken = new ActivityExecutionToken();

            initialToken.currentLocation = procedure.Activity.Initial;

            if (initialToken.currentLocation == null)
            {
                System.Console.WriteLine("ERROR: no initial node found, not allowed");
                System.Console.WriteLine("Procedure will not start.");
                return;
            }

            List <ActivityEdge> controlFlows = procedure.Activity.Initial.getOutgoingControlFlowEdges();

            if (controlFlows.Count == 1)
            {
                initialToken.outgoingEdge = controlFlows[0];
                activeTokens.Add(initialToken);

                ActionNode dummyActionVariable = null;
                tryToAdvanceToken(initialToken, dummyActionVariable, true); //first advancement
            }
            else
            {
                if (controlFlows.Count == 0)
                {
                    System.Console.WriteLine("WARNING: initial node has no outgoing edges");
                }
                else
                {
                    System.Console.WriteLine("ERROR: multiple outgoing edges for the initial node, not allowed");
                }
                System.Console.WriteLine("Procedure will not start.");
            }
        }