protected Number narrowNumber(Number original, Class<?> narrow) {
    if (original == null) {
      return original;
    }
    Number result = original;
    if (original instanceof BigDecimal) {
      BigDecimal bigd = (BigDecimal) original;
      // if it's bigger than a double it can't be narrowed
      if (bigd.compareTo(BIGD_DOUBLE_MAX_VALUE) > 0) {
        return original;
      }
      else {
        try {
          long l = bigd.longValueExact();
          // coerce to int when possible (int being so often used in method
          // parms)
          if (narrowAccept(narrow, Integer.class) && l <= Integer.MAX_VALUE && l >= Integer.MIN_VALUE) {
            return Integer.valueOf((int) l);
          }
          else if (narrowAccept(narrow, Long.class)) {
            return Long.valueOf(l);
          }
        }
        catch (ArithmeticException xa) {
          // ignore, no exact value possible
        }
      }
    }
    if (original instanceof Double || original instanceof Float || original instanceof BigDecimal) {
      double value = original.doubleValue();
      if (narrowAccept(narrow, Float.class) && value <= Float.MAX_VALUE && value >= Float.MIN_VALUE) {
        result = Float.valueOf(result.floatValue());
      }
      // else it fits in a double only
    }
    else {
      if (original instanceof BigInteger) {
        BigInteger bigi = (BigInteger) original;
        // if it's bigger than a Long it can't be narrowed
        if (bigi.compareTo(BIGI_LONG_MAX_VALUE) > 0 || bigi.compareTo(BIGI_LONG_MIN_VALUE) < 0) {
          return original;
        }
      }
      long value = original.longValue();
      if (narrowAccept(narrow, Byte.class) && value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) {
        // it will fit in a byte
        result = Byte.valueOf((byte) value);
      }
      else if (narrowAccept(narrow, Short.class) && value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) {
        result = Short.valueOf((short) value);
      }
      else if (narrowAccept(narrow, Integer.class) && value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE) {
        result = Integer.valueOf((int) value);
      }
      // else it fits in a long
    }
    return result;
  }
protected Number narrowNumber ( Number original , Class < ? > narrow ) { if ( original == null ) { return original ; } Number result = original ; if ( original instanceof BigDecimal ) { BigDecimal bigd = ( BigDecimal ) original ; if ( bigd . compareTo ( BIGD_DOUBLE_MAX_VALUE ) > 0 ) { return original ; } else { try { long l = bigd . longValueExact ( ) ; if ( narrowAccept ( narrow , Integer . class ) && l <= Integer . MAX_VALUE && l >= Integer . MIN_VALUE ) { return Integer . valueOf ( ( int ) l ) ; } else if ( narrowAccept ( narrow , Long . class ) ) { return Long . valueOf ( l ) ; } } catch ( ArithmeticException xa ) { } } } if ( original instanceof Double || original instanceof Float || original instanceof BigDecimal ) { double value = original . doubleValue ( ) ; if ( narrowAccept ( narrow , Float . class ) && value <= Float . MAX_VALUE && value >= Float . MIN_VALUE ) { result = Float . valueOf ( result . floatValue ( ) ) ; } } else { if ( original instanceof BigInteger ) { BigInteger bigi = ( BigInteger ) original ; if ( bigi . compareTo ( BIGI_LONG_MAX_VALUE ) > 0 || bigi . compareTo ( BIGI_LONG_MIN_VALUE ) < 0 ) { return original ; } } long value = original . longValue ( ) ; if ( narrowAccept ( narrow , Byte . class ) && value <= Byte . MAX_VALUE && value >= Byte . MIN_VALUE ) { result = Byte . valueOf ( ( byte ) value ) ; } else if ( narrowAccept ( narrow , Short . class ) && value <= Short . MAX_VALUE && value >= Short . MIN_VALUE ) { result = Short . valueOf ( ( short ) value ) ; } else if ( narrowAccept ( narrow , Integer . class ) && value <= Integer . MAX_VALUE && value >= Integer . MIN_VALUE ) { result = Integer . valueOf ( ( int ) value ) ; } } return result ; }
Given a Number, return back the value attempting to narrow it to a target
class.

@param original
the original number
@param narrow
the attempted target class
@return the narrowed number or the source if no narrowing was possible