code: @SuppressWarnings("unchecked")
    static Iterator<MarkerRange.Builder> add(
        Range constraint, List<FieldPartitioner> fps,
        Iterator<MarkerRange.Builder> inner) {
  
      Iterator<MarkerRange.Builder> current = inner;
      List<Pair<String, Range>> compatible = Lists.newArrayList();
      for (FieldPartitioner fp : fps) {
        Predicate<?> projected = fp.project(constraint);
        if (projected instanceof In) {
          current = addProjected(projected, fp.getName(), current);
        } else if (projected instanceof Range) {
          compatible.add(Pair.of(fp.getName(), (Range) projected));
        }
        // otherwise, all fields are included, so don't add anything
      }
  
      if (compatible.size() < 1) {
        return current;
      } else if (compatible.size() == 1) {
        Pair<String, Range> pair = compatible.get(0);
        return addProjected((Predicate<?>) pair.second(), pair.first(), current);
      } else {
        return new RangeGroupIterator(constraint, compatible, current);
      }
    }
docs: Convenience function to add the correct wrapper {@link StackedIterator} to
  the key range Iterator stack.
  
  This method checks the projected constraints to ensure they are compatible
  and can be used in a grouped iterator. The constraints that are not are
  added as a separate {@code StackedIterator}. For example, constraints
  projected by {@link org.kitesdk.data.spi.partition.ListFieldPartitioner} are
  "in" constraints and can't be grouped with ranges.
  
  @param constraint A "range" constraint for the <em>source</em> values
  @param fps A List of FieldPartitioners with the same source field
  @param inner An {@code Iterator} to wrap
  @return A key range Iterator