public static void fireFirstDeclared(Throwable t, Class... declaredTypes) {
        Throwable cause = t;
        while (cause != null) {
            cause = cause.getCause();
            if (cause == null) {
                break;
            }
            if (declaredTypes != null) {
                for (Class declaredType : declaredTypes) {
                    if (declaredType.isInstance(cause)) {
                        fire(cause);
                    }
                }
            }
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            }
            if (cause instanceof Error) {
                throw (Error) cause;
            }
        }
        throw new UndeclaredThrowableException(t);
    }