docs: @Override
      public void run() {
          if (tc.isEntryEnabled())
              Tr.entry(tc, "run");
          try {
              if (tc.isDebugEnabled())
                  Tr.debug(tc, "Performing recovery for " + _failureScopeController.serverName());
  
              // Lets update our entry in the leaseLog early
              if (_leaseLog != null) {
                  // TODO - need a sensible lease time
                  try {
                      //Don't update the server lease if this is a peer rather than local server.
                      if (_localRecoveryIdentity.equals(_failureScopeController.serverName()))
                          _leaseLog.updateServerLease(_failureScopeController.serverName(), _recoveryGroup, true);
                  } catch (Exception exc) {
                      FFDCFilter.processException(exc, "com.ibm.tx.jta.impl.RecoveryManager.run", "1698", this);
                      Tr.error(tc, "WTRN0112_LOG_OPEN_FAILURE", _leaseLog);
                      Object[] errorObject = new Object[] { _localRecoveryIdentity };
                      Tr.audit(tc, "CWRLS0008_RECOVERY_LOG_FAILED",
                               errorObject);
                      Tr.info(tc, "CWRLS0009_RECOVERY_LOG_FAILED_DETAIL", exc);
                      // If the logs were opened successfully then attempt to close them with a close immediate. This does
                      // not cause any keypointing, it just closes the file channels and handles (if they are still open)
                      closeLogs(false);
  
                      recoveryFailed(exc);
  
                      if (tc.isEventEnabled())
                          Tr.event(tc, "Exception caught opening Lease log!", exc);
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  }
              }
  
              // Open the transaction log. This contains details of inflight transactions.
              if (_tranLog != null) {
                  try {
                      _tranLog.openLog();
                  } catch (LogIncompatibleException exc) {
                      // No FFDC Code needed.
                      // The attempt to open the transaction log has failed because this recovery log is from a version
                      // of the RLS / transaction service thats not supported by this level of the code.
                      //
                      // This specific failure type is most likely to occur in an HA enabled environment
                      // where there are other servers in the cluster that are from a down-level websphere
                      // product. For example 5.1 and 6.0 servers in the same cluster. When a 6.0 server
                      // attempts to peer recover the 5.1 log (as will be the case since the 5.1 server
                      // will not join an HA group get ownership of its recovery logs) a
                      // LogIncompatibleException will be generated. To try and avoid confusion, this is
                      // logged in a single place only (in the trace - to be replaced with messages asap)
                      // Additionally, no FFDC is generated.
                      //
                      // The response by this service is to stop recovery processing and be able to handle
                      // as a noop any subsequent terminateRecovery request. This prevents the service
                      // conflicting with a downlevel server thats not playing the HA game.
                      //
                      // Clearly, this is somewhat in conflict with the reporting of errors when a recovery
                      // log from an older WS install is manually recovered on newer WS install (not supported
                      // anyway). The HA issues above are deemed to be more important.
                      haltDownlevelRecovery();
  
                      // Now signal recovery completion to ensure that no shutdown logic will hang pending this
                      // "recovery" process.
                      recoveryComplete();
  
                      if (_failureScopeController.localFailureScope())
                          TMHelper.asynchRecoveryProcessingComplete(exc);
  
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  } catch (LogAllocationException exc) {
                      FFDCFilter.processException(exc, "com.ibm.tx.jta.impl.RecoveryManager.run", "1830", this);
                      Tr.error(tc, "WTRN0111_LOG_ALLOCATION", _tranLog);
  
                      closeLogs(true);
  
                      recoveryFailed(exc);
  
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  } catch (Exception exc) {
                      FFDCFilter.processException(exc, "com.ibm.tx.jta.impl.RecoveryManager.run", "1698", this);
                      Tr.error(tc, "WTRN0112_LOG_OPEN_FAILURE", _tranLog);
  
                      // If the logs were opened successfully then attempt to close them with a close immediate. This does
                      // not cause any keypointing, it just closes the file channels and handles (if they are still open)
                      closeLogs(true);
  
                      recoveryFailed(exc);
  
                      if (tc.isEventEnabled())
                          Tr.event(tc, "Exception caught opening transaction recovery log!", exc);
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  }
              }
  
              // Check to see if shutdown has begun before proceeding. If it has, no
              // further action can be taken.
              if (shutdownInProgress()) {
                  if (tc.isEntryEnabled())
                      Tr.exit(tc, "run");
                  return;
              }
  
              // Open the partner log. This contains details of the resource managers in use by the above inflight transactions.
              if (_xaLog != null) {
                  try {
                      _xaLog.openLog();
                      if (_recoverXaLog != null)
                          _recoverXaLog.openLog();
                  } catch (LogIncompatibleException exc) {
                      // No FFDC Code needed.
                      // The attempt to open the transaction log has failed because this recovery log is from a version
                      // of the RLS / transaction service thats not supported by this level of the code.
                      //
                      // This specific failure type is most likely to occur in an HA enabled environment
                      // where there are other servers in the cluster that are from a down-level websphere
                      // product. For example 5.1 and 6.0 servers in the same cluster. When a 6.0 server
                      // attempts to peer recover the 5.1 log (as will be the case since the 5.1 server
                      // will not join an HA group get ownership of its recovery logs) a
                      // LogIncompatibleException will be generated. To try and avoid confusion, this is
                      // logged in a single place only (in the trace - to be replaced with messages asap)
                      // Additionally, no FFDC is generated.
                      //
                      // The response by this service is to stop recovery processing and be able to handle
                      // as a noop any subsequent terminateRecovery request. This prevents the service
                      // conflicting with a downlevel server thats not playing the HA game.
                      //
                      // Clearly, this is somewhat in conflict with the reporting of errors when a recovery
                      // log from an older WS install is manually recovered on newer WS install (not supported
                      // anyway). The HA issues above are deemed to be more important.
                      //
                      // There is no need to close the recovery log as its already been closed as a result
                      // of this exception.
                      haltDownlevelRecovery();
  
                      // Now signal recovery completion to ensure that no shutdown logic will hang pending this
                      // "recovery" process.
                      recoveryComplete();
  
                      if (_failureScopeController.localFailureScope())
                          TMHelper.asynchRecoveryProcessingComplete(exc);
  
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  } catch (LogAllocationException exc) {
                      FFDCFilter.processException(exc, "com.ibm.tx.jta.impl.RecoveryManager.run", "1922", this);
                      Tr.error(tc, "WTRN0111_LOG_ALLOCATION", _xaLog);
  
                      // If the logs were opened successfully then attempt to close them with a close immediate. This does
                      // not cause any keypointing, it just closes the file channels and handles (if they are still open)
                      closeLogs(true);
  
                      recoveryFailed(exc);
  
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  } catch (Exception exc) {
                      FFDCFilter.processException(exc, "com.ibm.tx.jta.impl.RecoveryManager.run", "1723", this);
                      Tr.error(tc, "WTRN0112_LOG_OPEN_FAILURE", _xaLog);
  
                      // If the logs were opened successfully then attempt to close them with a close immediate. This does
                      // not cause any keypointing, it just closes the file channels and handles (if they are still open)
                      closeLogs(true);
  
                      // Signal recovery completion to ensure that no shutdown logic will hang pending this
                      // "recovery" process.
                      recoveryFailed(exc);
  
                      if (tc.isEventEnabled())
                          Tr.event(tc, "Exception caught opening XA resources recovery log!", exc);
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
  
                      return;
                  }
              }
  
              // Check to see if shutdown has begun before proceeding. If it has, no
              // further action can be taken.
              if (shutdownInProgress()) {
                  if (tc.isEntryEnabled())
                      Tr.exit(tc, "run");
                  return;
              }
  
              // Replay the partner log. This method also checks shutdownInProgress and exits
              // directly if it retun true.
              final int _XAEntries;
  
              if (_xaLog != null) {
                  try {
                      _XAEntries = replayPartnerLog();
                  } catch (Throwable exc) {
                      // REQD:L:1578 Recovery processing has failed. We need to add a "leave group" instruction at this point
                      // if this turns out to be a peer recovery process. If this is the main line server run then there is
                      // nothing we can do. Simply allow the server to continue in 1PC only mode. Additional cleanup required.
                      FFDCFilter.processException(exc, "com.ibm.tx.jta.impl.RecoveryManager.run", "1814", this);
                      if (tc.isEventEnabled())
                          Tr.event(tc, "An unexpected error occured during partner log replay: " + exc);
  
                      closeLogs(true);
  
                      recoveryFailed(exc);
  
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  }
              } else {
                  _XAEntries = 0;
              }
  
              // Determine if shutdown processing started during replayPartnerLog processing.
              // If it has, no further action can be taken.
              if (shutdownInProgress()) {
                  if (tc.isEntryEnabled())
                      Tr.exit(tc, "run");
                  return;
              }
  
              // Replay the transaction log. This method also checks shutdownInProgress and exits
              // directly if it retun true.
              if (_tranLog != null) {
                  try {
                      if ((_xaLog instanceof DistributedRecoveryLog) && (_tranLog instanceof DistributedRecoveryLog)) {
                          // When the partner log fails non-HA can still process JTA transactions that do not require a new partner
                          // to be logged, hence pass false to associateLog on _xaLog
                          ((DistributedRecoveryLog) _xaLog).associateLog((DistributedRecoveryLog) _tranLog, false);
                          // In the event that the tran log fails, mark the partner as failed to ensure nothing tries to modify it.
                          ((DistributedRecoveryLog) _tranLog).associateLog((DistributedRecoveryLog) _xaLog, true);
                      }
                      replayTranLog();
                  } catch (Throwable exc) {
                      // REQD:L:1578 Recovery processing has failed. We need to add a "leave group" instruction at this point
                      // if this turns out to be a peer recovery process. If this is the main line server run then there is
                      // nothing we can do. Simply allow the server to continue in 1PC only mode. Additional cleanup required.
                      FFDCFilter.processException(exc, "com.ibm.tx.jta.impl.RecoveryManager.run", "1842", this);
                      if (tc.isEventEnabled())
                          Tr.event(tc, "An unexpected error occured during transaction log replay: " + exc);
  
                      closeLogs(true);
  
                      recoveryFailed(exc);
  
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  }
              }
  
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, "_recoveredApplId = " + (_recoveredApplId == null ? "null" : Util.toHexString(_recoveredApplId)));
                  Tr.debug(tc, "_recoveredEpoch = " + _recoveredEpoch);
              }
  
              // Determine if shutdown processing started during replayTranLog processing.
              // If it has, no further action can be taken.
              if (shutdownInProgress()) {
                  if (tc.isEntryEnabled())
                      Tr.exit(tc, "run");
                  return;
              }
  
              validateServiceData();
  
              // If this is main server startup recovery then update the overall server applId and Epoch in the main
              // Configuration as these will be used to create new GlobalTIDs and XIDs for this server instance.
              if (_failureScopeController.localFailureScope()) {
                  Configuration.setApplId(_ourApplId);
                  Configuration.setCurrentEpoch(_ourEpoch);
              }
  
              registerGlobalCoordinator();
  
              //
              // Inform the logs that all recovery work has been finished
              // so that they can keypoint.
              //
              if (_xaLog != null) {
                  try {
                      // Update the service data.
                      if (_failureScopeController.localFailureScope()) {
                          if (_tranLog != null) {
                              updateTranLogServiceData();
                          }
                          updatePartnerServiceData(); // this includes the status
                      }
  
                      // Determine if shutdown processing started during update processing.
                      // If it has, no further action can be taken.
                      if (shutdownInProgress()) {
                          if (tc.isEntryEnabled())
                              Tr.exit(tc, "run");
                          return;
                      }
  
                      if (_tranLog != null) {
                          _tranLog.recoveryComplete();
                      }
  
                      // Determine if shutdown processing started during recoveryComplete processing.
                      // If it has, no further action can be taken.
                      if (shutdownInProgress()) {
                          if (tc.isEntryEnabled())
                              Tr.exit(tc, "run");
                          return;
                      }
  
                      if (_xaLog != null) {
                          _xaLog.recoveryComplete();
                      }
  
                      // Determine if shutdown processing started during recoveryComplete processing.
                      // If it has, no further action can be taken.
                      if (shutdownInProgress()) {
                          if (tc.isEntryEnabled())
                              Tr.exit(tc, "run");
                          return;
                      }
                  } catch (Exception e) {
                      FFDCFilter.processException(e, "com.ibm.tx.jta.impl.RecoveryManager.run", "1866", this);
  
                      // REQD:L:1578 Recovery processing
                      // if this turns out to be a peer recovery process. If this is the main line server run then there is
                      // nothing we can do. Simply allow the server to continue in 1PC only mode. Additional cleanup required.
  
                      Tr.error(tc, "WTRN0026_KEYPOINT_EXC_IN_RECOVERY", e);
  
                      if (tc.isEventEnabled())
                          Tr.event(tc, "An unexpected error occured during keypointing: " + e);
  
                      recoveryFailed(e); // @254326C
  
                      if (tc.isEntryEnabled())
                          Tr.exit(tc, "run");
                      return;
                  }
              }
  
              if (tc.isEventEnabled())
                  Tr.event(tc, "replay completed");
  
              // Post the recovery in progress event so that requests waiting for replay
              // to complete may proceed.
              replayComplete();
  
              // NB Any exit point (be it a thrown exception or return statement) from this method
              // prior to this point MUST call the runtime framework to inform it that the
              // transaction service is "ready"; by supplying an instance of RuntimeError we can
              // cause the runtime to fail server startup.
  
              // Ensure that transaction service is enabled and can now import/export transactions or
              // start transactions and enlist more than one resource.
              ((TranManagerSet) TransactionManagerFactory.getTransactionManager()).replayComplete(_failureScopeController.localFailureScope());
  
              performResync(_XAEntries);
          } finally {
              if (tc.isDebugEnabled())
                  Tr.debug(tc, "Performed recovery for " + _failureScopeController.serverName());
          }
  
          if (tc.isEntryEnabled())
              Tr.exit(tc, "run");
      }