/// <summary>
        /// This method marshalls the incoming requests from the Initiators.
        /// </summary>
        /// <param name="caller">The caller.</param>
        /// <param name="message">The message to process.</param>
        protected virtual OutgoingRequestTracker OutgoingRequestTransmit(TransmissionPayload payload)
        {
            //Create and register the request holder.
            string id = payload.Message.OriginatorKey.ToUpperInvariant();

            //Get the maximum processing time.
            TimeSpan processingTime = payload.MaxProcessingTime.HasValue ?
                                      payload.MaxProcessingTime.Value : mPolicy.OutgoingRequestMaxProcessingTimeDefault;

            //Create and register the request holder.
            var holder = new OutgoingRequestTracker(id, payload, processingTime);

            //Add the outgoing holder to the collection
            if (!mOutgoingRequests.TryAdd(holder.Id, holder))
            {
                var errorStr = $"OutgoingRequestTransmit: Duplicate key {holder.Id}";
                Logger?.LogMessage(LoggingLevel.Error, errorStr);
                throw new OutgoingRequestTransmitException(errorStr);
            }

            //Submit the payload for processing
            TaskManager(this, holder.Payload);

            return(holder);
        }
        /// <summary>
        /// This method sends a message to the underlying dispatcher and tracks its progress.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <param name="payloadRq">The payload to process.</param>
        /// <param name="processResponse"></param>
        /// <param name="processAsync">Specifies whether the process in async in which case it is
        /// returned immediately without waiting for the payload to be processed.</param>
        /// <returns>The task with a payload of type K</returns>
        protected async Task <K> OutgoingRequestOut <K>(TransmissionPayload payloadRq,
                                                        Func <TaskStatus, TransmissionPayload, bool, K> processResponse,
                                                        bool processAsync = false)
        {
            ValidateServiceStarted();

            if (payloadRq == null)
            {
                throw new ArgumentNullException("payloadRequest has not been set.");
            }
            if (processResponse == null)
            {
                throw new ArgumentNullException("processPayload has not been set.");
            }

            //Create and register the request holder.
            var tracker = new OutgoingRequestTracker(payloadRq, payloadRq.MaxProcessingTime ?? Policy.OutgoingRequestMaxProcessingTimeDefault);

            //Add the outgoing holder to the collection
            if (!mOutgoingRequests.TryAdd(tracker.Id, tracker))
            {
                var errorStr = $"OutgoingRequestTransmit: Duplicate key {tracker.Id}";

                Collector?.LogMessage(LoggingLevel.Error, errorStr, "RqDuplicate");

                throw new OutgoingRequestTransmitException(errorStr);
            }

            //Raise the event.
            FireAndDecorateEventArgs(OnOutgoingRequest, () => new OutgoingRequestEventArgs(tracker));

            //Submit the payload for processing to the task manager
            TaskManager(this, tracker.Id, tracker.Payload);

            //OK, this is a sync process, let's wait until it responds or times out.
            TransmissionPayload payloadRs = null;

            //This has not been marked async so hold the current task until completion.
            if (!processAsync)
            {
                try
                {
                    if (UseASPNETThreadModel)
                    {
                        payloadRs = Task.Run(async() => await tracker.Tcs.Task).Result;
                    }
                    else
                    {
                        payloadRs = await tracker.Tcs.Task;
                    }
                }
                catch (Exception) { }
            }

            return(processResponse(tracker.Tcs.Task.Status, payloadRs, processAsync));
        }