@NotNull
  static ProblemType getTypeByLambdaCandidate(@NotNull PsiReferenceExpression optionalRef,
                                              @Nullable PsiElement lambdaCandidate,
                                              @Nullable PsiExpression falseExpression) {
    if (lambdaCandidate == null) return ProblemType.NONE;
    if (lambdaCandidate instanceof PsiReferenceExpression &&
        areElementsEquivalent(lambdaCandidate, optionalRef) && OptionalUtil.isOptionalEmptyCall(falseExpression)) {
      return ProblemType.WARNING;
    }
    if (!LambdaGenerationUtil.canBeUncheckedLambda(lambdaCandidate, optionalRef::isReferenceTo)) return ProblemType.NONE;
    Ref<Boolean> hasOptionalReference = new Ref<>(Boolean.FALSE);
    boolean hasNoBadRefs = PsiTreeUtil.processElements(lambdaCandidate, e -> {
      if (!(e instanceof PsiReferenceExpression)) return true;
      if (!areElementsEquivalent(e, optionalRef)) return true;
      // Check that Optional variable is referenced only in context of get() call
      hasOptionalReference.set(Boolean.TRUE);
      return isOptionalGetCall(e.getParent().getParent(), optionalRef);
    });
    if (!hasNoBadRefs) return ProblemType.NONE;
    if (!hasOptionalReference.get() || !(lambdaCandidate instanceof PsiExpression expression)) return ProblemType.INFO;
    if (falseExpression != null) {
      // falseExpression == null is "consumer" case (to be replaced with ifPresent())
      if (!ExpressionUtils.isNullLiteral(falseExpression) &&
          NullabilityUtil.getExpressionNullability(expression, true) != Nullability.NOT_NULL) {
        // if falseExpression is null literal, then semantics is preserved
        return ProblemType.INFO;
      }
      PsiType falseType = falseExpression.getType();
      PsiType trueType = expression.getType();
      if (falseType == null || trueType == null) return ProblemType.NONE;
      if (falseType instanceof PsiPrimitiveType && trueType instanceof PsiPrimitiveType) {
        if (falseType.equals(trueType) || JavaPsiMathUtil.getNumberFromLiteral(falseExpression) != null) {
          // like x ? double_expression : integer_expression; support only if integer_expression is simple literal,
          // so could be converted explicitly to double
          return ProblemType.WARNING;
        }
        return ProblemType.NONE;
      }
      if (!trueType.isAssignableFrom(falseType)) {
        return ProblemType.NONE;
      }
    }
    return ProblemType.WARNING;
  }
@NotNull
  static ProblemType getTypeByLambdaCandidate(@NotNull PsiReferenceExpression optionalRef,
                                              @Nullable PsiElement lambdaCandidate,
                                              @Nullable PsiExpression falseExpression)