docs: public synchronized Vote prepare() throws SystemException, HeuristicMixedException, HeuristicHazardException, RollbackException
      {
          if (tc.isEntryEnabled())
              Tr.entry(tc, "prepare", this);
  
          Vote result = Vote.VoteRollback;
  
          // If there is no associated transaction, raise an execption which should
          // cause the superior transaction to be rolled back.  We should only lose
          // the transaction if we do a destroy, eg on a rollback, or previous prepare
          // vote, etc. in which case we should never be calling prepare again.
          if (_transaction == null)
          {
              final SystemException se = new SystemException(MinorCode.NO_COORDINATOR);
  
              FFDCFilter.processException(se, "com.ibm.tx.remote.TransactionWrapper.prepare", "157", this);
              Tr.error(tc, "WTRN0001_ERR_INT_ERROR", new Object[] { "prepare", "com.ibm.ws.Transaction.JTS.TransactionWrapper" });
              destroy();
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "prepare", se);
              throw se;
          }
  
          // Ensure timeout cannot rollback the underlying transaction
          ((DistributableTransaction) _transaction).addAssociation();
  
          if (_transaction.getTransactionState().getState() == TransactionState.STATE_ACTIVE) {
              try {
                  // Resume the transaction created from the incoming
                  // request so that it is installed on the thread.
                  ((EmbeddableTranManagerSet) TransactionManagerFactory.getTransactionManager()).resume(_transaction);
  
                  // Get the TransactionImpl's vote.
                  // If the TransactionImpl throws HeuristicMixed, then rethrow.
                  // internalPrepare checks the tx state
                  final int state = _transaction.internalPrepare();
                  switch (state) {
                      case TransactionState.STATE_PREPARED:
                          // Start the in-doubt timer in case we never get a commit/rollback
                          EmbeddableTimeoutManager.setTimeout(_transaction, EmbeddableTimeoutManager.IN_DOUBT_TIMEOUT, _retryWait);
                          result = Vote.VoteCommit;
                          break;
                      case TransactionState.STATE_ROLLED_BACK: // one phase opt
                          result = Vote.VoteRollback;
                          _transaction.notifyCompletion();
                          break;
                      case TransactionState.STATE_COMMITTED:
                          result = Vote.VoteReadOnly;
                          _transaction.notifyCompletion();
                          break;
                      // If the TransactionImpl has voted to roll the transaction back, then this
                      // CoordinatorResourceImpl will not be called again.  Ensure that the
                      // TransactionImpl has rolled back.
                      case TransactionState.STATE_ROLLING_BACK:
                      default:
                          _transaction.internalRollback();
                          result = Vote.VoteRollback;
                          _transaction.notifyCompletion();
                          break;
                  }
              } catch (HeuristicMixedException hme) {
                  // No FFDC code needed.
                  // This exception should not be raised by internalPrepare for a subordinate
                  // but may be raised by internalRollback 
  
                  // must rollback any prepared resources ...
                  try {
                      _transaction.internalRollback();
                  } catch (Throwable t) {
                      FFDCFilter.processException(t, "com.ibm.tx.remote.TransactionWrapper.prepare", "228", this);
                      // swallow any exceptions ...
                  }
  
                  ((DistributableTransaction) _transaction).removeAssociation();
  
                  final HeuristicMixedException hm = new HeuristicMixedException();
                  if (tc.isEntryEnabled())
                      Tr.exit(tc, "prepare", hm);
                  throw hm;
              } catch (HeuristicHazardException hhe) {
                  // No FFDC code needed.
                  // This exception should not be raised by internalPrepare for a subordinate
                  // but may be raised by internalRollback 
  
                  // must rollback any prepared resources ...
                  try {
                      _transaction.internalRollback();
                  } catch (Throwable t) {
                      FFDCFilter.processException(t, "com.ibm.tx.remote.TransactionWrapper.prepare", "250", this);
                      // swallow any exceptions ...
                  }
  
                  ((DistributableTransaction) _transaction).removeAssociation();
  
                  final HeuristicHazardException hh = new HeuristicHazardException();
                  if (tc.isEntryEnabled())
                      Tr.exit(tc, "prepare", hh);
                  throw hh;
              } catch (Throwable t) { // IllegalState or javax.transaction.SystemException
                  FFDCFilter.processException(t, "com.ibm.tx.remote.TransactionWrapper.prepare", "241", this);
                  result = Vote.VoteRollback;
                  _transaction.notifyCompletion();
              } finally {
                  // suspend any context that is still on the thread
                  // NB we may have called notifyCompletion at this point,
                  // and suspend calls notifyUOWCallbacks, so if the tx is
                  // still on the thread, there could be a problem.
                  ((EmbeddableTranManagerSet) TransactionManagerFactory.getTransactionManager()).suspend();
              }
          } else { // probably timed out
              result = Vote.VoteRollback;
          }
  
          ((DistributableTransaction) _transaction).removeAssociation();
  
          if (tc.isEntryEnabled())
              Tr.exit(tc, "prepare", result);
          return result;
      }