private static PsiType getTargetTypeFromParent(final PsiElement context, Ref<String> errorMessage, boolean inferParent) {
    PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context);
    if (targetType != null) {
      return targetType;
    }
    final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
    if (parent instanceof PsiExpressionList) {
      PsiElement gParent = parent.getParent();
      if (gParent instanceof PsiAnonymousClass) {
        gParent = gParent.getParent();
      }
      if (gParent instanceof PsiCall) {
        final PsiExpressionList argumentList = ((PsiCall)gParent).getArgumentList();
        if (argumentList != null) {
          if (MethodCandidateInfo.isOverloadCheck(argumentList)) {
            return ThreadLocalTypes.getElementType(context);
          }

          final JavaResolveResult result = PsiDiamondType.getDiamondsAwareResolveResult((PsiCall)gParent);
          final PsiElement element = result.getElement();
          if (element == null) {
            errorMessage.set("Overload resolution failed");
            return null;
          }
          if (element instanceof PsiMethod && (inferParent || !((PsiMethod)element).hasTypeParameters())) {
            final boolean varargs = result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isVarargs();
            return PsiTypesUtil.getTypeByMethod(context, argumentList, result.getElement(), varargs, result.getSubstitutor(), inferParent);
          }
        }
      }
    }
    else if (parent instanceof PsiConditionalExpression) {
      return getTargetTypeFromParent(parent, errorMessage, inferParent);
    }
    else if (parent instanceof PsiLambdaExpression) {
      return getTargetTypeFromParentLambda((PsiLambdaExpression)parent, errorMessage, inferParent);
    }
    else if (parent instanceof PsiReturnStatement) {
      return getTargetTypeFromParentLambda(PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class, true, PsiMethod.class),
                                           errorMessage, inferParent);
    }
    PsiSwitchExpression switchExpression = PsiTreeUtil.getParentOfType(parent, PsiSwitchExpression.class);
    if (switchExpression  != null && PsiUtil.getSwitchResultExpressions(switchExpression).contains(context)) {
      return getTargetTypeFromParent(switchExpression, errorMessage, inferParent);
    }
    return null;
  }
private static PsiType getTargetTypeFromParent(final PsiElement context, Ref<String> errorMessage, boolean inferParent)