/** {@inheritDoc} */
  @Override
  public int compareTo(GridCacheMvccCandidate<K> o) {
    if (o == this) return 0;

    int c = ver.compareTo(o.ver);

    // This is done, so compare and equals methods will be consistent.
    if (c == 0) return key().equals(o.key()) ? 0 : id < o.id ? -1 : 1;

    return c;
  }
  /** {@inheritDoc} */
  @SuppressWarnings({"unchecked"})
  @Override
  public boolean equals(Object o) {
    if (o == null) return false;

    if (o == this) return true;

    GridCacheMvccCandidate<K> other = (GridCacheMvccCandidate<K>) o;

    assert key() != null && other.key() != null
        : "Key is null [this=" + this + ", other=" + o + ']';

    return ver.equals(other.ver) && key().equals(other.key());
  }
 /** {@inheritDoc} */
 @Override
 public int hashCode() {
   return ver.hashCode();
 }
 /**
  * Checks if this candidate matches version or thread-nodeId combination.
  *
  * @param nodeId Node ID to check.
  * @param ver Version to check.
  * @param threadId Thread ID to check.
  * @return {@code True} if matched.
  */
 public boolean matches(GridCacheVersion ver, UUID nodeId, long threadId) {
   return ver.equals(this.ver) || (nodeId.equals(this.nodeId) && threadId == this.threadId);
 }