public static String checkReturnType(
      PsiMethodReferenceExpression expression,
      JavaResolveResult result,
      PsiType functionalInterfaceType) {
    final PsiElement resolve = result.getElement();
    if (resolve instanceof PsiMethod) {
      final PsiClass containingClass = ((PsiMethod) resolve).getContainingClass();
      LOG.assertTrue(containingClass != null);
      PsiSubstitutor subst = result.getSubstitutor();
      PsiClass qContainingClass = getQualifierResolveResult(expression).getContainingClass();
      if (qContainingClass != null
          && isReceiverType(functionalInterfaceType, containingClass, (PsiMethod) resolve)) {
        subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst);
        LOG.assertTrue(subst != null);
      }

      final PsiType interfaceReturnType =
          LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType);

      PsiType returnType =
          PsiTypesUtil.patchMethodGetClassReturnType(
              expression,
              expression,
              (PsiMethod) resolve,
              null,
              PsiUtil.getLanguageLevel(expression));
      if (returnType == null) {
        returnType = ((PsiMethod) resolve).getReturnType();
      }
      PsiType methodReturnType = subst.substitute(returnType);
      if (interfaceReturnType != null && interfaceReturnType != PsiType.VOID) {
        if (methodReturnType == null) {
          methodReturnType =
              JavaPsiFacade.getElementFactory(expression.getProject())
                  .createType(containingClass, subst);
        }
        if (!TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false)) {
          return "Bad return type in method reference: cannot convert "
              + methodReturnType.getCanonicalText()
              + " to "
              + interfaceReturnType.getCanonicalText();
        }
      }
    }
    return null;
  }
    @Nullable
    private static PsiType getResultType(
        PsiMethodCallExpression call,
        PsiReferenceExpression methodExpression,
        JavaResolveResult result,
        @NotNull final LanguageLevel languageLevel) {
      final PsiMethod method = (PsiMethod) result.getElement();
      if (method == null) return null;

      boolean is15OrHigher = languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0;
      final PsiType getClassReturnType =
          PsiTypesUtil.patchMethodGetClassReturnType(
              call,
              methodExpression,
              method,
              new Condition<IElementType>() {
                @Override
                public boolean value(IElementType type) {
                  return type != JavaElementType.CLASS;
                }
              },
              languageLevel);

      if (getClassReturnType != null) {
        return getClassReturnType;
      }

      PsiType ret = method.getReturnType();
      if (ret == null) return null;
      if (ret instanceof PsiClassType) {
        ret = ((PsiClassType) ret).setLanguageLevel(languageLevel);
      }
      if (is15OrHigher) {
        return captureReturnType(call, method, ret, result, languageLevel);
      }
      return TypeConversionUtil.erasure(ret);
    }