protected override void ImplementOnException(InstructionBlock block, ITypeSignature exceptionType, InstructionWriter writer)
                {
                    MethodDefDeclaration targetMethod = this.transformationInstance.AspectWeaverInstance.TargetElement as MethodDefDeclaration;

                    if (targetMethod == null)
                    {
                        return;
                    }

                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder  = this.backendInstance.GetCategoryBuilder(category);
                    InstructionSequence     sequence = block.AddInstructionSequence(null, NodePosition.After, null);

                    writer.AttachInstructionSequence(sequence);

                    LocalVariableSymbol exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable(
                        exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex"));

                    LogSeverity logSeverity = LogSeverity.Warning;

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, logSeverity);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    builder.EmitWrite(writer, block, "An exception occurred:\n{0}", 1, logSeverity,
                                      w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal),
                                      (i, w) => w.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal));

                    writer.EmitInstruction(OpCodeNumber.Rethrow);
                    writer.DetachInstructionSequence();
                }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer, MethodDefDeclaration targetMethod, string messageFormatString)
                {
                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);

                    writer.AttachInstructionSequence(sequence);

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, LogSeverity.Trace);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    int  parameterCount = Context.MethodMapping.MethodSignature.ParameterCount;
                    bool hasThis        = Context.MethodMapping.MethodSignature.CallingConvention == CallingConvention.HasThis;

                    builder.EmitWrite(writer, block, messageFormatString, parameterCount, LogSeverity.Trace, null,
                                      (i, instructionWriter) =>
                    {
                        instructionWriter.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)(hasThis ? i + 1 : i));
                        instructionWriter.EmitConvertToObject(
                            this.Context.MethodMapping.MethodSignature.GetParameterType(i));
                    });

                    writer.DetachInstructionSequence();
                }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer,
                                         LogLevel logLevel, string messageFormatString, int[] arguments, ITypeSignature exceptionType = null)
                {
                    MethodDefDeclaration targetMethod = Context.TargetElement as MethodDefDeclaration;

                    if (targetMethod == null)
                    {
                        return;
                    }

                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);

                    writer.AttachInstructionSequence(sequence);

                    LocalVariableSymbol exceptionLocal = null;

                    if (exceptionType != null)
                    {
                        exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable(
                            exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex"));
                    }

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, logLevel);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    bool useWrapper = ShouldUseWrapper(targetMethod);

                    Action <InstructionWriter> getExceptionAction = exceptionLocal != null ? (Action <InstructionWriter>)(w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal)) : null;

                    builder.EmitWrite(writer,
                                      messageFormatString,
                                      exceptionType == null ? arguments.Length : arguments.Length + 1,
                                      logLevel,
                                      getExceptionAction,
                                      (i, instructionWriter) =>
                    {
                        if (i < arguments.Length)
                        {
                            int index = arguments[i];
                            if (index == MessageArgumentsFormatter.ThisArgumentPosition)
                            {
                                this.methodMappingWriter.EmitLoadInstance(false, instructionWriter);
                            }
                            else if (index == MessageArgumentsFormatter.ReturnParameterPosition)
                            {
                                instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, Context.ReturnValueVariable);
                                instructionWriter.EmitConvertToObject(
                                    Context.MethodMapping.MethodSignature.ReturnType);
                            }
                            else
                            {
                                this.methodMappingWriter.EmitLoadArgument(index, instructionWriter);

                                instructionWriter.EmitConvertToObject(this.methodMappingWriter.MethodMapping.MethodSignature.GetParameterType(index).GetNakedType(TypeNakingOptions.IgnoreManagedPointers));
                            }
                        }
                        else
                        {
                            //Emit exception parameter
                            instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal);
                        }
                    },
                                      useWrapper);
                    if (exceptionType == null)
                    {
                        writer.DetachInstructionSequence();
                    }
                }