private static PsiType getNormalizedType(PsiParameter parameter) {
   final PsiType type = parameter.getType();
   if (type instanceof PsiEllipsisType) {
     return ((PsiEllipsisType) type).getComponentType();
   }
   return type;
 }
 private static PsiClassType createDefaultConsumerType(Project project, PsiParameter parameter) {
   final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
   final PsiClass consumerClass =
       psiFacade.findClass("java.util.function.Consumer", GlobalSearchScope.allScope(project));
   return consumerClass != null
       ? psiFacade.getElementFactory().createType(consumerClass, parameter.getType())
       : null;
 }
 @Nullable
 private static PsiType getFunctionalType(
     int functionalTypeIdx, @NotNull CandidateInfo candidateInfo) {
   final PsiMethod psiMethod = (PsiMethod) candidateInfo.getElement();
   LOG.assertTrue(true);
   final PsiParameter[] methodParameters = psiMethod.getParameterList().getParameters();
   if (methodParameters.length == 0) return null;
   final PsiParameter param =
       functionalTypeIdx < methodParameters.length
           ? methodParameters[functionalTypeIdx]
           : methodParameters[methodParameters.length - 1];
   return ((MethodCandidateInfo) candidateInfo).getSiteSubstitutor().substitute(param.getType());
 }
  public static boolean isMethodEquivalentTo(@NotNull PsiMethod method1, PsiElement another) {
    if (method1 == another) return true;
    if (!(another instanceof PsiMethod)) return false;
    PsiMethod method2 = (PsiMethod) another;
    if (!another.isValid()) return false;
    if (!method1.getName().equals(method2.getName())) return false;
    PsiClass aClass1 = method1.getContainingClass();
    PsiClass aClass2 = method2.getContainingClass();
    PsiManager manager = method1.getManager();
    if (!(aClass1 != null && aClass2 != null && manager.areElementsEquivalent(aClass1, aClass2)))
      return false;

    PsiParameter[] parameters1 = method1.getParameterList().getParameters();
    PsiParameter[] parameters2 = method2.getParameterList().getParameters();
    if (parameters1.length != parameters2.length) return false;
    for (int i = 0; i < parameters1.length; i++) {
      PsiParameter parameter1 = parameters1[i];
      PsiParameter parameter2 = parameters2[i];
      PsiType type1 = parameter1.getType();
      PsiType type2 = parameter2.getType();
      if (!compareParamTypes(manager, type1, type2)) return false;
    }
    return true;
  }
 private static String createMapperFunctionalExpressionText(
     PsiParameter parameter, PsiExpression expression) {
   String iteration = "";
   if (!isIdentityMapping(parameter, expression)) {
     iteration += ".map(";
     iteration +=
         compoundLambdaOrMethodReference(
             parameter,
             expression,
             "java.util.function.Function",
             new PsiType[] {parameter.getType(), expression.getType()});
     iteration += ")";
   }
   return iteration;
 }
  private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions)
      throws IncorrectOperationException {
    // methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions
    newExceptions = filterCheckedExceptions(newExceptions);

    PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class);
    if (context instanceof PsiTryStatement) {
      PsiTryStatement tryStatement = (PsiTryStatement) context;
      PsiCodeBlock tryBlock = tryStatement.getTryBlock();

      // Remove unused catches
      Collection<PsiClassType> classes =
          ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock);
      PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters();
      for (PsiParameter parameter : catchParameters) {
        final PsiType caughtType = parameter.getType();

        if (!(caughtType instanceof PsiClassType)) continue;
        if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType) caughtType)) continue;

        if (!isCatchParameterRedundant((PsiClassType) caughtType, classes)) continue;
        parameter.getParent().delete(); // delete catch section
      }

      PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock);
      addExceptions(exceptionsToAdd, tryStatement);

      adjustPossibleEmptyTryStatement(tryStatement);
    } else {
      newExceptions = filterUnhandledExceptions(newExceptions, ref);
      if (newExceptions.length > 0) {
        // Add new try statement
        PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject());
        PsiTryStatement tryStatement =
            (PsiTryStatement)
                elementFactory.createStatementFromText("try {} catch (Exception e) {}", null);
        PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class);
        LOG.assertTrue(anchor != null);
        tryStatement.getTryBlock().add(anchor);
        tryStatement = (PsiTryStatement) anchor.getParent().addAfter(tryStatement, anchor);

        addExceptions(newExceptions, tryStatement);
        anchor.delete();
        tryStatement.getCatchSections()[0].delete(); // Delete dummy catch section
      }
    }
  }
  private static void checkCall(
      @NotNull PsiCallExpression methodCall, @NotNull ProblemsHolder holder) {
    PsiMethod method = methodCall.resolveMethod();
    if (method == null) return;
    PsiParameter[] parameters = method.getParameterList().getParameters();
    PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
    for (int i = 0; i < parameters.length; i++) {
      PsiParameter parameter = parameters[i];
      AllowedValues values = getAllowedValues(parameter, parameter.getType(), null);
      if (values == null) continue;
      if (i >= arguments.length) break;
      PsiExpression argument = arguments[i];
      argument = PsiUtil.deparenthesizeExpression(argument);
      if (argument == null) continue;

      checkMagicParameterArgument(parameter, argument, values, holder);
    }
  }
 private static String createFiltersChainText(
     PsiStatement body, PsiParameter parameter, PsiIfStatement ifStatement) {
   final List<String> filters = new ArrayList<String>();
   while (ifStatement != null && PsiTreeUtil.isAncestor(body, ifStatement, false)) {
     final PsiExpression condition = ifStatement.getCondition();
     if (condition != null) {
       filters.add(
           ".filter("
               + compoundLambdaOrMethodReference(
                   parameter,
                   condition,
                   "java.util.function.Predicate",
                   new PsiType[] {parameter.getType()})
               + ")");
     }
     ifStatement = PsiTreeUtil.getParentOfType(ifStatement, PsiIfStatement.class);
   }
   Collections.reverse(filters);
   return StringUtil.join(filters, "");
 }
  public static boolean isFreeFromTypeInferenceArgs(
      final PsiParameter[] methodParameters,
      final PsiLambdaExpression lambdaExpression,
      final PsiExpression expression,
      final PsiSubstitutor subst,
      final PsiType functionalInterfaceType,
      final PsiTypeParameter typeParam) {
    if (expression instanceof PsiCallExpression
        && ((PsiCallExpression) expression).getTypeArguments().length > 0) return true;
    if (expression instanceof PsiNewExpression) {
      final PsiJavaCodeReferenceElement classReference =
          ((PsiNewExpression) expression).getClassOrAnonymousClassReference();
      if (classReference != null) {
        final PsiReferenceParameterList parameterList = classReference.getParameterList();
        if (parameterList != null) {
          final PsiTypeElement[] typeParameterElements = parameterList.getTypeParameterElements();
          if (typeParameterElements.length > 0) {
            if (!(typeParameterElements[0].getType() instanceof PsiDiamondType)) {
              return true;
            }
          }
        }
      }
    }
    final PsiParameter[] lambdaParams = lambdaExpression.getParameterList().getParameters();
    if (lambdaParams.length != methodParameters.length) return false;
    final boolean[] independent = {true};
    final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(functionalInterfaceType);
    if (interfaceMethod == null) return false;
    final TypeParamsChecker paramsChecker = new TypeParamsChecker(lambdaExpression);
    for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) {
      subst.substitute(parameter.getType()).accept(paramsChecker);
    }
    paramsChecker.myUsedTypeParams.add(typeParam);

    expression.accept(
        new JavaRecursiveElementWalkingVisitor() {
          @Override
          public void visitConditionalExpression(PsiConditionalExpression expression) {
            final PsiExpression thenExpression = expression.getThenExpression();
            if (thenExpression != null) {
              thenExpression.accept(this);
            }
            final PsiExpression elseExpression = expression.getElseExpression();
            if (elseExpression != null) {
              elseExpression.accept(this);
            }
          }

          @Override
          public void visitReferenceExpression(PsiReferenceExpression expression) {
            super.visitReferenceExpression(expression);
            int usedParamIdx = -1;
            for (int i = 0; i < lambdaParams.length; i++) {
              PsiParameter param = lambdaParams[i];
              if (expression.isReferenceTo(param)) {
                usedParamIdx = i;
                break;
              }
            }

            if (usedParamIdx > -1
                && dependsOnTypeParams(
                    subst.substitute(methodParameters[usedParamIdx].getType()),
                    functionalInterfaceType,
                    lambdaExpression,
                    paramsChecker.myUsedTypeParams.toArray(
                        new PsiTypeParameter[paramsChecker.myUsedTypeParams.size()]))) {
              independent[0] = false;
            }
          }
        });
    return independent[0];
  }