@Override
  public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command)
      throws Throwable {
    GMUPrepareCommand spc = convert(command, GMUPrepareCommand.class);

    if (ctx.isOriginLocal()) {
      spc.setVersion(ctx.getTransactionVersion());
      spc.setReadSet(ctx.getReadSet());
    } else {
      ctx.setTransactionVersion(spc.getPrepareVersion());
    }

    wrapEntriesForPrepare(ctx, command);
    performValidation(ctx, spc);

    Object retVal = invokeNextInterceptor(ctx, command);

    if (ctx.isOriginLocal() && command.getModifications().length > 0) {
      EntryVersion commitVersion =
          calculateCommitVersion(
              ctx.getTransactionVersion(),
              versionGenerator,
              cll.getWriteOwners(ctx.getCacheTransaction()));
      ctx.setTransactionVersion(commitVersion);
    } else {
      retVal = ctx.getTransactionVersion();
    }

    if (command.isOnePhaseCommit()) {
      commitContextEntries.commitContextEntries(ctx);
    }

    return retVal;
  }
 @Override
 protected void afterWriteLocksAcquired(TxInvocationContext ctx, PrepareCommand command)
     throws InterruptedException {
   GMUPrepareCommand spc = GMUHelper.convert(command, GMUPrepareCommand.class);
   Object[] readSet = spc.getReadSet();
   TimSort.sort(readSet, keyComparator);
   acquireReadLocks(ctx, readSet);
 }
  /**
   * validates the read set and returns the prepare version from the commit queue
   *
   * @param ctx the context
   * @param command the prepare command
   * @throws InterruptedException if interrupted
   */
  protected void performValidation(TxInvocationContext ctx, GMUPrepareCommand command)
      throws InterruptedException {
    boolean hasToUpdateLocalKeys = hasLocalKeysToUpdate(command.getModifications());
    boolean isReadOnly = command.getModifications().length == 0;

    if (!isReadOnly) {
      cll.performReadSetValidation(ctx, command);
      if (hasToUpdateLocalKeys) {
        transactionCommitManager.prepareTransaction(ctx.getCacheTransaction());
      } else {
        transactionCommitManager.prepareReadOnlyTransaction(ctx.getCacheTransaction());
      }
    }

    if (log.isDebugEnabled()) {
      log.debugf(
          "Transaction %s can commit on this node. Prepare Version is %s",
          command.getGlobalTransaction().prettyPrint(), ctx.getTransactionVersion());
    }
  }