PsiExpression (@NotNull PsiLambdaExpression lambda, PsiElement body) { Project project = lambda.getProject(); PsiType functionalInterfaceType = lambda.getFunctionalInterfaceType(); if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return lambda; final PsiType denotableFunctionalInterfaceType = RefactoringChangeUtil.getTypeByExpression(lambda); if (denotableFunctionalInterfaceType == null) return lambda; final String methodRefText = createMethodReferenceText(body, functionalInterfaceType, lambda.getParameterList().getParameters()); if (methodRefText != null) { final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); final PsiExpression psiExpression = factory.createExpressionFromText(methodRefText, lambda); final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(project).createSmartTypePointer(denotableFunctionalInterfaceType); PsiExpression replace = (PsiExpression)new CommentTracker().replaceAndRestoreComments(lambda, psiExpression); if (!(replace instanceof PsiMethodReferenceExpression)) { LOG.error("Generated code is not method reference: "+replace.getClass(), new Attachment("replacement.txt", replace.getText()), new Attachment("origtext.txt", methodRefText)); return lambda; } final PsiType functionalTypeAfterReplacement = GenericsUtil.getVariableTypeByExpressionType(((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType()); functionalInterfaceType = typePointer.getType(); if (functionalInterfaceType != null && !functionalInterfaceType.equals(functionalTypeAfterReplacement)) { //ambiguity final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(A)a", replace); PsiTypeElement castType = cast.getCastType(); LOG.assertTrue(castType != null); castType.replace(factory.createTypeElement(functionalInterfaceType)); PsiExpression castOperand = cast.getOperand(); LOG.assertTrue(castOperand != null); castOperand.replace(replace); replace = (PsiExpression)replace.replace(cast); } JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace); return replace; } return lambda; }