private static boolean equal(TypeMirror a, TypeMirror b, Set<ComparedElements> visiting) {
        // TypeMirror.equals is not guaranteed to return true for types that are equal, but we can
        // assume that if it does return true then the types are equal. This check also avoids getting
        // stuck in infinite recursion when Eclipse decrees that the upper bound of the second K in
        // <K extends Comparable<K>> is a distinct but equal K.
        // The javac implementation of ExecutableType, at least in some versions, does not take thrown
        // exceptions into account in its equals implementation, so avoid this optimization for
        // ExecutableType.
        if (Objects.equal(a, b) && !(a instanceof ExecutableType)) {
            return true;
        }
        EqualVisitorParam p = new EqualVisitorParam();
        p.type = b;
        p.visiting = visiting;
        if (INTERSECTION_TYPE != null) {
            if (isIntersectionType(a)) {
                return equalIntersectionTypes(a, b, visiting);
            } else if (isIntersectionType(b)) {
                return false;
            }
        }
        return (a == b) || (a != null && b != null && a.accept(EQUAL_VISITOR, p));
    }
Utilities related to {@link TypeMirror} instances.

@author Gregory Kick
@since 2.0
android/annotation_processors/xposed_hook_compiler/src/main/java/github/tornaco/permission/compiler/common/MoreTypes.java