private void collectAdditionalConstraints(PsiParameter[] parameters,
                                            PsiExpression[] args,
                                            PsiMethod parentMethod,
                                            PsiSubstitutor siteSubstitutor,
                                            Set<ConstraintFormula> additionalConstraints,
                                            Set<ConstraintFormula> ignoredConstraints,
                                            boolean varargs,
                                            PsiSubstitutor initialSubstitutor) {
    for (int i = 0; i < args.length; i++) {
      final PsiExpression arg = PsiUtil.skipParenthesizedExprDown(args[i]);
      if (arg != null) {
        final PsiSubstitutor nestedSubstitutor = myInferenceSessionContainer.findNestedSubstitutor(arg, myInferenceSubstitution);
        final PsiType parameterType = nestedSubstitutor.substitute(getParameterType(parameters, i, siteSubstitutor, varargs));
        if (parameterType == null) continue;
        ExpressionCompatibilityConstraint compatibilityConstraint = new ExpressionCompatibilityConstraint(arg, parameterType);
        if (arg instanceof PsiFunctionalExpression && ignoreLambdaConstraintTree(arg) || dependsOnIgnoredConstraint(ignoredConstraints, compatibilityConstraint)) {
          ignoredConstraints.add(compatibilityConstraint);
          continue;
        }
        if (!isPertinentToApplicability(arg, parentMethod)) {
          additionalConstraints.add(compatibilityConstraint);
        }
        additionalConstraints.add(new CheckedExceptionCompatibilityConstraint(arg, parameterType));
        if (arg instanceof PsiCallExpression) {
          //If the expression is a poly class instance creation expression (15.9) or a poly method invocation expression (15.12), 
          //the set contains all constraint formulas that would appear in the set C when determining the poly expression's invocation type.
          final JavaResolveResult resolveResult = PsiDiamondType.getDiamondsAwareResolveResult((PsiCallExpression)arg);
          final PsiMethod calledMethod = resolveResult instanceof MethodCandidateInfo ? (PsiMethod)resolveResult.getElement() : null;
          if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(arg, calledMethod)) {
            collectAdditionalConstraints(additionalConstraints, ignoredConstraints, (PsiCallExpression)arg, initialSubstitutor);
          }
        }
        else if (arg instanceof PsiLambdaExpression &&
                 isPertinentToApplicability(arg, parentMethod)) {
          collectLambdaReturnExpression(additionalConstraints, ignoredConstraints, (PsiLambdaExpression)arg,
                                        ((PsiLambdaExpression)arg).getGroundTargetType(parameterType),
                                        !isProperType(initialSubstitutor.substitute(parameterType)),
                                        initialSubstitutor);
        }
      }
    }
  }
private void collectAdditionalConstraints(PsiParameter[] parameters,
                                            PsiExpression[] args,
                                            PsiMethod parentMethod,
                                            PsiSubstitutor siteSubstitutor,
                                            Set<ConstraintFormula> additionalConstraints,
                                            Set<ConstraintFormula> ignoredConstraints,
                                            boolean varargs,
                                            PsiSubstitutor initialSubstitutor)