docs: public static Exception mapException(Exception x, WSJdbcConnection handle, Object mapper, boolean sendEvent) {
          if (tc.isEntryEnabled())
              Tr.entry(tc, "mapException", x.getClass().getName(), toString(handle), toString(mapper), sendEvent ? "EVENT" : "NO EVENT");
  
          WSRdbManagedConnectionImpl mc = mapper instanceof WSRdbManagedConnectionImpl ?
                          (WSRdbManagedConnectionImpl) mapper : null;
  
          WSManagedConnectionFactoryImpl mcf = mapper instanceof WSManagedConnectionFactoryImpl || mc == null ?
                          (WSManagedConnectionFactoryImpl) mapper : mc.getManagedConnectionFactory();
  
          DatabaseHelper iHelper = mcf == null ? null : mcf.getHelper();
  
          DataStoreAdapterException dsae = x instanceof DataStoreAdapterException ?
                          (DataStoreAdapterException) x : null;
  
          SecurityException securityX = null;
  
          SQLException sqlX =
                          x instanceof SQLException ? (SQLException) x :
                                          dsae != null && dsae.getCause() instanceof SQLException ? (SQLException) dsae.getCause() :
                                                          null;
  
          boolean isStaleStatement = false;
          boolean mapsToStaleConnection = false;
  
          if (mcf != null // must have access to helper
              && sqlX != null // need an exception to map
              && (dsae == null || !dsae.beenMapped())) // not already mapped 
          {
              mapsToStaleConnection = iHelper.isConnectionError(sqlX);
  
              if (tc.isDebugEnabled())
                  Tr.debug(tc, "stale? " + mapsToStaleConnection + "; original exception is:", getStackTraceWithState(sqlX));
  
              // Check for stale statement
  
              if (iHelper.isStaleStatement(sqlX)) {
                  isStaleStatement = true;
                  if (handle == null) {
                      if (mc != null)
                          mc.clearStatementCache();
                  } else
                      WSJdbcUtil.handleStaleStatement(handle);
              }
          }
  
          SQLException mappedX = sqlX;
  
          // For DB2, SQLTransientConnectionException with error code -4498 is actually
          // a recoverable exception. Switch it to SQLRecoverableException. 
          if (mappedX instanceof SQLTransientConnectionException
              && iHelper != null && iHelper.failoverOccurred(sqlX)) {
              // Before:  transientX n--> nextX
              // After:   recoverX   n--> nextX
              //                     c--> transientX n--> nextX
  
              SQLException nextX = mappedX.getNextException();
              mappedX = new SQLRecoverableException(
                              mappedX.getMessage(), mappedX.getSQLState(), mappedX.getErrorCode(), mappedX);
              mappedX.setNextException(nextX);
          }
  
          // Check for authentication errors with DB2 trusted context.
          boolean isAuthenticationError = mcf != null && iHelper.isAnAuthorizationException(mappedX);
  
          // Look for fatal connection errors.
          // SQLRecoverableException and SQLNonTransientConnectionException indicate
          // bad connections.  SQLTransientConnectionException indicates a temporary
          // error that might disappear if the same operation is retried, even without
          // starting a new transaction.
  
          if ((sqlX instanceof SQLRecoverableException
               || sqlX instanceof SQLNonTransientConnectionException
               || isAuthenticationError
               || mapsToStaleConnection) 
              && !isStaleStatement) // it's a statement error, not a connection error
          {
              if (tc.isDebugEnabled())
                  Tr.debug(tc, isAuthenticationError ?
                                  "Detected an authentication error" :
                                  "Detected a connection error.");
  
              if (dsae != null && isAuthenticationError)
                  securityX = new SecurityException(dsae.getMessage(), mappedX);
  
              if (sendEvent && (dsae == null || !dsae.beenMapped())) {
                  if (handle != null)
                      handle.fireConnectionErrorEvent(sqlX, true);
  
                  else if (mc != null)
                      mc.processConnectionErrorOccurredEvent(null, sqlX);
              }
          }
  
          // Regardless of whether we actually found an exception to map to, mark the
          // DataStoreAdapterException as having already been through the mapping process.
  
          if (dsae != null)
              dsae.setBeenMapped();
  
          Exception result =
                          securityX != null ? securityX :
                                          dsae != null ? dsae :
                                                          mappedX != null ? mappedX :
                                                                          x;
          if (tc.isEntryEnabled())
              Tr.exit(tc, "mapException", (mappedX == null ? x : mappedX).getClass().getName());
  
          return result;
      }