docs: void dispatch(final SibRaMessageToken token, final Map context) {
  
          final String methodName = "dispatch";
          if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
              SibTr.entry(this, TRACE, methodName,
                      new Object[] { token, context });
          }
  
          SibRaMessagingEngineConnection connection = null;
          BifurcatedConsumerSession session = null;
          SibRaDispatcher dispatcher = null;
          try {
  
              /*
               * Obtain connection to messaging engine
               */
  
              connection = getConnection(token.getBusName(), token.getMeUuid());
  
              /*
               * Obtain bifurcated consumer session
               */
  
              synchronized (_sessionsByMeUuid) {
  
                  Map sessionsById = (Map) _sessionsByMeUuid.get(token
                          .getMeUuid());
  
                  if (sessionsById == null) {
  
                      sessionsById = new HashMap();
                      _sessionsByMeUuid.put(token.getMeUuid(), sessionsById);
  
                  }
  
                  session = (BifurcatedConsumerSession) sessionsById
                          .get(Long.valueOf(token.getSessionId()));
  
                  if (session == null) {
  
                      /*
                       * Create a new bifurcated consumer session
                       */
  
                      session = connection.getConnection()
                              .createBifurcatedConsumerSession(
                                      token.getSessionId());
                      sessionsById.put(Long.valueOf(token.getSessionId()), session);
  
                  }
  
              }
  
              /**
               * Create the first dispatcher
               */
              if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled()) SibTr.debug(TRACE, "creating dispatcher for: " + _j2eeName);
              dispatcher = connection.createDispatcher(session, Reliability.getReliability(token.getUnrecoveredReliability()), token.getMaxFailedDeliveries(), token.getSequentialMessageThreshold());
  
              /*
               * Get the array of message ids
               */
              SIMessageHandle [] msgHandles = token.getMessageHandleArray();
              SIBusMessage [] messages = null;
  
              /**
               * If we are a non transactional MDB then
               * - If we can delete the messages when they are read then perform a readAndDeleteSet
               * - If the messages should be kept (the message has a higher reliability than unrecovered reliability
               * defined on the session) then just perform a read set.
               * For transactional MDBs do not read the messages yet. This will be done in the dispatcher's
               * dispatch code after a transaction has been started so that the readAndDelete can be performed
               * under this transaction.
               */
              if ((dispatcher instanceof SibRaNonTransactionalDispatcher) && (messages == null)) {
                if (token.isDeleteMessagesWhenRead()) {
  
                    if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled ()) {
                      SibTr.debug(this, TRACE,
                          "These messages will be deleted when read " + Arrays.toString(token.getMessageHandleArray ()));
                    }
  
                    messages = session.readAndDeleteSet(token.getMessageHandleArray (), null); // For messages that are being deleted
  
                } else {
  
                    if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled ()) {
                      SibTr.debug(this, TRACE,
                          "These messages will be read but not deleted yet " + Arrays.toString(token.getMessageHandleArray ()));
                    }
  
                    messages = session.readSet (token.getMessageHandleArray ()); // For messages that are not being deleted
  
                }
  
              }
  
              if ((msgHandles != null) && (msgHandles.length > 0)) {
  
                  for (int i = 0; i < msgHandles.length; i++) {
  
                    /**
                     * Create a new dispatcher if we need one.
                     */
                    if (dispatcher == null) {
                          dispatcher = connection.createDispatcher(session, Reliability.getReliability(token.getUnrecoveredReliability()), token.getMaxFailedDeliveries(), token.getSequentialMessageThreshold());
                    }
  
                      dispatcher.dispatch(msgHandles[i], messages == null ? null : messages [i], context);
  
                      // Close the dispatcher and create a new one.
                      connection.closeDispatcher(dispatcher);
                      dispatcher = null;
  
                  }
              } else {
  
                  SibTr.error(TRACE, "READ_SET_CWSIV1051", new Object[] {
                          Long.valueOf(token.getSessionId()), token.getMeUuid(),
                          Arrays.deepToString (msgHandles), token.getJ2EEName() });
  
              }
  
          } catch (final SISessionUnavailableException exception) {
  
              // No FFDC code needed
  
              /*
               * Session has been closed by listener and message will have been
               * unlocked
               */
  
              if (TraceComponent.isAnyTracingEnabled() && TRACE.isEventEnabled()) {
                  SibTr.exception(this, TRACE, exception);
              }
  
          }
          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);
              }
  
          }
      catch (SIRollbackException exception) {
  
              FFDCFilter.processException(exception, CLASS_NAME + "."
                      + methodName, "1:348:1.19", this);
              SibTr.warning(TRACE, "EXCEPTION_CWSIV1052", new Object[] {
                      Long.valueOf(token.getSessionId()), token.getMeUuid(),
                      Arrays.deepToString(token.getMessageHandleArray()), exception });
  
          } catch (final Exception exception) {
  
              FFDCFilter.processException(exception, CLASS_NAME + "."
                      + methodName, "1:356:1.19", this);
              SibTr.warning(TRACE, "EXCEPTION_CWSIV1052", new Object[] {
                      Long.valueOf(token.getSessionId()), token.getMeUuid(),
                      Arrays.deepToString(token.getMessageHandleArray()), exception });
  
              /*
               * Close the dispatcher before closing the connection (if the connection is 
               * closed while a dispatcher is open the closeConnection will just hang waiting
               * for the last dispatcher to be closed).
               */
              if (dispatcher != null) {
                  connection.closeDispatcher(dispatcher);
              }
  
              // 255651: Close the connection to the ME if an unknown error occurs
              // to flush the connection and force a new one to be created
              closeConnection(token.getMeUuid(), false);
  
              // null out the disptacher so we don't try and close it again.
              dispatcher = null;
  
          } finally {
  
              /*
               * Close the dispatcher if its not already been closed
               */
  
              if (dispatcher != null) {
                  connection.closeDispatcher(dispatcher);
              }
  
          }
  
          if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
              SibTr.exit(this, TRACE, methodName);
          }
  
      }