private static PsiSubstitutor inferNested(final PsiParameter @NotNull [] parameters,
                                            final PsiExpression @NotNull [] arguments,
                                            final @NotNull PsiCall parent,
                                            final @NotNull MethodCandidateInfo currentMethod,
                                            final @NotNull InferenceSession parentSession) {
    final List<String> errorMessages = parentSession.getIncompatibleErrorMessages();
    if (errorMessages != null && !MethodCandidateInfo.isOverloadCheck()) {
      //for lambda parameter type calculation, the parent inference may contain errors due to skipping that lambda constraints
      //but the type of the lambda parameter should not depend on the lambda body, thus the nested inference may still provide valid results
      return null;
    }

    final CompoundInitialState compoundInitialState = createState(parentSession);
    InitialInferenceState initialInferenceState = compoundInitialState.getInitialState(parent);
    if (initialInferenceState != null) {
      InferenceSession childSession = new InferenceSession(initialInferenceState, parentSession.getInferencePolicy());
      return childSession.collectAdditionalAndInfer(parameters, arguments, currentMethod, compoundInitialState.getInitialSubstitutor());
    }

    //we do not investigate lambda return expressions when lambda's return type is already inferred (proper)
    //this way all calls from lambda's return expressions won't appear in nested sessions

    PsiElement gParent = PsiUtil.skipParenthesizedExprUp(parent.getParent());
    //find the nearest parent which appears in the map and start inference with a provided target type for a nested lambda
    while (true) {
      if (gParent instanceof PsiReturnStatement) { //process code block lambda
        gParent = PsiTreeUtil.getParentOfType(gParent, PsiLambdaExpression.class);
      }
      if (gParent instanceof PsiConditionalExpression) {
        gParent = PsiUtil.skipParenthesizedExprUp(gParent.getParent());
      }
      if (gParent instanceof PsiLambdaExpression) {
        final PsiCall call = PsiTreeUtil.getParentOfType(gParent, PsiCall.class);
        if (call != null) {
          initialInferenceState = compoundInitialState.getInitialState(call);
          if (initialInferenceState != null) {
            final PsiExpressionList argumentList = call.getArgumentList();
            final int idx = argumentList != null ? LambdaUtil.getLambdaIdx(argumentList, gParent) : -1;
            final JavaResolveResult result = PsiDiamondType.getDiamondsAwareResolveResult(call);
            final PsiElement method = result.getElement();
            if (method instanceof PsiMethod && idx > -1) {
              final PsiParameter[] methodParameters = ((PsiMethod)method).getParameterList().getParameters();
              if (methodParameters.length == 0) {
                break;
              }

              //one of the grand parents were found in the top inference session
              //start from it as it is the top level call
              InferenceSession sessionInsideLambda = new InferenceSession(initialInferenceState, parentSession.getInferencePolicy());
              sessionInsideLambda.collectAdditionalAndInfer(methodParameters, argumentList.getExpressions(), ((MethodCandidateInfo)result), compoundInitialState.getInitialSubstitutor());
              return inferNested(parameters, arguments, parent, currentMethod, sessionInsideLambda);
            }
          }
          else {
            gParent = PsiUtil.skipParenthesizedExprUp(call.getParent());
            continue;
          }
        }
      }
      break;
    }
    return null;
  }
private static PsiSubstitutor inferNested(final PsiParameter @NotNull [] parameters,
                                            final PsiExpression @NotNull [] arguments,
                                            final @NotNull PsiCall parent,
                                            final @NotNull MethodCandidateInfo currentMethod,
                                            final @NotNull InferenceSession parentSession)