/** @param entry Entry. */
    @SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter"})
    void recheck(@Nullable GridCacheEntryEx entry) {
      if (entry == null) return;

      if (exchLog.isDebugEnabled())
        exchLog.debug("Rechecking entry for completion [entry=" + entry + ", finFut=" + this + ']');

      Collection<GridCacheMvccCandidate> cands = pendingLocks.get(entry.txKey());

      if (cands != null) {
        synchronized (cands) {
          for (Iterator<GridCacheMvccCandidate> it = cands.iterator(); it.hasNext(); ) {
            GridCacheMvccCandidate cand = it.next();

            // Check exclude ID again, as key could have been reassigned.
            if (cand.removed()) it.remove();
          }

          if (cands.isEmpty()) pendingLocks.remove(entry.txKey());

          if (pendingLocks.isEmpty()) {
            onDone();

            if (exchLog.isDebugEnabled()) exchLog.debug("Finish lock future is done: " + this);
          }
        }
      }
    }
    /**
     * @param topVer Topology version.
     * @param entries Entries.
     */
    FinishLockFuture(Iterable<GridDistributedCacheEntry> entries, AffinityTopologyVersion topVer) {
      assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0;

      this.topVer = topVer;

      for (GridCacheEntryEx entry : entries) {
        // Either local or near local candidates.
        try {
          Collection<GridCacheMvccCandidate> locs = entry.localCandidates();

          if (!F.isEmpty(locs)) {
            Collection<GridCacheMvccCandidate> cands = new ConcurrentLinkedQueue<>();

            cands.addAll(F.view(locs, versionFilter()));

            if (!F.isEmpty(cands)) pendingLocks.put(entry.txKey(), cands);
          }
        } catch (GridCacheEntryRemovedException ignored) {
          if (exchLog.isDebugEnabled())
            exchLog.debug(
                "Got removed entry when adding it to finish lock future (will ignore): " + entry);
        }
      }

      if (exchLog.isDebugEnabled())
        exchLog.debug("Pending lock set [topVer=" + topVer + ", locks=" + pendingLocks + ']');
    }