/*******************************************************************************
 * 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: Expression.java,v $
 *  $Revision: 1.5 $  $Date: 2005/02/15 22:53:46 $ 
 */
package org.eclipse.jem.internal.proxy.core;

import java.text.MessageFormat;
import java.util.ArrayList;

import org.eclipse.jem.internal.proxy.initParser.tree.*;
 
/**
 * This is an internal implementation of Expression. It encapsulates much of the processing required
 * into a common form that will be turned into simple push/pop/evaluate type of interaction with the
 * actual other side. 
 * <p>
 * It will maintain a stack of the expressions. As the expressions come in they will be stacked if not
 * able to be executed immediately. The expressions come to this class in an  outside to inside order,
 * but they need to be processed in an inside-out order instead. 
 * <p>
 * Subclasses will be used for the different types of proxy interfaces. The abstract methods will
 * then be the simple interface. 
 * <p>
 * It is not meant to override the actual create expression methods because the processing the stack
 * is very sensitive and must execute in the proper sequence. So the create methods are final for this.
 * <p>
 * This class is not thread-safe.
 * 
 * @since 1.0.0
 */
public abstract class Expression implements IExpression {

	/*
	 * We have stack here, but rather than create a class that does the
	 * stack protocol, will simply have some private methods to do
	 * the same thing for the stack. (Note: Can't use java.util.Stack
	 * because that is a synchronized class, and don't want the overhead). 
	 * 
	 * The purpose of the stack is to stack up expressions that have not yet
	 * been evaluated. 
	 * 
	 * Each expression type will control the content of what it pushes and pops.
	 * The expression type will be the last thing it pushes so that on popping
	 * we know what kind of expression is now completed and ready for evaluation.
	 */
	private ArrayList controlStack = new ArrayList(30);
	
	protected final ProxyFactoryRegistry registry;
	protected final IStandardBeanProxyFactory beanProxyFactory;
	
	/**
	 * Push an object onto the control stack.
	 * 
	 * @param o
	 * 
	 * @since 1.0.0
	 */
	protected final void push(Object o) {
		controlStack.add(o);
	}
	
	/**
	 * Pop an object off of the control stack
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final Object pop() {
		return controlStack.remove(controlStack.size()-1);
	}
	
	/**
	 * Peek at an object from the control stack. <code>fromTop</code> is how far from the top of the stack to look.
	 * If it one, then it is the top entry, two is the next one down. Zero is an invalid value for the parameter.
	 * @param fromTop How far from the top to peek. <code>1</code> is the top, not zero.
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final Object peek(int fromTop) {
		// 1 means the top, 2 is the next one down.
		return controlStack.get(controlStack.size()-fromTop);
	}
	
	/*
	 * Expression type constants.
	 */
	
	/*
	 * ARRAY ACCESS expression.
	 * The expression stack will have:
	 * 	IExpression.ARRAYACCESS_ARRAY
	 * 	IExpression.ARRAYACCESS_INDEX (for 1 to n times depending on index count)
	 * 	PROCESS_EXPRESSION
	 * 
	 * The value stack will have
	 * 	ARRAYACCESS
	 * 	Integer(index count) 
	 */
	private static final Integer ARRAYACCESS = new Integer(IInternalExpressionConstants.ARRAY_ACCESS_EXPRESSION);
	private static final Integer ARRAYACCESS_INDEX_1 = new Integer(1);	// Use in normal case of one index count. Saves object creation.
	
	/*
	 * ARRAY CREATION expression.
	 * The expression stack will have:
	 * 	ARRAYCREATION_INITIALIZER - if hasInitializer
	 *  IExpression.ARRAYCREATION_DIMENSION (for 0 to n times depending on dimension count)
	 *  PROCESS_EXPRESSION
	 * 
	 * The value stack will have
	 *  ARRAYCREATION
	 *  type (either a string representing the type, or an IBeanProxyType representing the type).
	 *  Integer(dimension count) (if zero then there is an initializer) 
	 * 
	 * 
	 * Note: Array Initializer works with this in that it will peek into the value stack two entries down
	 * to find the type of array it should be creating.
	 */
	private static final Integer ARRAYCREATION = new Integer(IInternalExpressionConstants.ARRAY_CREATION_EXPRESSION);
	private static final Integer ARRAY_CREATION_DIMENSION_1 = new Integer(1);	// Use in normal case of one dimension. Save object creation.
	private static final Integer ARRAY_CREATION_DIMENSION_0 = new Integer(0);	// Use in normal case of initializer. Save object creation.
	private static final int ARRAY_INITIALIZER = -1;	// Local because only needed her for expression.
	
	/*
	 * ARRAY INITIALIZER expression
	 * The expression stack will have:
	 * 	IExpression.ARRAYINITIALIZER_EXPRESSION (for n times depending on number of expressions count)
	 * 	PROCESS_EXPRESSION
	 * 
	 * The value stack will have
	 * 	ARRAYINITIALIZER
	 *  type (either a string representing the type, or an IBeanProxyType representing the type).
	 * 		I.e. if array being created is int[][], the value pushed here will be int[]. This is because when created
	 * 		the array will wind up with int[expressioncount][] in the end.
	 * 	Integer (expression count)
	 * 
	 * Note: Imbedded Array Initializers works with this in that it will peek into the value stack two entries down
	 * to find the type of array it should be creating.
	 */
	private static final Integer ARRAYINITIALIZER = new Integer(IInternalExpressionConstants.ARRAY_INITIALIZER_EXPRESSION);
	private static final Integer ARRAYINITIALIZER_COUNT_0 = new Integer(0);	// Use in normal case of empty array. Save object creation.
	private static final Integer ARRAYINITIALIZER_COUNT_1 = new Integer(1);	// Use in normal case of one element array. Save object creation.
	private static final Integer ARRAYINITIALIZER_COUNT_2 = new Integer(2);	// Use in normal case of two element array. Save object creation.	
	
	/*
	 * CAST expression.
	 * The expression stack will have:
	 * 	IExpression.CAST_EXPRESSION
	 * 	PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 * 	CAST
	 * 	type (either a string representing the type, or an IBeanProxyType representing the type).
	 */
	private static final Integer CAST = new Integer(IInternalExpressionConstants.CAST_EXPRESSION);

	/*
	 * CLASS INSTANCE CREATION expression.
	 * The expression stack will have:
	 *  IExpression.CLASSINSTANCECREATION_ARGUMENT (for 0 to n times depending on argument count)
	 *  PROCESS_EXPRESSION
	 * 
	 * The value stack will have
	 *  CLASSINSTANCECREATION
	 *  type (either a string representing the type, or an IBeanProxyType representing the type).
	 *  Integer(argument count) 
	 * 
	 * 
	 * Note: Array Initializer works with this in that it will peek into the value stack two entries down
	 * to find the type of array it should be creating.
	 */
	private static final Integer CLASSINSTANCECREATION = new Integer(IInternalExpressionConstants.CLASS_INSTANCE_CREATION_EXPRESSION);
	private static final Integer CLASS_INSTANCE_CREATION_ARGUMENTS_1 = new Integer(1);	// Use in normal case of one argument. Save object creation.
	private static final Integer CLASS_INSTANCE_CREATION_ARGUMENTS_0 = new Integer(0);	// Use in normal case of no arguments (default ctor). Save object creation.

	/*
	 * CONDITIONAL expression.
	 * Since this can cause skipping of expressions (e.g. if condition is false, then the true condition should not be evaluated),
	 * we need to have a process expression and process call to the other side for each expression so that it can
	 * determine if it should be ignored or not.
	 * 
	 * The expression stack will have:
	 * 	IExpression.CONDITIONAL_CONDITION
	 * 	PROCESS_EXPRESSION
	 * 	IExpression.CONDITIONAL_TRUE
	 * 	PROCESS_EXPRESSION
	 * 	IExpression.CONDITIONAL_FALSE
	 * 	PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 * 	CONDITIONAL
	 * 	CONDITIONAL_CONDITION
	 * 	CONDITIONAL
	 * 	CONDITIONAL_TRUE
	 * 	CONDITIONAL
	 * 	CONDITIONAL_FALSE
	 * 
	 */
	private static final Integer CONDITIONAL = new Integer(IInternalExpressionConstants.CONDITIONAL_EXPRESSION);
	private static final Integer CONDITIONAL_TEST = new Integer(IExpressionConstants.CONDITIONAL_CONDITION);
	private static final Integer CONDITIONAL_TRUEEXP = new Integer(IExpressionConstants.CONDITIONAL_TRUE);
	private static final Integer CONDITIONAL_FALSEXP = new Integer(IExpressionConstants.CONDITIONAL_FALSE);
	
	/*
	 * PREFIX expression.
	 * The expression stack will have:
	 * 	IExpression.PREFIX_OPERAND
	 * 	PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 * 	PREFIX
	 * 	operator (using Integer prefix operator constants defined here) 
	 */
	private static final Integer PREFIX = new Integer(IInternalExpressionConstants.PREFIX_EXPRESSION);
	private static final Integer[] PREFIX_OPERATORS;
	static {
		PREFIX_OPERATORS = new Integer[IExpressionConstants.PRE_MAX+1];
		PREFIX_OPERATORS[IExpressionConstants.PRE_PLUS] = new Integer(IExpressionConstants.PRE_PLUS);
		PREFIX_OPERATORS[IExpressionConstants.PRE_MINUS] = new Integer(IExpressionConstants.PRE_MINUS);
		PREFIX_OPERATORS[IExpressionConstants.PRE_COMPLEMENT] = new Integer(IExpressionConstants.PRE_COMPLEMENT);
		PREFIX_OPERATORS[IExpressionConstants.PRE_NOT] = new Integer(IExpressionConstants.PRE_NOT);
	}
	
	/*
	 * INFIX expression.
	 * Since two types of infix operators (conditional and AND or) can cause skipping of expressions (e.g. once
	 * conditional and sees a false expression, the rest of the expressions are skipped and should not be evaluated),
	 * we need to have a process expression and process call to the other side for each expression so that it can
	 * determine if it should be ignored or not.
	 * 
	 * The expression stack will have:
	 * 	IExpression.INFIX_LEFT
	 * 	PROCESS_EXPRESSION
	 * 	IExpression.INFIX_RIGHT
	 *  PROCESS_EXPRESSION
	 * 		(for 0 to n times depending upon extended count)
	 * 		IExpression.INFIX_EXTENDED 
	 * 		PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 * 	INFIX
	 * 	operator (using Integer infix operator constants defined here)
	 *  IN_LEFT
	 * 		(for (extendedCount) times) This will cover the right one and all but last extended
	 * 		INFIX
	 * 		operator (using Integer infix operator constants defined here)
	 *  	IN_OTHER
	 * INFIX
	 * 	operator (using Integer infix operator constants defined here)
	 *  IN_LAST (this is covers either the right one if no extended, or the last extended)
	 */
	private static final Integer INFIX = new Integer(IInternalExpressionConstants.INFIX_EXPRESSION);
	private static final Integer IN_LEFT = new Integer(IInternalExpressionConstants.INFIX_LEFT_OPERAND);
	private static final Integer IN_OTHER= new Integer(IInternalExpressionConstants.INFIX_OTHER_OPERAND);
	private static final Integer IN_LAST = new Integer(IInternalExpressionConstants.INFIX_LAST_OPERAND);
	private static final Integer[] INFIX_OPERATORS;
	static {
		INFIX_OPERATORS = new Integer[IExpressionConstants.IN_MAX+1];
		INFIX_OPERATORS[IExpressionConstants.IN_AND] = new Integer(IExpressionConstants.IN_AND);
		INFIX_OPERATORS[IExpressionConstants.IN_CONDITIONAL_AND] = new Integer(IExpressionConstants.IN_CONDITIONAL_AND);
		INFIX_OPERATORS[IExpressionConstants.IN_CONDITIONAL_OR] = new Integer(IExpressionConstants.IN_CONDITIONAL_OR);
		INFIX_OPERATORS[IExpressionConstants.IN_DIVIDE] = new Integer(IExpressionConstants.IN_DIVIDE);
		INFIX_OPERATORS[IExpressionConstants.IN_EQUALS] = new Integer(IExpressionConstants.IN_EQUALS);
		INFIX_OPERATORS[IExpressionConstants.IN_GREATER] = new Integer(IExpressionConstants.IN_GREATER);
		INFIX_OPERATORS[IExpressionConstants.IN_GREATER_EQUALS] = new Integer(IExpressionConstants.IN_GREATER_EQUALS);
		INFIX_OPERATORS[IExpressionConstants.IN_LEFT_SHIFT] = new Integer(IExpressionConstants.IN_LEFT_SHIFT);
		INFIX_OPERATORS[IExpressionConstants.IN_LESS] = new Integer(IExpressionConstants.IN_LESS);
		INFIX_OPERATORS[IExpressionConstants.IN_LESS_EQUALS] = new Integer(IExpressionConstants.IN_LESS_EQUALS);
		INFIX_OPERATORS[IExpressionConstants.IN_MINUS] = new Integer(IExpressionConstants.IN_MINUS);
		INFIX_OPERATORS[IExpressionConstants.IN_NOT_EQUALS] = new Integer(IExpressionConstants.IN_NOT_EQUALS);
		INFIX_OPERATORS[IExpressionConstants.IN_OR] = new Integer(IExpressionConstants.IN_OR);
		INFIX_OPERATORS[IExpressionConstants.IN_PLUS] = new Integer(IExpressionConstants.IN_PLUS);
		INFIX_OPERATORS[IExpressionConstants.IN_REMAINDER] = new Integer(IExpressionConstants.IN_REMAINDER);
		INFIX_OPERATORS[IExpressionConstants.IN_RIGHT_SHIFT_SIGNED] = new Integer(IExpressionConstants.IN_RIGHT_SHIFT_SIGNED);
		INFIX_OPERATORS[IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED] = new Integer(IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED);
		INFIX_OPERATORS[IExpressionConstants.IN_TIMES] = new Integer(IExpressionConstants.IN_TIMES);
		INFIX_OPERATORS[IExpressionConstants.IN_XOR] = new Integer(IExpressionConstants.IN_XOR);
	}	
	
	/*
	 * INSTANCEOF expression.
	 * The expression stack will have:
	 * 	IExpression.INSTANCEOF_EXPRESSION
	 * 	PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 * 	INSTANCEOF
	 * 	type (either a string representing the type, or an IBeanProxyType representing the type).
	 */
	private static final Integer INSTANCEOF = new Integer(IInternalExpressionConstants.INSTANCEOF_EXPRESSION);

	/*
	 * Field access expression.
	 * The expression stack will have:
	 * 	IExpression.FIELD_RECEIVER (if hasReceiver is true)
	 * 	PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 * 	FIELDACCESS
	 * 	name (the name of the field)
	 *  Boolean (true if has receiver)
	 */
	private static final Integer FIELDACCESS = new Integer(IInternalExpressionConstants.FIELD_ACCESS_EXPRESSION);

	/*
	 * Method invocation expression.
	 * The expression stack will have:
	 * 	IExpression.METHOD_RECEIVER (if hasReceiver is true)
	 * 	IExpression.METHOD_ARGUMENT (0 to n times for how many arguments).
	 * 	PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 * 	METHODINVOCATION
	 * 	name (the name of the method)
	 *  Boolean (true if has receiver)
	 *  argCount (the number of arguments).
	 */
	private static final Integer METHODINVOCATION = new Integer(IInternalExpressionConstants.METHOD_EXPRESSION);
	private static final Integer METHOD_ARGUMENTS_1 = new Integer(1);	// Use in normal case of one argument. Save object creation.
	private static final Integer METHOD_ARGUMENTS_0 = new Integer(0);	// Use in normal case of no arguments. Save object creation.
	
	
	/*
	 * Next valid for expression stack. This is kept as a stack also.
	 * As the expressions come in, the appropriate order (in reverse)
	 * of expression types will be pushed, and then popped as they 
	 * come in.
	 * 
	 * Since we can't have an array list of ints, will simulate the
	 * stack here.
	 */
	private int[] nextForExpressionStack = new int[30];
	private int nextForExpressionStackPos = -1;	// Position of top entry in stack.
	private static final int INVALID = -2;	// Mark that this expression is now invalid. (Goes into nextForExpressionStackSize)
	private String invalidMsg = null;	// Msg for being invalid if default msg not sufficient.
	
	private static final int PROCESS_EXPRESSION = Integer.MIN_VALUE;	// This is pushed onto the next expression stack, and went it is popped, then the expression is complete
	
	/**
	 * Check the for expression, and if legal, set to the next valid for expression type,
	 * if it can.
	 * 
	 * @param forExpression
	 * @throws IllegalStateException
	 * 
	 * @since 1.0.0
	 */
	protected final void checkForExpression(int forExpression) throws IllegalStateException {
		if (nextForExpressionStackPos != INVALID) {
			if (nextForExpressionStackPos == -1)
				if (forExpression == IExpressionConstants.ROOTEXPRESSION)
					return;	// valid. We are at the root (i.e. nothing is waiting).
				else
					;	// invalid. drop through
			else if (nextForExpressionStack[nextForExpressionStackPos--] == forExpression)
				return;	// Valid, the top expression matched.
		} else {
			String expMsg = invalidMsg != null ? MessageFormat.format(ProxyMessages.getString("Expression.InInvalidStateDueTo_EXC_"), new Object[] {invalidMsg}) : ProxyMessages.getString("Expression.InInvalidState_EXC_"); //$NON-NLS-1$ //$NON-NLS-2$
			throw new IllegalStateException(expMsg);
		}
		
		// If we got here, then invalid.
		nextForExpressionStackPos = INVALID;
		throw new IllegalStateException(ProxyMessages.getString("Expression.TypeSentInInvalidOrder_EXC_")); //$NON-NLS-1$
	}
	
	/**
	 * Peek into the for expression stack to see if the top entry is the passed in value. It will
	 * not pop the stack nor throw any exceptions.
	 * 
	 * @param forExpression The top expression flag will be compared against this value.
	 * @return <code>true</code> if the top expression equals the parameter passed in.
	 * 
	 * @since 1.0.0
	 */
	protected final boolean peekForExpression(int forExpression) {
		if (nextForExpressionStackPos != INVALID) {
			if (nextForExpressionStackPos == -1)
				if (forExpression == IExpressionConstants.ROOTEXPRESSION)
					return true;	// valid. We are at the root (i.e. nothing is waiting).
				else
					;	// invalid. drop through
			else if (nextForExpressionStack[nextForExpressionStackPos] == forExpression)
				return true;	// Valid, the top expression matched.
		} 
		return false;
	}	
	
	/**
	 * Mark this expression as now invalid.
	 */
	protected final void markInvalid() {
		nextForExpressionStackPos = INVALID;
		controlStack.clear();
		closeProxy();
	}
	
	/**
	 * Mark this expression as now invalid, but supply a message to go with it.
	 * 
	 * @param msg
	 * 
	 * @since 1.0.0
	 */
	protected final void markInvalid(String msg) {
		invalidMsg = msg;
		markInvalid();
	}
	
	/*
	 * Check if the pending expression is ready for evaluation.
	 * It is complete if the next entry on the stack is a PROCESS_EXPRESSION
	 */
	private boolean expressionReady() {
		if (nextForExpressionStackPos >= 0 && nextForExpressionStack[nextForExpressionStackPos] == PROCESS_EXPRESSION) {
			checkForExpression(PROCESS_EXPRESSION);	// pop it
			return true;
		} else
			return false;
	}
	
	/*
	 * Push the next expression type.
	 */
	private void pushForExpression(int nextExpression) {
		if (++nextForExpressionStackPos >= nextForExpressionStack.length) {
			// Increase stack size.
			int[] newStack = new int[nextForExpressionStackPos*2];	// So room to grow without excessive allocations.
			System.arraycopy(nextForExpressionStack, 0, newStack, 0, nextForExpressionStack.length);
			nextForExpressionStack = newStack;
		}
		nextForExpressionStack[nextForExpressionStackPos] = nextExpression;
	}
	
	/*
	 * Check if expression is complete, and if it is, process it.
	 */
	private void processExpression() throws ThrowableProxy, NoExpressionValueException {
		while (expressionReady()) {
			try {
				// We've received all of the expressions for the expression, so process it.
				int expType = ((Integer) pop()).intValue();
				switch (expType) {
					case IInternalExpressionConstants.CAST_EXPRESSION:
						pushCastToProxy(pop());
						break;
					case IInternalExpressionConstants.INSTANCEOF_EXPRESSION:
						pushInstanceofToProxy(pop());
						break;
					case IInternalExpressionConstants.PREFIX_EXPRESSION:
						pushPrefixToProxy(((Integer)pop()).intValue());
						break;
					case IInternalExpressionConstants.INFIX_EXPRESSION:
						pushInfixToProxy(((Integer) pop()).intValue(), ((Integer) pop()).intValue());
						break;
					case IInternalExpressionConstants.ARRAY_ACCESS_EXPRESSION:
						pushArrayAccessToProxy(((Integer) pop()).intValue());
						break;
					case IInternalExpressionConstants.ARRAY_CREATION_EXPRESSION:
						pushArrayCreationToProxy(pop(), ((Integer) pop()).intValue());
						break;
					case IInternalExpressionConstants.ARRAY_INITIALIZER_EXPRESSION:
						pushArrayInitializerToProxy(pop(), ((Integer) pop()).intValue());
						break;
					case IInternalExpressionConstants.CLASS_INSTANCE_CREATION_EXPRESSION:
						pushClassInstanceCreationToProxy(pop(), ((Integer) pop()).intValue());
						break;
					case IInternalExpressionConstants.FIELD_ACCESS_EXPRESSION:
						pushFieldAccessToProxy((String) pop(), ((Boolean) pop()).booleanValue());
						break;
					case IInternalExpressionConstants.METHOD_EXPRESSION:
						pushMethodInvocationToProxy((String) pop(), ((Boolean) pop()).booleanValue(), ((Integer) pop()).intValue());
						break;
					case IInternalExpressionConstants.CONDITIONAL_EXPRESSION:
						pushConditionalToProxy(((Integer) pop()).intValue());
						break;
					default:
						internalProcessUnknownExpressionType(expType);
				}
			} catch (ThrowableProxy e) {
				markInvalid();
				throw e;
			} catch (NoExpressionValueException e) {
				markInvalid();
				throw e;
			} catch (RuntimeException e) {
				markInvalid();
				throw e;
			}
		}
	}
	
	private void internalProcessUnknownExpressionType(int expressionType) throws IllegalArgumentException {
		if (!processUnknownExpressionType(expressionType))
			throw new IllegalArgumentException();
	}

	/**
	 * An unknown expression type was found in the processing of expression stack. Subclasses can override
	 * to process new types of expressions. 
	 * <p>
	 * Overrides must return <code>true</code> if they processed the expression type. If they return <code>false</code>
	 * it means they didn't understand it either and we should do default processing for unknow type.
	 * @param expressionType
	 * @return <code>true</code> if type was processed, <code>false</code> if not known by subclass either.
	 * 
	 * @since 1.0.0
	 */
	protected boolean processUnknownExpressionType(int expressionType) {
		return false;
	}

	/**
	 * Create the expression.
	 * 
	 * @param registry
	 * 
	 * @since 1.0.0
	 */
	protected Expression(ProxyFactoryRegistry registry) {
		this.registry = registry;
		this.beanProxyFactory = this.registry.getBeanProxyFactory();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#invokeExpression()
	 */
	public final void invokeExpression() throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		try {
			checkForExpression(IExpressionConstants.ROOTEXPRESSION); // We are at the root.
			pushInvoke();
		} finally {
			markInvalid(); // Mark invalid so any new calls after this will fail.
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#getExpressionValue()
	 */
	public final IBeanProxy getExpressionValue() throws ThrowableProxy, NoExpressionValueException, IllegalStateException {
		try {
			checkForExpression(IExpressionConstants.ROOTEXPRESSION); // We are at the root.
			return pullProxyValue(); // Get the top value.
		} finally {
			markInvalid();	// Mark invalid so any new calls after this will fail.
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayAccess(int, int)
	 */
	public final void createArrayAccess(int forExpression, int indexCount) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushForExpression(PROCESS_EXPRESSION);
			int i = indexCount;
			while (i-- > 0)
				pushForExpression(IExpressionConstants.ARRAYACCESS_INDEX);
			pushForExpression(IExpressionConstants.ARRAYACCESS_ARRAY);

			push(indexCount == 1 ? ARRAYACCESS_INDEX_1 : new Integer(indexCount));
			push(ARRAYACCESS);
			processExpression(); // See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}		
	}
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayCreation(int, java.lang.String, int)
	 */
	public final void createArrayCreation(int forExpression, String type, int dimensionExpressionCount)
		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushArrayCreation(type, dimensionExpressionCount);	// Push this onto the local stack to wait for completion.
			processExpression();	// See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}		
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayCreation(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy, int)
	 */
	public final void createArrayCreation(int forExpression, IBeanTypeProxy type, int dimensionExpressionCount)
		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushArrayCreation(type, dimensionExpressionCount);	// Push this onto the local stack to wait for completion.
			processExpression();	// See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}		
	}

	private void pushArrayCreation(Object type, int dimensionExpressionCount) {
		switch (dimensionExpressionCount) {
			case 0:
				push(ARRAY_CREATION_DIMENSION_0);
				break;
			case 1:
				push(ARRAY_CREATION_DIMENSION_1);
				break;
			default:
				push(new Integer(dimensionExpressionCount));
				break;
		}
		push(type);
		push(ARRAYCREATION);
		
		pushForExpression(PROCESS_EXPRESSION);
		if (dimensionExpressionCount == 0)
			pushForExpression(ARRAY_INITIALIZER);
		else {
			while(dimensionExpressionCount-- >0)
				pushForExpression(IExpressionConstants.ARRAYCREATION_DIMENSION);
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayInitializer(int)
	 */
	public final void createArrayInitializer(int expressionCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		try {
			// This is special, we could be waiting for an array initializer or an array initializer expression.
			// We will peek to see what it is and handle it.
			if (peekForExpression(ARRAY_INITIALIZER))
				checkForExpression(ARRAY_INITIALIZER);
			else
				checkForExpression(IExpressionConstants.ARRAYINITIALIZER_EXPRESSION);
			
			Object arrayType = peek(2);	// Get the type from the value stack. Do before I mess up the stack.
			
			switch (expressionCount) {
				case 0:
					push(ARRAYINITIALIZER_COUNT_0);
					break;
				case 1:
					push(ARRAYINITIALIZER_COUNT_1);
					break;
				case 2:
					push(ARRAYINITIALIZER_COUNT_2);
					break;
				default:
					push(new Integer(expressionCount));
					break;
			}
			
			if (arrayType instanceof String) {
				// Need to remove the end set of "[]" to reduce by one dimension.
				String at = (String) arrayType;
				int i = at.lastIndexOf("[]"); //$NON-NLS-1$
				if (i == -1)
					throw new IllegalArgumentException(MessageFormat.format(ProxyMessages.getString("Expression.ArrayTypeNotAnArray_EXC_"), new Object[] {arrayType})); //$NON-NLS-1$
				arrayType = at.substring(0, i);
			} else if (arrayType instanceof IArrayBeanTypeProxy) {
				arrayType = ((IArrayBeanTypeProxy) arrayType).getComponentType();
			} else
				throw new IllegalArgumentException(MessageFormat.format(ProxyMessages.getString("Expression.ArrayTypeNotAnArray_EXC_"), new Object[] {arrayType})); //$NON-NLS-1$
			push(arrayType);
			push(ARRAYINITIALIZER);
			
			pushForExpression(PROCESS_EXPRESSION);
			while(expressionCount-->0)
				pushForExpression(IExpressionConstants.ARRAYINITIALIZER_EXPRESSION);
			
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}		
		
	}
 
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createCastExpression(int, java.lang.String)
	 * A cast expression has one nested expression.
	 */
	public final void createCastExpression(int forExpression, String type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		pushCast(forExpression, type); // Push this onto the local stack to wait for completion.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createCastExpression(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
	 */
	public final void createCastExpression(int forExpression, IBeanTypeProxy type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		pushCast(forExpression, type); // Push this onto the local stack to wait for completion.
	}
	
	/*
	 * Push for a cast.
	 */
	private void pushCast(int forExpression, Object type) throws ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			push(type);
			push(CAST);
			pushForExpression(PROCESS_EXPRESSION);	
			pushForExpression(IExpressionConstants.CAST_EXPRESSION);	// The next expression must be for the cast expression.
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}		
	}	

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createClassInstanceCreation(int, java.lang.String, int)
	 */
	public final void createClassInstanceCreation(int forExpression, String type, int argumentCount)
		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		pushClassInstanceCreation(forExpression, type, argumentCount);	// Push this onto the local stack to wait for completion.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createClassInstanceCreation(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy, int)
	 */
	public final void createClassInstanceCreation(int forExpression, IBeanTypeProxy type, int argumentCount)
		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		pushClassInstanceCreation(forExpression, type, argumentCount);	// Push this onto the local stack to wait for completion.
	}

	/*
	 * Push for a class instance creation
	 */
	private void pushClassInstanceCreation(int forExpression, Object type, int argumentCount) throws ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			switch (argumentCount) {
				case 0:
					push(CLASS_INSTANCE_CREATION_ARGUMENTS_0);
					break;
				case 1:
					push(CLASS_INSTANCE_CREATION_ARGUMENTS_1);
					break;
				default:
					push(new Integer(argumentCount));
					break;
			}
			push(type);
			push(CLASSINSTANCECREATION);
			
			pushForExpression(PROCESS_EXPRESSION);
			while(argumentCount-- >0)
					pushForExpression(IExpressionConstants.CLASSINSTANCECREATION_ARGUMENT);
			processExpression();	// See if previous expression is ready for processing.			
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}			
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createConditionalExpression(int)
	 */
	public final void createConditionalExpression(int forExpression) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(IExpressionConstants.CONDITIONAL_FALSE);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(IExpressionConstants.CONDITIONAL_TRUE);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(IExpressionConstants.CONDITIONAL_CONDITION);
			
			push(CONDITIONAL_FALSEXP);
			push(CONDITIONAL);
			push(CONDITIONAL_TRUEEXP);
			push(CONDITIONAL);
			push(CONDITIONAL_TEST);
			push(CONDITIONAL);
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createFieldAccess(int, java.lang.String, boolean)
	 */
	public final void createFieldAccess(int forExpression, String fieldName, boolean hasReceiver) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			if (!hasReceiver)
				throw new IllegalArgumentException(ProxyMessages.getString("Expression.CannotHandleNoReceiveOnFieldAccess_EXC_")); //$NON-NLS-1$
			
			push(hasReceiver ? Boolean.TRUE : Boolean.FALSE);	// We have a receiver
			push(fieldName);
			push(FIELDACCESS);
			
			pushForExpression(PROCESS_EXPRESSION);
			if (hasReceiver)
				pushForExpression(IExpressionConstants.FIELD_RECEIVER);
			processExpression();	// See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createInfixExpression(int, int, int)
	 */
	public final void createInfixExpression(int forExpression, int operator, int extendedOperandCount) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			Integer inoperator = INFIX_OPERATORS[operator];
			push(IN_LAST);
			push(inoperator);
			push(INFIX);
			int i = extendedOperandCount;
			while(i-->0) {
				push(IN_OTHER);
				push(inoperator);
				push(INFIX);
			}
			push(IN_LEFT);
			push(inoperator);
			push(INFIX);
		
			i = extendedOperandCount;
			while(i-->0) {
				pushForExpression(PROCESS_EXPRESSION);			
				pushForExpression(IExpressionConstants.INFIX_EXTENDED);
			}
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(IExpressionConstants.INFIX_RIGHT);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(IExpressionConstants.INFIX_LEFT);
			processExpression();	// See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createInstanceofExpression(int, java.lang.String)
	 */
	public final void createInstanceofExpression(int forExpression, String type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		pushInstanceof(forExpression, type);	// Push this onto the local stack to wait for completion.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createInstanceofExpression(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
	 */
	public final void createInstanceofExpression(int forExpression, IBeanTypeProxy type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		pushInstanceof(forExpression, type);	// Push this onto the local stack to wait for completion.
	}
	
	/*
	 * Push for a cast.
	 */
	private void pushInstanceof(int forExpression, Object type) throws ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			push(type);
			push(INSTANCEOF);
			pushForExpression(PROCESS_EXPRESSION);	
			pushForExpression(IExpressionConstants.INSTANCEOF_VALUE);	// The next expression must be for the instance of expression.
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}			
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createMethodInvocation(int, java.lang.String, boolean, int)
	 */
	public final void createMethodInvocation(int forExpression, String name, boolean hasReceiver, int argumentCount)
		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			if (!hasReceiver)
				throw new IllegalArgumentException(MessageFormat.format(ProxyMessages.getString("Expression.MethodsNeedReceiver_EXC_"), new Object[] {name})); //$NON-NLS-1$

			switch (argumentCount) {
				case 0 :
					push(METHOD_ARGUMENTS_0);
					break;
				case 1 :
					push(METHOD_ARGUMENTS_1);
					break;
				default :
					push(new Integer(argumentCount));
					break;
			}
			push(hasReceiver ? Boolean.TRUE : Boolean.FALSE);
			push(name);
			push(METHODINVOCATION);

			pushForExpression(PROCESS_EXPRESSION);
			while (argumentCount-- > 0)
				pushForExpression(IExpressionConstants.METHOD_ARGUMENT);
			if (hasReceiver)
				pushForExpression(IExpressionConstants.METHOD_RECEIVER);
			processExpression(); // See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrefixExpression(int, int)
	 */
	public final void createPrefixExpression(int forExpression, int operator) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			push(PREFIX_OPERATORS[operator]);
			push(PREFIX);
			
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(IExpressionConstants.PREFIX_OPERAND);
			processExpression();	// See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createNull(int)
	 */
	public final void createNull(int forExpression) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(null);
			processExpression();	// See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeLiteral(int, java.lang.String)
	 */
	public final void createTypeLiteral(int forExpression, String type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushTypeLiteralToProxy(type);
			processExpression();	// See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeReceiver(java.lang.String)
	 */
	public final void createTypeReceiver(String type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		pushTypeReceiver(type);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeReceiver(org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
	 */
	public final void createTypeReceiver(IBeanTypeProxy type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		pushTypeReceiver(type);
	}

	/*
	 * Push for a type receiver.
	 * @param type
	 * 
	 * @since 1.0.0
	 */
	private void pushTypeReceiver(Object type) throws ThrowableProxy, NoExpressionValueException {
		try {
			// This is special because type receivers are only valid as the receiver for a field access or a method access.
			// Since each has a different forExpression we need to test for one or the other. It doesn't make any difference
			// which one it is, but it must be one or the other.
			if (peekForExpression(FIELD_RECEIVER))
				checkForExpression(FIELD_RECEIVER);
			else
				checkForExpression(METHOD_RECEIVER);
			
			pushTypeReceiverToProxy(type);
			processExpression();	// See if previous expression is ready for processing.
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}			
	}
	
	/*
	 * For all of the primitive types we will be creating a IBeanProxy for them. That is because that
	 * would be the expected result of the expression, and no need to get the other side involved.
	 */


	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, boolean)
	 */
	public final void createPrimitiveLiteral(int forExpression, boolean value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, char)
	 */
	public final void createPrimitiveLiteral(int forExpression, char value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, byte)
	 */
	public final void createPrimitiveLiteral(int forExpression, byte value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, double)
	 */
	public final void createPrimitiveLiteral(int forExpression, double value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, float)
	 */
	public final void createPrimitiveLiteral(int forExpression, float value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, int)
	 */
	public final void createPrimitiveLiteral(int forExpression, int value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, long)
	 */
	public final void createPrimitiveLiteral(int forExpression, long value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, short)
	 */
	public final void createPrimitiveLiteral(int forExpression, short value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createStringLiteral(int, java.lang.String)
	 */
	public final void createStringLiteral(int forExpression, String value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createProxyExpression(int, org.eclipse.jem.internal.proxy.core.IBeanProxy)
	 */
	public final void createProxyExpression(int forExpression, IBeanProxy proxy) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
		try {
			checkForExpression(forExpression);
			pushToProxy(proxy);
			processExpression();
		} catch (ThrowableProxy e) {
			markInvalid();
			throw e;
		} catch (NoExpressionValueException e) {
			markInvalid();
			throw e;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	

	/**
	 * Push this proxy to the other side. It will simply take the proxy and push it onto
	 * its evaluation stack. It will be treated as the result of an expression. It's just 
	 * that the expression was evaluatable on this side (since it is already a proxy).
	 * 
	 * @param proxy
	 * @throws ThrowableProxy
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushToProxy(IBeanProxy proxy) throws ThrowableProxy;
	
	/**
	 * Tell the other side we are complete. This is only called for invoked expressions,
	 * i.e. no return value.
	 * 
	 * @throws ThrowableProxy
	 * 
	 * @since 1.0.0
	 */
	protected abstract void closeProxy();
	
	/**
	 * Do invoke. This should simply make sure everything is done and throw any pending errors.
	 * 
	 * @throws ThrowableProxy
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushInvoke() throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Pull the top expression value from the evaluation stack. It will also under
	 * the covers call closeProxy. 
	 * 
	 * @return The top level evaluation stack value.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract IBeanProxy pullProxyValue() throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the cast expression. The expression to use will be on the top of its evaluation stack.
	 * The result of the cast expression will be placed onto the evaluation stack.
	 *  
	 * @param type Cast type. It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushCastToProxy(Object type) throws ThrowableProxy, NoExpressionValueException;

	/**
	 * Push to proxy the instanceof expression. The expression to use will be on the top of its evaluation stack.
	 * The result of the instanceof expression will be placed onto the evaluation stack.
	 *  
	 * @param type Instanceof type. It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushInstanceofToProxy(Object type) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the infix operation. This is called on the completion of each operand of the expression.
	 * So it will be called a minimum of two times.
	 * 
	 * @param operator The operator, the values are from IExpressionConstants infix operators.
	 * @param operandType The operand type. left, other, or last. The values are from the IInternalExpressionConstants infix operations.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @see IExpressionConstants#IN_AND
	 * @see IInternalExpressionConstants#INFIX_LAST_OPERAND
	 * @since 1.0.0
	 */
	protected abstract void pushInfixToProxy(int operator, int operandType) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the prefix expression. The expression to use will be on top of its evaluation stack.
	 * The result of the prefix operation will be placed onto the evaluation stack.
	 * 
	 * @param operator The operator, the values are from IExpressionConstants prefix operators.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @see IExpressionConstants#PRE_MINUS
	 * @since 1.0.0
	 */
	protected abstract void pushPrefixToProxy(int operator) throws ThrowableProxy, NoExpressionValueException;	
	
	/**
	 * Push to proxy the type literal string. The result of the type literal string will be placed onto the evaluation
	 * stack.
	 *  
	 * @param type 
	 * @throws ThrowableProxy
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushTypeLiteralToProxy(String type) throws ThrowableProxy;
	
	/**
	 * Push to proxy the array access. The result will be placed onto the evaluation stack.
	 * 
	 * @param indexCount
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushArrayAccessToProxy(int indexCount) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the array creation. The result will be placed onto the evaluation stack.
	 * @param type The array type. (must be an array type) It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
	 * @param dimensionCount
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushArrayCreationToProxy(Object type, int dimensionCount) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the array initializer. The resulting array will be placed onto the evaluation stack.
	 * @param type The array type minus one dimension. (must be an array type) It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
	 * @param expressionCount
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushArrayInitializerToProxy(Object type, int expressionCount) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the class instance creation. The resulting class instance will be placed onto the evaluation stack.
	 * 
	 * @param type Class type. It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
	 * @param argumentCount The number of arguments.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushClassInstanceCreationToProxy(Object type, int argumentCount) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the type receiver. The resulting class will be placed onto the evaluation stack, along with it also
	 * being the expression type.
	 * @param type Class type. It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
	 * @throws ThrowableProxy
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushTypeReceiverToProxy(Object type) throws ThrowableProxy;

	/**
	 * Push to proxy the field access. The result value will be placed onto the evaluation stack.
	 * @param fieldName The name of the field.
	 * @param hasReceiver Has receiver flag.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushFieldAccessToProxy(String fieldName, boolean hasReceiver) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the method invocation. The result value will be placed onto the evaluation stack.
	 * 
	 * @param methodName
	 * @param hasReceiver
	 * @param argCount
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushMethodInvocationToProxy(String methodName, boolean hasReceiver, int argCount) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Push to proxy the conditional expression. This will be called on each part of expression. The expression type
	 * will be the current part (e.g. test, true, false).
	 * 
	 * @param expressionType The expression type, one of IExpressionConstants.CONDITIONAL_* constants.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @see IExpressionConstants#CONDITIONAL_CONDITION
	 * @since 1.0.0
	 */
	protected abstract void pushConditionalToProxy(int expressionType) throws ThrowableProxy, NoExpressionValueException;
}
