docs: private final void setState(int newAction, boolean validateOnly) throws TransactionException {
          final String methodName = "setState";
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
  
          if (isTraceOn && tc.isEntryEnabled()) 
              Tr.entry(this, tc, methodName, getStateAsString());
  
          switch (newAction) {
          // Allow only NO_TRANSACTION_ACTIVE -> GLOBAL_TRANSACTION_ACTIVE
              case XA_START:
                  if (transtate == NO_TRANSACTION_ACTIVE) {
                      if (validateOnly) {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(this, tc, methodName);
                          return;
                      }
                      transtate = GLOBAL_TRANSACTION_ACTIVE;
                  } else {
                      TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], true); 
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(this, tc, methodName, txe);
                      throw txe;
                  }
                  break;
  
              // Allow only GLOBAL_TRANSACTION_ACTIVE -> TRANSACTION_ENDING
              case XA_END:
                  if (transtate == GLOBAL_TRANSACTION_ACTIVE) {
                      if (validateOnly) {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(this, tc, methodName);
                          return;
                      }
  
                      transtate = TRANSACTION_ENDING;
                  } else {
                      TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], true); 
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(this, tc, methodName, txe);
                      throw txe;
                  }
                  break;
  
              // Allow only GLOBAL_TRANSACTION_ACTIVE -> TRANSACTION_ENDING
              case XA_END_FAIL:
                  if (transtate == GLOBAL_TRANSACTION_ACTIVE || transtate == TRANSACTION_ENDING) {
                      if (validateOnly) {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(this, tc, methodName);
                          return;
                      }
  
                      transtate = TRANSACTION_FAIL;
                  } else {
                      TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], true); 
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(this, tc, methodName, txe);
                      throw txe;
                  }
                  break;
  
              // Allow only TRANSACTION_ENDING-->NO_TRANSACTION_ACTIVE
              case XA_COMMIT:
              case XA_READONLY: 
                  if (transtate == TRANSACTION_ENDING || transtate == RECOVERY_IN_PROGRESS) {
                      if (validateOnly) {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(this, tc, methodName);
                          return;
                      }
  
                      transtate = NO_TRANSACTION_ACTIVE;
                  } else {
                      TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], true); 
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(this, tc, methodName, txe);
                      throw txe;
                  }
                  break;
  
              // Allow only TRANSACTION_ENDING-->NO_TRANSACTION_ACTIVE
              case XA_ROLLBACK:
                  if (transtate == TRANSACTION_ENDING || transtate == TRANSACTION_FAIL || transtate == RECOVERY_IN_PROGRESS) {
                      if (validateOnly) {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(this, tc, methodName);
                          return;
                      }
                      // In the event of a TRANSACTION_FAIL
                      // we dont want other threads to use this transaction until mc
                      // cleanup occurs
                      // so we keep this TX dirty i.e. in TRANSACTION_FAIL state.
                      if (transtate == TRANSACTION_ENDING || transtate == RECOVERY_IN_PROGRESS) {
                          transtate = NO_TRANSACTION_ACTIVE;
                      }
  
                  } else {
                      TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], true); 
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(this, tc, methodName, txe);
                      throw txe;
                  }
                  break;
  
              // Set the state to RECOVERY_IN_PROGRESS no matter what the starting
              // state was.
              case XA_RECOVER:
                  transtate = RECOVERY_IN_PROGRESS; 
                  break;
  
              // Send to NO_TRANSACTION_ACTIVE no matter what the starting state was.
              // This is the only time we can clean up our state for XA.
              // Even tho the DB would be in a rational state we would be in an in
              // inconsistent state.
              // so let us reset to NO_TRANSACTION_ACTIVE
              case XA_FORGET:
                  transtate = NO_TRANSACTION_ACTIVE;
                  break;
  
              // LT.BEGIN: only allow NO_TRANSACTION_ACTIVE ->
              // LOCAL_TRANSACTION_ACTIVE
              case LT_BEGIN:
                  if (transtate == NO_TRANSACTION_ACTIVE) {
                      if (validateOnly) {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(this, tc, methodName);
                          return;
                      }
                      transtate = LOCAL_TRANSACTION_ACTIVE;
                  } else {
                      TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], true); 
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(this, tc, methodName, txe);
                      throw txe;
                  }
                  break;
  
              // Allow only Local_Transaction_active -> NO_TRANSACTION_Active
              case LT_COMMIT:
              case LT_ROLLBACK:
                  if (transtate == LOCAL_TRANSACTION_ACTIVE) {
                      if (validateOnly) {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(this, tc, methodName);
                          return;
                      }
  
                      transtate = NO_TRANSACTION_ACTIVE;
                  } else {
                      TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], false); 
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(this, tc, methodName, txe);
                      throw txe;
                  }
                  break;
  
              // Allow only in transaction_active
              case EXECUTE:
                  if ((transtate == LOCAL_TRANSACTION_ACTIVE) || (transtate == GLOBAL_TRANSACTION_ACTIVE)) {
                      if (validateOnly) {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(this, tc, methodName);
                          return;
                      }
                  } else {
                      TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], true); 
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(this, tc, methodName, txe);
                      throw txe;
                  }
                  break;
  
              // CLEANUP - always set to NO_TRANSACTION_ACTIVE
              case MC_CLEANUP:
                  transtate = NO_TRANSACTION_ACTIVE;
                  break;
  
              // Send to TRANSACTION_HEURISTIC_END no matter what the starting state
              // was.
              case HEURISTIC_END:
                  transtate = TRANSACTION_HEURISTIC_END;
                  break;
  
              default:
                  TransactionException txe = new TransactionException(actions[newAction], transactions[transtate], true); 
                  if (isTraceOn && tc.isEntryEnabled())
                      Tr.exit(this, tc, methodName, txe);
                  throw txe;
          };
  
          if (isTraceOn && tc.isEntryEnabled()) 
              Tr.exit(this, tc, methodName, getStateAsString());
      }