docs: public static Class<?>[] getCheckedExceptions(Method method,
                                                    boolean isRmiRemote,
                                                    DeploymentTarget target,
                                                    EJBWrapperType wrapperType,
                                                    boolean declaredUncheckedAreSystemExceptions,
                                                    boolean declaredRemoteAreApplicationExceptions)
                      throws EJBConfigurationException
      {
          boolean throwsRemoteException = false;
          Class<?>[] exceptions = method.getExceptionTypes();
          int numExceptions = exceptions.length;
          ArrayList<Class<?>> checkedExceptions = new ArrayList<Class<?>>(numExceptions);
  
          for (Class<?> exception : exceptions)
          {
              // --------------------------------------------------------------------
              // Only Remote interfaces that implement java.rmi.Remote may throw
              // java.rmi.RemoteException.
              // --------------------------------------------------------------------
              if (exception == RemoteException.class)
              {
                  if (!isRmiRemote)
                  {
                      // This is only a warning since the spec says 'should' and not
                      // must... but let them know it is a bad idea.            d450525
                      Tr.warning(tc, "JIT_INVALID_THROW_REMOTE_CNTR5101W",
                                 new Object[] { method.getName(),
                                               method.getDeclaringClass().getName() });
                  }
                  throwsRemoteException = true;
                  continue; // skip - remote allowed, but not 'checked' exception
              }
  
              // --------------------------------------------------------------------
              // Application exceptions must not subclass RemoteException.
              // --------------------------------------------------------------------
              else if ((RemoteException.class).isAssignableFrom(exception))
              {
                  // Tolerate for stubs since the server EJB might allow.    RTC116527
                  if (target == DeploymentTarget.STUB)
                  {
                      // Keep the exception.
                  }
                  // For tie/wrapper, only allow if a custom property is specified and
                  // only then for business interfaces.                      RTC116527
                  else if (declaredRemoteAreApplicationExceptions &&
                           (wrapperType == null ||
                            wrapperType == EJBWrapperType.BUSINESS_REMOTE ||
                           wrapperType == EJBWrapperType.BUSINESS_LOCAL))
                  {
                      // Keep the exception.
                  }
                  else
                  {
                      // Log the error and throw meaningful exception.             d450525
                      String className = method.getDeclaringClass().getName();
                      Tr.error(tc, "JIT_INVALID_SUBCLASS_REMOTE_EX_CNTR5102E",
                               new Object[] { exception.getName(),
                                             method.getName(),
                                             className });
                      throw new EJBConfigurationException("Application exception " + exception.getName() +
                                                          " defined on method " + method.getName() + " of interface " +
                                                          className + " must not subclass java.rmi.RemoteException.");
                  }
              }
  
              // --------------------------------------------------------------------
              // Per the spec, unchecked exceptions (RuntimeException and Error)
              // should not be considered application.  They are also ignored by
              // rmic when generating stubs and ties.                         d660332
              // --------------------------------------------------------------------
              else if (RuntimeException.class.isAssignableFrom(exception) ||
                       Error.class.isAssignableFrom(exception)) // 651626.1
              {
                  // For stubs, we keep unchecked exceptions so that they can handle
                  // IDL strings from ties generated by previous releases where
                  // unchecked exceptions were not filtered.
                  if (target == DeploymentTarget.STUB)
                  {
                      // Keep the exception.
                  }
                  // For wrappers, we keep unchecked exceptions if the user has
                  // indicated that unchecked exceptions should be considered
                  // application exceptions.
                  else if (target == DeploymentTarget.WRAPPER &&
                           !declaredUncheckedAreSystemExceptions)
                  {
                      // Keep the exception.
                  }
                  else
                  {
                      // Remove the exception.
                      continue;
                  }
              }
              else if (!Exception.class.isAssignableFrom(exception)) // d608631
              {
                  String className = method.getDeclaringClass().getName();
                  Tr.error(tc, "JIT_INVALID_NOT_EXCEPTION_SUBCLASS_CNTR5107E",
                           new Object[] { exception.getName(),
                                         method.getName(),
                                         className });
  
                  throw new EJBConfigurationException("The " + exception.getName() +
                                                      " application exception defined on the " + method.getName() +
                                                      " method of the " + className +
                                                      " class must be defined as a subclass of the java.lang.Exception class.");
              }
  
              // --------------------------------------------------------------------
              // Exception is a valid application exception... but it cannot just
              // be added to the end of the list, since it may be a subclass of
              // other exceptions on the throws clause, which could result in
              // 'unreachable' code when adding 'catch' blocks.
              //
              // Instead, do one of two things:
              // 1 - Remove any exceptions that are subclasses of other exceptions.
              //     This is useful when a catch block is being added for each
              //     checked exception, and the processing done in the parent
              //     exception would be the same as any subclasses.  For example,
              //     in a generated wrapper, catch blocks for all checked exceptions
              //     just call 'setCheckedException'... so no need to duplicate that
              //     for all subclass exceptions.
              // 2 - Insert the current exception ahead of the first exception
              //     already in the list that is a parent.  This eliminates the
              //     'unreachable' code problem, and also ends up with the
              //     exceptions in the original order if there are no subclasses.
              // --------------------------------------------------------------------
  
              if (target == DeploymentTarget.WRAPPER) // d660332
              {
                  // -----------------------------------------------------------------
                  // Remove any already added exceptions that are subclasses of the
                  // current exception.  Ignore the current exception if a superclass
                  // has already been added.                                 RTC116527
                  // -----------------------------------------------------------------
                  boolean add = true;
                  for (Iterator<Class<?>> iter = checkedExceptions.iterator(); iter.hasNext();)
                  {
                      Class<?> checkedEx = iter.next();
                      if (exception.isAssignableFrom(checkedEx))
                      {
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                              Tr.debug(tc, "getCheckedExceptions: ignoring " +
                                           checkedEx.getName() + ", subclass of " +
                                           exception.getName());
                          iter.remove();
                      }
                      else if (checkedEx.isAssignableFrom(exception))
                      {
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                              Tr.debug(tc, "getCheckedExceptions: ignoring " +
                                           exception.getName() + ", subclass of " +
                                           checkedEx.getName());
                          add = false;
                          break;
                      }
                  }
  
                  if (add)
                  {
                      checkedExceptions.add(exception);
                  }
              }
              else
              {
                  // -----------------------------------------------------------------
                  // Sort exceptions, so that subclasses are ahead of parents
                  // -----------------------------------------------------------------
                  int j;
                  int numChecked = checkedExceptions.size();
                  for (j = 0; j < numChecked; ++j)
                  {
                      Class<?> checkedEx = checkedExceptions.get(j);
                      if (checkedEx.isAssignableFrom(exception))
                          break;
                  }
  
                  checkedExceptions.add(j, exception);
              }
          }
  
          // -----------------------------------------------------------------------
          // After all exceptions have been processed, make sure that a
          // RemoteException was present if the interface implements java.rmi.Remote
          // -----------------------------------------------------------------------
          if (isRmiRemote && !throwsRemoteException)
          {
              // Log the error and throw meaningful exception.                d450525
              String className = method.getDeclaringClass().getName();
              Tr.error(tc, "JIT_MISSING_REMOTE_EX_CNTR5104E",
                       new Object[] { method.getName(), className });
              throw new EJBConfigurationException("Method " + method.getName() + " of interface " + className +
                                                  " must throw java.rmi.RemoteException");
          }
  
          return checkedExceptions.toArray(new Class[checkedExceptions.size()]);
      }