@Override
    public boolean release() {
        // Call unwrap() before just in case that super.release() will change the ByteBuf instance that is returned
        // by unwrap().
        ByteBuf unwrapped = unwrap();
        if (super.release()) {
            closeLeak(unwrapped);
            return true;
        }
        return false;
    }
@Test
    public void forEachByteUnderLeakDetectionShouldNotThrowException() {
        CompositeByteBuf buf = (CompositeByteBuf) newBuffer(8);
        assertThat(buf, CoreMatchers.instanceOf(SimpleLeakAwareCompositeByteBuf.class));
        CompositeByteBuf comp = (CompositeByteBuf) newBuffer(8);
        assertThat(comp, CoreMatchers.instanceOf(SimpleLeakAwareCompositeByteBuf.class));

        ByteBuf inner = comp.alloc().directBuffer(1).writeByte(0);
        comp.addComponent(true, inner);
        buf.addComponent(true, comp);

        assertEquals(-1, buf.forEachByte(new ByteProcessor() {
            @Override
            public boolean process(byte value) {
                return true;
            }
        }));
        assertTrue(buf.release());
    }