protected virtual async Task ExecuteMessageHandlerAsync(
            EventArgs messageEventArgs,
            ReceivedItemHandlerAsyncDelegate receivedItemHandlerAsyncDelegateFunc,
            bool automaticFinalizationEnabled = true
            )
        {
            messageEventArgs.AssertNotNull(nameof(messageEventArgs));
            receivedItemHandlerAsyncDelegateFunc.AssertNotNull(nameof(receivedItemHandlerAsyncDelegateFunc));

            AzureServiceBusReceivedItem <TUniqueIdentifier, TPayload> azureServiceBusReceivedItem = null;

            //FIRST attempt to convert the Message into an AzureServiceBus Received Item....
            try
            {
                //Initialize the MessageHandler facade for processing the Azure Service Bus message...
                azureServiceBusReceivedItem = await CreateReceivedItemAsync(
                    messageEventArgs,
                    //Force Dead-lettering if there is any issue with initialization!
                    true
                    ).AssertNotNull(nameof(azureServiceBusReceivedItem));
            }
            catch (Exception exc)
            {
                var messageException = new Exception("The message could not be correctly initialized due to unexpected exception." +
                                                     " It must be Dead lettered to prevent blocking of the Service Bus as it will never be" +
                                                     " processed successfully.", exc);

                this.Options.ErrorHandlerCallback?.Invoke(messageException);
            }

            //IF the Received Item is successfully initialized then process it!
            if (azureServiceBusReceivedItem != null)
            {
                try
                {
                    //Execute the delegate to handle/process the published item...
                    await receivedItemHandlerAsyncDelegateFunc(azureServiceBusReceivedItem).ConfigureAwait(false);

                    //If necessary, we need to Finalize the item with Azure Service Bus (Complete/Abandon) based on the Status returned on the item!
                    if (automaticFinalizationEnabled && !azureServiceBusReceivedItem.IsStatusFinalized)
                    {
                        await azureServiceBusReceivedItem.SendFinalizedStatusToAzureServiceBusAsync().ConfigureAwait(false);
                    }
                }
                catch (Exception exc)
                {
                    this.Options.ErrorHandlerCallback?.Invoke(exc);

                    //Always attempt to Reject/Abandon the message if any unhandled exceptions are thrown...
                    if (!azureServiceBusReceivedItem.IsStatusFinalized)
                    {
                        //Finalize the status as set by the Delegate function if it's not already Finalized!
                        //NOTE: We ALWAYS do this even if autoMessageFinalizationEnabled is false to prevent BLOCKING and risk of Infinite Loops...
                        await azureServiceBusReceivedItem.SendFinalizedStatusToAzureServiceBusAsync().ConfigureAwait(false);
                    }
                }
            }
        }
        protected virtual async Task <AzureServiceBusReceivedItem <TUniqueIdentifier, TPayload> > CreateReceivedItemAsync(
            EventArgs baseMessageEventArgs,
            bool deadLetterOnFailureToInitialize = false
            )
        {
            AzureServiceBusReceivedItem <TUniqueIdentifier, TPayload> azureServiceBusReceivedItem = null;
            var initializationErrorMessage = $"Unable to initialize {nameof(SqlTransactionalOutbox)} Received Item [{nameof(AzureServiceBusReceivedItem<TUniqueIdentifier, TPayload>)}]";

            switch (baseMessageEventArgs)
            {
            case ProcessMessageEventArgs messageEventArgs:
                try
                {
                    azureServiceBusReceivedItem = new AzureServiceBusReceivedItem <TUniqueIdentifier, TPayload>(messageEventArgs, this.OutboxItemFactory);
                }
                catch (Exception exc)
                {
                    if (deadLetterOnFailureToInitialize)
                    {
                        await messageEventArgs.DeadLetterMessageAsync(messageEventArgs.Message, initializationErrorMessage, exc.GetMessagesRecursively());
                    }

                    throw;
                }
                break;

            case ProcessSessionMessageEventArgs sessionMessageEventArgs:
                try
                {
                    azureServiceBusReceivedItem = new AzureServiceBusReceivedItem <TUniqueIdentifier, TPayload>(sessionMessageEventArgs, this.OutboxItemFactory);
                }
                catch (Exception exc)
                {
                    if (deadLetterOnFailureToInitialize)
                    {
                        await sessionMessageEventArgs.DeadLetterMessageAsync(sessionMessageEventArgs.Message, initializationErrorMessage, exc.GetMessagesRecursively());
                    }

                    throw;
                }
                break;
            }

            return(azureServiceBusReceivedItem);
        }