protected <N extends Number> NumericRangeQuery<?> numericRange(
     Class<N> clazz,
     String field,
     @Nullable N min,
     @Nullable N max,
     boolean minInc,
     boolean maxInc) {
   if (clazz.equals(Integer.class)) {
     return NumericRangeQuery.newIntRange(field, (Integer) min, (Integer) max, minInc, maxInc);
   } else if (clazz.equals(Double.class)) {
     return NumericRangeQuery.newDoubleRange(field, (Double) min, (Double) max, minInc, minInc);
   } else if (clazz.equals(Float.class)) {
     return NumericRangeQuery.newFloatRange(field, (Float) min, (Float) max, minInc, minInc);
   } else if (clazz.equals(Long.class)) {
     return NumericRangeQuery.newLongRange(field, (Long) min, (Long) max, minInc, minInc);
   } else if (clazz.equals(Byte.class) || clazz.equals(Short.class)) {
     return NumericRangeQuery.newIntRange(
         field,
         min != null ? min.intValue() : null,
         max != null ? max.intValue() : null,
         minInc,
         maxInc);
   } else {
     throw new IllegalArgumentException("Unsupported numeric type " + clazz.getName());
   }
 }
 private static <N extends Number> N scale(Class<N> type, double value, N min, N max) {
   if (type.isAssignableFrom(Integer.class))
     return type.cast(Integer.valueOf((int) (value * max.intValue() + min.intValue())));
   if (type.isAssignableFrom(Double.class))
     return type.cast((value * max.doubleValue() + min.doubleValue()));
   if (type.isAssignableFrom(Long.class))
     return type.cast(Long.valueOf((long) (value * max.longValue() + min.longValue())));
   if (type.isAssignableFrom(Short.class))
     return type.cast(Short.valueOf((short) (value * max.shortValue() + min.shortValue())));
   if (type.isAssignableFrom(Byte.class))
     return type.cast(Byte.valueOf((byte) (value * max.byteValue() + min.byteValue())));
   if (type.isAssignableFrom(Float.class))
     return type.cast(Float.valueOf((float) (value * max.floatValue() + min.floatValue())));
   return null;
 }