docs: @Override
      public final void alarm(Object obj)
      {
          if (messagingEngine != null)
              SibTr.push(messagingEngine);
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.entry(this, tc, "alarm", "deliveryDelayIndexSize=" + deliveryDelayIndex.size());
  
          synchronized (lockObject)
          {
              // we try ensure there is only ever 1 alarm thread running and check at the end of each alarm 
              // if another needs scheduling.  3 consecutive checked exceptions are tolerated.
              alarmScheduled = false;
  
              while (alarming)
              {
                  // this is only now possible with a highly unlikely thread scheduling, but cope with it
                  // anyway.
                  try
                  {
                      lockObject.wait();
                  } catch (InterruptedException e)
                  {
                      // No FFDC Code Needed
                  }
              }
  
              alarming = true;
          }
  
          LocalTransaction transaction = null;
          int indexUsed = 0;
          long processed = 0;
          long unlocked = 0;
          long cleaned = 0;
          long gone = 0;
          long remain = 0;
  
          try
          {
              // Once every 5 cycles, set the flag to initiate full-index scan
              // for items which are no longer in the store.
              countForCleanup++;
              if (countForCleanup >= cleanupLimit)
              {
                  countForCleanup = 0;
                  cleanupDeletedItems = true;
              }
              else
              {
                  cleanupDeletedItems = false;
              }
  
              // Get current system time for start of cycle
              maximumTime = System.currentTimeMillis();
              indexUsed = saveStartTime(maximumTime);
  
              // Get the first entry from the index and start the cycle
              DeliveryDelayableReference deliveryDelayableRef = null;
              synchronized (lockObject)
              {
                  // Point to the start of the tree                  
                  deliveryDelayIndex.resetIterator();
                  deliveryDelayableRef = deliveryDelayIndex.next();
              }
              while (runEnabled && deliveryDelayableRef != null && deliveryDelayableRef.getDeliveryDelayTime() <= maximumTime)
              {
                  processed++;
  
                  DeliveryDelayable deliveryDelayable = (DeliveryDelayable) deliveryDelayableRef.get();
                  // If the soft reference is null or if the item indicates that it has
                  // already gone from the store, then remove the DeliveryDelayable ref from the index 
                  if (deliveryDelayable != null && deliveryDelayable.deliveryDelayableIsInStore())
                  {
                      // Now processing items which are either at or past their delivery delay time.
                      // Create a transaction if we don't have one already
                      if (transaction == null)
                      {
                          transaction = messageStore.getTransactionFactory().createLocalTransaction();
                      }
                      // Tell the DeliveryDelayable to unlock. If it returns true, then remove it from the DeliveryDelay index.
                      if (deliveryDelayable.deliveryDelayableUnlock((PersistentTransaction) transaction, AbstractItem.DELIVERY_DELAY_LOCK_ID))
                      {
                          unlocked++;
                          // Remove from DeliveryDelay index
                          remove(deliveryDelayableRef, true);
                          batchCount++;
                          if (batchCount >= BATCH_SIZE)
                          {
                              transaction.commit();
                              transaction = null;
                              batchCount = 0;
                          }
                      }
                      else
                      {
                          remain++;
                      }
                  }
                  else
                  {
                      if (remove(deliveryDelayableRef, false))
                      {
                          gone++;
                      }
                  }
                  synchronized (lockObject)
                  {
                      deliveryDelayableRef = deliveryDelayIndex.next();
                  }
              }
  
              // Once every 'n' cycles, continue to the end of the DeliveryDelay index
              // removing any entries for items which are no longer in the store.
              if (cleanupDeletedItems)
              {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                      SibTr.debug(this, tc, "DeliveryDelayManager cleanup in progress");
  
                  while (runEnabled && deliveryDelayableRef != null)
                  {
                      DeliveryDelayable deliveryDelayable = (DeliveryDelayable) deliveryDelayableRef.get();
                      // If the soft reference is null or if the item indicates that it has
                      // gone from the store, then remove the DeliveryDelayable ref from the index 
                      if (deliveryDelayable == null || !(deliveryDelayable.deliveryDelayableIsInStore()))
                      {
                          if (remove(deliveryDelayableRef, false))
                          {
                              cleaned++;
                          }
                      }
                      synchronized (lockObject)
                      {
                          deliveryDelayableRef = deliveryDelayIndex.next();
                      }
                  }
                  // Check how much useful work we did, and vary the frequency 
                  // of the cleanup cycle. 
                  if (cleaned < 10 && cleanupLimit < 100)
                  {
                      cleanupLimit += CLEANUP_EVERY_N_CYCLES; // Slow down
                  }
                  else if (cleaned > 1000 && cleanupLimit > CLEANUP_EVERY_N_CYCLES)
                  {
                      cleanupLimit = CLEANUP_EVERY_N_CYCLES; // Restore default
                  }
                  else if (cleaned > 100 && cleanupLimit > CLEANUP_EVERY_N_CYCLES)
                  {
                      cleanupLimit -= CLEANUP_EVERY_N_CYCLES; // Speed up
                  }
              }
  
              if (transaction != null) // Did we create a transaction?
              {
                  if (batchCount == 0) // No work outstanding  
                  {
                      transaction.rollback();
                  }
                  else // Work outstanding, must be committed  
                  {
                      transaction.commit();
                      batchCount = 0;
                  }
                  transaction = null;
              }
              consecutiveFailures = 0;
          } // end try
          catch (Exception e)
          {
              com.ibm.ws.ffdc.FFDCFilter.processException(e, "com.ibm.ws.sib.msgstore.deliverydelay.DeliveryDelayManager.alarm", "550", this);
              if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled())
                  SibTr.event(this, tc, "alarm", "DeliveryDelayManager thread exception: " + e);
  
              consecutiveFailures++;
              lastException = e;
              lastExceptionTime = timeNow();
  
              if (consecutiveFailures > MAX_CONSECUTIVE_FAILURES)
              {
                  synchronized (lockObject)
                  {
                      runEnabled = false;
                      addEnabled = false;
                  }
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                      SibTr.exit(tc, "alarm", e);
                  throw new MessageStoreRuntimeException("DELIVERYDELAYMANAGER_DAEMON_TERMINATED_SIMS2011", new Object[] { e }, e);
              }
          } finally
          {
              long currIndexSize = 0;
              // Synchronize while we decide whether to schedule another alarm or not
              synchronized (lockObject)
              {
                  alarming = false;
                  currIndexSize = deliveryDelayIndex.size();
  
                  if (runEnabled) // We have not been told to stop,
                  {
                      if (currIndexSize > 0) // and the index is not empty, 
                      {
                          scheduleAlarm(interval); // ... schedule the next alarm
                      }
                  }
                  else // DeliveryDelayManager is stopping
                  {
                      // Disallow addition of any further DeliveryDelayable to the index.
                      addEnabled = false;
                  }
                  lockObject.notifyAll();
              }
  
              // Save statistics for diagnostic dump using the same log index as
              // returned by saveStartTime() called at start of this cycle.
              logIndexSize[indexUsed] = currIndexSize;
              logProcessed[indexUsed] = processed;
              logUnlocked[indexUsed] = unlocked;
              logGone[indexUsed] = gone;
              logRemain[indexUsed] = remain;
              logCleaned[indexUsed] = cleaned;
  
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.exit(tc,
                         "alarm",
                         " processed=" + processed + " gone=" + gone + " unlocked=" + unlocked + " remain=" + remain + " cleaned=" + cleaned + " DeliveryDelayIndexSize="
                                         + deliveryDelayIndex.size()
                                         + " cleanupLimit="
                                         + cleanupLimit + " alarmScheduled=" + alarmScheduled);
  
          if (messagingEngine != null)
              SibTr.pop();
      }