private static void checkMethod(@NotNull ReflectiveClass ownerClass,
                                  @NotNull String methodName,
                                  @NotNull PsiExpression methodNameExpression,
                                  @NotNull PsiExpression methodTypeExpression,
                                  boolean isStaticExpected,
                                  boolean isAbstractAllowed,
                                  @NotNull PsiReferenceExpression factoryMethodExpression,
                                  @NotNull ProblemsHolder holder) {
    if (!ownerClass.isExact()) return;
    final PsiMethod[] methods = ownerClass.getPsiClass().findMethodsByName(methodName, true);
    if (methods.length == 0) {
      holder.registerProblem(methodNameExpression, JavaErrorBundle.message("cannot.resolve.method", methodName));
      return;
    }

    final List<PsiMethod> filteredMethods =
      ContainerUtil.filter(methods, method -> method.hasModifierProperty(PsiModifier.STATIC) == isStaticExpected);
    if (filteredMethods.isEmpty()) {
      final String factoryMethodName = factoryMethodExpression.getReferenceName();
      final PsiElement factoryMethodNameElement = factoryMethodExpression.getReferenceNameElement();
      if (factoryMethodName != null && factoryMethodNameElement != null) {
        final LocalQuickFix fix = SwitchStaticnessQuickFix.createFix(factoryMethodName, isStaticExpected);
        final String message = JavaBundle.message(
          isStaticExpected ? "inspection.handle.signature.method.not.static" : "inspection.handle.signature.method.static", methodName);
        holder.registerProblem(factoryMethodNameElement, message, LocalQuickFix.notNullElements(fix));
        return;
      }
    }

    final ReflectiveSignature methodSignature = composeMethodSignature(methodTypeExpression);
    if (methodSignature == null) return;

    final List<PsiMethod> matchingMethods = findMethodBySignature(filteredMethods, methodSignature);
    if (matchingMethods.isEmpty()) {
      final String declarationText = getMethodDeclarationText(methodName, methodSignature);
      final List<ReflectiveSignature> validSignatures = filteredMethods.stream()
        .map(JavaReflectionReferenceUtil::getMethodSignature)
        .filter(Objects::nonNull)
        .collect(Collectors.toList());
      final LocalQuickFix fix =
        ReplaceSignatureQuickFix.createFix(methodTypeExpression, methodName, validSignatures, false, holder.isOnTheFly());
      holder.registerProblem(methodTypeExpression, JavaErrorBundle.message("cannot.resolve.method", declarationText),
                             LocalQuickFix.notNullElements(fix));
      return;
    }
    if (!isAbstractAllowed) {
      final boolean allAbstract = ContainerUtil.and(matchingMethods, method -> method.hasModifierProperty(PsiModifier.ABSTRACT));
      if (allAbstract) {
        final String className = ownerClass.getPsiClass().getQualifiedName();
        if (className != null) {
          holder.registerProblem(methodNameExpression,
                                 JavaBundle.message("inspection.handle.signature.method.abstract", methodName, className));
        }
      }
    }
  }
private static void checkMethod(@NotNull ReflectiveClass ownerClass,
                                  @NotNull String methodName,
                                  @NotNull PsiExpression methodNameExpression,
                                  @NotNull PsiExpression methodTypeExpression,
                                  boolean isStaticExpected,
                                  boolean isAbstractAllowed,
                                  @NotNull PsiReferenceExpression factoryMethodExpression,
                                  @NotNull ProblemsHolder holder)