docs: protected void resync(int XAEntries) {
          if (tc.isEntryEnabled())
              Tr.entry(tc, "resync", XAEntries);
  
          try {
              boolean XArecovered = (XAEntries == 0);
              boolean auditRecovery = ConfigurationProviderManager.getConfigurationProvider().getAuditRecovery();
  
              ClassLoader cl = Thread.currentThread().getContextClassLoader();
  
              if (auditRecovery) {
                  Tr.audit(tc, "WTRN0134_RECOVERING_XARMS", XAEntries);
              }
  
              int retryAttempts = 0;
              final int configuredWait = ConfigurationProviderManager.getConfigurationProvider().getHeuristicRetryInterval();
              int retryWait = (configuredWait <= 0) ? TransactionImpl.defaultRetryTime : configuredWait;
  
              boolean callRecoveryComplete = true;
              boolean stopProcessing = shutdownInProgress();
  
              while (!stopProcessing) {
                  if (retryAttempts > 0 && tc.isDebugEnabled())
                      Tr.debug(tc, "Retrying resync");
  
                  // Get list of current recovered transactions
                  TransactionImpl[] recoveredTransactions = getRecoveringTransactions();
  
                  // Contact the XA RMs and get the indoubt XIDs.  Match any with our transactions, or else
                  // roll back the ones that we have no information about.  If some fail to recover, we retry
                  // later.
                  if (!XArecovered) {
                      // Build a list of transaction Xids to check with each recovered RM
                      final Xid[] txnXids = new Xid[recoveredTransactions.length];
                      for (int i = 0; i < recoveredTransactions.length; i++) {
                          txnXids[i] = recoveredTransactions[i].getXid();
                      }
  
                      // plt recover will return early if shutdown is detected.
                      XArecovered = getPartnerLogTable().recover(this, cl, txnXids);
                  }
  
                  if (XArecovered) {
                      // If there are any transactions, proceed with recover.
                      for (int i = 0; i < recoveredTransactions.length; i++) {
                          if (stopProcessing = shutdownInProgress()) {
                              break;
                          }
  
                          try {
                              //LIDB3645: don't recover JCA inbound tx in recovery-mode
                              if (!(recoveryOnlyMode && recoveredTransactions[i].isRAImport())) {
                                  recoveredTransactions[i].recover();
                                  if (recoveryOnlyMode) {
                                      if (recoveredTransactions[i].getTransactionState().getState() != TransactionState.STATE_NONE) {
                                          Tr.warning(tc, "WTRN0114_TRAN_RETRY_NEEDED",
                                                     new Object[] { recoveredTransactions[i].getTranName(),
                                                                    retryWait });
                                      }
                                  }
                              }
                          } catch (Throwable exc) {
                              FFDCFilter.processException(exc, "com.ibm.tx.jta.impl.RecoveryManager.resync", "1654", this);
                              Tr.error(tc, "WTRN0016_EXC_DURING_RECOVERY", exc);
                          }
                      }
                  }
  
                  if (stopProcessing = shutdownInProgress()) {
                      break;
                  }
  
                  boolean waitForTxComplete;
                  if (recoveryOnlyMode || _waitForRecovery) {
                      waitForTxComplete = !recoveryModeTxnsComplete();
                  } else {
                      waitForTxComplete = (_recoveringTransactions.size() > 0);
                  }
  
                  if (!XArecovered || waitForTxComplete) {
                      if (retryAttempts == 0 && !recoveryOnlyMode && _failureScopeController.localFailureScope()) {
                          // Call recoveryComplete after first attempt through the loop except for recoveryOnlyMode
                          // when we are the local server.  For recoveryOnlyMode we call recoveryComplete once we
                          // have fully completed recovery as this is a indication to shutdown the server.
                          // For the other case of local recovery, recoveryComplete indicates that we are far enough
                          // through recovery to allow further HA recovery to be enabled by joining their HA groups
                          // if everything was successful or shutdown the server if anything failed.
                          // For peer recovery we only call recoveryComplete once we have stopped any recovery action
                          // as this is used as a "lock" to wait on failback log tidy up.
                          // So this does not indicate that recovery has completed...
                          recoveryComplete();
                          callRecoveryComplete = false;
                      }
  
                      // Not yet completed recovery - wait a while and retry again
                      // Retry xa resources until complete... Note: we check txn retries in TransactionImpl
                      // and if they "timeout" they will get removed from _recoveringTransactions.
                      retryAttempts++;
  
                      // Extend the retry interval the same as for a normal transaction...
                      if (retryAttempts % 10 == 0 && retryWait < Integer.MAX_VALUE / 2) {
                          retryWait *= 2;
                      }
  
                      synchronized (_recoveryMonitor) {
                          long timeout = retryWait * 1000L;
                          long startTime = System.currentTimeMillis();
                          long startTimeout = timeout;
  
                          while (!_shutdownInProgress) {
                              try {
                                  if (tc.isDebugEnabled())
                                      Tr.debug(tc, "Resync retry in " + timeout + " milliseconds");
                                  _recoveryMonitor.wait(timeout);
                              } catch (InterruptedException e) {
                                  // No FFDC Code Needed.
                                  if (tc.isDebugEnabled())
                                      Tr.debug(tc, "Resync wait interrupted");
                              }
  
                              if (_shutdownInProgress) {
                                  break;
                              }
  
                              long elapsedTime = System.currentTimeMillis() - startTime;
                              if (elapsedTime < startTimeout) {
                                  timeout = startTimeout - elapsedTime;
                              } else {
                                  break;
                              }
                          }
                      }
  
                      stopProcessing = shutdownInProgress();
                  } else {
                      if (tc.isDebugEnabled())
                          Tr.debug(tc, "Resync completed");
                      break;
                  }
              }
  
              if (stopProcessing) {
                  // stopProcessing is either the local server closing down or peer recovery being halted for a failurescope.
                  if (_failureScopeController.localFailureScope()) {
                      if (tc.isDebugEnabled())
                          Tr.debug(tc, "local failure scope resync interupted");
                      // FailureScopeController.shutdown() closes the logs
                  } else {
                      if (tc.isDebugEnabled())
                          Tr.debug(tc, "Non-local failure scope resync interupted");
                      // FailureScopeController.shutdown() does the tidy up and closes the logs
                      // Don't bother checking that we have no recovering transactions and XArecovered
                      // since recoveryComplete has already been called so we'd need extra synchronization
                      // with the shutdown thread.
                  }
              }
              // If we have completed resync normally, take this opportunity to clean out the partner log
              // if all the trans have completed
              else if (XArecovered && (_recoveringTransactions.size() == 0)) {
                  // NOTE TO REVIEWERS - should we close the logs here or in shutdown?
                  // shutdown is always called.  We should not remove the RM from _activeRecoveryManagers
                  // until shutdown as we may recieve commit/rollback for completed transactions.
  
                  // NOTE it is NOT possible that shutdown is racing us to close the logs - it will be waiting in prepareToShutdown
                  if (tc.isDebugEnabled())
                      Tr.debug(tc, "Clearing any unused partners from partner log");
  
                  if (!_failureScopeController.localFailureScope()) {
                      // flag the RM as cleanRemoteShutdown - this stops a shutdown thread trying to close the logs too
                      // on the off chance that it is also running.
                      _cleanRemoteShutdown = true;
                      // Even though we think we have recovered everything, we need to
                      // check that there are no partners left because of some bad internal failure
                      // which may allow us to now corrupt the logs
                      // @D656080 - dont clean up logs for HA cases - if we have completed
                      // recovery the transactions will be marked complete. We will perform a
                      // XARM recovery on the next restart and clean up the partners at this point...
                      try /* @PK31789A */
                      { /* @PK31789A */
                          // preShutdown will ensure that the tranlog is forced.        @PK31789A
  
                          preShutdown(true); /* @D656080C */
                      } /* @PK31789A */
                      catch (Exception e) /* @PK31789A */
                      { /* @PK31789A */
                          // no FFDC required.                                          @PK31789A
                      } /* @PK31789A */
  
                      postShutdown(true); // Close the partner log
                  } else /* @PK31789A */
                  { /* @PK31789A */
                      // Ensure all end-tran records processed before we delete partners
                      boolean failed = false; /* @PK31789A */
                      if ((_tranLog != null) && (_tranLog instanceof DistributedRecoveryLog)) /* @PK31789A */
                      { /* @PK31789A */
                          try /* @PK31789A */
                          {
                              // keypoint will ensure that the tranlog is forced.       @PK31789A
                              // If there are any exceptions, then it is not safe to    @PK31789A
                              // tidy up the partnerlog (clearUnused skipped).          @PK31789A
  
                              ((DistributedRecoveryLog) _tranLog).keypoint(); /* @PK31789A */
                          } /* @PK31789A */
                          catch (Exception exc2) /* @PK31789A */
                          { /* @PK31789A */
                              FFDCFilter.processException(exc2, "com.ibm.tx.jta.impl.RecoveryManager.resync", "1974", this); /* @PK31789A */
                              if (tc.isDebugEnabled())
                                  Tr.debug(tc, "keypoint of transaction log failed ... partner log will not be tidied", exc2); /* @PK31789A */
  
                              failed = true; /* @PK31789A */
                          } /* @PK31789A */
                      } /* @PK31789A */
  
                      if (!failed) /* @PK31789A */
                      {
                          getPartnerLogTable().clearUnused(); /* @PK31789A */
                          if (auditRecovery)
                              Tr.audit(tc, "WTRN0133_RECOVERY_COMPLETE");
                      }
                  } /* @PK31789A */
  
                  if (callRecoveryComplete)
                      recoveryComplete();
              } else {
                  // Should only get here if we are in recoveryOnlyMode for local server.
                  if (tc.isDebugEnabled())
                      Tr.debug(tc, "Transactions were active. Not clearing any unused partners from partner log");
                  if (callRecoveryComplete)
                      recoveryComplete();
              }
          } catch (RuntimeException r) {
              FFDCFilter.processException(r, "com.ibm.tx.jta.impl.RecoveryManager.resync", "1729", this);
              resyncComplete(r);
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "resync", r);
              throw r;
          }
  
          resyncComplete(null);
  
          if (tc.isEntryEnabled())
              Tr.exit(tc, "resync");
      }