private Block CreateBlock(BlockLoadState blockState, int nextInstructionCount, ref int totalBranchCount)
        {
            // Calculate branch count for block
            int branchCount            = 0;
            int zeroStackSizeNodeCount = blockState.ZeroStackSizeNodes.Count;

            do
            {
                branchCount++;
                zeroStackSizeNodeCount--;
                totalBranchCount--;
                blockState.InstructionCount /= 2;
            }while (totalBranchCount > 0 && zeroStackSizeNodeCount > 0 && blockState.InstructionCount > nextInstructionCount);

            var block = new Block();

            block.Node = blockState.Node;

            // Sections
            int sectionCount = branchCount + 1;
            var sections     = new BlockSection[sectionCount];

            // Create
            for (int i = 0; i < sectionCount; i++)
            {
                sections[i] = new BlockSection();
            }

            // Init
            var firstSection = sections[0];

            firstSection.ProxyNode = blockState.Node.FirstChild.AddPrevious(OpCodes.Nop);
            firstSection.CodeNode  = firstSection.ProxyNode.AddNext(OpCodes.Nop);

            var lastSection = sections[sectionCount - 1];

            lastSection.LastNode = blockState.Node.LastChild.AddNext(OpCodes.Nop);

            int sectionOffsetSize = blockState.ZeroStackSizeNodes.Count / sectionCount;

            for (int i = 0; i < branchCount; i++)
            {
                var section1 = sections[i];
                var section2 = sections[i + 1];

                int branchIndex       = (sectionOffsetSize * (i + 1));
                var branchInstruction = blockState.ZeroStackSizeNodes[branchIndex];

                section1.Next      = section2;
                section1.LastNode  = branchInstruction.AddPrevious(OpCodes.Nop);
                section2.ProxyNode = section1.LastNode.AddNext(OpCodes.Nop);
                section2.CodeNode  = section2.ProxyNode.AddNext(OpCodes.Nop);
            }

            block.Sections     = sections;
            block.FirstSection = sections[0];

            return(block);
        }
        private void Load(LoadState state, ILBlock block)
        {
            var  zeroStackSizeNodes = new List <ILNode>();
            int  instructionCount   = 0;
            bool hasChildren        = false;
            var  node = block.FirstChild;

            while (node != null)
            {
                switch (node.NodeType)
                {
                case ILNodeType.Instruction:
                {
                    var instruction = (ILInstruction)node;

                    int stackSize;
                    if (state.StackSizeByInstruction.TryGetValue(instruction, out stackSize) && stackSize == 0)
                    {
                        if (CanBranchAtInstruction(instruction))
                        {
                            zeroStackSizeNodes.Add(instruction);
                        }
                    }

                    instructionCount++;
                }
                break;

                case ILNodeType.Block:
                {
                    var tryBlock = node as ILTryBlock;
                    if (tryBlock != null)
                    {
                        if (node.PreviousSibling != null)
                        {
                            zeroStackSizeNodes.Add(tryBlock);
                        }

                        hasChildren = true;
                        instructionCount++;
                    }
                }
                break;
                }

                node = node.NextSibling;
            }

            state.TotalInstructionCount += instructionCount;

            if (zeroStackSizeNodes.Count > 0)
            {
                var blockState = new BlockLoadState();
                blockState.Index              = state.Blocks.Count;
                blockState.InstructionCount   = instructionCount;
                blockState.Node               = block;
                blockState.ZeroStackSizeNodes = zeroStackSizeNodes;
                state.Blocks.Add(blockState);
            }

            // Load child blocks
            if (hasChildren)
            {
                node = block.FirstChild;
                while (node != null)
                {
                    var tryBlock = node as ILTryBlock;
                    if (tryBlock != null)
                    {
                        Load(state, tryBlock);
                    }

                    node = node.NextSibling;
                }
            }
        }