code: @SafeVarargs
      public static <T extends Throwable, C extends Class<? extends T>> T findCause(Throwable root, C... ofClasses) {
          for (C c : ofClasses) {
              Throwable t = root;
              while (t != null) {
                  if (c.isInstance(t)) {
                      return c.cast(t);
                  }
                  t = t.getCause();
              }
          }
          return null;
      }
docs: Search the cause chain of <em>t</em> (starting from and including <em>t</em>) for a Throwable
  that is assignable to any of <em>ofClasses</em>, or null if not found. The chain is first fully searched
  for the first of <em>C</em>, then second, etc.
  
  @param ofClasses Throwable classes in order of priority to be searched for.
  @param root      The cause from which the search is to be started.
  @param <T>       This should be figured out by the compiler: the lowest common ancestor of <em>ofClasses</em>.
  @param <C>       Should be figured out by the compiler too.