docs: private synchronized TickRange msgRemoved(long tick, StateStream ststream, TransactionCommon tran) throws SIResourceException
    {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
         SibTr.entry(this, tc, "msgRemoved", 
                     new Object[]{Long.valueOf(tick), 
                                 ststream, 
                                 tran});
         
      
      TickRange tr1 = null;
      boolean sendMessage = false;
  
      long stamp = tick;
      
      // We know we have reduced the number of messages in the stream
      totalMessages--;
          
      if(TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        SibTr.debug(this, tc, "totalMessages: " + totalMessages +
                              ", sendWindow: " + sendWindow +
                              ", definedSendWindow: " + definedSendWindow +
                              ", firstMsgOutsideSendWindow: " + firstMsgOutsideWindow);
      
      // We may not send any messages if our stream contains guesses
      // or if we are supposed to be reducing the sendWindow
      if( ( (containsGuesses) || (sendWindow > definedSendWindow ) )
        && ( stamp < firstMsgOutsideWindow ) )
      {
        // Just shrink the sendWindow
        if( sendWindow > 0)
        { 
          sendWindow--;
          persistSendWindow(sendWindow, tran); 
        }
      }
      else
      {
        // If the message we have just removed from the stream was
        // inside the sendWindow then we can move up our 
        // firstMsgOutsideWindow and possibly send the message which
        // moves inside the window
        // If it actually was the first message outside the window
        // the code below will also work
        // If it was beyond the window we can afford to ignore it 
        if (stamp <= firstMsgOutsideWindow)
        {
          // send firstMsgOutsideWindow
          // first need to get it and check that it is in Value state
          ststream.setCursor(firstMsgOutsideWindow);
   
          // Get the first TickRange outside the inDoubt window
          tr1 = ststream.getNext();
            
          // This range must be either Uncommitted or Value as that is how
          // we set the firstMsgOutsideWindow pointer    
          // Only want to send this message if it is 
          // committed. Otherwise do nothing as it will
          // get sent when it commits
          if (tr1.type == TickRange.Value)
          {
            sendMessage = true;
          }
       
          TickRange tr = null;
          if (totalMessages > sendWindow)
          {
            // Get the next Value or Uncommitted tick from the stream
            tr = ststream.getNext();
            while( tr.type == TickRange.Completed && tr.endstamp != RangeList.INFINITY)
            {
              tr = ststream.getNext();
            }
            firstMsgOutsideWindow = tr.valuestamp;
          }
          // That was the last message outside the send window, so put us back into a state
          // ignorant of guesses, otherwise we may not realise to re-calculate the firstMsgOutSideWindow
          // the next time we get a guess.
          else
          {
            firstMsgOutsideWindow = RangeList.INFINITY;
            containsGuesses = false;
          }
          
          if(TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
            SibTr.debug(this, tc, "firstMsgOutsideSendWindow: " + firstMsgOutsideWindow);
        }
      }
  
      // Return a null if nothing to send
      if (!sendMessage)
        tr1 = null;
  
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
          SibTr.exit(tc, "msgRemoved", tr1);
  
      return tr1;
    }