code: private List<Event<T>> scanEvents(boolean fullScan) {
          LOG.debug("Scan events, eviction policy {}", evictionPolicy);
          List<T> eventsToExpire = new ArrayList<>();
          List<Event<T>> eventsToProcess = new ArrayList<>();
          try {
              lock.lock();
              Iterator<Event<T>> it = queue.iterator();
              while (it.hasNext()) {
                  Event<T> windowEvent = it.next();
                  Action action = evictionPolicy.evict(windowEvent);
                  if (action == Action.EXPIRE) {
                      eventsToExpire.add(windowEvent.get());
                      it.remove();
                  } else if (!fullScan || action == Action.STOP) {
                      break;
                  } else if (action == Action.PROCESS) {
                      eventsToProcess.add(windowEvent);
                  }
              }
              expiredEvents.addAll(eventsToExpire);
          } finally {
              lock.unlock();
          }
          eventsSinceLastExpiry.set(0);
          LOG.debug("[{}] events expired from window.", eventsToExpire.size());
          if (!eventsToExpire.isEmpty()) {
              LOG.debug("invoking windowLifecycleListener.onExpiry");
              windowLifecycleListener.onExpiry(eventsToExpire);
          }
          return eventsToProcess;
      }
docs: Scan events in the queue, using the expiration policy to check
  if the event should be evicted or not.
  
  @param fullScan if set, will scan the entire queue; if not set, will stop
  as soon as an event not satisfying the expiration policy is found
  @return the list of events to be processed as a part of the current window