docs: synchronized void dispatch(final List messages, AsynchDispatchScheduler scheduler, SibRaListener listener) throws ResourceException {
  
      	final String methodName = "dispatch";
      	if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
      		SibTr.entry(this, TRACE, methodName, new Object[] {messages, scheduler, listener});
      	}
  
      	if (_session == null) {
  
      		/*
      		 * The dispatcher has been closed - return safe in the knowledge
      		 * that the messages will have already been unlocked by the close of
      		 * the session
      		 */
  
      		if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
      			SibTr.exit(this, TRACE, methodName);
      		}
      		return;
  
      	}
  
      	/*
      	 * Keep a list of the messages for which delivery has not been attempted
      	 */
  
      	final List undeliveredDispatchableMessages = new ArrayList(messages);
  
  
      	/**
      	 * The endpoint to deliver the message to.
      	 */
      	MessageEndpoint endpoint = null;
  
      	try {
  
      		/*
      		 * Obtain an endpoint
      		 */
      		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();
  
      		for (final Iterator iterator = messages.iterator(); iterator
      				.hasNext()
      				&& !isCancelled ();) {
  
      			final DispatchableMessage dispatchableMessage = (DispatchableMessage) iterator.next();
  
      			final SIBusMessage message = dispatchableMessage.getMessage();
      			boolean success = false;
      			try {
  
      				beforeDelivery(message, endpoint);
  
      				undeliveredDispatchableMessages.remove(dispatchableMessage);
  
  
      				try {
  
      					// 304501.ra - Call the pre MDB invoke on XD
      					MessagePacingControl mpc = MessagePacingControlFactory.getInstance();
      					if (mpc != null && mpc.isActive()) {
  
      						mpc.preMdbInvoke(this, scheduler);
  
      					}
  
      					_reliabilityPreInvoke.put(message.getMessageHandle(), 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, scheduler);
  
      					}
  
      				} 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);
      							}
      						}
      					}
      				}
  
      			}
  
  
      		}
  
      	} finally {
  
      		cleanup();
  
      		try {
  
      			// If possible, unlock any undelivered messages
  
      			if (undeliveredDispatchableMessages.size() > 0) {
  
      				try {
  
      					// If we delete best effort non persistent messages then
      					// remove any best effort non persitent messages from the
      					// list.
      					if (_deleteUnrecoverableMessages) {
  
      						for (final Iterator iterator = undeliveredDispatchableMessages
      								.iterator(); iterator.hasNext();) {
  
      							final DispatchableMessage dispatchableMsg = (DispatchableMessage) iterator.next();
      							final SIBusMessage msg = dispatchableMsg.getMessage();
  
      							if (_unrecoverableReliability.compareTo(msg.getReliability ()) >= 0) {
  
      								if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled()) {
      									SibTr.debug(this,
      											TRACE,
      											"Removing the following message as it has already been deleted: ",
      											msg);
      								}
  
      								iterator.remove();
  
      							}
  
      						}
  
      					}
  
      					// Make sure that we still have some undelivered messages
      					// since they may have all been deleted
      					if (undeliveredDispatchableMessages.size() > 0) {
  
      						if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled()) {
      							SibTr.debug(this, TRACE,
      									"Unlocking undelivered messages:",
      									undeliveredDispatchableMessages);
      						}
  
      						unlockMessages(undeliveredDispatchableMessages, false);
  
      					}
  
      				} catch (final ResourceException 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);
      	}
  
      }