/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
/*
 *  $RCSfile: ExpressionProcesser.java,v $
 *  $Revision: 1.17 $  $Date: 2005/07/11 19:40:00 $ 
 */
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.AmbiguousMethodException;
import org.eclipse.jem.internal.proxy.common.MethodHelper;
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$
		}
	}
	
	/**
	 * 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)
			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;
		}
	}
	
	/*
	 * 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_")); //$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
					processSyntaxException(new NoExpressionValueException());
			} else
				processSyntaxException(new NoExpressionValueException());
		} 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) {
				processSyntaxException(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) {
				processSyntaxException(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) {
				processSyntaxException(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) {
				processSyntaxException(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) {
			processSyntaxException(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) {
				processSyntaxException(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) {
				processSyntaxException(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) {
				processSyntaxException(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) {
				processSyntaxException(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) {
				processSyntaxException(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.
				if (argumentCount > 0) {
					Object[]  args = new Object[argumentCount];
					Class[] argTypes = new Class[argumentCount];
					for (int i = argumentCount - 1; i >= 0; i--) {
						args[i] = popExpression();
						argTypes[i] = popExpressionType(false);
					}
					
					// Now we need to find the appropriate constructor.
					Constructor ctor;
					ctor = MethodHelper.findCompatibleConstructor(type, argTypes);
					if (traceOn) {
						System.out.print(ctor);
						System.out.print(')');
					}
					value = ctor.newInstance(args);
				} else {
					// No args, just do default ctor.
					if (traceOn) {
						System.out.print("Default ctor)"); //$NON-NLS-1$
					}
					value = type.newInstance();
				}
				
				pushExpressionValue(value, type);
			} catch (RuntimeException e) {
				processException(e);
			} catch (NoExpressionValueException e) {
				processSyntaxException(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);
			}
		} 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) {
				processSyntaxException(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());
					
				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+'\"';
			}
			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) {
				processSyntaxException(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) {
				processSyntaxException(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.
			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) {
					processSyntaxException(e);
				}
			}
		} finally {
			if (traceOn)
				printTraceEnd();
		}			
	}


}
