package org.apache.commons.ognl;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.commons.ognl.enhance.UnsupportedCompilationException;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Enumeration;

/**
 * This is an abstract class with static methods that define the operations of OGNL.
 */
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 )
    {
        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 instanceof Comparable ) && v1.getClass().isAssignableFrom( v2.getClass() ) )
                        {
                            result = ( (Comparable) v1 ).compareTo( v2 );
                            break;
                        }
                        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 object1 First object to compare
     * @param object2 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 ) && object1.getClass().isArray() )
            {
                if ( ( object2 != null ) && 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
            {
                // Check for converted equivalence first, then equals() equivalence
                result =
                    ( object1 != null ) && ( object2 != null )
                        && ( object1.equals( object2 ) || ( compareWithConversion( object1, object2 ) == 0 ) );
            }
        }
        return result;
    }

    public static boolean booleanValue( boolean value )
    {
        return value;
    }

    public static boolean booleanValue( int value )
    {
        return value > 0;
    }

    public static boolean booleanValue( float value )
    {
        return value > 0;
    }

    public static boolean booleanValue( long value )
    {
        return value > 0;
    }

    public static boolean booleanValue( double value )
    {
        return value > 0;
    }

    /**
     * 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;
        }
        // if ( c == String.class )
        // return ((String)value).length() > 0;

        if ( c == Character.class )
        {
            return (Character) value != 0;
        }
        return !( value instanceof Number ) || ( (Number) value ).doubleValue() != 0;

    }

    /**
     * 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 )
    {
        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 ? 1 : 0;
        }
        if ( c == Character.class )
        {
            return (Character) value;
        }
        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 )
    {
        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 ? 1 : 0;
        }
        if ( c == Character.class )
        {
            return (Character) value;
        }
        String s = stringValue( value, true );

        return ( s.isEmpty() ) ? 0.0 : Double.parseDouble( s );
    }

    /**
     * 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 )
    {
        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 ? 1 : 0 );
        }
        if ( c == Character.class )
        {
            return BigInteger.valueOf( (Character) value );
        }
        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 )
    {
        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 == Boolean.class )
        {
            return BigDecimal.valueOf( (Boolean) value ? 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
     * @param trim if true trims the result
     * @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 )
    {
        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;
    }

    public static Object toArray( char value, Class<?> toType )
        throws OgnlException
    {
        return toArray( Character.valueOf( value ), toType );
    }

    public static Object toArray( byte value, Class<?> toType )
        throws OgnlException
    {
        return toArray( Byte.valueOf( value ), toType );
    }

    public static Object toArray( int value, Class<?> toType )
        throws OgnlException
    {
        return toArray( Integer.valueOf( value ), toType );
    }

    public static Object toArray( long value, Class<?> toType )
        throws OgnlException
    {
        return toArray( Long.valueOf( value ), toType );
    }

    public static Object toArray( float value, Class<?> toType )
        throws OgnlException
    {
        return toArray( Float.valueOf( value ), toType );
    }

    public static Object toArray( double value, Class<?> toType )
        throws OgnlException
    {
        return toArray( Double.valueOf( value ), toType );
    }

    public static Object toArray( boolean value, Class<?> toType )
        throws OgnlException
    {
        return toArray( Boolean.valueOf( value ), toType );
    }

    public static <T> Object convertValue( char value, Class<T> toType )
        throws OgnlException
    {
        return convertValue( Character.valueOf(value), toType );
    }

    public static <T> Object convertValue( byte value, Class<T> toType )
        throws OgnlException
    {
        return convertValue( Byte.valueOf( value ), toType );
    }

    public static <T> Object convertValue( int value, Class<T> toType )
        throws OgnlException
    {
        return convertValue( Integer.valueOf( value ), toType );
    }

    public static <T> Object convertValue( long value, Class<T> toType )
        throws OgnlException
    {
        return convertValue( Long.valueOf( value ), toType );
    }

    public static <T> Object convertValue( float value, Class<T> toType )
        throws OgnlException
    {
        return convertValue( Float.valueOf( value ), toType );
    }

    public static <T> Object convertValue( double value, Class<T> toType )
        throws OgnlException
    {
        return convertValue( Double.valueOf( value ), toType );
    }

    public static <T> Object convertValue( boolean value, Class<T> toType )
        throws OgnlException
    {
        return convertValue( Boolean.valueOf( value ), toType );
    }

    // //////////////////////////////////////////////////////////////

    public static <T> Object convertValue( char value, Class<T> toType, boolean preventNull )
        throws OgnlException
    {
        return convertValue( Character.valueOf( value ), toType, preventNull );
    }

    public static <T> Object convertValue( byte value, Class<T> toType, boolean preventNull )
        throws OgnlException
    {
        return convertValue( Byte.valueOf( value ), toType, preventNull );
    }

    public static <T> Object convertValue( int value, Class<T> toType, boolean preventNull )
        throws OgnlException
    {
        return convertValue( Integer.valueOf( value ), toType, preventNull );
    }

    public static <T> Object convertValue( long value, Class<T> toType, boolean preventNull )
        throws OgnlException
    {
        return convertValue( Long.valueOf( value ), toType, preventNull );
    }

    public static <T> Object convertValue( float value, Class<T> toType, boolean preventNull )
        throws OgnlException
    {
        return convertValue( new Float( value ), toType, preventNull );
    }

    public static <T> Object convertValue( double value, Class<T> toType, boolean preventNull )
        throws OgnlException
    {
        return convertValue( new Double( value ), toType, preventNull );
    }

    public static <T> Object convertValue( boolean value, Class<T> toType, boolean preventNull )
        throws OgnlException
    {
        return convertValue( Boolean.valueOf( value ), toType, preventNull );
    }

    // ///////////////////////////////////////////////////////////////

    public static Object toArray( char value, Class<?> toType, boolean preventNull )
        throws OgnlException
    {
        return toArray( Character.valueOf( value ), toType, preventNull );
    }

    public static Object toArray( byte value, Class<?> toType, boolean preventNull )
        throws OgnlException
    {
        return toArray( Byte.valueOf( value ), toType, preventNull );
    }

    public static Object toArray( int value, Class<?> toType, boolean preventNull )
        throws OgnlException
    {
        return toArray( Integer.valueOf( value ), toType, preventNull );
    }

    public static Object toArray( long value, Class<?> toType, boolean preventNull )
        throws OgnlException
    {
        return toArray( Long.valueOf(value), toType, preventNull );
    }

    public static Object toArray( float value, Class<?> toType, boolean preventNull )
        throws OgnlException
    {
        return toArray( Float.valueOf( value ), toType, preventNull );
    }

    public static Object toArray( double value, Class<?> toType, boolean preventNull )
        throws OgnlException
    {
        return toArray( Double.valueOf(value), toType, preventNull );
    }

    public static Object toArray( boolean value, Class<?> toType, boolean preventNull )
        throws OgnlException
    {
        return toArray( Boolean.valueOf( value ), toType, preventNull );
    }

    /**
     * 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 )
    {
        return convertValue( value, toType, false );
    }

    public static Object toArray( Object value, Class<?> toType )
        throws OgnlException
    {
        return toArray( value, toType, false );
    }

    public static Object toArray( Object value, Class<?> toType, boolean preventNulls )
        throws OgnlException
    {
        if ( value == null )
        {
            return null;
        }

        Object result;

        Class<?> aClass = value.getClass();
        if ( aClass.isArray() && toType.isAssignableFrom( aClass.getComponentType() ) )
        {
            return value;
        }

        if ( !aClass.isArray() )
        {

            if ( toType == Character.TYPE )
            {
                return stringValue( value ).toCharArray();
            }

            Object arr = Array.newInstance( toType, 1 );
            Array.set( arr, 0, convertValue( value, toType, preventNulls ) );

            return arr;
        }

        result = Array.newInstance( toType, Array.getLength( value ) );
        for ( int i = 0, icount = Array.getLength( value ); i < icount; i++ )
        {
            Array.set( result, i, convertValue( Array.get( value, i ), toType ) );
        }

        if ( result == null && preventNulls )
        {
            return value;
        }

        return result;
    }

    public static <T> Object convertValue( Object value, Class<T> toType, boolean preventNulls )
    {
        Object result = null;

        if ( value != null && toType.isAssignableFrom( value.getClass() ) )
        {
            return value;
        }

        if ( value != null )
        {
            /* If array -> array then convert components of array individually */
            boolean classIsArray = value.getClass().isArray();
            boolean toTypeIsArray = toType.isArray();
            if ( classIsArray && toTypeIsArray)
            {
                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 ( classIsArray && !toTypeIsArray)
            {

                return convertValue( Array.get( value, 0 ), toType );
            }
            else if ( toTypeIsArray )
            {

                if ( toType.getComponentType() == Character.TYPE )
                {

                    result = stringValue( value ).toCharArray();
                }
                else if ( toType.getComponentType() == Object.class )
                {
                    return new Object[] { value };
                }
            }
            else
            {
                if ( ( toType == Integer.class ) || ( toType == Integer.TYPE ) )
                {
                    result = (int) longValue( value );
                }
                else if ( ( toType == Double.class ) || ( toType == Double.TYPE ) )
                {
                    result = doubleValue( value );
                }
                else if ( ( toType == Boolean.class ) || ( toType == Boolean.TYPE ) )
                {
                    result = booleanValue( value ) ? Boolean.TRUE : Boolean.FALSE;
                }
                else if ( ( toType == Byte.class ) || ( toType == Byte.TYPE ) )
                {
                    result = (byte) longValue( value );
                }
                else if ( ( toType == Character.class ) || ( toType == Character.TYPE ) )
                {
                    result = (char) longValue( value );
                }
                else if ( ( toType == Short.class ) || ( toType == Short.TYPE ) )
                {
                    result = (short) longValue( value );
                }
                else if ( ( toType == Long.class ) || ( toType == Long.TYPE ) )
                {
                    result = longValue( value );
                }
                else if ( ( toType == Float.class ) || ( toType == Float.TYPE ) )
                {
                    result = new Float( doubleValue( value ) );
                }
                else if ( toType == BigInteger.class )
                {
                    result = bigIntValue( value );
                }
                else if ( toType == BigDecimal.class )
                {
                    result = bigDecValue( value );
                }
                else if ( toType == String.class )
                {
                    result = stringValue( value );
                }
            }
        }
        else
        {
            if ( toType.isPrimitive() )
            {
                result = OgnlRuntime.getPrimitiveDefaultValue( toType );
            }
            else if ( preventNulls && toType == Boolean.class )
            {
                result = Boolean.FALSE;
            }
            else if ( preventNulls && Number.class.isAssignableFrom( toType ) )
            {
                result = OgnlRuntime.getNumericDefaultValue( toType );
            }
        }

        if ( result == null && preventNulls )
        {
            return value;
        }

        if ( value != null && result == null )
        {

            throw new IllegalArgumentException( "Unable to convert type " + value.getClass().getName() + " of " + value
                + " to type of " + toType.getName() );
        }

        return result;
    }

    /**
     * Converts the specified value to a primitive integer value.
     * <ul>
     * <li>Null values will cause a -1 to be returned.</li>
     * <li>{@link Number} instances have their intValue() methods invoked.</li>
     * <li>All other types result in calling Integer.parseInt(value.toString());</li>
     * </ul>
     *
     * @param value The object to get the value of.
     * @return A valid integer.
     */
    public static int getIntValue( Object value )
    {
        try
        {
            if ( value == null )
            {
                return -1;
            }

            if ( Number.class.isInstance( value ) )
            {

                return ( (Number) value ).intValue();
            }

            String str = String.class.isInstance( value ) ? (String) value : value.toString();

            return Integer.parseInt( str );
        }
        catch ( Throwable t )
        {
            throw new RuntimeException( "Error converting " + value + " to integer:", t );
        }
    }

    /**
     * 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 );
        }
        if ( t2 < MIN_REAL_TYPE ) {
            return Math.max( t1, t2 );
        }
        if ( t1 < INT )
        {
            return t2;
        }
        if ( t1 == BIGINT )
        {
            return BIGDEC;
        }
        return Math.max( DOUBLE, 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 (int) value;

            case FLOAT:
                if ( (long) (float) value == value )
                {
                    return (float) value;
                }
                // else fall through:
            case DOUBLE:
                if ( (long) (double) value == value )
                {
                    return (double) value;
                }
                // else fall through:
            case LONG:
                return value;

            case BYTE:
                return (byte) value;

            case SHORT:
                return (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 (float) value;
        }
        return 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 ) );

        // FIXME O(n) is there a better way?!
        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 );

                if ( ( ( t1 != NONNUMERIC ) && ( v2 == null ) ) || ( ( t2 != NONNUMERIC ) && ( v1 == null ) ) )
                {
                    throw new NullPointerException( "Can't add values " + v1 + " , " + v2 );
                }

                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 ) );
        }
    }

    public static String getEscapeString( String value )
    {
        StringBuilder result = new StringBuilder();

        int length = value.length();
        for ( int i = 0; i < length; i++ )
        {
            result.append( getEscapedChar( value.charAt( i ) ) );
        }
        return result.toString();
    }

    public static String getEscapedChar( char ch )
    {
        String result;

        switch ( ch )
        {
            case '\b':
                result = "\b";
                break;
            case '\t':
                result = "\\t";
                break;
            case '\n':
                result = "\\n";
                break;
            case '\f':
                result = "\\f";
                break;
            case '\r':
                result = "\\r";
                break;
            case '\"':
                result = "\\\"";
                break;
            case '\'':
                result = "\\\'";
                break;
            case '\\':
                result = "\\\\";
                break;
            default:
                if ( Character.isISOControl( ch ) )
                {

                    String hc = Integer.toString( (int) ch, 16 );
                    int hcl = hc.length();

                    result = "\\u";
                    if ( hcl < 4 )
                    {
                        if ( hcl == 3 )
                        {
                            result = result + "0";
                        }
                        else
                        {
                            if ( hcl == 2 )
                            {
                                result = result + "00";
                            }
                            else
                            {
                                result = result + "000";
                            }
                        }
                    }

                    result = result + hc;
                }
                else
                {
                    result = ch + "";
                }
                break;
        }
        return result;
    }

    public static Object returnValue( Object ignore, Object returnValue )
    {
        return returnValue;
    }

    /**
     * Utility method that converts incoming exceptions to {@link RuntimeException} instances - or casts them if they
     * already are.
     *
     * @param t The exception to cast.
     * @return The exception cast to a {@link RuntimeException}.
     */
    public static RuntimeException castToRuntime( Throwable t )
    {
        if ( RuntimeException.class.isInstance( t ) )
        {
            return (RuntimeException) t;
        }

        if ( OgnlException.class.isInstance( t ) )
        {
            throw new UnsupportedCompilationException( "Error evluating expression: " + t.getMessage(), t );
        }

        return new RuntimeException( t );
    }
}
