docs: public void updateToCompleted(long startTick, long endTick) throws SIResourceException
    {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.entry(
          tc,
          "updateToCompleted",
          new Object[] { Long.valueOf(startTick), Long.valueOf(endTick)});
  
      boolean checkCompletedPrefix = false;
      _targetStream.setCursor(startTick);
      TickRange tr1 = _targetStream.getNext();
      TickRange tr2 = null;
  
      do
      {
        // long acceptedItemId = AnycastInputHandler.INVALID_ACCEPTED_ITEM_ID;
        boolean update = true;
        boolean resolve = false;
        AIStreamKey tsKey = null;
  
        // TickRange combinedRange = null;
        if (tr1.type == TickRange.Accepted)
        {
          AIAcceptedTick at = (AIAcceptedTick) tr1.value;
          // acceptedItemId = at.acceptedItemId;
          _acceptedTOM.removeTimeoutEntry(at);
          // Remove from initialTOM just in case we are not on a first time round (e.g. If a DecisionRequested msg came in from the DME
          // before the initialTOM popped)
          _initialAcceptedTOM.removeTimeoutEntry(at);
  
        }
        else if (tr1.type == TickRange.Rejected)
        {
          AIRejectedRange rr = (AIRejectedRange) tr1.value;
          _rejectedTOM.removeTimeoutEntry(rr);
        }
        else if (tr1.type == TickRange.Requested)
        {
          // This can occur if the DME crashes and recovers, at which point
          // it will have forgotten the Q/G and replaced it with an L/D; it's
          // up to the consumer to reissue the get request
          AIRequestedTick rt = (AIRequestedTick) tr1.value;
          // TODO would it be better to have stored the key with the tick?
          tsKey =
            new AIStreamKey(
              tr1.startstamp,
              rt.getRemoteDispatchableKey(),
              rt.getOriginalTimeout(),
              rt.getIssueTime());
          resolve = true;
  
          // If the request hasn't timed out, stop repeating it because it will be
          // re-requested as part of the resolve below
          if (rt.getTimeout() > 0 || rt.getOriginalTimeout() == SIMPConstants.INFINITE_TIMEOUT)
          {
            if (rt.isSlowed())
            {
              _slowedGetTOM.removeTimeoutEntry(rt);
            }
            else
            {
              _eagerGetTOM.removeTimeoutEntry(rt);
            }
          }
        }
        else if (tr1.type == TickRange.Value)
        {
          // This could be due to admin cleanup at the DME
          AIValueTick vt = (AIValueTick) tr1.value;
          if (!vt.isDelivered())
          {
            tsKey =
              new AIStreamKey(
                tr1.startstamp,
                vt.getRemoteDispatchableKey(),
                vt.getOriginalTimeout(),
                vt.getIssueTime());
            resolve = true;
          }
          else
          {
            // Tick was already delivered and turned to L/D
            SIErrorException e1 =
              new SIErrorException(
                nls.getFormattedMessage(
                  "INTERNAL_MESSAGING_ERROR_CWSIP0001",
                  new Object[] {
                    "com.ibm.ws.sib.processor.gd.AIStream",
                    "1:1146:1.108.2.18"  },
                  null));
  
            // FFDC
            FFDCFilter.processException(
              e1,
              "com.ibm.ws.sib.processor.gd.AIStream.updateToCompleted",
              "1:1153:1.108.2.18" ,
              this);
  
            SibTr.exception(tc, e1);
  
            SibTr.error(tc,
                        "INTERNAL_MESSAGING_ERROR_CWSIP0001",
                        new Object[] {
                          "com.ibm.ws.sib.processor.gd.AIStream",
                          "1:1162:1.108.2.18"  });
  
            if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.exit(tc, "updateToCompleted", null);
  
            throw e1;
          }
        }
        else
        {
          // If it's completed, no need to update; should not happen otherwise
          update = false;
        }
  
        if (update)
        {
          /* combinedRange = */
          writeCompletedRange(tr1.startstamp, tr1.endstamp);
          checkCompletedPrefix = true;
        }
  
        // If a completed came in before we send an accept or reject then we need
        // to re-request a msg so we dont forget about the outstanding request.
        if (resolve)
          _parent.resolve(tsKey);
  
        tr2 = tr1;
        tr1 = _targetStream.getNext();
      }
      while ((tr1.startstamp <= endTick) && (tr1 != tr2));
  
      if (checkCompletedPrefix)
      {
        synchronized (_completedPrefix)
        {
          if (_targetStream.getCompletedPrefix() > _completedPrefix.getTick())
          {
            // Update the item and schedule it for update if it is not already scheduled
            _completedPrefix.setTick(_targetStream.getCompletedPrefix());
            if (_completedPrefixNeedsToBeScheduled)
            {
              CompletedPrefixAsyncUpdate update = new CompletedPrefixAsyncUpdate();
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                SibTr.debug(tc, "CompletedPrefixAsyncUpdate " + update + " : " + _countOfOutstandingCPUpdates);
              if (doEnqueueWork(update))
              {
                _completedPrefixNeedsToBeScheduled = false;
                //  Make sure a thread that may be trying to remove the completed prefix waits
                // for notification when the count goes down to zero
                _countOfOutstandingCPUpdates++;
              }
              // else something went seriously wrong but we already FFDCed
            }
          }
        }
      }
  
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.exit(tc, "updateToCompleted");
    }