public Predicate<InMemoryFilterable> parse(final List<String> filterExpressions,
                                               final List<EntityAttribute> attributes) {
        if (filterExpressions == null || filterExpressions.isEmpty()) {
            return Predicates.alwaysTrue();
        }
        final Map<String, List<Filter>> groupedByField = filterExpressions.stream()
                .map(expr -> singleFilterParser.parseSingleExpression(expr, attributes))
                .collect(groupingBy(Filter::field));

        return groupedByField.values().stream()
                .map(grouped -> grouped.stream()
                        .map(Filter::toPredicate)
                        .collect(Collectors.toList()))
                .map(groupedPredicates -> groupedPredicates.stream().reduce(Predicate::or).orElse(Predicates.alwaysTrue()))
                .reduce(Predicate::and).orElse(Predicates.alwaysTrue());
    }
@Test
    void groupsMultipleFilterForTheSameFieldUsingOrLogic() {

        final List<EntityAttribute> attributes = List.of(EntityAttribute.builder()
                        .id("owner")
                        .title("Owner")
                        .filterable(true)
                        .build(),
                EntityAttribute.builder()
                        .id("title")
                        .title("Title")
                        .filterable(true)
                        .build());


        final Predicate<InMemoryFilterable> predicate = toTest.parse(List.of("owner:baldwin", "owner:beomund", "title:crusade"), attributes);
        assertTrue(predicate.test(createMock(Map.of("owner", "baldwin", "title", "crusade"))));
        assertTrue(predicate.test(createMock(Map.of("owner", "beomund", "title", "crusade"))));
        assertFalse(predicate.test(createMock(Map.of("owner", "casimir", "title", "crusade"))));
        assertFalse(predicate.test(createMock(Map.of("owner", "beomund", "title", "whatever"))));
    }