/// Author: Max Hamulyak
        /// Date:	08-06-2015
        /// <summary>
        /// Builds the condition class to be used, using priority rules
        /// </summary>
        /// <returns>The condition class.</returns>
        /// <param name="conditions">Conditions.</param>
        /// <param name="priorityOperator">Priority operator.</param>
        protected virtual ICondition BuildConditionClass(List<ICondition> conditions, ELogicOperators priorityOperator, int lineNumber)
        {
            int index = 0;
            bool stopLoop = false;

            while (index < conditions.Count && !stopLoop) {

                if (conditions.Count > 3) {
                    int loopIndex = 0;
                    while (loopIndex < conditions.Count) {
                        ICondition item = conditions.ElementAt (loopIndex);
                        if (item is Operator) {

                            if ((item as Operator).LogicOperator == priorityOperator) {

                                int itemIndex = conditions.IndexOf (item);
                                ICondition left = conditions.ElementAt (itemIndex - 1);
                                ICondition right = conditions.ElementAt (itemIndex + 1);
                                conditions.Remove (left);
                                conditions.Remove (right);
                                conditions.Remove (item);
                                if ((left is Solver) && (right is Solver)) {
                                    ConditionCombo newCondition = new ConditionCombo ((left as Solver), (right as Solver), priorityOperator);
                                    conditions.Insert (itemIndex - 1, newCondition);
                                } else {
                                    throw InvalidConditionCombo (left, right);
                                }
                            }
                        }
                        loopIndex++;
                    }
                    BuildConditionClass (conditions, priorityOperator + 1, lineNumber);
                } else {
                    stopLoop = true;
                }

            }
            //There is only one element, should be concrete instruction, if valid syntax
            ICondition returnCondition = null;
            if (conditions.Count == 1) {
                returnCondition = conditions.ElementAt (0);
            } else if (conditions.Count == 2) {

                if (conditions.ElementAt (0) is Operator) {
                    Operator o = conditions.ElementAt (0) as Operator;
                    if (o.LogicOperator == ELogicOperators.Not) {

                        if (conditions.ElementAt (1) is Solver) {

                            returnCondition = new ConditionCombo (conditions.ElementAt (1) as Solver, o.LogicOperator);

                        } else {
                            throw ExpectedConditionAfterNOT (lineNumber);
                        }

                    } else {
                        throw ExpectedButFound(lineNumber,ETokenType.LogicalOperator,"not", ETokenType.LogicalOperator, o.LogicOperator.ToString());
                    }
                } else {
                    throw ExpectedButFound (lineNumber);
                }

            } else if (conditions.Count == 3) {
                if (conditions.ElementAt (1) is Operator) {

                    if ((conditions.ElementAt (0) is Solver) && (conditions.ElementAt (2) is Solver)) {
                        returnCondition = new ConditionCombo (conditions.ElementAt (0) as Solver, conditions.ElementAt (2) as Solver, (conditions.ElementAt (1) as Operator).LogicOperator);
                    }
                }
            } else {
                throw EmptyConditionCombo (lineNumber);
            }
            return returnCondition;
        }
        public void whileLoop1()
        {
            EOrientation orientation = EOrientation.East;
            Robot robot = Robot.Create (orientation, new Map(EDifficulty.Easy));
            robot.xPosition = 1;
            robot.yPosition = 1;

            Solver condition1 = new ConcreteInstruction (ECanInstructions.Right);
            Solver condition2 = new ConcreteInstruction (ECanInstructions.Forward);
            Solver combo = new ConditionCombo (condition1, condition2, ELogicOperators.Or);

            WhileLoop whileLoop = new WhileLoop (combo);
            bool actual = whileLoop.execute (null);
            bool expected = false;
            Assert.AreEqual (expected, actual);
        }
        public void whileLoop3()
        {
            EOrientation orientation = EOrientation.East;
            Robot robot = Robot.Create (orientation, new Map(EDifficulty.Easy));

            Solver concreteInstruction1 = new ConcreteInstruction (ECanInstructions.Forward); //A
            Solver concreteInstruction2 = new ConcreteInstruction (ECanInstructions.Forward); //A
            Solver notInstruction = new ConditionCombo (concreteInstruction1, ELogicOperators.Not); //!A
            Solver combo = new ConditionCombo (notInstruction, concreteInstruction2, ELogicOperators.And); // !A && A

            ICodeBlock command = new TurnRight ();

            WhileLoop whileLoop = new WhileLoop (combo);
            whileLoop.addChild (command);
            whileLoop.execute (null);

            EOrientation actual = robot.orientationEnum;
            EOrientation expected = EOrientation.East;
            Assert.AreEqual (expected, actual);
        }
        public void SolverOr2()
        {
            Solver leftSolver = new ConcreteInstruction (ECanInstructions.Backward);
            Solver rightSolver = new ConcreteInstruction (ECanInstructions.Backward);
            Solver combo = new ConditionCombo (leftSolver, rightSolver, ELogicOperators.Or);

            EOrientation orientation = EOrientation.East;
            Robot robot = Robot.Create (orientation, new Map(EDifficulty.Easy));

            bool actual = combo.solve (null);
            bool expected = false;
            Assert.AreEqual (expected, actual);
        }