docs: @Override
      public final synchronized boolean enlist(ContainerTx tx, boolean txEnlist) // d114677
      throws RemoteException
      {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
          if (isTraceOn && tc.isEntryEnabled())
              Tr.entry(tc, "enlist: " + getStateName(state), new Object[] { tx, txEnlist });
  
          switch (state)
          {
              case METHOD_READY:
                  // A thread is about to invoke a method in the context
                  // of the given transaction
  
                  if (currentTx != null) {
                      throw new BeanNotReentrantException(getStateName(state) + ": Tx != null"); //PQ99986
                  }
  
                  if (ivExPcContext != null && tx.isTransactionGlobal()) {
                      container.getEJBRuntime().getEJBJPAContainer().onEnlistCMT(ivExPcContext);
                  }
  
                  currentTx = tx;
                  final boolean result = !txEnlist || tx.enlist(this); // F61004.1
  
                  // Session Synchronization AfterBegin needs to be called if either
                  // the annotation (or XML) was specified or the bean implemented
                  // the interface and a global transaction is active.        F743-25855
                  if ((ivAfterBegin != null || sessionSync != null) &&
                      tx.isTransactionGlobal())
                  {
                      setState(AFTER_BEGIN); // d159152
                      if (ivAfterBegin != null) {
                          invokeSessionSynchMethod(ivAfterBegin, null);
                      } else {
                          sessionSync.afterBegin();
                      }
                  }
  
                  setState(TX_METHOD_READY);
  
                  if (isTraceOn && tc.isEntryEnabled())
                      Tr.exit(tc, "enlist: " + result + ": " + getStateName(state));
  
                  return result;
  
              case TX_METHOD_READY:
                  // A thread is about to invoke a method in the context of
                  // the given transaction; it must be the same transaction
                  // which we're already associated with
  
                  if (currentTx != tx) {
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(tc, "enlist: not re-entrant");
                      throw new BeanNotReentrantException(StateStrs[state] +
                                                          ": wrong transaction"); // d116807
                  }
  
                  if (isTraceOn && tc.isEntryEnabled())
                      Tr.exit(tc, "enlist: false");
                  return false;
  
              case COMMITTING_OUTSIDE_METHOD:
                  // Either another thread is currently committing this bean (PQ52534),
                  // or current thread is re-enlisting this bean after beforeCompletion
                  // has been driven on it (i.e. another bean has called a method
                  // on this bean during beforeCompletion processing) (d115597).
  
                  if (currentTx != tx) { // PQ52534
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(tc, "enlist: not re-entrant");
                      throw new BeanNotReentrantException(StateStrs[state] +
                                                          ": wrong transaction"); // d116807
                  }
  
                  // Although already enlisted, need to call enlist again to make sure
                  // it gets added to the end of the list, and processed again.  d115597
                  boolean result1 = tx.enlist(this);
                  setState(TX_METHOD_READY);
  
                  if (isTraceOn && tc.isEntryEnabled())
                      Tr.exit(tc, "enlist: " + result1 + ": " + getStateName(state));
                  return result1;
  
              case TX_IN_METHOD:
              case REMOVING: // d159152
              case AFTER_BEGIN: // d159152
              case AFTER_COMPLETION: // d159152
                  // This bean is already in a transaction - and any of these states
                  // could be seen by a different transaction calling a method on it,
                  // or they could also be due to a customer coded callback to the same
                  // bean.
                  if (isTraceOn && tc.isEntryEnabled())
                      Tr.exit(tc, "enlist: not re-entrant");
                  if (currentTx != tx)
                      throw new BeanNotReentrantException(StateStrs[state] +
                                                          ": wrong transaction");
  
                  // This isn't a different thread/tran, but it is a reentrant call,
                  // which must be caught here rather than preInvoke to insure the
                  // extra cache pins are undone in the activation strategy.     d159152
                  throw new BeanNotReentrantException(getStateName(state));
  
              default:
                  // Any other state is a programming error... there should be no
                  // way to encounter these states even from another thread/transaction.
                  throw new InvalidBeanOStateException(getStateName(state),
                                  "METHOD_READY | TX_METHOD_READY");
  
          }
      }