/// <summary>
        /// Generates the finally block.
        /// </summary>
        /// <remarks>
        /// Since the condition block and the dispose invocation block should have a common successor, a new EmptyBlockLogicalConstruct
        /// is added to the logical tree.
        /// </remarks>
        /// <returns></returns>
        private BlockLogicalConstruct GenerateFinallyBlock()
        {
            CFGBlockLogicalConstruct finallySuccessor = ProcessFinallyNode(finallyEntryBlock, disposeCallBlock);

            finallySuccessor.RemoveFromPredecessors(conditionBlock);
            conditionBlock.RemoveFromSuccessors(finallySuccessor);

            EmptyBlockLogicalConstruct emptyCommonNode = new EmptyBlockLogicalConstruct(++logicalContext.MaxBlockIndex);

            emptyCommonNode.AddToPredecessors(disposeCallBlock);
            emptyCommonNode.AddToPredecessors(conditionBlock);
            disposeCallBlock.AddToSuccessors(emptyCommonNode);
            conditionBlock.AddToSuccessors(emptyCommonNode);

            emptyCommonNode.Parent = finallyEntryBlock.Parent;
            emptyCommonNode.Parent.Children.Add(emptyCommonNode);

            for (int i = 0; i < conditionBlock.TheBlock.Successors.Length; i++)
            {
                if (conditionBlock.TheBlock.Successors[i] == finallySuccessor.TheBlock)
                {
                    conditionBlock.TheBlock.Successors[i] = null;
                }
            }

            finallyBlocks.Add(emptyCommonNode);
            return(new BlockLogicalConstruct(finallyEntryBlock, finallyBlocks));
        }
        /// <summary>
        /// Redirect the predecessors and successors of the finally block.
        /// </summary>
        /// <remarks>
        /// Check if the finallyBlockEntry is only reachable by nodes in the try block.
        /// Make the successor of the finallyBlockEnd successor to all of the predecessors of the finallyBlockEntry.
        /// This will detach the finally block from the subgraph, which is a desired result since every normal finally block is not reachable from any where
        /// (the CLR takes care of executing the code in the finally block).
        /// </remarks>
        /// <param name="finallyBlockEntry"></param>
        /// <param name="finallyBlockEnd"></param>
        /// <returns>The successor of the finally block.</returns>
        private CFGBlockLogicalConstruct ProcessFinallyNode(CFGBlockLogicalConstruct finallyBlockEntry, CFGBlockLogicalConstruct finallyBlockEnd)
        {
            foreach (ILogicalConstruct predecessor in finallyBlockEntry.SameParentPredecessors)
            {
                if (!newTryBody.Contains(predecessor))
                {
                    throw new Exception("Invalid entry to the finally block");
                }
            }

            CFGBlockLogicalConstruct finallySuccessor;

            using (IEnumerator <CFGBlockLogicalConstruct> enumerator = finallyBlockEnd.CFGSuccessors.GetEnumerator())
            {
                enumerator.MoveNext();
                finallySuccessor = enumerator.Current;

                if (enumerator.MoveNext())
                {
                    throw new Exception("Invalid count of successors");
                }
            }

            HashSet <CFGBlockLogicalConstruct> finallyCFGPredecessors = new HashSet <CFGBlockLogicalConstruct>(finallyBlockEntry.CFGPredecessors);

            foreach (CFGBlockLogicalConstruct cfgPredecessor in finallyCFGPredecessors)
            {
                if (cfgPredecessor.TheBlock != finallyBlockEntry.TheBlock && cfgPredecessor.TheBlock.Successors.Length > 1)
                {
                    ProcessMultiWayCFGPredecessor(finallyBlockEntry, cfgPredecessor.TheBlock, finallySuccessor.TheBlock);
                }

                LogicalConstructBase currenConstruct = cfgPredecessor;
                while (currenConstruct != finallyBlockEntry.Parent)
                {
                    currenConstruct.RemoveFromSuccessors(finallyBlockEntry);
                    currenConstruct.AddToSuccessors(finallySuccessor);

                    currenConstruct = currenConstruct.Parent as LogicalConstructBase;
                }

                finallySuccessor.AddToPredecessors(cfgPredecessor);
                finallyBlockEntry.RemoveFromPredecessors(cfgPredecessor);
            }

            finallySuccessor.RemoveFromPredecessors(finallyBlockEnd);
            finallyBlockEnd.RemoveFromSuccessors(finallySuccessor);

            return(finallySuccessor);
        }
 private CFGBlockLogicalConstruct ProcessFinallyNode(CFGBlockLogicalConstruct finallyBlockEntry, CFGBlockLogicalConstruct finallyBlockEnd)
 {
     V_1 = finallyBlockEntry.get_SameParentPredecessors().GetEnumerator();
     try
     {
         while (V_1.MoveNext())
         {
             V_2 = (ILogicalConstruct)V_1.get_Current();
             if (this.newTryBody.Contains(V_2))
             {
                 continue;
             }
             throw new Exception("Invalid entry to the finally block");
         }
     }
     finally
     {
         ((IDisposable)V_1).Dispose();
     }
     V_3 = finallyBlockEnd.get_CFGSuccessors().GetEnumerator();
     try
     {
         dummyVar0 = V_3.MoveNext();
         V_0       = V_3.get_Current();
         if (V_3.MoveNext())
         {
             throw new Exception("Invalid count of successors");
         }
     }
     finally
     {
         if (V_3 != null)
         {
             V_3.Dispose();
         }
     }
     V_4 = (new HashSet <CFGBlockLogicalConstruct>(finallyBlockEntry.get_CFGPredecessors())).GetEnumerator();
     try
     {
         while (V_4.MoveNext())
         {
             V_5 = V_4.get_Current();
             if (InstructionBlock.op_Inequality(V_5.get_TheBlock(), finallyBlockEntry.get_TheBlock()) && (int)V_5.get_TheBlock().get_Successors().Length > 1)
             {
                 this.ProcessMultiWayCFGPredecessor(finallyBlockEntry, V_5.get_TheBlock(), V_0.get_TheBlock());
             }
             V_6 = V_5;
             while (V_6 != finallyBlockEntry.get_Parent())
             {
                 dummyVar1 = V_6.RemoveFromSuccessors(finallyBlockEntry);
                 V_6.AddToSuccessors(V_0);
                 V_6 = V_6.get_Parent() as LogicalConstructBase;
             }
             V_0.AddToPredecessors(V_5);
             dummyVar2 = finallyBlockEntry.RemoveFromPredecessors(V_5);
         }
     }
     finally
     {
         ((IDisposable)V_4).Dispose();
     }
     dummyVar3 = V_0.RemoveFromPredecessors(finallyBlockEnd);
     dummyVar4 = finallyBlockEnd.RemoveFromSuccessors(V_0);
     return(V_0);
 }