/// <summary>
        /// Determines whether the incoming message is a poison message.  This method is
        /// called before the <see cref="IMessageListener"/> is invoked.
        /// </summary>
        /// <param name="message">The incoming message.</param>
        /// <returns>
        ///     <c>true</c> if it is a poison message; otherwise, <c>false</c>.
        /// </returns>
        /// <remarks>
        /// The <see cref="DistributedTxMessageListenerContainer"/> will call
        /// <see cref="HandlePoisonMessage"/> if this method returns true and will
        /// then commit the distibuted transaction (removing the message from the queue).
        /// </remarks>
        public bool IsPoisonMessage(Message message)
        {
            string messageId = message.Id;

            lock (messageMapMonitor)
            {
                MessageStats messageStats = null;
                if (messageMap.Contains(messageId))
                {
                    messageStats = (MessageStats)messageMap[messageId];
                    if (messageStats.Count > MaxRetry)
                    {
                        LOG.Warn("Message with id = [" + message.Id + "] detected as poison message.");
                        return(true);
                    }
                }
                return(false);
            }
        }
        /// <summary>
        /// Called when an exception is thrown in listener processing.
        /// </summary>
        /// <param name="exception">The exception.</param>
        /// <param name="message">The message.</param>
        public void OnException(Exception exception, Message message)
        {
            string messageId = message.Id;

            lock (messageMapMonitor)
            {
                MessageStats messageStats = null;
                if (messageMap.Contains(messageId))
                {
                    messageStats = (MessageStats)messageMap[messageId];
                }
                else
                {
                    messageStats          = new MessageStats();
                    messageMap[messageId] = messageStats;
                }
                messageStats.Count++;
                LOG.Warn("Message Error Count = [" + messageStats.Count + "] for message id = [" + messageId +
                         "]");
            }
        }
        /// <summary>
        /// Called when an exception is thrown during listener processing under the
        /// scope of a <see cref="MessageQueueTransaction"/>.
        /// </summary>
        /// <param name="exception">The exception.</param>
        /// <param name="message">The message.</param>
        /// <param name="messageQueueTransaction">The message queue transaction.</param>
        /// <returns>
        /// An action indicating if the caller should commit or rollback the
        /// <see cref="MessageQueueTransaction"/>
        /// </returns>
        public TransactionAction OnException(Exception exception, Message message,
                                             MessageQueueTransaction messageQueueTransaction)
        {
            if (IsMessageAlreadyProcessedException(exception))
            {
                return(TransactionAction.Commit);
            }

            string messageId = message.Id;

            lock (messageMapMonitor)
            {
                MessageStats messageStats = null;
                if (messageMap.Contains(messageId))
                {
                    messageStats = (MessageStats)messageMap[messageId];
                }
                else
                {
                    messageStats          = new MessageStats();
                    messageMap[messageId] = messageStats;
                }
                messageStats.Count++;
                LOG.Warn("Message Error Count = [" + messageStats.Count + "] for message id = [" + messageId + "]");

                if (messageStats.Count > MaxRetry)
                {
                    LOG.Info("Maximum number of redelivery attempts exceeded for message id = [" + messageId + "]");
                    messageMap.Remove(messageId);
                    return(SendMessageToQueue(message, messageQueueTransaction));
                }
                else
                {
                    LOG.Warn("Rolling back delivery of message id [" + messageId + "]");
                    return(TransactionAction.Rollback);
                }
            }
        }
        /// <summary>
        /// Called when an exception is thrown during listener processing under the
        /// scope of a <see cref="MessageQueueTransaction"/>.
        /// </summary>
        /// <param name="exception">The exception.</param>
        /// <param name="message">The message.</param>
        /// <param name="messageQueueTransaction">The message queue transaction.</param>
        /// <returns>
        /// An action indicating if the caller should commit or rollback the
        /// <see cref="MessageQueueTransaction"/>
        /// </returns>
        public TransactionAction OnException(Exception exception, Message message,
                                             MessageQueueTransaction messageQueueTransaction)
        {
            if (IsMessageAlreadyProcessedException(exception))
            {
                return TransactionAction.Commit;
            }

            string messageId = message.Id;
            lock (messageMapMonitor)
            {
                MessageStats messageStats = null;
                if (messageMap.Contains(messageId))
                {
                    messageStats = (MessageStats) messageMap[messageId];
                }
                else
                {
                    messageStats = new MessageStats();
                    messageMap[messageId] = messageStats;
                }
                messageStats.Count++;
                LOG.Warn("Message Error Count = [" + messageStats.Count + "] for message id = [" + messageId + "]");

                if (messageStats.Count > MaxRetry)
                {
                    LOG.Info("Maximum number of redelivery attempts exceeded for message id = [" + messageId + "]");
                    messageMap.Remove(messageId);
                    return SendMessageToQueue(message, messageQueueTransaction);
                }
                else
                {
                    LOG.Warn("Rolling back delivery of message id [" + messageId + "]");
                    return TransactionAction.Rollback;
                }
            }
        }
 /// <summary>
 /// Called when an exception is thrown in listener processing.
 /// </summary>
 /// <param name="exception">The exception.</param>
 /// <param name="message">The message.</param>
 public void OnException(Exception exception, Message message)
 {
     string messageId = message.Id;
     lock (messageMapMonitor)
     {
         MessageStats messageStats = null;
         if (messageMap.Contains(messageId))
         {
             messageStats = (MessageStats) messageMap[messageId];
         }
         else
         {
             messageStats = new MessageStats();
             messageMap[messageId] = messageStats;
         }
         messageStats.Count++;
         LOG.Warn("Message Error Count = [" + messageStats.Count + "] for message id = [" + messageId +
                  "]");
     }
 }