docs: private void dispatchInternal(AIMessageItem msg) throws SIException, MessageStoreException
    {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(tc, "dispatchInternal", msg);
  
      // try to give it to the ConsumerKey that requested this message
      RemoteDispatchableKey dkey = msg.getAIStreamKey().getRemoteDispatchableKey();
      RemoteQPConsumerKey readyConsumer = null;
      if (dkey instanceof RemoteQPConsumerKey)
        readyConsumer = (RemoteQPConsumerKey) dkey;
  
      if (readyConsumer != null)
      {
        synchronized (_baseDestHandler.getReadyConsumerPointLock())
        {
          if (!readyConsumer.isKeyReady())
            readyConsumer = null;
          else
          {
            readyConsumer.markNotReady();
            dkey = (RemoteDispatchableKey) readyConsumer.getParent();
            removeReadyConsumer(dkey, !dkey.hasNonSpecificConsumers());
          }
        }
      }
  
      boolean accepted = false;
      if (readyConsumer != null)
      {
        // If noLocal is set to true and...
        // If the ProducerConnectionID is the same as the ConsumerConnection ID then we
        // do not deliver or store this message, but we DO accept it so that it is
        // removed from the subscription.
        if (dispatcherState.isNoLocal()
          && readyConsumer.getConnectionUuid().equals(msg.getProducerConnectionUuid()))
        {
          // Not only do we accept the message but we also immediately
          // remove it from the item stream.  Note: this must be an external
          // local transaction because the AIH will accept the message in
          // its preCommitRemove method.
          accepted = true;
          
          // 610985: We must lock the message before removing it as there's a chance
          // that another thread may have just locked this message. So if we were to
          // remove it without checking that it's ours (by attempting to lock it) then
          // it would come as a bit of a surprise to the other thread when it can no-longer
          // find the message it just locked
          // Even if we don't manage to lock it we consider this message delivered as
          // someone else is obviously on the ball with this one.
          if(msg.lockItemIfAvailable(lockID))
          {
            LocalTransaction tran = null;
            tran = _tranManager.createLocalTransaction(true);
            msg.remove((Transaction) tran,lockID);
            tran.commit();
          }
  
          // Also, give the LCP a chance to reissue the get in case it's blocked.
          ((JSLocalConsumerPoint) readyConsumer.consumerPoint).waitingNotify();
        } else {
          readyConsumer.updateLastNotReadyTime();
          accepted = readyConsumer.consumerPoint.put(msg, true);
        }
      }
  
      if (!accepted)
      {
        readyConsumer = null;
        boolean continueSearch = true;
  
        boolean newMatchRequired = false; // makes atmost one transition to true, and then to false
        MatchingConsumerPoint[] matchResults = null; // initialized when newMatchRequired set to true
        int startPoint, index; // real initialization occurs when matchResults initialized
        startPoint = index = 0;
  
        boolean grabCurrentReadyVersion = true;
        long newestReadyVersion = 0;
        while (continueSearch)
        {
          if (newMatchRequired)
          {
            // Get a search results object to use
            MessageProcessorSearchResults searchResults =
              (MessageProcessorSearchResults)_messageProcessor.
                getSearchResultsObjectPool().
                  remove();
  
            // Defect 382250, set the unlockCount from MsgStore into the message
            // in the case where the message is being redelivered.
            JsMessage searchMsg = msg.getMessage();
            int redelCount = msg.guessRedeliveredCount();
  
            if (redelCount > 0)
            {
              if(TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                SibTr.debug(tc, "Set deliverycount into message: " + redelCount);
              searchMsg.setDeliveryCount(redelCount);
            }
  
            // Search the match space.
            _messageProcessor.
              getMessageProcessorMatching().
                retrieveMatchingConsumerPoints(_baseDestHandler.getUuid(), // the uuid of the destination
                                               getUuid(), // the uuid of the remote consumer dispatcher
                                               searchMsg,
                                               searchResults);
  
            Object allResults[] = searchResults.getResults(_baseDestHandler.getName());
  
            Set matchSet =
              (Set) allResults[MessageProcessorMatchTarget.JS_CONSUMER_TYPE];
            matchResults =
             (MatchingConsumerPoint[])matchSet.toArray(new MatchingConsumerPoint[0]);
  
            //193008 - this result set might be empty
            int resultSize = matchResults.length;
            if(resultSize >0 )
            {
              startPoint = msg.getProducerSeed()%resultSize;
              index = startPoint;
            }
            else
            {
              //we have exhausted our search
              break;
            }
  
            newMatchRequired = false;
          }
  
          synchronized (_baseDestHandler.getReadyConsumerPointLock())
          {
            if (grabCurrentReadyVersion)
            { // this is done the first time in the while loop
              newestReadyVersion = readyConsumerVersion;
              grabCurrentReadyVersion = false;
            }
  
            if (matchResults == null)
            { // still searching non-specific ready consumers
              dkey = (RemoteDispatchableKey) nonSpecificReadyCPs.getFirst();
              readyConsumer = null;
              if (dkey != null)
              {
                if (dkey.getVersion() > newestReadyVersion)
                {
                  dkey = null;
                }
              }
              if (dkey == null)
              { // done searching non-specific ready consumers
                newMatchRequired = true; // do a match the next time through the while loop
              }
              else
              {
                // may have a RemoteQPConsumerKeyGroup, so resolve to a particular RemoteQPConsumerKey
                readyConsumer = (RemoteQPConsumerKey) dkey.resolvedKey();
              }
            } // end if (matchResults == null)
            else
            { // searching through specific consumers
              readyConsumer = null;
              // Check for a ready consumer
              while (readyConsumer == null)
              {
                DispatchableKey ck =
                  matchResults[index].getConsumerPointData();
  
                // Find a ready consumer that is old enough for us
                // SIB0113a We only want the remote consumer matches. There might
                // be local consumers in the matchspace too.
                if( (ck.isKeyReady())
                  &&(ck.getVersion() <= newestReadyVersion)
                  && ck instanceof RemoteDispatchableKey)
                {
                  // Remember this consumer but we won't try to deliver the message
                  // until the lock is released.
                  readyConsumer = (RemoteQPConsumerKey) ck;
                }
                else
                {
                  // Move on to the next consumer but check we haven't looped round
                  // to the start.
                  index = (index + 1) % matchResults.length;
                  if (index == startPoint)
                    break;
                } // end else
              } // end while (readyConsumer == null)
              if (readyConsumer == null)
              { // done searching specific ready consumers
                continueSearch = false;
              }
            } // end else
  
            if (readyConsumer != null)
            {
              readyConsumer.markNotReady();
              dkey = (RemoteDispatchableKey) readyConsumer.getParent();
              removeReadyConsumer(dkey, !dkey.hasNonSpecificConsumers());
  
            }
          } // end synchronized
          if (readyConsumer != null)
          {
            readyConsumer.updateLastNotReadyTime();
            accepted = readyConsumer.consumerPoint.put(msg, true);
            continueSearch = !accepted;
          }
        } // end while
      } // end if (!accepted)
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(tc, "dispatchInternal");
    }