* @param spareKey
     * @return
     * @throws PersistitException
     */
    boolean pruneMvvValues(final Tree tree, boolean pruneLongMVVs) throws PersistitException {

        boolean changed = false;
        try {
            boolean hasLongMvvRecords = false;

            if (!isMine()) {
                throw new IllegalStateException("Exclusive claim required " + this);
            }
            if (isDataPage() && _mvvCount != 0) {
                final long timestamp = _persistit.getTimestampAllocator().updateTimestamp();
                _mvvCount = 0;
                writePageOnCheckpoint(timestamp);
                List<PrunedVersion> prunedVersions = new ArrayList<PrunedVersion>();
                for (int p = KEY_BLOCK_START; p < _keyBlockEnd; p += KEYBLOCK_LENGTH) {
                    final int kbData = getInt(p);
                    final int tail = decodeKeyBlockTail(kbData);
                    final int tbData = getInt(tail);
                    final int klength = decodeTailBlockKLength(tbData);
                    final int oldTailSize = decodeTailBlockSize(tbData);
                    final int offset = tail + _tailHeaderSize + klength;
                    final int oldSize = oldTailSize - klength - _tailHeaderSize;

                    if (oldSize > 0) {
                        int valueByte = _bytes[offset] & 0xFF;
                        if (isLongMVV(_bytes, offset, oldSize)) {
                            /*
                             * Can't prune in this pass because of long record
                             * timestamp management. Simply remember that there
                             * are long records to prune, then prune them in a
                             * copy of the buffer.
                             */
                            hasLongMvvRecords = true;
                        }
                        if (valueByte == MVV.TYPE_MVV) {
                            final int newSize = MVV.prune(_bytes, offset, oldSize, _persistit.getTransactionIndex(),
                                    true, prunedVersions);
                            if (newSize != oldSize) {
                                changed = true;
                                int newTailSize = klength + newSize + _tailHeaderSize;
                                int oldNext = (tail + oldTailSize + ~TAILBLOCK_MASK) & TAILBLOCK_MASK;
                                int newNext = (tail + newTailSize + ~TAILBLOCK_MASK) & TAILBLOCK_MASK;
                                if (newNext < oldNext) {
                                    // Free the remainder of the old tail block
                                    deallocTail(newNext, oldNext - newNext);
                                } else {
                                    Debug.$assert0.t(newNext == oldNext);
                                }
                                // Rewrite the tail block header
                                putInt(tail, encodeTailBlock(newTailSize, klength));
                                if (Debug.ENABLED) {
                                    MVV.verify(_bytes, offset, newSize);
                                }
                            }
                            valueByte = newSize > 0 ? _bytes[offset] & 0xFF : -1;
                            incCountIfMvv(_bytes, offset, newSize);
                        }

                        if (pruneAntiValue(valueByte, p, tree)) {
                            changed = true;
                            p -= KEYBLOCK_LENGTH;
                        }
                    }
                }
                if (changed) {
                    setDirtyAtTimestamp(timestamp);
                }

                deallocatePrunedVersions(_persistit, _vol, prunedVersions);
                prunedVersions.clear();

                if (pruneLongMVVs && hasLongMvvRecords) {
                    List<PersistitException> deferredExceptions = new ArrayList<PersistitException>();
                    List<Long> oldChainsToDeallocate = new ArrayList<Long>();

                    Buffer copy = new Buffer(this);
                    boolean copyChanged = copy.pruneLongMvvValues(tree, prunedVersions, deferredExceptions,
                            oldChainsToDeallocate);
                    if (copyChanged) {
                        changed = true;
                        final long copyTimestamp = _persistit.getTimestampAllocator().updateTimestamp();
                        writePageOnCheckpoint(copyTimestamp);
                        System.arraycopy(copy._bytes, 0, _bytes, 0, _bufferSize);
                        _alloc = copy._alloc;
                        _slack = copy._slack;
                        _mvvCount = copy._mvvCount;
                        if (_keyBlockEnd != copy._keyBlockEnd) {
                            _keyBlockEnd = copy._keyBlockEnd;
                            invalidateFastIndex();
                        }
                        setDirtyAtTimestamp(copyTimestamp);
                        deallocatePrunedVersions(_persistit, _vol, prunedVersions);
                        for (final Long oldLongRecordChain : oldChainsToDeallocate) {
                            _vol.getStructure().deallocateGarbageChain(oldLongRecordChain, 0);
                        }
                    }
                    if (!deferredExceptions.isEmpty()) {
                        _mvvCount++;
                        throw deferredExceptions.get(0);
                    }
                }
            }

        } finally {
            if (Debug.ENABLED && changed) {
                assertVerify();
            }
        }

        return changed;
    }