public static Expression convert(Filter[] filters) {
    Expression expression = Expressions.alwaysTrue();
    for (Filter filter : filters) {
      Expression converted = convert(filter);
      Preconditions.checkArgument(
          converted != null, "Cannot convert filter to Iceberg: %s", filter);
      expression = Expressions.and(expression, converted);
    }
    return expression;
  }
@Test
  public void testQuotedAttributes() {
    Map<String, String> attrMap = Maps.newHashMap();
    attrMap.put("id", "id");
    attrMap.put("`i.d`", "i.d");
    attrMap.put("`i``d`", "i`d");
    attrMap.put("`d`.b.`dd```", "d.b.dd`");
    attrMap.put("a.`aa```.c", "a.aa`.c");

    attrMap.forEach(
        (quoted, unquoted) -> {
          IsNull isNull = IsNull.apply(quoted);
          Expression expectedIsNull = Expressions.isNull(unquoted);
          Expression actualIsNull = SparkFilters.convert(isNull);
          assertThat(actualIsNull.toString())
              .as("IsNull must match")
              .isEqualTo(expectedIsNull.toString());

          IsNotNull isNotNull = IsNotNull.apply(quoted);
          Expression expectedIsNotNull = Expressions.notNull(unquoted);
          Expression actualIsNotNull = SparkFilters.convert(isNotNull);
          assertThat(actualIsNotNull.toString())
              .as("IsNotNull must match")
              .isEqualTo(expectedIsNotNull.toString());

          LessThan lt = LessThan.apply(quoted, 1);
          Expression expectedLt = Expressions.lessThan(unquoted, 1);
          Expression actualLt = SparkFilters.convert(lt);
          assertThat(actualLt.toString())
              .as("LessThan must match")
              .isEqualTo(expectedLt.toString());

          LessThanOrEqual ltEq = LessThanOrEqual.apply(quoted, 1);
          Expression expectedLtEq = Expressions.lessThanOrEqual(unquoted, 1);
          Expression actualLtEq = SparkFilters.convert(ltEq);
          assertThat(actualLtEq.toString())
              .as("LessThanOrEqual must match")
              .isEqualTo(expectedLtEq.toString());

          GreaterThan gt = GreaterThan.apply(quoted, 1);
          Expression expectedGt = Expressions.greaterThan(unquoted, 1);
          Expression actualGt = SparkFilters.convert(gt);
          assertThat(actualGt.toString())
              .as("GreaterThan must match")
              .isEqualTo(expectedGt.toString());

          GreaterThanOrEqual gtEq = GreaterThanOrEqual.apply(quoted, 1);
          Expression expectedGtEq = Expressions.greaterThanOrEqual(unquoted, 1);
          Expression actualGtEq = SparkFilters.convert(gtEq);
          assertThat(actualGtEq.toString())
              .as("GreaterThanOrEqual must match")
              .isEqualTo(expectedGtEq.toString());

          EqualTo eq = EqualTo.apply(quoted, 1);
          Expression expectedEq = Expressions.equal(unquoted, 1);
          Expression actualEq = SparkFilters.convert(eq);
          assertThat(actualEq.toString()).as("EqualTo must match").isEqualTo(expectedEq.toString());

          EqualNullSafe eqNullSafe = EqualNullSafe.apply(quoted, 1);
          Expression expectedEqNullSafe = Expressions.equal(unquoted, 1);
          Expression actualEqNullSafe = SparkFilters.convert(eqNullSafe);
          assertThat(actualEqNullSafe.toString())
              .as("EqualNullSafe must match")
              .isEqualTo(expectedEqNullSafe.toString());

          In in = In.apply(quoted, new Integer[] {1});
          Expression expectedIn = Expressions.in(unquoted, 1);
          Expression actualIn = SparkFilters.convert(in);
          assertThat(actualIn.toString()).as("In must match").isEqualTo(expectedIn.toString());
        });
  }