class ReplicatedMapSegmentIteration<K, V, R> extends MapSegmentIteration<K, V, R>
        implements ReplicatedIterationContext<K, V, R>, ReplicableEntry,
        ReplicatedHashSegmentContext<K, MapEntry<K, V>> {

    @StageRef
    VanillaChronicleMapHolder<K, V, R> mh;
    @StageRef
    ReplicatedMapEntryStages<K, V> e;
    @StageRef
    ReplicationUpdate<K> ru;
    @StageRef
    DummyValueZeroData<V> dummyValue;
    @StageRef
    ReplicatedMapAbsentDelegatingForIteration<K, V> absentEntryDelegating;
    @StageRef
    ReplicatedMapEntryDelegating<K, V> entryDelegating;
    EntriesToTest entriesToTest = null;

    void initEntriesToTest(EntriesToTest entriesToTest) {
        this.entriesToTest = entriesToTest;
    }

    @Override
    public boolean shouldTestEntry() {
        throwExceptionIfClosed();

        return entriesToTest == ALL || !e.entryDeleted();
    }

    @Override
    public Object entryForIteration() {
        throwExceptionIfClosed();

        return !e.entryDeleted() ? entryDelegating : absentEntryDelegating;
    }

    @Override
    public long tierEntriesForIteration() {
        throwExceptionIfClosed();

        return entriesToTest == ALL ? s.tierEntries() : s.tierEntries() - s.tierDeleted();
    }

    @Override
    public void doReplaceValue(Data<V> newValue) {
        throwExceptionIfClosed();

        checkOnEachPublicOperation.checkOnEachPublicOperation();
        try {
            entry.innerDefaultReplaceValue(newValue);
            e.updatedReplicationStateOnPresentEntry();
            ru.updateChange();
        } finally {
            s.innerWriteLock.unlock();
        }
    }

    @Override
    public boolean forEachSegmentEntryWhile(Predicate<? super MapEntry<K, V>> predicate) {
        throwExceptionIfClosed();

        checkOnEachPublicOperation.checkOnEachPublicOperation();
        initEntriesToTest(PRESENT);
        s.innerUpdateLock.lock();
        return innerForEachSegmentEntryWhile(predicate);
    }

    @Override
    public boolean forEachSegmentReplicableEntryWhile(
            Predicate<? super ReplicableEntry> predicate) {
        throwExceptionIfClosed();

        checkOnEachPublicOperation.checkOnEachPublicOperation();
        initEntriesToTest(ALL);
        s.innerUpdateLock.lock();
        return innerForEachSegmentEntryWhile(predicate);
    }

    @Override
    public void forEachSegmentReplicableEntry(Consumer<? super ReplicableEntry> action) {
        throwExceptionIfClosed();

        forEachSegmentReplicableEntryWhile(e -> {
            action.accept(e);
            return true;
        });
    }

    @Override
    public void doRemove() {
        throwExceptionIfClosed();

        checkOnEachPublicOperation.checkOnEachPublicOperation();
        try {
            if (e.valueSize > dummyValue.size())
                e.innerDefaultReplaceValue(dummyValue);
            e.updatedReplicationStateOnPresentEntry();
            e.writeEntryDeleted();
            ru.updateChange();
            s.tierDeleted(s.tierDeleted() + 1);
        } finally {
            s.innerWriteLock.unlock();
        }
        initEntryRemovedOnThisIteration(true);
    }

    @Override
    public void doRemoveCompletely() {
        throwExceptionIfClosed();

        boolean wasDeleted = e.entryDeleted();
        super.doRemove();
        ru.dropChange();
        if (wasDeleted)
            s.tierDeleted(s.tierDeleted() - 1);
    }

    public void doInsert(Data<V> value) {
        throwExceptionIfClosed();

        checkOnEachPublicOperation.checkOnEachPublicOperation();
        if (e.entryDeleted()) {
            try {
                s.tierDeleted(s.tierDeleted() - 1);
                e.innerDefaultReplaceValue(value);
                s.incrementModCount();
                e.writeEntryPresent();
                e.updatedReplicationStateOnPresentEntry();
                ru.updateChange();
            } finally {
                s.innerWriteLock.unlock();
            }
        } else {
            throw new IllegalStateException(mh.h().toIdentityString() +
                    ": Entry is present in the map when doInsert() is called");
        }
    }

    public void doInsert() {<FILL_FUNCTION_BODY>}

    enum EntriesToTest {PRESENT, ALL}
}

        throwExceptionIfClosed();

        if (mh.set() == null)
            throw new IllegalStateException(mh.h().toIdentityString() +
                    ": Called SetAbsentEntry.doInsert() from Map context");
        doInsert((Data<V>) DummyValueData.INSTANCE);
    
<methods>public non-sealed void <init>() ,public WrappedValueInstanceDataHolderAccess<K,V,?> context() ,public void doReplaceValue(Data<V>) ,public void hookAfterEachIteration() <variables>MapEntryStages<K,V> entry,WrappedValueInstanceDataHolder<V> wrappedValueInstanceDataHolder,WrappedValueInstanceDataHolderAccess<K,V,?> wrappedValueInstanceDataHolderAccess