docs: private EJBException mapCSIException(CSIException ex,
                                           Exception causeEx,
                                           Throwable cause)
      {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.entry(tc, "mapCSIException: " + ex + ", cause = " + cause);
  
          EJBException ejbex;
          boolean createdEx = true;
  
          // -----------------------------------------------------------------------
          // First, obtain the message text used to create the CSIException.
          //
          // CSIException is a RemoteException, which contains a 'detail' field
          // that holds the 'cause', instead of the normal cause defined by
          // Throwable.  When detail is set, getMessage() will include the text
          // and stack of the detail, which ends up duplicating the message text.
          // To avoid this, 'detail' is cleared, resulting in getMessage()
          // returning only the message text specified when the CSIException was
          // created.
          //
          // Also, toString() must be avoided, as it would include the name of
          // the CSIException in the message text.
          // -----------------------------------------------------------------------
          String message = ExceptionUtil.getBaseMessage(ex);
  
          // -----------------------------------------------------------------------
          // Second, map the CSIException to its corresponding EJBException.
          //
          // If there isn't a specific/corresponding EJBException, then either
          // the cause will be returned (if it is an EJBException), or a plain
          // EJBException will be created with the nested cause.
          // -----------------------------------------------------------------------
          if (ex instanceof CSITransactionRolledbackException)
          {
              ejbex = new EJBTransactionRolledbackException(message, causeEx); // d396839
          }
          else if (ex instanceof CSIAccessException)
          {
              ejbex = new EJBAccessException(message); // d396839
          }
          else if (ex instanceof CSIInvalidTransactionException)
          {
              ejbex = new InvalidTransactionLocalException(message, causeEx);
          }
          else if (ex instanceof CSINoSuchObjectException)
          {
              ejbex = new NoSuchEJBException(message, causeEx);
          }
          else if (ex instanceof CSITransactionRequiredException)
          {
              ejbex = new EJBTransactionRequiredException(message); // d396839
          }
          //        else if (ex instanceof CSIInvalidActivityException)
  //        {
  //            ejbex = new InvalidActivityLocalException(message, causeEx);
  //        }
  //        else if (ex instanceof CSIActivityRequiredException)
  //        {
  //            ejbex = new ActivityRequiredLocalException(message, causeEx);
  //        }
  //        else if (ex instanceof CSIActivityCompletedException)
  //        {
  //            ejbex = new ActivityCompletedLocalException(message, causeEx);
  //        }
          else
          {
              // This will just return the cause, if it is already an EJBException,
              // and will otherwise create a new EJBException and take care of
              // setting the cause on Throwable and the stack.
              ejbex = ExceptionUtil.EJBException(message, causeEx);
  
              // If there was a cause, then either a new EJBException was not
              // created, or the cause and stack have already been filled in.
              if (causeEx != null)
                  createdEx = false;
          }
  
          // -----------------------------------------------------------------------
          // Finally, set the EJBException stack to something meaningful.
          //
          // If the returned EJBException was created in this mapping code, then
          // the exception stack pointing at this code is generally misleading,
          // and for sure not helpful.... and may cause very similar stacks to be
          // printed out / logged twice.
          //
          // If the EJBException is just 'replacing' a CSIException, with no
          // real 'cause', then set the stack to that of the CSIException that
          // is being replaced, so at least we know which EJB Container code
          // decided an exception was necessary.
          //
          // If the EJBException does have a 'root/cause', then just clear
          // the exception stack, so debug efforts will focus on the cause
          // of the problem, and not EJB Container's reporting of it.
          //
          // And, since EJBException doesn't normally set the cause on
          // Throwable, let's do that to be nice :-)
          // -----------------------------------------------------------------------
          if (createdEx)
          {
              if (causeEx == null)
              {
                  ejbex.setStackTrace(ex.getStackTrace());
              }
              else
              {
                  // Geronimo EJBException.getCause returns getCausedbyException, so
                  // we do not expect this code to be used.                     F53643
                  if (ejbex.getCause() == null) { //F743-16279
                      // Use the 'real' cause here, not the possibly wrapped one.
                      ejbex.initCause(cause);
                  }
              }
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.exit(tc, "mapCSIException returning: " + ejbex);
  
          return ejbex;
      }