docs: @Override
      public void beforeCompletion()
      {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled(); // d532639.2
  
          if (isTraceOn) // d527372
          {
              if (tc.isEntryEnabled())
                  Tr.entry(tc, "beforeCompletion",
                           new Object[]
                           { Boolean.valueOf(globalTransaction),
                            this,
                            Boolean.valueOf(isActivitySessionCompleting) });
  
              if (TETxLifeCycleInfo.isTraceEnabled()) // PQ74774
              { // PQ74774
                  String tid = getTxId();
                  if (tid != null)
                  {
                      if (globalTransaction)
                      {
                          TETxLifeCycleInfo.traceGlobalTxBeforeCompletion
                                          (tid, "Global/User Tx BeforeCompletion");
                      } else
                      {
                          TETxLifeCycleInfo.traceLocalTxBeforeCompletion
                                          (tid, "Local Tx BeforeCompletion");
                      }
                  }
              } // PQ74774
          }
  
          //d139562.11
          if (finderSyncList != null) // d173022.12
          { // d173022.12
              int numberofCallers = finderSyncList.size();
              for (int i = 0; i < numberofCallers; ++i) {
                  finderSyncList.get(i).beforeCompletion();
              }
          } // d173022.12
  
          if (ivBeanOsEnlistedInTx)
          {
              //d173022.2
              origLock = true;//d115597 set the origLock flag to true because beforeCompletion entered
  
              EJBThreadData threadData = EJSContainer.getThreadData(); // d630940
              BeanO beanO = null;
              boolean popCallbackBeanO = false;
              ComponentMetaData prevCMD = null;
              boolean resetCMD = false;
              ClassLoader prevClassLoader = null;
              Object origClassLoader = ThreadContextAccessor.UNCHANGED;
  
              try
              {
                  // Process beans in a loop to allow beforeCompletion callbacks to
                  // enlist additional beans.  We limit the number of iterations to
                  // detect infinite loops.                                      d115597
                  int iterationCount = 0;
                  for (ArrayList<BeanO> iterationBeanOs = beanOList; iterationBeanOs != null; iterationBeanOs = tempList, tempList = null)
                  {
                      if (iterationCount++ > MAX_ENLISTMENT_ITERATIONS)
                      {
                          beanO = null;
                          throw new RuntimeException("Exceeded " + MAX_ENLISTMENT_ITERATIONS + " enlistment iterations in beforeCompletion");
                      }
  
                      //--------------------------------------------------------------
                      // d115597
                      // Imposes an order in which the beforeCompletion callbacks
                      // will be fired on the beans.
                      // beforeCompletion is called on beans in the order they were
                      // enlisted.  This is true for beans enlisted after beforeCompletion
                      // has begun as well.
                      // d115597
                      //--------------------------------------------------------------
  
                      for (int i = 0, size = iterationBeanOs.size(); i < size; i++)
                      {
                          beanO = iterationBeanOs.get(i);
                          BeanMetaData bmd = beanO.home.beanMetaData;
  
                          // Process all beans if the activity session is completing.
                          // Only process entity beans if this is a checkpoint.
                          //
                          // d126930.3
                          // By default isActivitySessionCompleting is set to true even if there
                          // is no activitySession present.  This simply means we follow the normal
                          // ContainerTx logic for ending a transaction.
                          if (isActivitySessionCompleting || bmd.isEntityBean())
                          {
                              // Update the thread callback bean.
                              threadData.pushCallbackBeanO(beanO); // d168509, d630940
                              popCallbackBeanO = true;
  
                              // Update the thread CMD if it's not the same as the
                              // previous bean.
                              if (bmd != prevCMD)
                              {
                                  if (resetCMD)
                                  {
                                      cmdAccessor.endContext();
                                  }
  
                                  cmdAccessor.beginContext(bmd);
                                  prevCMD = bmd;
                                  resetCMD = true;
  
                                  // Update the class loader if it's not the same as the
                                  // previous bean.                         PK51366, PK83186
                                  ClassLoader classLoader = bmd.ivContextClassLoader; // F85059
                                  if (classLoader != prevClassLoader)
                                  {
                                      prevClassLoader = classLoader;
                                      origClassLoader = EJBThreadData.svThreadContextAccessor.repushContextClassLoaderForUnprivileged(origClassLoader, classLoader);
                                  }
                              }
  
                              // d126930.3
                              // EJB 2.0 beans may have sticky local transactions (i.e.
                              // local tx boundary = ActivitySession).  We need to assure
                              // the correct ComponentMetaData and local tx context is
                              // on thread in this case.  Note that EJB 1.1 beans may not
                              // have local tx boundary = ActivitySession.  This is enforced
                              // by a check in BeanMetaData
                              if (isActivitySessionCompleting &&
                                  (globalTransaction ||
                                  bmd._localTran.getBoundary() == LocalTransactionSettings.BOUNDARY_ACTIVITY_SESSION))
                              {
                                  beanO.beforeCompletion();
                              }
                              else
                              {
                                  TxContextChange changedContext = uowCtrl.setupLocalTxContext(beanO.getId());
                                  try
                                  {
                                      if (isActivitySessionCompleting)
                                      {
                                          beanO.beforeCompletion();
                                      }
                                      else
                                      {
                                          //-------------------------------------------------------------
                                          // Special case added for mid-activitySession checkpoint.
                                          // Entity beans enlisted in local transactions must be stored
                                          // to flush any in-memory updates out to the backing store
                                          // (ie. checkpoint them).  For other bean types, we do
                                          // nothing on mid-activitySession checkpoint.  The local
                                          // transaction service will make setCompleting = false calls to
                                          // the containerSynchronization interface at checkpoint.  Also,
                                          // beforeCompletion and afterCompletion will be called.  We
                                          // have special code both here, and in afterCompletion, so that
                                          // the beans' states do not change.  We just store them.
                                          // ------------------------------------------------------------
                                          beanO.store();
                                      }
                                  } finally
                                  {
                                      uowCtrl.teardownLocalTxContext(changedContext);
                                  }
                              }
  
                              popCallbackBeanO = false;
                              threadData.popCallbackBeanO();
                          }
                      }
                  }
              } catch (Throwable t)
              {
  
                  FFDCFilter.processException(t, CLASS_NAME + ".beforeCompletion",
                                              "562", this);
                  if (isTraceOn && tc.isEventEnabled()) // d144064
                      Tr.event(tc, "Exception during beforeCompletion(): rolling back",
                               new Object[] { beanO, t });
  
                  // Destroy the beanO, too late to delist. Destroying it should
                  // take care of the state when the transaction is rolled back.
                  // Note there may not be a beanO, if the exception is container
                  // detecting a loop condition - not a bean exception.     d160910
                  if (beanO != null)
                      beanO.destroy();
  
                  ivContainer.uowCtrl.setRollbackOnly();
  
                  // Log the exception
                  ExceptionUtil.logException(tc, t, null, beanO);
  
                  // Save the first exception that occurs during commit
                  // processing to nest in TransactionRolledBackException.  PQ90221
                  if (ivPostProcessingException == null)
                      ivPostProcessingException = t;
  
                  // Inform the transaction manager that the beforeCompletion
                  // failed. Else, the tran engine might continue to fire
                  // beforeCompletion callbacks on other participants
                  throw new RuntimeException("", t); //253963
  
              } finally
              {
                  EJBThreadData.svThreadContextAccessor.popContextClassLoaderForUnprivileged(origClassLoader);
  
                  if (resetCMD)
                  {
                      cmdAccessor.endContext();
                  }
  
                  if (popCallbackBeanO)
                  {
                      threadData.popCallbackBeanO();
                  }
              }
          }
  
          if (isActivitySessionCompleting)
          {
              //--------------------------------------------------------------
              // The before completion callbacks on the beans may result
              // in more beans getting enlisted in this transaction, so we don't
              // change the state to PREPARING until all beans are prepared.
              //--------------------------------------------------------------
              becomePreparing();
          }
  
          // Now that all of the beans have been successfully stored, call
          // before completion on the PM transaction listener.           d134692
          if (txListener != null) {
              try {
                  if (isTraceOn && tc.isDebugEnabled()) // d144064
                      Tr.debug(tc, "Calling txListener.beforeCompletion()");
                  txListener.beforeCompletion();
              } catch (Throwable e) {
                  FFDCFilter.processException(e, CLASS_NAME + ".beforeCompletion",
                                              "734", this);
  
                  if (ivPostProcessingException == null) { //253963
                      ivPostProcessingException = e; //253963
                  }
                  throw new RuntimeException("txListener exception" + e.toString());
              }
          }
  
          if (isTraceOn && tc.isEntryEnabled())
              Tr.exit(tc, "beforeCompletion"); // d144064
  
      }