docs: synchronized void dispatch(final SIMessageHandle messageHandle, SIBusMessage message,
              final Map handlerContext) throws ResourceException {
  
          final String methodName = "dispatch";
          if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
              SibTr.entry(this, TRACE, methodName, new Object[] { messageHandle, message,
                      handlerContext });
          }
  
          if (_session == null) {
  
              /*
               * The dispatcher has been closed - return safe in the knowledge
               * that the message will have already been unlocked by the close of
               * the session
               */
  
              if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
                  SibTr.exit(this, TRACE, methodName);
              }
              return;
  
          }
  
          boolean delivered = false;
  
          /**
           * The endpoint to deliver the message to.
           */
          MessageEndpoint endpoint = null;
  
          try {
  
            /**
             * Obtain The endpoint to deliver the message to.
             */
            endpoint = createEndpoint();
  
              /*
               * Obtain information for request metrics and handlers
               */
  
              final SIDestinationAddress destination = _session
                      .getDestinationAddress();
              final String busName = destination.getBusName();
              final String meName = _connection.getMeName();
              final String destinationName = destination.getDestinationName();
              final String messageSelector = _endpointConfiguration
                      .getMessageSelector();
              final ActivationSpec activationSpec = _endpointConfiguration
                      .getActivationSpec();
  
              boolean success = false;
              // Only proceed if not cancelled and handler invocation is
              // successful
              if (!isCancelled ()) {
  
                  try {
  
                      beforeDelivery(endpoint);
  
                      delivered = true;
  
                      try {
  
                        // 304501.ra - Call the pre MDB invoke on XD
                        MessagePacingControl mpc = MessagePacingControlFactory.getInstance();
                        if (mpc != null && mpc.isActive()) {
  
                          mpc.preMdbInvoke(this, null);
  
                        }
  
                        // If we are transactional we won't have read the message yet so perform a read and
                        // delete inside the transaction.
                        if (message == null)
                        {
                          message = readMessage (messageHandle); // null op for non trans mdb's
                        }
  
                        _reliabilityPreInvoke.put(messageHandle, message.getReliability());
  
                        success = _invoker.invokeEndpoint(endpoint,
                            message, _session, getTransaction(), _debugMEName);
  
                        // 304501.ra - Call the post MDB invoke method on XD
                        if (mpc != null && mpc.isActive()) {
  
                          mpc.postMdbInvoke (this, null);
  
                        }
                      } catch (final SIMessageNotLockedException exception) {
  
                          // No FFDC code needed
  
                                                  /*
                                                   * Message lock has expired and message will be
                                                   * reassigned
                                                   */
  
                                                  if (TraceComponent.isAnyTracingEnabled() && TRACE.isEventEnabled()) {
                                                          SibTr.exception(this, TRACE, exception);
                                                  }
  
                                      /*
                                       * Message lock has expired and message will be reassigned so drop out of dispatch
                                       */
                                                  return;
  
                      } finally {
  
                          afterDelivery(message, endpoint, success);
  
                      }
  
                  } finally {
  
  
                      // Call isTransactionRolledBack to clear up
                      // the data stored in the SibRaXaResource hashtable even if
                      // we are not using PMI
                      boolean tranRolledBack = isTransactionRolledBack ();
  
                      // Success should only be true if the endpoint
                      // was successfully invoked and the transaction
                      // was not rolled back.
                        success = success && !tranRolledBack;
   
                        if (success)
                        {
                          //This message was sucessfully delivered so reset all sequential message counters
                          clearSequentialFailureMessageCount();
                        }
                        else
                        {
                          // Make sure we have a message and the redelivered count exists
                          if ((message != null) && (((JsMessage)message).getRedeliveredCount() != null))
                          {
                              // message failed check its redelivery threshold
                              // we need to check for n - 1 where n is the max failed deliveries. The redeliveredCount means the 
                              // number of REdeliveries so we need to add one to this to align with the maxfaileddeliveries count.
                              if ( (((JsMessage)message).getRedeliveredCount().intValue() + 1) == (_maxFailedDeliveries - 1))
                              {
                                //We are about to hit the threshold
                                addToSequentialFailureMessageCount();
                              }
                          }
                          else
                          {
                              if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled()) 
                              {
                                  if (null == message)
                                  {
                                      SibTr.debug(TRACE, "The message was null");
                                  }
                                  else
                                  {
                                      SibTr.debug(TRACE, "Unable to obtain the redelivered count from message " + message);
                                  }
                              }
                          }
                        }
                    }
  
              } else {
  
                // One or more of the handlers failed. Force a increment on the
                // retry count of the message.
                  if (!isCancelled ())
                  {
  
                    if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled()) {
                          SibTr.debug(this, TRACE, "An RA Handler failed - increasing retry count on message by rolling back a delete on the message:",
                                      message);
                    }
  
                  increaseRetryCount(messageHandle);
  
                  // Set delivered to be true so that we don't try and unlock it later.
                  // The process of deleting and rolling back will unlock the mesage.
                  delivered = true;
  
                  }
              }
  
          } finally {
  
            try {
  
              cleanup();
  
              // If possible, unlock an undelivered message
  
              if ((!delivered) && (message!= null)) {
  
                  if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled()) {
                              SibTr.debug(this, TRACE, "Unlocking undelivered message:",
                                              message);
                  }
  
                  try {
  
                  // If we do not delete unrecoverable messages
                  // or if we do delete unrecoverable message but
                  // this particular message is recoverable then unlock the
                  // message.
                  boolean canDeleteMessage = (_unrecoverableReliability.compareTo(message.getReliability ()) >= 0);
                  if ((!_deleteUnrecoverableMessages)
                          || (!(canDeleteMessage))) {
  
                      _session.unlockSet(new SIMessageHandle[] { message
                              .getMessageHandle() });
                  }
  
                } catch (final SIException exception) {
  
                  // No FFDC code needed
                  if (TraceComponent.isAnyTracingEnabled() && TRACE.isEventEnabled()) {
                      SibTr.exception(this, TRACE, exception);
                  }
  
                }
  
              }
  
            } finally {
  
              if (endpoint != null) {
  
                  endpoint.release ();
  
              }
  
            }
  
          }
  
          if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
              SibTr.exit(this, TRACE, methodName);
          }
  
      }