public void destroy()
    {
        List<SerializedPageReference> removedPages;
        PendingRead pendingRead;
        synchronized (this) {
            removedPages = ImmutableList.copyOf(pages);
            pages.clear();

            bufferedBytes.getAndSet(0);

            noMorePages = true;
            destroyed.set(true);

            pendingRead = this.pendingRead;
            this.pendingRead = null;
        }

        dereferencePages(removedPages, onPagesReleased);

        if (pendingRead != null) {
            pendingRead.completeResultFutureWithEmpty();
        }
    }
@Test
    public void testReferenceCount()
    {
        AtomicInteger releasedPages = new AtomicInteger(0);
        PagesReleasedListener onPagesReleased = (lifespan, releasedPagesCount, releasedSizeInBytes) -> {
            releasedPages.addAndGet(releasedPagesCount);
        };
        ClientBuffer buffer = new ClientBuffer(TASK_INSTANCE_ID, BUFFER_ID, onPagesReleased);

        // add 2 pages and verify they are referenced
        addPage(buffer, createPage(0));
        addPage(buffer, createPage(1));
        assertEquals(releasedPages.get(), 0);
        assertBufferInfo(buffer, 2, 0);

        // read one page
        assertBufferResultEquals(TYPES, getBufferResult(buffer, 0, sizeOfPages(0), NO_WAIT), bufferResult(0, createPage(0)));
        assertEquals(releasedPages.get(), 0);
        assertBufferInfo(buffer, 2, 0);

        // acknowledge first page
        assertBufferResultEquals(TYPES, getBufferResult(buffer, 1, sizeOfPages(1), NO_WAIT), bufferResult(1, createPage(1)));
        assertEquals(releasedPages.get(), 1);
        assertBufferInfo(buffer, 1, 1);

        // destroy the buffer
        buffer.destroy();
        assertEquals(releasedPages.get(), 2);
        assertBufferDestroyed(buffer, 1);
    }