docs: private void writeSilenceInternal(TickRange tr, boolean forced)
      {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.entry(this, tc, "writeSilenceInternal", new Object[] { tr, Boolean.valueOf(forced) });
  
          List msgList = null;
  
          // Take lock on target stream and hold it until messages have been
          // added to batch by deliverOrderedMessages 
          synchronized (this)
          {
              // We are only allowed to remove a message from the stream and replace 
              // it with Silence if it has not yet been added to a Batch to be delivered
              // We know that this can't happen asynchronously once we hold the targetStream lock
              // and the nextCompletedPrefix tells us the last message in the current batch 
              if (!forced || tr.valuestamp > this.nextCompletedPrefix)
              {
  
                  synchronized (oststream)
                  {
                      // Get the completedPrefix 
                      long completedPrefix = oststream.getCompletedPrefix();
  
                      // check if all ticks in Silence msg are already acked as if
                      // so they will be changed to Completed anyway and we don't need
                      // to do it now
                      if (tr.endstamp > completedPrefix)
                      {
                          if (forced == false)
                              oststream.writeRange(tr);
                          else
                              oststream.writeCompletedRangeForced(tr);
  
                          // Get updated completedPrefix
                          completedPrefix = oststream.getCompletedPrefix();
  
                      }
  
                      // The completedPrefix may have advanced when the Silence message
                      // was writen to the stream or both
                      if ((completedPrefix + 1) > doubtHorizon)
                      {
                          // advance the doubt horizon
                          doubtHorizon = completedPrefix + 1;
  
                          // now call the method which trys to advance the doubtHorizon
                          // from it's current setting by moving over any ticks in Completed 
                          // state and sending Values messages until it reaches a tick in
                          // Unknown or Requested
                          msgList = advanceDoubtHorizon(null);
                      }
  
                      if ((doubtHorizon - 1) > unknownHorizon)
                          unknownHorizon = doubtHorizon - 1;
  
                      // the message was writen to the stream
                      // see if this message created a gap
                      if (tr.endstamp > unknownHorizon)
                      {
                          // check if gap created
                          if (tr.startstamp > (unknownHorizon + 1))
                          {
                              handleNewGap(unknownHorizon + 1, tr.startstamp - 1);
                          }
                          unknownHorizon = tr.endstamp;
                      }
  
                      // Reset the health state
                      if (lastNackTick >= 0)
                      {
                          if (tr.startstamp <= lastNackTick && tr.endstamp >= lastNackTick)
                          {
                              getControlAdapter().getHealthState().updateHealth(HealthStateListener.MSG_LOST_ERROR_STATE,
                                                                                HealthState.GREEN);
                              lastNackTick = -1;
                          }
                      }
  
                      // If the stream is blocked, see if we have a silence for the blocking tick
                      if (isStreamBlocked())
                      {
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                              SibTr.debug(tc, "Stream is blocked on tick: " + linkBlockingTick + ", see if we can unblock it");
                          if (tr.endstamp >= linkBlockingTick)
                          {
                              if (tr.startstamp <= linkBlockingTick)
                              {
                                  // The stream is no longer blocked
                                  setStreamIsBlocked(false, DestinationHandler.OUTPUT_HANDLER_FOUND, null, null);
                              }
                          }
                      } // eof isStreamBlocked()
                  } // end sync ( release the oststream lock )
  
                  // Deliver messages outside of synchronise 
                  // We do this because deliverOrderedMessages takes the 
                  // BatchHandler lock and the BatchHandler callbacks require
                  // the stream lock to update the completedPrefix. If we call
                  // the BatchHandler when we hold the stream lock it could cause
                  // a deadlock
                  if (msgList != null)
                  {
                      // Call the Input or Output Handler to deliver the messages
                      try
                      {
                          deliverer.deliverOrderedMessages(msgList, this, priority, reliability);
                      } catch (SINotPossibleInCurrentConfigurationException e)
                      {
                          // No FFDC code needed
                          SibTr.exception(tc, e);
  
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                              SibTr.debug(tc, "writeSilenceInternal", "GDException");
  
                          // Dont rethrow the exception. The GD protocols will handle the resend of
                          // the message
                      } catch (SIException e)
                      {
                          // FFDC
                          FFDCFilter.processException(
                                                      e,
                                                      "com.ibm.ws.sib.processor.gd.GuaranteedTargetStream.writeSilenceInternal",
                                                      "1:960:1.110",
                                                      this);
  
                          SibTr.exception(tc, e);
                          SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0002",
                                      new Object[] {
                                                    "com.ibm.ws.sib.processor.gd.GuaranteedTargetStream",
                                                    "1:967:1.110",
                                                    e });
  
                          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                              SibTr.exit(tc, "writeSilenceInternal", "GDException");
  
                          throw new SIErrorException(
                                          nls.getFormattedMessage(
                                                                  "INTERNAL_MESSAGING_ERROR_CWSIP0002",
                                                                  new Object[] {
                                                                                "com.ibm.ws.sib.processor.gd.GuaranteedTargetStream",
                                                                                "1:977:1.110",
                                                                                e },
                                                                  null),
                                          e);
                      }
                  }
  
              } // else can't remove as already in batch 
          } // end sync - release lock on target stream
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.exit(tc, "writeSilenceInternal");
      }