BlockInstr findProxyCall(DelegateInfo di, Block block, int index, Dictionary<Block, bool> visited, int stack)
        {
            if (visited.ContainsKey(block))
                return null;
            if (index <= 0)
                visited[block] = true;

            var instrs = block.Instructions;
            for (int i = index + 1; i < instrs.Count; i++) {
                if (stack <= 0)
                    return null;
                var instr = instrs[i];
                DotNetUtils.updateStack(instr.Instruction, ref stack, false);
                if (stack < 0)
                    return null;

                if (instr.OpCode != OpCodes.Call && instr.OpCode != OpCodes.Callvirt)
                    continue;
                var method = DotNetUtils.getMethod(module, instr.Operand as MethodReference);
                if (method == null)
                    continue;
                if (stack != (DotNetUtils.hasReturnValue(method) ? 1 : 0))
                    continue;
                if (method.DeclaringType != di.field.DeclaringType)
                    continue;

                return new BlockInstr {
                    Block = block,
                    Index = i,
                };
            }
            if (stack <= 0)
                return null;

            foreach (var target in block.getTargets()) {
                var info = findProxyCall(di, target, -1, visited, stack);
                if (info != null)
                    return info;
            }

            return null;
        }