docs: public void receive(int requestNumber,
                         int transaction,
                         long timeout)
     {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc, "receive",
                                             new Object[]{requestNumber, transaction, timeout});
  
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        {
           SibTr.debug(this, tc, "RQ: " + requestNumber + ", Timeout: " + timeout);
  
           if (timeout == -1)
           {
              SibTr.debug(this, tc, "Emulating a receiveNoWait()");
           }
           else if (timeout == 0)
           {
              SibTr.debug(this, tc, "Emulating an indefinate receive()");
           }
           else
           {
              SibTr.debug(this, tc, "Emulating a receive() for " + timeout + "ms");
           }
        }
  
        requestsReceived++;
  
        // First ensure the session is stopped
        try
        {
           if (mainConsumer.isStarted()) getConsumerSession().stop();
        }
        catch (SIException sis)
        {
           //No FFDC code needed
           //Only FFDC if we haven't received a meTerminated event.
           if(!((ConversationState)getConversation().getAttachment()).hasMETerminated())
           {
              FFDCFilter.processException(sis, CLASS_NAME + ".receive",
                                          CommsConstants.CATSESSSYNCHCONSUMER_RECEIVE_01, this);
           }
  
           if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, sis.getMessage(), sis);
  
           // At this point we can not do much - so we will carry on
           // It is likely that if an exception was thrown here something
           // fairly bad went wrong and this should be flagged by subsequent
           // actions in this method
        }
  
        // Have we an async reader for this session?
        if (asynchReader == null)
        {
           if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Creating async reader for first time");
  
           asynchReader = new CATSyncAsynchReader(transaction,        // The transaction ID
                                                  getConversation(),  // The conversation
                                                  mainConsumer,       // The main consumer
                                                  requestNumber);     // The initial request #
           try
           {
              // Here we need to examine the config parameter that will denote whether we are telling
              // MP to inline our async callbacks or not. We will default to false, but this can
              // be overrideen.
              boolean inlineCallbacks =
                 CommsUtils.getRuntimeBooleanProperty(CommsConstants.INLINE_ASYNC_CBACKS_KEY,
                                                      CommsConstants.INLINE_ASYNC_CBACKS);
  
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Inline async callbacks: " + inlineCallbacks);
  
              // Here we need to examine the unrecoverable reliability setting for the session.
              // The deal is that if we are not transacted then we want to ensure that as little
              // overhead takes place as possible. As such, if we are not transacted we will
              // override the sessions unrecoverable reliability with the highest reliability
              // - making everything unrecoverable.
              // We can only override this by casting to the special MP form of consumer session
  
              Reliability unrecov = getUnrecoverableReliability();
              if (transaction == CommsConstants.NO_TRANSACTION)
              {
                 if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Setting unrecoverable reliability to max");
                 unrecov = Reliability.ASSURED_PERSISTENT;
              }
  
              MPConsumerSession mpSession = (MPConsumerSession) getConsumerSession();
              mpSession.registerAsynchConsumerCallback(asynchReader,    // The reader
                                                       0,               // Max active messages
                                                       0,               // Message lock expiry
                                                       1,               // Batch size
                                                       unrecov,         // Unrecov reliability
                                                       inlineCallbacks, // Inline
                                                       null);           // Ordering context
           }
           catch (SIException s)
           {
              //No FFDC code needed
              //Only FFDC if we haven't received a meTerminated event.
              if(!((ConversationState)getConversation().getAttachment()).hasMETerminated())
              {
                 FFDCFilter.processException(s, CLASS_NAME + ".receive",
                                             CommsConstants.CATSESSSYNCHCONSUMER_RECEIVE_02, this);
              }
  
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, s.getMessage(), s);
  
              // Inform the client - note that this will mark the reader
              // complete so that only one response is sent to the client
              asynchReader.sendErrorToClient(s,
                                             CommsConstants.CATSESSSYNCHCONSUMER_RECEIVE_02);
  
              // Kill me
              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "receive");
              return;
           }
        }
        else
        {
           // Inform the consumer that we have not receieved a message
           asynchReader.setComplete(false);
           // Save the request number in the async consumer
           asynchReader.setRequestNumber(requestNumber);
           // Ensure we tell the reader which transaction to operate under
           asynchReader.setTransaction(transaction);
        }
  
        // Flush the consumer as a one shot to see if we can get
        // a message
        try
        {
           if (logicallyStarted) mainConsumer.getConsumerSession().activateAsynchConsumer(true);
        }
        catch (SIException s)
        {
           //No FFDC code needed
           //Only FFDC if we haven't received a meTerminated event.
           if(!((ConversationState)getConversation().getAttachment()).hasMETerminated())
           {
              FFDCFilter.processException(s, CLASS_NAME + ".receive",
                                          CommsConstants.CATSESSSYNCHCONSUMER_RECEIVE_03, this);
           }
  
           if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc, s.getMessage(), s);
  
           // Inform the client - note that this will mark the reader
           // complete so that only one response is sent to the client
           asynchReader.sendErrorToClient(s, CommsConstants.CATSESSSYNCHCONSUMER_RECEIVE_03);
  
           // Kill me
           if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "receive");
           return;
        }
  
        // If the consumer received a message then we are done
        if (!asynchReader.isComplete())
        {
           // If we specified a timeout, then start the consumer
           // and start the timer
           if (timeout == -1)
           {
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "No message received");
  
              asynchReader.sendNoMessageToClient();
           }
           else
           {
              asynchReader.setCurrentlyDoingReceiveWithWait(true);
              
              //At this point we are poised to go asynch so we need to register asynchReader as a SICoreConnectionListener.
              try
              {
                 final MPConsumerSession mpSession = (MPConsumerSession)getConsumerSession();
                 mpSession.getConnection().addConnectionListener(asynchReader);
              }        
              catch(SIException s)
              {
                 //No FFDC code needed
                 //Only FFDC if we haven't received a meTerminated event.
                 if(!((ConversationState)getConversation().getAttachment()).hasMETerminated())
                 {
                    FFDCFilter.processException(s, CLASS_NAME + ".receive", CommsConstants.CATSESSSYNCHCONSUMER_RECEIVE_04, this);
                 }
                 
                 if(TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, s.getMessage(), s);
                 
                 //Inform the client - note that this will mark the reader
                 //complete so that only one response is sent to the client
                 asynchReader.sendErrorToClient(s, CommsConstants.CATSESSSYNCHCONSUMER_RECEIVE_04);
                 
                 if(TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "receive");
                 return;
              }
  
              // If we are waiting indefinately, then we do not need a wake up call
              if (timeout != 0)
              {
                 // Start the timer and associate it with the reader
                 CATTimer catTimer = new CATTimer(asynchReader);
                 Alarm alarm = AlarmManager.createNonDeferrable(timeout, catTimer, "RQ: "+requestNumber);
                 if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                    SibTr.debug(this, tc, "Setting async readers alarm to: " + alarm.toString());
                 asynchReader.setCATTimer(alarm);
              }
  
              // Now start the message delivery
              if (logicallyStarted)
              {
                 if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                    SibTr.debug(this, tc, "Starting async consumer. Timeout = " + timeout + "ms");
                 mainConsumer.start(requestNumber, true, false, null);
              }
           }
        }
  
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "receive");
     }