docs: public boolean prepareAddActiveMessage()
    {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.entry(this,tc, "prepareAddActiveMessage");
      
      boolean messageAccepted = false;
      boolean limitReached = false;
  
      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        SibTr.debug(tc, "maxActiveMessagePrepareReadLock.lock(): " + maxActiveMessagePrepareLock);
      
      // Add us as a reader - this will block if a writer currently holds the lock.
      maxActiveMessagePrepareReadLock.lock(); 
  
      // Lock the actual message counters - to prevent other 'readers' concurrently making
      // changes.
      synchronized(maxActiveMessageLock)
      {
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
          SibTr.debug(tc, "Active Messages: current: " + currentActiveMessages +
                            ", prepared: " + preparedActiveMessages +
                            ", maximum: " + maxActiveMessages +
                            " (suspended: " + consumerSetSuspended + ")");
        
        // If we're already suspended we'll simply unlock the prepare and reject the message,
        // causing the consumer to suspend itself.
        
        // Otherwise, we need to check the current number of active messages...
        if(!consumerSetSuspended)
        {
          // If adding this message would cause us to reach the limit then we need to
          // drop out of this synchronize and re-take the prepare lock as a write lock.
          if((currentActiveMessages + preparedActiveMessages) == (maxActiveMessages - 1))
          {
            limitReached = true;
          }
          // Otherwise, we're safe to accept the message and add this message to the
          // prepare counter
          else
          {
            preparedActiveMessages++;
            messageAccepted = true;
            
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
              SibTr.debug(tc, "Prepare added");
          }
        }
        
        // If the message hasn't been accepted yet (because we're suspended or we
        // have to take the write lock) then release the read lock
        if(!messageAccepted)
        {
          maxActiveMessagePrepareReadLock.unlock();
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
            SibTr.debug(tc, "maxActiveMessagePrepareReadLock.unlock(): " + maxActiveMessagePrepareLock);
        }
      } // synchronize
      
      // If this message would cause us to reach the limit then we must take the write
      // lock to prevent others preparing messages while we're in the middle of this
      // threashold-case. We also need to block until any existing prepares complete to
      // ensure that we really are on the brink of suspending the set
      if(limitReached)
      {
        boolean releaseWriteLock = true;
        
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
          SibTr.debug(tc, "maxActiveMessagePrepareWriteLock.lock(): " + maxActiveMessagePrepareLock);
        
        // Take the write lock and hold it until the commit/rollback
        maxActiveMessagePrepareWriteLock.lock();
        
        // Re-take the active message counter lock
        synchronized(maxActiveMessageLock)
        {
          // We could have been suspended between us releasing the locks above
          // and re-taking them here, if that's the case we simply release the
          // write lock and reject the message add.
          if(!consumerSetSuspended)
          {
            // We're not suspended yet so accept this message and add the prepared
            // message
            messageAccepted = true;
            preparedActiveMessages++;
  
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
              SibTr.debug(tc, "Prepare added");
            
            // If we're still in the position where committing this add would make
            // us hit the limit then we need to hold onto the write lock until the
            // commit/rollback.
            if((currentActiveMessages + preparedActiveMessages) == maxActiveMessages)
            {
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                SibTr.debug(tc, "Write lock held until commit/rollback");
              
              releaseWriteLock = false;
            }
            // Otherwise, someone must have got in while we'd released the locks and
            // removed one or more of the active messages. In which case this add won't
            // make us hit the limit so we downgrade the prepare lock to a read and release
            // the write lock once we've done it.
            else
            {
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                SibTr.debug(tc, "maxActiveMessagePrepareReadLock.lock(): " + maxActiveMessagePrepareLock);
              maxActiveMessagePrepareReadLock.lock();
            }
          }
          
          // If we were told to release the write lock do it now.
          if(releaseWriteLock)
          {
            maxActiveMessagePrepareWriteLock.unlock();
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
              SibTr.debug(tc, "maxActiveMessagePrepareWriteLock.unlock(): " + maxActiveMessagePrepareLock);
          }
        }
      }
  
      if(TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.exit(this, tc, "prepareAddActiveMessage", Boolean.valueOf(messageAccepted));
        
      return messageAccepted;
    }