/*******************************************************************************
 * 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.7 $  $Date: 2005/05/16 19:11:23 $ 
 */
package org.eclipse.jem.internal.proxy.core;

import java.text.MessageFormat;
import java.util.*;

import org.eclipse.jem.internal.proxy.initParser.tree.*;
 
/**
 * This is implementation of IExpression. 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. All registry specific implementations of IExpression must subclass this class.
 * <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 for subclasses 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 reason.
 * <p>
 * This class is not thread-safe.
 * <p>
 * This class also has API of its own and can be used by customers for advanced usage. Those advanced API are
 * listed on each method as to whether it is customer API or implementers API (i.e. API for implementers of
 * expression subclasses to use). 
 * 
 * 
 * @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_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 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 ForExpression ARRAY_INITIALIZER = new ExpressionEnum(Integer.MIN_VALUE+1, "Array Initializer Internal");
	
	/*
	 * 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_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).
	 */

	/*
	 * 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 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
	 * 
	 */
	
	/*
	 * 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) 
	 */
	
	/*
	 * 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)
	 */
	
	/*
	 * 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).
	 */

	/*
	 * 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)
	 */

	/*
	 * 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 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.
	

	/*
	 * Assignment expression
	 * The expression stack will have:
	 *  IExpression.ASSIGNMENT_RIGHT
	 *  IExpression.ASSIGNMENT_LEFT
	 *  PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 *  ASSIGNMENT
	 *  left expression (variable reference)
	 *  right expression
	 */

	/*
	 * Assignment proxy expression
	 * The expression stack will have:
	 *  IExpression.ASSIGNMENT_RIGHT
	 *  PROCESS_EXPRESSION
	 * 
	 * The value stack will have:
	 *  ASSIGNMENT_PROXY
	 *  expression proxy (an expression proxy)
	 */
	
	/*
	 * 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 ForExpression[] nextForExpressionStack = new ForExpression[30];
	private int nextForExpressionStackPos = -1;	// Position of top entry in stack.
	private boolean expressionValid = true;	// Is the expression currently valid.
	private String invalidMsg = null;	// Msg for being invalid if default msg not sufficient.
	private List expressionProxies;	// List of expression proxies. The index of the proxy is its id. This list must never shrink in size.

	// A MarkEntry. To allow restore in case of error.
	private static class MarkEntry {
		public int markID;
		public int controlStackPos;	// Position of control stack at time of mark.
		public int nextExpressionStackPos;	// Position of nextForExpression stack at time of mark.
		public int expressionProxiesPos;	// Position of expressionProxies list at time of mark.
	}
	
	private int highestMarkID = 0;	// Next mark id. '0' is invalid, as in no marks. This is incremented for each new mark. Never decremented.
	private MarkEntry currentMarkEntry;	// Just a convienence to the current mark entry so no need to look into the list every time.
	private List markEntries;	// Stack of mark entries.
	
	// This class is here so we can add our special internal ForExpression: PROCESS_EXPRESSION. These are never used outside Expression.
	private static class ExpressionEnum extends ForExpression {

		public ExpressionEnum(int value, String name) {
			super(value, name);
		}
		
	}
	
	// This is pushed onto the next expression stack, and when it is popped, then the expression is complete and ready to be pushed to the proxy side.
	private static final ForExpression PROCESS_EXPRESSION = new ExpressionEnum(Integer.MIN_VALUE, "Process Expression");
	
	// This is pushed onto the next expression stack for end block and will test if this there to make sure that it is being called correctly.
	private static final ForExpression BLOCKEND_EXPRESSION = new ExpressionEnum(PROCESS_EXPRESSION.getValue()-2, "End Block Expression");

	// This is pushed onto the next expression stack for end try and will test if this there to make sure that it is being called correctly.
	private static final ForExpression TRYEND_EXPRESSION = new ExpressionEnum(BLOCKEND_EXPRESSION.getValue()-1, "End Try Expression");

	// This is pushed onto the next expression stack for catch and will test if this there to make sure that it is being called correctly.
	private static final ForExpression TRYCATCH_EXPRESSION = new ExpressionEnum(TRYEND_EXPRESSION.getValue()-1, "Catch Expression");
	

	// This is pushed onto the next expression stack for begin thread transfer and will test if this there to make sure that it is being called correctly.
	private static final ForExpression THREADTRANSFER_EXPRESSION = new ExpressionEnum(TRYCATCH_EXPRESSION.getValue()-1, "Catch Expression");

	/**
	 * Check the for expression, and if legal, set to the next valid for expression type,
	 * if it can. If the stack entry is ROOTEXPRESSION, and the forExpression is ROOTEXPRESSION,
	 * then the expression is allowed, but it is not popped. It must be popped later when appropriate.
	 * <p>
	 * This is for "block" expressions. We don't want to pop down the stack passed the ROOTEXPRESSION
	 * that got added by the create block until we get an end block. That allows root expressions to
	 * be added to the block without the stack popping up past the block start in the stack.
	 * 
	 * @param forExpression
	 * @throws IllegalStateException
	 * 
	 * @since 1.0.0
	 */
	protected final void checkForExpression(ForExpression forExpression) throws IllegalStateException {
		if (expressionValid) {
			if (nextForExpressionStackPos == -1)
				if (forExpression == ForExpression.ROOTEXPRESSION)
					return;	// valid. We are at the root (i.e. nothing is waiting).
				else
					;	// invalid. drop through
			else if (nextForExpressionStack[nextForExpressionStackPos] == forExpression) {
				// Valid, either the root expression matched (We don't implicitly pop those. That needs to be done explicitly). 
				// Or we matched non-root, those will be popped.
				if (forExpression != ForExpression.ROOTEXPRESSION) {
					popForExpression();	// Pop the stack since stack not a root expression.
				}
				return;	
			}
		} 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.
		ForExpression expected = nextForExpressionStack[nextForExpressionStackPos];
		expressionValid = false;
		throw new IllegalStateException(MessageFormat.format(ProxyMessages.getString("Expression.TypeSentInInvalidOrder_EXC_"), new Object[] {forExpression, expected})); //$NON-NLS-1$
	}
	
	/**
	 * Pop the top for expression, whatever it is.
	 * @throws IllegalStateException thrown if try to pop through through the current mark entry. The endMark is the only one who can do this.
	 * @since 1.1.0
	 */
	protected final void popForExpression() throws IllegalStateException {
		if (expressionValid && nextForExpressionStackPos >= 0) {
			nextForExpressionStackPos--;
			if (currentMarkEntry != null && nextForExpressionStackPos < currentMarkEntry.nextExpressionStackPos) {
				nextForExpressionStackPos++;	// Restore to what it was
				throwInvalidMarkNesting();
			}
		}
	}

	/*
	 * @throws IllegalStateException
	 * 
	 * @since 1.1.0
	 */
	private void throwInvalidMarkNesting() throws IllegalStateException {
		expressionValid = false;
		throw new IllegalStateException(MessageFormat.format(ProxyMessages.getString("Expression.InvalidMarkNesting"), new Object[] {new Integer(currentMarkEntry != null ? currentMarkEntry.markID : 0)})); //$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(ForExpression forExpression) {
		if (expressionValid) {
			if (nextForExpressionStackPos == -1)
				if (forExpression == ForExpression.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() {
		expressionValid = false;
	}
	
	/**
	 * 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();
	}
	
	public void close() {
		nextForExpressionStackPos = -1;
		controlStack.clear();
		if (expressionProxies != null)
			markAllProxiesNotResolved(expressionProxies);	// They weren't processed, close must of been called early.
		expressionProxies = null;
		markEntries = null;
		expressionValid = false;
		closeProxy();
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#isValid()
	 */
	public boolean isValid() {
		return expressionValid;
	}
	
	/*
	 * 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(ForExpression nextExpression) {
		if (++nextForExpressionStackPos >= nextForExpressionStack.length) {
			// Increase stack size.
			ForExpression[] newStack = new ForExpression[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() {
		while (expressionReady()) {
			try {
				// We've received all of the expressions for the expression, so process it.
				int expType = ((InternalExpressionTypes) pop()).getValue();
				switch (expType) {
					case InternalExpressionTypes.CAST_EXPRESSION_VALUE:
						pushCastToProxy((IProxyBeanType) pop());
						break;
					case InternalExpressionTypes.INSTANCEOF_EXPRESSION_VALUE:
						pushInstanceofToProxy((IProxyBeanType) pop());
						break;
					case InternalExpressionTypes.PREFIX_EXPRESSION_VALUE:
						pushPrefixToProxy((PrefixOperator)pop());
						break;
					case InternalExpressionTypes.INFIX_EXPRESSION_VALUE:
						pushInfixToProxy((InfixOperator) pop(), (InternalInfixOperandType) pop());
						break;
					case InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION_VALUE:
						pushArrayAccessToProxy(((Integer) pop()).intValue());
						break;
					case InternalExpressionTypes.ARRAY_CREATION_EXPRESSION_VALUE:
						pushArrayCreationToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue());
						break;
					case InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION_VALUE:
						pushArrayInitializerToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue(), ((Integer) pop()).intValue());
						break;
					case InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION_VALUE:
						pushClassInstanceCreationToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue());
						break;
					case InternalExpressionTypes.FIELD_ACCESS_EXPRESSION_VALUE:
						pushFieldAccessToProxy(pop(), ((Boolean) pop()).booleanValue());
						break;
					case InternalExpressionTypes.METHOD_EXPRESSION_VALUE:
						pushMethodInvocationToProxy(pop(), ((Boolean) pop()).booleanValue(), ((Integer) pop()).intValue());
						break;
					case InternalExpressionTypes.CONDITIONAL_EXPRESSION_VALUE:
						pushConditionalToProxy((InternalConditionalOperandType) pop());
						break;
					case InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION_VALUE:
						pushAssignmentToProxy((ExpressionProxy) pop());
						break;
					case InternalExpressionTypes.ASSIGNMENT_EXPRESSION_VALUE:
						pushAssignmentToProxy();
						break;
					case InternalExpressionTypes.BLOCK_END_EXPRESSION_VALUE:
						pushBlockEndToProxy(((Integer) pop()).intValue());
						break;
					case InternalExpressionTypes.TRY_END_EXPRESSION_VALUE:
						pushTryEndToProxy(((Integer) pop()).intValue());
						break;
					case InternalExpressionTypes.THROW_EXPRESSION_VALUE:
						pushThrowToProxy();
						break;
					case InternalExpressionTypes.IF_TEST_EXPRESSION_VALUE:
						pushIfTestToProxy();
						break;												
					case InternalExpressionTypes.IF_ELSE_EXPRESSION_VALUE:
						pushIfElseToProxy((InternalIfElseOperandType) pop());
						break;						
					default:
						internalProcessUnknownExpressionType(expType);
				}
			} 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#getRegistry()
	 */
	public ProxyFactoryRegistry getRegistry() {
		return registry;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#invokeExpression()
	 */
	public final void invokeExpression() throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION); // We are at the root.
			popForExpression();	// Get rid of any intermediate roots.
			checkForExpression(ForExpression.ROOTEXPRESSION);	// We should be at true root now. We don't have more than one intermediate root pushed in sequence.
			List proxies = expressionProxies;
			expressionProxies = null;
			pushInvoke(processExpressionProxyCallbacks(proxies), proxies);
		} finally {
			markInvalid(); // Mark invalid so any new calls after this will fail.
			close();
		}
	}
		
	/*
	 * Process the expression proxy callbacks, if any.
	 * @return the number of proxies that have callbacks.
	 */
	private int processExpressionProxyCallbacks(List proxies) {
		if (proxies != null) {
			// Strip list down to only those with callbacks and send on.
			int proxiesWithCallbacks = 0;
			for (ListIterator eps = proxies.listIterator(); eps.hasNext();) {
				ExpressionProxy proxy = (ExpressionProxy) eps.next();
				if (!proxy.hasListeners())
					eps.set(null);	// Remove it from the list. No one cares.
				else
					proxiesWithCallbacks++;
			}
			return proxiesWithCallbacks;
		}
		return 0;
	}
		
	/**
	 * Called by subclass to fill in the value of an expression proxy. See {@link Expression#pullProxyValue(int, List))} for an example of who would call it.
	 * @param ep
	 * @param beanproxy
	 * 
	 * @since 1.1.0
	 */
	protected void fireProxyResolved(ExpressionProxy ep, IBeanProxy beanproxy) {
		ep.fireResolved(beanproxy);
	}
	
	/**
	 * Called by subclass to fire proxy was not resolved. See {@link Expression#pullProxyValue(int, List))} for an example of who would call it.
	 * @param ep
	 * 
	 * @since 1.1.0
	 */
	protected void fireProxyNotResolved(ExpressionProxy ep) {
		ep.fireNotResolved();
	}
	
	/**
	 * Called by subclass to fire proxy resolved to a void return type. See {@link Expression#pullProxyValue(int, List))} for an example of who would call it.
	 * @param ep
	 * 
	 * @since 1.1.0
	 */
	protected void fireProxyVoid(ExpressionProxy ep) {
		ep.fireVoidResolved();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#getExpressionValue()
	 */
	public final IBeanProxy getExpressionValue() throws ThrowableProxy, NoExpressionValueException, IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION); // We are at the root.
			popForExpression();	// Get rid of any intermediate roots.
			checkForExpression(ForExpression.ROOTEXPRESSION);	// We should be at true root now. We don't have more than one intermediate root pushed in sequence.
			List proxies = expressionProxies;
			expressionProxies = null;
			return pullProxyValue(processExpressionProxyCallbacks(proxies), proxies); // Get the top value.
		} finally {
			markInvalid();	// Mark invalid so any new calls after this will fail. 
			close();
		}
	}

	
	/**
	 * Mark the list of proxies as not resolved. 
	 * 
	 * @since 1.1.0
	 */
	protected void markAllProxiesNotResolved(List proxies) {
		if (proxies != null) {
			for (ListIterator eps = proxies.listIterator(); eps.hasNext();) {
				ExpressionProxy proxy = (ExpressionProxy) eps.next();
				if (proxy != null && proxy.hasListeners())
					fireProxyNotResolved(proxy);
			}
		}
	}

	private int blockNumber = -1;	// Current block number. This is always incrementing.
	
	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createBlockBegin()
	 */
	public final int createBlockBegin() throws IllegalStateException {
		try {
			// Blocks are special, they can be anywhere at root, of could be the true or else clause of an if/else.
			if (peekForExpression(ForExpression.ROOTEXPRESSION))
				checkForExpression(ForExpression.ROOTEXPRESSION);
			else if (peekForExpression(ForExpression.IF_TRUE))
				checkForExpression(ForExpression.IF_TRUE);
			else
				checkForExpression(ForExpression.IF_ELSE);
			
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(BLOCKEND_EXPRESSION);
			pushForExpression(ForExpression.ROOTEXPRESSION);

			pushBlockBeginToProxy(++blockNumber);
			push(new Integer(blockNumber));
			push(InternalExpressionTypes.BLOCK_END_EXPRESSION);
			processExpression();
			return blockNumber;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createBlockBreak(int)
	 */
	public final void createBlockBreak(int blockNumber) throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			pushBlockBreakToProxy(blockNumber);
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createBlockEnd()
	 */
	public final void createBlockEnd() throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			popForExpression(); // Remove the root expression since block is done.
			checkForExpression(BLOCKEND_EXPRESSION); // This needs to be next for it to be valid.
			processExpression(); // Now let it handle the previously pushed end block, containing the block number being ended.
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

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

			push(indexCount == 1 ? ARRAYACCESS_INDEX_1 : new Integer(indexCount));
			push(InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION);
			processExpression(); // See if previous expression is ready for processing.
		} 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(ForExpression forExpression, String type, int dimensionExpressionCount)
		throws IllegalStateException {
		pushArrayCreation(forExpression, getProxyBeanType(type), dimensionExpressionCount);
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayCreation(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyBeanType, int)
	 */
	public final void createArrayCreation(ForExpression forExpression, IProxyBeanType type, int dimensionExpressionCount)
		throws IllegalStateException {
		pushArrayCreation(forExpression, type, dimensionExpressionCount);
	}

	private void pushArrayCreation(ForExpression forExpression, IProxyBeanType type, int dimensionExpressionCount) throws IllegalStateException {
		try {
			checkForExpression(forExpression);

			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(InternalExpressionTypes.ARRAY_CREATION_EXPRESSION);

			pushForExpression(PROCESS_EXPRESSION);
			if (dimensionExpressionCount == 0)
				pushForExpression(ARRAY_INITIALIZER);
			else {
				while (dimensionExpressionCount-- > 0)
					pushForExpression(ForExpression.ARRAYCREATION_DIMENSION);
			}
			processExpression(); // See if previous expression is ready for processing.		
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayInitializer(int)
	 */
	public final void createArrayInitializer(int expressionCount) throws IllegalStateException {
		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(ForExpression.ARRAYINITIALIZER_EXPRESSION);

			// At this point in time that stack may either have:
			// array_type, array_creation
			// strip_count, array_type, array_initializer
			// So we can get the array type from peek(2), and get the command type from peek(1).
			// Then if the command type is array_creation, strip_count will be inited to 0, while
			// else it will be inited to peek(3). From that we can increment the strip_count to
			// use for this initializer.
			//
			// We need to peek here because we will be adding various pushes to the stack and we
			// need to get the info while it is still at the top of the stack.
			Object arrayType = peek(2); 
			int stripCount = 0;
			if (peek(1) == InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION)
				stripCount = ((Integer) peek(3)).intValue();

			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) {
				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 = getProxyBeanType(at);
			} else if (!(arrayType instanceof IProxyBeanType)) {
				throw new IllegalArgumentException(MessageFormat.format(
						ProxyMessages.getString("Expression.ArrayTypeNotAnArray_EXC_"), new Object[] { arrayType})); //$NON-NLS-1$
			}
			push(new Integer(++stripCount));
			push(arrayType);
			push(InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION);

			pushForExpression(PROCESS_EXPRESSION);
			while (expressionCount-- > 0)
				pushForExpression(ForExpression.ARRAYINITIALIZER_EXPRESSION);

			processExpression(); 
		} 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(ForExpression forExpression, String type) throws IllegalStateException {
		pushCast(forExpression, getProxyBeanType(type)); // Push this onto the local stack to wait for completion.
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createCastExpression(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyBeanType)
	 */
	public final void createCastExpression(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException {
		pushCast(forExpression, type); // Push this onto the local stack to wait for completion.
	}
	
	/*
	 * Push for a cast.
	 */
	private void pushCast(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			push(type);
			push(InternalExpressionTypes.CAST_EXPRESSION);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.CAST_EXPRESSION); // The next expression must be for the cast expression.
			processExpression(); 
		} 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(ForExpression forExpression, String type, int argumentCount)
		throws IllegalStateException {
		pushClassInstanceCreation(forExpression, getProxyBeanType(type), argumentCount);	// Push this onto the local stack to wait for completion.
	}

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

	/*
	 * Push for a class instance creation
	 */
	private void pushClassInstanceCreation(ForExpression forExpression, IProxyBeanType type, int argumentCount) throws IllegalStateException {
		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(InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION);

			pushForExpression(PROCESS_EXPRESSION);
			while (argumentCount-- > 0)
				pushForExpression(ForExpression.CLASSINSTANCECREATION_ARGUMENT);
			processExpression(); // See if previous expression is ready for processing.						
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createConditionalExpression(int)
	 */
	public final void createConditionalExpression(ForExpression forExpression) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.CONDITIONAL_FALSE);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.CONDITIONAL_TRUE);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.CONDITIONAL_CONDITION);

			push(InternalConditionalOperandType.CONDITIONAL_FALSE);
			push(InternalExpressionTypes.CONDITIONAL_EXPRESSION);
			push(InternalConditionalOperandType.CONDITIONAL_TRUE);
			push(InternalExpressionTypes.CONDITIONAL_EXPRESSION);
			push(InternalConditionalOperandType.CONDITIONAL_TEST);
			push(InternalExpressionTypes.CONDITIONAL_EXPRESSION);
			processExpression();
		} 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(ForExpression forExpression, String fieldName, boolean hasReceiver) throws IllegalStateException, IllegalArgumentException {
		try {
			// Only for string fieldnames is this invalid when no receiver because no way to determine receiver. (Don't handle implicit "this" yet for fields). 
			// For the accessor that takes a IFieldProxy we can get away with no receiver because the field proxy can determine if static or not, and if not
			// static it will fail at evaluation time.
			if (!hasReceiver)
				throw new IllegalArgumentException(MessageFormat.format(
						ProxyMessages.getString("Expression.CannotHandleNoReceiveOnFieldAccess_EXC_"), new Object[] { fieldName})); //$NON-NLS-1$
			pushFieldAccess(forExpression, fieldName, hasReceiver);
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createIfElse(boolean)
	 */
	public final void createIfElse(boolean hasElseClause) throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			
			pushForExpression(PROCESS_EXPRESSION);
			if (hasElseClause) {
				pushForExpression(ForExpression.IF_ELSE);
			}
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.IF_TRUE);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.IF_CONDITION);

			// We still push an else clause so that we know when finished. We don't have a pushForExpression for it because there
			// won't be any. But the else clause processing will be on the push stack so that we can clean up when end of if stmt occurs.
			push(InternalIfElseOperandType.ELSE_CLAUSE);	
			push(InternalExpressionTypes.IF_ELSE_EXPRESSION);
			
			push(InternalIfElseOperandType.TRUE_CLAUSE);
			push(InternalExpressionTypes.IF_ELSE_EXPRESSION);
			push(InternalExpressionTypes.IF_TEST_EXPRESSION);
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/*
	 * Push the field access.
	 * @param forExpression
	 * @param field String if field name, or IProxyField.
	 * @param hasReceiver
	 * @throws IllegalAccessException
	 * 
	 * @since 1.1.0
	 */
	private void pushFieldAccess(ForExpression forExpression, Object field, boolean hasReceiver) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			push(hasReceiver ? Boolean.TRUE : Boolean.FALSE); // We have a receiver
			push(field);
			push(InternalExpressionTypes.FIELD_ACCESS_EXPRESSION);

			pushForExpression(PROCESS_EXPRESSION);
			if (hasReceiver)
				pushForExpression(ForExpression.FIELD_RECEIVER);
			processExpression(); // See if previous expression is ready for processing.
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createInfixExpression(int, int, int)
	 */
	public final void createInfixExpression(ForExpression forExpression, InfixOperator operator, int extendedOperandCount) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			push(InternalInfixOperandType.INFIX_LAST_OPERAND);
			push(operator);
			push(InternalExpressionTypes.INFIX_EXPRESSION);
			int i = extendedOperandCount;
			while (i-- > 0) {
				push(InternalInfixOperandType.INFIX_OTHER_OPERAND);
				push(operator);
				push(InternalExpressionTypes.INFIX_EXPRESSION);
			}
			push(InternalInfixOperandType.INFIX_LEFT_OPERAND);
			push(operator);
			push(InternalExpressionTypes.INFIX_EXPRESSION);

			i = extendedOperandCount;
			while (i-- > 0) {
				pushForExpression(PROCESS_EXPRESSION);
				pushForExpression(ForExpression.INFIX_EXTENDED);
			}
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.INFIX_RIGHT);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.INFIX_LEFT);
			processExpression(); // See if previous expression is ready for processing.
		} 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(ForExpression forExpression, String type) throws IllegalStateException {
		pushInstanceof(forExpression, getProxyBeanType(type));	// Push this onto the local stack to wait for completion.
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createInstanceofExpression(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyBeanType)
	 */
	public final void createInstanceofExpression(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException {
		pushInstanceof(forExpression, type);	// Push this onto the local stack to wait for completion.
	}
	
	/*
	 * Push for a cast.
	 */
	private void pushInstanceof(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			push(type);
			push(InternalExpressionTypes.INSTANCEOF_EXPRESSION);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.INSTANCEOF_VALUE); // The next expression must be for the instance of expression.
			processExpression(); 
		} 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(ForExpression forExpression, String name, boolean hasReceiver, int argumentCount)
		throws IllegalStateException, IllegalArgumentException {
		try {
			// Only for string methodnames is this invalid when no receiver because no way to determine receiver. (Don't handle implicit "this" yet for methods). 
			// For the accessor that takes a IFieldProxy we can get away with no receiver because the field proxy can determine if static or not, and if not
			// static it will fail at evaluation time.
			if (!hasReceiver)
				throw new IllegalArgumentException(MessageFormat.format(
						ProxyMessages.getString("Expression.MethodsNeedReceiver_EXC_"), new Object[] { name})); //$NON-NLS-1$

			pushMethodInvocation(forExpression, name, hasReceiver, argumentCount);
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	/**
	 * @param forExpression
	 * @param method String for method name, IMethodProxy otherwise.
	 * @param hasReceiver 
	 * @param argumentCount
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.1.0
	 */
	private void pushMethodInvocation(ForExpression forExpression, Object method, boolean hasReceiver, int argumentCount) throws IllegalArgumentException, IllegalStateException {
		try {
			checkForExpression(forExpression);
			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(method);
			push(InternalExpressionTypes.METHOD_EXPRESSION);

			pushForExpression(PROCESS_EXPRESSION);
			while (argumentCount-- > 0)
				pushForExpression(ForExpression.METHOD_ARGUMENT);
			if (hasReceiver)
				pushForExpression(ForExpression.METHOD_RECEIVER);
			processExpression(); // See if previous expression is ready for processing.
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrefixExpression(int, org.eclipse.jem.internal.proxy.initParser.tree.PrefixOperator)
	 */
	public final void createPrefixExpression(ForExpression forExpression, PrefixOperator operator) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			push(operator);
			push(InternalExpressionTypes.PREFIX_EXPRESSION);
			
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.PREFIX_OPERAND);
			processExpression();	// See if previous expression is ready for processing.
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	/**
	 * Create a new instance using the initialization string. The result must be compatible with the
	 * given type. This is not on the IExpression interface because it is not for use of regular
	 * customers. It is here for the allocation processer to create entries that are just strings.
	 * <p>
	 * This is not customer advanced API. This API for the implementers of registries and expression subclasses.
	 * 
	 * @param forExpression
	 * @param initializationString
	 * @param type
	 * 
	 * @since 1.1.0
	 */
	public final void createNewInstance(ForExpression forExpression, String initializationString, IProxyBeanType type) {
		try {
			checkForExpression(forExpression);
			pushNewInstanceToProxy(initializationString, type);
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createNull(int)
	 */
	public final void createNull(ForExpression forExpression) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			pushToProxy(null);
			processExpression();	// See if previous expression is ready for processing.
		} 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(ForExpression forExpression, String type) throws IllegalStateException {
		createProxyExpression(forExpression, getProxyBeanType(type));
	}

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

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

	/*
	 * Push for a type receiver.
	 * @param type
	 * 
	 * @since 1.0.0
	 */
	private void pushTypeReceiver(IProxyBeanType type) throws IllegalStateException {
		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(ForExpression.FIELD_RECEIVER))
				checkForExpression(ForExpression.FIELD_RECEIVER);
			else
				checkForExpression(ForExpression.METHOD_RECEIVER);
			
			pushTypeReceiverToProxy(type);
			processExpression();	// See if previous expression is ready for processing.
		} 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(ForExpression forExpression, boolean value) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

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

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

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

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

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

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

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, short)
	 */
	public final void createPrimitiveLiteral(ForExpression forExpression, short value) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} 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(ForExpression forExpression, String value) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createProxyExpression(int, org.eclipse.jem.internal.proxy.core.IProxy)
	 */
	public final void createProxyExpression(ForExpression forExpression, IProxy proxy) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			pushToProxy(proxy);
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createAssignmentExpression(int)
	 */
	public final void createAssignmentExpression(ForExpression forExpression) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			push(InternalExpressionTypes.ASSIGNMENT_EXPRESSION);
			
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.ASSIGNMENT_RIGHT);
			pushForExpression(ForExpression.ASSIGNMENT_LEFT);
			processExpression();	// See if previous expression is ready for processing.
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createAssignmentExpression(int)
	 */
	public final ExpressionProxy createProxyAssignmentExpression(ForExpression forExpression) throws IllegalStateException {
		try {
			checkForExpression(forExpression);
			ExpressionProxy proxy = allocateExpressionProxy(NORMAL_EXPRESSION_PROXY);
			push(proxy);
			push(InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION);

			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.ASSIGNMENT_RIGHT);
			processExpression(); // See if previous expression is ready for processing.
			return proxy;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	/**
	 * Called by registries to create an expression proxy for a bean type. It is not in the interface because it should
	 * only be called by the proxy registry to create an expression proxy. It shouldn't be called outside of the registries
	 * because there may already exist in the registry the true IBeanTypeProxy, and that one should be used instead.
	 * <p>
	 * This is not customer advanced API. This API for the implementers of registries and expression subclasses.
	 * 
	 * @param typeName
	 * @return expression proxy that is hooked up and will notify when resolved. It can be called at any time. The resolution will occur at this point in the
	 * execution stack, but since it will not interfere with the stack this is OK, other than it could throw a ClassNotFoundException on the
	 * execution.
	 * 
	 * @since 1.1.0
	 */
	public final IProxyBeanType createBeanTypeExpressionProxy(String typeName) {
		IBeanTypeExpressionProxy proxy = (IBeanTypeExpressionProxy) allocateExpressionProxy(BEANTYPE_EXPRESSION_PROXY);
		proxy.setTypeName(typeName);
		// This can be sent at any time. It doesn't matter what is on the expression stack. It will be sent to be resolved immediately.
		pushBeanTypeToProxy(proxy);
		return proxy;
	}

	/**
	 * Called by registries to create an expression proxy for a method. It is not in the interface because it should
	 * only be called by the proxy registry to create an expression proxy. It shouldn't be called outside of the registries
	 * because there may already exist in the registry the true IMethodProxy, and that one should be used instead.
	 * <p>
	 * This is not customer advanced API. This API for the implementers of registries and expression subclasses.
	 * 
	 * @param declaringType
	 * @param methodName
	 * @param parameterTypes parameter types or <code>null</code> if no parameter types.
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public final IProxyMethod createMethodExpressionProxy(IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes) {
		ExpressionProxy proxy = allocateExpressionProxy(METHOD_EXPRESSION_PROXY);
		// This can be sent at any time. It doesn't matter what is on the expression stack. It will be sent to be resolved immediately.
		pushMethodToProxy(proxy, declaringType, methodName, parameterTypes);
		return (IProxyMethod) proxy;
	}
	
	/**
	 * Called by registries to create an expression proxy for a field. It is not in the interface because it should
	 * only be called by the proxy registry to create an expression proxy. It shouldn't be called outside of the registries
	 * because there may already exist in the registry the true IFieldProxy, and that one should be used instead.
	 * <p>
	 * This is not customer advanced API. This API for the implementers of registries and expression subclasses.
	 * 
	 * @param declaringType
	 * @param fieldName
	 * 
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public final IProxyField createFieldExpressionProxy(IProxyBeanType declaringType, String fieldName) {
		ExpressionProxy proxy = allocateExpressionProxy(FIELD_EXPRESSION_PROXY);
		// This can be sent at any time. It doesn't matter what is on the expression stack. It will be sent to be resolved immediately.
		pushFieldToProxy(proxy, declaringType, fieldName);
		return (IProxyField) proxy;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createProxyReassignmentExpression(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.ExpressionProxy)
	 */
	public final void createProxyReassignmentExpression(ForExpression forExpression, ExpressionProxy proxy) throws IllegalStateException, IllegalArgumentException {
		try {
			checkForExpression(forExpression);
			if (!proxy.isValidForReassignment())
				throw new IllegalArgumentException("Invalid expression type for reassignment:"+proxy.toString());
			push(proxy);
			push(InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION);

			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.ASSIGNMENT_RIGHT);
			processExpression(); // See if previous expression is ready for processing.
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
		
	protected static final int NORMAL_EXPRESSION_PROXY = 0;
	protected static final int BEANTYPE_EXPRESSION_PROXY = 1;
	protected static final int METHOD_EXPRESSION_PROXY = 2;
	protected static final int FIELD_EXPRESSION_PROXY = 3;
	/**
	 * Allocate a new ExpressionProxy
	 * @return new ExpressionProxy.
	 * 
	 * @since 1.1.0
	 */
	protected final ExpressionProxy allocateExpressionProxy(int proxyType) {
		if (expressionProxies == null)
			expressionProxies = new ArrayList();
		// It is very important that this always creates a proxy id that is greater than all previous. This is
		// so that it can be assured that proxies will be resolved in order of creation.
		// Currently this is done here by using expressionProxies.size().
		ExpressionProxy proxy = createExpressionProxy(proxyType, expressionProxies.size());
		expressionProxies.add(proxy);
		return proxy;
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createFieldAccess(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyField, boolean)
	 */
	public final void createFieldAccess(ForExpression forExpression, IProxyField fieldProxy, boolean hasReceiver) throws IllegalStateException {
		pushFieldAccess(forExpression, fieldProxy, hasReceiver);
	}
	
	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createMethodInvocation(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyMethod, boolean, int)
	 */
	public final void createMethodInvocation(ForExpression forExpression, IProxyMethod methodProxy, boolean hasReceiver, int argumentCount) throws IllegalArgumentException,
			IllegalStateException {
		pushMethodInvocation(forExpression, methodProxy, hasReceiver, argumentCount);
	}
	
	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createSimpleFieldAccess(org.eclipse.jem.internal.proxy.core.IProxyField, org.eclipse.jem.internal.proxy.core.IProxy)
	 */
	public final ExpressionProxy createSimpleFieldAccess(IProxyField field, IProxy receiver) throws IllegalStateException {
		ExpressionProxy result = createProxyAssignmentExpression(ForExpression.ROOTEXPRESSION);
		createFieldAccess(ForExpression.ASSIGNMENT_RIGHT, field, receiver != null);
		if (receiver != null)
			createProxyExpression(ForExpression.FIELD_RECEIVER, receiver);
		return result;
	}
	
	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createSimpleFieldSet(org.eclipse.jem.internal.proxy.core.IProxyField, org.eclipse.jem.internal.proxy.core.IProxy, org.eclipse.jem.internal.proxy.core.IProxy, boolean)
	 */
	public final ExpressionProxy createSimpleFieldSet(IProxyField field, IProxy receiver, IProxy value, boolean wantResult) throws IllegalStateException {
		ExpressionProxy result = null;
		ForExpression forExpression = ForExpression.ROOTEXPRESSION;
		if (wantResult) {
			result = createProxyAssignmentExpression(forExpression);
			forExpression = ForExpression.ASSIGNMENT_RIGHT;			
		}		
		createAssignmentExpression(forExpression);
		createFieldAccess(ForExpression.ASSIGNMENT_LEFT, field, receiver != null);
		if (receiver != null)
			createProxyExpression(ForExpression.FIELD_RECEIVER, receiver);
		createProxyExpression(ForExpression.ASSIGNMENT_RIGHT, value);
		return result;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createSimpleMethodInvoke(org.eclipse.jem.internal.proxy.core.IMethodProxy, org.eclipse.jem.internal.proxy.core.IProxy, org.eclipse.jem.internal.proxy.core.IProxy[], boolean)
	 */
	public final ExpressionProxy createSimpleMethodInvoke(IProxyMethod method, IProxy receiver, IProxy[] arguments, boolean wantResult)
			throws IllegalStateException {
		ForExpression nextExpression = ForExpression.ROOTEXPRESSION;
		ExpressionProxy result = null;
		if (wantResult) {
			result = createProxyAssignmentExpression(nextExpression);
			nextExpression = ForExpression.ASSIGNMENT_RIGHT;
		}
		createMethodInvocation(nextExpression, method, receiver != null, arguments != null ? arguments.length : 0);
		if (receiver != null)
			createProxyExpression(ForExpression.METHOD_RECEIVER, receiver);
		if (arguments != null) {
			for (int i = 0; i < arguments.length; i++) {
				createProxyExpression(ForExpression.METHOD_ARGUMENT, arguments[i]);
			}
		}
		return result;
	}
	
	private int tryNumber = -1;	// Current try number. This is always incrementing.
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTry()
	 */
	public final void createTry() throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			pushForExpression(PROCESS_EXPRESSION); // Set up so that when reached we can process the TRY_END that we've pushed data for later in this method.
			pushForExpression(TRYEND_EXPRESSION); // Must get a try end before we can process it.
			pushForExpression(TRYCATCH_EXPRESSION); // Must get a catch/finally clause (or try end, which knows how to handle this).
			pushForExpression(ForExpression.ROOTEXPRESSION); // Expecting root expressions for the try clause.

			pushTryBeginToProxy(++tryNumber);
			push(new Integer(tryNumber));
			push(InternalExpressionTypes.TRY_END_EXPRESSION);
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryCatchClause(org.eclipse.jem.internal.proxy.core.IProxyBeanType, boolean)
	 */
	public final ExpressionProxy createTryCatchClause(IProxyBeanType exceptionType, boolean wantExceptionReturned)
			throws IllegalStateException {
		return pushTryCatch(exceptionType, wantExceptionReturned);
	}
	
	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryCatchClause(java.lang.String, boolean)
	 */
	public final ExpressionProxy createTryCatchClause(String exceptionType, boolean wantExceptionReturned)
		throws IllegalStateException {
		return pushTryCatch(getProxyBeanType(exceptionType), wantExceptionReturned);
	}

	/**
	 * @param exceptionType
	 * @param wantExceptionReturned
	 * @return
	 * @throws IllegalStateException
	 * 
	 * @since 1.1.0
	 */
	private ExpressionProxy pushTryCatch(IProxyBeanType exceptionType, boolean wantExceptionReturned) throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			popForExpression(); // Remove the root expression since try or previous catch clause is done.
			checkForExpression(TRYCATCH_EXPRESSION); // This needs to be next for it to be valid.
			pushForExpression(TRYCATCH_EXPRESSION); // Set up for a following catch/finally clause.
			pushForExpression(ForExpression.ROOTEXPRESSION); // Root expressions are next for the catch clause.

			int tryNumber = ((Integer) peek(2)).intValue(); // Get the try#. It should be in this place on the stack.

			ExpressionProxy ep = null;
			if (wantExceptionReturned)
				ep = allocateExpressionProxy(NORMAL_EXPRESSION_PROXY);
			pushTryCatchClauseToProxy(tryNumber, exceptionType, ep);

			processExpression();
			return ep;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryEnd()
	 */
	public final void createTryEnd() throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			popForExpression(); // Remove the root expression since try or previous catch clause is done.
			if (peekForExpression(TRYCATCH_EXPRESSION))
				checkForExpression(TRYCATCH_EXPRESSION); // This may of been next if no finally clause was added. If a finally clause was added this would not be here.
			checkForExpression(TRYEND_EXPRESSION); // And this needs to be after that to be valid.

			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryFinallyClause()
	 */
	public final void createTryFinallyClause() throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			popForExpression(); // Remove the root expression since try or previous catch clause is done.
			checkForExpression(TRYCATCH_EXPRESSION); // This needs to be next for it to be valid.
			pushForExpression(ForExpression.ROOTEXPRESSION); // Root expressions are next for the finally clause.

			int tryNumber = ((Integer) peek(2)).intValue(); // Get the try#. It should be in this place on the stack.

			pushTryFinallyClauseToProxy(tryNumber);
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createRethrow()
	 */
	public final void createRethrow() throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			popForExpression(); // Remove the root expression since try or previous catch clause is done.
			checkForExpression(TRYCATCH_EXPRESSION); // This needs to be next for it to be valid.
			// It is in a valid state, so put the catch and root back on so that things work correctly.
			pushForExpression(TRYCATCH_EXPRESSION);
			pushForExpression(ForExpression.ROOTEXPRESSION); 

			int tryNumber = ((Integer) peek(2)).intValue(); // Get the try#. It should be in this place on the stack.

			pushRethrowToProxy(tryNumber);
			processExpression();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createThrow()
	 */
	public final void createThrow() throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			push(InternalExpressionTypes.THROW_EXPRESSION);
			pushForExpression(PROCESS_EXPRESSION);
			pushForExpression(ForExpression.THROW_OPERAND); // The next expression must be for the throw value.
			processExpression(); 
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	
	public final int mark() throws IllegalStateException {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			++highestMarkID;
			currentMarkEntry = new MarkEntry();
			currentMarkEntry.markID = highestMarkID;
			currentMarkEntry.controlStackPos = controlStack.size() - 1;
			currentMarkEntry.nextExpressionStackPos = nextForExpressionStackPos;
			currentMarkEntry.expressionProxiesPos = expressionProxies != null ? expressionProxies.size() - 1 : -1;
			if (markEntries == null)
				markEntries = new ArrayList(5);
			markEntries.add(currentMarkEntry);
			pushMarkToProxy(highestMarkID);
			return highestMarkID;
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
	
	public void endMark(int markNumber) throws IllegalStateException {
		if (isValid()) {
			// Can only do a valid end mark if we are at root. If not at root, we fall through and treat as invalid.
			if (peekForExpression(ForExpression.ROOTEXPRESSION)) {
				checkForExpression(ForExpression.ROOTEXPRESSION);	// Now remove it if it should be removed. 
				// If the current mark number is not the same as the incoming mark number, we have improper nesting.
				if (currentMarkEntry == null || currentMarkEntry.markID != markNumber)
					throwInvalidMarkNesting();	// We have improper nesting.
				// We are popping the current mark. Since we are valid, just move up one in the mark stack.
				MarkEntry me = (MarkEntry) markEntries.remove(markEntries.size()-1);
				if (!markEntries.isEmpty())
					currentMarkEntry = (MarkEntry) markEntries.get(markEntries.size()-1);
				else
					currentMarkEntry = null;
				pushEndmarkToProxy(markNumber, false);
				if (me.controlStackPos != controlStack.size()-1 || me.nextExpressionStackPos != nextForExpressionStackPos)
					throwInvalidMarkNesting();	// The stacks should be back to the same size at this point for a valid end mark.
				return;
			}
		} 
		
		// It was invalid, or became invalid.
		if (markEntries == null)
			throwInvalidMarkNesting();	// We have no marks, so this is an invalid end mark.
		
		// We are invalid, need to pop to the given markNumber.
		// Starting from the end we search back to find the entry for the given mark number. We do it
		// from the end because it is more likely to be closer to the end than to the beginning.
		for (int i = markEntries.size()-1; i >=0; i--) {
			MarkEntry me = (MarkEntry) markEntries.get(i);
			if (me.markID == markNumber) {
				// Found it.
				// Trim the control stack down to the size at time of mark. (No easy way to do this other than repeated remove's.
				// We do it backwards to eliminate repeated shuffling of entries.
				for (int j = controlStack.size()-1; j > me.controlStackPos; j--) {
					controlStack.remove(j);
				}
				
				// Trim the expression stack. This is simple, just reset the next entry pointer.
				nextForExpressionStackPos = me.nextExpressionStackPos;
				
				if (expressionProxies != null) {
					// Now we need to mark all of the expression proxies that occured after the mark as
					// not resolved (since someone may be listening), and remove them, and reuse the proxies.
					for (int j = expressionProxies.size()-1; j > me.expressionProxiesPos; j--) {
						ExpressionProxy proxy = (ExpressionProxy) expressionProxies.remove(j);
						if (proxy != null && proxy.hasListeners())
							fireProxyNotResolved(proxy);
					}
				}
				
				// Now that we know it is valid, we want to remove all of the mark entries above it in the stack
				// since those are now invalid. We couldn't remove them as we were searching for the entry because
				// if the entry wasn't found we didn't want to wipe out the probably valid ones.
				for (int j = markEntries.size()-1; j >= i; j--) {
					markEntries.remove(j);
				}
				
				if (!markEntries.isEmpty())
					currentMarkEntry = (MarkEntry) markEntries.get(markEntries.size()-1);
				else
					currentMarkEntry = null;					
				pushEndmarkToProxy(markNumber, true);
				expressionValid = true;
				return;
			} 
		}
		throwInvalidMarkNesting();	// The mark number wasn't found, so this is an invalid end mark.
	}
	
	/**
	 * Begin the transfer of the expression to another thread.
	 * <p>
	 * This is used when the expression needs to continue to be built up, but it needs
	 * to be done on a different thread. The reason for doing something special other
	 * than just using it on the other thread is that some proxy registries connections are
	 * tied through the thread. If you switched to another thread the connections would not
	 * be properly set up.
	 * This is not on the IExpression interface because even though it is API, it is tricky
	 * to use and so not exposed to everyone. Users can legitimately cast to Expression and 
	 * use this as API for advanced use. 
	 * <p>
	 * You must be at ForExpression.ROOT_EXPRESSION.
	 * <p>
	 * This is used to begin the transfer. It puts it into a state ready for the transfer. Calling this
	 * method will cause a synchronization of the expression up to the current level. This means
	 * that it will not return until the expression has been completely processed in the proxy registry
	 * up to this point. Typically the connection is a pipe where the instructions are just pushed onto
	 * it and the caller is not held up waiting for the registry to process it. 
	 * <p>
	 * Then when the other thread is done, it will call beginTransferThread itself to signal that it is done
	 * and that the old thread can pick it up. Then the old thread will call transferThread to pick up processing.
	 * <p>
	 * It will be:
	 * <pre><code>
	 *   ... expression stuff ...
	 *   expression.beginTransferThread()
	 *   ... do what is necessary to get to the other thread ...
	 *   ... on other thread:
	 *   expression.transferThread();
	 *   try {
	 *     ... do your expression stuff on this thread ...
	 *   } finally {
	 *     expression.beginTransferThread(); // This is to return it to old thread.
	 *   }
	 *   ... tell old thread to pick up ...
	 *   ... back on old thread:
	 *   expression.transferThread();
	 *   ... do more expression stuff ...
	 *   expression.invokeExpression();
	 * </code></pre>
	 * 
	 * @throws IllegalStateException
	 * @throws ThrowableProxy Thrown if there was an exception with the remote vm during this request.
	 * @since 1.1.0
	 */
	public final void beginTransferThread() throws IllegalStateException, ThrowableProxy {
		try {
			checkForExpression(ForExpression.ROOTEXPRESSION);
			pushForExpression(THREADTRANSFER_EXPRESSION);
			pushBeginTransferThreadToProxy();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}
	}
		
	/**
	 * Transfer the expression to the current thread.
	 * <p>
	 * This is called to actually transfer to the current thread. It must be the next call against
	 * the expression after the beginTransferThread, but on the new thread.
	 * <p>
	 * This is not on the IExpression interface because even though it is API, it is tricky
	 * to use and so not exposed to everyone. Users can legitimately cast to Expression and 
	 * use this as API for advanced use. 
	 * @see Expression#beginTransferThread() for a full explanation.
	 * @throws IllegalStateException
	 * 
	 * @since 1.1.0
	 */
	public final void transferThread() throws IllegalStateException {
		try {
			checkForExpression(THREADTRANSFER_EXPRESSION);
			pushTransferThreadToProxy();
		} catch (RuntimeException e) {
			markInvalid();
			throw e;
		}		
	}
	
	
	/**
	 * Get the IProxyBeanType for the type string sent in.
	 * @param type
	 * @return
	 * 
	 * @since 1.1.0
	 */
	protected IProxyBeanType getProxyBeanType(String type) {
		return getRegistry().getBeanTypeProxyFactory().getBeanTypeProxy(this, type);
	}
	
	/**
	 * Create the expression proxy subclass that is applicable for this kind of processor. 
	 * @param proxyType type of proxy. {@link Expression#NORMAL_EXPRESSION_PROXY
	 * @param proxyID the id of the new expression proxy.
	 * 
	 * @return
	 * 
	 * @since 1.1.0
	 */
	protected abstract ExpressionProxy createExpressionProxy(int proxyType, int proxyID);
	
	/**
	 * 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
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushToProxy(IProxy proxy);

	/**
	 * Tell the other side we are complete. This will always be called after expression evaluation, or
	 * if expression was prematurely closed.
	 * <p>
	 * <b>Note:</b> The implementation must be able to handle multiple invocations, where the first call is a valid close and any
	 * subsequent call should be ignored.
	 * 
	 * @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.
	 * <p>
	 * <b>Note:</b> The expression proxies MUST be resolved (callbacks called) in the order they are found in the expressionProxies list. This
	 * is so that the contract is followed that resolution notifications will occur in the order of creation.
	 * 
	 * @param proxycount Number of Expression Proxies that need a callback.
	 * @param list of expression proxies. If proxycount > 0, then process the non-null entries in the list. They will be of type ExpressionProxy.
	 * @throws ThrowableProxy
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushInvoke(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException;
	
	/**
	 * Pull the top expression value from the evaluation stack. It will also under
	 * the covers call closeProxy.  It also must process the expression proxy callbacks. It must do the expression proxy callbacks first, and then
	 * process the result value. If an error had occured sometime during processing, it should still process the proxy callbacks before throwing
	 * an exception.
	 * <p>
	 * <b>Note:</b> The expression proxies MUST be resolved (callbacks called) in the order they are found in the expressionProxies list. This
	 * is so that the contract is followed that resolution notifications will occur in the order of creation. Also <b>REQUIRED</b> is that
	 * the entire list must be processed of proxies must be processed by this call. It cannot do some or none.
	 * 
	 * @param proxycount Number of Expression Proxies that need a callback.
	 * @param list of expression proxies. If proxycount > 0, then process the non-null entries in the list. They will be of type ExpressionProxy.
	 * @return The top level evaluation stack value.
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	protected abstract IBeanProxy pullProxyValue(int proxycount, List expressionProxies) 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. 
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushCastToProxy(IProxyBeanType type);

	/**
	 * 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.
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushInstanceofToProxy(IProxyBeanType type);
	
	/**
	 * 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.
	 * @param operandType The operand type. left, other, or last.
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushInfixToProxy(InfixOperator operator, InternalInfixOperandType operandType);
	
	/**
	 * 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 
	 * 
	 * @see IExpressionConstants#PRE_MINUS
	 * @since 1.0.0
	 */
	protected abstract void pushPrefixToProxy(PrefixOperator operator);	

	
	/**
	 * Push to proxy the array access. The result will be placed onto the evaluation stack.
	 * 
	 * @param indexCount
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushArrayAccessToProxy(int indexCount);
	
	/**
	 * Push to proxy the array creation. The result will be placed onto the evaluation stack.
	 * @param type The array type. 
	 * @param dimensionCount
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushArrayCreationToProxy(IProxyBeanType type, int dimensionCount);
	
	/**
	 * Push to proxy the array initializer. The resulting array will be placed onto the evaluation stack.
	 * @param type The array type. (must be an array type).
	 * @param stripDimCount the number of dimensions that must be stripped from the array type. This is needed
	 * because the first array initializer needs to be for the component type of the array (array minus one dimension), and
	 * each initializer after that needs one more dimension stripped off. But since we are working with possible expression
	 * proxies for "type", we can't create the appropriate component types of the array. So we need to tell the
	 * processor how many dims to strip from the original type (which is what is sent in on every initializer push, the original type).
	 * @param expressionCount
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushArrayInitializerToProxy(IProxyBeanType type, int stripDimCount, int expressionCount);
	
	/**
	 * Push to proxy the class instance creation. The resulting class instance will be placed onto the evaluation stack.
	 * 
	 * @param type Class type. 
	 * @param argumentCount The number of arguments.
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushClassInstanceCreationToProxy(IProxyBeanType type, int argumentCount);
	
	/**
	 * 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. 
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushTypeReceiverToProxy(IProxyBeanType type);

	/**
	 * Push to proxy the field access. The result value will be placed onto the evaluation stack.
	 * @param field The name of the field if string, or an IFieldProxy.
	 * @param hasReceiver Has receiver flag.
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushFieldAccessToProxy(Object field, boolean hasReceiver);
	
	/**
	 * Push to proxy the method invocation. The result value will be placed onto the evaluation stack.
	 * 
	 * @param method String for method name or IProxyMethod
	 * @param hasReceiver
	 * @param argCount
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushMethodInvocationToProxy(Object method, boolean hasReceiver, int argCount);
	
	/**
	 * 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.
	 * 
	 * @since 1.0.0
	 */
	protected abstract void pushConditionalToProxy(InternalConditionalOperandType expressionType);
	
	/**
	 * Push to the proxy the expression proxy. Whatever the last expression value is will be assigned to the ExpressionProxy.
	 * 
	 * @param proxy
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushAssignmentToProxy(ExpressionProxy proxy);
	
	/**
	 * Push the assignment expression. The operands are already on the stack.
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushAssignmentToProxy();

	
	/**
	 * Push the begin block expression. 
	 * @param blockNumber 
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushBlockBeginToProxy(int blockNumber);
	
	/**
	 * Push the end block expression.
	 * @param blockNumber
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushBlockEndToProxy(int blockNumber);

	/**
	 * Push the break block expression.
	 * @param blockNumber
	 * 
	 * @since 1.1.0
	 *
	 */
	protected abstract void pushBlockBreakToProxy(int blockNumber);
	
	/**
	 * Push the begin try expression. 
	 * @param tryNumber 
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushTryBeginToProxy(int tryNumber);

	/**
	 * Push the catch clause to proxy.
	 * @param tryNumber
	 * @param exceptionType 
	 * @param ep ExpressionProxy to be assigned with the exception or <code>null</code> if exception is not to be assigned.
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushTryCatchClauseToProxy(int tryNumber, IProxyBeanType exceptionType, ExpressionProxy ep);

	/**
	 * Push the finally clause to proxy.
	 * @param tryNumber
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushTryFinallyClauseToProxy(int tryNumber);

	/**
	 * Push try end to proxy.
	 * @param tryNumber
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushTryEndToProxy(int tryNumber);
	
	/**
	 * Push the throw of the exception to proxy.
	 * @param exception
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushThrowToProxy();
	
	/**
	 * Push a rethrow to proxy.
	 * @param tryNumber
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushRethrowToProxy(int tryNumber);

	/**
	 * Push the BeanType Expression proxy to be resolved on the execution side.
	 * @param proxy
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushBeanTypeToProxy(IBeanTypeExpressionProxy proxy);
	
	/**
	 * Push the Method Expression proxy to be resolved on the execution side.
	 * @param proxy
	 * @param declaringType
	 * @param methodName
	 * @param parameterTypes parameter types or <code>null</code> if no parameters.
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushMethodToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes);

	/**
	 * Push the Field Expression Proxy to be resolved on the execution side.
	 * @param proxy
	 * @param declaringType
	 * @param fieldName
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushFieldToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String fieldName);
	
	/**
	 * Push the If test condition to proxy.
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushIfTestToProxy();
	
	/**
	 * Push a true or else clause to proxy.
	 * @param clauseType
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushIfElseToProxy(InternalIfElseOperandType clauseType);
	
	/**
	 * Push to proxy a new instance using an initialization string.
	 * @param initializationString
	 * @param resultType
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushNewInstanceToProxy(String initializationString, IProxyBeanType resultType);
	
	/**
	 * Push the mark id to proxy.
	 * 
	 * @param markID
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushMarkToProxy(int markID);
	
	/**
	 * Push the end mark id to proxy.
	 * 
	 * @param markID
	 * @param restore <code>true</code> if this is a restore due to error, <code>false</code> if this is just a normal end mark.
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushEndmarkToProxy(int markID, boolean restore);
	
	/**
	 * Push the begin transfer thread to proxy.
	 * 
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushBeginTransferThreadToProxy() throws ThrowableProxy;
	
	/**
	 * Push the actual transfer to the current thread to proxy.
	 * 
	 * 
	 * @since 1.1.0
	 */
	protected abstract void pushTransferThreadToProxy();

}
