private static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN, @Flags int flags, @Nullable Set<? super PsiMember> processed) {
    PsiModifierList modifierList = listOwner.getModifierList();
    if (modifierList == null) return false;

    PsiAnnotation annotation = modifierList.findAnnotation(annotationFQN);
    if (annotation != null) return true;

    if (BitUtil.isSet(flags, CHECK_TYPE)) {
      PsiType type = null;
      if (listOwner instanceof PsiMethod) {
        type = ((PsiMethod)listOwner).getReturnType();
      }
      else if (listOwner instanceof PsiParameter &&
               listOwner.getParent() instanceof PsiParameterList &&
               listOwner.getParent().getParent() instanceof PsiLambdaExpression) {
        if (((PsiParameter)listOwner).getTypeElement() != null) {
          // Avoid lambda parameter type inference: anyway it doesn't have any explicit annotations
          type = ((PsiParameter)listOwner).getType();
        }
      }
      else if (listOwner instanceof PsiVariable) {
        type = ((PsiVariable)listOwner).getType();
      }
      if (type != null && type.hasAnnotation(annotationFQN)) {
        return true;
      }
    }

    if (BitUtil.isSet(flags, CHECK_EXTERNAL)) {
      Project project = listOwner.getProject();
      if (ExternalAnnotationsManager.getInstance(project).findExternalAnnotation(listOwner, annotationFQN) != null) {
        return true;
      }
    }

    if (BitUtil.isSet(flags, CHECK_INFERRED)) {
      Project project = listOwner.getProject();
      if (InferredAnnotationsManager.getInstance(project).findInferredAnnotation(listOwner, annotationFQN) != null) {
        return true;
      }
    }

    if (BitUtil.isSet(flags, CHECK_HIERARCHY)) {
      if (listOwner instanceof PsiMethod) {
        PsiMethod method = (PsiMethod)listOwner;
        if (processed == null) {
          processed = new HashSet<>();
        }
        if (!processed.add(method)) {
          return false;
        }
        for (PsiMethod superMethod : method.findSuperMethods()) {
          if (isAnnotated(superMethod, annotationFQN, flags, processed)) {
            return true;
          }
        }
      }
      else if (listOwner instanceof PsiClass) {
        PsiClass clazz = (PsiClass)listOwner;
        if (processed == null) {
          processed = new HashSet<>();
        }
        if (!processed.add(clazz)) {
          return false;
        }
        for (PsiClass superClass : clazz.getSupers()) {
          if (isAnnotated(superClass, annotationFQN, flags, processed)) {
            return true;
          }
        }
      }
    }

    return false;
  }
private static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN, @Flags int flags, @Nullable Set<? super PsiMember> processed)