@Nullable
  @Contract("_, null -> null")
  public static DfaValue getExpressionDfaValue(@NotNull DfaValueFactory factory, @Nullable PsiExpression expression) {
    if (expression == null) return null;

    if (expression instanceof PsiParenthesizedExpression) {
      return getExpressionDfaValue(factory, ((PsiParenthesizedExpression)expression).getExpression());
    }

    if (expression instanceof PsiArrayAccessExpression) {
      PsiExpression arrayExpression = ((PsiArrayAccessExpression)expression).getArrayExpression();
      DfaValue qualifier = getQualifierValue(factory, arrayExpression);
      if (qualifier != null) {
        Object index = ExpressionUtils.computeConstantExpression(((PsiArrayAccessExpression)expression).getIndexExpression());
        if (index instanceof Integer) {
          DfaValue arrayElementValue = ArrayElementDescriptor.getArrayElementValue(factory, qualifier, (Integer)index);
          if (arrayElementValue != null) {
            return arrayElementValue;
          }
        }
      }
      PsiType type = expression.getType();
      if (type != null) {
        return factory.fromDfType(DfTypes.typedObject(type, DfaPsiUtil.getElementNullability(type, null)));
      }
    }

    if (expression instanceof PsiMethodCallExpression) {
      return createReferenceValue(factory, ((PsiMethodCallExpression)expression).getMethodExpression());
    }

    if (expression instanceof PsiReferenceExpression) {
      return createReferenceValue(factory, (PsiReferenceExpression)expression);
    }

    if (expression instanceof PsiLiteralExpression) {
      return factory.fromDfType(DfaPsiUtil.fromLiteral((PsiLiteralExpression)expression));
    }

    if (expression instanceof PsiNewExpression) {
      PsiType psiType = expression.getType();
      DfType dfType = psiType == null ? DfType.TOP : TypeConstraints.exact(psiType).asDfType();
      return factory.fromDfType(dfType.meet(DfTypes.NOT_NULL_OBJECT));
    }

    if (expression instanceof PsiLambdaExpression) {
      DfType dfType = JavaDfaHelpers.getFunctionDfType((PsiFunctionalExpression)expression);
      return factory.fromDfType(dfType.meet(DfTypes.NOT_NULL_OBJECT));
    }

    final Object value = JavaConstantExpressionEvaluator.computeConstantExpression(expression, false);
    if (value != null) {
      PsiType type = expression.getType();
      if (type != null) {
        return factory.fromDfType(DfTypes.constant(value, type));
      }
    }

    if (expression instanceof PsiQualifiedExpression) {
      PsiJavaCodeReferenceElement qualifier = ((PsiQualifiedExpression)expression).getQualifier();
      PsiClass target;
      if (qualifier != null) {
        target = tryCast(qualifier.resolve(), PsiClass.class);
      }
      else {
        target = PsiUtil.getContainingClass(expression);
      }
      return target == null
             ? factory.fromDfType(DfTypes.typedObject(expression.getType(), Nullability.NOT_NULL))
             : ThisDescriptor.createThisValue(factory, target);
    }
    return null;
  }
@Nullable
  @Contract("_, null -> null")
  public static DfaValue getExpressionDfaValue(@NotNull DfaValueFactory factory, @Nullable PsiExpression expression)