/// <summary>
        /// Performs a move out operation on the goto statement. For more information see
        /// Chapter 2.2.1 "Outward-movement Transformations"
        /// </summary>
        /// <param name="gotoStatement"></param>
        /// <param name="label"></param>
        private void MoveOut(IfStatement gotoStatement, string label)
        {
            /// Preprocessing.
            BlockStatement containingBlock = gotoStatement.Parent as BlockStatement;
            BlockStatement outerBlock = GetOuterBlock(containingBlock);
            VariableReferenceExpression conditionVar = new VariableReferenceExpression(GetLabelVariable(label), null);

            ExtractConditionIntoVariable(conditionVar.CloneExpressionOnly() as VariableReferenceExpression, gotoStatement, containingBlock);

            Statement oldEnclosingStatement = containingBlock.Parent;
            if (oldEnclosingStatement is SwitchCase)
            {
                oldEnclosingStatement = oldEnclosingStatement.Parent;
            }
            if (containingBlock.Parent is SwitchCase || containingBlock.Parent is WhileStatement || containingBlock.Parent is DoWhileStatement || containingBlock.Parent is ForStatement
                || containingBlock.Parent is ForEachStatement)
            {
                /// Then we can exit using break.
                /// Create the if - break.
                BlockStatement thenBlock = new BlockStatement();
                thenBlock.AddStatement(new BreakStatement(null));  //might have to keep track of brakes
                IfStatement breakIf = new IfStatement(conditionVar.CloneExpressionOnly(), thenBlock, null);

                /// Replace the original goto
                int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
                containingBlock.Statements.Remove(gotoStatement);
                containingBlock.AddStatementAt(gotoIndex, breakIf);
            }
            else if (containingBlock.Parent is IfStatement || containingBlock.Parent is TryStatement || containingBlock.Parent is IfElseIfStatement)
            {
                /// Then we can exit via introducing another condition.
                int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
                int index = gotoIndex + 1;
                BlockStatement thenBlock = new BlockStatement();
                while (index < containingBlock.Statements.Count)
                {
                    thenBlock.AddStatement(containingBlock.Statements[index]);
                    containingBlock.Statements.RemoveAt(index);
                }
                UnaryExpression condition = new UnaryExpression(UnaryOperator.LogicalNot, conditionVar.CloneExpressionOnly(), null);
                IfStatement innerIf = new IfStatement(condition, thenBlock, null);

                /// At this point the goto statement should be the last one in the block.
                /// Simply replace it with the new if.
                containingBlock.Statements.Remove(gotoStatement);
                /// If the then block is empty, the if should not be added.
                if (innerIf.Then.Statements.Count != 0)
                {
                    containingBlock.AddStatement(innerIf);
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("Goto statement can not leave this parent construct.");
            }

            /// Add the goto statement after the construct.
            /// The goto statement shoud be detached from the AST at this point.
            outerBlock.AddStatementAt(outerBlock.Statements.IndexOf(oldEnclosingStatement) + 1, gotoStatement);
        }
        /// <summary>
        /// Performs a move-in transformation as described in Chapter 2.2.2 in <see cref="Taming Control Flow A Structured Approach to Eliminating Goto Statements.pdf"/>.
        /// </summary>
        /// <param name="gotoStatement">The goto statement to be moved in.</param>
        /// <param name="targetStatement">The statement that the goto will move in.</param>
        /// <param name="label">The target label.</param>
        private void MoveIn(IfStatement gotoStatement, Statement targetStatement, string label)
        {
            /// Preprocessing.
            BlockStatement containingBlock = gotoStatement.Parent as BlockStatement;
            VariableReferenceExpression conditionVar = new VariableReferenceExpression(GetLabelVariable(label), null);

            /// Create the statement conditionVariable = originalCondition;
            /// Add the assigning statement before gotoStatement and replace originalCondition with conditionVariable
            ExtractConditionIntoVariable(conditionVar.CloneExpressionOnly() as VariableReferenceExpression, gotoStatement, containingBlock);

            /// Collect the statements between the goto jump and the target statement.
            int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
            int targetIndex = containingBlock.Statements.IndexOf(targetStatement);
            BlockStatement thenBlock = CollectStatements(gotoIndex + 1, targetIndex, containingBlock);

            /// Create the new if.
            IfStatement outerIfStatement =
                new IfStatement(new UnaryExpression(UnaryOperator.LogicalNot, conditionVar.CloneExpressionOnly(), null), thenBlock, null);

            /// Replace the old goto with the new if statement.
            if (outerIfStatement.Then.Statements.Count > 0)
            {
                containingBlock.AddStatementAt(gotoIndex, outerIfStatement);
            }
            containingBlock.Statements.Remove(gotoStatement);

            /// At this point the original goto statement is completely detached from the AST. It must be reattached as the first statement in the target.
            if (targetStatement is DoWhileStatement)
            {
                /// Loops with more than one entry can be created only by this step, so the do-while loops is the only one
                /// that must be considered.
                (targetStatement as DoWhileStatement).Body.AddStatementAt(0, gotoStatement);
            }
            else if (targetStatement is IfStatement)
            {
                /// If statements with more than one entry to then/else blocks can be created only by this step, so that's why
                /// the only case that must be considered is the case when the target is in the then block.
                IfStatement targetIf = targetStatement as IfStatement;
                targetIf.Condition = UpdateCondition(targetIf.Condition, conditionVar.CloneExpressionOnly() as VariableReferenceExpression); /// This greatly depends on the short-circut evaluation.
                targetIf.Then.AddStatementAt(0, gotoStatement);
            }
            else if (targetStatement is SwitchCase)
            {
                MoveInCase(gotoStatement, targetStatement as SwitchCase, label);
            }
            else if (targetStatement is WhileStatement)
            {
                /// This case should not be reachable.
                WhileStatement @while = targetStatement as WhileStatement;
                @while.Body.AddStatementAt(0, gotoStatement);
                @while.Condition = UpdateCondition(@while.Condition, conditionVar.CloneExpressionOnly() as VariableReferenceExpression);
            }
            else
            {
                throw new NotSupportedException("Unsupported target statement for goto jump.");
            }
        }
        /// <summary>
        /// Contains the logic for moving a  goto inside the case of switch statement. For more information 
        /// see Chapter "2.2.2 Inward-movement Transformations : Moving a goto into a switch statement" from
        /// <see cref="Taming Control Flow A Structured Approach to Eliminating Goto Statements.pdf"/>.
        /// </summary>
        /// <param name="gotoStatement">The goto statement to be moved in.</param>
        /// <param name="switchCase">The switch case that contains the target of the goto statement.</param>
        /// <param name="label">The label of the target.</param>
        private void MoveInCase(IfStatement gotoStatement, SwitchCase switchCase, string label)
        {
            VariableReferenceExpression conditionVariable = new VariableReferenceExpression(GetLabelVariable(label), null);
            BlockStatement containingBlock = GetOuterBlock(gotoStatement);
            SwitchStatement switchStatement = switchCase.Parent as SwitchStatement;

            int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
            int switchIndex = containingBlock.Statements.IndexOf(switchStatement);

            /// Generate variable and extract the switch condition
            string switchVariableName = "switch" + switchStatement.ConditionBlock.First.Offset;
            TypeReference switchVariableType = GetSwitchType(switchStatement);
            VariableDefinition switchVariable = new VariableDefinition(switchVariableName, switchVariableType);
            switchVariables.Add(switchVariable);
            VariableReferenceExpression switchVarEx = new VariableReferenceExpression(switchVariable, null);
            ExtractConditionIntoVariable(switchVarEx, switchStatement, containingBlock);

            BlockStatement thenBlock = CollectStatements(gotoIndex + 1, switchIndex + 1, containingBlock);

            BlockStatement elseBlock = new BlockStatement();

            /// Adds swCond = caseCond; in the last part of else.
            BinaryExpression assignSwitchVariable = new BinaryExpression(BinaryOperator.Assign, switchVarEx.CloneExpressionOnly(), GetCaseConditionExpression(switchCase), typeSystem, null);
            elseBlock.AddStatement(new ExpressionStatement(assignSwitchVariable));

            IfStatement precedingIf = new IfStatement(new UnaryExpression(UnaryOperator.LogicalNot, conditionVariable, null), thenBlock, elseBlock);

            /// Attach new if and move the goto conditional.
            /// Attach it only if the then block is not empty.
            if (precedingIf.Then.Statements.Count != 0)
            {
                containingBlock.AddStatementAt(gotoIndex, precedingIf);
            }
            containingBlock.Statements.Remove(gotoStatement);
            switchCase.Body.AddStatementAt(0, gotoStatement);
        }
        /// <summary>
        /// Extracts the condition of the condition statement into new variable. Replaces the condition of the statement with the new variable and inserts 
        /// the assignment statement right before the condition statement.
        /// </summary>
        /// <param name="conditionVar">The variable which should be assigned the condition.</param>
        /// <param name="gotoStatement">The conditional goto.</param>
        /// <param name="containingBlock">The block that contains the conditional goto.</param>
        private void ExtractConditionIntoVariable(VariableReferenceExpression conditionVar, ConditionStatement statement, BlockStatement containingBlock)
        {
            /// Create the statement conditionVariable = originalCondition;
            BinaryExpression conditionAssignment = new BinaryExpression(BinaryOperator.Assign, conditionVar, statement.Condition, typeSystem, null);
            ExpressionStatement assignStatement = new ExpressionStatement(conditionAssignment);

            /// Insert the statement before the original goto statement.
            int gotoIndex = containingBlock.Statements.IndexOf(statement);
            containingBlock.AddStatementAt(gotoIndex, assignStatement);

            /// Update the condition of the goto statement.
            statement.Condition = conditionVar.CloneExpressionOnly();
        }