@Override
  public @NotNull PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, boolean isOnTheFly) {
    return new JavaElementVisitor() {
      @Override
      public void visitMethodReferenceExpression(@NotNull PsiMethodReferenceExpression expression) {
        final PsiExpression qualifierExpression = expression.getQualifierExpression();
        final PsiElement referenceNameElement = expression.getReferenceNameElement();
        doCheckCall(expression, () -> expression.resolve(), qualifierExpression, referenceNameElement,
                    InspectionGadgetsBundle.message("replace.method.ref.with.qualifier.problem.method"));
      }

      @Override
      public void visitLambdaExpression(@NotNull PsiLambdaExpression lambdaExpression) {
        PsiElement body = lambdaExpression.getBody();
        PsiExpression asMethodReference = LambdaCanBeMethodReferenceInspection
          .canBeMethodReferenceProblem(body, lambdaExpression.getParameterList().getParameters(), lambdaExpression.getFunctionalInterfaceType(), null);
        if (asMethodReference instanceof PsiMethodCallExpression) {
          PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)asMethodReference).getMethodExpression();
          PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
          doCheckCall(lambdaExpression, () -> ((PsiMethodCallExpression)asMethodReference).resolveMethod(), qualifierExpression, asMethodReference,
                    InspectionGadgetsBundle.message("replace.method.ref.with.qualifier.problem.lambda"));
        }
      }

      private void doCheckCall(PsiFunctionalExpression expression,
                               Supplier<? extends PsiElement> resolver,
                               PsiExpression qualifierExpression,
                               PsiElement referenceNameElement,
                               final @InspectionMessage String errorMessage) {
        if (qualifierExpression != null && referenceNameElement != null && !(qualifierExpression instanceof PsiSuperExpression)) {
          final PsiType qualifierType = qualifierExpression.getType();
          if (qualifierType != null) {
            //don't get the ground type as check is required over the expected type instead
            final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(expression, true);
            final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType);
            if (interfaceMethod != null) {
              final PsiElement resolve = resolver.get();
              if (resolve instanceof PsiMethod &&
                  (interfaceMethod == resolve || MethodSignatureUtil.isSuperMethod(interfaceMethod, (PsiMethod)resolve)) &&
                  TypeConversionUtil.isAssignable(functionalInterfaceType, qualifierType) &&
                  !mayOverrideDefaultMethods(qualifierExpression, functionalInterfaceType)) {
                holder.registerProblem(referenceNameElement, errorMessage, new ReplaceMethodRefWithQualifierFix());
              }
            }
          }
        }
      }

      private static boolean mayOverrideDefaultMethods(PsiExpression expression, PsiType functionalInterfaceType) {
        PsiClass functionalInterface = PsiUtil.resolveClassInClassTypeOnly(functionalInterfaceType);
        if (functionalInterface == null || !functionalInterface.isInterface()) return true;
        if (!ContainerUtil.exists(functionalInterface.getAllMethods(), m -> m.hasModifierProperty(PsiModifier.DEFAULT))) {
          return false;
        }
        PsiType qualifierType = null;
        if (CommonDataflow.getDfType(expression) instanceof DfReferenceType refType) {
          qualifierType = refType.getConstraint().getPsiType(functionalInterface.getProject());
        }
        if (qualifierType == null) {
          qualifierType = expression.getType();
        }
        PsiClass qualifierClass = PsiUtil.resolveClassInClassTypeOnly(qualifierType);
        if (qualifierClass == null) return true;
        if (qualifierClass.isEquivalentTo(functionalInterface)) return false;
        for (PsiMethod method : qualifierClass.getAllMethods()) {
          for (PsiMethod superMethod : method.findSuperMethods(functionalInterface)) {
            if (superMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
              return true;
            }
          }
        }
        return false;
      }
    };
  }
@Override
  public @NotNull PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, boolean isOnTheFly)