/** {@inheritDoc} */
  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    nodeId = GridUtils.readUuid(in);

    ver = CU.readVersion(in);

    timeout = in.readLong();
    threadId = in.readLong();
    id = in.readLong();

    short flags = in.readShort();

    mask(OWNER, OWNER.get(flags));
    mask(USED, USED.get(flags));
    mask(TX, TX.get(flags));

    ts = U.currentTimeMillis();
  }
  /**
   * @param parent Parent entry.
   * @param nodeId Requesting node ID.
   * @param otherNodeId Near node ID.
   * @param otherVer Other version.
   * @param threadId Requesting thread ID.
   * @param ver Cache version.
   * @param timeout Maximum wait time.
   * @param loc {@code True} if the lock is local.
   * @param reentry {@code True} if candidate is for reentry.
   * @param tx Transaction flag.
   * @param singleImplicit Single-key-implicit-transaction flag.
   * @param nearLoc Near-local flag.
   * @param dhtLoc DHT local flag.
   */
  public GridCacheMvccCandidate(
      GridCacheEntryEx<K, ?> parent,
      UUID nodeId,
      @Nullable UUID otherNodeId,
      @Nullable GridCacheVersion otherVer,
      long threadId,
      GridCacheVersion ver,
      long timeout,
      boolean loc,
      boolean reentry,
      boolean tx,
      boolean singleImplicit,
      boolean nearLoc,
      boolean dhtLoc) {
    assert nodeId != null;
    assert ver != null;
    assert parent != null;

    this.parent = parent;
    this.nodeId = nodeId;
    this.otherNodeId = otherNodeId;
    this.otherVer = otherVer;
    this.threadId = threadId;
    this.ver = ver;
    this.timeout = timeout;

    mask(LOCAL, loc);
    mask(REENTRY, reentry);
    mask(TX, tx);
    mask(SINGLE_IMPLICIT, singleImplicit);
    mask(NEAR_LOCAL, nearLoc);
    mask(DHT_LOCAL, dhtLoc);

    ts = U.currentTimeMillis();

    id = IDGEN.incrementAndGet();
  }