// same as replay_completion(res) : added for delegated recovery support
  public Status replay_completion(Resource res, String logPath) throws NotPrepared {

    if (_logger.isLoggable(Level.FINE)) {
      _logger.logp(
          Level.FINE,
          "RecoveryCoordinatorImpl",
          "replay_completion()",
          "replay_completion on Resource:" + res);
    }

    Status result = Status.StatusRolledBack;

    CoordinatorImpl coord = DelegatedRecoveryManager.getCoordinator(globalTID, logPath);
    if (coord != null) {
      try {
        result = coord.get_status();
      } catch (SystemException exc) {
      }
    }

    switch (result.value()) {

        /*
         * If the transaction is still active, raise the NotPrepared
         * exception. The Coordinator must be marked rollback-only at
         * this point because we cannot allow the transaction to
         * complete if a participant has failed.
         */

      case Status._StatusActive:
      case Status._StatusMarkedRollback:
        try {
          coord.rollback_only();
        } catch (Throwable exc) {
        }

        throw new NotPrepared();

        /*
         * If the transaction is prepared, the caller must wait for the
         * Coordinator to tell it what to do, so return an unknown status, and
         * do nothing.  Note that if this Coordinator is sitting waiting for
         * its superior, this could take a int time.
         */

      case Status._StatusPrepared:
        result = Status.StatusUnknown;
        break;

        /*
         * If the transaction has been committed, the caller will receive
         * a commit.
         *
         * GDH If the transaction is commiting then we pass this on
         * to the caller. This state (added in OTS 1.1 means that
         * TopCoordinator.recover must now accept the COMMITTING state.
         */

      case Status._StatusCommitting:
        // MODIFICATION (Ram Jeyaraman) commented out the code below,
        // since a StatusCommitting will be upgraded to Committed in
        // the subordinate.
        /*
        // (Ram Jeyaraman) let the subordinate wait, and allow the root
        // finish driving the commit.
        result = Status.StatusUnknown;
        */
        break;

      case Status._StatusCommitted:
        break;

      case Status._StatusRolledBack:

        // If the transaction has been rolled back, and there is
        // no Coordinator for the transaction, we must invoke rollback
        // directly, as it will not be done otherwise.  However for
        // proxies, this rollback cannot be done from this thread as
        // it would cause deadlock in the server requesting resync.

        if (coord == null) {

          if (!Configuration.getProxyChecker().isProxy(res)) {
            rollbackOrphan(res);
          } else {

            // We must pass a duplicate of the proxy to the
            // rollback thread because this proxy will be destroyed
            // when the replay_completion request returns
            // to the remote server.

            try {
              OrphanRollbackThread rollbackThread =
                  new OrphanRollbackThread(this, (Resource) res._duplicate());
              rollbackThread.start();
            } catch (SystemException exc) {
            }
          }
        }

        break;

        /*
         * In any other situation, assume that the transaction has been rolled
         * back. As there is a Coordinator, it will direct the Resource to roll
         * back.
         */

      default:
        result = Status.StatusRolledBack;
    }

    return result;
  }