private void WriteStructureBody(ILBlock s, HashSet<int> branchTargets, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch = false;
            int childIndex = 0;
            while (inst != null && inst.Offset < s.EndOffset)
            {
                int offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILBlock child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize);
                    WriteStructureFooter(child);
                }
                else
                {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset)))
                    {
                        WriteLine();
                    }
                    WriteInstruction(inst);

                    if (currentMethodMapping != null)
                    {
                        currentMethodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                            {
                                ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset },
                                MemberMapping = currentMethodMapping
                            });
                    }

                    WriteLine();

                    prevInstructionWasBranch = (inst.OpCode.FlowControl == FlowControl.Branch) ||
                                               (inst.OpCode.FlowControl == FlowControl.Cond_Branch) ||
                                               (inst.OpCode.FlowControl == FlowControl.Return) ||
                                               (inst.OpCode.FlowControl == FlowControl.Throw);

                    inst = inst.Next;
                }
                isFirstInstructionInStructure = false;
            }
        }
		internal static MemberMapping CreateCodeMapping(MethodDefinition member, CodeMappings codeMappings)
		{
			if (member == null || !member.HasBody)
				return null;
			
			if (codeMappings == null)
				return null;
			
			MemberMapping currentMemberMapping = null;
			if (codeMappings.FullName == member.DeclaringType.FullName)
			{
				var mapping = codeMappings.Mapping;
				if (mapping.Find(map => (int)map.MetadataToken == member.MetadataToken.ToInt32()) == null)
				{
					currentMemberMapping = new MemberMapping()
					{
						MetadataToken = (uint)member.MetadataToken.ToInt32(),
						MemberReference = member.DeclaringType.Resolve(),
						MemberCodeMappings = new List<SourceCodeMapping>(),
						CodeSize = member.Body.CodeSize
					};
					mapping.Add(currentMemberMapping);
				}
			}
			
			return currentMemberMapping;
		}
        private void Disassemble(MethodBody body, MemberMapping methodMapping)
        {
            MethodDefinition method = body.Method;
            if (method.DeclaringType.Module.Assembly.EntryPoint == method)
            {
                WriteKeyword(".entrypoint");
                WriteLine();
            }

            if (method.Body.HasVariables)
            {
                WriteMethodVariables(method);
                WriteLine();
            }

            if (shouldGenerateBlocks && body.Instructions.Count > 0)
            {
                Instruction inst = body.Instructions[0];
                HashSet<int> branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(new ILBlock(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize);
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    WriteInstruction(inst);

                    if (methodMapping != null)
                    {
                        methodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                            {
                                ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset },
                                MemberMapping = methodMapping
                            });
                    }

                    WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        WriteExceptionHandler(eh);
                        WriteLine();
                    }
                }
            }
        }