public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall,
                                                              IAgentWrapperApi agentWrapperApi)
        {
            var context = instrumentedMethodCall.MethodCall.MethodArguments
                          .ExtractNotNullAs <IIncomingLogicalMessageContext>(0);
            var incomingLogicalMessage = context.Message;

            if (incomingLogicalMessage == null)
            {
                throw new NullReferenceException("logicalMessage");
            }
            var headers = context.Headers;

            if (headers == null)
            {
                throw new NullReferenceException("headers");
            }
            var queueName = TryGetQueueName(incomingLogicalMessage);

            agentWrapperApi.CreateMessageBrokerTransaction(MessageBrokerDestinationType.Queue, "NServiceBus", queueName);
            var segment = agentWrapperApi.StartMessageBrokerSegment(instrumentedMethodCall.MethodCall, MessageBrokerDestinationType.Queue, MessageBrokerAction.Peek, "NServiceBus", queueName);

            agentWrapperApi.ProcessInboundRequest(headers);

            return(Delegates.GetDelegateFor <Task>(null, task =>
            {
                agentWrapperApi.RemoveSegmentFromCallStack(segment);
                if (task == null)
                {
                    return;
                }
                if (SynchronizationContext.Current != null)
                {
                    task.ContinueWith(responseTask => agentWrapperApi.HandleExceptions(() =>
                    {
                        agentWrapperApi.EndSegment(segment);
                        agentWrapperApi.EndTransaction();
                    }), TaskScheduler.FromCurrentSynchronizationContext());
                }
                else
                {
                    task.ContinueWith(responseTask => agentWrapperApi.HandleExceptions(() =>
                    {
                        agentWrapperApi.EndSegment(segment);
                        agentWrapperApi.EndTransaction();
                    }), TaskContinuationOptions.ExecuteSynchronously);
                }
            }, ex =>
            {
                if (ex != null)
                {
                    agentWrapperApi.NoticeError(ex);
                }
                agentWrapperApi.EndSegment(segment);
            }));
        }
        public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall,
                                                              IAgentWrapperApi agentWrapperApi)
        {
            var context = instrumentedMethodCall.MethodCall.MethodArguments
                          .ExtractNotNullAs <IIncomingLogicalMessageContext>(0);
            var incomingLogicalMessage = context.Message;

            if (incomingLogicalMessage == null)
            {
                throw new NullReferenceException("logicalMessage");
            }
            var headers = context.Headers;

            if (headers == null)
            {
                throw new NullReferenceException("headers");
            }
            var queueName = TryGetQueueName(incomingLogicalMessage);

            agentWrapperApi.CreateMessageBrokerTransaction(0, "NServiceBus", queueName);
            var isegment = agentWrapperApi.StartMessageBrokerSegment(instrumentedMethodCall.MethodCall, 0,
                                                                     (MessageBrokerAction)1, "NServiceBus", queueName);

            agentWrapperApi.ProcessInboundRequest(headers);
            return(Delegates.GetDelegateFor(() =>
            {
                agentWrapperApi.EndSegment(isegment);
                agentWrapperApi.EndTransaction();
            }, null, agentWrapperApi.NoticeError));
        }