You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by cb...@apache.org on 2009/01/23 07:32:46 UTC

svn commit: r736963 [9/21] - in /ibatis/trunk/java/ibatis-3: ibatis-3-compat/src/main/java/com/ibatis/common/jdbc/ ibatis-3-compat/src/main/java/com/ibatis/common/resources/ ibatis-3-compat/src/main/java/com/ibatis/common/util/ ibatis-3-compat/src/main...

Modified: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlOps.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlOps.java?rev=736963&r1=736962&r2=736963&view=diff
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlOps.java (original)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/ognl/OgnlOps.java Thu Jan 22 22:32:36 2009
@@ -37,692 +37,664 @@
 
 /**
  * This is an abstract class with static methods that define the operations of OGNL.
+ *
  * @author Luke Blanshard (blanshlu@netscape.net)
  * @author Drew Davidson (drew@ognl.org)
  */
-public abstract class OgnlOps implements NumericTypes
-{
-    /**
-     * Compares two objects for equality, even if it has to convert
-     * one of them to the other type.  If both objects are numeric
-     * they are converted to the widest type and compared.  If
-     * one is non-numeric and one is numeric the non-numeric is
-     * converted to double and compared to the double numeric
-     * value.  If both are non-numeric and Comparable and the
-     * types are compatible (i.e. v1 is of the same or superclass
-     * of v2's type) they are compared with Comparable.compareTo().
-     * If both values are non-numeric and not Comparable or of
-     * incompatible classes this will throw and IllegalArgumentException.
-     *
-     * @param v1    First value to compare
-     * @param v2    second value to compare
-     *
-     * @return integer describing the comparison between the two objects.
-     *          A negative number indicates that v1 < v2.  Positive indicates
-     *          that v1 > v2.  Zero indicates v1 == v2.
-     *
-     * @throws IllegalArgumentException if the objects are both non-numeric
-     *              yet of incompatible types or do not implement Comparable.
-     */
-    public static int compareWithConversion( Object v1, Object v2 )
-    {
-        return compareWithConversion(v1, v2, false);
-    }
-
-    /**
-     * Compares two objects for equality, even if it has to convert
-     * one of them to the other type.  If both objects are numeric
-     * they are converted to the widest type and compared.  If
-     * one is non-numeric and one is numeric the non-numeric is
-     * converted to double and compared to the double numeric
-     * value.  If both are non-numeric and Comparable and the
-     * types are compatible (i.e. v1 is of the same or superclass
-     * of v2's type) they are compared with Comparable.compareTo().
-     * If both values are non-numeric and not Comparable or of
-     * incompatible classes this will throw and IllegalArgumentException.
-     *
-     * @param v1    First value to compare
-     * @param v2    second value to compare
-     *
-     * @return integer describing the comparison between the two objects.
-     *          A negative number indicates that v1 < v2.  Positive indicates
-     *          that v1 > v2.  Zero indicates v1 == v2.
-     *
-     * @throws IllegalArgumentException if the objects are both non-numeric
-     *              yet of incompatible types or do not implement Comparable.
-     */
-    public static int compareWithConversion( Object v1, Object v2, boolean equals )
-    {
-        int     result;
-
-        if (v1 == v2) {
-            result = 0;
-        } else {
-            int     t1 = getNumericType(v1),
-                    t2 = getNumericType(v2),
-                    type = getNumericType(t1, t2, true);
-
-            switch (type) {
-                case BIGINT:
-                    result = bigIntValue(v1).compareTo(bigIntValue(v2));
-                    break;
-
-                case BIGDEC:
-                    result = bigDecValue(v1).compareTo(bigDecValue(v2));
+public abstract class OgnlOps implements NumericTypes {
+  /**
+   * Compares two objects for equality, even if it has to convert
+   * one of them to the other type.  If both objects are numeric
+   * they are converted to the widest type and compared.  If
+   * one is non-numeric and one is numeric the non-numeric is
+   * converted to double and compared to the double numeric
+   * value.  If both are non-numeric and Comparable and the
+   * types are compatible (i.e. v1 is of the same or superclass
+   * of v2's type) they are compared with Comparable.compareTo().
+   * If both values are non-numeric and not Comparable or of
+   * incompatible classes this will throw and IllegalArgumentException.
+   *
+   * @param v1 First value to compare
+   * @param v2 second value to compare
+   * @return integer describing the comparison between the two objects.
+   *         A negative number indicates that v1 < v2.  Positive indicates
+   *         that v1 > v2.  Zero indicates v1 == v2.
+   * @throws IllegalArgumentException if the objects are both non-numeric
+   *                                  yet of incompatible types or do not implement Comparable.
+   */
+  public static int compareWithConversion(Object v1, Object v2) {
+    return compareWithConversion(v1, v2, false);
+  }
+
+  /**
+   * Compares two objects for equality, even if it has to convert
+   * one of them to the other type.  If both objects are numeric
+   * they are converted to the widest type and compared.  If
+   * one is non-numeric and one is numeric the non-numeric is
+   * converted to double and compared to the double numeric
+   * value.  If both are non-numeric and Comparable and the
+   * types are compatible (i.e. v1 is of the same or superclass
+   * of v2's type) they are compared with Comparable.compareTo().
+   * If both values are non-numeric and not Comparable or of
+   * incompatible classes this will throw and IllegalArgumentException.
+   *
+   * @param v1 First value to compare
+   * @param v2 second value to compare
+   * @return integer describing the comparison between the two objects.
+   *         A negative number indicates that v1 < v2.  Positive indicates
+   *         that v1 > v2.  Zero indicates v1 == v2.
+   * @throws IllegalArgumentException if the objects are both non-numeric
+   *                                  yet of incompatible types or do not implement Comparable.
+   */
+  public static int compareWithConversion(Object v1, Object v2, boolean equals) {
+    int result;
+
+    if (v1 == v2) {
+      result = 0;
+    } else {
+      int t1 = getNumericType(v1),
+          t2 = getNumericType(v2),
+          type = getNumericType(t1, t2, true);
+
+      switch (type) {
+        case BIGINT:
+          result = bigIntValue(v1).compareTo(bigIntValue(v2));
+          break;
+
+        case BIGDEC:
+          result = bigDecValue(v1).compareTo(bigDecValue(v2));
+          break;
+
+        case NONNUMERIC:
+          if ((t1 == NONNUMERIC) && (t2 == NONNUMERIC)) {
+            if ((v1 == null) || (v2 == null)) {
+              result = (v1 == v2) ? 0 : 1;
+            } else {
+              if (v1.getClass().isAssignableFrom(v2.getClass()) || v2.getClass().isAssignableFrom(v1.getClass())) {
+                if (v1 instanceof Comparable) {
+                  result = ((Comparable) v1).compareTo(v2);
+                  break;
+                } else {
+                  if (equals) {
+                    result = v1.equals(v2) ? 0 : 1;
                     break;
-
-                case NONNUMERIC:
-                    if ((t1 == NONNUMERIC) && (t2 == NONNUMERIC)) {
-                        if ((v1 == null) || (v2 == null)) {
-                            result = (v1 == v2) ? 0 : 1;
-                        } else {
-                            if (v1.getClass().isAssignableFrom(v2.getClass()) || v2.getClass().isAssignableFrom(v1.getClass())) {
-                                if (v1 instanceof Comparable) {
-                                    result = ((Comparable)v1).compareTo(v2);
-                                    break;
-                                } else {
-                                    if (equals) {
-                                        result = v1.equals(v2) ? 0 : 1;
-                                        break;
-                                    }
-                                }
-                            }
-                            if (equals) {
-                                // Equals comparison between non-numerics that are not of a common
-                                // superclass return not equal
-                                result = 1;
-                                break;
-                            } else {
-                                throw new IllegalArgumentException("invalid comparison: " + v1.getClass().getName() + " and " + v2.getClass().getName());
-                            }
-                        }
-                    }
-                    // else fall through
-                case FLOAT:
-                case DOUBLE:
-                    double      dv1 = doubleValue(v1),
-                                dv2 = doubleValue(v2);
-
-                    return (dv1 == dv2) ? 0 : ((dv1 < dv2) ? -1 : 1);
-
-                default:
-                    long        lv1 = longValue(v1),
-                                lv2 = longValue(v2);
-
-                    return (lv1 == lv2) ? 0 : ((lv1 < lv2) ? -1 : 1);
-              }
-        }
-        return result;
-    }
-
-    /**
-     * Returns true if object1 is equal to object2 in either the
-     * sense that they are the same object or, if both are non-null
-     * if they are equal in the <CODE>equals()</CODE> sense.
-     *
-     * @param v1 First object to compare
-     * @param v2 Second object to compare
-     *
-     * @return true if v1 == v2
-     */
-    public static boolean isEqual(Object object1, Object object2)
-    {
-        boolean     result = false;
-
-          if (object1 == object2) {
-              result = true;
-          } else {
-              if ((object1 != null) && (object2 != null)) {
-                  if (object1.getClass().isArray() && object2.getClass().isArray() && (object2.getClass() == object1.getClass())) {
-                      result = (Array.getLength(object1) == Array.getLength(object2));
-                    if (result) {
-                        for (int i = 0, icount = Array.getLength(object1); result && (i < icount); i++) {
-                            result = isEqual(Array.get(object1, i), Array.get(object2, i));
-                        }
-                    }
-                  } else {
-                      if ((object1 != null) && (object2 != null)) {
-                          // Check for converted equivalence first, then equals() equivalence
-                        result = (compareWithConversion(object1, object2, true) == 0) || object1.equals(object2);
-                    }
+                  }
                 }
+              }
+              if (equals) {
+                // Equals comparison between non-numerics that are not of a common
+                // superclass return not equal
+                result = 1;
+                break;
+              } else {
+                throw new IllegalArgumentException("invalid comparison: " + v1.getClass().getName() + " and " + v2.getClass().getName());
+              }
             }
+          }
+          // else fall through
+        case FLOAT:
+        case DOUBLE:
+          double dv1 = doubleValue(v1),
+              dv2 = doubleValue(v2);
+
+          return (dv1 == dv2) ? 0 : ((dv1 < dv2) ? -1 : 1);
+
+        default:
+          long lv1 = longValue(v1),
+              lv2 = longValue(v2);
+
+          return (lv1 == lv2) ? 0 : ((lv1 < lv2) ? -1 : 1);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Returns true if object1 is equal to object2 in either the
+   * sense that they are the same object or, if both are non-null
+   * if they are equal in the <CODE>equals()</CODE> sense.
+   *
+   * @param v1 First object to compare
+   * @param v2 Second object to compare
+   * @return true if v1 == v2
+   */
+  public static boolean isEqual(Object object1, Object object2) {
+    boolean result = false;
+
+    if (object1 == object2) {
+      result = true;
+    } else {
+      if ((object1 != null) && (object2 != null)) {
+        if (object1.getClass().isArray() && object2.getClass().isArray() && (object2.getClass() == object1.getClass())) {
+          result = (Array.getLength(object1) == Array.getLength(object2));
+          if (result) {
+            for (int i = 0, icount = Array.getLength(object1); result && (i < icount); i++) {
+              result = isEqual(Array.get(object1, i), Array.get(object2, i));
+            }
+          }
+        } else {
+          if ((object1 != null) && (object2 != null)) {
+            // Check for converted equivalence first, then equals() equivalence
+            result = (compareWithConversion(object1, object2, true) == 0) || object1.equals(object2);
+          }
         }
-        return result;
+      }
     }
+    return result;
+  }
 
-      /**
-       * Evaluates the given object as a boolean: if it is a Boolean object, it's easy; if
-       * it's a Number or a Character, returns true for non-zero objects; and otherwise
-       * returns true for non-null objects.
-       *
-       * @param value an object to interpret as a boolean
-       * @return the boolean value implied by the given object
-       */
-    public static boolean booleanValue( Object value )
-    {
-        if ( value == null )
-            return false;
-        Class c = value.getClass();
-        if ( c == Boolean.class )
-            return ((Boolean)value).booleanValue();
+  /**
+   * Evaluates the given object as a boolean: if it is a Boolean object, it's easy; if
+   * it's a Number or a Character, returns true for non-zero objects; and otherwise
+   * returns true for non-null objects.
+   *
+   * @param value an object to interpret as a boolean
+   * @return the boolean value implied by the given object
+   */
+  public static boolean booleanValue(Object value) {
+    if (value == null)
+      return false;
+    Class c = value.getClass();
+    if (c == Boolean.class)
+      return ((Boolean) value).booleanValue();
 //        if ( c == String.class )
 //            return ((String)value).length() > 0;
-        if ( c == Character.class )
-            return ((Character)value).charValue() != 0;
-        if ( value instanceof Number )
-            return ((Number)value).doubleValue() != 0;
-        return true; // non-null
-    }
-
-      /**
-       * Evaluates the given object as a long integer.
-       *
-       * @param value an object to interpret as a long integer
-       * @return the long integer value implied by the given object
-       * @throws NumberFormatException if the given object can't be understood as a long integer
-       */
-    public static long longValue( Object value ) throws NumberFormatException
-    {
-        if (value == null)
-            return 0L;
-        Class c = value.getClass();
-        if ( c.getSuperclass() == Number.class )
-            return ((Number)value).longValue();
-        if ( c == Boolean.class )
-            return ((Boolean)value).booleanValue()? 1 : 0;
-        if ( c == Character.class )
-            return ((Character)value).charValue();
-        return Long.parseLong( stringValue(value, true) );
-    }
-
-      /**
-       * Evaluates the given object as a double-precision floating-point number.
-       *
-       * @param value an object to interpret as a double
-       * @return the double value implied by the given object
-       * @throws NumberFormatException if the given object can't be understood as a double
-       */
-    public static double doubleValue( Object value ) throws NumberFormatException
-    {
-        if (value == null)
-            return 0.0;
-        Class c = value.getClass();
-        if ( c.getSuperclass() == Number.class )
-            return ((Number)value).doubleValue();
-        if ( c == Boolean.class )
-            return ((Boolean)value).booleanValue()? 1 : 0;
-        if ( c == Character.class )
-            return ((Character)value).charValue();
-        String  s = stringValue(value, true);
-
-        return (s.length() == 0) ? 0.0 : Double.parseDouble( s );
-        /*
-            For 1.1 parseDouble() is not available
-         */
-        //return Double.valueOf( value.toString() ).doubleValue();
-    }
-
-      /**
-       * Evaluates the given object as a BigInteger.
-       *
-       * @param value an object to interpret as a BigInteger
-       * @return the BigInteger value implied by the given object
-       * @throws NumberFormatException if the given object can't be understood as a BigInteger
-       */
-    public static BigInteger bigIntValue( Object value ) throws NumberFormatException
-    {
-        if (value == null)
-            return BigInteger.valueOf(0L);
-        Class c = value.getClass();
-        if ( c == BigInteger.class )
-            return (BigInteger)value;
-        if ( c == BigDecimal.class )
-            return ((BigDecimal)value).toBigInteger();
-        if ( c.getSuperclass() == Number.class )
-            return BigInteger.valueOf( ((Number)value).longValue() );
-        if ( c == Boolean.class )
-            return BigInteger.valueOf( ((Boolean)value).booleanValue()? 1 : 0 );
-        if ( c == Character.class )
-            return BigInteger.valueOf( ((Character)value).charValue() );
-        return new BigInteger( stringValue(value, true) );
-    }
-
-      /**
-       * Evaluates the given object as a BigDecimal.
-       *
-       * @param value an object to interpret as a BigDecimal
-       * @return the BigDecimal value implied by the given object
-       * @throws NumberFormatException if the given object can't be understood as a BigDecimal
-       */
-    public static BigDecimal bigDecValue( Object value ) throws NumberFormatException
-    {
-        if (value == null)
-            return BigDecimal.valueOf(0L);
-        Class c = value.getClass();
-        if ( c == BigDecimal.class )
-            return (BigDecimal)value;
-        if ( c == BigInteger.class )
-            return new BigDecimal( (BigInteger)value );
-        if ( c.getSuperclass() == Number.class )
-            return new BigDecimal( ((Number)value).doubleValue() );
-        if ( c == Boolean.class )
-            return BigDecimal.valueOf( ((Boolean)value).booleanValue()? 1 : 0 );
-        if ( c == Character.class )
-            return BigDecimal.valueOf( ((Character)value).charValue() );
-        return new BigDecimal( stringValue(value, true) );
-    }
-
-      /**
-       * Evaluates the given object as a String and trims it if the trim flag is true.
-       *
-       * @param value an object to interpret as a String
-       * @return the String value implied by the given object as returned by the toString() method,
-                or "null" if the object is null.
-       */
-    public static String stringValue( Object value, boolean trim )
-    {
-        String      result;
-
-        if (value == null) {
-            result = OgnlRuntime.NULL_STRING;
-        } else {
-            result = value.toString();
-            if (trim) {
-               result = result.trim();
-            }
+    if (c == Character.class)
+      return ((Character) value).charValue() != 0;
+    if (value instanceof Number)
+      return ((Number) value).doubleValue() != 0;
+    return true; // non-null
+  }
+
+  /**
+   * Evaluates the given object as a long integer.
+   *
+   * @param value an object to interpret as a long integer
+   * @return the long integer value implied by the given object
+   * @throws NumberFormatException if the given object can't be understood as a long integer
+   */
+  public static long longValue(Object value) throws NumberFormatException {
+    if (value == null)
+      return 0L;
+    Class c = value.getClass();
+    if (c.getSuperclass() == Number.class)
+      return ((Number) value).longValue();
+    if (c == Boolean.class)
+      return ((Boolean) value).booleanValue() ? 1 : 0;
+    if (c == Character.class)
+      return ((Character) value).charValue();
+    return Long.parseLong(stringValue(value, true));
+  }
+
+  /**
+   * Evaluates the given object as a double-precision floating-point number.
+   *
+   * @param value an object to interpret as a double
+   * @return the double value implied by the given object
+   * @throws NumberFormatException if the given object can't be understood as a double
+   */
+  public static double doubleValue(Object value) throws NumberFormatException {
+    if (value == null)
+      return 0.0;
+    Class c = value.getClass();
+    if (c.getSuperclass() == Number.class)
+      return ((Number) value).doubleValue();
+    if (c == Boolean.class)
+      return ((Boolean) value).booleanValue() ? 1 : 0;
+    if (c == Character.class)
+      return ((Character) value).charValue();
+    String s = stringValue(value, true);
+
+    return (s.length() == 0) ? 0.0 : Double.parseDouble(s);
+    /*
+       For 1.1 parseDouble() is not available
+    */
+    //return Double.valueOf( value.toString() ).doubleValue();
+  }
+
+  /**
+   * Evaluates the given object as a BigInteger.
+   *
+   * @param value an object to interpret as a BigInteger
+   * @return the BigInteger value implied by the given object
+   * @throws NumberFormatException if the given object can't be understood as a BigInteger
+   */
+  public static BigInteger bigIntValue(Object value) throws NumberFormatException {
+    if (value == null)
+      return BigInteger.valueOf(0L);
+    Class c = value.getClass();
+    if (c == BigInteger.class)
+      return (BigInteger) value;
+    if (c == BigDecimal.class)
+      return ((BigDecimal) value).toBigInteger();
+    if (c.getSuperclass() == Number.class)
+      return BigInteger.valueOf(((Number) value).longValue());
+    if (c == Boolean.class)
+      return BigInteger.valueOf(((Boolean) value).booleanValue() ? 1 : 0);
+    if (c == Character.class)
+      return BigInteger.valueOf(((Character) value).charValue());
+    return new BigInteger(stringValue(value, true));
+  }
+
+  /**
+   * Evaluates the given object as a BigDecimal.
+   *
+   * @param value an object to interpret as a BigDecimal
+   * @return the BigDecimal value implied by the given object
+   * @throws NumberFormatException if the given object can't be understood as a BigDecimal
+   */
+  public static BigDecimal bigDecValue(Object value) throws NumberFormatException {
+    if (value == null)
+      return BigDecimal.valueOf(0L);
+    Class c = value.getClass();
+    if (c == BigDecimal.class)
+      return (BigDecimal) value;
+    if (c == BigInteger.class)
+      return new BigDecimal((BigInteger) value);
+    if (c.getSuperclass() == Number.class)
+      return new BigDecimal(((Number) value).doubleValue());
+    if (c == Boolean.class)
+      return BigDecimal.valueOf(((Boolean) value).booleanValue() ? 1 : 0);
+    if (c == Character.class)
+      return BigDecimal.valueOf(((Character) value).charValue());
+    return new BigDecimal(stringValue(value, true));
+  }
+
+  /**
+   * Evaluates the given object as a String and trims it if the trim flag is true.
+   *
+   * @param value an object to interpret as a String
+   * @return the String value implied by the given object as returned by the toString() method,
+   *         or "null" if the object is null.
+   */
+  public static String stringValue(Object value, boolean trim) {
+    String result;
+
+    if (value == null) {
+      result = OgnlRuntime.NULL_STRING;
+    } else {
+      result = value.toString();
+      if (trim) {
+        result = result.trim();
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Evaluates the given object as a String.
+   *
+   * @param value an object to interpret as a String
+   * @return the String value implied by the given object as returned by the toString() method,
+   *         or "null" if the object is null.
+   */
+  public static String stringValue(Object value) {
+    return stringValue(value, false);
+  }
+
+  /**
+   * Returns a constant from the NumericTypes interface that represents the numeric
+   * type of the given object.
+   *
+   * @param value an object that needs to be interpreted as a number
+   * @return the appropriate constant from the NumericTypes interface
+   */
+  public static int getNumericType(Object value) {
+    int result = NONNUMERIC;
+
+    if (value != null) {
+      Class c = value.getClass();
+      if (c == Integer.class) return INT;
+      if (c == Double.class) return DOUBLE;
+      if (c == Boolean.class) return BOOL;
+      if (c == Byte.class) return BYTE;
+      if (c == Character.class) return CHAR;
+      if (c == Short.class) return SHORT;
+      if (c == Long.class) return LONG;
+      if (c == Float.class) return FLOAT;
+      if (c == BigInteger.class) return BIGINT;
+      if (c == BigDecimal.class) return BIGDEC;
+    }
+    return NONNUMERIC;
+  }
+
+  /**
+   * Returns the value converted numerically to the given class type
+   * <p/>
+   * This method also detects when arrays are being converted and
+   * converts the components of one array to the type of the other.
+   *
+   * @param value  an object to be converted to the given type
+   * @param toType class type to be converted to
+   * @return converted value of the type given, or value if the value
+   *         cannot be converted to the given type.
+   */
+  public static Object convertValue(Object value, Class toType) {
+    Object result = null;
+
+    if (value != null) {
+      /* If array -> array then convert components of array individually */
+      if (value.getClass().isArray() && toType.isArray()) {
+        Class componentType = toType.getComponentType();
+
+        result = Array.newInstance(componentType, Array.getLength(value));
+        for (int i = 0, icount = Array.getLength(value); i < icount; i++) {
+          Array.set(result, i, convertValue(Array.get(value, i), componentType));
         }
-        return result;
-    }
-
-      /**
-       * Evaluates the given object as a String.
-       *
-       * @param value an object to interpret as a String
-       * @return the String value implied by the given object as returned by the toString() method,
-                or "null" if the object is null.
-       */
-    public static String stringValue( Object value )
-    {
-        return stringValue(value, false);
-    }
-
-      /**
-       * Returns a constant from the NumericTypes interface that represents the numeric
-       * type of the given object.
-       *
-       * @param value an object that needs to be interpreted as a number
-       * @return the appropriate constant from the NumericTypes interface
-       */
-    public static int getNumericType( Object value )
-    {
-        int     result = NONNUMERIC;
-
-        if (value != null) {
-            Class c = value.getClass();
-            if ( c == Integer.class )       return INT;
-            if ( c == Double.class )        return DOUBLE;
-            if ( c == Boolean.class )       return BOOL;
-            if ( c == Byte.class )          return BYTE;
-            if ( c == Character.class )     return CHAR;
-            if ( c == Short.class )         return SHORT;
-            if ( c == Long.class )          return LONG;
-            if ( c == Float.class )         return FLOAT;
-            if ( c == BigInteger.class )    return BIGINT;
-            if ( c == BigDecimal.class )    return BIGDEC;
+      } else {
+        if ((toType == Integer.class) || (toType == Integer.TYPE)) result = new Integer((int) longValue(value));
+        if ((toType == Double.class) || (toType == Double.TYPE)) result = new Double(doubleValue(value));
+        if ((toType == Boolean.class) || (toType == Boolean.TYPE))
+          result = booleanValue(value) ? Boolean.TRUE : Boolean.FALSE;
+        if ((toType == Byte.class) || (toType == Byte.TYPE)) result = new Byte((byte) longValue(value));
+        if ((toType == Character.class) || (toType == Character.TYPE)) result = new Character((char) longValue(value));
+        if ((toType == Short.class) || (toType == Short.TYPE)) result = new Short((short) longValue(value));
+        if ((toType == Long.class) || (toType == Long.TYPE)) result = new Long(longValue(value));
+        if ((toType == Float.class) || (toType == Float.TYPE)) result = new Float(doubleValue(value));
+        if (toType == BigInteger.class) result = bigIntValue(value);
+        if (toType == BigDecimal.class) result = bigDecValue(value);
+        if (toType == String.class) result = stringValue(value);
+      }
+    } else {
+      if (toType.isPrimitive()) {
+        result = OgnlRuntime.getPrimitiveDefaultValue(toType);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Returns the constant from the NumericTypes interface that best expresses the type
+   * of a numeric operation on the two given objects.
+   *
+   * @param v1 one argument to a numeric operator
+   * @param v2 the other argument
+   * @return the appropriate constant from the NumericTypes interface
+   */
+  public static int getNumericType(Object v1, Object v2) {
+    return getNumericType(v1, v2, false);
+  }
+
+  /**
+   * Returns the constant from the NumericTypes interface that best expresses the type
+   * of an operation, which can be either numeric or not, on the two given types.
+   *
+   * @param t1              type of one argument to an operator
+   * @param t2              type of the other argument
+   * @param canBeNonNumeric whether the operator can be interpreted as non-numeric
+   * @return the appropriate constant from the NumericTypes interface
+   */
+  public static int getNumericType(int t1, int t2, boolean canBeNonNumeric) {
+    if (t1 == t2)
+      return t1;
+
+    if (canBeNonNumeric && (t1 == NONNUMERIC || t2 == NONNUMERIC || t1 == CHAR || t2 == CHAR))
+      return NONNUMERIC;
+
+    if (t1 == NONNUMERIC) t1 = DOUBLE;    // Try to interpret strings as doubles...
+    if (t2 == NONNUMERIC) t2 = DOUBLE;    // Try to interpret strings as doubles...
+
+    if (t1 >= MIN_REAL_TYPE) {
+      if (t2 >= MIN_REAL_TYPE)
+        return Math.max(t1, t2);
+      if (t2 < INT)
+        return t1;
+      if (t2 == BIGINT)
+        return BIGDEC;
+      return Math.max(DOUBLE, t1);
+    } else if (t2 >= MIN_REAL_TYPE) {
+      if (t1 < INT)
+        return t2;
+      if (t1 == BIGINT)
+        return BIGDEC;
+      return Math.max(DOUBLE, t2);
+    } else
+      return Math.max(t1, t2);
+  }
+
+  /**
+   * Returns the constant from the NumericTypes interface that best expresses the type
+   * of an operation, which can be either numeric or not, on the two given objects.
+   *
+   * @param v1              one argument to an operator
+   * @param v2              the other argument
+   * @param canBeNonNumeric whether the operator can be interpreted as non-numeric
+   * @return the appropriate constant from the NumericTypes interface
+   */
+  public static int getNumericType(Object v1, Object v2, boolean canBeNonNumeric) {
+    return getNumericType(getNumericType(v1), getNumericType(v2), canBeNonNumeric);
+  }
+
+  /**
+   * Returns a new Number object of an appropriate type to hold the given integer
+   * value.  The type of the returned object is consistent with the given type
+   * argument, which is a constant from the NumericTypes interface.
+   *
+   * @param type  the nominal numeric type of the result, a constant from the NumericTypes interface
+   * @param value the integer value to convert to a Number object
+   * @return a Number object with the given value, of type implied by the type argument
+   */
+  public static Number newInteger(int type, long value) {
+    switch (type) {
+      case BOOL:
+      case CHAR:
+      case INT:
+        return new Integer((int) value);
+
+      case FLOAT:
+        if ((long) (float) value == value) {
+          return new Float((float) value);
         }
-        return NONNUMERIC;
-    }
-
-    /**
-       * Returns the value converted numerically to the given class type
-       *
-       * This method also detects when arrays are being converted and
-       * converts the components of one array to the type of the other.
-       *
-       * @param value an object to be converted to the given type
-       * @param toType class type to be converted to
-       * @return converted value of the type given, or value if the value
-       *                cannot be converted to the given type.
-     */
-    public static Object convertValue( Object value, Class toType)
-    {
-        Object  result = null;
-
-        if (value != null) {
-            /* If array -> array then convert components of array individually */
-            if ( value.getClass().isArray() && toType.isArray() ) {
-                Class       componentType = toType.getComponentType();
-
-                result = Array.newInstance(componentType, Array.getLength(value));
-                for (int i = 0, icount = Array.getLength(value); i < icount; i++) {
-                    Array.set(result, i, convertValue(Array.get(value, i), componentType));
-                }
-            } else {
-                if ( ( toType == Integer.class ) || ( toType == Integer.TYPE ) )        result = new Integer((int)longValue(value));
-                if ( ( toType == Double.class ) || ( toType == Double.TYPE ) )          result = new Double(doubleValue(value));
-                if ( ( toType == Boolean.class ) || ( toType == Boolean.TYPE ) )        result = booleanValue(value) ? Boolean.TRUE : Boolean.FALSE;
-                if ( ( toType == Byte.class ) || ( toType == Byte.TYPE ) )              result = new Byte((byte)longValue(value));
-                if ( ( toType == Character.class ) || ( toType == Character.TYPE ) )    result = new Character((char)longValue(value));
-                if ( ( toType == Short.class ) || ( toType == Short.TYPE ) )            result = new Short((short)longValue(value));
-                if ( ( toType == Long.class ) || ( toType == Long.TYPE ) )              result = new Long(longValue(value));
-                if ( ( toType == Float.class ) || ( toType == Float.TYPE ) )            result = new Float(doubleValue(value));
-                if ( toType == BigInteger.class )                                       result = bigIntValue(value);
-                if ( toType == BigDecimal.class )                                       result = bigDecValue(value);
-                if ( toType == String.class )                                           result = stringValue(value);
-            }
-        } else {
-            if (toType.isPrimitive()) {
-                result = OgnlRuntime.getPrimitiveDefaultValue(toType);
-            }
+        // else fall through:
+      case DOUBLE:
+        if ((long) (double) value == value) {
+          return new Double((double) value);
         }
-        return result;
-    }
-
-      /**
-       * Returns the constant from the NumericTypes interface that best expresses the type
-       * of a numeric operation on the two given objects.
-       *
-       * @param v1 one argument to a numeric operator
-       * @param v2 the other argument
-       * @return the appropriate constant from the NumericTypes interface
-       */
-    public static int getNumericType( Object v1, Object v2 )
-    {
-        return getNumericType( v1, v2, false );
-    }
-
-      /**
-       * Returns the constant from the NumericTypes interface that best expresses the type
-       * of an operation, which can be either numeric or not, on the two given types.
-       *
-       * @param t1 type of one argument to an operator
-       * @param t2 type of the other argument
-       * @param canBeNonNumeric whether the operator can be interpreted as non-numeric
-       * @return the appropriate constant from the NumericTypes interface
-       */
-    public static int getNumericType( int t1, int t2, boolean canBeNonNumeric )
-    {
-        if ( t1 == t2 )
-            return t1;
-
-        if ( canBeNonNumeric && (t1 == NONNUMERIC || t2 == NONNUMERIC || t1 == CHAR || t2 == CHAR) )
-            return NONNUMERIC;
-
-        if ( t1 == NONNUMERIC ) t1 = DOUBLE;    // Try to interpret strings as doubles...
-        if ( t2 == NONNUMERIC ) t2 = DOUBLE;    // Try to interpret strings as doubles...
-
-        if ( t1 >= MIN_REAL_TYPE )
-          {
-            if ( t2 >= MIN_REAL_TYPE )
-                return Math.max(t1,t2);
-            if ( t2 < INT )
-                return t1;
-            if ( t2 == BIGINT )
-                return BIGDEC;
-            return Math.max(DOUBLE,t1);
-          }
-        else if ( t2 >= MIN_REAL_TYPE )
-          {
-            if ( t1 < INT )
-                return t2;
-            if ( t1 == BIGINT )
-                return BIGDEC;
-            return Math.max(DOUBLE,t2);
-          }
-        else
-            return Math.max(t1,t2);
-    }
-
-      /**
-       * Returns the constant from the NumericTypes interface that best expresses the type
-       * of an operation, which can be either numeric or not, on the two given objects.
-       *
-       * @param v1 one argument to an operator
-       * @param v2 the other argument
-       * @param canBeNonNumeric whether the operator can be interpreted as non-numeric
-       * @return the appropriate constant from the NumericTypes interface
-       */
-    public static int getNumericType( Object v1, Object v2, boolean canBeNonNumeric )
-    {
-        return getNumericType(getNumericType(v1), getNumericType(v2), canBeNonNumeric);
-    }
-
-      /**
-       * Returns a new Number object of an appropriate type to hold the given integer
-       * value.  The type of the returned object is consistent with the given type
-       * argument, which is a constant from the NumericTypes interface.
-       *
-       * @param type    the nominal numeric type of the result, a constant from the NumericTypes interface
-       * @param value   the integer value to convert to a Number object
-       * @return        a Number object with the given value, of type implied by the type argument
-       */
-    public static Number newInteger( int type, long value )
-    {
-        switch ( type )
-          {
-            case BOOL:
-            case CHAR:
-            case INT:
-                return new Integer( (int)value );
-
-            case FLOAT:
-                if ( (long)(float)value == value ) {
-                    return new Float( (float)value );
-                }
-                // else fall through:
-            case DOUBLE:
-                if ( (long)(double)value == value ) {
-                    return new Double( (double)value );
-                }
-                // else fall through:
-            case LONG:
-                return new Long( value );
+        // else fall through:
+      case LONG:
+        return new Long(value);
+
+      case BYTE:
+        return new Byte((byte) value);
+
+      case SHORT:
+        return new Short((short) value);
+
+      default:
+        return BigInteger.valueOf(value);
+    }
+  }
+
+  /**
+   * Returns a new Number object of an appropriate type to hold the given real value.
+   * The type of the returned object is always either Float or Double, and is only
+   * Float if the given type tag (a constant from the NumericTypes interface) is
+   * FLOAT.
+   *
+   * @param type  the nominal numeric type of the result, a constant from the NumericTypes interface
+   * @param value the real value to convert to a Number object
+   * @return a Number object with the given value, of type implied by the type argument
+   */
+  public static Number newReal(int type, double value) {
+    if (type == FLOAT)
+      return new Float((float) value);
+    return new Double(value);
+  }
+
+  public static Object binaryOr(Object v1, Object v2) {
+    int type = getNumericType(v1, v2);
+    if (type == BIGINT || type == BIGDEC)
+      return bigIntValue(v1).or(bigIntValue(v2));
+    return newInteger(type, longValue(v1) | longValue(v2));
+  }
+
+  public static Object binaryXor(Object v1, Object v2) {
+    int type = getNumericType(v1, v2);
+    if (type == BIGINT || type == BIGDEC)
+      return bigIntValue(v1).xor(bigIntValue(v2));
+    return newInteger(type, longValue(v1) ^ longValue(v2));
+  }
+
+  public static Object binaryAnd(Object v1, Object v2) {
+    int type = getNumericType(v1, v2);
+    if (type == BIGINT || type == BIGDEC)
+      return bigIntValue(v1).and(bigIntValue(v2));
+    return newInteger(type, longValue(v1) & longValue(v2));
+  }
+
+  public static boolean equal(Object v1, Object v2) {
+    if (v1 == null)
+      return v2 == null;
+    if (v1 == v2 || isEqual(v1, v2))
+      return true;
+    if (v1 instanceof Number && v2 instanceof Number)
+      return ((Number) v1).doubleValue() == ((Number) v2).doubleValue();
+    return false;
+  }
+
+  public static boolean less(Object v1, Object v2) {
+    return compareWithConversion(v1, v2) < 0;
+  }
+
+  public static boolean greater(Object v1, Object v2) {
+    return compareWithConversion(v1, v2) > 0;
+  }
+
+  public static boolean in(Object v1, Object v2) throws OgnlException {
+    if (v2 == null)   // A null collection is always treated as empty
+      return false;
+
+    ElementsAccessor elementsAccessor = OgnlRuntime.getElementsAccessor(OgnlRuntime.getTargetClass(v2));
+    for (Enumeration e = elementsAccessor.getElements(v2); e.hasMoreElements();) {
+      Object o = e.nextElement();
+
+      if (equal(v1, o))
+        return true;
+    }
+    return false;
+  }
+
+  public static Object shiftLeft(Object v1, Object v2) {
+    int type = getNumericType(v1);
+    if (type == BIGINT || type == BIGDEC)
+      return bigIntValue(v1).shiftLeft((int) longValue(v2));
+    return newInteger(type, longValue(v1) << (int) longValue(v2));
+  }
+
+  public static Object shiftRight(Object v1, Object v2) {
+    int type = getNumericType(v1);
+    if (type == BIGINT || type == BIGDEC)
+      return bigIntValue(v1).shiftRight((int) longValue(v2));
+    return newInteger(type, longValue(v1) >> (int) longValue(v2));
+  }
+
+  public static Object unsignedShiftRight(Object v1, Object v2) {
+    int type = getNumericType(v1);
+    if (type == BIGINT || type == BIGDEC)
+      return bigIntValue(v1).shiftRight((int) longValue(v2));
+    if (type <= INT)
+      return newInteger(INT, ((int) longValue(v1)) >>> (int) longValue(v2));
+    return newInteger(type, longValue(v1) >>> (int) longValue(v2));
+  }
+
+  public static Object add(Object v1, Object v2) {
+    int type = getNumericType(v1, v2, true);
+    switch (type) {
+      case BIGINT:
+        return bigIntValue(v1).add(bigIntValue(v2));
+      case BIGDEC:
+        return bigDecValue(v1).add(bigDecValue(v2));
+      case FLOAT:
+      case DOUBLE:
+        return newReal(type, doubleValue(v1) + doubleValue(v2));
+      case NONNUMERIC:
+        int t1 = getNumericType(v1),
+            t2 = getNumericType(v2);
 
-            case BYTE:
-                return new Byte( (byte)value );
-
-            case SHORT:
-                return new Short( (short)value );
-
-            default:
-                return BigInteger.valueOf( value );
-          }
-    }
-
-      /**
-       * Returns a new Number object of an appropriate type to hold the given real value.
-       * The type of the returned object is always either Float or Double, and is only
-       * Float if the given type tag (a constant from the NumericTypes interface) is
-       * FLOAT.
-       *
-       * @param type    the nominal numeric type of the result, a constant from the NumericTypes interface
-       * @param value   the real value to convert to a Number object
-       * @return        a Number object with the given value, of type implied by the type argument
-       */
-    public static Number newReal( int type, double value )
-    {
-        if ( type == FLOAT )
-            return new Float( (float)value );
-        return new Double( value );
-    }
-
-    public static Object binaryOr( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1,v2);
-        if ( type == BIGINT || type == BIGDEC )
-            return bigIntValue(v1).or(bigIntValue(v2));
-        return newInteger( type, longValue(v1) | longValue(v2) );
-    }
-
-    public static Object binaryXor( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1,v2);
-        if ( type == BIGINT || type == BIGDEC )
-            return bigIntValue(v1).xor(bigIntValue(v2));
-        return newInteger( type, longValue(v1) ^ longValue(v2) );
-    }
-
-    public static Object binaryAnd( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1,v2);
-        if ( type == BIGINT || type == BIGDEC )
-            return bigIntValue(v1).and(bigIntValue(v2));
-        return newInteger( type, longValue(v1) & longValue(v2) );
-    }
-
-    public static boolean equal( Object v1, Object v2 )
-    {
-        if ( v1 == null )
-            return v2 == null;
-        if ( v1 == v2 || isEqual(v1, v2) )
-            return true;
-        if ( v1 instanceof Number && v2 instanceof Number )
-            return ((Number)v1).doubleValue() == ((Number)v2).doubleValue();
-        return false;
-    }
-
-    public static boolean less( Object v1, Object v2 )
-    {
-        return compareWithConversion(v1, v2) < 0;
-    }
-
-    public static boolean greater( Object v1, Object v2 )
-    {
-        return compareWithConversion(v1, v2) > 0;
-    }
-
-    public static boolean in( Object v1, Object v2 ) throws OgnlException
-    {
-        if ( v2 == null )   // A null collection is always treated as empty
-            return false;
-
-        ElementsAccessor elementsAccessor = OgnlRuntime.getElementsAccessor(OgnlRuntime.getTargetClass(v2));
-        for ( Enumeration e = elementsAccessor.getElements(v2); e.hasMoreElements(); ) {
-            Object  o = e.nextElement();
-
-            if ( equal(v1, o) )
-                return true;
+        if (((t1 != NONNUMERIC) && (v2 == null)) || ((t2 != NONNUMERIC) && (v1 == null))) {
+          throw new NullPointerException();
         }
-        return false;
-    }
-
-    public static Object shiftLeft( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1);
-        if ( type == BIGINT || type == BIGDEC )
-            return bigIntValue(v1).shiftLeft( (int)longValue(v2) );
-        return newInteger( type, longValue(v1) << (int)longValue(v2) );
-    }
-
-    public static Object shiftRight( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1);
-        if ( type == BIGINT || type == BIGDEC )
-            return bigIntValue(v1).shiftRight( (int)longValue(v2) );
-        return newInteger( type, longValue(v1) >> (int)longValue(v2) );
-    }
-
-    public static Object unsignedShiftRight( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1);
-        if ( type == BIGINT || type == BIGDEC )
-            return bigIntValue(v1).shiftRight( (int)longValue(v2) );
-        if ( type <= INT )
-            return newInteger( INT, ((int)longValue(v1)) >>> (int)longValue(v2) );
-        return newInteger( type, longValue(v1) >>> (int)longValue(v2) );
-    }
-
-    public static Object add( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1,v2,true);
-        switch ( type )
-          {
-            case BIGINT:    return bigIntValue(v1).add(bigIntValue(v2));
-            case BIGDEC:    return bigDecValue(v1).add(bigDecValue(v2));
-            case FLOAT:
-            case DOUBLE:    return newReal( type, doubleValue(v1) + doubleValue(v2) );
-            case NONNUMERIC:
-                int     t1 = getNumericType(v1),
-                        t2 = getNumericType(v2);
-
-                if (((t1 != NONNUMERIC) && (v2 == null)) || ((t2 != NONNUMERIC) && (v1 == null))) {
-                    throw new NullPointerException();
-                }
-                return stringValue(v1) + stringValue(v2);
-            default:        return newInteger( type, longValue(v1) + longValue(v2) );
-          }
-    }
-
-    public static Object subtract( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1,v2);
-        switch ( type )
-          {
-            case BIGINT:    return bigIntValue(v1).subtract(bigIntValue(v2));
-            case BIGDEC:    return bigDecValue(v1).subtract(bigDecValue(v2));
-            case FLOAT:
-            case DOUBLE:    return newReal( type, doubleValue(v1) - doubleValue(v2) );
-            default:        return newInteger( type, longValue(v1) - longValue(v2) );
-          }
-    }
-
-    public static Object multiply( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1,v2);
-        switch ( type )
-          {
-            case BIGINT:    return bigIntValue(v1).multiply(bigIntValue(v2));
-            case BIGDEC:    return bigDecValue(v1).multiply(bigDecValue(v2));
-            case FLOAT:
-            case DOUBLE:    return newReal( type, doubleValue(v1) * doubleValue(v2) );
-            default:        return newInteger( type, longValue(v1) * longValue(v2) );
-          }
-    }
-
-    public static Object divide( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1,v2);
-        switch ( type )
-          {
-            case BIGINT:    return bigIntValue(v1).divide(bigIntValue(v2));
-            case BIGDEC:    return bigDecValue(v1).divide( bigDecValue(v2), BigDecimal.ROUND_HALF_EVEN );
-            case FLOAT:
-            case DOUBLE:    return newReal( type, doubleValue(v1) / doubleValue(v2) );
-            default:        return newInteger( type, longValue(v1) / longValue(v2) );
-          }
-    }
-
-    public static Object remainder( Object v1, Object v2 )
-    {
-        int type = getNumericType(v1,v2);
-        switch ( type )
-          {
-            case BIGDEC:
-            case BIGINT:    return bigIntValue(v1).remainder(bigIntValue(v2));
-            default:        return newInteger( type, longValue(v1) % longValue(v2) );
-          }
-    }
-
-    public static Object negate( Object value )
-    {
-        int type = getNumericType(value);
-        switch ( type )
-          {
-            case BIGINT:    return bigIntValue(value).negate();
-            case BIGDEC:    return bigDecValue(value).negate();
-            case FLOAT:
-            case DOUBLE:    return newReal( type, -doubleValue(value) );
-            default:        return newInteger( type, -longValue(value) );
-          }
-    }
-
-    public static Object bitNegate( Object value )
-    {
-        int type = getNumericType(value);
-        switch ( type )
-          {
-            case BIGDEC:
+        return stringValue(v1) + stringValue(v2);
+      default:
+        return newInteger(type, longValue(v1) + longValue(v2));
+    }
+  }
+
+  public static Object subtract(Object v1, Object v2) {
+    int type = getNumericType(v1, v2);
+    switch (type) {
+      case BIGINT:
+        return bigIntValue(v1).subtract(bigIntValue(v2));
+      case BIGDEC:
+        return bigDecValue(v1).subtract(bigDecValue(v2));
+      case FLOAT:
+      case DOUBLE:
+        return newReal(type, doubleValue(v1) - doubleValue(v2));
+      default:
+        return newInteger(type, longValue(v1) - longValue(v2));
+    }
+  }
+
+  public static Object multiply(Object v1, Object v2) {
+    int type = getNumericType(v1, v2);
+    switch (type) {
+      case BIGINT:
+        return bigIntValue(v1).multiply(bigIntValue(v2));
+      case BIGDEC:
+        return bigDecValue(v1).multiply(bigDecValue(v2));
+      case FLOAT:
+      case DOUBLE:
+        return newReal(type, doubleValue(v1) * doubleValue(v2));
+      default:
+        return newInteger(type, longValue(v1) * longValue(v2));
+    }
+  }
+
+  public static Object divide(Object v1, Object v2) {
+    int type = getNumericType(v1, v2);
+    switch (type) {
+      case BIGINT:
+        return bigIntValue(v1).divide(bigIntValue(v2));
+      case BIGDEC:
+        return bigDecValue(v1).divide(bigDecValue(v2), BigDecimal.ROUND_HALF_EVEN);
+      case FLOAT:
+      case DOUBLE:
+        return newReal(type, doubleValue(v1) / doubleValue(v2));
+      default:
+        return newInteger(type, longValue(v1) / longValue(v2));
+    }
+  }
+
+  public static Object remainder(Object v1, Object v2) {
+    int type = getNumericType(v1, v2);
+    switch (type) {
+      case BIGDEC:
+      case BIGINT:
+        return bigIntValue(v1).remainder(bigIntValue(v2));
+      default:
+        return newInteger(type, longValue(v1) % longValue(v2));
+    }
+  }
+
+  public static Object negate(Object value) {
+    int type = getNumericType(value);
+    switch (type) {
+      case BIGINT:
+        return bigIntValue(value).negate();
+      case BIGDEC:
+        return bigDecValue(value).negate();
+      case FLOAT:
+      case DOUBLE:
+        return newReal(type, -doubleValue(value));
+      default:
+        return newInteger(type, -longValue(value));
+    }
+  }
+
+  public static Object bitNegate(Object value) {
+    int type = getNumericType(value);
+    switch (type) {
+      case BIGDEC:
             case BIGINT:    return bigIntValue(value).not();
             default:        return newInteger( type, ~longValue(value) );
           }