@Override
    public T poll() {
        if (size == 0) {
            return null;
        }
        T result = queue[0];
        result.priorityQueueIndex(this, INDEX_NOT_IN_QUEUE);

        T last = queue[--size];
        queue[size] = null;
        if (size != 0) { // Make sure we don't add the last element back.
            bubbleDown(0, last);
        }

        return result;
    }
@Test
    public void testPoll() {
        PriorityQueue<TestElement> queue = new DefaultPriorityQueue<TestElement>(TestElementComparator.INSTANCE, 0);
        assertEmptyQueue(queue);

        TestElement a = new TestElement(5);
        TestElement b = new TestElement(10);
        TestElement c = new TestElement(2);
        TestElement d = new TestElement(7);
        TestElement e = new TestElement(6);

        assertOffer(queue, a);
        assertOffer(queue, b);
        assertOffer(queue, c);
        assertOffer(queue, d);

        // Remove the first element
        assertSame(c, queue.peek());
        assertSame(c, queue.poll());
        assertEquals(3, queue.size());

        // Test that offering another element preserves the priority queue semantics.
        assertOffer(queue, e);
        assertEquals(4, queue.size());
        assertSame(a, queue.peek());
        assertSame(a, queue.poll());
        assertEquals(3, queue.size());

        // Keep removing the remaining elements
        assertSame(e, queue.peek());
        assertSame(e, queue.poll());
        assertEquals(2, queue.size());

        assertSame(d, queue.peek());
        assertSame(d, queue.poll());
        assertEquals(1, queue.size());

        assertSame(b, queue.peek());
        assertSame(b, queue.poll());
        assertEmptyQueue(queue);
    }