WrappingAsyncPeekIterator implements AsyncPeekCallbackIterator<T> { @Override public boolean hasNext() { return onHasNext().join(); } WrappingAsyncPeekIterator(@Nonnull AsyncIterator<T> underlying);   WrappingAsyncPeekIterator(@Nonnull AsyncIterator<T> underlying, @Nonnull Consumer<T> callback); @Override CompletableFuture<Boolean> onHasNext(); @Override boolean hasNext(); @Override T peek(); @Override T next(); @Override void cancel(); @Override void setCallback(@Nonnull Consumer<T> callback); @Override @Nonnull Consumer<T> getCallback();  }
@Test public void wrappingEmptyList() { AsyncPeekIterator<Integer> iterator = AsyncPeekIterator.wrap(new NonAsyncIterator<>(Collections.emptyIterator())); assertFalse(iterator.hasNext()); assertThrows(NoSuchElementException.class, iterator::peek); assertThrows(NoSuchElementException.class, iterator::next); assertThrows(NoSuchElementException.class, iterator::peek); assertFalse(iterator.hasNext()); }