*            A set of Volumes for which IV records have already been
     *            written. This method adds a volume to this set whenever it
     *            writes an IV record.
     * @throws Exception
     */
    void dump(final ByteBuffer bb, final boolean secure, boolean verbose, final Set<Volume> identifiedVolumes)
            throws Exception {
        byte[] bytes = new byte[_bufferSize];
        int type;
        int keyBlockEnd;
        int alloc;
        int slack;
        long page;
        Volume volume;
        long rightSibling;
        long timestamp;
        int bufferSize;
        /*
         * Copy all the information needed quickly and then release the buffer.
         */
        boolean claimed = claim(false, Persistit.SHORT_DELAY);
        try {
            bufferSize = _bufferSize;
            type = _type;
            keyBlockEnd = _keyBlockEnd;
            alloc = _alloc;
            slack = _slack;
            page = _page;
            volume = _vol;
            rightSibling = _rightSibling;
            timestamp = _timestamp;
            System.arraycopy(_bytes, 0, bytes, 0, bufferSize);
        } finally {
            if (claimed) {
                release();
            }
        }

        String toString = toString();
        if (verbose) {
            System.out.println(toString);
        }

        int volumeHandle = volume == null ? 0 : volume.getHandle();
        if (volume != null && !identifiedVolumes.contains(volume)) {
            IV.putType(bb);
            IV.putHandle(bb, volumeHandle);
            IV.putVolumeId(bb, volume.getId());
            IV.putTimestamp(bb, 0);
            IV.putVolumeName(bb, volume.getName());
            bb.position(bb.position() + IV.getLength(bb));
            identifiedVolumes.add(volume);
        }

        boolean isDataPage = type == PAGE_TYPE_DATA;
        boolean isIndexPage = type >= PAGE_TYPE_INDEX_MIN && type <= PAGE_TYPE_INDEX_MAX;
        boolean isLongRecordPage = type == PAGE_TYPE_LONG_RECORD;

        /*
         * Following is equivalent to the save method, except written to the
         * byte array copy.
         */
        Util.putLong(bytes, TIMESTAMP_OFFSET, timestamp);
        if (page != 0) {
            Util.putByte(bytes, TYPE_OFFSET, type);
            Util.putByte(bytes, BUFFER_LENGTH_OFFSET, bufferSize / 256);
            Util.putChar(bytes, KEY_BLOCK_END_OFFSET, keyBlockEnd);
            Util.putChar(bytes, FREE_OFFSET, alloc);
            Util.putChar(bytes, SLACK_OFFSET, slack);
            Util.putLong(bytes, PAGE_ADDRESS_OFFSET, page);
            Util.putLong(bytes, RIGHT_SIBLING_OFFSET, rightSibling);
        }

        if (isDataPage && secure) {
            dumpSecureOverwriteValues(bytes);
        }

        int left = bufferSize;
        int right = 0;
        if (isDataPage || isIndexPage) {
            if (KEY_BLOCK_START <= keyBlockEnd && keyBlockEnd <= alloc && alloc < left) {
                right = left - alloc;
                left = keyBlockEnd;
            }
        } else if (secure && isLongRecordPage) {
            left = KEY_BLOCK_START;
        }
        int recordSize = PA.OVERHEAD + left + right;
        PA.putLength(bb, recordSize);
        PA.putType(bb);
        PA.putVolumeHandle(bb, volumeHandle);
        PA.putTimestamp(bb, timestamp);
        PA.putLeftSize(bb, left);
        PA.putBufferSize(bb, bufferSize);
        PA.putPageAddress(bb, page);
        bb.position(bb.position() + PA.OVERHEAD);
        bb.put(bytes, 0, left);
        bb.put(bytes, bufferSize - right, right);
    }