public static PsiExpression adjustLambdaContainingExpression(PsiExpression expression,
                                                               boolean insertTypeCase,
                                                               PsiType targetType,
                                                               @NotNull TypeEvaluator evaluator) {
    if (expression instanceof PsiNewExpression) {
      final PsiAnonymousClass anonymousClass = ((PsiNewExpression)expression).getAnonymousClass();
      if (anonymousClass != null) {
        return convertAnonymousClass((PsiNewExpression)expression, anonymousClass, evaluator);
      }
      else {
        final GuavaLambda lambda = GuavaLambda.findFor(evaluator.evaluateType(expression));
        if (lambda == null) {
          return expression;
        }
        else {
          final PsiExpression expressionWithMethodReference = addMethodReference(expression, lambda);
          if (insertTypeCase) {
            return adjustLambdaContainingExpression(expressionWithMethodReference, true, targetType, evaluator);
          } else {
            return expressionWithMethodReference;
          }
        }
      }
    }
    if (expression instanceof PsiMethodReferenceExpression) {
      final PsiExpression qualifier = ((PsiMethodReferenceExpression)expression).getQualifierExpression();
      final PsiType evaluatedType = evaluator.evaluateType(qualifier);
      final GuavaLambda lambda = GuavaLambda.findJavaAnalogueFor(evaluatedType);
      if (lambda != null) {
        PsiExpression replaced = (PsiExpression)expression.replace(qualifier);
        if (targetType == null &&
            lambda.getSamName().equals(((PsiMethodReferenceExpression)expression).getReferenceName())) {
          return replaced;
        }
        return adjustLambdaContainingExpression(replaced, insertTypeCase, targetType, evaluator);
      }
    }
    if (expression instanceof PsiFunctionalExpression) {
      if (insertTypeCase) {
        return JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText("((" + targetType.getCanonicalText() + ")" + expression.getText() + ")", expression);
      }
    }
    else if (expression instanceof PsiMethodCallExpression || expression instanceof PsiReferenceExpression) {
      final PsiType type = expression.getType();
      if (targetType != null && type != null && !targetType.isAssignableFrom(type)) {
        final GuavaLambda lambda = GuavaLambda.findFor(evaluator.evaluateType(expression));
        if (lambda != null) {
          expression = addMethodReference(expression, lambda);
          return adjustLambdaContainingExpression(expression, insertTypeCase, targetType, evaluator);
        }
      }
    }
    return expression;
  }
public static PsiExpression adjustLambdaContainingExpression(PsiExpression expression,
                                                               boolean insertTypeCase,
                                                               PsiType targetType,
                                                               @NotNull TypeEvaluator evaluator)