/*
         * geração das transitions baseado no protocolo da ação.
         */
        public List <Transition> getTransitions(XmlNode node, MetaUnit unit, int initial, int final, int numStates, int numTransations)
        {
            List <Transition>  transitions = new List <Transition> ();
            Queue <Transition> treat       = new Queue <Transition> ();

            //Console.WriteLine("Initial {0} | Final {1} | numStates {2} | numTrans {3}", initial, final, numStates, numTransations);
            treat.Enqueue(new Transition(initial, final, node, numTransations++));

            Transition   t;
            XmlNode      pivotNode, child, guardNode;
            XmlNodeList  children;
            XmlAttribute attr;
            Condition    condition;
            int          initialState, finalState;
            bool         repeat;

            initialState = finalState = 0;

            while (treat.Count > 0)
            {
                t         = treat.Dequeue();
                pivotNode = (XmlNode)t.Action;
                t.Action  = null;
                transitions.Add(t);
                condition = null;

                attr = (XmlAttribute)pivotNode.Attributes.GetNamedItem("id");
                if (attr != null)
                {
                    t.AddId(attr.Value);
                }

                repeat = false;
                attr   = (XmlAttribute)pivotNode.Attributes.GetNamedItem("repeat");
                if (attr != null)
                {
                    repeat = attr.Value.Equals("true");
                }

                guardNode = pivotNode.SelectSingleNode("guard");
                condition = null;

                //Console.WriteLine("[XmlLoaderUtil.getTransitions] Ação a avaliar... {0}", pivotNode.Name);
                if (pivotNode.Name.Equals("seq") || pivotNode.Name.Equals("par"))
                {
                    if (guardNode != null)
                    {
                        condition = getCondition(guardNode);
                        Transition tElse;
                        initialState = numStates++;

                        if (condition != null)                           //condition nao é else.
                        {
                            transitions.Add(new Transition(t.InitialState, initialState, new ExecutionAction(null, condition), Transition.INTERNAL_TRANSITION));
                            tElse = new Transition(t.InitialState, t.FinalState, Configuration.LAMBDA_TRANSITION, Transition.INTERNAL_TRANSITION);
                        }
                        else
                        {
                            tElse = new Transition(t.InitialState, initialState, Configuration.LAMBDA_TRANSITION, Transition.INTERNAL_TRANSITION);
                        }

                        tElse.IsElse = true;
                        transitions.Add(tElse);
                    }
                    else
                    {
                        initialState = t.InitialState;
                    }
                }

                switch (pivotNode.Name)
                {
                case "seq":

                    children = pivotNode.ChildNodes;

                    for (int r = 0; r < children.Count; r++)
                    {
                        child = children.Item(r);

                        if (child.Name.Equals("guard"))
                        {
                            continue;
                        }

                        if (r == (children.Count - 1))
                        {
                            if (repeat)
                            {
                                finalState = t.InitialState;
                            }
                            else
                            {
                                finalState = t.FinalState;
                            }
                        }
                        else
                        {
                            finalState = numStates++;
                        }

                        treat.Enqueue(new Transition(initialState, finalState, child.FirstChild, numTransations++));

                        initialState = finalState;
                    }

                    break;

                case "par":


                    children = pivotNode.ChildNodes;


                    if (repeat)
                    {
                        finalState = numStates++;
                        transitions.Add(new Transition(finalState, t.InitialState, Configuration.LAMBDA_TRANSITION, Transition.INTERNAL_TRANSITION));
                    }
                    else
                    {
                        finalState = t.FinalState;
                    }

                    for (int r = 0; r < children.Count; r++)
                    {
                        child = children.Item(r);

                        if (child.Name.Equals("guard"))
                        {
                            continue;
                        }

                        treat.Enqueue(new Transition(initialState, finalState, child.FirstChild, numTransations++));
                    }

                    break;

                case "perform":
                    bool isElse = false;

                    initialState = t.InitialState;
                    finalState   = t.FinalState;

                    child = pivotNode;

                    if (guardNode != null)
                    {
                        condition = getCondition(guardNode);

                        if (condition == null)
                        {
                            isElse = true;
                        }
                    }
                    attr = (XmlAttribute)child.Attributes.GetNamedItem("slice_id");
                    //Console.WriteLine("[XmlLoaderUtil.getTransitions] Avaliando ação sobre a fatia {0}", attr.Value);
                    string sliceName = "";
                    if (attr != null)
                    {
                        sliceName = attr.Value;
                    }

                    string methodName = child.Attributes.GetNamedItem("action_id").Value;
                    //Console.WriteLine("[XmlLoaderUtil.getTransitions] Avaliando ação {0}", methodName);
                    MetaAction selectedAction = null;

                    if (sliceName.Equals(""))
                    {
                        //Console.WriteLine("[XmlLoaderUtil.getTransitions] unit {0} | action {1}", unit.Name, methodName);
                        unit.Actions.TryGetValue(methodName, out selectedAction);

                        //Console.WriteLine("[XmlLoaderUtil.getTransitions] Action {0} encontrada? {1}",methodName, selectedAction != null);

                        if (selectedAction == null)
                        {
                            selectedAction        = new MetaAction();
                            selectedAction.Id     = generator.genId();
                            selectedAction.Name   = methodName;
                            selectedAction.Father = unit;
                            unit.AddAction(methodName, selectedAction);
                        }
                    }
                    else
                    {
                        MetaSlice slice = null;
                        //Console.WriteLine("[XmlLoaderUtil.getTransitions] slice {0}", sliceName);

                        unit.Slices.TryGetValue(sliceName, out slice);

                        if (slice == null && candidateSlices != null)
                        {
                            candidateSlices.TryGetValue(sliceName, out slice);
                        }

                        if (slice != null)
                        {
                            //Console.WriteLine("[XmlLoaderUtil.getTransitions] slice {0} encontrada", sliceName);

                            if (slice.Unit.Actions != null)
                            {
                                foreach (MetaAction mact in slice.Unit.Actions.Values)
                                {
                                    if (mact.Name.Equals(methodName))
                                    {
                                        selectedAction = mact;
                                        break;
                                    }
                                }
                            }

                            if (selectedAction == null)
                            {
                                selectedAction        = new MetaAction();
                                selectedAction.Id     = generator.genId();
                                selectedAction.Name   = methodName;
                                selectedAction.Father = slice.Unit;
                                slice.Unit.AddAction(methodName, selectedAction);
                            }
                        }
                    }

                    if (selectedAction != null)
                    {
                        Transition tst = new Transition(initialState, finalState, new ExecutionAction(selectedAction, condition), numTransations++);
                        tst.IsElse = isElse;
                        transitions.Add(tst);
                    }
                    else
                    {
                        throw new Exception("Fatia inexistente nesta unidade: " + sliceName);
                    }

                    break;

                default:
                    throw new Exception("invalid action: " + pivotNode.Name);
                }
            }

            this.numStates      = numStates;
            this.numTransations = numTransations;
            return(transitions);
        }
        /*
         * Procura e retorna a fatia procurada. Ela corresponde a uma unidade de um innerComponent.
         * Caso não exista, a unidade será criada, atribuída ao innerComponent e ao final retornada.
         *
         * Caso innerComponent citado não exista, o retorno do método será nulo.
         */
        public Dictionary <string, MetaSlice> getSlices(XmlNodeList sliceNodes)
        {
            Dictionary <string, MetaSlice> slices = new Dictionary <string, MetaSlice> ();

            List <MetaInnerComponent> innerList = new List <MetaInnerComponent>();

            innerList.AddRange(innerComponents);
            if (candidateInnerComponents != null)
            {
                innerList.AddRange(candidateInnerComponents);
            }

            if (sliceNodes != null)
            {
                MetaUnit     unit = null;
                MetaSlice    slice = null;
                string       innerName, unitName;
                int          index;
                XmlAttribute attr;
                XmlNode      sliceNode;

                IEnumerator senum = (IEnumerator)sliceNodes.GetEnumerator();

                while (senum.MoveNext())
                {
                    sliceNode = (XmlNode)senum.Current;

                    attr      = (XmlAttribute)sliceNode.Attributes.GetNamedItem("inner");
                    innerName = attr.Value;

                    attr     = (XmlAttribute)sliceNode.Attributes.GetNamedItem("unit");
                    unitName = attr.Value;

                    attr = (XmlAttribute)sliceNode.Attributes.GetNamedItem("index");
                    if (attr != null)
                    {
                        index = Convert.ToInt32(attr.Value);
                    }
                    else
                    {
                        index = 0;
                    }

                    foreach (MetaInnerComponent comp in innerList)
                    {
                        if (comp.Identifier.Equals(innerName))
                        {
                            if (comp.Units != null)
                            {
                                //TODO deveria usar a indexacao do dictionary. O index pode trazer problemas.
                                foreach (MetaUnit u in comp.Units.Values)
                                {
                                    if (u.Name.Equals(unitName) /* && u.Index.Equals (index)*/)
                                    {
                                        unit = u;
                                        break;
                                    }
                                }
                            }

                            if (unit == null)
                            {
                                unit        = new MetaUnit();
                                unit.Id     = generator.genId();
                                unit.Father = comp;
                                unit.Name   = unitName;
                                unit.Index  = index;

                                comp.AddUnit(unit.Name, unit);
                            }

                            break;
                        }
                    }

                    if (unit != null)
                    {
                        slice       = new MetaSlice(unit);
                        slice.Inner = innerName;

                        unit = null;
                    }

                    if (slice != null)
                    {
                        slices.Add(innerName, slice);
                    }
                    else
                    {
                        throw new Exception("Erro ao carregar fatia: Inner component inexistente: " + innerName);
                    }
                }
            }

            return(slices);
        }