/** {@inheritDoc} */
  @Override
  public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr)
      throws IgniteCheckedException {
    super.finishUnmarshal(ctx, ldr);

    if (writes != null) unmarshalTx(writes, false, ctx, ldr);

    if (reads != null) unmarshalTx(reads, false, ctx, ldr);

    if (grpLockKeyBytes != null && grpLockKey == null)
      grpLockKey = ctx.marshaller().unmarshal(grpLockKeyBytes, ldr);

    if (dhtVerKeys != null && dhtVers == null) {
      assert dhtVerVals != null;
      assert dhtVerKeys.size() == dhtVerVals.size();

      Iterator<IgniteTxKey> keyIt = dhtVerKeys.iterator();
      Iterator<GridCacheVersion> verIt = dhtVerVals.iterator();

      dhtVers = U.newHashMap(dhtVerKeys.size());

      while (keyIt.hasNext()) {
        IgniteTxKey key = keyIt.next();

        key.finishUnmarshal(ctx.cacheContext(key.cacheId()), ldr);

        dhtVers.put(key, verIt.next());
      }
    }

    if (txNodesBytes != null) txNodes = ctx.marshaller().unmarshal(txNodesBytes, ldr);
  }
  /** {@inheritDoc} */
  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    super.readExternal(in);

    threadId = in.readLong();
    commit = in.readBoolean();
    invalidate = in.readBoolean();
    reply = in.readBoolean();

    futId = U.readGridUuid(in);
    commitVer = CU.readVersion(in);
    baseVer = CU.readVersion(in);

    writeEntries = U.readList(in);
  }
  /** {@inheritDoc} */
  @Override
  public void writeExternal(ObjectOutput out) throws IOException {
    super.writeExternal(out);

    out.writeLong(threadId);
    out.writeBoolean(commit);
    out.writeBoolean(invalidate);
    out.writeBoolean(reply);

    U.writeGridUuid(out, futId);
    CU.writeVersion(out, commitVer);
    CU.writeVersion(out, baseVer);

    U.writeCollection(out, writeEntries);
  }
  /**
   * {@inheritDoc}
   *
   * @param ctx
   */
  @Override
  public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
    super.prepareMarshal(ctx);

    if (writes != null) marshalTx(writes, ctx);

    if (reads != null) marshalTx(reads, ctx);

    if (grpLockKey != null && grpLockKeyBytes == null)
      grpLockKeyBytes = ctx.marshaller().marshal(grpLockKey);

    if (dhtVers != null) {
      for (IgniteTxKey key : dhtVers.keySet()) {
        GridCacheContext cctx = ctx.cacheContext(key.cacheId());

        key.prepareMarshal(cctx);
      }

      dhtVerKeys = dhtVers.keySet();
      dhtVerVals = dhtVers.values();
    }

    if (txNodes != null) txNodesBytes = ctx.marshaller().marshal(txNodes);
  }
  /** {@inheritDoc} */
  @Override
  public void p2pUnmarshal(GridCacheContext<K, V> ctx, ClassLoader ldr) throws GridException {
    super.p2pUnmarshal(ctx, ldr);

    unmarshalTx(writeEntries, ctx, ldr);
  }
  /** {@inheritDoc} */
  @Override
  public void p2pMarshal(GridCacheContext<K, V> ctx) throws GridException {
    super.p2pMarshal(ctx);

    marshalTx(writeEntries, ctx);
  }