class PagesListMetaIO extends PageIO {
    /** */
    private static final int CNT_OFF = COMMON_HEADER_END;

    /** */
    private static final int NEXT_META_PAGE_OFF = CNT_OFF + 2;

    /** */
    public static final int ITEMS_OFF = NEXT_META_PAGE_OFF + 8;

    /** */
    public static final int ITEM_SIZE = 10;

    /** */
    public static final IOVersions<PagesListMetaIO> VERSIONS = new IOVersions<>(
        new PagesListMetaIO(1)
    );

    /**
     * @param ver  Page format version.
     */
    private PagesListMetaIO(int ver) {
        super(T_PAGE_LIST_META, ver);
    }

    /** {@inheritDoc} */
    @Override public void initNewPage(long pageAddr, long pageId, int pageSize, PageMetrics metrics) {
        super.initNewPage(pageAddr, pageId, pageSize, metrics);

        setCount(pageAddr, 0);
        setNextMetaPageId(pageAddr, 0L);
    }

    /**
     * @param pageAddr Page address.
     * @return Stored items count.
     */
    private int getCount(long pageAddr) {
        return PageUtils.getShort(pageAddr, CNT_OFF);
    }

    /**
     * @param pageAddr Page address.
     * @param cnt Stored items count.
     */
    private void setCount(long pageAddr, int cnt) {
        assert cnt >= 0 && cnt <= Short.MAX_VALUE : cnt;
        assertPageType(pageAddr);

        PageUtils.putShort(pageAddr, CNT_OFF, (short)cnt);
    }

    /**
     * @param pageAddr Page address.
     * @return Next meta page ID.
     */
    public long getNextMetaPageId(long pageAddr) {
        return PageUtils.getLong(pageAddr, NEXT_META_PAGE_OFF);
    }

    /**
     * @param pageAddr Page address.
     * @param metaPageId Next meta page ID.
     */
    public void setNextMetaPageId(long pageAddr, long metaPageId) {
        assertPageType(pageAddr);

        PageUtils.putLong(pageAddr, NEXT_META_PAGE_OFF, metaPageId);
    }

    /**
     * @param pageAddr Page address.
     */
    public void resetCount(long pageAddr) {
        setCount(pageAddr, 0);
    }

    /**
     * @param pageSize Page size.
     * @param pageAddr Page address.
     * @param bucket Bucket number.
     * @param tails Tails.
     * @param tailsOff Tails offset.
     * @return Number of items written.
     */
    public int addTails(int pageSize, long pageAddr, int bucket, PagesList.Stripe[] tails, int tailsOff) {
        assert bucket >= 0 && bucket <= Short.MAX_VALUE : bucket;
        assertPageType(pageAddr);

        int cnt = getCount(pageAddr);
        int cap = getCapacity(pageSize, pageAddr);

        if (cnt == cap)
            return 0;

        int off = offset(cnt);

        int write = Math.min(cap - cnt, tails.length - tailsOff);

        for (int i = 0; i < write; i++) {
            PageUtils.putShort(pageAddr, off, (short)bucket);
            PageUtils.putLong(pageAddr, off + 2, tails[tailsOff].tailId);

            tailsOff++;

            off += ITEM_SIZE;
        }

        setCount(pageAddr, cnt + write);

        return write;
    }

    /**
     * @param pageAddr Page address.
     * @param res Results map.
     */
    public void getBucketsData(long pageAddr, Map<Integer, GridLongList> res) {<FILL_FUNCTION_BODY>}

    /**
     * @param pageAddr Page address.
     * @return Maximum number of items which can be stored in buffer.
     */
    public int getCapacity(int pageSize, long pageAddr) {
        return (pageSize - ITEMS_OFF) / ITEM_SIZE;
    }

    /**
     * @param idx Item index.
     * @return Item offset.
     */
    private int offset(int idx) {
        return ITEMS_OFF + ITEM_SIZE * idx;
    }

    /** {@inheritDoc} */
    @Override protected void printPage(long addr, int pageSize, GridStringBuilder sb) throws IgniteCheckedException {
        int cnt = getCount(addr);

        sb.a("PagesListMeta [\n\tnextMetaPageId=").appendHex(getNextMetaPageId(addr))
            .a(",\n\tcount=").a(cnt)
            .a(",\n\tbucketData={");

        Map<Integer, GridLongList> bucketsData = new HashMap<>(cnt);

        getBucketsData(addr, bucketsData);

        for (Map.Entry<Integer, GridLongList> e : bucketsData.entrySet())
            sb.a("\n\t\tbucket=").a(e.getKey()).a(", list=").a(e.getValue());

        sb.a("\n\t}\n]");
    }

    /** {@inheritDoc} */
    @Override public int getFreeSpace(int pageSize, long pageAddr) {
        return (getCapacity(pageSize, pageAddr) - getCount(pageAddr)) * ITEM_SIZE;
    }
}

        int cnt = getCount(pageAddr);

        assert cnt >= 0 && cnt <= Short.MAX_VALUE : cnt;

        if (cnt == 0)
            return;

        int off = offset(0);

        for (int i = 0; i < cnt; i++) {
            int bucket = (int)PageUtils.getShort(pageAddr, off);
            assert bucket >= 0 && bucket <= Short.MAX_VALUE : bucket;

            long tailId = PageUtils.getLong(pageAddr, off + 2);
            assert tailId != 0;

            GridLongList list = res.get(bucket);

            if (list == null)
                res.put(bucket, list = new GridLongList());

            list.add(tailId);

            off += ITEM_SIZE;
        }
    
<methods>public static org.apache.ignite.internal.metric.IndexPageType deriveIndexPageType(long) ,public static Q getBPlusIO(long) throws org.apache.ignite.IgniteCheckedException,public static Q getBPlusIO(int, int) throws org.apache.ignite.IgniteCheckedException,public static short getCompactedSize(java.nio.ByteBuffer) ,public static short getCompactedSize(long) ,public static short getCompressedSize(java.nio.ByteBuffer) ,public static short getCompressedSize(long) ,public static byte getCompressionType(java.nio.ByteBuffer) ,public static byte getCompressionType(long) ,public static int getCrc(long) ,public static int getCrc(java.nio.ByteBuffer) ,public abstract int getFreeSpace(int, long) ,public static IOVersions<? extends BPlusInnerIO<?>> getInnerVersions(int) ,public static IOVersions<? extends BPlusLeafIO<?>> getLeafVersions(int) ,public static Q getPageIO(long) throws org.apache.ignite.IgniteCheckedException,public static Q getPageIO(java.nio.ByteBuffer) throws org.apache.ignite.IgniteCheckedException,public static Q getPageIO(int, int) throws org.apache.ignite.IgniteCheckedException,public static long getPageId(java.nio.ByteBuffer) ,public static long getPageId(long) ,public static int getRotatedIdPart(long) ,public static int getType(java.nio.ByteBuffer) ,public static int getType(long) ,public final int getType() ,public static int getVersion(java.nio.ByteBuffer) ,public static int getVersion(long) ,public final int getVersion() ,public void initNewPage(long, long, int, org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMetrics) ,public static boolean isDataPageType(int) ,public static boolean isIndexPage(int) ,public static java.lang.String printPage(long, int) ,public static void registerH2(IOVersions<? extends BPlusInnerIO<?>>, IOVersions<? extends BPlusLeafIO<?>>) ,public static void registerH2ExtraInner(IOVersions<? extends BPlusInnerIO<?>>) ,public static void registerH2ExtraLeaf(IOVersions<? extends BPlusLeafIO<?>>) ,public static void registerTest(BPlusInnerIO<?>, BPlusLeafIO<?>) ,public static void registerTest(org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO) ,public static void setCompactedSize(java.nio.ByteBuffer, short) ,public static void setCompressedSize(java.nio.ByteBuffer, short) ,public static void setCompressionType(java.nio.ByteBuffer, byte) ,public static void setCrc(long, int) ,public static void setCrc(java.nio.ByteBuffer, int) ,public static void setPageId(long, long) ,public static void setRotatedIdPart(long, int) ,public static void setType(long, int) ,public java.lang.String toString() <variables>public static final int COMMON_HEADER_END,private static final int COMPACTED_SIZE_OFF,private static final int COMPRESSED_SIZE_OFF,private static final int COMPRESSION_TYPE_OFF,public static final int CRC_OFF,public static final short MAX_PAYLOAD_SIZE,public static final int PAGE_ID_OFF,private static final int RESERVED_2_OFF,private static final int RESERVED_3_OFF,private static final int RESERVED_SHORT_OFF,public static final int ROTATED_ID_PART_OFF,public static final int TYPE_OFF,public static final short T_BPLUS_META,public static final short T_CACHE_ID_AWARE_DATA_REF_INNER,public static final short T_CACHE_ID_AWARE_DATA_REF_LEAF,public static final short T_CACHE_ID_AWARE_PENDING_REF_INNER,public static final short T_CACHE_ID_AWARE_PENDING_REF_LEAF,public static final short T_DATA,public static final short T_DATA_METASTORAGE,public static final short T_DATA_PART,public static final short T_DATA_REF_INNER,public static final short T_DATA_REF_LEAF,public static final short T_DATA_REF_METASTORAGE_INNER,public static final short T_DATA_REF_METASTORAGE_LEAF,public static final short T_DEFRAG_LINK_MAPPING_INNER,public static final short T_DEFRAG_LINK_MAPPING_LEAF,public static final short T_H2_EX_REF_INNER_END,public static final short T_H2_EX_REF_INNER_START,public static final short T_H2_EX_REF_LEAF_END,public static final short T_H2_EX_REF_LEAF_START,public static final short T_H2_REF_INNER,public static final short T_H2_REF_LEAF,public static final short T_MARKER_PAGE,public static final short T_META,public static final short T_METASTORE_INNER,public static final short T_METASTORE_LEAF,public static final short T_PAGE_LIST_META,public static final short T_PAGE_LIST_NODE,public static final short T_PAGE_UPDATE_TRACKING,public static final short T_PART_CNTRS,public static final short T_PART_META,public static final short T_PENDING_REF_INNER,public static final short T_PENDING_REF_LEAF,public static final int VER_OFF,private static final List<IOVersions<? extends BPlusInnerIO<?>>> h2ExtraInnerIOs,private static final List<IOVersions<? extends BPlusLeafIO<?>>> h2ExtraLeafIOs,private static IOVersions<? extends BPlusInnerIO<?>> h2InnerIOs,private static IOVersions<? extends BPlusLeafIO<?>> h2LeafIOs,private static BPlusInnerIO<?> innerTestIO,private static BPlusLeafIO<?> leafTestIO,private static org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO testIO,private final non-sealed int type,private final non-sealed int ver