docs: final AbstractItem cmdRemoveIfMatches(final Filter filter, PersistentTransaction transaction) throws SevereMessageStoreException
      {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.entry(this, tc, "cmdRemoveIfMatches", new Object[] { "Item Link:   " + this, "Stream Link: " + _owningStreamLink, "Filter:      " + filter,
                                                                        "Transaction: " + transaction });
  
          AbstractItem foundItem = null;
  
          /*
           * A new filter DeliveryDelayDeleteFilter is explicitly created
           * to fetch the items which are available or
           * are locked for delivery delay and off course which
           * are not expired
           */
  
          isExpired();
          /*
           * <p>
           * Prior to delivery delay feature when the destination is deleted,
           * the AsyncDeletionThread internally passes null as the filter and
           * used to delete only the available messages which are not expired.
           * But with the introduction of delivery delay feature items
           * locked for delivery delay that also must be deleted
           * or reallocated to exception destination.
           * <p>
           * Now when destination is deleted, if the item is either locked
           * for delivery delay or if its in available state and not expired
           * the item is eligible for deletion or reallocation to exception
           * destination
           */
          if (isAvailable() || (getLockID() == Item.DELIVERY_DELAY_LOCK_ID && isStateLocked()))
          {
              AbstractItem item = getItem();
              if (null == item)
              {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                      SibTr.debug(this, tc, "item does not exist");
              }
              else
              {
                  try
                  {
                      // DeliveryDelayDeleteFilter will always return true
                      if (null == filter || filter.filterMatches(item))
                      {
                          // only if we pass all the tests will take the monitor and lock.
                          boolean hasBecomeNotReleasable = false;
                          synchronized (this)
                          {
                              // matching may cause restore, which may cause expiry
                              if (isAvailable() || (_lockID == Item.DELIVERY_DELAY_LOCK_ID && isStateLocked()))
                              {
                                  ListStatistics stats = getParentStatistics();
                                  synchronized (stats)
                                  {
                                      stats.decrementAvailable();
                                      stats.incrementRemoving();
                                  }
  
                                  foundItem = item;
                                  hasBecomeNotReleasable = _declareNotDiscardable(item);
  
                                  _transactionId = transaction.getPersistentTranId();
  
                                  // to maintain consistency set the appropriate item link state
                                  if (_lockID == Item.DELIVERY_DELAY_LOCK_ID)
                                      _itemLinkState = ItemLinkState.STATE_REMOVING_LOCKED;
                                  else
                                      _itemLinkState = ItemLinkState.STATE_REMOVING_WITHOUT_LOCK;
                              }
  
                              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                                  SibTr.debug(this, tc, "matched");
                          }
  
                          if (null != foundItem)
                          {
                              if (hasBecomeNotReleasable)
                              {
                                  _declareNotReleasable();
                              }
                              Task task = new RemoveTask(this);
                              transaction.addWork(task);
                          }
                      }
                  } catch (MessageStoreException e)
                  {
                      //No FFDC Code Needed.
                      // assume exception is false return
                  }
              }
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.exit(this, tc, "removeIfMatches", foundItem);
          return foundItem;
      }