public static <E> Predicate byRanges(
      Root<E> root,
      CriteriaQuery<?> query,
      CriteriaBuilder builder,
      final List<Range<?, ?>> ranges,
      final Class<E> type) {

    List<Predicate> predicates = newArrayList();
    for (Range<?, ?> r : ranges) {
      @SuppressWarnings("unchecked")
      Range<E, ?> range = (Range<E, ?>) r;
      if (range.isSet()) {
        Predicate rangePredicate = buildRangePredicate(range, root, builder);

        if (rangePredicate != null) {
          if (!range.isIncludeNullSet() || range.getIncludeNull() == FALSE) {
            predicates.add(rangePredicate);
          } else {
            predicates.add(builder.or(rangePredicate, builder.isNull(root.get(range.getField()))));
          }
        }

        // no range at all, let's take the opportunity to keep only null...
        if (TRUE == range.getIncludeNull()) {
          predicates.add(builder.isNull(root.get(range.getField())));
        } else if (FALSE == range.getIncludeNull()) {
          predicates.add(builder.isNotNull(root.get(range.getField())));
        }
      }
    }

    return JpaUtil.andPredicate(builder, predicates);
  }