/// <summary>
            ///   Initializes a new instance of the <see cref="PooledProducer" /> class.
            /// </summary>
            ///
            /// <param name="transportProducer">An abstracted Event Hub transport-specific producer that is associated with the Event Hub gateway or a specific partition.</param>
            /// <param name="cleanUp">The function responsible of cleaning up the resources in use.</param>
            ///
            public PooledProducer(TransportProducer transportProducer,
                                  Func <TransportProducer, Task> cleanUp = default)
            {
                Argument.AssertNotNull(transportProducer, nameof(transportProducer));

                TransportProducer = transportProducer;
                CleanUp           = cleanUp;
            }
        /// <summary>
        ///   Initializes a new instance of the <see cref="TransportProducerPool" /> class.
        /// </summary>
        ///
        /// <param name="transportProducerFactory">A factory method for spawning a <see cref="TransportProducer" /> for a given partition.</param>
        /// <param name="pool">The pool of <see cref="PoolItem" /> that is going to be used to store the partition specific <see cref="TransportProducer" />.</param>
        /// <param name="performExpirationPeriod">The period after which <see cref="CreateExpirationTimerCallback" /> is run. Overrides <see cref="DefaultPerformExpirationPeriod" />.</param>
        /// <param name="eventHubProducer">An abstracted Event Hub transport-specific producer that is associated with the Event Hub gateway rather than a specific partition.</param>
        ///
        public TransportProducerPool(Func <string, TransportProducer> transportProducerFactory,
                                     ConcurrentDictionary <string, PoolItem> pool = default,
                                     TimeSpan?performExpirationPeriod             = default,
                                     TransportProducer eventHubProducer           = default)
        {
            performExpirationPeriod ??= DefaultPerformExpirationPeriod;

            Pool                     = pool ?? new ConcurrentDictionary <string, PoolItem>();
            EventHubProducer         = eventHubProducer ?? transportProducerFactory(null);
            TransportProducerFactory = transportProducerFactory;
            ExpirationTimer          = new Timer(CreateExpirationTimerCallback(), null, performExpirationPeriod.Value, performExpirationPeriod.Value);
        }
        /// <summary>
        ///   Initializes a new instance of the <see cref="TransportProducerPool" /> class.
        /// </summary>
        ///
        /// <param name="connection">The <see cref="EventHubConnection" /> connection to use for communication with the Event Hubs service.</param>
        /// <param name="retryPolicy">The policy to use for determining retry behavior for when an operation fails.</param>
        /// <param name="pool">The pool of <see cref="PoolItem" /> that is going to be used to store the partition specific <see cref="TransportProducer" />.</param>
        /// <param name="performExpirationPeriod">The period after which <see cref="CreateExpirationTimerCallback" /> is run. Overrides <see cref="DefaultPerformExpirationPeriod" />.</param>
        /// <param name="eventHubProducer">An abstracted Event Hub transport-specific producer that is associated with the Event Hub gateway rather than a specific partition.</param>
        ///
        public TransportProducerPool(EventHubConnection connection,
                                     EventHubsRetryPolicy retryPolicy,
                                     ConcurrentDictionary <string, PoolItem> pool = default,
                                     TimeSpan?performExpirationPeriod             = default,
                                     TransportProducer eventHubProducer           = default)
        {
            Connection  = connection;
            RetryPolicy = retryPolicy;
            Pool        = pool ?? new ConcurrentDictionary <string, PoolItem>();
            performExpirationPeriod ??= DefaultPerformExpirationPeriod;
            EventHubProducer = eventHubProducer ?? connection.CreateTransportProducer(null, retryPolicy);

            ExpirationTimer = new Timer(CreateExpirationTimerCallback(),
                                        null,
                                        performExpirationPeriod.Value,
                                        performExpirationPeriod.Value);
        }
            /// <summary>
            ///   Initializes a new instance of the <see cref="PoolItem" /> class with a default timespan of <see cref="DefaultRemoveAfterDuration" />.
            /// </summary>
            ///
            /// <param name="partitionId">The unique identifier of a partition associated with the Event Hub.</param>
            /// <param name="partitionProducer">An Event Hub transport-specific producer specific to a given partition.</param>
            /// <param name="removeAfterDuration">The interval after which a <see cref="PoolItem" /> will become eligible for eviction. Overrides <see cref="DefaultRemoveAfterDuration" />.</param>
            /// <param name="removeAfter">The UTC date and time when a <see cref="PoolItem" /> will become eligible for eviction.</param>
            ///
            public PoolItem(string partitionId,
                            TransportProducer partitionProducer,
                            TimeSpan?removeAfterDuration = default,
                            DateTimeOffset?removeAfter   = default)
            {
                Argument.AssertNotNullOrEmpty(partitionId, nameof(partitionId));
                Argument.AssertNotNull(partitionProducer, nameof(partitionProducer));

                PartitionProducer = partitionProducer;
                PartitionId       = partitionId;

                if (removeAfter == default)
                {
                    ExtendRemoveAfter(removeAfterDuration);
                }
                else
                {
                    RemoveAfter = removeAfter.Value;
                }
            }