code: public <T> Batcher<T> build(BatchListener<T> listener) {
          requireNonNull(listener);
          checkState(maxSize != UNSET_INT || interval != UNSET_INT, "All batchers are required to have either a time or size bound.");
  
          ExecutorService handler = (listenerService == null ? newCachedThreadPool() : listenerService);
          BlockingQueue<T> backingQueue = (maxBufferSize == UNSET_INT ? new LinkedBlockingQueue<T>() : new ArrayBlockingQueue<T>(maxBufferSize));
  
          if (maxSize != UNSET_INT && interval != UNSET_INT) {
              return new TimeOrSizeBatcher<>(backingQueue, listener, handler, maxSize, interval)
                      .start();
          } else if (maxSize != UNSET_INT) {
              return new SizeBatcher<>(backingQueue, listener, handler, maxSize)
                      .start();
          } else {
              return new TimeBatcher<>(backingQueue, listener, handler, interval)
                      .start();
          }
      }
docs: Builds a {@link Batcher} which will provide batches to the provided {@code listener}.
  
  Note: The builder is required to have either a time or size bound to build a batch.