public static Expression convert(Predicate[] predicates) {
    Expression expression = Expressions.alwaysTrue();
    for (Predicate predicate : predicates) {
      Expression converted = convert(predicate);
      Preconditions.checkArgument(
          converted != null, "Cannot convert Spark predicate to Iceberg expression: %s", predicate);
      expression = Expressions.and(expression, converted);
    }

    return expression;
  }
@Test
  public void testNotInNull() {
    String col = "strCol";
    NamedReference namedReference = FieldReference.apply(col);
    LiteralValue nullValue = new LiteralValue(null, DataTypes.StringType);
    LiteralValue value1 = new LiteralValue("value1", DataTypes.StringType);
    LiteralValue value2 = new LiteralValue("value2", DataTypes.StringType);

    // Values only contains null
    Predicate notInNull = new Not(new Predicate("IN", expressions(namedReference, nullValue)));
    Expression expectedNotInNull =
        Expressions.and(Expressions.notNull(col), Expressions.notIn(col));
    Expression actualNotInNull = SparkV2Filters.convert(notInNull);
    assertEquals(expectedNotInNull, actualNotInNull);

    Predicate notIn =
        new Not(new Predicate("IN", expressions(namedReference, nullValue, value1, value2)));
    Expression expectedNotIn =
        Expressions.and(Expressions.notNull(col), Expressions.notIn(col, "value1", "value2"));
    Expression actualNotIn = SparkV2Filters.convert(notIn);
    assertEquals(expectedNotIn, actualNotIn);
  }