/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ignite.internal.processors.cache;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.marshaller.Marshaller;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Ignore;
import org.junit.Test;

import static org.apache.ignite.cache.CacheMode.REPLICATED;

/**
 * Test cases for multi-threaded tests.
 */
// Tests that are not ready to be used with BinaryMarshaller.
@Ignore("https://issues.apache.org/jira/browse/IGNITE-9214")
public class GridCacheMvccSelfTest extends GridCommonAbstractTest {
    /** Grid. */
    private IgniteKernal grid;

    /**
     *
     */
    public GridCacheMvccSelfTest() {
        super(true /*start grid. */);
    }

    /** {@inheritDoc} */
    @Override protected void beforeTest() throws Exception {
        grid = (IgniteKernal)grid();
    }

    /** {@inheritDoc} */
    @Override protected void afterTest() throws Exception {
        grid = null;
    }

    /** {@inheritDoc} */
    @Override protected IgniteConfiguration getConfiguration() throws Exception {
        IgniteConfiguration cfg = super.getConfiguration();

        CacheConfiguration cacheCfg = defaultCacheConfiguration();

        cacheCfg.setCacheMode(REPLICATED);

        cfg.setCacheConfiguration(cacheCfg);

        return cfg;
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testMarshalUnmarshalCandidate() throws Exception {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx parent = new GridCacheTestEntryEx(cache.context(), "1");

        GridCacheMvccCandidate cand = new GridCacheMvccCandidate(
            parent,
            UUID.randomUUID(),
            UUID.randomUUID(),
            version(1),
            123,
            version(2),
            /*local*/false,
            /*reentry*/false,
            true,
            false,
            false,
            false,
            null,
            false
        );

        Marshaller marshaller = getTestResources().getMarshaller();

        GridCacheMvccCandidate unmarshalled = marshaller.unmarshal(marshaller.marshal(cand), null);

        info(unmarshalled.toString());
    }

    /**
     * Tests remote candidates.
     */
    @Test
    public void testRemotes() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);

        entry.addRemote(node1, 1, ver1, true);

        Collection<GridCacheMvccCandidate> cands = entry.remoteMvccSnapshot();

        assert cands.size() == 1;
        assert cands.iterator().next().version().equals(ver1);

        entry.addRemote(node2, 5, ver5, true);

        cands = entry.remoteMvccSnapshot();

        assert cands.size() == 2;

        info(cands);

        // Check order.
        checkOrder(cands, ver1, ver5);

        entry.addRemote(node1, 3, ver3, true);

        cands = entry.remoteMvccSnapshot();

        info(cands);

        assert cands.size() == 3;

        // No reordering happens.
        checkOrder(cands, ver1, ver5, ver3);

        entry.doneRemote(ver3);

        checkDone(entry.candidate(ver3));

        entry.addRemote(node1, 2, ver2, true);

        cands = entry.remoteMvccSnapshot();

        info(cands);

        assert cands.size() == 4;

        // Check order.
        checkOrder(cands, ver1, ver5, ver3, ver2);

        entry.orderCompleted(
            new GridCacheVersion(1, 2, 0, 0),
            Arrays.asList(new GridCacheVersion(1, 3, 4, 0), ver2, new GridCacheVersion(1, 5, 6, 0)),
            Collections.<GridCacheVersion>emptyList()
        );

        cands = entry.remoteMvccSnapshot();

        info(cands);

        assert cands.size() == 4;

        // Done ver 2.
        checkOrder(cands, ver1, ver2, ver5, ver3);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, true, false);
        checkRemote(entry.candidate(ver3), ver3, true, true);
        checkRemote(entry.candidate(ver5), ver5, false, false);

        entry.doneRemote(ver5);

        checkDone(entry.candidate(ver5));

        entry.addRemote(node1, 4, ver4, true);

        cands = entry.remoteMvccSnapshot();

        info(cands);

        assert cands.size() == 5;

        // Check order.
        checkOrder(cands, ver1, ver2, ver5, ver3, ver4);

        entry.orderCompleted(ver3, Arrays.asList(ver2, ver5), Collections.<GridCacheVersion>emptyList());

        cands = entry.remoteMvccSnapshot();

        info(cands);

        assert cands.size() == 5;

        checkOrder(cands, ver1, ver2, ver5, ver3, ver4);

        assert entry.anyOwner() == null;

        entry.doneRemote(ver1);

        checkRemoteOwner(entry.anyOwner(), ver1);

        entry.removeLock(ver1);

        assert entry.remoteMvccSnapshot().size() == 4;

        assert entry.anyOwner() == null;

        entry.doneRemote(ver2);

        checkRemoteOwner(entry.anyOwner(), ver2);

        entry.removeLock(ver2);

        assert entry.remoteMvccSnapshot().size() == 3;

        checkRemoteOwner(entry.anyOwner(), ver5);

        entry.removeLock(ver3);

        assert entry.remoteMvccSnapshot().size() == 2;

        checkRemoteOwner(entry.anyOwner(), ver5);

        entry.removeLock(ver5);

        assert entry.remoteMvccSnapshot().size() == 1;

        assert entry.anyOwner() == null;

        entry.doneRemote(ver4);

        checkRemoteOwner(entry.anyOwner(), ver4);

        entry.removeLock(ver4);

        assert entry.remoteMvccSnapshot().isEmpty();

        assert entry.anyOwner() == null;
    }

    /**
     * Tests that orderOwned does not reorder owned locks.
     */
    @Test
    public void testNearRemoteWithOwned() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);

        GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, true);
        GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, true);
        GridCacheMvccCandidate c3 = entry.addRemote(node1, 1, ver3, true);
        GridCacheMvccCandidate c4 = entry.addRemote(node1, 1, ver4, true);

        GridCacheMvccCandidate[] candArr = new GridCacheMvccCandidate[] {c1, c2, c3, c4};

        Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();

        assert rmtCands.size() == 4;
        assert rmtCands.iterator().next().version().equals(ver1);

        entry.orderOwned(ver1, ver2);

        rmtCands = entry.remoteMvccSnapshot();

        int i = 0;

        for (GridCacheMvccCandidate cand : rmtCands) {
            assertTrue(cand == candArr[i]);

            assertTrue(ver2.equals(cand.ownerVersion()) || cand != c1);

            i++;
        }
    }

    /**
     * Tests that orderOwned does not reorder owned locks.
     */
    @Test
    public void testNearRemoteWithOwned1() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);

        GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, true);
        GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, true);
        GridCacheMvccCandidate c3 = entry.addRemote(node1, 1, ver3, true);
        GridCacheMvccCandidate c4 = entry.addRemote(node1, 1, ver4, true);
        GridCacheMvccCandidate c5 = entry.addRemote(node1, 1, ver5, true);
        GridCacheMvccCandidate c6 = entry.addRemote(node1, 1, ver6, true);

        GridCacheMvccCandidate[] candArr = new GridCacheMvccCandidate[] {c1, c2, c3, c4, c5, c6};

        Collection<GridCacheMvccCandidate> cands = entry.remoteMvccSnapshot();

        assert cands.size() == 6;
        assert cands.iterator().next().version().equals(ver1);

        entry.orderOwned(ver1, ver3);

        cands = entry.remoteMvccSnapshot();

        int i = 0;

        for (GridCacheMvccCandidate cand : cands) {
            assert cand == candArr[i];

            assertTrue(ver3.equals(cand.ownerVersion()) || cand != c1);

            i++;
        }
    }

    /**
     * Tests that orderOwned does not reorder owned locks.
     */
    @Test
    public void testNearRemoteWithOwned2() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();

        GridCacheVersion ver0 = version(0);
        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);

        GridCacheMvccCandidate c0 = entry.addRemote(node1, 1, ver0, true);
        GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, true);
        GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, true);
        GridCacheMvccCandidate c3 = entry.addRemote(node1, 1, ver3, true);
        GridCacheMvccCandidate c4 = entry.addRemote(node1, 1, ver4, true);
        GridCacheMvccCandidate c5 = entry.addRemote(node1, 1, ver5, true);
        GridCacheMvccCandidate c6 = entry.addRemote(node1, 1, ver6, true);

        GridCacheMvccCandidate[] candArr = new GridCacheMvccCandidate[] {c0, c1, c2, c3, c4, c5, c6};

        Collection<GridCacheMvccCandidate> cands = entry.remoteMvccSnapshot();

        assert cands.size() == 7;
        assert cands.iterator().next().version().equals(ver0);

        entry.orderOwned(ver1, ver2);

        cands = entry.remoteMvccSnapshot();

        int i = 0;

        for (GridCacheMvccCandidate cand : cands) {
            assert cand == candArr[i];

            assertTrue(ver2.equals(cand.ownerVersion()) || cand != c1);

            i++;
        }
    }

    /**
     * Tests remote candidates.
     */
    @Test
    public void testLocal() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);

        entry.addLocal(3, ver3, 0, true, true);

        Collection<GridCacheMvccCandidate> cands = entry.localCandidates();

        assert cands.size() == 1;

        assert cands.iterator().next().version().equals(ver3);

        entry.addLocal(5, ver5, 0, true, true);

        cands = entry.localCandidates();

        assert cands.size() == 2;

        info(cands);

        // Check order.
        checkOrder(cands, ver3, ver5);

        assert entry.anyOwner() == null;

        entry.readyLocal(ver3);

        checkLocalOwner(entry.anyOwner(), ver3, false);

        // Reentry.
        entry.addLocal(3, ver4, 0, true, true);

        checkLocalOwner(entry.anyOwner(), ver4, true);

        assert entry.localCandidates().size() == 2;
        assert entry.localCandidates(true).size() == 3;

        // Check order.
        checkOrder(entry.localCandidates(true), ver4, ver3, ver5);

        entry.removeLock(ver4);

        assert entry.localCandidates(true).size() == 2;

        entry.readyLocal(ver5);

        checkLocalOwner(entry.anyOwner(), ver3, false);

        // Check order.
        checkOrder(entry.localCandidates(true), ver3, ver5);

        entry.removeLock(ver3);

        assert entry.localCandidates(true).size() == 1;

        checkLocalOwner(entry.anyOwner(), ver5, false);

        assert !entry.lockedByAny(ver5);

        entry.removeLock(ver5);

        assert !entry.lockedByAny();
        assert entry.anyOwner() == null;
        assert entry.localCandidates(true).isEmpty();
    }

    /**
     * Tests assignment of local candidates when remote exist.
     */
    @Test
    public void testLocalWithRemote() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID nodeId = UUID.randomUUID();

        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);

        entry.addRemote(nodeId, 1, ver2, true);

        entry.addLocal(3, ver3, 0, false, true);

        assert entry.anyOwner() == null;

        entry.readyLocal(ver3);

        assert entry.anyOwner() == null;

        entry.removeLock(ver2);

        assert entry.localCandidates().size() == 1;

        checkLocalOwner(entry.anyOwner(), ver3, false);

        entry.removeLock(ver3);

        assert !entry.lockedByAny();
        assert entry.anyOwner() == null;
        assert entry.localCandidates(true).isEmpty();
    }

    /**
     *
     */
    @Test
    public void testCompletedWithBaseInTheMiddle() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);
        GridCacheVersion ver8 = version(8);

        entry.addRemote(node1, 1, ver1, true);
        entry.addRemote(node2, 2, ver2, true);
        entry.addRemote(node1, 3, ver3, true);
        entry.addRemote(node2, 4, ver4, true);
        entry.addRemote(node1, 5, ver5, true);
        entry.addRemote(node2, 7, ver7, true);
        entry.addRemote(node2, 8, ver8, true);

        GridCacheMvccCandidate doomed = entry.addRemote(node2, 6, ver6, true);

        // No reordering happens.
        checkOrder(entry.remoteMvccSnapshot(), ver1, ver2, ver3, ver4, ver5, ver7, ver8, ver6);

        List<GridCacheVersion> committed = Arrays.asList(ver4, ver7);
        List<GridCacheVersion> rolledback = Arrays.asList(ver6);

        entry.orderCompleted(ver2, committed, rolledback);

        assert !entry.lockedBy(ver6);

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver4, ver7, ver2, ver3, ver5, ver8);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, false, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, true, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
        checkRemote(entry.candidate(ver7), ver7, true, false);
        checkRemote(entry.candidate(ver8), ver8, false, false);

        checkRemote(doomed, ver6, false, true);
    }

    /**
     *
     */
    @Test
    public void testCompletedWithCompletedBaseInTheMiddle() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        entry.addRemote(node1, 1, ver1, true);
        entry.addRemote(node2, 2, ver2, true);
        entry.addRemote(node1, 3, ver3, true);
        entry.addRemote(node2, 4, ver4, true);
        entry.addRemote(node1, 5, ver5, true);
        entry.addRemote(node2, 6, ver6, true);
        entry.addRemote(node2, 7, ver7, true);

        List<GridCacheVersion> committed = Arrays.asList(ver4, ver6, ver2);

        entry.orderCompleted(ver2, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver4, ver6, ver2, ver3, ver5, ver7);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, true, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, true, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
        checkRemote(entry.candidate(ver6), ver6, true, false);
        checkRemote(entry.candidate(ver7), ver7, false, false);
    }

    /**
     *
     */
    @Test
    public void testCompletedTwiceWithBaseInTheMiddle() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        entry.addRemote(node1, 1, ver1, true);
        entry.addRemote(node2, 2, ver2, true);
        entry.addRemote(node1, 3, ver3, true);
        entry.addRemote(node2, 4, ver4, true);
        entry.addRemote(node1, 5, ver5, true);
        entry.addRemote(node2, 6, ver6, true);
        entry.addRemote(node2, 7, ver7, true);

        List<GridCacheVersion> completed = Arrays.asList(ver4, ver6);

        entry.orderCompleted(ver2, completed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver4, ver6, ver2, ver3, ver5, ver7);

        entry.orderCompleted(ver4, completed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver6, ver4, ver2, ver3, ver5, ver7);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, false, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, true, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
        checkRemote(entry.candidate(ver6), ver6, true, false);
        checkRemote(entry.candidate(ver7), ver7, false, false);
    }

    /**
     *
     */
    @Test
    public void testCompletedWithBaseInTheMiddleNoChange() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        entry.addRemote(node1, 1, ver1, false);
        entry.addRemote(node2, 2, ver2, false);
        entry.addRemote(node1, 3, ver3, false);
        entry.addRemote(node2, 4, ver4, false);
        entry.addRemote(node1, 5, ver5, false);

        List<GridCacheVersion> committed = Arrays.asList(ver6, ver7);

        entry.orderCompleted(ver4, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver2, ver3, ver4, ver5);

        // Nothing set to owner since there is no change.
        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, false, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, false, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
    }

    /**
     *
     */
    @Test
    public void testCompletedWithBaseInTheBeginning() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        entry.addRemote(node1, 1, ver1, false);
        entry.addRemote(node2, 2, ver2, false);
        entry.addRemote(node1, 3, ver3, false);
        entry.addRemote(node2, 4, ver4, false);
        entry.addRemote(node1, 5, ver5, false);
        entry.addRemote(node2, 6, ver6, false);
        entry.addRemote(node2, 7, ver7, false);

        List<GridCacheVersion> committed = Arrays.asList(ver4, ver6, ver3);

        entry.orderCompleted(ver1, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver3, ver4, ver6, ver1, ver2, ver5, ver7);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, false, false);
        checkRemote(entry.candidate(ver3), ver3, true, false);
        checkRemote(entry.candidate(ver4), ver4, true, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
        checkRemote(entry.candidate(ver6), ver6, true, false);
        checkRemote(entry.candidate(ver7), ver7, false, false);
    }

    /**
     * This case should never happen, nevertheless we need to test for it.
     */
    @Test
    public void testCompletedWithBaseInTheBeginningNoChange() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        entry.addRemote(node1, 1, ver1, false);
        entry.addRemote(node2, 2, ver2, false);
        entry.addRemote(node1, 3, ver3, false);
        entry.addRemote(node2, 4, ver4, false);
        entry.addRemote(node1, 5, ver5, false);

        List<GridCacheVersion> committed = Arrays.asList(ver6, ver7);

        entry.orderCompleted(ver1, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver2, ver3, ver4, ver5);

        // Nothing set to owner since there is no change.
        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, false, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, false, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
    }

    /**
     * This case should never happen, nevertheless we need to test for it.
     */
    @Test
    public void testCompletedWithBaseInTheEndNoChange() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        entry.addRemote(node1, 1, ver1, false);
        entry.addRemote(node2, 2, ver2, false);
        entry.addRemote(node1, 3, ver3, false);
        entry.addRemote(node2, 4, ver4, false);
        entry.addRemote(node1, 5, ver5, false);

        List<GridCacheVersion> committed = Arrays.asList(ver6, ver7);

        entry.orderCompleted(ver5, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver2, ver3, ver4, ver5);

        // Nothing set to owner since there is no change.
        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, false, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, false, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
    }

    /**
     *
     */
    @Test
    public void testCompletedWithBaseNotPresentInTheMiddle() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        // Don't add version 2.
        entry.addRemote(node1, 1, ver1, true);
        entry.addRemote(node1, 3, ver3, true);
        entry.addRemote(node2, 4, ver4, true);
        entry.addRemote(node1, 5, ver5, true);
        entry.addRemote(node2, 6, ver6, true);
        entry.addRemote(node2, 7, ver7, true);

        List<GridCacheVersion> committed = Arrays.asList(ver6, ver4);

        entry.orderCompleted(ver2, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver4, ver6, ver3, ver5, ver7);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, true, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
        checkRemote(entry.candidate(ver6), ver6, true, false);
        checkRemote(entry.candidate(ver7), ver7, false, false);
    }

    /**
     *
     */
    @Test
    public void testCompletedWithBaseNotPresentInTheMiddleNoChange() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        // Don't add versions 2, 5, 6, 7.
        entry.addRemote(node1, 1, ver1, true);
        entry.addRemote(node1, 3, ver3, true);
        entry.addRemote(node2, 4, ver4, true);

        List<GridCacheVersion> committed = Arrays.asList(ver6, ver5, ver7);

        entry.orderCompleted(ver2, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver3, ver4);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, false, false);
    }

    /**
     *
     */
    @Test
    public void testCompletedWithBaseNotPresentInTheBeginning() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        // Don't add version 1.
        entry.addRemote(node1, 2, ver2, true);
        entry.addRemote(node1, 3, ver3, true);
        entry.addRemote(node2, 4, ver4, true);
        entry.addRemote(node1, 5, ver5, true);
        entry.addRemote(node2, 6, ver6, true);
        entry.addRemote(node2, 7, ver7, true);

        List<GridCacheVersion> committed = Arrays.asList(ver4, ver6, ver3);

        entry.orderCompleted(ver1, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver3, ver4, ver6, ver2, ver5, ver7);

        checkRemote(entry.candidate(ver2), ver2, false, false);
        checkRemote(entry.candidate(ver3), ver3, true, false);
        checkRemote(entry.candidate(ver4), ver4, true, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
        checkRemote(entry.candidate(ver6), ver6, true, false);
        checkRemote(entry.candidate(ver7), ver7, false, false);
    }

    /**
     *
     */
    @Test
    public void testCompletedWithBaseNotPresentInTheBeginningNoChange() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        // Don't add version 6, 7
        entry.addRemote(node1, 2, ver2, true);
        entry.addRemote(node1, 3, ver3, true);
        entry.addRemote(node2, 4, ver4, true);
        entry.addRemote(node1, 5, ver5, true);
        entry.addRemote(node1, 6, ver6, true);
        entry.addRemote(node1, 7, ver7, true);

        List<GridCacheVersion> committed = Arrays.asList(ver2, ver3);

        entry.orderCompleted(ver1, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver2, ver3, ver4, ver5, ver6, ver7);

        checkRemote(entry.candidate(ver2), ver2, true, false);
        checkRemote(entry.candidate(ver3), ver3, true, false);
        checkRemote(entry.candidate(ver4), ver4, false, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);
        checkRemote(entry.candidate(ver6), ver6, false, false);
        checkRemote(entry.candidate(ver7), ver7, false, false);
    }

    /**
     *
     */
    @Test
    public void testCompletedWithBaseNotPresentInTheEndNoChange() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);
        GridCacheVersion ver6 = version(6);
        GridCacheVersion ver7 = version(7);

        // Don't add version 5, 6, 7
        entry.addRemote(node1, 1, ver1, true);
        entry.addRemote(node1, 2, ver2, true);
        entry.addRemote(node1, 3, ver3, true);
        entry.addRemote(node2, 4, ver4, true);

        List<GridCacheVersion> committed = Arrays.asList(ver6, ver7);

        entry.orderCompleted(ver5, committed, Collections.<GridCacheVersion>emptyList());

        checkOrder(entry.remoteMvccSnapshot(), ver1, ver2, ver3, ver4);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver2), ver2, false, false);
        checkRemote(entry.candidate(ver3), ver3, false, false);
        checkRemote(entry.candidate(ver4), ver4, false, false);
    }

    /**
     * Test local and remote candidates together.
     */
    @Test
    public void testLocalAndRemote() {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        UUID node1 = UUID.randomUUID();
        UUID node2 = UUID.randomUUID();

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);
        GridCacheVersion ver5 = version(5);

        entry.addRemote(node1, 1, ver1, false);
        entry.addLocal(2, ver2, 0, true, true);

        Collection<GridCacheMvccCandidate> cands = entry.remoteMvccSnapshot();

        assert cands.size() == 1;
        assert cands.iterator().next().version().equals(ver1);

        entry.addRemote(node2, 5, ver5, false);

        cands = entry.remoteMvccSnapshot();

        assert cands.size() == 2;

        info(cands);

        checkOrder(cands, ver1, ver5);
        checkOrder(entry.localCandidates(true), ver2);

        entry.addRemote(node1, 3, ver3, true);
        entry.addLocal(4, ver4, 0, /*reenter*/true, false);

        cands = entry.remoteMvccSnapshot();

        assert cands.size() == 3;

        // Check order.
        checkOrder(entry.remoteMvccSnapshot(), ver1, ver5, ver3);
        checkOrder(entry.localCandidates(), ver2, ver4);

        entry.orderCompleted(
            ver2 /*local version.*/,
            Arrays.asList(new GridCacheVersion(1, 1, 2, 0), ver3, new GridCacheVersion(1, 5, 6, 0)),
            Collections.<GridCacheVersion>emptyList()
        );

        // Done ver3.
        checkOrder(entry.remoteMvccSnapshot(), ver1, ver3, ver5);
        checkOrder(entry.localCandidates(), ver2, ver4);

        checkRemote(entry.candidate(ver1), ver1, false, false);
        checkRemote(entry.candidate(ver3), ver3, true, false);
        checkRemote(entry.candidate(ver5), ver5, false, false);

        checkLocal(entry.candidate(ver2), ver2, false, false, false);
        checkLocal(entry.candidate(ver4), ver4, false, false, false);

        entry.readyLocal(ver2);

        checkLocal(entry.candidate(ver2), ver2, true, false, false);
        checkLocal(entry.candidate(ver4), ver4, false, false, false);

        assert entry.anyOwner() == null;

        entry.doneRemote(ver1);

        checkRemoteOwner(entry.anyOwner(), ver1);

        entry.removeLock(ver1);

        checkOrder(entry.remoteMvccSnapshot(), ver3, ver5);

        assert entry.anyOwner() == null;

        entry.doneRemote(ver3);

        checkRemoteOwner(entry.anyOwner(), ver3);

        entry.removeLock(ver3);

        checkLocalOwner(entry.anyOwner(), ver2, false);

        entry.removeLock(ver2);

        assert !entry.lockedByAny(ver4, ver5);

        checkOrder(entry.remoteMvccSnapshot(), ver5);
        checkOrder(entry.localCandidates(), ver4);

        assert entry.anyOwner() == null;

        entry.readyLocal(ver4);

        checkLocalOwner(entry.anyOwner(), ver4, false);

        entry.removeLock(ver4);

        assert entry.anyOwner() == null;

        GridCacheMvccCandidate c5 = entry.candidate(ver5);

        assert c5 != null;

        c5.setOwner();

        assert entry.anyOwner() == null;

        entry.doneRemote(ver5);

        checkRemoteOwner(entry.anyOwner(), ver5);

        assert !entry.lockedByAny(ver5);

        entry.removeLock(ver5);

        assert !entry.lockedByAny();
        assert entry.anyOwner() == null;
    }

    /**
     * @throws Exception If test failed.
     */
    @Test
    public void testMultipleLocalAndRemoteLocks1() throws Exception {
        UUID nodeId = UUID.randomUUID();

        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheContext<String, String> ctx = cache.context();

        GridCacheTestEntryEx entry1 = new GridCacheTestEntryEx(ctx, "1");
        GridCacheTestEntryEx entry2 = new GridCacheTestEntryEx(ctx, "2");
        GridCacheTestEntryEx entry3 = new GridCacheTestEntryEx(ctx, "3");

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);

        GridCacheMvccCandidate c13 = entry1.addLocal(1, ver3, 0, true, false);

        entry1.readyLocal(ver3);

        checkLocalOwner(entry1.candidate(ver3), ver3, false);

        GridCacheMvccCandidate c11 = entry1.addLocal(2, ver1, 0, true, true);
        GridCacheMvccCandidate c21 = entry2.addLocal(2, ver1, 0, true, true);
        GridCacheMvccCandidate c31 = entry3.addLocal(2, ver1, 0, true, true);

        GridCacheMvccCandidate c33 = entry3.addLocal(1, ver3, 0, true, false);

        linkCandidates(ctx, c11, c21, c31);

        entry1.readyLocal(ver1);
        entry2.readyLocal(ver1);
        entry3.readyLocal(ver1);

        checkLocal(entry1.candidate(ver1), ver1, true, false, false);
        checkLocal(entry2.candidate(ver1), ver1, true, false, false);
        checkLocal(entry3.candidate(ver1), ver1, true, false, false);

        checkLocal(entry3.candidate(ver3), ver3, false, false, false);

        linkCandidates(ctx, c13, c33);

        entry2.addRemote(nodeId, 3, ver2, true);

        checkLocal(entry2.candidate(ver1), ver1, true, false, false);

        entry3.addRemote(nodeId, 3, ver2, false);

        entry3.readyLocal(ver3);

        checkLocal(entry1.candidate(ver3), ver3, true, true, false);
        checkLocal(entry3.candidate(ver3), ver3, true, true, false);
        checkLocal(entry1.candidate(ver1), ver1, true, false, false);
        checkLocal(entry2.candidate(ver1), ver1, true, false, false);
        checkLocal(entry3.candidate(ver1), ver1, true, false, false);

        entry1.releaseLocal(1);

        entry2.recheckLock();

        checkLocal(entry1.candidate(ver1), ver1, true, true, false);
        checkLocal(entry2.candidate(ver1), ver1, true, true, false);
        checkLocal(entry3.candidate(ver1), ver1, true, false, false);

        entry3.releaseLocal(1);

        checkLocal(entry1.candidate(ver1), ver1, true, true, false);
        checkLocal(entry2.candidate(ver1), ver1, true, true, false);
        checkLocal(entry3.candidate(ver1), ver1, true, true, false);
    }

    /**
     * @throws Exception If test failed.
     */
    @Test
    public void testMultipleLocalAndRemoteLocks2() throws Exception {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheContext<String, String> ctx = cache.context();

        GridCacheTestEntryEx entry1 = new GridCacheTestEntryEx(ctx, "1");
        GridCacheTestEntryEx entry2 = new GridCacheTestEntryEx(ctx, "2");
        GridCacheTestEntryEx entry3 = new GridCacheTestEntryEx(ctx, "3");

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);

        GridCacheMvccCandidate c13 = entry1.addLocal(1, ver3, 0, true, true);

        entry1.readyLocal(ver3);

        checkLocalOwner(entry1.candidate(ver3), ver3, false);

        GridCacheMvccCandidate c11 = entry1.addLocal(2, ver2, 0, true, false);
        GridCacheMvccCandidate c21 = entry2.addLocal(2, ver2, 0, true, false);
        GridCacheMvccCandidate c31 = entry3.addLocal(2, ver2, 0, true, false);

        GridCacheMvccCandidate c33 = entry3.addLocal(1, ver3, 0, true, true);

        linkCandidates(ctx, c11, c21, c31);

        entry1.readyLocal(ver2);
        entry2.readyLocal(ver2);
        entry3.readyLocal(ver2);

        checkLocal(entry1.candidate(ver2), ver2, true, false, false);
        checkLocal(entry2.candidate(ver2), ver2, true, false, false);
        checkLocal(entry3.candidate(ver2), ver2, true, false, false);

        checkLocal(entry3.candidate(ver3), ver3, false, false, false);

        linkCandidates(ctx, c13, c33);

        entry2.addRemote(UUID.randomUUID(), 3, ver1, true);

        checkLocal(entry2.candidate(ver2), ver2, true, false, false);

        entry3.addRemote(UUID.randomUUID(), 3, ver1, true);

        entry3.readyLocal(ver3);

        checkLocal(entry1.candidate(ver3), ver3, true, true, false);
        checkLocal(entry3.candidate(ver3), ver3, true, false, false);
        checkLocal(entry1.candidate(ver2), ver2, true, false, false);
        checkLocal(entry2.candidate(ver2), ver2, true, false, false);
        checkLocal(entry3.candidate(ver2), ver2, true, false, false);

        entry2.removeLock(ver1);

        checkLocal(entry1.candidate(ver3), ver3, true, true, false);
        checkLocal(entry3.candidate(ver3), ver3, true, false, false);
        checkLocal(entry1.candidate(ver2), ver2, true, false, false);
        checkLocal(entry2.candidate(ver2), ver2, true, false, false);
        checkLocal(entry3.candidate(ver2), ver2, true, false, false);

        entry3.removeLock(ver1);

        checkLocal(entry1.candidate(ver3), ver3, true, true, false);
        checkLocal(entry3.candidate(ver3), ver3, true, true, false);
        checkLocal(entry1.candidate(ver2), ver2, true, false, false);
        checkLocal(entry2.candidate(ver2), ver2, true, false, false);
        checkLocal(entry3.candidate(ver2), ver2, true, false, false);

        entry1.releaseLocal(1);

        entry2.recheckLock();

        checkLocal(entry1.candidate(ver2), ver2, true, true, false);
        checkLocal(entry2.candidate(ver2), ver2, true, true, false);
        checkLocal(entry3.candidate(ver2), ver2, true, false, false);

        entry3.releaseLocal(1);

        checkLocal(entry1.candidate(ver2), ver2, true, true, false);
        checkLocal(entry2.candidate(ver2), ver2, true, true, false);
        checkLocal(entry3.candidate(ver2), ver2, true, true, false);
    }

    /**
     * @throws Exception If test failed.
     */
    @Test
    public void testMultipleLocalLocks() throws Exception {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheContext<String, String> ctx = cache.context();

        GridCacheTestEntryEx entry1 = new GridCacheTestEntryEx(ctx, "1");
        GridCacheTestEntryEx entry2 = new GridCacheTestEntryEx(ctx, "2");
        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver3 = version(3);

        GridCacheMvccCandidate c13 = entry1.addLocal(1, ver3, 0, true, false);

        entry1.readyLocal(ver3);

        checkLocalOwner(entry1.candidate(ver3), ver3, false);

        GridCacheMvccCandidate c11 = entry1.addLocal(2, ver1, 0, true, true);

        GridCacheMvccCandidate c21 = entry2.addLocal(2, ver1, 0, true, false);

        linkCandidates(ctx, c11, c21);

        entry1.readyLocal(ver1);
        entry2.readyLocal(ver1);

        checkLocal(entry1.candidate(ver1), ver1, true, false, false);
        checkLocal(entry2.candidate(ver1), ver1, true, false, false);

        GridCacheMvccCandidate c23 = entry2.addLocal(1, ver3, 0, true, true);

        linkCandidates(ctx, c13, c23);

        entry2.readyLocal(ver3);

        checkLocalOwner(entry2.candidate(ver3), ver3, false);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testUsedCandidates() throws Exception {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheContext<String, String> ctx = cache.context();

        GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);
        GridCacheVersion ver4 = version(4);

        GridCacheMvccCandidate c1 = entry.addLocal(1, ver1, 0, true, false);

        ctx.mvcc().addNext(ctx, c1);

        ctx.mvcc().contextReset();

        GridCacheMvccCandidate c2 = entry.addLocal(2, ver2, 0, true, false);

        ctx.mvcc().addNext(ctx, c2);

        ctx.mvcc().contextReset();

        GridCacheMvccCandidate c3 = entry.addLocal(3, ver3, 0, true, true);

        ctx.mvcc().addNext(ctx, c3);

        ctx.mvcc().contextReset();

        checkLocal(entry.candidate(ver1), ver1, false, false, false);
        checkLocal(entry.candidate(ver2), ver2, false, false, false);
        checkLocal(entry.candidate(ver3), ver3, false, false, false);

        entry.readyLocal(ver1);
        entry.readyLocal(ver3);

        checkLocal(entry.candidate(ver1), ver1, true, true, false);
        checkLocal(entry.candidate(ver2), ver2, false, false, false);
        checkLocal(entry.candidate(ver3), ver3, true, false, false);

        entry.removeLock(ver2);

        assert c3 != null;
        assert c2 != null;

        checkLocal(c2, ver2, false, false, false, true);

        checkLocal(entry.candidate(ver1), ver1, true, true, false);
        checkLocal(entry.candidate(ver3), ver3, true, false, false);

        entry.removeLock(ver1);

        checkLocal(entry.candidate(ver3), ver3, true, true, false);

        GridCacheMvccCandidate c4 = entry.addLocal(4, ver4, 0, true, true);

        ctx.mvcc().addNext(ctx, c4);

        assert c4 != null;
    }

    /**
     * Test 2 keys with candidates in reverse order.
     */
    @Test
    public void testReverseOrder1() {
        UUID id = UUID.randomUUID();

        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheContext<String, String> ctx = cache.context();

        GridCacheTestEntryEx entry1 = new GridCacheTestEntryEx(cache.context(), "1");
        GridCacheTestEntryEx entry2 = new GridCacheTestEntryEx(cache.context(), "2");

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);

        GridCacheMvccCandidate c1k1 = entry1.addLocal(2, ver2, 0, true, false);

        // Link up.
        ctx.mvcc().addNext(ctx, c1k1);

        entry1.readyLocal(ver2);

        checkLocal(c1k1, ver2, true, true, false);

        GridCacheMvccCandidate c2k1 = entry1.addRemote(id, 2, ver1, true);

        // Force recheck of assignments.
        entry1.recheckLock();

        checkLocal(c1k1, ver2, true, true, false);
        checkRemote(c2k1, ver1, false, false);

        GridCacheMvccCandidate c1k2 = entry2.addLocal(2, ver2, 0, true, false);

        assert c1k2 != null;

        ctx.mvcc().addNext(ctx, c1k2);

        assert c1k2.previous() == c1k1;

        GridCacheMvccCandidate c2k2 = entry2.addRemote(id, 3, ver1, true);

        entry2.readyLocal(c1k2);

        // Local entry2 should become owner, because otherwise remote will be stuck, waiting
        // for local entry1, which in turn awaits for local entry2.
        checkLocal(c1k2, ver2, true, true, false);
        checkRemote(c2k2, ver1, false, false);
    }

    /**
     * Test 2 keys with candidates in reverse order.
     *
     * @throws Exception If failed.
     */
    @Test
    public void testReverseOrder2() throws Exception {
        UUID id = UUID.randomUUID();

        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheContext<String, String> ctx = cache.context();

        GridCacheTestEntryEx entry1 = new GridCacheTestEntryEx(ctx, "1");
        GridCacheTestEntryEx entry2 = new GridCacheTestEntryEx(ctx, "2");

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);

        // Local with higher version.
        GridCacheMvccCandidate v3k1 = entry1.addLocal(3, ver3, 0, true, true);
        GridCacheMvccCandidate v3k2 = entry2.addLocal(3, ver3, 0, true, true);

        // Link up.
        linkCandidates(ctx, v3k1, v3k2);

        entry1.readyLocal(v3k1);

        checkLocal(v3k1, ver3, true, true, false);
        checkLocal(v3k2, ver3, false, false, false);

        // Remote locks.
        GridCacheMvccCandidate v2k1 = entry1.addRemote(id, 3, ver2, false);
        GridCacheMvccCandidate v2k2 = entry2.addRemote(id, 3, ver2, false);

        checkRemote(v2k1, ver2, false, false);
        checkRemote(v2k2, ver2, false, false);

        // Local with lower version.
        GridCacheMvccCandidate v1k1 = entry1.addLocal(4, ver1, 0, true, true);
        GridCacheMvccCandidate v1k2 = entry2.addLocal(4, ver1, 0, true, true);

        // Link up.
        linkCandidates(ctx, v1k1, v1k2);

        entry1.readyLocal(v1k1);
        entry2.readyLocal(v1k2);

        checkLocal(v1k1, ver1, true, false, false);
        checkLocal(v1k2, ver1, true, false, false);

        checkLocal(v3k2, ver3, false, false, false);

        entry2.readyLocal(v3k2);

        // Note, ver3 should be acquired before ver1 (i.e. in reverse order from natural versions order).
        checkLocal(v3k2, ver3, true, true, false);

        checkLocal(v1k1, ver1, true, false, false);
        checkLocal(v1k2, ver1, true, false, false);
    }

    /**
     * Tests local-only locks in reverse order.
     *
     * @throws Exception If failed.
     */
    @Test
    public void testReverseOrder3() throws Exception {
        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheContext<String, String> ctx = cache.context();

        GridCacheTestEntryEx entry1 = new GridCacheTestEntryEx(ctx, "1");
        GridCacheTestEntryEx entry2 = new GridCacheTestEntryEx(ctx, "2");

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver3 = version(3);

        // Local with higher version.
        GridCacheMvccCandidate v3k1 = entry1.addLocal(3, ver3, 0, true, false);
        GridCacheMvccCandidate v3k2 = entry2.addLocal(3, ver3, 0, true, false);

        linkCandidates(ctx, v3k1, v3k2);

        entry1.readyLocal(ver3);

        checkLocal(v3k1, ver3, true, true, false);
        checkLocal(v3k2, ver3, false, false, false);

        GridCacheMvccCandidate v1k1 = entry1.addLocal(4, ver1, 0, true, true);
        GridCacheMvccCandidate v1k2 = entry2.addLocal(4, ver1, 0, true, true);

        // Link up.
        linkCandidates(ctx, v1k1, v1k2);

        entry1.readyLocal(ver1);
        entry2.readyLocal(ver1);

        checkLocal(v3k1, ver3, true, true, false); // Owner.
        checkLocal(v3k2, ver3, false, false, false);

        checkLocal(v1k1, ver1, true, false, false);
        checkLocal(v1k2, ver1, true, false, false);

        entry2.readyLocal(v3k2);

        checkLocal(v3k1, ver3, true, true, false);
        checkLocal(v3k2, ver3, true, true, false);
    }

    /**
     * Tests local candidates with remote version in the middle on key2.
     *
     * @throws Exception If failed.
     */
    @Test
    public void testReverseOrder4() throws Exception {
        UUID id = UUID.randomUUID();

        GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);

        GridCacheContext<String, String> ctx = cache.context();

        GridCacheTestEntryEx entry1 = new GridCacheTestEntryEx(ctx, "1");
        GridCacheTestEntryEx entry2 = new GridCacheTestEntryEx(ctx, "2");

        GridCacheVersion ver1 = version(1);
        GridCacheVersion ver2 = version(2);
        GridCacheVersion ver3 = version(3);

        // Local with higher version.
        GridCacheMvccCandidate v3k1 = entry1.addLocal(3, ver3, 0, true, false);
        GridCacheMvccCandidate v3k2 = entry2.addLocal(3, ver3, 0, true, false);

        linkCandidates(ctx, v3k1, v3k2);

        entry1.readyLocal(ver3);

        checkLocal(v3k1, ver3, true, true, false);
        checkLocal(v3k2, ver3, false, false, false);

        GridCacheMvccCandidate v1k1 = entry1.addLocal(4, ver1, 0, true, true);
        GridCacheMvccCandidate v1k2 = entry2.addLocal(4, ver1, 0, true, true);

        // Link up.
        linkCandidates(ctx, v1k1, v1k2);

        entry1.readyLocal(ver1);
        entry2.readyLocal(ver1);

        checkLocal(v3k1, ver3, true, true, false); // Owner.
        checkLocal(v3k2, ver3, false, false, false);

        checkLocal(v1k1, ver1, true, false, false);
        checkLocal(v1k2, ver1, true, false, false);

        GridCacheMvccCandidate v2k2 = entry2.addRemote(id, 5, ver2, false);

        checkRemote(v2k2, ver2, false, false);

        entry2.readyLocal(v3k2);

        checkLocal(v3k1, ver3, true, true, false);
        checkLocal(v3k2, ver3, true, true, false);
    }

    /**
     * Gets version based on order.
     *
     * @param order Order.
     * @return Version.
     */
    private GridCacheVersion version(int order) {
        return new GridCacheVersion(1, order, order, 0);
    }

    /**
     * Links candidates.
     *
     * @param ctx Cache context.
     * @param cands Candidates.
     * @throws Exception If failed.
     */
    private void linkCandidates(final GridCacheContext<String, String> ctx,
        final GridCacheMvccCandidate... cands) throws Exception {
        multithreaded(new Runnable() {
            @Override public void run() {
                for (GridCacheMvccCandidate cand : cands) {
                    boolean b = grid.<String, String>internalCache(DEFAULT_CACHE_NAME).context().mvcc().addNext(ctx, cand);

                    assert b;
                }

                info("Link thread finished.");
            }
        }, 1);
    }

    /**
     * Check order in collection.
     *
     * @param cands Candidates to check order for.
     * @param vers Ordered versions.
     */
    private void checkOrder(Collection<GridCacheMvccCandidate> cands, GridCacheVersion... vers) {
        assertEquals(vers.length, cands.size());

        int i = 0;

        for (GridCacheMvccCandidate cand : cands) {
            assert cand.version().equals(vers[i]) : "Invalid order of candidates [cands=" + toString(cands) +
                ", order=" + toString(vers) + ']';

            i++;
        }
    }

    /**
     * @param objs Object to print.
     * @return String representation.
     */
    private String toString(Iterable<?> objs) {
        String eol = System.getProperty("line.separator");

        StringBuilder buf = new StringBuilder(eol);

        for (Object obj : objs)
            buf.append(obj.toString()).append(eol);

        return buf.toString();
    }

    /**
     * @param objs Object to print.
     * @return String representation.
     */
    private String toString(Object[] objs) {
        String eol = System.getProperty("line.separator");

        StringBuilder buf = new StringBuilder(eol);

        for (Object obj : objs)
            buf.append(obj.toString()).append(eol);

        return buf.toString();
    }

    /**
     * Checks flags on done candidate.
     *
     * @param cand Candidate to check.
     */
    private void checkDone(GridCacheMvccCandidate cand) {
        assert cand != null;

        info("Done candidate: " + cand);

        assert cand.used();
        assert cand.owner();

        assert !cand.ready();
        assert !cand.reentry();
        assert !cand.local();
    }

    /**
     * @param cand Candidate to check.
     * @param ver Version.
     * @param owner Owner flag.
     * @param used Done flag.
     */
    private void checkRemote(GridCacheMvccCandidate cand, GridCacheVersion ver, boolean owner, boolean used) {
        assert cand != null;

        info("Done candidate: " + cand);

        assert cand.version().equals(ver);

        // Check flags.
        assert cand.used() == used;
        assert cand.owner() == owner;

        assert !cand.ready();
        assert !cand.reentry();
        assert !cand.local();
    }

    /**
     * Checks flags on remote owner candidate.
     *
     * @param cand Candidate to check.
     * @param ver Version.
     */
    private void checkRemoteOwner(GridCacheMvccCandidate cand, GridCacheVersion ver) {
        assert cand != null;

        info("Done candidate: " + cand);

        assert cand.version().equals(ver);

        // Check flags.
        assert cand.used();
        assert cand.owner();

        assert !cand.ready();
        assert !cand.reentry();
        assert !cand.local();
    }

    /**
     * Checks flags on local candidate.
     *
     * @param cand Candidate to check.
     * @param ver Cache version.
     * @param ready Ready flag.
     * @param owner Lock owner.
     * @param reentry Reentry flag.
     */
    private void checkLocal(GridCacheMvccCandidate cand, GridCacheVersion ver, boolean ready,
        boolean owner, boolean reentry) {
        assert cand != null;

        info("Done candidate: " + cand);

        assert cand.version().equals(ver);

        // Check flags.
        assert cand.ready() == ready;
        assert cand.owner() == owner;
        assert cand.reentry() == reentry;

        assert !cand.used();

        assert cand.local();
    }

    /**
     * Checks flags on local candidate.
     *
     * @param cand Candidate to check.
     * @param ver Cache version.
     * @param ready Ready flag.
     * @param owner Lock owner.
     * @param reentry Reentry flag.
     * @param used Used flag.
     */
    private void checkLocal(GridCacheMvccCandidate cand, GridCacheVersion ver, boolean ready,
        boolean owner, boolean reentry, boolean used) {
        assert cand != null;

        info("Done candidate: " + cand);

        assert cand.version().equals(ver);

        // Check flags.
        assert cand.ready() == ready;
        assert cand.owner() == owner;
        assert cand.reentry() == reentry;
        assert cand.used() == used;

        assert cand.local();
    }

    /**
     * Checks flags on local owner candidate.
     *
     * @param cand Candidate to check.
     * @param ver Cache version.
     * @param reentry Reentry flag.
     */
    private void checkLocalOwner(GridCacheMvccCandidate cand, GridCacheVersion ver, boolean reentry) {
        assert cand != null;

        info("Done candidate: " + cand);

        assert cand.version().equals(ver);

        // Check flags.
        assert cand.reentry() == reentry;

        assert !cand.used();

        assert cand.ready();
        assert cand.owner();
        assert cand.local();
    }

    /**
     * @param cands Candidates to print.
     */
    private void info(Iterable<GridCacheMvccCandidate> cands) {
        info("Collection of candidates: ");

        for (GridCacheMvccCandidate c : cands)
            info(">>> " + c);
    }
}
