/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
/*
 *  $RCSfile: ExpressionProcesser.java,v $
 *  $Revision: 1.7 $  $Date: 2005/02/16 14:38:04 $ 
 */
package org.eclipse.jem.internal.proxy.initParser.tree;

import java.lang.reflect.*;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.text.MessageFormat;
import java.util.ArrayList;

import org.eclipse.jem.internal.proxy.common.AmbiguousMethodException;
import org.eclipse.jem.internal.proxy.common.MethodHelper;
import org.eclipse.jem.internal.proxy.initParser.EvaluationException;
import org.eclipse.jem.internal.proxy.initParser.tree.IExpressionConstants.NoExpressionValueException;
 
/**
 * Expression processing. This does the actual expression processing with the live objects.
 * It is meant to be subclassed only to provide additional expression types. All of the
 * current expressions cannot be overridden. This is because the stack is very sensitive to 
 * call order.
 * 
 * @since 1.0.0
 */
public class ExpressionProcesser {

	/**
	 * The expression result stack and the expression result type stack.
	 * The type stack is used to be expected type of the corresponding
	 * expression result. This is needed for converting to primitives
	 * and for finding correct method call from the argument types. In
	 * this case, it is not the true value, but the value expected, e.g.
	 * <code>Object getObject()</code> returns something of type Object.
	 * This needs to be maintained so that if it goes into another method
	 * we don't accidently return a more specific method instead of the
	 * one that takes Object as an argument. 
	 * 
	 * expressionStack has result of the expression.
	 * expressionTypeStack has the computed type of the expression i.e.
	 * the type that the expression returns, not the type of the value.
	 * These can be different because the expression (e.g. method) may
	 * return an Object, but the expression value will be some specific
	 * subclass. So the expressionTypeStack would have a <code>java.lang.Object.class</code>
	 * on it in that case.
	 * Note: if the expressionStack has a <code>null</code> on it, then the type stack
	 * may either have a specific type in it, or it may be <code>MethodHelper.NULL_TYPE</code>. It
	 * would be this if it was explicitly pushed in and not as the
	 * result of a computation. If the result of a computation, it would have the
	 * true value.
	 * Note: if the expressionStack has a <code>Void.type</code> on it, then that
	 * means the previous expression had no result. This is an error if trying to
	 * use the expression in another expression.
	 * 
	 * @see org.eclipse.jem.internal.proxy.initParser.MethodHelper#NULL_TYPE
	 */
	private ArrayList expressionStack = new ArrayList(10);
	private ArrayList expressionTypeStack = new ArrayList(10);
	
	/**
	 * Push the expression value and its expected type.
	 * @param o
	 * @param type
	 * 
	 * @since 1.0.0
	 */
	protected final void pushExpressionValue(Object o, Class type) {
		expressionStack.add(o);
		expressionTypeStack.add(type);
	}
	
	/**
	 * Pop just the expression value. It is imperitive that the expression type
	 * is popped immediately following. Separated the methods so that we
	 * don't need to create an array to return two values.
	 * 
	 * @return The value.
	 * @throws ThrowableProxy
	 * 
	 * @since 1.0.0
	 */
	protected final Object popExpression() throws NoExpressionValueException {
		try {
			return expressionStack.remove(expressionStack.size()-1);
		} catch (IndexOutOfBoundsException e) {
			throw new NoExpressionValueException();
		}
	}

	/**
	 * Get the expression at <code>fromTop</code> down from the top. This is
	 * need for when multi-operators happen and they are stored in reverse of 
	 * what is needed. They would normally be stored left to right, with the
	 * rightmost one on top. But they need to be processed left to right, so
	 * to get the left most one requires digging down in the stack.
	 * <p>
	 * When done, <code>popExpressions(int count)</code> must be called to
	 * clean them out since they were processed.
	 *  
	 * @param fromTop <code>1</code> is the top one, <code>2</code> is the next one down.
	 * @return The entry from the top that was requested.
	 * @throws NoExpressionValueException
	 * 
	 * @see IDEExpression#popExpressions(int)
	 * @since 1.0.0
	 */
	protected final Object getExpression(int fromTop) throws NoExpressionValueException {
		try {
			return expressionStack.get(expressionStack.size()-fromTop);
		} catch (IndexOutOfBoundsException e) {
			throw new NoExpressionValueException();
		}
	}
	
	/**
	 * Remove the top <code>count</code> items.
	 * 
	 * @param count
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected final void popExpressions(int count) throws NoExpressionValueException {
		try {
			int remove = expressionStack.size()-1;
			while (count-- > 0)
				expressionStack.remove(remove--);
		} catch (IndexOutOfBoundsException e) {
			throw new NoExpressionValueException();
		}
	}
	
	/**
	 * Pop just the expression type. It is imperitive that the expression type
	 * is popped immediately following popExpression. Separated the methods so that we
	 * don't need to create an array to return two values.
	 * <p>
	 * If the allowVoid is false and type is void, then a NoExpressionValueException will be thrown.
	 * This is for the case where the expression was trying to be used in a different
	 * expression. This will be set to void only on expressions that return no value (only
	 * method's do this for now).
	 * 
	 * @param allowVoid Allow void types if <code>true</code>
	 * @return The type.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * @since 1.0.0
	 */
	protected final Class popExpressionType(boolean allowVoid) throws NoExpressionValueException {
		try {
			Class result = (Class) expressionTypeStack.remove(expressionTypeStack.size()-1);
			if (!allowVoid && result == Void.TYPE)
				throw new NoExpressionValueException();
			return result;
				
		} catch (IndexOutOfBoundsException e) {
			throw new NoExpressionValueException();
		}
	}

	/**
	 * Get the expression type at <code>fromTop</code> down from the top. This is
	 * need for when multi-operators happen and they are stored in reverse of 
	 * what is needed. They would normally be stored left to right, with the
	 * rightmost one on top. But they need to be processed left to right, so
	 * to get the left most one requires digging down in the stack.
	 * <p>
	 * When done, <code>popExpressionTypes(int count)</code> must be called to
	 * clean them out since they were processed.

	 * @param fromTop <code>1</code> is the top one, <code>2</code> is the next one down.
	 * @param allowVoid Allow void types if <code>true</code>
	 * @return The type from the top that was requested.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @see IDEExpression#popExpressionTypes(int)
	 * @since 1.0.0
	 */
	protected final Class getExpressionType(int fromTop, boolean allowVoid) throws NoExpressionValueException {
		try {
			Class result = (Class) expressionTypeStack.get(expressionTypeStack.size()-fromTop);
			if (!allowVoid && result == Void.TYPE)
				throw new NoExpressionValueException();
			return result;
		} catch (IndexOutOfBoundsException e) {
			throw new NoExpressionValueException();
		}
	}
	
	/**
	 * Remove the top <code>count</code> items.
	 * 
	 * @param count
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected final void popExpressionTypes(int count) throws NoExpressionValueException {
		try {
			int remove = expressionTypeStack.size()-1;
			while (count-- > 0)
				expressionTypeStack.remove(remove--);
		} catch (IndexOutOfBoundsException e) {
			throw new NoExpressionValueException();
		}
	}
	
	/**
	 * Flag indicating expression should be ignored and not processed.
	 * This happens because of few cases, like conditional and, that
	 * if one returns false, the rest of the expressions in that conditional and
	 * expression should be ignored and not processed.
	 * <p>
	 * It is an int so that those expressions that can initiate an ignore can 
	 * know if it is thiers or not. Only when it decrements to zero will ignore
	 * be over. Those expressions that can start an ignore must increment the
	 * ignore counter if the ignore counter is on, but ignore the expression,
	 * and decrement it when they are complete.
	 * <p>
	 * All of the pushTo...Proxy methods must test this for this to work correctly.
	 */
	protected int ignoreExpression = 0;	
	
	/**
	 * Create the IDEExpression
	 * @param registry
	 * 
	 * @since 1.0.0
	 */
	public ExpressionProcesser() {
	}
	
	/**
	 * Close the exception processing
	 * 
	 * @since 1.0.0
	 */
	public final void close() {
		expressionStack.clear();
		expressionTypeStack.clear();
	}

	/**
	 * Pull the value. The value will be placed into the array passed in.
	 * It will be stored as value[0] = value value[1] = valuetype(Class).
	 * 
	 * @param value The value array to store the value and type into.
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	public final void pullValue(Object[] value) throws NoExpressionValueException {
		value[0] = popExpression();
		value[1] = popExpressionType(false);
		close();
	}
	
	/**
	 * Push the expression (just a value) onto the stack.
	 * 
	 * @param o
	 * @param t
	 * 
	 * @since 1.0.0
	 */
	public final void pushExpression(Object o, Class t) {
		if (ignoreExpression>0)
			return;
		pushExpressionValue(o, t);
	}
	
	/**
	 * Push a cast onto stack. The type passed in is either a String (with classname to cast to) or the
	 * type to cast to.
	 * @param type To cast to. If <code>String</code> then convert to type (using something like <code>Class.forName()</code>) or it is a Class
	 * @throws NoExpressionValueException
	 * @throws ClassCastException
	 * 
	 * @since 1.0.0
	 */
	public final void pushCast(Class type) throws NoExpressionValueException, ClassCastException {
		if (ignoreExpression>0)
			return;
		
		Object exp = popExpression();
		Class exptype = popExpressionType(false);
		
		pushExpressionValue(castBean(type, exp, exptype), type);
	}
	
	/**
	 * Cast a bean into the return type. If the return type is not primitive, then
	 * the bean is left alone, however it is checked to be an instance of
	 * the return type. If the return type is primitive, then the
	 * correct primitive wrapper is created from the bean (bean must be a number or character or boolean primitve so
	 * that cast will work).
	 * <p>
	 * However if can't be cast for primitive or if not an instance of the
	 * returntype for objects, a ClassCastException will be raised.
	 * 
	 * @param returnType
	 * @param bean
	 * @param beanType The type that bean is supposed to be (e.g. even though it is a Number, it actually represents a primitive).
	 * @return The cast bean (either to the appropriate primitive wrapper type or bean)
	 * 
	 * @throws ClassCastException
	 * @since 1.0.0
	 */
	protected final Object castBean(Class returnType, Object bean, Class beanType) throws ClassCastException {
		// Cast uses true value and true class of bean, not expected type (i.e. not beanType).
		if (bean == null)
			if (!returnType.isPrimitive())
				return bean;	// bean is null, and return type is not primitive, so this is a valid cast.
			else 
				throwClassCast(returnType, bean);
		else if (returnType.equals(bean.getClass()))
			return bean;	// They are already the same.
		else if (!returnType.isPrimitive()) {
			if (!beanType.isPrimitive() && returnType.isInstance(bean))
				return bean;
			else
				throwClassCast(returnType, bean);	// Either bean type was wrappering primitive or not instanceof returntype.
		} else {
			if (!beanType.isPrimitive())
				throwClassCast(returnType, bean);	// bean type was not wrappering a primitive. Can't cast to primitive.
			// It is return type of primitive. Now convert to correct primitive.
			if (returnType == Boolean.TYPE)
				if (bean instanceof Boolean)
					return bean;
				else
					throwClassCast(returnType, bean);
			else {
				if (bean instanceof Number) {
					if (returnType == Integer.TYPE)
						if (bean instanceof Integer)
							return bean;
						else
							return new Integer(((Number) bean).intValue());
					else if (returnType == Byte.TYPE)
						if (bean instanceof Byte)
							return bean;
						else
							return new Byte(((Number) bean).byteValue());
					else if (returnType == Character.TYPE)
						if (bean instanceof Character)
							return bean;
						else
							return new Character((char) ((Number) bean).intValue());
					else if (returnType == Double.TYPE)
						if (bean instanceof Double)
							return bean;
						else
							return new Double(((Number) bean).doubleValue());
					else if (returnType == Float.TYPE)
						if (bean instanceof Float)
							return bean;
						else
							return new Float(((Number) bean).floatValue());
					else if (returnType == Long.TYPE)
						if (bean instanceof Long)
							return bean;
						else
							return new Long(((Number) bean).longValue());
					else if (returnType == Short.TYPE)
						if (bean instanceof Short)
							return bean;
						else
							return new Short(((Number) bean).shortValue());	
					else
						throwClassCast(returnType, bean);
				} else if (bean instanceof Character) {
					if (returnType == Character.TYPE)
						return bean;
					else if (returnType == Integer.TYPE)
						return new Integer(((Character) bean).charValue());
					else if (returnType == Byte.TYPE)
						return new Byte((byte) ((Character) bean).charValue());
					else if (returnType == Double.TYPE)
						return new Double((double) ((Character) bean).charValue());
					else if (returnType == Float.TYPE)
						return new Float((float) ((Character) bean).charValue());
					else if (returnType == Long.TYPE)
						return new Long((long) ((Character) bean).charValue());
					else if (returnType == Short.TYPE)
						return new Short((short) ((Character) bean).charValue());	
					else
						throwClassCast(returnType, bean);
				} else
					throwClassCast(returnType, bean);
			}
			
		}
		return null;	// It should never get here;
	}
	
	private void throwClassCast(Class returnType, Object bean) throws ClassCastException {
		throw new ClassCastException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.CannotCastXToY_EXC_"), new Object[] {bean != null ? bean.getClass().getName() : null, returnType.getName()})); //$NON-NLS-1$
	}

	/**
	 * Return the primitive type that the wrapper bean represents (i.e. Boolean instance returns Boolean.TYPE) 
	 * @param bean
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final Class getPrimitiveType(Object bean) {
		if (bean instanceof Boolean)
			return Boolean.TYPE;
		else if (bean instanceof Integer)
			return Integer.TYPE;
		else if (bean instanceof Byte)
			return Byte.TYPE;
		else if (bean instanceof Character)
			return Character.TYPE;
		else if (bean instanceof Double)
			return Double.TYPE;
		else if (bean instanceof Float)
			return Float.TYPE;
		else if (bean instanceof Long)
			return Long.TYPE;
		else if (bean instanceof Short)
			return Short.TYPE;
		else
			throw new IllegalArgumentException(bean != null ? bean.getClass().getName() : "null"); //$NON-NLS-1$
	}
	

	/**
	 * Push the instanceof expression.  The type passed in is either a String (with classname to test against) or the
	 * type to test against.
	 * @param type To test against.
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	public final void pushInstanceof(Class type) throws NoExpressionValueException {
		if (ignoreExpression>0)
			return;
		
		Object exp = popExpression();
		Class exptype = popExpressionType(false);
		pushExpressionValue(isInstance(type, exp, exptype) ? Boolean.TRUE : Boolean.FALSE, Boolean.TYPE);
	}
	
	/**
	 * Test if instance of. It will make sure that primitive to non-primitive is not permitted.
	 * This is a true instance of, which means null IS NOT AN instance of any type. This is
	 * different then assignable from, in that case null can be assigned to any class type.
	 * 
	 * @param type
	 * @param bean
	 * @param beanType
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final boolean isInstance(Class type, Object bean, Class beanType) {
		if (type.isPrimitive())
			return beanType.isPrimitive() && type == beanType;	// Can't use isInstance because for a primitive type isInstance returns false.
		else 
			return type.isInstance(bean);
	}

	private static final String[] PRE_OPER_TO_STRING;
	static {
		PRE_OPER_TO_STRING = new String[IExpressionConstants.PRE_MAX+1];
		PRE_OPER_TO_STRING[IExpressionConstants.PRE_PLUS] = "+"; //$NON-NLS-1$
		PRE_OPER_TO_STRING[IExpressionConstants.PRE_MINUS] = "-"; //$NON-NLS-1$
		PRE_OPER_TO_STRING[IExpressionConstants.PRE_COMPLEMENT] = "~"; //$NON-NLS-1$
		PRE_OPER_TO_STRING[IExpressionConstants.PRE_NOT] = "!"; //$NON-NLS-1$
	}
	
	/**
	 * Push prefix expression.
	 * @param operator The operator from IExpressionConstants
	 * @throws NoExpressionValueException
	 * 
	 * @see IExpressionConstants#PRE_MINUS
	 * @since 1.0.0
	 */
	public final void pushPrefix(int operator) throws NoExpressionValueException {
		if (ignoreExpression>0)
			return;
		
		if (operator == IExpressionConstants.PRE_PLUS)
			return;	// Do nothing. "+" doesn't affect the result of the current top expression.
		
		Object exp = popExpression();
		Class exptype = popExpressionType(false);
		if (!exptype.isPrimitive())
			throwInvalidPrefix(operator, exp);
		
		int primTypeEnum = getEnumForPrimitive(exptype);
		switch (operator) {
			case IExpressionConstants.PRE_MINUS:
				switch (primTypeEnum) {
					case BOOLEAN:
						throwInvalidPrefix(operator, exp);						
					case BYTE:
						exp = new Integer(-((Number) exp).byteValue());
						break;
					case CHAR:
						exp = new Integer(-((Character) exp).charValue());
						break;
					case DOUBLE:
						exp = new Double(-((Number) exp).doubleValue());
						break;
					case FLOAT:
						exp = new Float(-((Number) exp).floatValue());
						break;
					case INT:
						exp = new Integer(-((Number) exp).intValue());
						break;
					case LONG:
						exp = new Long(-((Number) exp).longValue());
						break;
					case SHORT:
						exp = new Integer(-((Number) exp).shortValue());
						break;
				}
				exptype = getPrimitiveType(exp);	// It can actually change the type.				
				break;
				
			case IExpressionConstants.PRE_COMPLEMENT:
				switch (primTypeEnum) {
					case BOOLEAN:
					case DOUBLE:
					case FLOAT:
						throwInvalidPrefix(operator, exp);						
					case BYTE:
						exp = new Integer(~((Number) exp).byteValue());
						break;
					case CHAR:
						exp = new Integer(~((Character) exp).charValue());
						break;
					case INT:
						exp = new Integer(~((Number) exp).intValue());
						break;
					case LONG:
						exp = new Long(~((Number) exp).longValue());
						break;
					case SHORT:
						exp = new Integer(~((Number) exp).shortValue());
						break;
				}
				exptype = getPrimitiveType(exp);	// It can actually change the type.
				break;
			case IExpressionConstants.PRE_NOT:
				switch (primTypeEnum) {
					case BOOLEAN:
						exp = !((Boolean) exp).booleanValue() ? Boolean.TRUE : Boolean.FALSE;
						break;
					case BYTE:
					case CHAR:
					case DOUBLE:
					case FLOAT:
					case INT:
					case LONG:
					case SHORT:
						throwInvalidPrefix(operator, exp);						
				}				
				break;
			}
		
		pushExpressionValue(exp, exptype);	// Push the result back on the stack.
	}

	/**
	 * The primitive enums. 
	 * NOTE: Their order must not changed. They are in order of permitted widening.
	 * 
	 */
	protected static final int
		BOOLEAN = 0,
		BYTE = 1,
		SHORT = 2,	
		CHAR = 3,
		INT = 4,
		LONG = 5,
		FLOAT = 6,
		DOUBLE = 7;
		
		
	
	/**
	 * Get the enum constant for the type of primitive passed in.
	 * @param primitiveType
	 * @return
	 * 
	 * @see ExpressionProcesser#BOOLEAN
	 * @since 1.0.0
	 */
	protected final int getEnumForPrimitive(Class primitiveType) {
		if (primitiveType == Boolean.TYPE)
			return BOOLEAN;
		else if (primitiveType == Integer.TYPE)
			return INT;
		else if (primitiveType == Byte.TYPE)
			return BYTE;
		else if (primitiveType == Character.TYPE)
			return CHAR;
		else if (primitiveType == Double.TYPE)
			return DOUBLE;
		else if (primitiveType == Float.TYPE)
			return FLOAT;
		else if (primitiveType == Long.TYPE)
			return LONG;
		else if (primitiveType == Short.TYPE)
			return SHORT;
		else
			throw new IllegalArgumentException();
	}
	
	private void throwInvalidPrefix(int operator, Object exp) throws IllegalArgumentException {
		throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.InvalidOperandOfPrefixOperator_EXC_"), new Object[] {exp != null ? exp.toString() : null, PRE_OPER_TO_STRING[operator]})); //$NON-NLS-1$
	}

	private static final String[] IN_OPER_TO_STRING;
	static {
		IN_OPER_TO_STRING = new String[IExpressionConstants.IN_MAX+1];
		IN_OPER_TO_STRING[IExpressionConstants.IN_AND] = "&"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_CONDITIONAL_AND] = "&&"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_CONDITIONAL_OR] = "||"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_DIVIDE] = "/"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_EQUALS] = "=="; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_GREATER] = ">"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_GREATER_EQUALS] = ">="; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_LEFT_SHIFT] = "<<"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_LESS] = "<"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_LESS_EQUALS] = "<="; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_MINUS] = "-"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_NOT_EQUALS] = "!="; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_OR] = "|"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_PLUS] = "+"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_REMAINDER] = "%"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_RIGHT_SHIFT_SIGNED] = ">>"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED] = ">>>"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_TIMES] = "*"; //$NON-NLS-1$
		IN_OPER_TO_STRING[IExpressionConstants.IN_XOR] = "^"; //$NON-NLS-1$
	}
		
	
	/**
	 * Push the infix expression onto the stack.
	 * @param operator
	 * @param operandType The operator type from IExpressionConstants.IN_*
	 * @throws NoExpressionValueException
	 * 
	 * @see IExpressionConstants#IN_AND
	 * @since 1.0.0
	 */
	public final void pushInfix(int operator, int operandType) throws NoExpressionValueException {
		boolean wasIgnoring = ignoreExpression>0;
		if (wasIgnoring)
			if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
				ignoreExpression++;	// Increment it so that entire expression is ignored because we already are in an ignore.
			else if (operandType == IInternalExpressionConstants.INFIX_LAST_OPERAND)
				ignoreExpression--;	// Decrement it because we have reached the end.
		if (ignoreExpression>0)
			return;	// We are still ignoring.
		
		if (wasIgnoring && operandType == IInternalExpressionConstants.INFIX_LAST_OPERAND)
			return;	// We've received the last operand but we were ignoring, but the value of the entire expression is still the top stack value.
		
		Object right = null;
		Class rightType = null;
		if (operandType != IInternalExpressionConstants.INFIX_LEFT_OPERAND) {
			// We are not the left operand, so the stack has the right on the top, followed by the left.
			right = popExpression();
			rightType = popExpressionType(false);
		} 
		
		Object value = popExpression();
		Class valueType = popExpressionType(false);

		switch (operator) {
			case IExpressionConstants.IN_AND:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidBitType(valueType, IExpressionConstants.IN_AND);
				testValidBitType(rightType, IExpressionConstants.IN_AND);
				if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) & getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it is int. (even two shorts together produce an int).
					value = new Integer(getInt(value) & getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_CONDITIONAL_AND:
				// This is tricky.
				// First if this is left type, then just continue.
				// Else if this other or last, then need to make it the new value.
				if (operandType != IInternalExpressionConstants.INFIX_LEFT_OPERAND) {
					value = right;
					valueType = rightType;
				}
					
				//If the value is now false, we need to ignore the rest.
				if (valueType != Boolean.TYPE)
					throwInvalidInfix(operator, value);
				if (!((Boolean) value).booleanValue() && operandType != IInternalExpressionConstants.INFIX_LAST_OPERAND)
					++ignoreExpression;	// Start ignoring since current value is now false.
				break;
			case IExpressionConstants.IN_CONDITIONAL_OR:
				// This is tricky.
				// First if this is left type, then just continue.
				// Else if this other or last, then need to make it the new value.
				if (operandType != IInternalExpressionConstants.INFIX_LEFT_OPERAND) {
					value = right;
					valueType = rightType;
				}
				
				//If the value is now true, we need to ignore the rest.
				if (valueType != Boolean.TYPE)
					throwInvalidInfix(operator, value);
				if (((Boolean) value).booleanValue() && operandType != IInternalExpressionConstants.INFIX_LAST_OPERAND)
					++ignoreExpression;	// Start ignoring since current value is now true.
				break;
			case IExpressionConstants.IN_DIVIDE:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidArithmeticType(valueType, IExpressionConstants.IN_DIVIDE);
				testValidArithmeticType(rightType, IExpressionConstants.IN_DIVIDE);
				if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, the result will be double.
					value = new Double(getDouble(value) / getDouble(right));
					valueType = Double.TYPE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, the result will be float.
					value = new Float(getFloat(value) / getFloat(right));
					valueType = Float.TYPE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) / getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it will result in an int, even if both sides are short.
					value = new Integer(getInt(value) / getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_EQUALS:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				// We should never get extended operator for this, but we'll ignore the possibility.
				if (valueType.isPrimitive() && rightType.isPrimitive()) {
					// Primitives require more testing than just ==. boolean primitives 
					if (valueType == Boolean.TYPE || rightType == Boolean.TYPE) {
						// If either side is a boolean, then the other side needs to be boolean for it to even try to be true.
						if (valueType != Boolean.TYPE || valueType != Boolean.TYPE)
							value = Boolean.FALSE;
						else
							value = (((Boolean) value).booleanValue() == ((Boolean) right).booleanValue()) ? Boolean.TRUE : Boolean.FALSE;
					} else {
						// Now do number tests since not boolean primitive, only numbers are left
						if (valueType == Double.TYPE || rightType == Double.TYPE) {
							// If either side is double, compare as double.
							value = (getDouble(value) == getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
							// If either side is float, compare as float.
							value = (getFloat(value) == getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
							// If either side is long, the compare as long.
							value = (getLong(value) == getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
						} else {
							// Else it will compare as int, even if both sides are short.
							value = (getInt(value) == getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
						}
					}
				} else if (valueType.isPrimitive() || rightType.isPrimitive())
					value = Boolean.FALSE;	// Can't be true if one side prim and the other isn't
				else {
					// Just do object ==
					value = (value == right) ? Boolean.TRUE : Boolean.FALSE;
				}
				valueType = Boolean.TYPE;	// We know result will be a boolean.
				break;
			case IExpressionConstants.IN_GREATER:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidArithmeticType(valueType, IExpressionConstants.IN_GREATER);
				testValidArithmeticType(rightType, IExpressionConstants.IN_GREATER);
				if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, compare will be double.
					value = (getDouble(value) > getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, compare will be float.
					value = (getFloat(value) > getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, compare will be long.
					value = (getLong(value) > getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else {
					// Else compare will be int, even if both sides are short.
					value = (getInt(value) > getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
				}
				valueType = Boolean.TYPE;	// We know result will be a boolean.
				break;
			case IExpressionConstants.IN_GREATER_EQUALS:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidArithmeticType(valueType, IExpressionConstants.IN_GREATER_EQUALS);
				testValidArithmeticType(rightType, IExpressionConstants.IN_GREATER_EQUALS);
				if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, compare will be double.
					value = (getDouble(value) >= getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, compare will be float.
					value = (getFloat(value) >= getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, compare will be long.
					value = (getLong(value) >= getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else {
					// Else compare will be int, even if both sides are short.
					value = (getInt(value) >= getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
				}
				valueType = Boolean.TYPE;	// We know result will be a boolean.
				break;
			case IExpressionConstants.IN_LEFT_SHIFT:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidBitType(valueType, IExpressionConstants.IN_LEFT_SHIFT);
				testValidBitType(rightType, IExpressionConstants.IN_LEFT_SHIFT);
				if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) << getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it is int. (even two shorts together produce an int).
					value = new Integer(getInt(value) << getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_LESS:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidArithmeticType(valueType, IExpressionConstants.IN_LESS);
				testValidArithmeticType(rightType, IExpressionConstants.IN_LESS);
				if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, compare will be double.
					value = (getDouble(value) < getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, compare will be float.
					value = (getFloat(value) < getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, compare will be long.
					value = (getLong(value) < getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else {
					// Else compare will be int, even if both sides are short.
					value = (getInt(value) < getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
				}
				valueType = Boolean.TYPE;	// We know result will be a boolean.
				break;
			case IExpressionConstants.IN_LESS_EQUALS:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidArithmeticType(valueType, IExpressionConstants.IN_LESS_EQUALS);
				testValidArithmeticType(rightType, IExpressionConstants.IN_LESS_EQUALS);
				if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, compare will be double.
					value = (getDouble(value) <= getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, compare will be float.
					value = (getFloat(value) <= getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, compare will be long.
					value = (getLong(value) <= getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
				} else {
					// Else compare will be int, even if both sides are short.
					value = (getInt(value) <= getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
				}
				valueType = Boolean.TYPE;	// We know result will be a boolean.
				break;
			case IExpressionConstants.IN_MINUS:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidArithmeticType(valueType, IExpressionConstants.IN_MINUS);
				testValidArithmeticType(rightType, IExpressionConstants.IN_MINUS);
				if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, the result will be double.
					value = new Double(getDouble(value) - getDouble(right));
					valueType = Double.TYPE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, the result will be float.
					value = new Float(getFloat(value) - getFloat(right));
					valueType = Float.TYPE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) - getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it will result in an int, even if both sides are short.
					value = new Integer(getInt(value) - getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_NOT_EQUALS:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				// We should never get extended operator for this, but we'll ignore the possibility.
				if (valueType.isPrimitive() && rightType.isPrimitive()) {
					// Primitives require more testing than just ==. boolean primitives 
					if (valueType == Boolean.TYPE || rightType == Boolean.TYPE) {
						// If either side is a boolean, then the other side needs to be boolean for it to even try to be true.
						if (valueType != Boolean.TYPE || valueType != Boolean.TYPE)
							value = Boolean.TRUE;
						else
							value = (((Boolean) value).booleanValue() != ((Boolean) right).booleanValue()) ? Boolean.TRUE : Boolean.FALSE;
					} else {
						// Now do number tests since not boolean primitive, only numbers are left
						if (valueType == Double.TYPE || rightType == Double.TYPE) {
							// If either side is double, compare as double.
							value = (getDouble(value) != getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
							// If either side is float, compare as float.
							value = (getFloat(value) != getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
							// If either side is long, the compare as long.
							value = (getLong(value) != getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
						} else {
							// Else it will compare as int, even if both sides are short.
							value = (getInt(value) != getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
						}
					}
				} else if (valueType.isPrimitive() || rightType.isPrimitive())
					value = Boolean.TRUE;	// Must be true if one side prim and the other isn't
				else {
					// Just do object !=
					value = (value != right) ? Boolean.TRUE : Boolean.FALSE;
				}
				valueType = Boolean.TYPE;	// We know result will be a boolean.
				break;
			case IExpressionConstants.IN_OR:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidBitType(valueType, IExpressionConstants.IN_OR);
				testValidBitType(rightType, IExpressionConstants.IN_OR);
				if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) | getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it is int. (even two shorts together produce an int).
					value = new Integer(getInt(value) | getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_PLUS:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND) {
					if (valueType == String.class) {
						// Special. left argument is a string, so we want to store a string buffer instead
						// since we know we will be appending to it. 
						value = new StringBuffer((String) value);
					}	
					break;	// Do nothing with first operand
				}
				
				testValidPlusType(valueType, rightType);
				if (valueType == String.class || rightType == String.class) {
					// Special we have a string on one side. Need to do it as strings instead.
					// We are going to be tricky in that we will store a StringBuffer on the stack (if not last operand)
					// but call it a string.
					StringBuffer sb = null;
					if (valueType == String.class) {
						sb = (StringBuffer) value;	// We know that if the value (left) is string type, we've already converted it to buffer.
					} else {
						// The right is the one that introduces the string, so we change the value over to a string buffer.
						sb = new StringBuffer(((String) right).length()+16);	// We can't put the value in yet, need to get left into it.
						appendToBuffer(sb, value, valueType);	// Put the left value in now
						value = sb;
						valueType = String.class;	// Make it a string class
					}
					appendToBuffer(sb, right, rightType);
					// Now if we are the last operand, we should get rid of the buffer and put a true string back in.
					if (operandType == IInternalExpressionConstants.INFIX_LAST_OPERAND)
						value = sb.toString();
				} else if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, the result will be double.
					value = new Double(getDouble(value) + getDouble(right));
					valueType = Double.TYPE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, the result will be float.
					value = new Float(getFloat(value) + getFloat(right));
					valueType = Float.TYPE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) + getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it will result in an int, even if both sides are short.
					value = new Integer(getInt(value) + getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_REMAINDER:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidArithmeticType(valueType, IExpressionConstants.IN_REMAINDER);
				testValidArithmeticType(rightType, IExpressionConstants.IN_REMAINDER);
				if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, the result will be double.
					value = new Double(getDouble(value) % getDouble(right));
					valueType = Double.TYPE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, the result will be float.
					value = new Float(getFloat(value) % getFloat(right));
					valueType = Float.TYPE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) % getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it will result in an int, even if both sides are short.
					value = new Integer(getInt(value) % getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_RIGHT_SHIFT_SIGNED:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidBitType(valueType, IExpressionConstants.IN_RIGHT_SHIFT_SIGNED);
				testValidBitType(rightType, IExpressionConstants.IN_RIGHT_SHIFT_SIGNED);
				if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) >> getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it is int. (even two shorts together produce an int).
					value = new Integer(getInt(value) >> getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidBitType(valueType, IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED);
				testValidBitType(rightType, IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED);
				if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) >>> getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it is int. (even two shorts together produce an int).
					value = new Integer(getInt(value) >>> getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_TIMES:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidArithmeticType(valueType, IExpressionConstants.IN_TIMES);
				testValidArithmeticType(rightType, IExpressionConstants.IN_TIMES);
				if (valueType == Double.TYPE || rightType == Double.TYPE) {
					// If either side is double, the result will be double.
					value = new Double(getDouble(value) * getDouble(right));
					valueType = Double.TYPE;
				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
					// If either side is float, the result will be float.
					value = new Float(getFloat(value) * getFloat(right));
					valueType = Float.TYPE;
				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) * getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it will result in an int, even if both sides are short.
					value = new Integer(getInt(value) * getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			case IExpressionConstants.IN_XOR:
				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
					break;	// Do nothing with first operand
				
				testValidBitType(valueType, IExpressionConstants.IN_XOR);
				testValidBitType(rightType, IExpressionConstants.IN_XOR);
				if (valueType == Long.TYPE || rightType == Long.TYPE) {
					// If either side is long, the result will be long.
					value = new Long(getLong(value) ^ getLong(right));
					valueType = Long.TYPE;
				} else {
					// Else it is int. (even two shorts together produce an int).
					value = new Integer(getInt(value) ^ getInt(right));
					valueType = Integer.TYPE;
				}
				break;
			} 
		
		pushExpressionValue(value, valueType);	// Push the result back on the stack.
	}

	/**
	 * Get int value of the primitive wrapper bean passed in (must be either a <code>Number/code> or <code>Character</code>.
	 * Anything else will cause a class cast error.
	 * 
	 * @param bean
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final int getInt(Object bean) {
		return (bean instanceof Number) ? ((Number) bean).intValue() : ((Character) bean).charValue();
	}
	
	/**
	 * Get float value of the primitive wrapper bean passed in (must be either a <code>Number/code> or <code>Character</code>.
	 * Anything else will cause a class cast error.
	 * 
	 * @param bean
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final float getFloat(Object bean) {
		return (bean instanceof Number) ? ((Number) bean).floatValue() : ((Character) bean).charValue();
	}

	/**
	 * Get double value of the primitive wrapper bean passed in (must be either a <code>Number/code> or <code>Character</code>.
	 * Anything else will cause a class cast error.
	 * 
	 * @param bean
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final double getDouble(Object bean) {
		return (bean instanceof Number) ? ((Number) bean).doubleValue() : ((Character) bean).charValue();
	}
	
	/**
	 * Get long value of the primitive wrapper bean passed in (must be either a <code>Number/code> or <code>Character</code>.
	 * Anything else will cause a class cast error.
	 * 
	 * @param bean
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final long getLong(Object bean) {
		return (bean instanceof Number) ? ((Number) bean).longValue() : ((Character) bean).charValue();
	}
	
	private void throwInvalidInfix(int operator, Object value) throws IllegalArgumentException {
		throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.InvalidOperandOfOperator_EXC_"), new Object[] {value != null ? value.toString() : null, IN_OPER_TO_STRING[operator]})); //$NON-NLS-1$
	}
	
	private void testValidBitType(Class type, int operator) {
		if (!type.isPrimitive() || type == Boolean.TYPE || type == Double.TYPE|| type == Float.TYPE)
			throwInvalidInfix(operator, type);
	}
	
	private void testValidArithmeticType(Class type, int operator) {
		if (!type.isPrimitive() || type == Boolean.TYPE)
			throwInvalidInfix(operator, type);
	}

	private void testValidPlusType(Class left, Class right) {
		// Plus is special in that string objects are also valid.
		if (left == String.class || right == String.class)
			return;	// As long as one side is string. Anything is valid.
		// If neither is string, then standard arithmetic test.
		testValidArithmeticType(left, IExpressionConstants.IN_PLUS);
		testValidArithmeticType(right, IExpressionConstants.IN_PLUS);
	}
	
	private void appendToBuffer(StringBuffer sb, Object value, Class valueType) {
		if (value == null)
			sb.append((Object)null);
		else if (valueType == String.class)
			sb.append((String) value);
		else if (valueType.isPrimitive()) {
			switch (getEnumForPrimitive(valueType)) {
				case BOOLEAN:
					sb.append(((Boolean) value).booleanValue());
					break;
				case BYTE:
					sb.append(((Number) value).byteValue());
					break;
				case CHAR:
					sb.append(((Character) value).charValue());
					break;
				case DOUBLE:
					sb.append(((Number) value).doubleValue());
					break;
				case FLOAT:
					sb.append(((Number) value).floatValue());
					break;
				case INT:
					sb.append(((Number) value).intValue());
					break;
				case LONG:
					sb.append(((Number) value).longValue());
					break;
				case SHORT:
					sb.append(((Number) value).shortValue());
					break;		
			}
		} else {
			// Just an object.
			sb.append(value);
		}
	}
	
	/**
	 * Push the array access expression.
	 * 
	 * @param indexCount Number of dimensions being accessed
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	public final void pushArrayAccess(int indexCount) throws NoExpressionValueException {
		if (ignoreExpression>0)
			return;
		
		// We need to pop off the args. The topmost will be the rightmost index, and the bottom most will be the array itself.
		int[] arguments = new int[indexCount];
		// Fill the arg array in reverse order.
		for(int i=indexCount-1; i >= 0; i--) {
			Object index = popExpression();
			Class indexType = popExpressionType(false);
			if (indexType.isPrimitive() && (indexType == Integer.TYPE || indexType == Short.TYPE || indexType == Character.TYPE || indexType == Byte.TYPE)) {
				arguments[i] = getInt(index);
			} else
				throwClassCast(Integer.TYPE, index);
		}
		
		Object array = popExpression();
		Class arrayType = popExpressionType(false);
		if (arrayType.isArray()) {
			// First figure out how many dimensions are available. Stop when we hit indexcount because we won't be going further.
			int dimcount = 0;
			Class[] componentTypes = new Class[indexCount];	// 
			Class componentType = arrayType;
			while (dimcount < indexCount && componentType.isArray()) {
				componentTypes[dimcount++] = componentType = componentType.getComponentType();
			}
			
			if (dimcount < indexCount)
				throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.XIsGreaterThanNumberOfDimensionsInArray_EXC_"), new Object[] {new Integer(indexCount), new Integer(dimcount)})); //$NON-NLS-1$
			
			// Now start accessing one index at a time.
			Object value = array;	// Final value, start with full array. 
			for(int i=0; i<indexCount; i++) {
				value = Array.get(value, arguments[i]);
			}
			pushExpressionValue(value, componentTypes[indexCount-1]);
		}  else
			throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.NotAnArray_EXC_"), new Object[] {arrayType})); //$NON-NLS-1$
	}
	
	/**
	 * Push the array creation request.
	 * 
	 * @param arrayType The type of the array
	 * @param dimensionCount The number of dimensions being initialized. Zero if using an initializer.
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	public final void pushArrayCreation(Class arrayType, int dimensionCount) throws NoExpressionValueException {
		if (ignoreExpression>0)
			return;
		
		if (dimensionCount == 0) {
			// The top value is the array itself, from the array initializer.
			// So we do nothing.
		} else {
			// Strip off dimensionCounts from the array type, e.g.
			// ArrayType is int[][][]
			// Dimensioncount is 2
			// Then we need to strip two componenttypes off of the array type
			// wind up with int[]
			// This is necessary because Array.new will add those dimensions back
			// on through the dimension count.
			Class componentType = arrayType;
			for(int i=0; i < dimensionCount && componentType != null; i++)
				componentType = componentType.getComponentType();
			if (componentType == null)
				throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.ArraytypeHasFewerDimensionsThanRequested_EXC_"), new Object[] {arrayType, new Integer(dimensionCount)})); //$NON-NLS-1$
			
			// We need to pull in the dimension initializers. They are stacked in reverse order.
			int[] dimInit = new int[dimensionCount];
			for(int i=dimensionCount-1; i >= 0; i--) {
				Object index = popExpression();
				Class dimType = popExpressionType(false);
				if (dimType.isPrimitive() && (dimType == Integer.TYPE || dimType == Short.TYPE || dimType == Character.TYPE || dimType == Byte.TYPE)) {
					dimInit[i] = getInt(index);
				} else
					throwClassCast(Integer.TYPE, index);
			}
			
			// Finally create the array.
			Object array = Array.newInstance(componentType, dimInit);
			pushExpressionValue(array, arrayType);
		}
	}

	/**
	 * Push the array initializer request.
	 * 
	 * @param arrayType The type of the array to create, minus one dimension.
	 * @param expressionCount
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	public final void pushArrayInitializer(Class arrayType, int expressionCount) throws NoExpressionValueException {
		if (ignoreExpression>0)
			return;

		Object[] dimValues = null;
		if (expressionCount > 0) {
			// We need to pull in the initializers. They are stacked in reverse order.
			dimValues = new Object[expressionCount];
			for (int i = expressionCount - 1; i >= 0; i--) {
				Object dimValue = dimValues[i] = popExpression();
				Class dimType = popExpressionType(false);
				if (arrayType.isPrimitive()) {
					if (dimValue == null || !dimType.isPrimitive())
						throwClassCast(arrayType, dimType);
					// A little trickier. Can assign short to an int, but can't assign long to an int. Widening is permitted.
					if (arrayType != dimType) {
						int compEnum = getEnumForPrimitive(arrayType);
						int dimEnum = getEnumForPrimitive(dimType);
						if (compEnum == BOOLEAN || dimEnum == BOOLEAN)
							throwClassCast(arrayType, dimType);
						int dimValueAsInt = getInt(dimValue);
						switch (compEnum) {
							case BYTE :
								// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
								// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
								// however, at this point in time we no longer know this. So we will simply allow it.
								if (dimEnum > INT || dimValueAsInt > Byte.MAX_VALUE || dimValueAsInt < Byte.MIN_VALUE)
									throwClassCast(arrayType, dimType);
								// But need to be changed to appropriate type for the array.set to work.									
								dimValues[i] = new Byte((byte)dimValueAsInt);
								break;
							case SHORT :								
								// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
								// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
								// however, at this point in time we no longer know this. So we will simply allow it.
								if (dimEnum > INT || dimValueAsInt > Short.MAX_VALUE || dimValueAsInt < Short.MIN_VALUE)
									throwClassCast(arrayType, dimType);
								// But need to be changed to appropriate type for the array.set to work.									
								dimValues[i] = new Short((short)dimValueAsInt);
								break;
							case CHAR :
								// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
								// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
								// however, at this point in time we no longer know this. So we will simply allow it.
								if (dimEnum > INT || dimValueAsInt > Character.MAX_VALUE || dimValueAsInt < Character.MIN_VALUE)
									throwClassCast(arrayType, dimType);
								// But need to be changed to appropriate type for the array.set to work.									
								dimValues[i] = new Character((char)dimValueAsInt);
								break;
							case INT :
								// Can accept byte, short, char, or int. Can't accept long, double, float at all.
								if (dimEnum > INT)
									throwClassCast(arrayType, dimType);
								// But need to be changed to appropriate type for the array.set to work.									
								dimValues[i] = new Integer(dimValueAsInt);
								break;
							case LONG :
								// Can accept byte, short, char, int, or long. Can't accept double, float at all.
								if (dimEnum > LONG)
									throwClassCast(arrayType, dimType);
								// But need to be changed to appropriate type for the array.set to work.									
								dimValues[i] = new Long(getLong(dimValue));
								break;
							case FLOAT :
								// Can accept byte, short, char, int, long, or float. Can't accept double at all.
								if (dimEnum > FLOAT)
									throwClassCast(arrayType, dimType);
								// But need to be changed to appropriate type for the array.set to work.									
								dimValues[i] = new Float(getFloat(dimValue));
								break;
							case DOUBLE :
								// But need to be changed to appropriate type for the array.set to work.									
								dimValues[i] = new Double(getDouble(dimValue));
								break;

						}
					}
					// Compatible, so ok.
				} else if (dimType != MethodHelper.NULL_TYPE && !arrayType.isAssignableFrom(dimType)) {
					// If it is NULL_TYPE, then this is a pushed null. This is always assignable to a non-primitive.
					// So we don't enter here in that case. However, a null that was returned from some expression
					// won't have a NULL_TYPE, it will instead have the expected return type. That must be used
					// in the assignment instead. That is because in java it uses the expected type to determine
					// compatibility, not the actual type.
					throwClassCast(arrayType, dimType);
				}
			}
			
		}
		
		// Now we finally create the array.
		Object array = Array.newInstance(arrayType, new int[] {expressionCount});
		for (int i = 0; i < expressionCount; i++) {
			Array.set(array, i, dimValues[i]);
		}
		
		pushExpressionValue(array, array.getClass());	// Adjust to true array type, not the incoming type (which is one dimension too small).
	}

	/**
	 * Push the class instance creation request.
	 * 
	 * @param type The type to create an instance of
	 * @param argumentCount The number of arguments (which are stored on the stack).	 * @throws NoExpressionValueException
	 * @throws EvaluationException
	 * @throws IllegalArgumentException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * 
	 * @since 1.0.0
	 */
	public final void pushClassInstanceCreation(Class type, int argumentCount) throws NoExpressionValueException, EvaluationException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
		if (ignoreExpression>0)
			return;
					
		// We need to pull in the arguments. They are stacked in reverse order.
		Object value = null;	// The new instance.
		if (argumentCount > 0) {
			Object[]  args = new Object[argumentCount];
			Class[] argTypes = new Class[argumentCount];
			for (int i = argumentCount - 1; i >= 0; i--) {
				args[i] = popExpression();
				argTypes[i] = popExpressionType(false);
			}
			
			// Now we need to find the appropriate constructor.
			Constructor ctor;
			try {
				ctor = MethodHelper.findCompatibleConstructor(type, argTypes);
			} catch (NoSuchMethodException e) {
				throw new EvaluationException(e);
			} catch (AmbiguousMethodException e) {
				throw new EvaluationException(e);
			}
			value = ctor.newInstance(args);
		} else {
			// No args, just do default ctor.
			value = type.newInstance();
		}
		
		pushExpressionValue(value, type);
	}

	/**
	 * Push the field access expression.
	 * @param fieldName
	 * @param hasReceiver
	 * @throws NoExpressionValueException
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * 
	 * @since 1.0.0
	 */
	public final void pushFieldAccess(String fieldName, boolean hasReceiver) throws NoExpressionValueException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
		if (ignoreExpression>0)
			return;
	
		// Get the receiver off of the stack.
		Object receiver = popExpression();
		Class receiverType = popExpressionType(false);
		
		// Find the field.
		Field field = receiverType.getField(fieldName);
		// Access the field.
		Object value = field.get(receiver);
		Class valueType = field.getType();
		pushExpressionValue(value, valueType);
	}

	/**
	 * Push the method invocation expression.
	 * @param methodName
	 * @param hasReceiver
	 * @param argCount
	 * @throws NoExpressionValueException
	 * @throws EvaluationException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * 
	 * @since 1.0.0
	 */
	public final void pushMethodInvocation(String methodName, boolean hasReceiver, int argCount) throws NoExpressionValueException, EvaluationException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		if (ignoreExpression>0)
			return;
		
		// We need to pull in the arguments. They are stacked in reverse order.
		Object[]  args = new Object[argCount];
		Class[] argTypes = new Class[argCount];
		for (int i = argCount - 1; i >= 0; i--) {
			args[i] = popExpression();
			argTypes[i] = popExpressionType(false);
		}
		
		// Now get receiver
		Object receiver = popExpression();
		Class receiverType = popExpressionType(false);
		
		// Now we need to find the appropriate method.
		Method method;
		try {
			method = MethodHelper.findCompatibleMethod(receiverType, methodName, argTypes);
		} catch (NoSuchMethodException e) {
			throw new EvaluationException(e);
		} catch (AmbiguousMethodException e) {
			throw new EvaluationException(e);
		}
		Object value = method.invoke(receiver, args);
		
		pushExpressionValue(value, method.getReturnType());
	}

	/**
	 * @param expressionType
	 * 
	 * @since 1.0.0
	 */
	public final void pushConditional(int expressionType) throws NoExpressionValueException {
		boolean wasIgnoring = ignoreExpression>0;
		if (wasIgnoring) {
			if (expressionType == IExpressionConstants.CONDITIONAL_CONDITION)
				ignoreExpression+=2;	// Increment it twice so that entire expression is ignored because we already are in an ignore.
			else
				ignoreExpression--;	// Decrement it because we have ignored one of the expressions.
			if (ignoreExpression>0)
				return;	// We are still ignoring.
		}
		
		switch (expressionType) {
			case IExpressionConstants.CONDITIONAL_CONDITION:
				Object condition = popExpression();
				Class type = popExpressionType(false);
				if (type != Boolean.TYPE)
					throwClassCast(Boolean.TYPE, condition);
				if (((Boolean) condition).booleanValue()) {
					// Condition was true.
					// Do nothing. Let true condition be processed.
				} else {
					// Condition was false.
					++ignoreExpression;	// Tell the true condition it should be ignored.
				}
				// We don't put anything back on the stack because the condition test is not ever returned.
				// The appropriate true or false condition will be left on the stack.
				break;
			case IExpressionConstants.CONDITIONAL_TRUE:
				if (!wasIgnoring) {
					// true was processed, so now tell false to not process.
					// The true condition and type will be left on top of the stack.
					++ignoreExpression;	
				}
				break;
			case IExpressionConstants.CONDITIONAL_FALSE:
				// There's nothing to do, if it was ignored due to true, then true is on the stack.
				// If it wasn't ignored, then false expression is on the stack, which is what it should be.
				break;
		}
	}
}
