/// <summary>
 /// Try to find a rule, in this state machine, or in a sub state machine
 /// which
 /// </summary>
 /// <param name="ruleConditions"></param>
 /// <param name="priority"></param>
 /// <param name="currentStateVariable">The variable which holds the current state of the procedure</param>
 private void EvaluateStateMachine(List <Rules.RuleCondition> ruleConditions, Generated.acceptor.RulePriority priority, Variables.IVariable currentStateVariable)
 {
     if (currentStateVariable != null)
     {
         Constants.State    currentState        = currentStateVariable.Value as Constants.State;
         Types.StateMachine currentStateMachine = currentState.StateMachine;
         while (currentStateMachine != null)
         {
             foreach (Rule rule in currentStateMachine.Rules)
             {
                 rule.Evaluate(this, priority, currentStateVariable, ruleConditions);
             }
             currentStateMachine = currentStateMachine.EnclosingStateMachine;
         }
     }
 }
        /// <summary>
        /// Provides the possible references for this designator (only available during semantic analysis)
        /// </summary>
        /// <param name="instance">the instance on which this element should be found.</param>
        /// <param name="expectation">the expectation on the element found</param>
        /// <param name="lastElement">Indicates that this element is the last one in a dereference chain</param>
        /// <returns></returns>
        public ReturnValue getReferences(INamable instance, Filter.AcceptableChoice expectation, bool lastElement)
        {
            ReturnValue retVal = new ReturnValue(this);

            if (instance == null)
            {
                // Special handling for THIS
                if (Image.CompareTo("THIS") == 0)
                {
                    INamable currentElem = Root;
                    while (currentElem != null)
                    {
                        Types.Type type = currentElem as Types.Type;
                        if (type != null)
                        {
                            Types.StateMachine stateMachine = type as Types.StateMachine;
                            while (stateMachine != null)
                            {
                                type         = stateMachine;
                                stateMachine = stateMachine.EnclosingStateMachine;
                            }
                            retVal.Add(type);
                            return(retVal);
                        }
                        currentElem = enclosing(currentElem);
                    }

                    return(retVal);
                }

                // No enclosing instance. Try to first name of a . separated list of names
                //  . First in the enclosing expression
                InterpreterTreeNode current = this;
                while (current != null)
                {
                    ISubDeclarator subDeclarator = current as ISubDeclarator;
                    if (FillBySubdeclarator(subDeclarator, expectation, retVal) > 0)
                    {
                        // If this is the last element in the dereference chain, stop at first match
                        if (lastElement)
                        {
                            return(retVal);
                        }
                        current = null;
                    }
                    else
                    {
                        current = current.Enclosing;
                    }
                }

                // . In the predefined elements
                addReference(EFSSystem.getPredefinedItem(Image), expectation, retVal);
                if (lastElement && !retVal.IsEmpty)
                {
                    return(retVal);
                }

                // . In the enclosing items, except the enclosing dictionary since dictionaries are handled in a later step
                INamable currentNamable = Root;
                while (currentNamable != null)
                {
                    Utils.ISubDeclarator subDeclarator = currentNamable as Utils.ISubDeclarator;
                    if (subDeclarator != null && !(subDeclarator is Dictionary))
                    {
                        if (FillBySubdeclarator(subDeclarator, expectation, retVal) > 0 && lastElement)
                        {
                            return(retVal);
                        }
                    }

                    currentNamable = enclosingSubDeclarator(currentNamable);
                }

                // . In the dictionaries declared in the system
                foreach (Dictionary dictionary in EFSSystem.Dictionaries)
                {
                    if (FillBySubdeclarator(dictionary, expectation, retVal) > 0 && lastElement)
                    {
                        return(retVal);
                    }

                    Types.NameSpace defaultNameSpace = dictionary.findNameSpace("Default");
                    if (defaultNameSpace != null)
                    {
                        if (FillBySubdeclarator(defaultNameSpace, expectation, retVal) > 0 && lastElement)
                        {
                            return(retVal);
                        }
                    }
                }
            }
            else
            {
                // The instance is provided, hence, this is not the first designator in the . separated list of designators
                if (instance is Types.ITypedElement && !(instance is Constants.State))
                {
                    // If the instance is a typed element, dereference it to its corresponding type
                    Types.ITypedElement element = instance as Types.ITypedElement;
                    if (element.Type != EFSSystem.NoType)
                    {
                        instance = element.Type;
                    }
                }

                // Find the element in all enclosing sub declarators of the instance
                while (instance != null)
                {
                    Utils.ISubDeclarator subDeclarator = instance as Utils.ISubDeclarator;
                    if (FillBySubdeclarator(subDeclarator, expectation, retVal) > 0)
                    {
                        instance = null;
                    }
                    else
                    {
                        if (instance is Dictionary)
                        {
                            instance = enclosingSubDeclarator(instance);
                        }
                        else
                        {
                            instance = null;
                        }
                    }
                }
            }

            return(retVal);
        }
        /// <summary>
        /// Provides the type of this expression
        /// </summary>
        /// <returns></returns>
        public override Types.Type GetExpressionType()
        {
            Types.Type retVal = null;

            Types.Type leftType = Left.GetExpressionType();
            if (leftType == null)
            {
                AddError("Cannot determine expression type (1) for " + Left.ToString());
            }
            else
            {
                Types.Type rightType = Right.GetExpressionType();
                if (rightType == null)
                {
                    AddError("Cannot determine expression type (2) for " + Right.ToString());
                }
                else
                {
                    switch (Operation)
                    {
                    case OPERATOR.EXP:
                    case OPERATOR.MULT:
                    case OPERATOR.DIV:
                    case OPERATOR.ADD:
                    case OPERATOR.SUB:
                        if (leftType.Match(rightType))
                        {
                            if (leftType is Types.IntegerType || leftType is Types.DoubleType)
                            {
                                retVal = rightType;
                            }
                            else
                            {
                                retVal = leftType;
                            }
                        }
                        else
                        {
                            retVal = leftType.CombineType(rightType, Operation);
                        }

                        break;

                    case OPERATOR.AND:
                    case OPERATOR.OR:
                        if (leftType == EFSSystem.BoolType && rightType == EFSSystem.BoolType)
                        {
                            retVal = EFSSystem.BoolType;
                        }
                        break;

                    case OPERATOR.EQUAL:
                    case OPERATOR.NOT_EQUAL:
                    case OPERATOR.LESS:
                    case OPERATOR.LESS_OR_EQUAL:
                    case OPERATOR.GREATER:
                    case OPERATOR.GREATER_OR_EQUAL:
                        if (leftType.Match(rightType) || rightType.Match(leftType))
                        {
                            retVal = EFSSystem.BoolType;
                        }
                        break;

                    case OPERATOR.IN:
                    case OPERATOR.NOT_IN:
                        Types.Collection collection = rightType as Types.Collection;
                        if (collection != null)
                        {
                            if (collection.Type == null)
                            {
                                retVal = EFSSystem.BoolType;
                            }
                            else if (collection.Type == leftType)
                            {
                                retVal = EFSSystem.BoolType;
                            }
                        }
                        else
                        {
                            Types.StateMachine stateMachine = rightType as Types.StateMachine;
                            if (stateMachine != null && leftType.Match(stateMachine))
                            {
                                retVal = EFSSystem.BoolType;
                            }
                        }
                        break;

                    case OPERATOR.UNDEF:
                        break;
                    }
                }
            }

            return(retVal);
        }