docs: synchronized public void recover() {
          if (tc.isEntryEnabled())
              Tr.entry(tc, "recover", this);
  
          final int state = _status.getState();
          if (_subordinate) {
              // For a subordinate, first check whether the global outcome is known locally.
              switch (state) {
                  // Due to the possibility of recovery being attempted asynchronously to
                  // an incoming superior request, we must cover the case where the
                  // transaction has now actually committed already.
                  case TransactionState.STATE_HEURISTIC_ON_COMMIT:
                  case TransactionState.STATE_COMMITTED:
                  case TransactionState.STATE_COMMITTING:
                      recoverCommit(true);
                      break;
                  // Due to the possibility of recovery being attempted asynchronously to
                  // an incoming superior request, we must cover the case where the
                  // transaction has now actually rolled back already.
                  case TransactionState.STATE_HEURISTIC_ON_ROLLBACK:
                  case TransactionState.STATE_ROLLED_BACK:
                  case TransactionState.STATE_ROLLING_BACK:
                      recoverRollback(true);
                      break;
                  // For a subordinate, the replay_completion method is invoked on the superior.
                  // If the number of times the replay_completion has been retried is greater
                  // than the value specified by COMMITRETRY, then HEURISTICDIRECTION is used
                  // to determine the transaction outcome.
                  default:
                      // If we were imported from a JCA provider, check whether it's still installed.
                      // If so, we need do nothing here since we expect the RA to complete the transaction.
                      // Otherwise, we will complete using the configured direction.
                      if (_JCARecoveryData != null) {
                          final String id = _JCARecoveryData.getWrapper().getProviderId();
                          if (TMHelper.isProviderInstalled(id)) {
                              if (tc.isDebugEnabled())
                                  Tr.debug(tc, "recover", "Do nothing. Expect provider " + id + " will complete.");
                              // Do nothing. RA is responsible for completing.
                          } else {
                              switch (_configProvider.getHeuristicCompletionDirection()) {
                                  case ConfigurationProvider.HEURISTIC_COMPLETION_DIRECTION_COMMIT:
                                      Tr.error(tc, "WTRN0098_COMMIT_RA_UNINSTALLED", new Object[] { getTranName(), id });
                                      recoverCommit(false);
                                      break;
                                  case ConfigurationProvider.HEURISTIC_COMPLETION_DIRECTION_MANUAL:
                                      // do nothing, administrative completion is required
                                      _needsManualCompletion = true;
                                      Tr.info(tc, "WTRN0101_MANUAL_RA_UNINSTALLED", new Object[] { getTranName(), id });
                                      break;
                                  default:
                                      Tr.error(tc, "WTRN0099_ROLLBACK_RA_UNINSTALLED", new Object[] { getTranName(), id });
                                      recoverRollback(false);
                              }
                          }
                      } else {
                          retryCompletion();
                      }
                      break;
              }
          } else {
              // For a top-level Transaction, we will only recover in the case
              // where we have successfully prepared.  If the state is not committing,
              // then assume it is rollback.
              if (state == TransactionState.STATE_LAST_PARTICIPANT) {
                  // LIDB1673-13 lps heuristic completion.
                  // The transaction was attempting to complete its
                  // 1PC resource when the server went down.
                  // Use the lpsHeuristicCompletion flag to determine
                  // how to complete the tx.
                  switch (ConfigurationProviderManager.getConfigurationProvider().getHeuristicCompletionDirection()) {
                      case ConfigurationProvider.HEURISTIC_COMPLETION_DIRECTION_COMMIT:
                          Tr.error(tc, "WTRN0096_HEURISTIC_MAY_HAVE_OCCURED", getTranName());
                          recoverCommit(false);
                          break;
                      case ConfigurationProvider.HEURISTIC_COMPLETION_DIRECTION_MANUAL:
                          // do nothing!?
                          _needsManualCompletion = true;
                          Tr.info(tc, "WTRN0097_HEURISTIC_MANUAL_COMPLETION", getTranName());
                          break;
                      default:
                          Tr.error(tc, "WTRN0102_HEURISTIC_MAY_HAVE_OCCURED", getTranName());
                          recoverRollback(false);
                  }
              } else if (state == TransactionState.STATE_COMMITTING)
                  recoverCommit(false);
              else
                  recoverRollback(false);
          }
  
          if (tc.isEntryEnabled())
              Tr.exit(tc, "recover");
      }