@Override
  public @NotNull SliceValueFilter parseFilter(@NotNull PsiElement expression, @NotNull String filter) throws SliceFilterParseException {
    PsiType type = getType(expression);
    if (type == null) {
      return SliceLanguageSupportProvider.super.parseFilter(expression, filter);
    }
    if (filter.equals("null")) {
      if (type instanceof PsiPrimitiveType) {
        throw new SliceFilterParseException(
          JavaBundle.message("slice.filter.parse.error.null.filter.not.applicable.for.primitive.type", type.getPresentableText()));
      }
      return new JavaValueFilter(DfTypes.NULL);
    }
    if (filter.equals("!null")) {
      if (type instanceof PsiPrimitiveType) {
        throw new SliceFilterParseException(
          JavaBundle.message("slice.filter.parse.error.not.null.filter.not.applicable.for.primitive.type", type.getPresentableText()));
      }
      return new JavaValueFilter(DfTypes.NOT_NULL_OBJECT);
    }
    RelationType relationType = RelationType.EQ;
    if (PsiTypes.byteType().equals(type) ||
        PsiTypes.charType().equals(type) ||
        PsiTypes.shortType().equals(type) ||
        PsiTypes.intType().equals(type) ||
        PsiTypes.longType().equals(type)) {
      for (RelationType relType : RelationType.values()) {
        if (filter.startsWith(relType.toString())) {
          relationType = relType;
          filter = filter.substring(relType.toString().length()).trim();
          break;
        }
      }
    }
    PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(type);
    if (psiClass != null && psiClass.isEnum()) {
      PsiField enumConstant = psiClass.findFieldByName(filter, false);
      if (enumConstant instanceof PsiEnumConstant) {
        return new JavaValueFilter(DfTypes.referenceConstant(enumConstant, type));
      } else {
        throw new SliceFilterParseException(JavaBundle.message("slice.filter.parse.error.enum.constant.not.found", filter));
      }
    }
    PsiExpression constant;
    try {
      constant = JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(filter, expression);
    }
    catch (IncorrectOperationException ignore) {
      throw new SliceFilterParseException(JavaBundle.message("slice.filter.parse.error.incorrect.expression", filter));
    }
    PsiType constantType = constant.getType();
    if (constantType == null || !type.isAssignableFrom(constantType)) {
      throw new SliceFilterParseException(JavaBundle.message("slice.filter.parse.error.incorrect.constant.type", type.getPresentableText()));
    }
    Object o = ExpressionUtils.computeConstantExpression(constant);
    if (o == null) {
      throw new SliceFilterParseException(JavaBundle.message("slice.filter.parse.error.expression.must.evaluate.to.constant", filter));
    }
    if (relationType != RelationType.EQ) {
      if (!(o instanceof Number)) {
        throw new SliceFilterParseException(JavaBundle.message("slice.filter.parse.error.incorrect.constant.expected.number", filter));
      }
      if (PsiTypes.longType().equals(type)) {
        LongRangeSet rangeSet = LongRangeSet.point(((Number)o).longValue()).fromRelation(relationType);
        return new JavaValueFilter(DfTypes.longRange(rangeSet));
      }
      LongRangeSet rangeSet = LongRangeSet.point(((Number)o).intValue()).fromRelation(relationType);
      return new JavaValueFilter(DfTypes.intRangeClamped(rangeSet));
    }
    return new JavaValueFilter(DfTypes.constant(o, type));
  }
@Override
  public @NotNull SliceValueFilter parseFilter(@NotNull PsiElement expression, @NotNull String filter)