private bool TryGetSimpleCaseStatementType(SwitchCase theCase, out StatementType statementType, out string gotoLabel)
        {
            gotoLabel = null;
            statementType = StatementType.None;
            if (theCase.Body.Statements.Count != 1 || !string.IsNullOrEmpty(theCase.Body.Statements[0].Label))
            {
                return false;
            }

            Statement statement = theCase.Body.Statements[0];
            if (statement is GotoStatement)
            {
                statementType = StatementType.Goto;
                gotoLabel = (statement as GotoStatement).TargetLabel;
            }
            else if (statement is BreakStatement)
            {
                statementType = StatementType.Break;
            }
            else if (statement is ContinueStatement)
            {
                statementType = StatementType.Continue;
            }

            return statementType != StatementType.None;
        }
 public void AddCase(SwitchCase @case)
 {
     cases.Add(@case);
     @case.Parent = this;
     needsRefreshing = true;
 }
        /// <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>
        /// Gets the condition that is representing the supplied case.
        /// </summary>
        /// <param name="switchCase">The switch case, whose condition is being needed.</param>
        /// <returns>Returns expression, evaluating so that the switch jumps to <paramref name="switchCase"/>.</returns>
        private Expression GetCaseConditionExpression(SwitchCase switchCase)
        {
            if (switchCase is ConditionCase)
            {
                return (switchCase as ConditionCase).Condition;
            }
            else
            {
                /// SwitchCase is the default case
                SwitchStatement switchStatement = switchCase.Parent as SwitchStatement;
                //TypeReference switchType = GetSwitchType(switchCase.Parent as SwitchStatement);

                /// this could possibly be long instead of int, but this case should be quite rare
                int result = 1;
                foreach (SwitchCase @case in switchStatement.Cases)
                {
                    if (@case is DefaultCase)
                    {
                        continue;
                    }
                    result += (int)(((@case as ConditionCase).Condition as LiteralExpression).Value);
                }
                return GetLiteralExpression(result);
            }
        }
		public CaseGotoStatement(GotoStatement transformedGoto, SwitchCase targetedCase) : base(transformedGoto.Label, transformedGoto.UnderlyingSameMethodInstructions)
		{
			this.TargetedSwitchCase = targetedCase;
		}
		/// <summary>
		/// Copy-constructor for cloning purposes.
		/// </summary>
		/// <param name="toClone">The statement to clone.</param>
		private CaseGotoStatement(CaseGotoStatement toClone, IEnumerable<Instruction> instructions) : base(toClone.Label, instructions)
		{
			this.TargetedSwitchCase = toClone.TargetedSwitchCase;
		}
 public CaseGotoStatement(GotoStatement transformedGoto, SwitchCase targetedCase)
 {
     base(transformedGoto.get_Label(), transformedGoto.get_UnderlyingSameMethodInstructions());
     this.set_TargetedSwitchCase(targetedCase);
     return;
 }