private PsiType inferVarType(PsiElement parent) {
    if (parent instanceof PsiParameter) {
      PsiParameter parameter = (PsiParameter)parent;
      if (parameter instanceof PsiPatternVariable) {
        return JavaPsiPatternUtil.getDeconstructedImplicitPatternVariableType((PsiPatternVariable)parameter);
      }
      PsiElement declarationScope = parameter.getDeclarationScope();
      if (declarationScope instanceof PsiForeachStatement) {
        PsiExpression iteratedValue = ((PsiForeachStatement)declarationScope).getIteratedValue();
        if (iteratedValue != null) {
          PsiType type = JavaGenericsUtil.getCollectionItemType(iteratedValue);
          //Upward projection is applied to the type of the initializer when determining the type of the
          //variable
          return type != null ? JavaVarTypeUtil.getUpwardProjection(type) : null;
        }
        return null;
      }

      if (declarationScope instanceof PsiLambdaExpression) {
        return parameter.getType();
      }
    }
    else {
      for (PsiElement e = this; e != null; e = e.getNextSibling()) {
        if (e instanceof PsiExpression) {
          if (!PsiTreeUtil.processElements(
            e, PsiReferenceExpression.class, ref -> !ref.isReferenceTo(parent))) {
            return null;
          }
          if (!(e instanceof PsiArrayInitializerExpression)) {
            PsiExpression expression = (PsiExpression)e;
            RecursionGuard.StackStamp stamp = RecursionManager.markStack();
            PsiType type = RecursionManager.doPreventingRecursion(expression, true, () -> expression.getType());
            if (stamp.mayCacheNow()) {
              return type == null ? null : JavaVarTypeUtil.getUpwardProjection(type);
            }
            return null;
          }
          return null;
        }
      }
    }
    return null;
  }
private PsiType inferVarType(PsiElement parent)