/// <summary>
        /// Execute Run.
        /// </summary>
        public void Run()
        {
            var aborted = false;

            try
            {
                try
                {
                    this.consumer.Start();
                    this.start.CountDown();
                }
                catch (FatalListenerStartupException ex)
                {
                    throw;
                }
                catch (Exception t)
                {
                    this.start.CountDown();
                    this.HandleStartupFailure(t);
                    throw;
                }

                // Always better to stop receiving as soon as possible if
                // transactional
                var continuable = false;
                while (this.outer.IsActive || continuable)
                {
                    try
                    {
                        // Will come back false when the queue is drained
                        continuable = this.outer.ReceiveAndExecute(this.consumer) && !this.outer.IsChannelTransacted;
                    }
                    catch (ListenerExecutionFailedException ex)
                    {
                        // Continue to process, otherwise re-throw
                    }
                }
            }
            catch (ThreadInterruptedException e)
            {
                this.logger.Debug("Consumer thread interrupted, processing stopped.");
                Thread.CurrentThread.Interrupt();
                aborted = true;
            }
            catch (FatalListenerStartupException ex)
            {
                this.logger.Error("Consumer received fatal exception on startup", ex);
                this.startupException = ex;

                // Fatal, but no point re-throwing, so just abort.
                aborted = true;
            }
            catch (FatalListenerExecutionException ex)
            {
                this.logger.Error("Consumer received fatal exception during processing", ex);

                // Fatal, but no point re-throwing, so just abort.
                aborted = true;
            }
            catch (Exception t)
            {
                if (this.logger.IsDebugEnabled)
                {
                    this.logger.Warn("Consumer raised exception, processing can restart if the connection factory supports it", t);
                }
                else
                {
                    this.logger.Warn("Consumer raised exception, processing can restart if the connection factory supports it. " + "Exception summary: " + t);
                }
            }

            // In all cases count down to allow container to progress beyond startup
            this.start.CountDown();

            if (!this.outer.IsActive || aborted)
            {
                this.logger.Debug("Cancelling " + this.consumer);
                try
                {
                    this.consumer.Stop();
                }
                catch (AmqpException e)
                {
                    this.logger.Info("Could not cancel message consumer", e);
                }

                if (aborted)
                {
                    this.logger.Info("Stopping container from aborted consumer");
                    this.outer.Stop();
                }
            }
            else
            {
                this.logger.Info("Restarting " + this.consumer);
                this.outer.Restart(this.consumer);
            }
        }
        /// <summary>
        /// Execute Run.
        /// </summary>
        public void Run()
        {
            var aborted = false;

            try
            {
                try
                {
                    this.consumer.Start();
                    this.start.Signal();
                }
                catch (FatalListenerStartupException ex)
                {
                    throw;
                }
                catch (Exception t)
                {
                    if (this.start.CurrentCount > 0)
                    {
                        this.start.Signal();
                    }

                    this.outer.HandleStartupFailure(t);
                    throw;
                }

                if (this.outer.transactionManager != null)
                {
                    // Register the consumer's channel so it will be used by the transaction manager
                    // if it's an instance of RabbitTransactionManager.
                    ConnectionFactoryUtils.RegisterConsumerChannel(this.consumer.Channel);
                }

                // Always better to stop receiving as soon as possible if
                // transactional
                var continuable = false;
                while (this.outer.IsActive || continuable)
                {
                    try
                    {
                        // Will come back false when the queue is drained
                        continuable = this.outer.ReceiveAndExecute(this.consumer) && !this.outer.ChannelTransacted;
                    }
                    catch (ListenerExecutionFailedException ex)
                    {
                        Logger.Trace(m => m("Error on ReceiveAndExecute"), ex);

                        // Continue to process, otherwise re-throw
                    }
                }
            }
            catch (ThreadInterruptedException e)
            {
                Logger.Debug(m => m("Consumer thread interrupted, processing stopped."));
                Thread.CurrentThread.Interrupt();
                aborted = true;
            }
            catch (FatalListenerStartupException ex)
            {
                Logger.Error(m => m("Consumer received fatal exception on startup", ex));
                this.startupException = ex;

                // Fatal, but no point re-throwing, so just abort.
                aborted = true;
            }
            catch (FatalListenerExecutionException ex)
            {
                Logger.Error(m => m("Consumer received fatal exception during processing"), ex);

                // Fatal, but no point re-throwing, so just abort.
                aborted = true;
            }
            catch (Exception t)
            {
                Logger.Warn(m => m("Consumer raised exception, processing can restart if the connection factory supports it. " + "Exception summary: " + t));
            }
            finally
            {
                if (this.outer.transactionManager != null)
                {
                    ConnectionFactoryUtils.UnRegisterConsumerChannel();
                }
            }

            // In all cases count down to allow container to progress beyond startup
            if (this.start.CurrentCount > 0)
            {
                this.start.Signal();
            }

            if (!this.outer.IsActive || aborted)
            {
                Logger.Debug(m => m("Cancelling {0}", this.consumer));
                try
                {
                    this.consumer.Stop();
                }
                catch (AmqpException e)
                {
                    Logger.Info(m => m("Could not cancel message consumer"), e);
                }

                if (aborted)
                {
                    Logger.Info(m => m("Stopping container from aborted consumer"));
                    this.outer.Stop();
                }
            }
            else
            {
                Logger.Info(m => m("Restarting {0}", this.consumer));
                this.outer.Restart(this.consumer);
            }
        }
        /// <summary>
        /// Execute Run.
        /// </summary>
        public void Run()
        {
            var aborted = false;

            try
            {
                try
                {
                    this.consumer.Start();
                    this.start.Signal();
                }
                catch (FatalListenerStartupException ex)
                {
                    throw;
                }
                catch (Exception t)
                {
                    if (this.start.CurrentCount > 0)
                    {
                        this.start.Signal();
                    }

                    this.outer.HandleStartupFailure(t);
                    throw;
                }

                if (this.outer.transactionManager != null)
                {
                    // Register the consumer's channel so it will be used by the transaction manager
                    // if it's an instance of RabbitTransactionManager.
                    ConnectionFactoryUtils.RegisterConsumerChannel(this.consumer.Channel);
                }

                // Always better to stop receiving as soon as possible if
                // transactional
                var continuable = false;
                while (this.outer.IsActive || continuable)
                {
                    try
                    {
                        // Will come back false when the queue is drained
                        continuable = this.outer.ReceiveAndExecute(this.consumer) && !this.outer.ChannelTransacted;
                    }
                    catch (ListenerExecutionFailedException ex)
                    {
                        Logger.Trace(m => m("Error on ReceiveAndExecute"), ex);

                        // Continue to process, otherwise re-throw
                    }
                }
            }
            catch (ThreadInterruptedException e)
            {
                Logger.Debug(m => m("Consumer thread interrupted, processing stopped."));
                Thread.CurrentThread.Interrupt();
                aborted = true;
            }
            catch (FatalListenerStartupException ex)
            {
                Logger.Error(m => m("Consumer received fatal exception on startup", ex));
                this.startupException = ex;

                // Fatal, but no point re-throwing, so just abort.
                aborted = true;
            }
            catch (FatalListenerExecutionException ex)
            {
                Logger.Error(m => m("Consumer received fatal exception during processing"), ex);

                // Fatal, but no point re-throwing, so just abort.
                aborted = true;
            }
            catch (Exception t)
            {
                Logger.Warn(m => m("Consumer raised exception, processing can restart if the connection factory supports it. " + "Exception summary: " + t));
            }
            finally
            {
                if (this.outer.transactionManager != null)
                {
                    ConnectionFactoryUtils.UnRegisterConsumerChannel();
                }
            }

            // In all cases count down to allow container to progress beyond startup
            if (this.start.CurrentCount > 0)
            {
                this.start.Signal();
            }

            if (!this.outer.IsActive || aborted)
            {
                Logger.Debug(m => m("Cancelling {0}", this.consumer));
                try
                {
                    this.consumer.Stop();
                }
                catch (AmqpException e)
                {
                    Logger.Info(m => m("Could not cancel message consumer"), e);
                }

                if (aborted)
                {
                    Logger.Info(m => m("Stopping container from aborted consumer"));
                    this.outer.Stop();
                }
            }
            else
            {
                Logger.Info(m => m("Restarting {0}", this.consumer));
                this.outer.Restart(this.consumer);
            }
        }