@Override
  public Filter getFilter(Element e) throws ParserException {
    String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
    String lowerTerm = DOMUtils.getAttributeOrFail(e, "lowerTerm");
    String upperTerm = DOMUtils.getAttributeOrFail(e, "upperTerm");
    boolean lowerInclusive = DOMUtils.getAttribute(e, "includeLower", true);
    boolean upperInclusive = DOMUtils.getAttribute(e, "includeUpper", true);
    int precisionStep =
        DOMUtils.getAttribute(e, "precisionStep", NumericUtils.PRECISION_STEP_DEFAULT);

    String type = DOMUtils.getAttribute(e, "type", "int");
    try {
      Filter filter;
      if (type.equalsIgnoreCase("int")) {
        filter =
            NumericRangeFilter.newIntRange(
                field,
                precisionStep,
                Integer.valueOf(lowerTerm),
                Integer.valueOf(upperTerm),
                lowerInclusive,
                upperInclusive);
      } else if (type.equalsIgnoreCase("long")) {
        filter =
            NumericRangeFilter.newLongRange(
                field,
                precisionStep,
                Long.valueOf(lowerTerm),
                Long.valueOf(upperTerm),
                lowerInclusive,
                upperInclusive);
      } else if (type.equalsIgnoreCase("double")) {
        filter =
            NumericRangeFilter.newDoubleRange(
                field,
                precisionStep,
                Double.valueOf(lowerTerm),
                Double.valueOf(upperTerm),
                lowerInclusive,
                upperInclusive);
      } else if (type.equalsIgnoreCase("float")) {
        filter =
            NumericRangeFilter.newFloatRange(
                field,
                precisionStep,
                Float.valueOf(lowerTerm),
                Float.valueOf(upperTerm),
                lowerInclusive,
                upperInclusive);
      } else {
        throw new ParserException("type attribute must be one of: [long, int, double, float]");
      }
      return filter;
    } catch (NumberFormatException nfe) {
      if (strictMode) {
        throw new ParserException("Could not parse lowerTerm or upperTerm into a number", nfe);
      }
      return NO_MATCH_FILTER;
    }
  }
 @Override
 public Filter nullValueFilter() {
   if (nullValue == null) {
     return null;
   }
   return NumericRangeFilter.newIntRange(
       names.indexName(), precisionStep, nullValue, nullValue, true, true);
 }
 @Override
 public Filter rangeFilter(
     Object lowerTerm,
     Object upperTerm,
     boolean includeLower,
     boolean includeUpper,
     @Nullable QueryParseContext context) {
   return NumericRangeFilter.newIntRange(
       names.indexName(),
       precisionStep,
       lowerTerm == null ? null : parseValue(lowerTerm),
       upperTerm == null ? null : parseValue(upperTerm),
       includeLower,
       includeUpper);
 }
 @Override
 public Filter rangeFilter(
     String lowerTerm,
     String upperTerm,
     boolean includeLower,
     boolean includeUpper,
     @Nullable QueryParseContext context) {
   return NumericRangeFilter.newIntRange(
       names.indexName(),
       precisionStep,
       lowerTerm == null ? null : Integer.parseInt(lowerTerm),
       upperTerm == null ? null : Integer.parseInt(upperTerm),
       includeLower,
       includeUpper);
 }
  public void testIsCacheAble() throws Exception {
    Directory dir = newDirectory();
    RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
    writer.addDocument(new Document());
    writer.close();

    IndexReader reader = SlowCompositeReaderWrapper.wrap(DirectoryReader.open(dir));

    // not cacheable:
    assertDocIdSetCacheable(
        reader, new QueryWrapperFilter(new TermQuery(new Term("test", "value"))), false);
    // returns default empty docidset, always cacheable:
    assertDocIdSetCacheable(
        reader,
        NumericRangeFilter.newIntRange(
            "test", Integer.valueOf(10000), Integer.valueOf(-10000), true, true),
        true);
    // is cacheable:
    assertDocIdSetCacheable(
        reader,
        FieldCacheRangeFilter.newIntRange(
            "test", Integer.valueOf(10), Integer.valueOf(20), true, true),
        true);
    // a fixedbitset filter is always cacheable
    assertDocIdSetCacheable(
        reader,
        new Filter() {
          @Override
          public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) {
            return new FixedBitSet(context.reader().maxDoc());
          }
        },
        true);

    reader.close();
    dir.close();
  }
 @Override
 public Filter termFilter(Object value, @Nullable QueryParseContext context) {
   int iValue = parseValue(value);
   return NumericRangeFilter.newIntRange(
       names.indexName(), precisionStep, iValue, iValue, true, true);
 }
 @Override
 public Filter fieldFilter(String value, @Nullable QueryParseContext context) {
   int iValue = Integer.parseInt(value);
   return NumericRangeFilter.newIntRange(
       names.indexName(), precisionStep, iValue, iValue, true, true);
 }