/*******************************************************************************
 * Copyright (c) 2004, 2006 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
 *******************************************************************************/
/*


 */
package org.eclipse.jem.internal.proxy.initParser.tree;

import java.lang.reflect.*;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jem.internal.proxy.common.*;
import org.eclipse.jem.internal.proxy.initParser.InitializationStringEvaluationException;
import org.eclipse.jem.internal.proxy.initParser.InitializationStringParser;
 
/**
 * 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 {

	/**
	 * A variable reference for a field access.
	 * 
	 * @since 1.1.0
	 */
	protected static class FieldAccessReference extends VariableReference {
		
		private final Field field;
		private final Object receiver;

		/**
		 * Use this to construct a FieldAccessReference. This will do checks to make sure
		 * it is valid so that exceptions won't be thrown later when actually dereferenced.
		 * 
		 * @param field
		 * @param receiver
		 * @return
		 * @throws IllegalArgumentException
		 * 
		 * @since 1.1.0
		 */
		public static FieldAccessReference createFieldAccessReference(Field field, Object receiver) throws IllegalArgumentException {
			// If static, then receiver is ignored.
			if (!Modifier.isStatic(field.getModifiers())) {
				if (!field.getDeclaringClass().isInstance(receiver))
					throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.CreateFieldAccessReference.FieldsTypesNotMatching_EXC_"), new Object[]{field.getType(), (receiver!=null ? receiver.getClass() : null)})); //$NON-NLS-1$
			}
			field.setAccessible(true);	// Make it always accessible. Trust it. 
			return new FieldAccessReference(field, receiver);
		}
		
		protected FieldAccessReference(Field field, Object receiver) {
			this.field = field;
			this.receiver = receiver;
		}
		
		
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.initParser.tree.ExpressionProcesser.VariableReference#dereference()
		 */
		public Object dereference() {
			try {
				return field.get(receiver);
			} catch (IllegalArgumentException e) {
				// Shouldn't occur. Already tested for this.
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// Shouldn't occur. Already tested for this.
				e.printStackTrace();
			}
			return null;
		}
		
		
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.initParser.tree.ExpressionProcesser.VariableReference#set(java.lang.Object, java.lang.Class)
		 */
		public Object set(Object value, Class type) throws IllegalArgumentException, IllegalAccessException {
			field.set(receiver, value);
			return field.get(receiver);	// Just in case some conversion happened. Technically it is not the value set but the retrieved when in an assignment.
		}
		
		
		/* (non-Javadoc)
		 * @see java.lang.Object#toString()
		 */
		public String toString() {
			return "FieldAccess{"+field.toString()+"} on "+(receiver != null ? receiver.toString() : "<static access>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
	}
	
	/**
	 * A variable reference for an Array access. It will reference only the last indexed entry of the array.
	 * For example if <code>x[3][4]</code> is the access, then what will be given to this reference will be
	 * the array entry at x[3][4], not the x array itself.
	 * 
	 * @since 1.1.0
	 */
	protected static class ArrayAccessReference extends VariableReference {
		
		
		private final Object array;
		private final int index;

		/**
		 * Use this to construct an array access reference. This will do checks to make sure
		 * it is valid so that exceptions won't be thrown later when actually dereferenced.
		 * 
		 * @param array
		 * @param index
		 * @return
		 * @throws IllegalArgumentException
		 * 
		 * @since 1.1.0
		 */
		public static ArrayAccessReference createArrayAccessReference(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
			int len = Array.getLength(array);
			if (index < 0 || len <= index)
				throw new ArrayIndexOutOfBoundsException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.CreateArrayAccessReference.OutOfBounds_EXC_"), new Object[]{new Integer(index), new Integer(len)})); //$NON-NLS-1$
			return new ArrayAccessReference(array, index);
		}
		/**
		 * Construct the reference with the array and the index of the entry being referenced.
		 * @param array
		 * @param index
		 * 
		 * @since 1.1.0
		 */
		protected ArrayAccessReference(Object array, int index) {
			this.array = array;
			this.index = index;
		}
		
		
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.initParser.tree.VariableReference#dereference()
		 */
		public Object dereference() {
			return Array.get(array, index);
		}
		
		
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.initParser.tree.VariableReference#set(java.lang.Object, java.lang.Class)
		 */
		public Object set(Object value, Class type) throws IllegalArgumentException {
			Array.set(array, index, value);
			return Array.get(array, index);	// In case there was some conversion applied. Technically it is not the value set but the retrieved when in an assignment.
		}
		
		
		/* (non-Javadoc)
		 * @see java.lang.Object#toString()
		 */
		public String toString() {
			return "ArrayAccess["+index+"]: "+array.toString(); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}
	
	/**
	 * 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 List expressionStack = new ArrayList(10);
	private List expressionTypeStack = new ArrayList(10);
	
	/**
	 * List of the expression proxies. The index into the list is the
	 * same as the expression proxy id. 
	 */
	private ArrayList expressionProxies;	// It is array list because we want to call ensureCapacity and that is not available on List.
	
	/**
	 * An error has occurred. At this point all subcommands will simply make sure they flush the input stream
	 * correctly, but they do not process it.
	 * 
	 * @since 1.0.0
	 */
	private boolean errorOccurred = false;
	private boolean novalueException = false;
	
	private Throwable exception = null;	// Was there another kind of exception that was caught.
	
	/**
	 * Process all other exceptions then the NoExpressionValueException. This can be called from usage code so that if there was an error
	 * in setting up for a call to the processer it can be logged.
	 * 
	 * @param e
	 * 
	 * @since 1.0.0
	 */
	public final void processException(Throwable e) {
		// Process all other exceptions.
		novalueException = false;
		while (e.getCause() != null)
			e = e.getCause();
		if (traceOn) {
			System.out.println();
			System.out.print("***** >>>\tException: "); //$NON-NLS-1$
			System.out.println(e);
		}
		throwException(e);	// Treat as a throw to let try/catches expressions handle it.
	}
	
	/**
	 * This is a syntax exception. This means data coming across is corrupted in
	 * some way so no further processing should occur. 
	 * @param e
	 * 
	 * @since 1.1.0
	 */
	protected final void processSyntaxException(Throwable e) {
		errorOccurred = true;
		novalueException = false;
		exception = e;		
	}
		
	/**
	 * Process a NoExpressionValueException. Don't wrapper these.
	 * @param e
	 * 
	 * @since 1.1.0
	 */
	protected final void processSyntaxException(NoExpressionValueException e) {
		if (traceOn) {
			// This can happen at any time, so make sure we are on a new line.
			System.out.println();
			printTrace("Expression has no value", false); //$NON-NLS-1$
		}
		try {
			errorOccurred = true;
			novalueException = true;
			exception = e;
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	/**
	 * Return whether there are any errors.
	 * 
	 * @return <code>true</code> if no errors.
	 * 
	 * @since 1.0.0
	 */
	public boolean noErrors() {
		return !errorOccurred;
	}
	
	/**
	 * Return whether the error is a NoExpressionValueException or not.
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public boolean isNoExpressionValue() {
		return novalueException;
	}
	
	/**
	 * Return the throwable if a Throwable was caught.
	 * 
	 * @return The throwable, or <code>null</code> if not set.
	 * 
	 * @since 1.0.0
	 */
	public Throwable getErrorThrowable() {
		return exception;
	}

	/**
	 * 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. This will dereference
	 * any variable references.
	 * 
	 * @return The value.
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected final Object popExpression() throws NoExpressionValueException {
		return popExpression(true);
	}
	
	/**
	 * 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.
	 * 
	 * @param deReference If the top expression is a Reference, then dereference it.
	 * @return The value.
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected final Object popExpression(boolean deReference) throws NoExpressionValueException {
		try {
			// Do not pop above the current subexpression pos, if any.
			if (topSubexpression != -1)
				if (expressionStack.size() == subexpressionStackPos[topSubexpression])
					throw new NoExpressionValueException();
			
			Object result = expressionStack.remove(expressionStack.size()-1);
			if (deReference && result instanceof VariableReference)
				result = ((VariableReference) result).dereference();
			return result;
		} 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.
	 * <p>
	 * This will not dereference the expression. It is the job of the caller to do this. 
	 *  
	 * @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 {
			// Do not pull above the current subexpression pos, if any.			
			if (topSubexpression != -1)
				if (expressionStack.size()-fromTop < subexpressionStackPos[topSubexpression])
					throw new NoExpressionValueException();
			
			return expressionStack.get(expressionStack.size()-fromTop);
		} catch (IndexOutOfBoundsException e) {
			throw new NoExpressionValueException();
		}
	}
	
	/**
	 * Remove the top <code>count</code> items. This will not cause dereferencing to occur. It
	 * removes the corresponding type stack entries.
	 * 
	 * @param count
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected final void popExpressions(int count) throws NoExpressionValueException {
		try {
			// Do not pop above the current subexpression pos, if any.
			int stop = topSubexpression != -1 ? subexpressionStackPos[topSubexpression] : -1;
			int remove = expressionStack.size()-1;
			while (count-- > 0) {
				if (expressionStack.size() <= stop)
					throw new NoExpressionValueException();	// Try to go above the current subexpression.
				expressionStack.remove(remove);
				expressionTypeStack.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 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(InitparserTreeMessages.getString("ExpressionProcesser.PopExpressionType.ExpressionVoid_EXC_")); //$NON-NLS-1$
			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();
		}
	}
	
	/**
	 * 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 Object that acts as an enum for the type of expression that initiated the ignore. 
	 * If it is <code>null</code> then no one is ignoring. 
	 * <p>
	 * All of the pushTo...Proxy methods must test this for this to work correctly.
	 * Each expression has some way of testing that their particular nesting of 
	 * expressions is complete and they can turn off the ignore flag.
	 * <p>
	 * Only one type of ignore can exist at a time.
	 */
	protected Object ignoreExpression = null;	
	
	
	private List saveStates;
	
	/**
	 * Are we tracing or not.
	 */
	protected final boolean traceOn;
	private final long thresholdTime;
	private long startExpressionStepTime;
	private long startExpressionTime;
	private long lastExpressionEndTime;
	
	/**
	 * Trace head of this expression. So that traces from different expressions can be distinquished.
	 * It is simply an monotonically increasing counter. It is the header string for any trace output.
	 */
	protected final String traceHeader;
	
	private int indent = 0;	// Indented for certain block expressions.
	
	/*
	 * Trace counter. It is incremented once for each expression and assigned to the traceId of the expression.
	 */
	private static int TRACE_COUNTER;
	
	/**
	 * Create the Expression without tracing.
	 * @param registry
	 * 
	 * @since 1.0.0
	 */
	public ExpressionProcesser() {
		this(false, -1);
	}
	
	/**
	 * Create the expression, and set the tracing mode and threshold time. Use -1
	 * for default time of 100ms.
	 * @param traceOn
	 * 
	 * @since 1.1.0
	 */
	public ExpressionProcesser(boolean traceOn, long threshold) {
		this.traceOn = traceOn;
		if (traceOn) {
			traceHeader = "**"+(++TRACE_COUNTER)+':'; //$NON-NLS-1$
			System.out.print(traceHeader);
			System.out.println(" Start expression"); //$NON-NLS-1$
			this.thresholdTime = threshold != -1 ? threshold : 100;
			lastExpressionEndTime = startExpressionTime = System.currentTimeMillis();
		} else {
			traceHeader = null;
			thresholdTime = 100;
		}
	}
	
	/**
	 * Trace msg helper. Should only be called if traceOn is true. This method is only used to start a new trace message.
	 * The caller is must call printTraceEnd at the end.
	 *  
	 * @param msg message to print
	 * @param ignore are we ignoring the expression, or is it being processed (this just alters the trace output slightly).
	 * 
	 * @since 1.1.0
	 */
	protected void printTrace(String msg, boolean ignore) {
		startExpressionStepTime = System.currentTimeMillis();
		long sinceLastExpression = startExpressionStepTime - lastExpressionEndTime;
		System.out.print(traceHeader);
		if (sinceLastExpression > 0) {
			System.out.print('(');
			if (sinceLastExpression > thresholdTime)
				System.out.print("***"); //$NON-NLS-1$
			System.out.print(sinceLastExpression);
			System.out.print("ms)"); //$NON-NLS-1$
		}
		System.out.print('\t');
		if (!ignore)
			System.out.print("\t"); //$NON-NLS-1$
		else
			System.out.print("##\t"); //$NON-NLS-1$
		
		printIndent();
		System.out.print(msg);
	}
	
	/**
	 * print the indent. It will not do a new line before nor after.
	 * 
	 * @since 1.1.0
	 */
	protected void printIndent() {
		for(int i=indent; i>0; i--) {
			System.out.print("  "); //$NON-NLS-1$
		}
	}

	protected void printTraceEnd() {
		long stop = System.currentTimeMillis()-startExpressionStepTime;
		if (stop > 0) {
			System.out.print(" ("); //$NON-NLS-1$
			if (stop > thresholdTime)
				System.out.print("***"); //$NON-NLS-1$
			System.out.print(stop);
			System.out.print("ms)"); //$NON-NLS-1$
		}
		System.out.println();
		lastExpressionEndTime = System.currentTimeMillis();
	}
	
	/**
	 * Do an indent (undent) according to indent flag.
	 * @param indent <code>true</code> to increment indent, or otherwise decrement.
	 * 
	 * @since 1.1.0
	 */
	protected void indent(boolean indent) {
		this.indent += (indent ? 1 : -1);
		if (this.indent < 0)
			this.indent = 0;
	}
	
	/**
	 * Print the object and type. It will not end with a newline char, so one will be needed afterwards.
	 * 
	 * @param o
	 * @param t
	 * 
	 * @since 1.1.0
	 */
	protected void printObjectAndType(Object o, Class t) {
		System.out.print(' ');
		System.out.print("Object-"); //$NON-NLS-1$
		System.out.print(o);
		System.out.print(" Type-"); //$NON-NLS-1$
		System.out.print(t);
		System.out.print(' ');
	}
	
	/**
	 * Close the exception processing
	 * 
	 * @since 1.0.0
	 */
	public final void close() {
		boolean firstClose = expressionStack != null;
		if (firstClose && traceOn) {
			printTrace("End expression", false); //$NON-NLS-1$
			long totalTime = System.currentTimeMillis()-startExpressionTime;
			System.out.print(" Total expression evaluation time: "); //$NON-NLS-1$
			System.out.print(totalTime);
			System.out.print("ms."); //$NON-NLS-1$
		}
		try {
			expressionStack = null;
			expressionTypeStack = null;
			expressionProxies = null;
			exception = null;
			catchThrowable = null;
			saveStates = null;
		} finally {
			if (firstClose && traceOn)
				printTraceEnd();
		}
	}

	/**
	 * 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 {
		if (traceOn)
			printTrace("Pull value:", false); //$NON-NLS-1$
		try {
			value[0] = popExpression();
			value[1] = popExpressionType(false);
		} finally {
			if (traceOn) {
				printObjectAndType(value[0], (Class) value[1]);
				printTraceEnd();
			}
		}
		close();
	}
	
	/**
	 * Pull the value of the expression proxy, dereferencing it if necessary. This is for resolution only purposes at the
	 * end of the expression being processed. Not meant for general access to the value of expression proxy. Use 
	 * {@link ExpressionProcesser#getExpressionProxyValue(int, Object[])} instead for general access to the value.
	 * 
	 * @param proxyid
	 * @param value
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.1.0
	 */
	public final void pullExpressionProxyValue(int proxyid, Object[] value) throws NoExpressionValueException {
		getExpressionProxyValue(proxyid, value, true, true);
	}
	
	/**
	 * Get the expression proxy value. If the expression has not yet been evaluated it will
	 * return false. If it has it will return true.
	 * @param proxyid
	 * @param value put value into value[0] and the type into value[1].
	 * @return <code>true</code> if successful, or <code>false</code> if the expression proxy was never resolved or doesn't exist.
	 * 
	 * @since 1.1.0
	 */
	public boolean getExpressionProxyValue(int proxyid, Object[] value) {
		try {
			return getExpressionProxyValue(proxyid, value, true, false);
		} catch (NoExpressionValueException e) {
			return false;
		}
	}
	
	/**
	 * Get the expression proxy value, or the NoExpressionValueException if not resolved. This
	 * is useful for callers that need to handle the proxy itself for failed calls.
	 * 
	 * @param proxyid
	 * @param value
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.1.0
	 */
	public void getExpressionProxy(int proxyid, Object[] value) throws NoExpressionValueException {
		getExpressionProxyValue(proxyid, value, true, false);
	}
	
	/*
	 * Internal method use to actually get the value, but to distinquish between pull and get of the public interface.
	 * Get will process the errors as normal execution errors, while pull will throw the errors. finalTrace is when
	 * this is the final call to return the values to the client. We will trace the results in that case.
	 * Return true if successful.
	 */
	private boolean getExpressionProxyValue(int proxyid, Object[] value, boolean pull, boolean finalTrace) throws NoExpressionValueException {
		// Note: This will throw the exceptions right away since this is called from outside to fill in the value and
		// so we are holding such exceptions.
		boolean doTrace = finalTrace && traceOn;
		try {
			if (expressionProxies != null && expressionProxies.size() > proxyid) {
				InternalExpressionProxy proxy = (InternalExpressionProxy) expressionProxies.get(proxyid);
				if (proxy != null && proxy.isSet()) {
					value[0] = proxy.getValue();
					if (value[0] instanceof VariableReference)
						value[0] = ((VariableReference) value[0]).dereference(); // Here we want the final current value.
					value[1] = proxy.getType();
					if (doTrace)
						if (value[1] != Void.TYPE) {
							printTrace("Return Proxy #" + proxyid + " Resolved to", false); //$NON-NLS-1$ //$NON-NLS-2$
							printObjectAndType(value[0], (Class) value[1]);
						} else
							printTrace("Return Proxy #" + proxyid + " Resolved to void.", false); //$NON-NLS-1$ //$NON-NLS-2$
					return true;

				} else {
					if (doTrace)
						printTrace("Return Proxy #" + proxyid + ": Not resolved", false); //$NON-NLS-1$ //$NON-NLS-2$
					NoExpressionValueException e = new NoExpressionValueException(InitparserTreeMessages.getString("ExpressionProcesser.GetExpressionProxyValue.ExpressionProxyNotSet_EXC_"), proxy); //$NON-NLS-1$
					if (pull)
						throw e;
					else
						processSyntaxException(e);
					return false;
				}
			} else {
				if (doTrace)
					printTrace("Return Proxy #" + proxyid + ": Never created.", false); //$NON-NLS-1$ //$NON-NLS-2$
				NoExpressionValueException e = new NoExpressionValueException(InitparserTreeMessages.getString("ExpressionProcesser.GetExpressionProxyValue.ExpressionProxyDoesntExist_EXC_")); //$NON-NLS-1$
				if (pull)
					throw e;
				else
					processSyntaxException(e);
				return false;
			}
		} finally {
			if (doTrace)
				printTraceEnd();
		}
	}
	
	/**
	 * 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) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		if (traceOn) {
			printTrace("Push: ", ignore); //$NON-NLS-1$
			printObjectAndType(o, t);
		}
		try {
			if (ignore)
				return;
			pushExpressionValue(o, t);
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	/**
	 * Get the value of the expression proxy (from proxy id), and push the value onto the stack.
	 *  
	 * @param proxyid The proxy id of the ExpressionProxy to push as a value.
	 * 
	 * @since 1.0.0
	 */
	public final void pushExpressionProxy(int proxyid) {
		boolean ignore =(ignoreExpression != null || errorOccurred);
		if (traceOn)
			printTrace("Push Expression Proxy #"+proxyid, ignore); //$NON-NLS-1$
		try {
			if (ignore)
				return;
			if (expressionProxies != null && expressionProxies.size() > proxyid) {
				InternalExpressionProxy proxy = (InternalExpressionProxy) expressionProxies.get(proxyid);
				if (proxy != null && proxy.isSet()) {
					if (traceOn)
						printObjectAndType(proxy.getValue(), proxy.getType());
					pushExpressionValue(proxy.getValue(), proxy.getType());	// Can push a VariableReference. This is ok. When used it will then deref with the current value.
				} else
					processException(new NoExpressionValueException("Proxy id: "+proxyid)); //$NON-NLS-1$
			} else
				processException(new NoExpressionValueException("Proxy id: "+proxyid)); //$NON-NLS-1$
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	/**
	 * 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
	 * 
	 * @since 1.0.0
	 */
	public final void pushCast(Class type) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		if (traceOn)
			printTrace("Cast to: "+type, ignore); //$NON-NLS-1$
		try {
			if (ignore)
				return;
			
			try {
				Object exp = popExpression();
				Class exptype = popExpressionType(false);
				
				pushExpressionValue(castBean(type, exp, exptype), type);
			} catch (RuntimeException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
			
	}
	
	/**
	 * 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.
	 * <p>
	 * This is a helper method for expression processer to cast a bean. Since it is a helper method it doesn't
	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
	 * 
	 * @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(((Character) bean).charValue());
					else if (returnType == Float.TYPE)
						return new Float(((Character) bean).charValue());
					else if (returnType == Long.TYPE)
						return new 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) 
	 * <p>
	 * This is a helper method for expression processer to get the primitive type. Since it is a helper method it doesn't
	 * check nor process the exception. It throws it. Callers must handle it as they see fit.

	 * @param bean
	 * @return the primitive type class of the given bean.
	 * @throws IllegalArgumentException if bean is <code>null</code> or not of the type that can be converted to a primitive.
	 * 
	 * @since 1.0.0
	 */
	protected final Class getPrimitiveType(Object bean) throws IllegalArgumentException {
		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$
	}
	
	private static final Object IFELSE_IGNORE = "IF/ELSE IGNORE";	// Flag for if/else in ingore //$NON-NLS-1$
	private int ifElseNesting = 0;	// Nesting of if/else expressions.
	private int ifElseIgnoreNestCount = 0;	// When ignoring if/else expressions, ignore until this nest count.
	private boolean ifElseSkipTruePart;

	
	/**
	 * Push an if test expression.
	 * @param hasElseClause
	 * 
	 * @since 1.0.0
	 */
	public final void pushIfElse() {
		try {
			boolean ignore = true;
			try {
				if (errorOccurred)
					return;
				// Slightly different here in that if an ignoring occurred we still need to process at least part of it so that
				// we can get the expression grouping correct.
				ifElseNesting++;	// We have the test.
	
				if (ignoreExpression != null)
					return;
				ignore = false;
			} finally {
				if (traceOn)
					printTrace("If test condition", ignore); //$NON-NLS-1$
			}
					
			try {
				Object condition = popExpression();
				Class type = popExpressionType(false);
				if (type != Boolean.TYPE)
					throwClassCast(Boolean.TYPE, condition);
				if (traceOn) {
					System.out.print(" Test Result="+condition); //$NON-NLS-1$
					printTraceEnd();
					indent(true);
					printTrace("Begin True Expression.", ignore); //$NON-NLS-1$
					printTraceEnd();
					indent(true);
				}				
				if (((Boolean) condition).booleanValue()) {
					// Condition was true.
					// Do nothing. Let true condition be processed.
				} else {
					// Condition was false.
					ifElseSkipTruePart = true;	// Tell the true condition should be ignored.
					ignoreExpression = IFELSE_IGNORE;
					ifElseIgnoreNestCount = ifElseNesting;
				}
				// We don't put anything back on the stack because the condition test is not ever returned.
				// The appropriate true or false condition evaluation will be left on the stack.
			} catch (RuntimeException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}

	/**
	 * Push an if/else clause. It can be any clause of the if (true, or false clause).
	 * @param clauseType
	 * 
	 * @since 1.0.0
	 */
	public final void pushIfElse(InternalIfElseOperandType clauseType) {
		try {
			boolean ignore = true;
			if (errorOccurred)
				return;
			// Slightly different here in that if an ignoring occurred we still need to process at least part of it so that
			// we can get the expression grouping correct.
			switch (clauseType.getValue()) {
			case InternalIfElseOperandType.TRUE_CLAUSE_VALUE:
					if (traceOn) {
						indent(false);
						printTrace("Begin False Expression.", ignore); //$NON-NLS-1$
						printTraceEnd();
						indent(true);
					}
					if (ifElseSkipTruePart && ignoreExpression == IFELSE_IGNORE && ifElseIgnoreNestCount == ifElseNesting) {
						// stop ignoring, we've ignored the true condition of interest.
						ignoreExpression = null;
						return; // However, leave because since this condition was ignored.
					}
					break;
				case InternalIfElseOperandType.ELSE_CLAUSE_VALUE:
					if (traceOn) {
						indent(false);
						indent(false);
						printTrace("End IF/ELSE Expression.", ignore); //$NON-NLS-1$
						printTraceEnd();
					}					
					int currentNesting = ifElseNesting--;
					if (ignoreExpression == IFELSE_IGNORE && ifElseIgnoreNestCount == currentNesting) {
						// stop ignoring, we've ignored the false condition of interest.
						ignoreExpression = null;
						return; // However, leave because since this condition was ignored.
					}
			}
	
				if (ignoreExpression != null)
					return;
				ignore = false;

					
			try {
				switch (clauseType.getValue()) {
					case InternalIfElseOperandType.TRUE_CLAUSE_VALUE:
						ifElseSkipTruePart = false;	// Tell the false condition should be ignored.
						ignoreExpression = IFELSE_IGNORE;
						ifElseIgnoreNestCount = ifElseNesting;
						break;
					case InternalIfElseOperandType.ELSE_CLAUSE_VALUE:
						// There's nothing to do, if it was ignored due to true, we wouldn't of gotton here.
						// If it wasn't ignored, then the result of the false expression is on the stack, which is what it should be.
						break;
				}
			} catch (RuntimeException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}

	/**
	 * 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.
	 * @since 1.0.0
	 */
	public final void pushInstanceof(Class type) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		if (traceOn)
			printTrace("Instanceof type: "+type, ignore); //$NON-NLS-1$
		try {
			if (ignore)
				return;
			
			try {
				Object exp = popExpression();
				Class exptype = popExpressionType(false);
				pushExpressionValue(Boolean.valueOf(isInstance(type, exp, exptype)), Boolean.TYPE);
			} catch (NoExpressionValueException e) {
				processException(e);
			} catch (RuntimeException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	/**
	 * 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.
	 * <p>
	 * This is a helper method for expression processer to do isInstance. Since it is a helper method it doesn't
	 * check nor process exceptions.

	 * @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);
	}
	
	/**
	 * Push new instance from string.
	 * @param initializationString
	 * @param resultType expected result type. If it isn't of that type, a classcast will be processed. 
	 * @param classloader classloader to use for finding classes, or <code>null</code> to use classloader of InitializationStringParser.class.
	 * 
	 * @since 1.1.0
	 */
	public final void pushNewInstanceFromString(String initializationString, Class resultType, ClassLoader classloader) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		if (traceOn)
			printTrace("New instance from string: \""+initializationString+"\" Type="+resultType, ignore); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			if (ignore)
				return;
			
			try {
				InitializationStringParser parser = InitializationStringParser.createParser(initializationString, classloader);
				Object newValue = parser.evaluate();
				newValue = castBean(resultType, newValue, parser.getExpectedType());
				pushExpressionValue(newValue, resultType);
			} catch (RuntimeException e) {
				processException(e);
			} catch (InitializationStringEvaluationException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}

	}

	/**
	 * Push prefix expression.
	 * @param operator 
	 * @since 1.0.0
	 */
	public final void pushPrefix(PrefixOperator operator) {
		try {
			if (ignoreExpression != null || errorOccurred) {
				if (traceOn)
					printTrace("Prefix: \'"+operator+"\'", true); //$NON-NLS-1$ //$NON-NLS-2$
				return;
			}
			
			if (operator == PrefixOperator.PRE_PLUS)
				return;	// Do nothing. "+" doesn't affect the result of the current top expression.
	
			if (traceOn)
				printTrace("Prefix: \'"+operator+"\' ", false); //$NON-NLS-1$ //$NON-NLS-2$
	
			try {
				Object exp = popExpression();
				Class exptype = popExpressionType(false);
				if (!exptype.isPrimitive())
					throwInvalidPrefix(operator, exp);
				
				int primTypeEnum = getEnumForPrimitive(exptype);
				switch (operator.getValue()) {
					case PrefixOperator.PRE_MINUS_VALUE:
						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 PrefixOperator.PRE_COMPLEMENT_VALUE:
						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 PrefixOperator.PRE_NOT_VALUE:
						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;
					}
				
				if (traceOn)
					printObjectAndType(exp, exptype);
				pushExpressionValue(exp, exptype);	// Push the result back on the stack.
	
			} catch (IllegalArgumentException e) {
				processSyntaxException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			} catch (RuntimeException e) {
				processException(e);
			} 
		} finally {
			if (traceOn)
				printTraceEnd();
		}
			
	}
	
	/**
	 * Assign the right expression to the left expression.
	 * @since 1.1.0
	 */
	public final void pushAssignment() {
		if (ignoreExpression != null || errorOccurred) {
			if (traceOn) {
				printTrace("Assignment", true); //$NON-NLS-1$
				printTraceEnd();
			}
			return;
		}
		
		try {
			// KLUDGE: The only reason leftValue/refType are outside of try/finally is because
			// of tracing. pushExpression() does its own trace statements, so we need to end
			// our trace before calling pushExpression. 
			Object leftValue;
			Class refType;
			try {
				if (traceOn)
					printTrace("Assignment: ", false);			 //$NON-NLS-1$	
				// The order on the stack is right then left operand.
				// First the right operand
				Object value = popExpression();
				Class type = popExpressionType(false);

				// Next the left operand, should be a reference.
				VariableReference left = (VariableReference) popExpression(false); // Don't dereference it.
				refType = popExpressionType(false);

				if (traceOn)
					printObjectAndType(left, refType);

				leftValue = left.set(value, type);
			} finally {
				if (traceOn)
					printTraceEnd();
			}
			
			// Now do assignment and return the value to the stack.
			pushExpression(leftValue, refType);	// The type of the result is the type of the reference.

		} catch (IllegalArgumentException e) {
			processException(e);
		} catch (NoExpressionValueException e) {
			processException(e);
		} catch (IllegalAccessException e) {
			processException(e);
		} catch (RuntimeException e) {
			processException(e);
		}
			
	}
	
	/**
	 * Assign the expression proxy to the top expression value.
	 * 
	 * @param proxy
	 * 
	 * @since 1.1.0
	 */
	public final void pushAssignment(InternalExpressionProxy proxy) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		try {
			if (traceOn) {
				printTrace("Assign to Proxy #"+proxy.getProxyID(), ignore); //$NON-NLS-1$
			}
			if (ignore)
				return;
			
			try {
				assignToExpressionProxyFromTopStackEntry(proxy);
				if (traceOn)
					printObjectAndType(proxy.getValue(), proxy.getType());
			} catch (NoExpressionValueException e) {
				processException(e);
			} catch (RuntimeException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}

	}

	/**
	 * Assign the top stack entry to the new expression proxy and allocate it for callback later.
	 * @param proxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.1.0
	 */
	protected void assignToExpressionProxyFromTopStackEntry(InternalExpressionProxy proxy) throws NoExpressionValueException {
		Object value = getExpression(1);
		Class type = getExpressionType(1, true);
		if (value instanceof VariableReference)
			value = ((VariableReference) value).dereference();	// Here we want the final current value.

		proxy.setProxy(value, type);
		allocateExpressionProxy(proxy);
	}

	/**
	 * Allocate an expression proxy. This is used to make an expression proxy known to the processor. The expression proxy must
	 * have been setProxy() at this point. This is used to assign from the top of the stack or to add from outside an evaluated proxy
	 * to be used later by others.
	 * 
	 * @param proxy
	 * 
	 * @since 1.1.0
	 */
	public void allocateExpressionProxy(InternalExpressionProxy proxy) {
		int minSize = proxy.getProxyID()+1;
		if (expressionProxies == null)
			expressionProxies = new ArrayList(minSize+10);	// Allow room to grow ten more.
		else if (expressionProxies.size() < minSize)
			expressionProxies.ensureCapacity(minSize+10);	// Allow room to grow ten more.
		int fill = minSize-expressionProxies.size();	// Number of "null" fill entries needed. Probably shouldn't occur, but to be safe.
		if (fill > 0) {
			while (--fill > 0)
				expressionProxies.add(null);
			expressionProxies.add(proxy);
		} else
			expressionProxies.set(proxy.getProxyID(), proxy);	// Already large enough, replace entry.

	}

	/**
	 * 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.
	 * <p>
	 * This is a helper method for expression processer to get the enum for the primitive type. Since it is a helper method it doesn't
	 * check nor process the exception. It throws it. Callers must handle it as they see fit.

	 * @param primitiveType
	 * @return
	 * @throws IllegalArgumentException if type is not a primitive.
	 * 
	 * @see ExpressionProcesser#BOOLEAN
	 * @since 1.0.0
	 */
	protected final int getEnumForPrimitive(Class primitiveType) throws IllegalArgumentException {
		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(primitiveType != null ? primitiveType.getName() : "null"); //$NON-NLS-1$
	}
	
	private void throwInvalidPrefix(PrefixOperator operator, Object exp) throws IllegalArgumentException {
		throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.InvalidOperandOfPrefixOperator_EXC_"), new Object[] {exp != null ? exp.toString() : null, operator.toString()})); //$NON-NLS-1$
	}		
	
	private static final Object INFIX_IGNORE = "INFIX IGNORE";	// Flag for infix in ingore //$NON-NLS-1$
	private int infixNesting = 0;	// Nesting of infix expressions.
	private int infixIgnoreNestCount = 0;	// When ignoring infix expressions, ignore until this nest count.
	/**
	 * Push the infix expression onto the stack.
	 * @param operator
	 * @param operandType The operator type. Left, right, other.
	 * @since 1.0.0
	 */
	public final void pushInfix(InfixOperator operator, InternalInfixOperandType operandType) {
		try {
			boolean ignore = true;
			try {
				if (errorOccurred) {
					return;
				}
				// Slightly different here in that if an ignored occurred we still need to process at least part of it so that
				// we can get the expression grouping correct.
				if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
					infixNesting++;
				else if (operandType == InternalInfixOperandType.INFIX_LAST_OPERAND) {
					int currentNest = infixNesting--;
					if (ignoreExpression == INFIX_IGNORE && currentNest == infixIgnoreNestCount) {
						// We were ignoring, and it was this expression that was being ignore.
						// We have received the last operand of the nested expression that was being ignored,
						// so we can stop ignoring. But we still leave since the value of the expression is on the
						// top of the stack.
						ignoreExpression = null;
						return;
					}
				}
	
				if (ignoreExpression != null)
					return;
				ignore = false;
			} finally {
				if (traceOn)
					printTrace("Infix: "+operator, ignore); //$NON-NLS-1$
			}
			
			try {
				Object right = null;
				Class rightType = null;
				if (operandType != InternalInfixOperandType.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.getValue()) {
					case InfixOperator.IN_AND_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidBitType(valueType, InfixOperator.IN_AND);
						testValidBitType(rightType, InfixOperator.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 InfixOperator.IN_CONDITIONAL_AND_VALUE:
						// 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 != InternalInfixOperandType.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 != InternalInfixOperandType.INFIX_LAST_OPERAND)
							startInfixIgnore();	// Start ignoring because we know the value of the expression at this point. It is false.
						break;
					case InfixOperator.IN_CONDITIONAL_OR_VALUE:
						// 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 != InternalInfixOperandType.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 != InternalInfixOperandType.INFIX_LAST_OPERAND)
							startInfixIgnore(); // Start ignoring because we know the value of the expression at this point. It is true.
						break;
					case InfixOperator.IN_DIVIDE_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidArithmeticType(valueType, InfixOperator.IN_DIVIDE);
						testValidArithmeticType(rightType, InfixOperator.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 InfixOperator.IN_EQUALS_VALUE:
						if (operandType == InternalInfixOperandType.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 InfixOperator.IN_GREATER_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidArithmeticType(valueType, InfixOperator.IN_GREATER);
						testValidArithmeticType(rightType, InfixOperator.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 InfixOperator.IN_GREATER_EQUALS_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidArithmeticType(valueType, InfixOperator.IN_GREATER_EQUALS);
						testValidArithmeticType(rightType, InfixOperator.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 InfixOperator.IN_LEFT_SHIFT_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidBitType(valueType, InfixOperator.IN_LEFT_SHIFT);
						testValidBitType(rightType, InfixOperator.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 InfixOperator.IN_LESS_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidArithmeticType(valueType, InfixOperator.IN_LESS);
						testValidArithmeticType(rightType, InfixOperator.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 InfixOperator.IN_LESS_EQUALS_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidArithmeticType(valueType, InfixOperator.IN_LESS_EQUALS);
						testValidArithmeticType(rightType, InfixOperator.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 InfixOperator.IN_MINUS_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidArithmeticType(valueType, InfixOperator.IN_MINUS);
						testValidArithmeticType(rightType, InfixOperator.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 InfixOperator.IN_NOT_EQUALS_VALUE:
						if (operandType == InternalInfixOperandType.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 InfixOperator.IN_OR_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidBitType(valueType, InfixOperator.IN_OR);
						testValidBitType(rightType, InfixOperator.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 InfixOperator.IN_PLUS_VALUE:
						if (operandType == InternalInfixOperandType.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 == InternalInfixOperandType.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 InfixOperator.IN_REMAINDER_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidArithmeticType(valueType, InfixOperator.IN_REMAINDER);
						testValidArithmeticType(rightType, InfixOperator.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 InfixOperator.IN_RIGHT_SHIFT_SIGNED_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidBitType(valueType, InfixOperator.IN_RIGHT_SHIFT_SIGNED);
						testValidBitType(rightType, InfixOperator.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 InfixOperator.IN_RIGHT_SHIFT_UNSIGNED_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidBitType(valueType, InfixOperator.IN_RIGHT_SHIFT_UNSIGNED);
						testValidBitType(rightType, InfixOperator.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 InfixOperator.IN_TIMES_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidArithmeticType(valueType, InfixOperator.IN_TIMES);
						testValidArithmeticType(rightType, InfixOperator.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 InfixOperator.IN_XOR_VALUE:
						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
							break;	// Do nothing with first operand
						
						testValidBitType(valueType, InfixOperator.IN_XOR);
						testValidBitType(rightType, InfixOperator.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;
					} 
				
				if (traceOn)
					printObjectAndType(value, valueType);
				pushExpressionValue(value, valueType);	// Push the result back on the stack.
	
			} catch (IllegalArgumentException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			} catch (RuntimeException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
			
	}

	/**
	 * Start ignoring rest of the current infix expression.
	 * 
	 * @since 1.1.0
	 */
	private void startInfixIgnore() {
		ignoreExpression = INFIX_IGNORE;
		infixIgnoreNestCount = infixNesting;	// Ignore until we get back to the current nesting.

	}

	/**
	 * 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.
	 * <p>
	 * This is a helper method for expression processer to get the int value of the object. Since it is a helper method it doesn't
	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
	 * @param bean
	 * @return the int value of the number/character
	 * @throws ClassCastException
	 * 
	 * @since 1.0.0
	 */
	protected final int getInt(Object bean) throws ClassCastException {
		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.
	 * <p>
	 * This is a helper method for expression processer to get the float value of the object. Since it is a helper method it doesn't
	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
	 * @param bean 
	 * @return float value of the Number/character
	 * @throws ClassCastException
	 * @since 1.0.0
	 */
	protected final float getFloat(Object bean) throws ClassCastException {
		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.
	 * <p>
	 * This is a helper method for expression processer to get the float value of the object. Since it is a helper method it doesn't
	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
	 * 
	 * @param bean
	 * @return double value of the Number/Character.
	 * @throws ClassCastException
	 * @since 1.0.0
	 */
	protected final double getDouble(Object bean) throws ClassCastException {
		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.
	 * <p>
	 * This is a helper method for expression processer to get the float value of the object. Since it is a helper method it doesn't
	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
	 * 
	 * @param bean
	 * @return
	 * @throws ClassCastException
	 * @since 1.0.0
	 */
	protected final long getLong(Object bean) throws ClassCastException {
		return (bean instanceof Number) ? ((Number) bean).longValue() : ((Character) bean).charValue();
	}
	
	private void throwInvalidInfix(InfixOperator operator, Object value) throws IllegalArgumentException {
		throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.InvalidOperandOfOperator_EXC_"), new Object[] {value != null ? value.toString() : null, operator.toString()})); //$NON-NLS-1$
	}
	
	private void testValidBitType(Class type, InfixOperator operator) {
		if (!type.isPrimitive() || type == Boolean.TYPE || type == Double.TYPE|| type == Float.TYPE)
			throwInvalidInfix(operator, type);
	}
	
	private void testValidArithmeticType(Class type, InfixOperator 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, InfixOperator.IN_PLUS);
		testValidArithmeticType(right, InfixOperator.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
	 * @since 1.0.0
	 */
	public final void pushArrayAccess(int indexCount) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		
		if (traceOn) {
			printTrace("Array Access["+indexCount+']', ignore); //$NON-NLS-1$
		}
		try {
			if (ignore)
				return;
			
			try {
				// 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, stop just before the last one. The last one will be turned into an ArrayAccessReference.
					Object value = array;	// Final value, start with full array.
					int pullCount = indexCount-1;
					for(int i=0; i<pullCount; i++) {
						value = Array.get(value, arguments[i]);
					}
					ArrayAccessReference arrayValue = ArrayAccessReference.createArrayAccessReference(value, arguments[pullCount]);
					if (traceOn)
						printObjectAndType(arrayValue, componentTypes[pullCount]);
					pushExpressionValue(arrayValue, componentTypes[pullCount]);
				}  else
					 throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.NotAnArray_EXC_"), new Object[] {arrayType})); //$NON-NLS-1$
	
			} catch (NoExpressionValueException e) {
				processException(e);
			} catch (RuntimeException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	/**
	 * 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.
	 * @since 1.0.0
	 */
	public final void pushArrayCreation(Class arrayType, int dimensionCount) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		if (traceOn)
			printTrace("Array Creation: "+arrayType.getName()+'['+dimensionCount+']', ignore); //$NON-NLS-1$
		
		try {
			if (ignore)
				return;
			
			try {
				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);
				}
			} catch (RuntimeException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
			
	}

	/**
	 * Push the array initializer request.
	 * 
	 * @param arrayType The original type of the array to create.
	 * @param stripCount the count of how many dimensions to strip to get the type needed for this initializer.
	 * @param expressionCount
	 * @since 1.0.0
	 */
	public final void pushArrayInitializer(Class arrayType, int stripCount, int expressionCount) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		
		if (traceOn)
			printTrace("Initialize Array: "+arrayType.getName()+'{'+expressionCount+'}', ignore); //$NON-NLS-1$
		
		try {
			if (ignore)
				return;
	
			try {
				if (!arrayType.isArray()) {
					// It is not an array type.
					throw new ClassCastException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.CannotCastXToY_EXC_"), new Object[] {arrayType, "array"})); //$NON-NLS-1$ //$NON-NLS-2$
				} 
				// Strip off the number of dimensions specified.
				while(stripCount-->0) {
					arrayType = arrayType.getComponentType();
				}
				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).
	
			} catch (RuntimeException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
			
	}

	/**
	 * 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
	 * @since 1.0.0
	 */
	public final void pushClassInstanceCreation(Class type, int argumentCount) {
		boolean ignore = (ignoreExpression != null || errorOccurred);
		
		if (traceOn)
			printTrace("Create Class: "+type+" (", ignore); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			if (ignore)
				return;
						
			try {
				// We need to pull in the arguments. They are stacked in reverse order.
				Object value = null;	// The new instance.
				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;
				ctor = MethodHelper.findCompatibleConstructor(type, argTypes);
				if (traceOn) {
					if (argumentCount == 0) {
						// No args, just do default ctor.
						System.out.print("Default ctor)"); //$NON-NLS-1$
					} else {						
						System.out.print(ctor);
						System.out.print(')');
					}
				}
				value = ctor.newInstance(args);
				
				pushExpressionValue(value, type);
			} catch (RuntimeException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			} catch (InstantiationException e) {
				processException(e);
			} catch (IllegalAccessException e) {
				processException(e);
			} catch (InvocationTargetException e) {
				processException(e);
			} catch (NoSuchMethodException e) {
				processException(e);
			} catch (AmbiguousMethodException e) {
				processException(e);
			} catch (LinkageError e) {
				processException(e);
			} catch (Error e) {
				if (e.getClass() == Error.class) {
					// If exactly Error.class, then process it. This is hopefully just a "unresolved compilation error".
					processException(new UnresolvedCompilationError(e));
				} else
					throw e;	// All subclasses we throw on out.
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
			
	}

	/**
	 * Push the field access expression.
	 * @param field String for fieldname, or a java.lang.reflect.Field.
	 * @param fieldIsString <code>true</code> if field is a string name, and not a java.lang.reflect.Field.
	 * @param hasReceiver
	 * 
	 * @since 1.0.0
	 */
	public final void pushFieldAccess(Object field, boolean fieldIsString, boolean hasReceiver) {
		try {
			if (ignoreExpression != null || errorOccurred) {
				if (traceOn)
					printTrace("Field Access", true); //$NON-NLS-1$
				return;
			}
		
			if (traceOn)
				printTrace("Field Access: ", false); //$NON-NLS-1$
			try {
				// Get the receiver off of the stack.
				Object receiver = null;
				Class receiverType = null;
				if (hasReceiver) {
					receiver = popExpression();
					receiverType = popExpressionType(false);
				}
				
				// Find the field.
				Field reflectField = fieldIsString ? receiverType.getField((String) field) : (Field) field;
				// Access the field.
				Object value = FieldAccessReference.createFieldAccessReference(reflectField, receiver);
				Class valueType = reflectField.getType();
				if (traceOn) {
					System.out.print("Field: "); //$NON-NLS-1$
					if (fieldIsString)
						System.out.print("(looked up) "); //$NON-NLS-1$
					System.out.print(reflectField);
					System.out.print(">"); //$NON-NLS-1$
					printObjectAndType(value, valueType);
				}
					
				pushExpressionValue(value, valueType);
			} catch (RuntimeException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			} catch (NoSuchFieldException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
			
	}

	/**
	 * Push the method invocation expression.
	 * @param method
	 * @param methodIsString <code>true</code> if method is a string (so string name) or else it is a java.lang.reflect.Method.
	 * @param hasReceiver
	 * @param argCount
	 * @since 1.0.0
	 */
	public final void pushMethodInvocation(Object method, boolean methodIsString, boolean hasReceiver, int argCount) {
		try {
			if (ignoreExpression != null || errorOccurred) {
				if (traceOn)
					printTrace("Invoke", true); //$NON-NLS-1$
				return;
			}
			
			if (traceOn)
				printTrace("Invoke: ", false); //$NON-NLS-1$
			
			Method reflectMethod = null;
			try {
				// 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 = null;
				Class receiverType = null;
				if (hasReceiver) {
					receiver = popExpression();
					receiverType = popExpressionType(false);
				}
				
				// Now we need to find the appropriate method. If it is a string then there must be a receiver, otherwise no way to know.
				if (methodIsString) {
					reflectMethod = MethodHelper.findCompatibleMethod(receiverType, (String) method, argTypes);
				} else
					reflectMethod = (Method) method;
				
				if (traceOn && reflectMethod != null) {
					System.out.print("Method: "); //$NON-NLS-1$
					if (methodIsString)
						System.out.print("(looked up) "); //$NON-NLS-1$
					System.out.print(reflectMethod);					
				}
				
				if (!Modifier.isStatic(reflectMethod.getModifiers()) && receiver == null)
					throw new NullPointerException("No receiver for non-static method: "+reflectMethod.toString()); //$NON-NLS-1$
					
				Object value = reflectMethod.invoke(receiver, args);
				
				if (traceOn) {
					System.out.print(" returns: "); //$NON-NLS-1$
					printObjectAndType(value, reflectMethod.getReturnType());
				}
				pushExpressionValue(value, reflectMethod.getReturnType());
			} catch (RuntimeException e) {
				processException(fixUpMethodException(e, reflectMethod));
			} catch (NoExpressionValueException e) {
				processException(fixUpMethodException(e, reflectMethod));
			} catch (IllegalAccessException e) {
				processException(fixUpMethodException(e, reflectMethod));
			} catch (InvocationTargetException e) {
				processException(fixUpMethodException(e.getCause(), reflectMethod));
			} catch (NoSuchMethodException e) {
				processException(e);
			} catch (AmbiguousMethodException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
			
	}
	
	/*
	 * Many of the exceptions don't add in what method had the error, so we
	 * will do that here.
	 */
	private Throwable fixUpMethodException(Throwable e, Method method) {
		if (method == null)
			return e;
		try {
			String msg = e.getMessage();
			Constructor eWithStringCtor = e.getClass().getConstructor(new Class[] {String.class});
			String newMsg;
			if (msg == null) {
				newMsg = method.toString();
			} else {
				newMsg = method.toString()+": \""+msg+'\"'; //$NON-NLS-1$
			}
			Exception fixedupE = (Exception) eWithStringCtor.newInstance(new Object[] {newMsg});
			fixedupE.setStackTrace(e.getStackTrace());
			return fixedupE;
		} catch (Exception e1) {
			return e;
		}
  
	}

	private static final Object CONDITIONAL_IGNORE = "CONDITIONAL IGNORE";	// Flag for conditional in ingore //$NON-NLS-1$
	private int conditionalNesting = 0;	// Nesting of conditional expressions.
	private int conditionalIgnoreNestCount = 0;	// When ignoring conditional expressions, ignore until this nest count.
	private boolean skipTruePart;

	/**
	 * Push a conditional expression. It can be any clause of the conditional (test, true, or false clause).
	 * @param expressionType
	 * 
	 * @since 1.0.0
	 */
	public final void pushConditional(InternalConditionalOperandType expressionType) {
		try {
			boolean ignore = true;
			try {
				if (errorOccurred)
					return;
				// Slightly different here in that if an ignoring occurred we still need to process at least part of it so that
				// we can get the expression grouping correct.
				switch (expressionType.getValue()) {
					case InternalConditionalOperandType.CONDITIONAL_TEST_VALUE:
						conditionalNesting++;
						break;
					case InternalConditionalOperandType.CONDITIONAL_TRUE_VALUE:
						if (skipTruePart && ignoreExpression == CONDITIONAL_IGNORE && conditionalIgnoreNestCount == conditionalNesting) {
							// stop ignoring, we've ignored the true condition of interest.
							ignoreExpression = null;
							return; // However, leave because since this condition was ignored.
						}
						break;
					case InternalConditionalOperandType.CONDITIONAL_FALSE_VALUE:
						int currentNesting = conditionalNesting--;
						if (ignoreExpression == CONDITIONAL_IGNORE && conditionalIgnoreNestCount == currentNesting) {
							// stop ignoring, we've ignored the false condition of interest.
							ignoreExpression = null;
							return; // However, leave because since this condition was ignored.
						}
				}
	
				if (ignoreExpression != null)
					return;
				ignore = false;
			} finally {
				if (traceOn)
					printTrace("Conditional "+expressionType, ignore); //$NON-NLS-1$
			}
					
			try {
				switch (expressionType.getValue()) {
					case InternalConditionalOperandType.CONDITIONAL_TEST_VALUE:
						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.
							skipTruePart = true;	// Tell the true condition should be ignored.
							ignoreExpression = CONDITIONAL_IGNORE;
							conditionalIgnoreNestCount = conditionalNesting;
						}
						// We don't put anything back on the stack because the condition test is not ever returned.
						// The appropriate true or false condition evaluation will be left on the stack.
						break;
					case InternalConditionalOperandType.CONDITIONAL_TRUE_VALUE:
						skipTruePart = false;	// Tell the false condition should be ignored.
						ignoreExpression = CONDITIONAL_IGNORE;
						conditionalIgnoreNestCount = conditionalNesting;
						break;
					case InternalConditionalOperandType.CONDITIONAL_FALSE_VALUE:
						// There's nothing to do, if it was ignored due to true, we wouldn't of gotton here.
						// If it wasn't ignored, then the result of the false expression is on the stack, which is what it should be.
						break;
				}
			} catch (RuntimeException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	private static final Object BLOCK_IGNORE = "BLOCK IGNORE"; //$NON-NLS-1$
	private int[] blocks;	// Stack of block numbers currently evaluating.
	private int topBlock = -1;	// Top block index.
	private int breakBlock = -1;	// Block number we are breaking to.
	
	/**
	 * Push a begin block.
	 * @param blockNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushBlockBegin(int blockNumber) {
		if (traceOn) {
			printTrace("Begin Block #"+blockNumber, errorOccurred); //$NON-NLS-1$
			indent(true);
		}
		try {
			if (errorOccurred)
				return;
			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
			if (blocks == null)
				blocks = new int[10];
			if (++topBlock >= blocks.length) {
				int[] newList = new int[blocks.length*2];
				System.arraycopy(blocks, 0, newList, 0, blocks.length);
				blocks = newList;
			}
			blocks[topBlock] = blockNumber;
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	/**
	 * Push a block end. The current block must be the given number, or it is an error.
	 * 
	 * @param blockNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushBlockEnd(int blockNumber) {
		try {
			if (traceOn) {
				indent(false);
				printTrace("End Block #"+blockNumber, errorOccurred); //$NON-NLS-1$
			}
			if (errorOccurred)
				return;
			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
			if (blocks == null || topBlock < 0 || blocks[topBlock] != blockNumber) {
				processSyntaxException(new IllegalStateException(InitparserTreeMessages.getString("ExpressionProcesser.PushBlockEnd.ReceivedEndBlocksOutOfOrder_EXC_"))); //$NON-NLS-1$
			} else {
				topBlock--;
				if (ignoreExpression == BLOCK_IGNORE && blockNumber == breakBlock) {
					ignoreExpression = null;
				}
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}			
	}
	
	/**
	 * Skip all following until we hit the requested block number.
	 * @param blockNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushBlockBreak(int blockNumber) {
		try {
			if (traceOn)
				printTrace("Break Block #"+blockNumber, errorOccurred); //$NON-NLS-1$
			if (errorOccurred)
				return;
			if (ignoreExpression == null) {
				ignoreExpression = BLOCK_IGNORE;	// Start ignoring expressions until we hit the block number end block.
				breakBlock = blockNumber;
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	private static final Object TRY_THROW_IGNORE = "TRY THROW IGNORE"; //$NON-NLS-1$
	private static final Object TRY_FINAL_IGNORE = "TRY FINAL IGNORE"; //$NON-NLS-1$
	private int[] trys;	// Stack of try numbers currently evaluating.
	// Stack of trys in catch clause (i.e. starting executing a catch/final clause for the try). Corresponds with try from same index in trys. Contains the throwable for the catch.
	// This is used to know we are executing a catch (entry not null) and for the rethrow short-hand to rethrow the same exception within the catch.
	private Throwable[] trysInCatch;	
	private int topTry = -1;	// Top try index.
	private int breakTry = -1;	// Try number we are breaking to.
	private Throwable catchThrowable;	// The throwable to check catches against.
	
	/**
	 * Push a try statement.
	 * @param tryNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushTryBegin(int tryNumber) {
		try {
			if (traceOn) {
				printTrace("Begin Try #"+tryNumber, errorOccurred); //$NON-NLS-1$
				indent(true);
			}
	
			if (errorOccurred)
				return;
			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
			if (trys == null) {
				trys = new int[10];
				trysInCatch = new Throwable[10];
			}
			if (++topTry >= trys.length) {
				int[] newList = new int[trys.length*2];
				System.arraycopy(trys, 0, newList, 0, trys.length);
				trys = newList;
				Throwable[] newCatches = new Throwable[trys.length];
				System.arraycopy(trysInCatch, 0, newCatches, 0, trysInCatch.length);
				trysInCatch = newCatches;
			}
			trys[topTry] = tryNumber;
			trysInCatch[topTry] = null;
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}

	/**
	 * Throw the top stack entry. It must be an exception.
	 * 
	 * 
	 * @since 1.1.0
	 */
	public final void pushThrowException() {
		try {
			boolean ignore = (ignoreExpression != null || errorOccurred);
			if (traceOn)
				printTrace("Throw exception: ", ignore); //$NON-NLS-1$
			
			if (ignore)
				return;
	
			try {
				Object t = popExpression();
				popExpressionType(false);
				if (traceOn) {
					System.out.print(t);
				}
				throwException((Throwable) t);
			} catch (NoExpressionValueException e) {
				processException(e);
			} catch (ClassCastException e) {
				processException(e);
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}			
	}
	
	/**
	 * Throw this exception (means throw through the expression being processed, not throw for this thread).
	 * @param exception
	 * 
	 * @since 1.1.0
	 */
	protected final void throwException(Throwable exception) {
		if (topTry == -1) {
			// There are no tries, so treat this as a syntax error.
			if (exception instanceof NoExpressionValueException)
				processSyntaxException((NoExpressionValueException) exception);
			else
				processSyntaxException(exception);
		} else if (trysInCatch[topTry] == null) {
			// We are not in a catch clause of the top try. So do a throw ignore for toptry.
			ignoreExpression = TRY_THROW_IGNORE;
			breakTry = trys[topTry];
			catchThrowable = exception;
		} else {
			// We are in a catch of the top try. So do a throw to finally instead.
			ignoreExpression = TRY_FINAL_IGNORE;
			trysInCatch[topTry] = FINAL_CATCH;
			breakTry = trys[topTry];
			catchThrowable = exception;
		}
	}
	
	/**
	 * Push a catch clause
	 * @param tryNumber
	 * @param exceptionType
	 * @param expressionProxy
	 * 
	 * @since 1.1.0
	 */
	public final void pushTryCatchClause(int tryNumber, Class exceptionType, InternalExpressionProxy expressionProxy) {
		try {
			if (traceOn) {
				indent(false);
				if (expressionProxy == null)
					printTrace("Catch Try #"+tryNumber+" ("+exceptionType+')', errorOccurred); //$NON-NLS-1$ //$NON-NLS-2$
				else
					printTrace("Catch Try #"+tryNumber+" ("+exceptionType+") Return exception in proxy #"+expressionProxy.getProxyID(), errorOccurred); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				indent(true);
			}
			
			if (errorOccurred)
				return;
			
			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
			if (trys == null || topTry < 0 || trys[topTry] != tryNumber) {
				processSyntaxException(new IllegalStateException(InitparserTreeMessages.getString("ExpressionProcesser.PushTryCatchClause.CatchReceivedOutOfOrder_EXC_"))); //$NON-NLS-1$
			} else {
				if (ignoreExpression == null) {
					// Normal flow, no throw in progress, so just ignore now until the finally or end try reached.
					ignoreExpression = TRY_FINAL_IGNORE;
					breakTry = tryNumber;
				} else if (ignoreExpression == TRY_THROW_IGNORE && tryNumber == breakTry) {
					// We are here due to a throw occuring in this try block, see if for us, and if it is, stop ignoring.
					// Else just continue ignoring.
					if (exceptionType.isInstance(catchThrowable)) {
						// For us, so just turn everything back on, except mark that we are in the catch phase.
						ignoreExpression = null;
						trysInCatch[topTry] = catchThrowable; // This is so that we know if we throw again that we should not catch anything.
						breakTry = -1;
						if (expressionProxy != null) {
							expressionProxy.setProxy(catchThrowable, catchThrowable.getClass());
							allocateExpressionProxy(expressionProxy);
						}
						if (traceOn) {
							System.out.print(" Caught: "); //$NON-NLS-1$
							System.out.print(catchThrowable);
						}
						catchThrowable = null;
					}
				}
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}			
	}
	
	// This is used only so that finally clause can indicate it was executing so that end expression knows this.
	private static final Throwable FINAL_CATCH = new RuntimeException();

	/**
	 * Push the try finally clause.
	 * @param tryNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushTryFinallyClause(int tryNumber) {
		try {
			if (traceOn) {
				indent(false);
				printTrace("Finally Try #"+tryNumber, errorOccurred); //$NON-NLS-1$
				indent(true);
			}
			if (errorOccurred)
				return;
			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
			if (trys == null || topTry < 0 || trys[topTry] != tryNumber) {
				processSyntaxException(new IllegalStateException(InitparserTreeMessages.getString("ExpressionProcesser.PushTryFinallyClause.FinallyReceivedOutOfOrder_EXC_"))); //$NON-NLS-1$
			} else {
				if (tryNumber == breakTry && (ignoreExpression == TRY_THROW_IGNORE || ignoreExpression == TRY_FINAL_IGNORE)) {
					// We are here due to a throw occuring in this try block or a catch was reached (in which case all intervening catch's were ignored).
					// Now do a normal execution. If we are here due to a throw that wasn't cleared (either no catch or another throw occured within the catch)
					// then we leave it uncleared so that try/end may rethrow it.
					ignoreExpression = null;
					trysInCatch[topTry] = FINAL_CATCH; // We are in the finally clause of a exception being thrown within this try.
					breakTry = -1;
					if (traceOn)
						System.out.print(" Executing finally."); //$NON-NLS-1$
				}
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}			
	}
	
	/**
	 * Rethrow the caught exception. This is a shortcut for:
	 * } catch (Exception e) {
	 *   ... do stuff ...
	 *   throw e;
	 * }
	 * @param tryNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushTryRethrow(int tryNumber) {
		if (traceOn)
			printTrace("Rethrow Try #"+tryNumber, errorOccurred  || ignoreExpression != null); //$NON-NLS-1$
		
		try {
			if (errorOccurred)
				return;
			// We are not checking ignore because we need to make sure this is not called out of order.
			if (trys == null || topTry < 0 || trys[topTry] != tryNumber) {
				processSyntaxException(new IllegalStateException(InitparserTreeMessages.getString("ExpressionProcesser.PushTryRethrow.RethrowReceivedOutOfOrder_EXC_"))); //$NON-NLS-1$
			} else if (ignoreExpression == null) {
				if (trysInCatch[topTry] == null || trysInCatch[topTry] == FINAL_CATCH)
					processSyntaxException(new IllegalStateException(InitparserTreeMessages.getString("ExpressionProcesser.PushTryRethrow.RetryReceivedOutOfExecutingCatchClause_EXC_"))); //$NON-NLS-1$
				else {
					throwException(trysInCatch[topTry]);
				}
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}		
	}
	
	public final void pushTryEnd(int tryNumber) {
		if (traceOn) {
			indent(false);
			printTrace("End Try #"+tryNumber, errorOccurred); //$NON-NLS-1$
		}
		try {
			if (errorOccurred)
				return;
			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
			if (trys == null || topTry < 0 || trys[topTry] != tryNumber) {
				processSyntaxException(new IllegalStateException(InitparserTreeMessages.getString("ExpressionProcesser.PushTryEnd.TryEndReceivedOutOfOrder_EXC_"))); //$NON-NLS-1$
			} else {
				boolean inCatch = trysInCatch[topTry] != null;
				trysInCatch[topTry] = null;
				topTry--;
				if (inCatch || (tryNumber == breakTry && (ignoreExpression == TRY_THROW_IGNORE || ignoreExpression == TRY_FINAL_IGNORE))) {
					// We are here due to a throw or normal flow through a catch. Either way if there is a throwable still pending, we rethrow.
					ignoreExpression = null;
					breakTry = -1;
					if (catchThrowable != null)
						throwException(catchThrowable);
				} 
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}			
	}
	
	/**
	 * Class used to save the state at time of mark. It will
	 * be used to restore state if error.
	 * 
	 * @since 1.1.0
	 */
	protected class SaveState {
		public int markID;
		
		// Block state
		public int topBlock;
		public int breakBlock;

		// Subexpression state
		public int topSubexpression;

		// Try state
		public int topTry;
		public int breakTry;
		public Throwable catchThrowable;
		
		// Error state
		public boolean errorOccurred;
		public boolean novalueException;
		public Throwable exception;
		public Object ignoreExpression;
		
		// Expression stack state
		public int expressionStackPos;
		
		// If/else state
		public int ifElseNesting;
		public int ifElseIgnoreNestCount;
		public boolean ifElseSkipTruePart;
		
		// Other
		public int indent;
		public int expressionProxyPos;
		
		/**
		 * Construct and save the state.
		 * 
		 * @param markNumber
		 * 
		 * @since 1.1.0
		 */
		public SaveState(int markID) {
			this.markID = markID;
			
			ExpressionProcesser ep = ExpressionProcesser.this;
			this.topBlock = ep.topBlock;
			this.breakBlock = ep.breakBlock;
			
			this.topSubexpression = ep.topSubexpression;
			
			this.topTry = ep.topTry;
			this.breakTry = ep.breakTry;
			this.catchThrowable = ep.catchThrowable;
			
			this.errorOccurred = ep.errorOccurred;
			this.novalueException = ep.novalueException;
			this.exception = ep.exception;
			this.ignoreExpression = ep.ignoreExpression;
			
			this.expressionStackPos = expressionStack.size()-1;
			
			this.ifElseNesting = ep.ifElseNesting;
			this.ifElseIgnoreNestCount = ep.ifElseIgnoreNestCount;
			this.ifElseSkipTruePart = ep.ifElseSkipTruePart;
			
			this.indent = ep.indent;
			this.expressionProxyPos = expressionProxies != null ? expressionProxies.size()-1 : -1;
		}
		
		/**
		 * Restore the state.
		 * 
		 * 
		 * @since 1.1.0
		 */
		public void restoreState() {
			ExpressionProcesser ep = ExpressionProcesser.this;
			ep.topBlock = this.topBlock;
			ep.breakBlock = this.breakBlock;

			ep.topSubexpression = this.topSubexpression;
			
			ep.topTry = this.topTry;
			ep.breakTry = this.breakTry;
			ep.catchThrowable = this.catchThrowable;
			if (trysInCatch != null) {
				for (int i = topTry + 1; i < ep.trysInCatch.length; i++) {
					ep.trysInCatch[i] = null;
				}
			}

			ep.errorOccurred = this.errorOccurred;
			ep.novalueException = ep.novalueException;
			ep.exception = this.exception;
			ep.ignoreExpression = this.ignoreExpression;
			
			// Pop stack down to saved state.
			for (int i = expressionStack.size()-1; i > this.expressionStackPos; i--) {
				expressionStack.remove(i);
				expressionTypeStack.remove(i);
			}
			
			ep.ifElseNesting = this.ifElseNesting;
			ep.ifElseIgnoreNestCount = this.ifElseIgnoreNestCount;
			ep.ifElseSkipTruePart = this.ifElseSkipTruePart;
			
			ep.indent = this.indent;
			
			if (expressionProxies != null) {
				for (int i = expressionProxies.size() - 1; i > this.expressionProxyPos; i--) {
					expressionProxies.remove(i);
				}
			}
			
			// These settings can't cross mark boundaries, so reset them to not set. This is in case we were in this state somewhere
			// in the mark when the restore occurred.
			ep.conditionalIgnoreNestCount = 0;
			ep.conditionalNesting = 0;
			ep.skipTruePart = false;
			
			ep.infixIgnoreNestCount = 0;
			ep.infixNesting = 0;
		}
	}
	
	/**
	 * Create the save state with the given id.
	 * @param markID
	 * @return
	 * 
	 * @since 1.1.0
	 */
	protected SaveState createSaveState(int markID) {
		return new SaveState(markID);
	}
	
	/**
	 * Push the start of a mark.
	 * @param markNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushMark(int markNumber) {
		if (traceOn)
			printTrace("Mark#"+markNumber, false); //$NON-NLS-1$
		
		if (saveStates == null)
			saveStates = new ArrayList();
		saveStates.add(createSaveState(markNumber));
		
		if (traceOn)
			printTraceEnd();
	}
	
	/**
	 * Push the end mark. If there is no error, it will simply
	 * remove it and all save states in the map after it. If there
	 * is an error it will do this plus it will restore the state.
	 * <p>
	 * It is assumed that the calls are coming in correct order from
	 * the server so we won't check validity.
	 * 
	 * @param markID
	 * @param restore
	 * 
	 * @since 1.1.0
	 */
	public final void pushEndmark(int markID, boolean restore) {
		if (traceOn)
			printTrace("End Mark#"+markID+" Restored="+restore, false); //$NON-NLS-1$ //$NON-NLS-2$
		
		try {
			if (saveStates != null) {
				// Start from the end (since that is where it most likely will be) and start
				// search, removing the end one until we reach the markID.
				for (int i = saveStates.size() - 1; i >= 0; i--) {
					SaveState state = (SaveState) saveStates.remove(i);
					if (state.markID == markID) {
						// We found it.
						if (restore)
							state.restoreState();
						return;
					}
				}
				// But to be safe, if we got here, this is bad. We tried restore a mark we didn't have.
				processSyntaxException(new IllegalStateException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.PushEndmark.EndMarkOnNonExistingID_EXC_"), new Object[]{new Integer(markID)}))); //$NON-NLS-1$
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	private int[] subexpressions;	// Stack of subexpression numbers currently evaluating.
	private int[] subexpressionStackPos;	// Stack of the expression stack positions (next entry index) for currently evaluating expressions. The evaluation stack cannot be popped beyond the current top. And at end it will be cleaned up to the position.
	private int topSubexpression = -1;	// Top subexpression index.

	
	/**
	 * Push a begin subexpression.
	 * @param subexpressionNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushSubexpressionBegin(int subexpressionNumber) {
		if (traceOn) {
			printTrace("Begin Subexpression #"+subexpressionNumber, errorOccurred); //$NON-NLS-1$
			indent(true);
		}
		try {
			if (errorOccurred)
				return;
			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
			if (subexpressions == null) {
				subexpressions = new int[10];
				subexpressionStackPos = new int[10];
			}
			if (++topSubexpression >= subexpressions.length) {
				int[] newList = new int[subexpressions.length*2];
				System.arraycopy(subexpressions, 0, newList, 0, subexpressions.length);
				subexpressions = newList;
				newList = new int[subexpressionStackPos.length*2];
				System.arraycopy(subexpressionStackPos, 0, newList, 0, subexpressionStackPos.length);
				subexpressionStackPos = newList;				
			}
			subexpressions[topSubexpression] = subexpressionNumber;
			subexpressionStackPos[topSubexpression] = expressionStack.size();
		} finally {
			if (traceOn)
				printTraceEnd();
		}
	}
	
	/**
	 * Push a subexpression end. The current subexpression must be the given number, or it is an error.
	 * 
	 * @param subexpressionNumber
	 * 
	 * @since 1.1.0
	 */
	public final void pushSubexpressionEnd(int subexpressionNumber) {
		try {
			if (traceOn) {
				indent(false);
				printTrace("End Subexpression #"+subexpressionNumber, errorOccurred); //$NON-NLS-1$
			}
			if (errorOccurred)
				return;
			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
			if (subexpressions == null || topSubexpression < 0 || subexpressions[topSubexpression] != subexpressionNumber) {
				processSyntaxException(new IllegalStateException(InitparserTreeMessages.getString("ExpressionProcesser.PushSubexpressionEnd.ReceivedEndSubexpressionsOutOfOrder_EXC_"))); //$NON-NLS-1$
			} else {
				try {
					popExpressions(expressionStack.size()-subexpressionStackPos[topSubexpression]);
					topSubexpression--;
				} catch (NoExpressionValueException e) {
					processException(e);
				}
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}			
	}


}
