protected void removeDispatchedEvents(EventID lastDispatched)
      throws CacheException, InterruptedException {
    ThreadIdentifier ti = getThreadIdentifier(lastDispatched);
    long sequenceID = lastDispatched.getSequenceID();
    // get the DispatchedAndCurrentEvents object for this threadID
    DispatchedAndCurrentEvents dace = (DispatchedAndCurrentEvents) eventsMap.get(ti);
    if (dace != null && dace.lastDispatchedSequenceId < sequenceID) {
      dace.setLastDispatchedIDAndRemoveEvents(sequenceID);
    } else if (dace == null) {
      dace = new DispatchedAndCurrentEvents(this);
      dace.lastDispatchedSequenceId = sequenceID;
      DispatchedAndCurrentEvents oldDace =
          (DispatchedAndCurrentEvents) eventsMap.putIfAbsent(ti, dace);
      if (oldDace != null) {
        dace = oldDace;
        if (dace.lastDispatchedSequenceId < sequenceID) {
          dace.setLastDispatchedIDAndRemoveEvents(sequenceID);
        }
      } else {
        // Add the recently added ThreadIdentifier to the RegionQueue for
        // expiry
        region.put(ti, dace.lastDispatchedSequenceId);
        // update the stats
        stats.incThreadIdentifiers();
      }
    }
  }
This method is invoked by the QRM to remove the IDs which have already been dispatched by the
primary node. It sets the last dispatched sequence ID in the DACE iff the sequenceID received
is more than the current. If the renoval emssage arrives before the DACE was created, it
creates a DACE. Only one QRM operates at a time on a DACE & any other mesasge will be waiting
for the current thread to exit. This is accomplished by taking a lock on QRM_LOCK object in the
DACE.

@param lastDispatched EventID containing the ThreadIdentifier and the last dispatched sequence
       Id
geode-core/src/main/java/org/apache/geode/internal/cache/ha/HARegionQueue.java