@Override
    public Optional<Listener> acquire(ContextT context) {
        return tryAcquire(context).map(delegate -> new Listener() {
            @Override
            public void onSuccess() {
                delegate.onSuccess();
                unblock();
            }

            @Override
            public void onIgnore() {
                delegate.onIgnore();
                unblock();
            }

            @Override
            public void onDropped() {
                delegate.onDropped();
                unblock();
            }
        });
    }
@Test
    public void verifyFifoOrder() {
        // Make sure all tokens are acquired
        List<Optional<Limiter.Listener>> firstBatch = acquireN(blockingLimiter, 4);

        // Kick off 5 requests with a small delay to ensure futures are created in the correct order
        List<Integer> values = new CopyOnWriteArrayList<>();
        List<CompletableFuture<Void>> futures = IntStream.range(0, 5)
                .peek(i -> {
                    try {
                        TimeUnit.MILLISECONDS.sleep(50);
                    } catch (InterruptedException e) {
                    }
                })
                .mapToObj(i -> CompletableFuture.<Void>supplyAsync(() -> {
                    Optional<Limiter.Listener> listener = blockingLimiter.acquire(null);
                    if (!listener.isPresent()) {
                        values.add(-1);
                    }
                    try {
                        values.add(i);
                    } finally {
                        listener.get().onSuccess();
                    }
                    return null;
                }, executor))
                .collect(Collectors.toList());

        // Release the first batch of tokens
        firstBatch.forEach(listener -> {
            try {
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
            }
            listener.get().onSuccess();
        });

        // Make sure all requests finished
        futures.forEach(future -> {
                    try {
                        future.get();
                    } catch (Exception e) {
                    }
                });

        // Verify that results are in reverse order
        Assert.assertEquals(Arrays.asList(4, 3, 2, 1, 0), values);
    }