[82257] Batching with proxies, phase I, Swing/AWT/Base Beans.
diff --git a/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/adapters/BeaninfoProxyConstants.java b/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/adapters/BeaninfoProxyConstants.java
index 10020aa..5f86239 100644
--- a/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/adapters/BeaninfoProxyConstants.java
+++ b/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/adapters/BeaninfoProxyConstants.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: BeaninfoProxyConstants.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:44:20 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:28 $ 
  */
 package org.eclipse.jem.internal.beaninfo.adapters;
 
@@ -26,7 +26,7 @@
  */
 public final class BeaninfoProxyConstants {
 
-	private static final String REGISTRY_KEY = "org.eclipse.jem.internal.beaninfo.adapters.BeaninfoProxyConstants:"; //$NON-NLS-1$
+	private static final Object REGISTRY_KEY = new Object();
 
 	private final IMethodProxy introspectProxy;
 
diff --git a/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/core/BeanInfoCacheController.java b/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/core/BeanInfoCacheController.java
index 1520ddb..9abdb21 100644
--- a/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/core/BeanInfoCacheController.java
+++ b/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/core/BeanInfoCacheController.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: BeanInfoCacheController.java,v $
- *  $Revision: 1.7 $  $Date: 2005/05/04 15:13:15 $ 
+ *  $Revision: 1.8 $  $Date: 2005/05/11 19:01:28 $ 
  */
 package org.eclipse.jem.internal.beaninfo.core;
 
@@ -27,7 +27,6 @@
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.change.ChangeDescription;
-import org.eclipse.emf.ecore.change.ChangePackage;
 import org.eclipse.emf.ecore.change.impl.EObjectToChangesMapEntryImpl;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.resource.ResourceSet;
@@ -864,8 +863,6 @@
 		return ce;
 	}
 
-	protected static final ChangePackage CP = ChangePackage.eINSTANCE;	// TODO When emf bug 80491 if fixed.
-	
 	/**
 	 * Get the cache resource for the given java class.
 	 * <p>
@@ -890,29 +887,17 @@
 			boolean waitForJob = false;
 			synchronized (ce) {
 				if (ce.getPendingResource() != null) {
-//					// We are waiting to write it out, so just make a copy of it and use it. (After EMF bug 80547 fix is available.
-//					Resource cres = ce.getPendingOverrideResource();
-//					ResourceSet rset = cres.getResourceSet();
-//					Resource copyRes = rset.createResource(cres.getURI().appendSegment("temporary"));
-//					copyRes.getContents().addAll(EcoreUtil.copyAll(cres.getContents()));
-//					return copyRes;
-					// TODO EMF bug 80547 is available, we can simply return a copy of the resource when it is a pending resource instead of 
-					// waiting for the cache job to finish. Because then we can make a copy with no problem.
-					// Actually copy won't work because it refers directly to classes in the other project's resource set. So
-					// when loading using the copied version, it creates incorrect linkages. Need a copy that turns outside refs into proxies
-					// so when needed again they will be resolved.
-					// Need to create a special ECoreUtil.Copier that overrides copyReferences and changes any values that are not copied,
-					// i.e. came from outside the copy set, into new proxies pointing the URI of original ref value. This way it will
-					// be reresolved under the project resource set instead of the original rset. Actually only needed if resource set
-					// for ref value different resource set than ours being copied. But it doesn't buy anything to add that overhead.
-					// This should still be faster than waiting for the save to disk and then reading it back in again.
+					// We have one pending. So wait until write cache job is done, and then load it in.
+					// Note: Can't just copy the pending resource because it has references to JavaClasses
+					// and these could be in a different project (since this could be a workspace wide class).
+					// We would get the wrong java classes then when we apply it. 
 					waitForJob = true;
 					if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER))
 						BeaninfoPlugin.getPlugin().getLogger().log("Using pending class cache.", Level.FINER);
 				}
 			}
 			if (waitForJob)
-				waitForCacheSaveJob();	// This is part of the fix which can go away when 80547 is available.
+				waitForCacheSaveJob();	
 
 			try {
 				return jclass.eResource().getResourceSet().getResource(
@@ -925,45 +910,20 @@
 				return null;
 			}
 		} else {
-//			synchronized (ce) {
-//				if (ce.getPendingOverrideResource() != null) {
-//					if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER))
-//						BeaninfoPlugin.getPlugin().getLogger().log("Using pending cache.", Level.FINER);
-//
-//					// We are waiting to write it out, so just make a copy of it and use it.
-//					Resource cres = ce.getPendingOverrideResource();
-//					ResourceSet rset = cres.getResourceSet();
-//					Resource copyRes = rset.createResource(cres.getURI().appendSegment("temporary"));
-//					copyRes.getContents().addAll(EcoreUtil.copyAll(cres.getContents()));
-//					return copyRes;
-//				}
-//			}
 			boolean waitForJob = false;
 			synchronized (ce) {
-				if (ce.getPendingResource() != null) {
-//					// We are waiting to write it out, so just make a copy of it and use it. (After EMF bug 80547 fix is available.
-//					Resource cres = ce.getPendingOverrideResource();
-//					ResourceSet rset = cres.getResourceSet();
-//					Resource copyRes = rset.createResource(cres.getURI().appendSegment("temporary"));
-//					copyRes.getContents().addAll(EcoreUtil.copyAll(cres.getContents()));
-//					return copyRes;
-					// TODO EMF bug 80547 is available, we can simply return a copy of the resource when it is a pending resource instead of 
-					// waiting for the cache job to finish. Because then we can make a copy with no problem.
-					// Actually copy won't work because it refers directly to classes in the other project's resource set. So
-					// when loading using the copied version, it creates incorrect linkages. Need a copy that turns outside refs into proxies
-					// so when needed again they will be resolved.
-					// Need to create a special ECoreUtil.Copier that overrides copyReferences and changes any values that are not copied,
-					// i.e. came from outside the copy set, into new proxies pointing the URI of original ref value. This way it will
-					// be reresolved under the project resource set instead of the original rset. Actually only needed if resource set
-					// for ref value different resource set than ours being copied. But it doesn't buy anything to add that overhead.
-					// This should still be faster than waiting for the save to disk and then reading it back in again.
+				if (ce.getPendingOverrideResource() != null) {
+					// We have one pending. So wait until write cache job is done, and then load it in.
+					// Note: Can't just copy the pending resource because it has references to JavaClasses
+					// and these could be in a different project (since this could be a workspace wide class).
+					// We would get the wrong java classes then when we apply it. 
 					waitForJob = true;
 					if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER))
 						BeaninfoPlugin.getPlugin().getLogger().log("Using pending override cache.", Level.FINER);
 				}
 			}
 			if (waitForJob)
-				waitForCacheSaveJob();	// This is part of the fix which can go away when 80547 is available.
+				waitForCacheSaveJob();	
 
 			try {
 				return jclass.eResource().getResourceSet().getResource(
@@ -1395,8 +1355,7 @@
 	static {
 		SAVE_CACHE_OPTIONS = new HashMap(3);
 		SAVE_CACHE_OPTIONS.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, Boolean.TRUE);
-		//	SAVE_CACHE_OPTIONS.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
-		// TODO when we step up to EMF 2.1, bug 80502 should fix this.
+		SAVE_CACHE_OPTIONS.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
         SAVE_CACHE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8");
 	}
 
diff --git a/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/impl/PropertyDecoratorImpl.java b/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/impl/PropertyDecoratorImpl.java
index 4d1cf5b..57d46a8 100644
--- a/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/impl/PropertyDecoratorImpl.java
+++ b/plugins/org.eclipse.jem.beaninfo/beaninfo/org/eclipse/jem/internal/beaninfo/impl/PropertyDecoratorImpl.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.beaninfo.impl;
 /*
  *  $RCSfile: PropertyDecoratorImpl.java,v $
- *  $Revision: 1.11 $  $Date: 2005/04/14 19:05:36 $ 
+ *  $Revision: 1.12 $  $Date: 2005/05/11 19:01:28 $ 
  */
 
 
@@ -1148,14 +1148,14 @@
 	 * @see org.eclipse.jem.internal.beaninfo.PropertyDecorator#isWriteable()
 	 */
 	public boolean isWriteable() {
-		return !(getWriteMethod() == null && getField() == null);
+		return getWriteMethod() != null || (getField() != null && !isFieldReadOnly()); 
 	}
 	
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.beaninfo.PropertyDecorator#isReadable()
 	 */
 	public boolean isReadable() {
-		return !(getReadMethod() == null && getField() == null);
+		return getReadMethod() != null || getField() != null;
 	}
 	
 
diff --git a/plugins/org.eclipse.jem.proxy/.options b/plugins/org.eclipse.jem.proxy/.options
index 699ac69..95c080f 100644
--- a/plugins/org.eclipse.jem.proxy/.options
+++ b/plugins/org.eclipse.jem.proxy/.options
@@ -2,6 +2,8 @@
 org.eclipse.jem.proxy/remote/debug/ioconsole=false
 org.eclipse.jem.proxy/remote/debug/vmtraceout=false
 org.eclipse.jem.proxy/remote/debug/notimeouts=false
+org.eclipse.jem.proxy/debug/traceexpressions=false
+org.eclipse.jem.proxy/debug/traceexpressionstimethreshold=100
 org.eclipse.jem.proxy/debug/logtrace=default
 org.eclipse.jem.proxy/debug/logtracefile=default
 org.eclipse.jem.proxy/debug/loglevel=default
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/InitializationStringEvaluationException.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/InitializationStringEvaluationException.java
index e3dfbfc..8844fb6 100644
--- a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/InitializationStringEvaluationException.java
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/InitializationStringEvaluationException.java
@@ -11,19 +11,18 @@
  *******************************************************************************/
 /*
  *  $RCSfile: InitializationStringEvaluationException.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:55:20 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
 
 public class InitializationStringEvaluationException extends Exception {
 	
-	protected Throwable originalException;
 	
 public InitializationStringEvaluationException(Throwable exc){
-	originalException = exc;
+	super(exc);
 }
 public Throwable getOriginalException(){
-	return originalException;
+	return getCause();
 }
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/AbstractEnum.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/AbstractEnum.java
new file mode 100644
index 0000000..010b0bc
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/AbstractEnum.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: AbstractEnum.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+
+/**
+ * Base abstract implementation of the enum.
+ * @since 1.1.0
+ */
+public abstract class AbstractEnum implements Enum {
+
+	/**
+	 * The name of the enumerator.
+	 */
+	private final String name;
+
+	/**
+	 * The <code>int</code> value of the enumerator.
+	 */
+	private final int value;
+
+	/**
+	 * Creates an initialized instance.
+	 * 
+	 * @param value
+	 *            the <code>int</code> value of the enumerator.
+	 * @param name
+	 *            the name of the enumerator.
+	 */
+	protected AbstractEnum(int value, String name) {
+		this.name = name;
+		this.value = value;
+	}
+
+	/**
+	 * Returns the name of the enumerator.
+	 * 
+	 * @return the name.
+	 */
+	public final String getName() {
+		return name;
+	}
+
+	/**
+	 * Returns the <code>int</code> value of the enumerator.
+	 * 
+	 * @return the value.
+	 */
+	public final int getValue() {
+		return value;
+	}
+
+	/**
+	 * Returns the name of the enumerator.
+	 * 
+	 * @return the name.
+	 */
+	public final String toString() {
+		return name;
+	}
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/Enum.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/Enum.java
new file mode 100644
index 0000000..7d2fb3e
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/Enum.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: Enum.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+
+/**
+ * TypeSafe enumerations for the IExpression processing.
+ * 
+ * @since 1.1.0
+ */
+public interface Enum {
+
+	/**
+	 * Returns the name of the enumerator.
+	 * 
+	 * @return the name.
+	 */
+	String getName();
+
+	/**
+	 * Returns the <code>int</code> value of the enumerator.
+	 * 
+	 * @return the value.
+	 */
+	int getValue();
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/ExpressionProcesser.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/ExpressionProcesser.java
index 82e969d..4def2a7 100644
--- a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/ExpressionProcesser.java
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/ExpressionProcesser.java
@@ -10,20 +10,19 @@
  *******************************************************************************/
 /*
  *  $RCSfile: ExpressionProcesser.java,v $
- *  $Revision: 1.7 $  $Date: 2005/02/16 14:38:04 $ 
+ *  $Revision: 1.8 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.initParser.tree;
 
 import java.lang.reflect.*;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.List;
 
 import org.eclipse.jem.internal.proxy.common.AmbiguousMethodException;
 import org.eclipse.jem.internal.proxy.common.MethodHelper;
-import org.eclipse.jem.internal.proxy.initParser.EvaluationException;
-import org.eclipse.jem.internal.proxy.initParser.tree.IExpressionConstants.NoExpressionValueException;
+import org.eclipse.jem.internal.proxy.initParser.InitializationStringEvaluationException;
+import org.eclipse.jem.internal.proxy.initParser.InitializationStringParser;
  
 /**
  * Expression processing. This does the actual expression processing with the live objects.
@@ -36,6 +35,145 @@
 public class ExpressionProcesser {
 
 	/**
+	 * A variable reference for a field access.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected static class FieldAccessReference extends VariableReference {
+		
+		private final Field field;
+		private final Object receiver;
+
+		/**
+		 * Use this to construct a FieldAccessReference. This will do checks to make sure
+		 * it is valid so that exceptions won't be thrown later when actually dereferenced.
+		 * 
+		 * @param field
+		 * @param receiver
+		 * @return
+		 * @throws IllegalArgumentException
+		 * 
+		 * @since 1.1.0
+		 */
+		public static FieldAccessReference createFieldAccessReference(Field field, Object receiver) throws IllegalArgumentException {
+			// If static, then receiver is ignored.
+			if (!Modifier.isStatic(field.getModifiers())) {
+				if (!field.getDeclaringClass().isInstance(receiver))
+					throw new IllegalArgumentException("Field receiver does not match the type of the field: Field: "+field.getType()+" receiver: "+(receiver!=null ? receiver.getClass() : null));
+			}
+			field.setAccessible(true);	// Make it always accessible. Trust it. 
+			return new FieldAccessReference(field, receiver);
+		}
+		
+		protected FieldAccessReference(Field field, Object receiver) {
+			this.field = field;
+			this.receiver = receiver;
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.ExpressionProcesser.VariableReference#dereference()
+		 */
+		public Object dereference() {
+			try {
+				return field.get(receiver);
+			} catch (IllegalArgumentException e) {
+				// Shouldn't occur. Already tested for this.
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				// Shouldn't occur. Already tested for this.
+				e.printStackTrace();
+			}
+			return null;
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.ExpressionProcesser.VariableReference#set(java.lang.Object, java.lang.Class)
+		 */
+		public Object set(Object value, Class type) throws IllegalArgumentException, IllegalAccessException {
+			field.set(receiver, value);
+			return field.get(receiver);	// Just in case some conversion happened. Technically it is not the value set but the retrieved when in an assignment.
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see java.lang.Object#toString()
+		 */
+		public String toString() {
+			return "FieldAccess{"+field.toString()+"} on "+receiver.toString();
+		}
+	}
+	
+	/**
+	 * A variable reference for an Array access. It will reference only the last indexed entry of the array.
+	 * For example if <code>x[3][4]</code> is the access, then what will be given to this reference will be
+	 * the array entry at x[3][4], not the x array itself.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected static class ArrayAccessReference extends VariableReference {
+		
+		
+		private final Object array;
+		private final int index;
+
+		/**
+		 * Use this to construct an array access reference. This will do checks to make sure
+		 * it is valid so that exceptions won't be thrown later when actually dereferenced.
+		 * 
+		 * @param array
+		 * @param index
+		 * @return
+		 * @throws IllegalArgumentException
+		 * 
+		 * @since 1.1.0
+		 */
+		public static ArrayAccessReference createArrayAccessReference(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+			int len = Array.getLength(array);
+			if (index < 0 || len <= index)
+				throw new ArrayIndexOutOfBoundsException("Index: "+index+" size:"+len);
+			return new ArrayAccessReference(array, index);
+		}
+		/**
+		 * Construct the reference with the array and the index of the entry being referenced.
+		 * @param array
+		 * @param index
+		 * 
+		 * @since 1.1.0
+		 */
+		protected ArrayAccessReference(Object array, int index) {
+			this.array = array;
+			this.index = index;
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.VariableReference#dereference()
+		 */
+		public Object dereference() {
+			return Array.get(array, index);
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.VariableReference#set(java.lang.Object, java.lang.Class)
+		 */
+		public Object set(Object value, Class type) throws IllegalArgumentException {
+			Array.set(array, index, value);
+			return Array.get(array, index);	// In case there was some conversion applied. Technically it is not the value set but the retrieved when in an assignment.
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see java.lang.Object#toString()
+		 */
+		public String toString() {
+			return "ArrayAccess["+index+"]: "+array.toString();
+		}
+	}
+	
+	/**
 	 * The expression result stack and the expression result type stack.
 	 * The type stack is used to be expected type of the corresponding
 	 * expression result. This is needed for converting to primitives
@@ -64,10 +202,112 @@
 	 * 
 	 * @see org.eclipse.jem.internal.proxy.initParser.MethodHelper#NULL_TYPE
 	 */
-	private ArrayList expressionStack = new ArrayList(10);
-	private ArrayList expressionTypeStack = new ArrayList(10);
+	private List expressionStack = new ArrayList(10);
+	private List expressionTypeStack = new ArrayList(10);
 	
 	/**
+	 * List of the expression proxies. The index into the list is the
+	 * same as the expression proxy id. 
+	 */
+	private ArrayList expressionProxies;	// It is array list because we want to call ensureCapacity and that is not available on List.
+	
+	/**
+	 * An error has occurred. At this point all subcommands will simply make sure they flush the input stream
+	 * correctly, but they do not process it.
+	 * 
+	 * @since 1.0.0
+	 */
+	private boolean errorOccurred = false;
+	private boolean novalueException = false;
+	
+	private Throwable exception = null;	// Was there another kind of exception that was caught.
+	
+	/**
+	 * Process all other exceptions then the NoExpressionValueException. This can be called from usage code so that if there was an error
+	 * in setting up for a call to the processer it can be logged.
+	 * 
+	 * @param e
+	 * 
+	 * @since 1.0.0
+	 */
+	public final void processException(Throwable e) {
+		// Process all other exceptions.
+		novalueException = false;
+		while (e.getCause() != null)
+			e = e.getCause();
+		if (traceOn) {
+			System.out.println();
+			System.out.print("***** >>>\tException: ");
+			System.out.println(e);
+		}
+		throwException(e);	// Treat as a throw to let try/catches expressions handle it.
+	}
+	
+	/**
+	 * This is a syntax exception. This means data coming across is corrupted in
+	 * some way so no further processing should occur. 
+	 * @param e
+	 * 
+	 * @since 1.1.0
+	 */
+	protected final void processSyntaxException(Throwable e) {
+		errorOccurred = true;
+		novalueException = false;
+		exception = e;		
+	}
+		
+	/**
+	 * Process a NoExpressionValueException. Don't wrapper these.
+	 * @param e
+	 * 
+	 * @since 1.1.0
+	 */
+	protected final void processSyntaxException(NoExpressionValueException e) {
+		if (traceOn)
+			printTrace("Expression has no value", false);
+		try {
+			errorOccurred = true;
+			novalueException = true;
+			exception = e;
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+	}
+	
+	/**
+	 * Return whether there are any errors.
+	 * 
+	 * @return <code>true</code> if no errors.
+	 * 
+	 * @since 1.0.0
+	 */
+	public boolean noErrors() {
+		return !errorOccurred;
+	}
+	
+	/**
+	 * Return whether the error is a NoExpressionValueException or not.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean isNoExpressionValue() {
+		return novalueException;
+	}
+	
+	/**
+	 * Return the throwable if a Throwable was caught.
+	 * 
+	 * @return The throwable, or <code>null</code> if not set.
+	 * 
+	 * @since 1.0.0
+	 */
+	public Throwable getErrorThrowable() {
+		return exception;
+	}
+
+	/**
 	 * Push the expression value and its expected type.
 	 * @param o
 	 * @param type
@@ -78,20 +318,39 @@
 		expressionStack.add(o);
 		expressionTypeStack.add(type);
 	}
+
+	/**
+	 * Pop just the expression value. It is imperitive that the expression type
+	 * is popped immediately following. Separated the methods so that we
+	 * don't need to create an array to return two values. This will dereference
+	 * any variable references.
+	 * 
+	 * @return The value.
+	 * @throws NoExpressionValueException
+	 * 
+	 * @since 1.0.0
+	 */
+	protected final Object popExpression() throws NoExpressionValueException {
+		return popExpression(true);
+	}
 	
 	/**
 	 * Pop just the expression value. It is imperitive that the expression type
 	 * is popped immediately following. Separated the methods so that we
 	 * don't need to create an array to return two values.
 	 * 
+	 * @param deReference If the top expression is a Reference, then dereference it.
 	 * @return The value.
-	 * @throws ThrowableProxy
+	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	protected final Object popExpression() throws NoExpressionValueException {
+	protected final Object popExpression(boolean deReference) throws NoExpressionValueException {
 		try {
-			return expressionStack.remove(expressionStack.size()-1);
+			Object result = expressionStack.remove(expressionStack.size()-1);
+			if (deReference && result instanceof VariableReference)
+				result = ((VariableReference) result).dereference();
+			return result;
 		} catch (IndexOutOfBoundsException e) {
 			throw new NoExpressionValueException();
 		}
@@ -106,6 +365,8 @@
 	 * <p>
 	 * When done, <code>popExpressions(int count)</code> must be called to
 	 * clean them out since they were processed.
+	 * <p>
+	 * This will not dereference the expression. It is the job of the caller to do this. 
 	 *  
 	 * @param fromTop <code>1</code> is the top one, <code>2</code> is the next one down.
 	 * @return The entry from the top that was requested.
@@ -123,7 +384,8 @@
 	}
 	
 	/**
-	 * Remove the top <code>count</code> items.
+	 * Remove the top <code>count</code> items. This will not cause dereferencing to occur. It
+	 * removes the corresponding type stack entries.
 	 * 
 	 * @param count
 	 * @throws NoExpressionValueException
@@ -133,8 +395,10 @@
 	protected final void popExpressions(int count) throws NoExpressionValueException {
 		try {
 			int remove = expressionStack.size()-1;
-			while (count-- > 0)
-				expressionStack.remove(remove--);
+			while (count-- > 0) {
+				expressionStack.remove(remove);
+				expressionTypeStack.remove(remove--);
+			}
 		} catch (IndexOutOfBoundsException e) {
 			throw new NoExpressionValueException();
 		}
@@ -152,7 +416,6 @@
 	 * 
 	 * @param allowVoid Allow void types if <code>true</code>
 	 * @return The type.
-	 * @throws ThrowableProxy
 	 * @throws NoExpressionValueException
 	 * @since 1.0.0
 	 */
@@ -160,7 +423,7 @@
 		try {
 			Class result = (Class) expressionTypeStack.remove(expressionTypeStack.size()-1);
 			if (!allowVoid && result == Void.TYPE)
-				throw new NoExpressionValueException();
+				throw new NoExpressionValueException("Expression was void.");
 			return result;
 				
 		} catch (IndexOutOfBoundsException e) {
@@ -199,46 +462,159 @@
 	}
 	
 	/**
-	 * Remove the top <code>count</code> items.
-	 * 
-	 * @param count
-	 * @throws NoExpressionValueException
-	 * 
-	 * @since 1.0.0
-	 */
-	protected final void popExpressionTypes(int count) throws NoExpressionValueException {
-		try {
-			int remove = expressionTypeStack.size()-1;
-			while (count-- > 0)
-				expressionTypeStack.remove(remove--);
-		} catch (IndexOutOfBoundsException e) {
-			throw new NoExpressionValueException();
-		}
-	}
-	
-	/**
 	 * Flag indicating expression should be ignored and not processed.
 	 * This happens because of few cases, like conditional and, that
 	 * if one returns false, the rest of the expressions in that conditional and
 	 * expression should be ignored and not processed.
 	 * <p>
-	 * It is an int so that those expressions that can initiate an ignore can 
-	 * know if it is thiers or not. Only when it decrements to zero will ignore
-	 * be over. Those expressions that can start an ignore must increment the
-	 * ignore counter if the ignore counter is on, but ignore the expression,
-	 * and decrement it when they are complete.
+	 * It is an Object that acts as an enum for the type of expression that initiated the ignore. 
+	 * If it is <code>null</code> then no one is ignoring. 
 	 * <p>
 	 * All of the pushTo...Proxy methods must test this for this to work correctly.
+	 * Each expression has some way of testing that their particular nesting of 
+	 * expressions is complete and they can turn off the ignore flag.
+	 * <p>
+	 * Only one type of ignore can exist at a time.
 	 */
-	protected int ignoreExpression = 0;	
+	protected Object ignoreExpression = null;	
+	
+	
+	private List saveStates;
 	
 	/**
-	 * Create the IDEExpression
+	 * Are we tracing or not.
+	 */
+	protected final boolean traceOn;
+	private final long thresholdTime;
+	private long startExpressionStepTime;
+	private long startExpressionTime;
+	private long lastExpressionEndTime;
+	
+	/**
+	 * Trace head of this expression. So that traces from different expressions can be distinquished.
+	 * It is simply an monotonically increasing counter. It is the header string for any trace output.
+	 */
+	protected final String traceHeader;
+	
+	private int indent = 0;	// Indented for certain block expressions.
+	
+	/*
+	 * Trace counter. It is incremented once for each expression and assigned to the traceId of the expression.
+	 */
+	private static int TRACE_COUNTER;
+	
+	/**
+	 * Create the Expression without tracing.
 	 * @param registry
 	 * 
 	 * @since 1.0.0
 	 */
 	public ExpressionProcesser() {
+		this(false, -1);
+	}
+	
+	/**
+	 * Create the expression, and set the tracing mode and threshold time. Use -1
+	 * for default time of 100ms.
+	 * @param traceOn
+	 * 
+	 * @since 1.1.0
+	 */
+	public ExpressionProcesser(boolean traceOn, long threshold) {
+		this.traceOn = traceOn;
+		if (traceOn) {
+			traceHeader = "**"+(++TRACE_COUNTER)+':';
+			System.out.print(traceHeader);
+			System.out.println(" Start expression");
+			this.thresholdTime = threshold != -1 ? threshold : 100;
+			lastExpressionEndTime = startExpressionTime = System.currentTimeMillis();
+		} else {
+			traceHeader = null;
+			thresholdTime = 100;
+		}
+	}
+	
+	/**
+	 * Trace msg helper. Should only be called if traceOn is true. This method is only used to start a new trace message.
+	 * The caller is must call printTraceEnd at the end.
+	 *  
+	 * @param msg message to print
+	 * @param ignore are we ignoring the expression, or is it being processed (this just alters the trace output slightly).
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void printTrace(String msg, boolean ignore) {
+		startExpressionStepTime = System.currentTimeMillis();
+		long sinceLastExpression = startExpressionStepTime - lastExpressionEndTime;
+		System.out.print(traceHeader);
+		if (sinceLastExpression > 0) {
+			System.out.print('(');
+			if (sinceLastExpression > thresholdTime)
+				System.out.print("***");
+			System.out.print(sinceLastExpression);
+			System.out.print("ms)");
+		}
+		System.out.print('\t');
+		if (!ignore)
+			System.out.print("\t");
+		else
+			System.out.print("##\t");
+		
+		printIndent();
+		System.out.print(msg);
+	}
+	
+	/**
+	 * print the indent. It will not do a new line before nor after.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void printIndent() {
+		for(int i=indent; i>0; i--) {
+			System.out.print("  ");
+		}
+	}
+
+	protected void printTraceEnd() {
+		long stop = System.currentTimeMillis()-startExpressionStepTime;
+		if (stop > 0) {
+			System.out.print(" (");
+			if (stop > thresholdTime)
+				System.out.print("***");
+			System.out.print(stop);
+			System.out.print("ms)");
+		}
+		System.out.println();
+		lastExpressionEndTime = System.currentTimeMillis();
+	}
+	
+	/**
+	 * Do an indent (undent) according to indent flag.
+	 * @param indent <code>true</code> to increment indent, or otherwise decrement.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void indent(boolean indent) {
+		this.indent += (indent ? 1 : -1);
+		if (this.indent < 0)
+			this.indent = 0;
+	}
+	
+	/**
+	 * Print the object and type. It will not end with a newline char, so one will be needed afterwards.
+	 * 
+	 * @param o
+	 * @param t
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void printObjectAndType(Object o, Class t) {
+		System.out.print(' ');
+		System.out.print("Object-");
+		System.out.print(o);
+		System.out.print(" Type-");
+		System.out.print(t);
+		System.out.print(' ');
 	}
 	
 	/**
@@ -247,8 +623,25 @@
 	 * @since 1.0.0
 	 */
 	public final void close() {
-		expressionStack.clear();
-		expressionTypeStack.clear();
+		boolean firstClose = expressionStack != null;
+		if (firstClose && traceOn) {
+			printTrace("End expression", false);
+			long totalTime = System.currentTimeMillis()-startExpressionTime;
+			System.out.print(" Total expression evaluation time: ");
+			System.out.print(totalTime);
+			System.out.print("ms.");
+		}
+		try {
+			expressionStack = null;
+			expressionTypeStack = null;
+			expressionProxies = null;
+			exception = null;
+			catchThrowable = null;
+			saveStates = null;
+		} finally {
+			if (firstClose && traceOn)
+				printTraceEnd();
+		}
 	}
 
 	/**
@@ -257,16 +650,108 @@
 	 * 
 	 * @param value The value array to store the value and type into.
 	 * @throws NoExpressionValueException
-	 * 
 	 * @since 1.0.0
 	 */
 	public final void pullValue(Object[] value) throws NoExpressionValueException {
-		value[0] = popExpression();
-		value[1] = popExpressionType(false);
+		if (traceOn)
+			printTrace("Pull value:", false);
+		try {
+			value[0] = popExpression();
+			value[1] = popExpressionType(false);
+		} finally {
+			if (traceOn) {
+				printObjectAndType(value[0], (Class) value[1]);
+				printTraceEnd();
+			}
+		}
 		close();
 	}
 	
 	/**
+	 * Pull the value of the expression proxy, dereferencing it if necessary. This is for resolution only purposes at the
+	 * end of the expression being processed. Not meant for general access to the value of expression proxy. Use 
+	 * {@link ExpressionProcesser#getExpressionProxyValue(int, Object[])} instead for general access to the value.
+	 * 
+	 * @param proxyid
+	 * @param value
+	 * @throws NoExpressionValueException
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pullExpressionProxyValue(int proxyid, Object[] value) throws NoExpressionValueException {
+		getExpressionProxyValue(proxyid, value, true, true);
+	}
+	
+	/**
+	 * Get the expression proxy value. If the expression has not yet been evaluated it will
+	 * return false. If it has it will return true.
+	 * @param proxyid
+	 * @param value put value into value[0] and the type into value[1].
+	 * @return <code>true</code> if successful, or <code>false</code> if the expression proxy was never resolved or doesn't exist.
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean getExpressionProxyValue(int proxyid, Object[] value) {
+		try {
+			return getExpressionProxyValue(proxyid, value, true, false);
+		} catch (NoExpressionValueException e) {
+			return false;
+		}
+	}
+	
+	/*
+	 * Internal method use to actually get the value, but to distinquish between pull and get of the public interface.
+	 * Get will process the errors as normal execution errors, while pull will throw the errors. finalTrace is when
+	 * this is the final call to return the values to the client. We will trace the results in that case.
+	 * Return true if successful.
+	 */
+	private boolean getExpressionProxyValue(int proxyid, Object[] value, boolean pull, boolean finalTrace) throws NoExpressionValueException {
+		// Note: This will throw the exceptions right away since this is called from outside to fill in the value and
+		// so we are holding such exceptions.
+		boolean doTrace = finalTrace && traceOn;
+		try {
+			if (expressionProxies != null && expressionProxies.size() > proxyid) {
+				InternalExpressionProxy proxy = (InternalExpressionProxy) expressionProxies.get(proxyid);
+				if (proxy != null && proxy.isSet()) {
+					value[0] = proxy.getValue();
+					if (value[0] instanceof VariableReference)
+						value[0] = ((VariableReference) value[0]).dereference(); // Here we want the final current value.
+					value[1] = proxy.getType();
+					if (doTrace)
+						if (value[1] != Void.TYPE) {
+							printTrace("Return Proxy #" + proxyid + " Resolved to", false);
+							printObjectAndType(value[0], (Class) value[1]);
+						} else
+							printTrace("Return Proxy #" + proxyid + " Resolved to void.", false);
+					return true;
+
+				} else {
+					if (doTrace)
+						printTrace("Return Proxy #" + proxyid + ": Not resolved", false);
+					NoExpressionValueException e = new NoExpressionValueException("Expression Proxy never set.");
+					if (pull)
+						throw e;
+					else
+						processSyntaxException(e);
+					return false;
+				}
+			} else {
+				if (doTrace)
+					printTrace("Return Proxy #" + proxyid + ": Never created.", false);
+				NoExpressionValueException e = new NoExpressionValueException("Expression proxy doesn't exist.");
+				if (pull)
+					throw e;
+				else
+					processSyntaxException(e);
+				return false;
+			}
+		} finally {
+			if (doTrace)
+				printTraceEnd();
+		}
+	}
+	
+	/**
 	 * Push the expression (just a value) onto the stack.
 	 * 
 	 * @param o
@@ -275,28 +760,81 @@
 	 * @since 1.0.0
 	 */
 	public final void pushExpression(Object o, Class t) {
-		if (ignoreExpression>0)
-			return;
-		pushExpressionValue(o, t);
+		boolean ignore = (ignoreExpression != null || errorOccurred);
+		if (traceOn) {
+			printTrace("Push: ", ignore);
+			printObjectAndType(o, t);
+		}
+		try {
+			if (ignore)
+				return;
+			pushExpressionValue(o, t);
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+	}
+	
+	/**
+	 * Get the value of the expression proxy (from proxy id), and push the value onto the stack.
+	 *  
+	 * @param proxyid The proxy id of the ExpressionProxy to push as a value.
+	 * 
+	 * @since 1.0.0
+	 */
+	public final void pushExpressionProxy(int proxyid) {
+		boolean ignore =(ignoreExpression != null || errorOccurred);
+		if (traceOn)
+			printTrace("Push Expression Proxy #"+proxyid, ignore);
+		try {
+			if (ignore)
+				return;
+			if (expressionProxies != null && expressionProxies.size() > proxyid) {
+				InternalExpressionProxy proxy = (InternalExpressionProxy) expressionProxies.get(proxyid);
+				if (proxy != null && proxy.isSet()) {
+					if (traceOn)
+						printObjectAndType(proxy.getValue(), proxy.getType());
+					pushExpressionValue(proxy.getValue(), proxy.getType());	// Can push a VariableReference. This is ok. When used it will then deref with the current value.
+				} else
+					processSyntaxException(new NoExpressionValueException());
+			} else
+				processSyntaxException(new NoExpressionValueException());
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
 	}
 	
 	/**
 	 * Push a cast onto stack. The type passed in is either a String (with classname to cast to) or the
 	 * type to cast to.
 	 * @param type To cast to. If <code>String</code> then convert to type (using something like <code>Class.forName()</code>) or it is a Class
-	 * @throws NoExpressionValueException
-	 * @throws ClassCastException
 	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushCast(Class type) throws NoExpressionValueException, ClassCastException {
-		if (ignoreExpression>0)
-			return;
-		
-		Object exp = popExpression();
-		Class exptype = popExpressionType(false);
-		
-		pushExpressionValue(castBean(type, exp, exptype), type);
+	public final void pushCast(Class type) {
+		boolean ignore = (ignoreExpression != null || errorOccurred);
+		if (traceOn)
+			printTrace("Cast to: "+type, ignore);
+		try {
+			if (ignore)
+				return;
+			
+			try {
+				Object exp = popExpression();
+				Class exptype = popExpressionType(false);
+				
+				pushExpressionValue(castBean(type, exp, exptype), type);
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+			
 	}
 	
 	/**
@@ -308,6 +846,9 @@
 	 * <p>
 	 * However if can't be cast for primitive or if not an instance of the
 	 * returntype for objects, a ClassCastException will be raised.
+	 * <p>
+	 * This is a helper method for expression processer to cast a bean. Since it is a helper method it doesn't
+	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
 	 * 
 	 * @param returnType
 	 * @param bean
@@ -410,12 +951,17 @@
 
 	/**
 	 * Return the primitive type that the wrapper bean represents (i.e. Boolean instance returns Boolean.TYPE) 
+	 * <p>
+	 * This is a helper method for expression processer to get the primitive type. Since it is a helper method it doesn't
+	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
+
 	 * @param bean
-	 * @return
+	 * @return the primitive type class of the given bean.
+	 * @throws IllegalArgumentException if bean is <code>null</code> or not of the type that can be converted to a primitive.
 	 * 
 	 * @since 1.0.0
 	 */
-	protected final Class getPrimitiveType(Object bean) {
+	protected final Class getPrimitiveType(Object bean) throws IllegalArgumentException {
 		if (bean instanceof Boolean)
 			return Boolean.TYPE;
 		else if (bean instanceof Integer)
@@ -436,29 +982,176 @@
 			throw new IllegalArgumentException(bean != null ? bean.getClass().getName() : "null"); //$NON-NLS-1$
 	}
 	
+	private static final Object IFELSE_IGNORE = "IF/ELSE IGNORE";	// Flag for if/else in ingore
+	private int ifElseNesting = 0;	// Nesting of if/else expressions.
+	private int ifElseIgnoreNestCount = 0;	// When ignoring if/else expressions, ignore until this nest count.
+	private boolean ifElseSkipTruePart;
+
+	
+	/**
+	 * Push an if test expression.
+	 * @param hasElseClause
+	 * 
+	 * @since 1.0.0
+	 */
+	public final void pushIfElse() {
+		try {
+			boolean ignore = true;
+			try {
+				if (errorOccurred)
+					return;
+				// Slightly different here in that if an ignoring occurred we still need to process at least part of it so that
+				// we can get the expression grouping correct.
+				ifElseNesting++;	// We have the test.
+	
+				if (ignoreExpression != null)
+					return;
+				ignore = false;
+			} finally {
+				if (traceOn)
+					printTrace("If test condition", ignore);
+			}
+					
+			try {
+				Object condition = popExpression();
+				Class type = popExpressionType(false);
+				if (type != Boolean.TYPE)
+					throwClassCast(Boolean.TYPE, condition);
+				if (traceOn) {
+					System.out.print(" Test Result="+condition);
+					printTraceEnd();
+					indent(true);
+					printTrace("Begin True Expression.", ignore);
+					printTraceEnd();
+					indent(true);
+				}				
+				if (((Boolean) condition).booleanValue()) {
+					// Condition was true.
+					// Do nothing. Let true condition be processed.
+				} else {
+					// Condition was false.
+					ifElseSkipTruePart = true;	// Tell the true condition should be ignored.
+					ignoreExpression = IFELSE_IGNORE;
+					ifElseIgnoreNestCount = ifElseNesting;
+				}
+				// We don't put anything back on the stack because the condition test is not ever returned.
+				// The appropriate true or false condition evaluation will be left on the stack.
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+	}
+
+	/**
+	 * Push an if/else clause. It can be any clause of the if (true, or false clause).
+	 * @param clauseType
+	 * 
+	 * @since 1.0.0
+	 */
+	public final void pushIfElse(InternalIfElseOperandType clauseType) {
+		try {
+			boolean ignore = true;
+			if (errorOccurred)
+				return;
+			// Slightly different here in that if an ignoring occurred we still need to process at least part of it so that
+			// we can get the expression grouping correct.
+			switch (clauseType.getValue()) {
+			case InternalIfElseOperandType.TRUE_CLAUSE_VALUE:
+					if (traceOn) {
+						indent(false);
+						printTrace("Begin False Expression.", ignore);
+						printTraceEnd();
+						indent(true);
+					}
+					if (ifElseSkipTruePart && ignoreExpression == IFELSE_IGNORE && ifElseIgnoreNestCount == ifElseNesting) {
+						// stop ignoring, we've ignored the true condition of interest.
+						ignoreExpression = null;
+						return; // However, leave because since this condition was ignored.
+					}
+					break;
+				case InternalIfElseOperandType.ELSE_CLAUSE_VALUE:
+					if (traceOn) {
+						indent(false);
+						indent(false);
+						printTrace("End IF/ELSE Expression.", ignore);
+						printTraceEnd();
+					}					
+					int currentNesting = ifElseNesting--;
+					if (ignoreExpression == IFELSE_IGNORE && ifElseIgnoreNestCount == currentNesting) {
+						// stop ignoring, we've ignored the false condition of interest.
+						ignoreExpression = null;
+						return; // However, leave because since this condition was ignored.
+					}
+			}
+	
+				if (ignoreExpression != null)
+					return;
+				ignore = false;
+
+					
+			try {
+				switch (clauseType.getValue()) {
+					case InternalIfElseOperandType.TRUE_CLAUSE_VALUE:
+						ifElseSkipTruePart = false;	// Tell the false condition should be ignored.
+						ignoreExpression = IFELSE_IGNORE;
+						ifElseIgnoreNestCount = ifElseNesting;
+						break;
+					case InternalIfElseOperandType.ELSE_CLAUSE_VALUE:
+						// There's nothing to do, if it was ignored due to true, we wouldn't of gotton here.
+						// If it wasn't ignored, then the result of the false expression is on the stack, which is what it should be.
+						break;
+				}
+			} catch (RuntimeException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+	}
 
 	/**
 	 * Push the instanceof expression.  The type passed in is either a String (with classname to test against) or the
 	 * type to test against.
 	 * @param type To test against.
-	 * @throws NoExpressionValueException
-	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushInstanceof(Class type) throws NoExpressionValueException {
-		if (ignoreExpression>0)
-			return;
-		
-		Object exp = popExpression();
-		Class exptype = popExpressionType(false);
-		pushExpressionValue(isInstance(type, exp, exptype) ? Boolean.TRUE : Boolean.FALSE, Boolean.TYPE);
+	public final void pushInstanceof(Class type) {
+		boolean ignore = (ignoreExpression != null || errorOccurred);
+		if (traceOn)
+			printTrace("Instanceof type: "+type, ignore);
+		try {
+			if (ignore)
+				return;
+			
+			try {
+				Object exp = popExpression();
+				Class exptype = popExpressionType(false);
+				pushExpressionValue(Boolean.valueOf(isInstance(type, exp, exptype)), Boolean.TYPE);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (RuntimeException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
 	}
 	
 	/**
 	 * Test if instance of. It will make sure that primitive to non-primitive is not permitted.
 	 * This is a true instance of, which means null IS NOT AN instance of any type. This is
 	 * different then assignable from, in that case null can be assigned to any class type.
-	 * 
+	 * <p>
+	 * This is a helper method for expression processer to do isInstance. Since it is a helper method it doesn't
+	 * check nor process exceptions.
+
 	 * @param type
 	 * @param bean
 	 * @param beanType
@@ -472,109 +1165,282 @@
 		else 
 			return type.isInstance(bean);
 	}
+	
+	/**
+	 * Push new instance from string.
+	 * @param initializationString
+	 * @param resultType expected result type. If it isn't of that type, a classcast will be processed. 
+	 * @param classloader classloader to use for finding classes, or <code>null</code> to use classloader of InitializationStringParser.class.
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushNewInstanceFromString(String initializationString, Class resultType, ClassLoader classloader) {
+		boolean ignore = (ignoreExpression != null || errorOccurred);
+		if (traceOn)
+			printTrace("New instance from string: \""+initializationString+"\" Type="+resultType, ignore);
+		try {
+			if (ignore)
+				return;
+			
+			try {
+				InitializationStringParser parser = InitializationStringParser.createParser(initializationString, classloader);
+				Object newValue = parser.evaluate();
+				newValue = castBean(resultType, newValue, parser.getExpectedType());
+				pushExpressionValue(newValue, resultType);
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (InitializationStringEvaluationException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
 
-	private static final String[] PRE_OPER_TO_STRING;
-	static {
-		PRE_OPER_TO_STRING = new String[IExpressionConstants.PRE_MAX+1];
-		PRE_OPER_TO_STRING[IExpressionConstants.PRE_PLUS] = "+"; //$NON-NLS-1$
-		PRE_OPER_TO_STRING[IExpressionConstants.PRE_MINUS] = "-"; //$NON-NLS-1$
-		PRE_OPER_TO_STRING[IExpressionConstants.PRE_COMPLEMENT] = "~"; //$NON-NLS-1$
-		PRE_OPER_TO_STRING[IExpressionConstants.PRE_NOT] = "!"; //$NON-NLS-1$
+	}
+
+	/**
+	 * Push prefix expression.
+	 * @param operator 
+	 * @since 1.0.0
+	 */
+	public final void pushPrefix(PrefixOperator operator) {
+		try {
+			if (ignoreExpression != null || errorOccurred) {
+				if (traceOn)
+					printTrace("Prefix: \'"+operator+"\'", true);
+				return;
+			}
+			
+			if (operator == PrefixOperator.PRE_PLUS)
+				return;	// Do nothing. "+" doesn't affect the result of the current top expression.
+	
+			if (traceOn)
+				printTrace("Prefix: \'"+operator+"\' ", false);
+	
+			try {
+				Object exp = popExpression();
+				Class exptype = popExpressionType(false);
+				if (!exptype.isPrimitive())
+					throwInvalidPrefix(operator, exp);
+				
+				int primTypeEnum = getEnumForPrimitive(exptype);
+				switch (operator.getValue()) {
+					case PrefixOperator.PRE_MINUS_VALUE:
+						switch (primTypeEnum) {
+							case BOOLEAN:
+								throwInvalidPrefix(operator, exp);						
+							case BYTE:
+								exp = new Integer(-((Number) exp).byteValue());
+								break;
+							case CHAR:
+								exp = new Integer(-((Character) exp).charValue());
+								break;
+							case DOUBLE:
+								exp = new Double(-((Number) exp).doubleValue());
+								break;
+							case FLOAT:
+								exp = new Float(-((Number) exp).floatValue());
+								break;
+							case INT:
+								exp = new Integer(-((Number) exp).intValue());
+								break;
+							case LONG:
+								exp = new Long(-((Number) exp).longValue());
+								break;
+							case SHORT:
+								exp = new Integer(-((Number) exp).shortValue());
+								break;
+						}
+						exptype = getPrimitiveType(exp);	// It can actually change the type.				
+						break;
+						
+					case PrefixOperator.PRE_COMPLEMENT_VALUE:
+						switch (primTypeEnum) {
+							case BOOLEAN:
+							case DOUBLE:
+							case FLOAT:
+								throwInvalidPrefix(operator, exp);						
+							case BYTE:
+								exp = new Integer(~((Number) exp).byteValue());
+								break;
+							case CHAR:
+								exp = new Integer(~((Character) exp).charValue());
+								break;
+							case INT:
+								exp = new Integer(~((Number) exp).intValue());
+								break;
+							case LONG:
+								exp = new Long(~((Number) exp).longValue());
+								break;
+							case SHORT:
+								exp = new Integer(~((Number) exp).shortValue());
+								break;
+						}
+						exptype = getPrimitiveType(exp);	// It can actually change the type.
+						break;
+					case PrefixOperator.PRE_NOT_VALUE:
+						switch (primTypeEnum) {
+							case BOOLEAN:
+								exp = !((Boolean) exp).booleanValue() ? Boolean.TRUE : Boolean.FALSE;
+								break;
+							case BYTE:
+							case CHAR:
+							case DOUBLE:
+							case FLOAT:
+							case INT:
+							case LONG:
+							case SHORT:
+								throwInvalidPrefix(operator, exp);						
+						}				
+						break;
+					}
+				
+				if (traceOn)
+					printObjectAndType(exp, exptype);
+				pushExpressionValue(exp, exptype);	// Push the result back on the stack.
+	
+			} catch (IllegalArgumentException e) {
+				processSyntaxException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (RuntimeException e) {
+				processException(e);
+			} 
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+			
 	}
 	
 	/**
-	 * Push prefix expression.
-	 * @param operator The operator from IExpressionConstants
+	 * Assign the right expression to the left expression.
+	 * @since 1.1.0
+	 */
+	public final void pushAssignment() {
+		if (ignoreExpression != null || errorOccurred) {
+			if (traceOn) {
+				printTrace("Assignment", true);
+				printTraceEnd();
+			}
+			return;
+		}
+		
+		try {
+			// KLUDGE: The only reason leftValue/refType are outside of try/finally is because
+			// of tracing. pushExpression() does its own trace statements, so we need to end
+			// our trace before calling pushExpression. 
+			Object leftValue;
+			Class refType;
+			try {
+				if (traceOn)
+					printTrace("Assignment: ", false);				
+				// The order on the stack is right then left operand.
+				// First the right operand
+				Object value = popExpression();
+				Class type = popExpressionType(false);
+
+				// Next the left operand, should be a reference.
+				VariableReference left = (VariableReference) popExpression(false); // Don't dereference it.
+				refType = popExpressionType(false);
+
+				if (traceOn)
+					printObjectAndType(left, refType);
+
+				leftValue = left.set(value, type);
+			} finally {
+				if (traceOn)
+					printTraceEnd();
+			}
+			
+			// Now do assignment and return the value to the stack.
+			pushExpression(leftValue, refType);	// The type of the result is the type of the reference.
+
+		} catch (IllegalArgumentException e) {
+			processException(e);
+		} catch (NoExpressionValueException e) {
+			processSyntaxException(e);
+		} catch (IllegalAccessException e) {
+			processException(e);
+		} catch (RuntimeException e) {
+			processException(e);
+		}
+			
+	}
+	
+	/**
+	 * Assign the expression proxy to the top expression value.
+	 * 
+	 * @param proxy
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushAssignment(InternalExpressionProxy proxy) {
+		boolean ignore = (ignoreExpression != null || errorOccurred);
+		try {
+			if (traceOn) {
+				printTrace("Assign to Proxy #"+proxy.getProxyID(), ignore);
+			}
+			if (ignore)
+				return;
+			
+			try {
+				assignToExpressionProxyFromTopStackEntry(proxy);
+				if (traceOn)
+					printObjectAndType(proxy.getValue(), proxy.getType());
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (RuntimeException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+
+	}
+
+	/**
+	 * Assign the top stack entry to the new expression proxy and allocate it for callback later.
+	 * @param proxy
 	 * @throws NoExpressionValueException
 	 * 
-	 * @see IExpressionConstants#PRE_MINUS
-	 * @since 1.0.0
+	 * @since 1.1.0
 	 */
-	public final void pushPrefix(int operator) throws NoExpressionValueException {
-		if (ignoreExpression>0)
-			return;
-		
-		if (operator == IExpressionConstants.PRE_PLUS)
-			return;	// Do nothing. "+" doesn't affect the result of the current top expression.
-		
-		Object exp = popExpression();
-		Class exptype = popExpressionType(false);
-		if (!exptype.isPrimitive())
-			throwInvalidPrefix(operator, exp);
-		
-		int primTypeEnum = getEnumForPrimitive(exptype);
-		switch (operator) {
-			case IExpressionConstants.PRE_MINUS:
-				switch (primTypeEnum) {
-					case BOOLEAN:
-						throwInvalidPrefix(operator, exp);						
-					case BYTE:
-						exp = new Integer(-((Number) exp).byteValue());
-						break;
-					case CHAR:
-						exp = new Integer(-((Character) exp).charValue());
-						break;
-					case DOUBLE:
-						exp = new Double(-((Number) exp).doubleValue());
-						break;
-					case FLOAT:
-						exp = new Float(-((Number) exp).floatValue());
-						break;
-					case INT:
-						exp = new Integer(-((Number) exp).intValue());
-						break;
-					case LONG:
-						exp = new Long(-((Number) exp).longValue());
-						break;
-					case SHORT:
-						exp = new Integer(-((Number) exp).shortValue());
-						break;
-				}
-				exptype = getPrimitiveType(exp);	// It can actually change the type.				
-				break;
-				
-			case IExpressionConstants.PRE_COMPLEMENT:
-				switch (primTypeEnum) {
-					case BOOLEAN:
-					case DOUBLE:
-					case FLOAT:
-						throwInvalidPrefix(operator, exp);						
-					case BYTE:
-						exp = new Integer(~((Number) exp).byteValue());
-						break;
-					case CHAR:
-						exp = new Integer(~((Character) exp).charValue());
-						break;
-					case INT:
-						exp = new Integer(~((Number) exp).intValue());
-						break;
-					case LONG:
-						exp = new Long(~((Number) exp).longValue());
-						break;
-					case SHORT:
-						exp = new Integer(~((Number) exp).shortValue());
-						break;
-				}
-				exptype = getPrimitiveType(exp);	// It can actually change the type.
-				break;
-			case IExpressionConstants.PRE_NOT:
-				switch (primTypeEnum) {
-					case BOOLEAN:
-						exp = !((Boolean) exp).booleanValue() ? Boolean.TRUE : Boolean.FALSE;
-						break;
-					case BYTE:
-					case CHAR:
-					case DOUBLE:
-					case FLOAT:
-					case INT:
-					case LONG:
-					case SHORT:
-						throwInvalidPrefix(operator, exp);						
-				}				
-				break;
-			}
-		
-		pushExpressionValue(exp, exptype);	// Push the result back on the stack.
+	protected void assignToExpressionProxyFromTopStackEntry(InternalExpressionProxy proxy) throws NoExpressionValueException {
+		Object value = getExpression(1);
+		Class type = getExpressionType(1, true);
+		if (value instanceof VariableReference)
+			value = ((VariableReference) value).dereference();	// Here we want the final current value.
+
+		proxy.setProxy(value, type);
+		allocateExpressionProxy(proxy);
+	}
+
+	/**
+	 * Allocate an expression proxy. This is used to make an expression proxy known to the processor. The expression proxy must
+	 * have been setProxy() at this point. This is used to assign from the top of the stack or to add from outside an evaluated proxy
+	 * to be used later by others.
+	 * 
+	 * @param proxy
+	 * 
+	 * @since 1.1.0
+	 */
+	public void allocateExpressionProxy(InternalExpressionProxy proxy) {
+		int minSize = proxy.getProxyID()+1;
+		if (expressionProxies == null)
+			expressionProxies = new ArrayList(minSize+10);	// Allow room to grow ten more.
+		else if (expressionProxies.size() < minSize)
+			expressionProxies.ensureCapacity(minSize+10);	// Allow room to grow ten more.
+		int fill = minSize-expressionProxies.size();	// Number of "null" fill entries needed. Probably shouldn't occur, but to be safe.
+		if (fill > 0) {
+			while (--fill > 0)
+				expressionProxies.add(null);
+			expressionProxies.add(proxy);
+		} else
+			expressionProxies.set(proxy.getProxyID(), proxy);	// Already large enough, replace entry.
+
 	}
 
 	/**
@@ -596,13 +1462,18 @@
 	
 	/**
 	 * Get the enum constant for the type of primitive passed in.
+	 * <p>
+	 * This is a helper method for expression processer to get the enum for the primitive type. Since it is a helper method it doesn't
+	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
+
 	 * @param primitiveType
 	 * @return
+	 * @throws IllegalArgumentException if type is not a primitive.
 	 * 
 	 * @see ExpressionProcesser#BOOLEAN
 	 * @since 1.0.0
 	 */
-	protected final int getEnumForPrimitive(Class primitiveType) {
+	protected final int getEnumForPrimitive(Class primitiveType) throws IllegalArgumentException {
 		if (primitiveType == Boolean.TYPE)
 			return BOOLEAN;
 		else if (primitiveType == Integer.TYPE)
@@ -620,564 +1491,595 @@
 		else if (primitiveType == Short.TYPE)
 			return SHORT;
 		else
-			throw new IllegalArgumentException();
+			throw new IllegalArgumentException(primitiveType != null ? primitiveType.getName() : "null");
 	}
 	
-	private void throwInvalidPrefix(int operator, Object exp) throws IllegalArgumentException {
-		throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.InvalidOperandOfPrefixOperator_EXC_"), new Object[] {exp != null ? exp.toString() : null, PRE_OPER_TO_STRING[operator]})); //$NON-NLS-1$
-	}
-
-	private static final String[] IN_OPER_TO_STRING;
-	static {
-		IN_OPER_TO_STRING = new String[IExpressionConstants.IN_MAX+1];
-		IN_OPER_TO_STRING[IExpressionConstants.IN_AND] = "&"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_CONDITIONAL_AND] = "&&"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_CONDITIONAL_OR] = "||"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_DIVIDE] = "/"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_EQUALS] = "=="; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_GREATER] = ">"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_GREATER_EQUALS] = ">="; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_LEFT_SHIFT] = "<<"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_LESS] = "<"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_LESS_EQUALS] = "<="; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_MINUS] = "-"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_NOT_EQUALS] = "!="; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_OR] = "|"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_PLUS] = "+"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_REMAINDER] = "%"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_RIGHT_SHIFT_SIGNED] = ">>"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED] = ">>>"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_TIMES] = "*"; //$NON-NLS-1$
-		IN_OPER_TO_STRING[IExpressionConstants.IN_XOR] = "^"; //$NON-NLS-1$
-	}
-		
+	private void throwInvalidPrefix(PrefixOperator operator, Object exp) throws IllegalArgumentException {
+		throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.InvalidOperandOfPrefixOperator_EXC_"), new Object[] {exp != null ? exp.toString() : null, operator.toString()})); //$NON-NLS-1$
+	}		
 	
+	private static final Object INFIX_IGNORE = "INFIX IGNORE";	// Flag for infix in ingore
+	private int infixNesting = 0;	// Nesting of infix expressions.
+	private int infixIgnoreNestCount = 0;	// When ignoring infix expressions, ignore until this nest count.
 	/**
 	 * Push the infix expression onto the stack.
 	 * @param operator
-	 * @param operandType The operator type from IExpressionConstants.IN_*
-	 * @throws NoExpressionValueException
-	 * 
-	 * @see IExpressionConstants#IN_AND
+	 * @param operandType The operator type. Left, right, other.
 	 * @since 1.0.0
 	 */
-	public final void pushInfix(int operator, int operandType) throws NoExpressionValueException {
-		boolean wasIgnoring = ignoreExpression>0;
-		if (wasIgnoring)
-			if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-				ignoreExpression++;	// Increment it so that entire expression is ignored because we already are in an ignore.
-			else if (operandType == IInternalExpressionConstants.INFIX_LAST_OPERAND)
-				ignoreExpression--;	// Decrement it because we have reached the end.
-		if (ignoreExpression>0)
-			return;	// We are still ignoring.
-		
-		if (wasIgnoring && operandType == IInternalExpressionConstants.INFIX_LAST_OPERAND)
-			return;	// We've received the last operand but we were ignoring, but the value of the entire expression is still the top stack value.
-		
-		Object right = null;
-		Class rightType = null;
-		if (operandType != IInternalExpressionConstants.INFIX_LEFT_OPERAND) {
-			// We are not the left operand, so the stack has the right on the top, followed by the left.
-			right = popExpression();
-			rightType = popExpressionType(false);
-		} 
-		
-		Object value = popExpression();
-		Class valueType = popExpressionType(false);
+	public final void pushInfix(InfixOperator operator, InternalInfixOperandType operandType) {
+		try {
+			boolean ignore = true;
+			try {
+				if (errorOccurred) {
+					return;
+				}
+				// Slightly different here in that if an ignored occurred we still need to process at least part of it so that
+				// we can get the expression grouping correct.
+				if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+					infixNesting++;
+				else if (operandType == InternalInfixOperandType.INFIX_LAST_OPERAND) {
+					int currentNest = infixNesting--;
+					if (ignoreExpression == INFIX_IGNORE && currentNest == infixIgnoreNestCount) {
+						// We were ignoring, and it was this expression that was being ignore.
+						// We have received the last operand of the nested expression that was being ignored,
+						// so we can stop ignoring. But we still leave since the value of the expression is on the
+						// top of the stack.
+						ignoreExpression = null;
+						return;
+					}
+				}
+	
+				if (ignoreExpression != null)
+					return;
+				ignore = false;
+			} finally {
+				if (traceOn)
+					printTrace("Infix: "+operator, ignore);
+			}
+			
+			try {
+				Object right = null;
+				Class rightType = null;
+				if (operandType != InternalInfixOperandType.INFIX_LEFT_OPERAND) {
+					// We are not the left operand, so the stack has the right on the top, followed by the left.
+					right = popExpression();
+					rightType = popExpressionType(false);
+				} 
+				
+				Object value = popExpression();
+				Class valueType = popExpressionType(false);
+	
+				switch (operator.getValue()) {
+					case InfixOperator.IN_AND_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidBitType(valueType, InfixOperator.IN_AND);
+						testValidBitType(rightType, InfixOperator.IN_AND);
+						if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) & getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it is int. (even two shorts together produce an int).
+							value = new Integer(getInt(value) & getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_CONDITIONAL_AND_VALUE:
+						// This is tricky.
+						// First if this is left type, then just continue.
+						// Else if this other or last, then need to make it the new value.
+						if (operandType != InternalInfixOperandType.INFIX_LEFT_OPERAND) {
+							value = right;
+							valueType = rightType;
+						}
+							
+						//If the value is now false, we need to ignore the rest.
+						if (valueType != Boolean.TYPE)
+							throwInvalidInfix(operator, value);
+						if (!((Boolean) value).booleanValue() && operandType != InternalInfixOperandType.INFIX_LAST_OPERAND)
+							startInfixIgnore();	// Start ignoring because we know the value of the expression at this point. It is false.
+						break;
+					case InfixOperator.IN_CONDITIONAL_OR_VALUE:
+						// This is tricky.
+						// First if this is left type, then just continue.
+						// Else if this other or last, then need to make it the new value.
+						if (operandType != InternalInfixOperandType.INFIX_LEFT_OPERAND) {
+							value = right;
+							valueType = rightType;
+						}
+						
+						//If the value is now true, we need to ignore the rest.
+						if (valueType != Boolean.TYPE)
+							throwInvalidInfix(operator, value);
+						if (((Boolean) value).booleanValue() && operandType != InternalInfixOperandType.INFIX_LAST_OPERAND)
+							startInfixIgnore(); // Start ignoring because we know the value of the expression at this point. It is true.
+						break;
+					case InfixOperator.IN_DIVIDE_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidArithmeticType(valueType, InfixOperator.IN_DIVIDE);
+						testValidArithmeticType(rightType, InfixOperator.IN_DIVIDE);
+						if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, the result will be double.
+							value = new Double(getDouble(value) / getDouble(right));
+							valueType = Double.TYPE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, the result will be float.
+							value = new Float(getFloat(value) / getFloat(right));
+							valueType = Float.TYPE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) / getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it will result in an int, even if both sides are short.
+							value = new Integer(getInt(value) / getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_EQUALS_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						// We should never get extended operator for this, but we'll ignore the possibility.
+						if (valueType.isPrimitive() && rightType.isPrimitive()) {
+							// Primitives require more testing than just ==. boolean primitives 
+							if (valueType == Boolean.TYPE || rightType == Boolean.TYPE) {
+								// If either side is a boolean, then the other side needs to be boolean for it to even try to be true.
+								if (valueType != Boolean.TYPE || valueType != Boolean.TYPE)
+									value = Boolean.FALSE;
+								else
+									value = (((Boolean) value).booleanValue() == ((Boolean) right).booleanValue()) ? Boolean.TRUE : Boolean.FALSE;
+							} else {
+								// Now do number tests since not boolean primitive, only numbers are left
+								if (valueType == Double.TYPE || rightType == Double.TYPE) {
+									// If either side is double, compare as double.
+									value = (getDouble(value) == getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
+								} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+									// If either side is float, compare as float.
+									value = (getFloat(value) == getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
+								} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+									// If either side is long, the compare as long.
+									value = (getLong(value) == getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
+								} else {
+									// Else it will compare as int, even if both sides are short.
+									value = (getInt(value) == getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
+								}
+							}
+						} else if (valueType.isPrimitive() || rightType.isPrimitive())
+							value = Boolean.FALSE;	// Can't be true if one side prim and the other isn't
+						else {
+							// Just do object ==
+							value = (value == right) ? Boolean.TRUE : Boolean.FALSE;
+						}
+						valueType = Boolean.TYPE;	// We know result will be a boolean.
+						break;
+					case InfixOperator.IN_GREATER_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidArithmeticType(valueType, InfixOperator.IN_GREATER);
+						testValidArithmeticType(rightType, InfixOperator.IN_GREATER);
+						if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, compare will be double.
+							value = (getDouble(value) > getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, compare will be float.
+							value = (getFloat(value) > getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, compare will be long.
+							value = (getLong(value) > getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else {
+							// Else compare will be int, even if both sides are short.
+							value = (getInt(value) > getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
+						}
+						valueType = Boolean.TYPE;	// We know result will be a boolean.
+						break;
+					case InfixOperator.IN_GREATER_EQUALS_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidArithmeticType(valueType, InfixOperator.IN_GREATER_EQUALS);
+						testValidArithmeticType(rightType, InfixOperator.IN_GREATER_EQUALS);
+						if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, compare will be double.
+							value = (getDouble(value) >= getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, compare will be float.
+							value = (getFloat(value) >= getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, compare will be long.
+							value = (getLong(value) >= getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else {
+							// Else compare will be int, even if both sides are short.
+							value = (getInt(value) >= getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
+						}
+						valueType = Boolean.TYPE;	// We know result will be a boolean.
+						break;
+					case InfixOperator.IN_LEFT_SHIFT_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidBitType(valueType, InfixOperator.IN_LEFT_SHIFT);
+						testValidBitType(rightType, InfixOperator.IN_LEFT_SHIFT);
+						if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) << getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it is int. (even two shorts together produce an int).
+							value = new Integer(getInt(value) << getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_LESS_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidArithmeticType(valueType, InfixOperator.IN_LESS);
+						testValidArithmeticType(rightType, InfixOperator.IN_LESS);
+						if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, compare will be double.
+							value = (getDouble(value) < getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, compare will be float.
+							value = (getFloat(value) < getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, compare will be long.
+							value = (getLong(value) < getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else {
+							// Else compare will be int, even if both sides are short.
+							value = (getInt(value) < getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
+						}
+						valueType = Boolean.TYPE;	// We know result will be a boolean.
+						break;
+					case InfixOperator.IN_LESS_EQUALS_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidArithmeticType(valueType, InfixOperator.IN_LESS_EQUALS);
+						testValidArithmeticType(rightType, InfixOperator.IN_LESS_EQUALS);
+						if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, compare will be double.
+							value = (getDouble(value) <= getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, compare will be float.
+							value = (getFloat(value) <= getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, compare will be long.
+							value = (getLong(value) <= getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
+						} else {
+							// Else compare will be int, even if both sides are short.
+							value = (getInt(value) <= getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
+						}
+						valueType = Boolean.TYPE;	// We know result will be a boolean.
+						break;
+					case InfixOperator.IN_MINUS_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidArithmeticType(valueType, InfixOperator.IN_MINUS);
+						testValidArithmeticType(rightType, InfixOperator.IN_MINUS);
+						if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, the result will be double.
+							value = new Double(getDouble(value) - getDouble(right));
+							valueType = Double.TYPE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, the result will be float.
+							value = new Float(getFloat(value) - getFloat(right));
+							valueType = Float.TYPE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) - getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it will result in an int, even if both sides are short.
+							value = new Integer(getInt(value) - getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_NOT_EQUALS_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						// We should never get extended operator for this, but we'll ignore the possibility.
+						if (valueType.isPrimitive() && rightType.isPrimitive()) {
+							// Primitives require more testing than just ==. boolean primitives 
+							if (valueType == Boolean.TYPE || rightType == Boolean.TYPE) {
+								// If either side is a boolean, then the other side needs to be boolean for it to even try to be true.
+								if (valueType != Boolean.TYPE || valueType != Boolean.TYPE)
+									value = Boolean.TRUE;
+								else
+									value = (((Boolean) value).booleanValue() != ((Boolean) right).booleanValue()) ? Boolean.TRUE : Boolean.FALSE;
+							} else {
+								// Now do number tests since not boolean primitive, only numbers are left
+								if (valueType == Double.TYPE || rightType == Double.TYPE) {
+									// If either side is double, compare as double.
+									value = (getDouble(value) != getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
+								} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+									// If either side is float, compare as float.
+									value = (getFloat(value) != getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
+								} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+									// If either side is long, the compare as long.
+									value = (getLong(value) != getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
+								} else {
+									// Else it will compare as int, even if both sides are short.
+									value = (getInt(value) != getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
+								}
+							}
+						} else if (valueType.isPrimitive() || rightType.isPrimitive())
+							value = Boolean.TRUE;	// Must be true if one side prim and the other isn't
+						else {
+							// Just do object !=
+							value = (value != right) ? Boolean.TRUE : Boolean.FALSE;
+						}
+						valueType = Boolean.TYPE;	// We know result will be a boolean.
+						break;
+					case InfixOperator.IN_OR_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidBitType(valueType, InfixOperator.IN_OR);
+						testValidBitType(rightType, InfixOperator.IN_OR);
+						if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) | getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it is int. (even two shorts together produce an int).
+							value = new Integer(getInt(value) | getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_PLUS_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND) {
+							if (valueType == String.class) {
+								// Special. left argument is a string, so we want to store a string buffer instead
+								// since we know we will be appending to it. 
+								value = new StringBuffer((String) value);
+							}	
+							break;	// Do nothing with first operand
+						}
+						
+						testValidPlusType(valueType, rightType);
+						if (valueType == String.class || rightType == String.class) {
+							// Special we have a string on one side. Need to do it as strings instead.
+							// We are going to be tricky in that we will store a StringBuffer on the stack (if not last operand)
+							// but call it a string.
+							StringBuffer sb = null;
+							if (valueType == String.class) {
+								sb = (StringBuffer) value;	// We know that if the value (left) is string type, we've already converted it to buffer.
+							} else {
+								// The right is the one that introduces the string, so we change the value over to a string buffer.
+								sb = new StringBuffer(((String) right).length()+16);	// We can't put the value in yet, need to get left into it.
+								appendToBuffer(sb, value, valueType);	// Put the left value in now
+								value = sb;
+								valueType = String.class;	// Make it a string class
+							}
+							appendToBuffer(sb, right, rightType);
+							// Now if we are the last operand, we should get rid of the buffer and put a true string back in.
+							if (operandType == InternalInfixOperandType.INFIX_LAST_OPERAND)
+								value = sb.toString();
+						} else if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, the result will be double.
+							value = new Double(getDouble(value) + getDouble(right));
+							valueType = Double.TYPE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, the result will be float.
+							value = new Float(getFloat(value) + getFloat(right));
+							valueType = Float.TYPE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) + getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it will result in an int, even if both sides are short.
+							value = new Integer(getInt(value) + getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_REMAINDER_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidArithmeticType(valueType, InfixOperator.IN_REMAINDER);
+						testValidArithmeticType(rightType, InfixOperator.IN_REMAINDER);
+						if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, the result will be double.
+							value = new Double(getDouble(value) % getDouble(right));
+							valueType = Double.TYPE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, the result will be float.
+							value = new Float(getFloat(value) % getFloat(right));
+							valueType = Float.TYPE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) % getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it will result in an int, even if both sides are short.
+							value = new Integer(getInt(value) % getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_RIGHT_SHIFT_SIGNED_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidBitType(valueType, InfixOperator.IN_RIGHT_SHIFT_SIGNED);
+						testValidBitType(rightType, InfixOperator.IN_RIGHT_SHIFT_SIGNED);
+						if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) >> getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it is int. (even two shorts together produce an int).
+							value = new Integer(getInt(value) >> getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_RIGHT_SHIFT_UNSIGNED_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidBitType(valueType, InfixOperator.IN_RIGHT_SHIFT_UNSIGNED);
+						testValidBitType(rightType, InfixOperator.IN_RIGHT_SHIFT_UNSIGNED);
+						if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) >>> getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it is int. (even two shorts together produce an int).
+							value = new Integer(getInt(value) >>> getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_TIMES_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidArithmeticType(valueType, InfixOperator.IN_TIMES);
+						testValidArithmeticType(rightType, InfixOperator.IN_TIMES);
+						if (valueType == Double.TYPE || rightType == Double.TYPE) {
+							// If either side is double, the result will be double.
+							value = new Double(getDouble(value) * getDouble(right));
+							valueType = Double.TYPE;
+						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
+							// If either side is float, the result will be float.
+							value = new Float(getFloat(value) * getFloat(right));
+							valueType = Float.TYPE;
+						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) * getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it will result in an int, even if both sides are short.
+							value = new Integer(getInt(value) * getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					case InfixOperator.IN_XOR_VALUE:
+						if (operandType == InternalInfixOperandType.INFIX_LEFT_OPERAND)
+							break;	// Do nothing with first operand
+						
+						testValidBitType(valueType, InfixOperator.IN_XOR);
+						testValidBitType(rightType, InfixOperator.IN_XOR);
+						if (valueType == Long.TYPE || rightType == Long.TYPE) {
+							// If either side is long, the result will be long.
+							value = new Long(getLong(value) ^ getLong(right));
+							valueType = Long.TYPE;
+						} else {
+							// Else it is int. (even two shorts together produce an int).
+							value = new Integer(getInt(value) ^ getInt(right));
+							valueType = Integer.TYPE;
+						}
+						break;
+					} 
+				
+				if (traceOn)
+					printObjectAndType(value, valueType);
+				pushExpressionValue(value, valueType);	// Push the result back on the stack.
+	
+			} catch (IllegalArgumentException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (RuntimeException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+			
+	}
 
-		switch (operator) {
-			case IExpressionConstants.IN_AND:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidBitType(valueType, IExpressionConstants.IN_AND);
-				testValidBitType(rightType, IExpressionConstants.IN_AND);
-				if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) & getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it is int. (even two shorts together produce an int).
-					value = new Integer(getInt(value) & getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_CONDITIONAL_AND:
-				// This is tricky.
-				// First if this is left type, then just continue.
-				// Else if this other or last, then need to make it the new value.
-				if (operandType != IInternalExpressionConstants.INFIX_LEFT_OPERAND) {
-					value = right;
-					valueType = rightType;
-				}
-					
-				//If the value is now false, we need to ignore the rest.
-				if (valueType != Boolean.TYPE)
-					throwInvalidInfix(operator, value);
-				if (!((Boolean) value).booleanValue() && operandType != IInternalExpressionConstants.INFIX_LAST_OPERAND)
-					++ignoreExpression;	// Start ignoring since current value is now false.
-				break;
-			case IExpressionConstants.IN_CONDITIONAL_OR:
-				// This is tricky.
-				// First if this is left type, then just continue.
-				// Else if this other or last, then need to make it the new value.
-				if (operandType != IInternalExpressionConstants.INFIX_LEFT_OPERAND) {
-					value = right;
-					valueType = rightType;
-				}
-				
-				//If the value is now true, we need to ignore the rest.
-				if (valueType != Boolean.TYPE)
-					throwInvalidInfix(operator, value);
-				if (((Boolean) value).booleanValue() && operandType != IInternalExpressionConstants.INFIX_LAST_OPERAND)
-					++ignoreExpression;	// Start ignoring since current value is now true.
-				break;
-			case IExpressionConstants.IN_DIVIDE:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidArithmeticType(valueType, IExpressionConstants.IN_DIVIDE);
-				testValidArithmeticType(rightType, IExpressionConstants.IN_DIVIDE);
-				if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, the result will be double.
-					value = new Double(getDouble(value) / getDouble(right));
-					valueType = Double.TYPE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, the result will be float.
-					value = new Float(getFloat(value) / getFloat(right));
-					valueType = Float.TYPE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) / getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it will result in an int, even if both sides are short.
-					value = new Integer(getInt(value) / getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_EQUALS:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				// We should never get extended operator for this, but we'll ignore the possibility.
-				if (valueType.isPrimitive() && rightType.isPrimitive()) {
-					// Primitives require more testing than just ==. boolean primitives 
-					if (valueType == Boolean.TYPE || rightType == Boolean.TYPE) {
-						// If either side is a boolean, then the other side needs to be boolean for it to even try to be true.
-						if (valueType != Boolean.TYPE || valueType != Boolean.TYPE)
-							value = Boolean.FALSE;
-						else
-							value = (((Boolean) value).booleanValue() == ((Boolean) right).booleanValue()) ? Boolean.TRUE : Boolean.FALSE;
-					} else {
-						// Now do number tests since not boolean primitive, only numbers are left
-						if (valueType == Double.TYPE || rightType == Double.TYPE) {
-							// If either side is double, compare as double.
-							value = (getDouble(value) == getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
-						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-							// If either side is float, compare as float.
-							value = (getFloat(value) == getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
-						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-							// If either side is long, the compare as long.
-							value = (getLong(value) == getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
-						} else {
-							// Else it will compare as int, even if both sides are short.
-							value = (getInt(value) == getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
-						}
-					}
-				} else if (valueType.isPrimitive() || rightType.isPrimitive())
-					value = Boolean.FALSE;	// Can't be true if one side prim and the other isn't
-				else {
-					// Just do object ==
-					value = (value == right) ? Boolean.TRUE : Boolean.FALSE;
-				}
-				valueType = Boolean.TYPE;	// We know result will be a boolean.
-				break;
-			case IExpressionConstants.IN_GREATER:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidArithmeticType(valueType, IExpressionConstants.IN_GREATER);
-				testValidArithmeticType(rightType, IExpressionConstants.IN_GREATER);
-				if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, compare will be double.
-					value = (getDouble(value) > getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, compare will be float.
-					value = (getFloat(value) > getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, compare will be long.
-					value = (getLong(value) > getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else {
-					// Else compare will be int, even if both sides are short.
-					value = (getInt(value) > getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
-				}
-				valueType = Boolean.TYPE;	// We know result will be a boolean.
-				break;
-			case IExpressionConstants.IN_GREATER_EQUALS:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidArithmeticType(valueType, IExpressionConstants.IN_GREATER_EQUALS);
-				testValidArithmeticType(rightType, IExpressionConstants.IN_GREATER_EQUALS);
-				if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, compare will be double.
-					value = (getDouble(value) >= getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, compare will be float.
-					value = (getFloat(value) >= getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, compare will be long.
-					value = (getLong(value) >= getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else {
-					// Else compare will be int, even if both sides are short.
-					value = (getInt(value) >= getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
-				}
-				valueType = Boolean.TYPE;	// We know result will be a boolean.
-				break;
-			case IExpressionConstants.IN_LEFT_SHIFT:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidBitType(valueType, IExpressionConstants.IN_LEFT_SHIFT);
-				testValidBitType(rightType, IExpressionConstants.IN_LEFT_SHIFT);
-				if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) << getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it is int. (even two shorts together produce an int).
-					value = new Integer(getInt(value) << getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_LESS:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidArithmeticType(valueType, IExpressionConstants.IN_LESS);
-				testValidArithmeticType(rightType, IExpressionConstants.IN_LESS);
-				if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, compare will be double.
-					value = (getDouble(value) < getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, compare will be float.
-					value = (getFloat(value) < getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, compare will be long.
-					value = (getLong(value) < getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else {
-					// Else compare will be int, even if both sides are short.
-					value = (getInt(value) < getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
-				}
-				valueType = Boolean.TYPE;	// We know result will be a boolean.
-				break;
-			case IExpressionConstants.IN_LESS_EQUALS:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidArithmeticType(valueType, IExpressionConstants.IN_LESS_EQUALS);
-				testValidArithmeticType(rightType, IExpressionConstants.IN_LESS_EQUALS);
-				if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, compare will be double.
-					value = (getDouble(value) <= getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, compare will be float.
-					value = (getFloat(value) <= getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, compare will be long.
-					value = (getLong(value) <= getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
-				} else {
-					// Else compare will be int, even if both sides are short.
-					value = (getInt(value) <= getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
-				}
-				valueType = Boolean.TYPE;	// We know result will be a boolean.
-				break;
-			case IExpressionConstants.IN_MINUS:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidArithmeticType(valueType, IExpressionConstants.IN_MINUS);
-				testValidArithmeticType(rightType, IExpressionConstants.IN_MINUS);
-				if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, the result will be double.
-					value = new Double(getDouble(value) - getDouble(right));
-					valueType = Double.TYPE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, the result will be float.
-					value = new Float(getFloat(value) - getFloat(right));
-					valueType = Float.TYPE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) - getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it will result in an int, even if both sides are short.
-					value = new Integer(getInt(value) - getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_NOT_EQUALS:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				// We should never get extended operator for this, but we'll ignore the possibility.
-				if (valueType.isPrimitive() && rightType.isPrimitive()) {
-					// Primitives require more testing than just ==. boolean primitives 
-					if (valueType == Boolean.TYPE || rightType == Boolean.TYPE) {
-						// If either side is a boolean, then the other side needs to be boolean for it to even try to be true.
-						if (valueType != Boolean.TYPE || valueType != Boolean.TYPE)
-							value = Boolean.TRUE;
-						else
-							value = (((Boolean) value).booleanValue() != ((Boolean) right).booleanValue()) ? Boolean.TRUE : Boolean.FALSE;
-					} else {
-						// Now do number tests since not boolean primitive, only numbers are left
-						if (valueType == Double.TYPE || rightType == Double.TYPE) {
-							// If either side is double, compare as double.
-							value = (getDouble(value) != getDouble(right)) ? Boolean.TRUE : Boolean.FALSE;
-						} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-							// If either side is float, compare as float.
-							value = (getFloat(value) != getFloat(right)) ? Boolean.TRUE : Boolean.FALSE;
-						} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-							// If either side is long, the compare as long.
-							value = (getLong(value) != getLong(right)) ? Boolean.TRUE : Boolean.FALSE;
-						} else {
-							// Else it will compare as int, even if both sides are short.
-							value = (getInt(value) != getInt(right)) ? Boolean.TRUE : Boolean.FALSE;
-						}
-					}
-				} else if (valueType.isPrimitive() || rightType.isPrimitive())
-					value = Boolean.TRUE;	// Must be true if one side prim and the other isn't
-				else {
-					// Just do object !=
-					value = (value != right) ? Boolean.TRUE : Boolean.FALSE;
-				}
-				valueType = Boolean.TYPE;	// We know result will be a boolean.
-				break;
-			case IExpressionConstants.IN_OR:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidBitType(valueType, IExpressionConstants.IN_OR);
-				testValidBitType(rightType, IExpressionConstants.IN_OR);
-				if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) | getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it is int. (even two shorts together produce an int).
-					value = new Integer(getInt(value) | getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_PLUS:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND) {
-					if (valueType == String.class) {
-						// Special. left argument is a string, so we want to store a string buffer instead
-						// since we know we will be appending to it. 
-						value = new StringBuffer((String) value);
-					}	
-					break;	// Do nothing with first operand
-				}
-				
-				testValidPlusType(valueType, rightType);
-				if (valueType == String.class || rightType == String.class) {
-					// Special we have a string on one side. Need to do it as strings instead.
-					// We are going to be tricky in that we will store a StringBuffer on the stack (if not last operand)
-					// but call it a string.
-					StringBuffer sb = null;
-					if (valueType == String.class) {
-						sb = (StringBuffer) value;	// We know that if the value (left) is string type, we've already converted it to buffer.
-					} else {
-						// The right is the one that introduces the string, so we change the value over to a string buffer.
-						sb = new StringBuffer(((String) right).length()+16);	// We can't put the value in yet, need to get left into it.
-						appendToBuffer(sb, value, valueType);	// Put the left value in now
-						value = sb;
-						valueType = String.class;	// Make it a string class
-					}
-					appendToBuffer(sb, right, rightType);
-					// Now if we are the last operand, we should get rid of the buffer and put a true string back in.
-					if (operandType == IInternalExpressionConstants.INFIX_LAST_OPERAND)
-						value = sb.toString();
-				} else if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, the result will be double.
-					value = new Double(getDouble(value) + getDouble(right));
-					valueType = Double.TYPE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, the result will be float.
-					value = new Float(getFloat(value) + getFloat(right));
-					valueType = Float.TYPE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) + getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it will result in an int, even if both sides are short.
-					value = new Integer(getInt(value) + getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_REMAINDER:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidArithmeticType(valueType, IExpressionConstants.IN_REMAINDER);
-				testValidArithmeticType(rightType, IExpressionConstants.IN_REMAINDER);
-				if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, the result will be double.
-					value = new Double(getDouble(value) % getDouble(right));
-					valueType = Double.TYPE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, the result will be float.
-					value = new Float(getFloat(value) % getFloat(right));
-					valueType = Float.TYPE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) % getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it will result in an int, even if both sides are short.
-					value = new Integer(getInt(value) % getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_RIGHT_SHIFT_SIGNED:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidBitType(valueType, IExpressionConstants.IN_RIGHT_SHIFT_SIGNED);
-				testValidBitType(rightType, IExpressionConstants.IN_RIGHT_SHIFT_SIGNED);
-				if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) >> getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it is int. (even two shorts together produce an int).
-					value = new Integer(getInt(value) >> getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidBitType(valueType, IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED);
-				testValidBitType(rightType, IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED);
-				if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) >>> getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it is int. (even two shorts together produce an int).
-					value = new Integer(getInt(value) >>> getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_TIMES:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidArithmeticType(valueType, IExpressionConstants.IN_TIMES);
-				testValidArithmeticType(rightType, IExpressionConstants.IN_TIMES);
-				if (valueType == Double.TYPE || rightType == Double.TYPE) {
-					// If either side is double, the result will be double.
-					value = new Double(getDouble(value) * getDouble(right));
-					valueType = Double.TYPE;
-				} else if (valueType == Float.TYPE || rightType == Float.TYPE) {
-					// If either side is float, the result will be float.
-					value = new Float(getFloat(value) * getFloat(right));
-					valueType = Float.TYPE;
-				} else if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) * getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it will result in an int, even if both sides are short.
-					value = new Integer(getInt(value) * getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			case IExpressionConstants.IN_XOR:
-				if (operandType == IInternalExpressionConstants.INFIX_LEFT_OPERAND)
-					break;	// Do nothing with first operand
-				
-				testValidBitType(valueType, IExpressionConstants.IN_XOR);
-				testValidBitType(rightType, IExpressionConstants.IN_XOR);
-				if (valueType == Long.TYPE || rightType == Long.TYPE) {
-					// If either side is long, the result will be long.
-					value = new Long(getLong(value) ^ getLong(right));
-					valueType = Long.TYPE;
-				} else {
-					// Else it is int. (even two shorts together produce an int).
-					value = new Integer(getInt(value) ^ getInt(right));
-					valueType = Integer.TYPE;
-				}
-				break;
-			} 
-		
-		pushExpressionValue(value, valueType);	// Push the result back on the stack.
+	/**
+	 * Start ignoring rest of the current infix expression.
+	 * 
+	 * @since 1.1.0
+	 */
+	private void startInfixIgnore() {
+		ignoreExpression = INFIX_IGNORE;
+		infixIgnoreNestCount = infixNesting;	// Ignore until we get back to the current nesting.
+
 	}
 
 	/**
 	 * Get int value of the primitive wrapper bean passed in (must be either a <code>Number/code> or <code>Character</code>.
 	 * Anything else will cause a class cast error.
-	 * 
+	 * <p>
+	 * This is a helper method for expression processer to get the int value of the object. Since it is a helper method it doesn't
+	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
 	 * @param bean
-	 * @return
+	 * @return the int value of the number/character
+	 * @throws ClassCastException
 	 * 
 	 * @since 1.0.0
 	 */
-	protected final int getInt(Object bean) {
+	protected final int getInt(Object bean) throws ClassCastException {
 		return (bean instanceof Number) ? ((Number) bean).intValue() : ((Character) bean).charValue();
 	}
 	
 	/**
 	 * Get float value of the primitive wrapper bean passed in (must be either a <code>Number/code> or <code>Character</code>.
 	 * Anything else will cause a class cast error.
-	 * 
-	 * @param bean
-	 * @return
-	 * 
+	 * <p>
+	 * This is a helper method for expression processer to get the float value of the object. Since it is a helper method it doesn't
+	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
+	 * @param bean 
+	 * @return float value of the Number/character
+	 * @throws ClassCastException
 	 * @since 1.0.0
 	 */
-	protected final float getFloat(Object bean) {
+	protected final float getFloat(Object bean) throws ClassCastException {
 		return (bean instanceof Number) ? ((Number) bean).floatValue() : ((Character) bean).charValue();
 	}
 
 	/**
 	 * Get double value of the primitive wrapper bean passed in (must be either a <code>Number/code> or <code>Character</code>.
 	 * Anything else will cause a class cast error.
+	 * <p>
+	 * This is a helper method for expression processer to get the float value of the object. Since it is a helper method it doesn't
+	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
 	 * 
 	 * @param bean
-	 * @return
-	 * 
+	 * @return double value of the Number/Character.
+	 * @throws ClassCastException
 	 * @since 1.0.0
 	 */
-	protected final double getDouble(Object bean) {
+	protected final double getDouble(Object bean) throws ClassCastException {
 		return (bean instanceof Number) ? ((Number) bean).doubleValue() : ((Character) bean).charValue();
 	}
 	
 	/**
 	 * Get long value of the primitive wrapper bean passed in (must be either a <code>Number/code> or <code>Character</code>.
 	 * Anything else will cause a class cast error.
+	 * <p>
+	 * This is a helper method for expression processer to get the float value of the object. Since it is a helper method it doesn't
+	 * check nor process the exception. It throws it. Callers must handle it as they see fit.
 	 * 
 	 * @param bean
 	 * @return
-	 * 
+	 * @throws ClassCastException
 	 * @since 1.0.0
 	 */
-	protected final long getLong(Object bean) {
+	protected final long getLong(Object bean) throws ClassCastException {
 		return (bean instanceof Number) ? ((Number) bean).longValue() : ((Character) bean).charValue();
 	}
 	
-	private void throwInvalidInfix(int operator, Object value) throws IllegalArgumentException {
-		throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.InvalidOperandOfOperator_EXC_"), new Object[] {value != null ? value.toString() : null, IN_OPER_TO_STRING[operator]})); //$NON-NLS-1$
+	private void throwInvalidInfix(InfixOperator operator, Object value) throws IllegalArgumentException {
+		throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.InvalidOperandOfOperator_EXC_"), new Object[] {value != null ? value.toString() : null, operator.toString()})); //$NON-NLS-1$
 	}
 	
-	private void testValidBitType(Class type, int operator) {
+	private void testValidBitType(Class type, InfixOperator operator) {
 		if (!type.isPrimitive() || type == Boolean.TYPE || type == Double.TYPE|| type == Float.TYPE)
 			throwInvalidInfix(operator, type);
 	}
 	
-	private void testValidArithmeticType(Class type, int operator) {
+	private void testValidArithmeticType(Class type, InfixOperator operator) {
 		if (!type.isPrimitive() || type == Boolean.TYPE)
 			throwInvalidInfix(operator, type);
 	}
@@ -1187,8 +2089,8 @@
 		if (left == String.class || right == String.class)
 			return;	// As long as one side is string. Anything is valid.
 		// If neither is string, then standard arithmetic test.
-		testValidArithmeticType(left, IExpressionConstants.IN_PLUS);
-		testValidArithmeticType(right, IExpressionConstants.IN_PLUS);
+		testValidArithmeticType(left, InfixOperator.IN_PLUS);
+		testValidArithmeticType(right, InfixOperator.IN_PLUS);
 	}
 	
 	private void appendToBuffer(StringBuffer sb, Object value, Class valueType) {
@@ -1233,48 +2135,67 @@
 	 * Push the array access expression.
 	 * 
 	 * @param indexCount Number of dimensions being accessed
-	 * @throws NoExpressionValueException
-	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushArrayAccess(int indexCount) throws NoExpressionValueException {
-		if (ignoreExpression>0)
-			return;
+	public final void pushArrayAccess(int indexCount) {
+		boolean ignore = (ignoreExpression != null || errorOccurred);
 		
-		// We need to pop off the args. The topmost will be the rightmost index, and the bottom most will be the array itself.
-		int[] arguments = new int[indexCount];
-		// Fill the arg array in reverse order.
-		for(int i=indexCount-1; i >= 0; i--) {
-			Object index = popExpression();
-			Class indexType = popExpressionType(false);
-			if (indexType.isPrimitive() && (indexType == Integer.TYPE || indexType == Short.TYPE || indexType == Character.TYPE || indexType == Byte.TYPE)) {
-				arguments[i] = getInt(index);
-			} else
-				throwClassCast(Integer.TYPE, index);
+		if (traceOn) {
+			printTrace("Array Access["+indexCount+']', ignore);
 		}
-		
-		Object array = popExpression();
-		Class arrayType = popExpressionType(false);
-		if (arrayType.isArray()) {
-			// First figure out how many dimensions are available. Stop when we hit indexcount because we won't be going further.
-			int dimcount = 0;
-			Class[] componentTypes = new Class[indexCount];	// 
-			Class componentType = arrayType;
-			while (dimcount < indexCount && componentType.isArray()) {
-				componentTypes[dimcount++] = componentType = componentType.getComponentType();
-			}
+		try {
+			if (ignore)
+				return;
 			
-			if (dimcount < indexCount)
-				throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.XIsGreaterThanNumberOfDimensionsInArray_EXC_"), new Object[] {new Integer(indexCount), new Integer(dimcount)})); //$NON-NLS-1$
-			
-			// Now start accessing one index at a time.
-			Object value = array;	// Final value, start with full array. 
-			for(int i=0; i<indexCount; i++) {
-				value = Array.get(value, arguments[i]);
+			try {
+				// We need to pop off the args. The topmost will be the rightmost index, and the bottom most will be the array itself.
+				int[] arguments = new int[indexCount];
+				// Fill the arg array in reverse order.
+				for(int i=indexCount-1; i >= 0; i--) {
+					Object index = popExpression();
+					Class indexType = popExpressionType(false);
+					if (indexType.isPrimitive() && (indexType == Integer.TYPE || indexType == Short.TYPE || indexType == Character.TYPE || indexType == Byte.TYPE)) {
+						arguments[i] = getInt(index);
+					} else
+						throwClassCast(Integer.TYPE, index);
+				}
+				
+				Object array = popExpression();
+				Class arrayType = popExpressionType(false);
+				if (arrayType.isArray()) {
+					// First figure out how many dimensions are available. Stop when we hit indexcount because we won't be going further.
+					int dimcount = 0;
+					Class[] componentTypes = new Class[indexCount];	// 
+					Class componentType = arrayType;
+					while (dimcount < indexCount && componentType.isArray()) {
+						componentTypes[dimcount++] = componentType = componentType.getComponentType();
+					}
+					
+					if (dimcount < indexCount)
+						throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.XIsGreaterThanNumberOfDimensionsInArray_EXC_"), new Object[] {new Integer(indexCount), new Integer(dimcount)})); //$NON-NLS-1$
+					
+					// Now start accessing one index at a time, stop just before the last one. The last one will be turned into an ArrayAccessReference.
+					Object value = array;	// Final value, start with full array.
+					int pullCount = indexCount-1;
+					for(int i=0; i<pullCount; i++) {
+						value = Array.get(value, arguments[i]);
+					}
+					ArrayAccessReference arrayValue = ArrayAccessReference.createArrayAccessReference(value, arguments[pullCount]);
+					if (traceOn)
+						printObjectAndType(arrayValue, componentTypes[pullCount]);
+					pushExpressionValue(arrayValue, componentTypes[pullCount]);
+				}  else
+					 throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.NotAnArray_EXC_"), new Object[] {arrayType})); //$NON-NLS-1$
+	
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (RuntimeException e) {
+				processException(e);
 			}
-			pushExpressionValue(value, componentTypes[indexCount-1]);
-		}  else
-			throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.NotAnArray_EXC_"), new Object[] {arrayType})); //$NON-NLS-1$
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
 	}
 	
 	/**
@@ -1282,154 +2203,193 @@
 	 * 
 	 * @param arrayType The type of the array
 	 * @param dimensionCount The number of dimensions being initialized. Zero if using an initializer.
-	 * @throws NoExpressionValueException
-	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushArrayCreation(Class arrayType, int dimensionCount) throws NoExpressionValueException {
-		if (ignoreExpression>0)
-			return;
+	public final void pushArrayCreation(Class arrayType, int dimensionCount) {
+		boolean ignore = (ignoreExpression != null || errorOccurred);
+		if (traceOn)
+			printTrace("Array Creation: "+arrayType.getName()+'['+dimensionCount+']', ignore);
 		
-		if (dimensionCount == 0) {
-			// The top value is the array itself, from the array initializer.
-			// So we do nothing.
-		} else {
-			// Strip off dimensionCounts from the array type, e.g.
-			// ArrayType is int[][][]
-			// Dimensioncount is 2
-			// Then we need to strip two componenttypes off of the array type
-			// wind up with int[]
-			// This is necessary because Array.new will add those dimensions back
-			// on through the dimension count.
-			Class componentType = arrayType;
-			for(int i=0; i < dimensionCount && componentType != null; i++)
-				componentType = componentType.getComponentType();
-			if (componentType == null)
-				throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.ArraytypeHasFewerDimensionsThanRequested_EXC_"), new Object[] {arrayType, new Integer(dimensionCount)})); //$NON-NLS-1$
+		try {
+			if (ignore)
+				return;
 			
-			// We need to pull in the dimension initializers. They are stacked in reverse order.
-			int[] dimInit = new int[dimensionCount];
-			for(int i=dimensionCount-1; i >= 0; i--) {
-				Object index = popExpression();
-				Class dimType = popExpressionType(false);
-				if (dimType.isPrimitive() && (dimType == Integer.TYPE || dimType == Short.TYPE || dimType == Character.TYPE || dimType == Byte.TYPE)) {
-					dimInit[i] = getInt(index);
-				} else
-					throwClassCast(Integer.TYPE, index);
+			try {
+				if (dimensionCount == 0) {
+					// The top value is the array itself, from the array initializer.
+					// So we do nothing.
+				} else {
+					// Strip off dimensionCounts from the array type, e.g.
+					// ArrayType is int[][][]
+					// Dimensioncount is 2
+					// Then we need to strip two componenttypes off of the array type
+					// wind up with int[]
+					// This is necessary because Array.new will add those dimensions back
+					// on through the dimension count.
+					Class componentType = arrayType;
+					for(int i=0; i < dimensionCount && componentType != null; i++)
+						componentType = componentType.getComponentType();
+					if (componentType == null)
+						throw new IllegalArgumentException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.ArraytypeHasFewerDimensionsThanRequested_EXC_"), new Object[] {arrayType, new Integer(dimensionCount)})); //$NON-NLS-1$
+					
+					// We need to pull in the dimension initializers. They are stacked in reverse order.
+					int[] dimInit = new int[dimensionCount];
+					for(int i=dimensionCount-1; i >= 0; i--) {
+						Object index = popExpression();
+						Class dimType = popExpressionType(false);
+						if (dimType.isPrimitive() && (dimType == Integer.TYPE || dimType == Short.TYPE || dimType == Character.TYPE || dimType == Byte.TYPE)) {
+							dimInit[i] = getInt(index);
+						} else
+							throwClassCast(Integer.TYPE, index);
+					}
+					
+					// Finally create the array.
+					Object array = Array.newInstance(componentType, dimInit);
+					pushExpressionValue(array, arrayType);
+				}
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
 			}
-			
-			// Finally create the array.
-			Object array = Array.newInstance(componentType, dimInit);
-			pushExpressionValue(array, arrayType);
+		} finally {
+			if (traceOn)
+				printTraceEnd();
 		}
+			
 	}
 
 	/**
 	 * Push the array initializer request.
 	 * 
-	 * @param arrayType The type of the array to create, minus one dimension.
+	 * @param arrayType The original type of the array to create.
+	 * @param stripCount the count of how many dimensions to strip to get the type needed for this initializer.
 	 * @param expressionCount
-	 * @throws NoExpressionValueException
-	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushArrayInitializer(Class arrayType, int expressionCount) throws NoExpressionValueException {
-		if (ignoreExpression>0)
-			return;
-
-		Object[] dimValues = null;
-		if (expressionCount > 0) {
-			// We need to pull in the initializers. They are stacked in reverse order.
-			dimValues = new Object[expressionCount];
-			for (int i = expressionCount - 1; i >= 0; i--) {
-				Object dimValue = dimValues[i] = popExpression();
-				Class dimType = popExpressionType(false);
-				if (arrayType.isPrimitive()) {
-					if (dimValue == null || !dimType.isPrimitive())
-						throwClassCast(arrayType, dimType);
-					// A little trickier. Can assign short to an int, but can't assign long to an int. Widening is permitted.
-					if (arrayType != dimType) {
-						int compEnum = getEnumForPrimitive(arrayType);
-						int dimEnum = getEnumForPrimitive(dimType);
-						if (compEnum == BOOLEAN || dimEnum == BOOLEAN)
+	public final void pushArrayInitializer(Class arrayType, int stripCount, int expressionCount) {
+		boolean ignore = (ignoreExpression != null || errorOccurred);
+		
+		if (traceOn)
+			printTrace("Initialize Array: "+arrayType.getName()+'{'+expressionCount+'}', ignore);
+		
+		try {
+			if (ignore)
+				return;
+	
+			try {
+				if (!arrayType.isArray()) {
+					// It is not an array type.
+					throw new ClassCastException(MessageFormat.format(InitparserTreeMessages.getString("ExpressionProcesser.CannotCastXToY_EXC_"), new Object[] {arrayType, "array"}));
+				} 
+				// Strip off the number of dimensions specified.
+				while(stripCount-->0) {
+					arrayType = arrayType.getComponentType();
+				}
+				Object[] dimValues = null;
+				if (expressionCount > 0) {
+					// We need to pull in the initializers. They are stacked in reverse order.
+					dimValues = new Object[expressionCount];
+					for (int i = expressionCount - 1; i >= 0; i--) {
+						Object dimValue = dimValues[i] = popExpression();
+						Class dimType = popExpressionType(false);
+						if (arrayType.isPrimitive()) {
+							if (dimValue == null || !dimType.isPrimitive())
+								throwClassCast(arrayType, dimType);
+							// A little trickier. Can assign short to an int, but can't assign long to an int. Widening is permitted.
+							if (arrayType != dimType) {
+								int compEnum = getEnumForPrimitive(arrayType);
+								int dimEnum = getEnumForPrimitive(dimType);
+								if (compEnum == BOOLEAN || dimEnum == BOOLEAN)
+									throwClassCast(arrayType, dimType);
+								int dimValueAsInt = getInt(dimValue);
+								switch (compEnum) {
+									case BYTE :
+										// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
+										// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
+										// however, at this point in time we no longer know this. So we will simply allow it.
+										if (dimEnum > INT || dimValueAsInt > Byte.MAX_VALUE || dimValueAsInt < Byte.MIN_VALUE)
+											throwClassCast(arrayType, dimType);
+										// But need to be changed to appropriate type for the array.set to work.									
+										dimValues[i] = new Byte((byte)dimValueAsInt);
+										break;
+									case SHORT :								
+										// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
+										// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
+										// however, at this point in time we no longer know this. So we will simply allow it.
+										if (dimEnum > INT || dimValueAsInt > Short.MAX_VALUE || dimValueAsInt < Short.MIN_VALUE)
+											throwClassCast(arrayType, dimType);
+										// But need to be changed to appropriate type for the array.set to work.									
+										dimValues[i] = new Short((short)dimValueAsInt);
+										break;
+									case CHAR :
+										// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
+										// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
+										// however, at this point in time we no longer know this. So we will simply allow it.
+										if (dimEnum > INT || dimValueAsInt > Character.MAX_VALUE || dimValueAsInt < Character.MIN_VALUE)
+											throwClassCast(arrayType, dimType);
+										// But need to be changed to appropriate type for the array.set to work.									
+										dimValues[i] = new Character((char)dimValueAsInt);
+										break;
+									case INT :
+										// Can accept byte, short, char, or int. Can't accept long, double, float at all.
+										if (dimEnum > INT)
+											throwClassCast(arrayType, dimType);
+										// But need to be changed to appropriate type for the array.set to work.									
+										dimValues[i] = new Integer(dimValueAsInt);
+										break;
+									case LONG :
+										// Can accept byte, short, char, int, or long. Can't accept double, float at all.
+										if (dimEnum > LONG)
+											throwClassCast(arrayType, dimType);
+										// But need to be changed to appropriate type for the array.set to work.									
+										dimValues[i] = new Long(getLong(dimValue));
+										break;
+									case FLOAT :
+										// Can accept byte, short, char, int, long, or float. Can't accept double at all.
+										if (dimEnum > FLOAT)
+											throwClassCast(arrayType, dimType);
+										// But need to be changed to appropriate type for the array.set to work.									
+										dimValues[i] = new Float(getFloat(dimValue));
+										break;
+									case DOUBLE :
+										// But need to be changed to appropriate type for the array.set to work.									
+										dimValues[i] = new Double(getDouble(dimValue));
+										break;
+	
+								}
+							}
+							// Compatible, so ok.
+						} else if (dimType != MethodHelper.NULL_TYPE && !arrayType.isAssignableFrom(dimType)) {
+							// If it is NULL_TYPE, then this is a pushed null. This is always assignable to a non-primitive.
+							// So we don't enter here in that case. However, a null that was returned from some expression
+							// won't have a NULL_TYPE, it will instead have the expected return type. That must be used
+							// in the assignment instead. That is because in java it uses the expected type to determine
+							// compatibility, not the actual type.
 							throwClassCast(arrayType, dimType);
-						int dimValueAsInt = getInt(dimValue);
-						switch (compEnum) {
-							case BYTE :
-								// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
-								// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
-								// however, at this point in time we no longer know this. So we will simply allow it.
-								if (dimEnum > INT || dimValueAsInt > Byte.MAX_VALUE || dimValueAsInt < Byte.MIN_VALUE)
-									throwClassCast(arrayType, dimType);
-								// But need to be changed to appropriate type for the array.set to work.									
-								dimValues[i] = new Byte((byte)dimValueAsInt);
-								break;
-							case SHORT :								
-								// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
-								// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
-								// however, at this point in time we no longer know this. So we will simply allow it.
-								if (dimEnum > INT || dimValueAsInt > Short.MAX_VALUE || dimValueAsInt < Short.MIN_VALUE)
-									throwClassCast(arrayType, dimType);
-								// But need to be changed to appropriate type for the array.set to work.									
-								dimValues[i] = new Short((short)dimValueAsInt);
-								break;
-							case CHAR :
-								// Can accept byte, short, char, or int as long as value is <= byte max. Can't accept long, double, float at all.
-								// Note: This isn't actually true. The max/min test is only valid if the value is a literal, not an expression,
-								// however, at this point in time we no longer know this. So we will simply allow it.
-								if (dimEnum > INT || dimValueAsInt > Character.MAX_VALUE || dimValueAsInt < Character.MIN_VALUE)
-									throwClassCast(arrayType, dimType);
-								// But need to be changed to appropriate type for the array.set to work.									
-								dimValues[i] = new Character((char)dimValueAsInt);
-								break;
-							case INT :
-								// Can accept byte, short, char, or int. Can't accept long, double, float at all.
-								if (dimEnum > INT)
-									throwClassCast(arrayType, dimType);
-								// But need to be changed to appropriate type for the array.set to work.									
-								dimValues[i] = new Integer(dimValueAsInt);
-								break;
-							case LONG :
-								// Can accept byte, short, char, int, or long. Can't accept double, float at all.
-								if (dimEnum > LONG)
-									throwClassCast(arrayType, dimType);
-								// But need to be changed to appropriate type for the array.set to work.									
-								dimValues[i] = new Long(getLong(dimValue));
-								break;
-							case FLOAT :
-								// Can accept byte, short, char, int, long, or float. Can't accept double at all.
-								if (dimEnum > FLOAT)
-									throwClassCast(arrayType, dimType);
-								// But need to be changed to appropriate type for the array.set to work.									
-								dimValues[i] = new Float(getFloat(dimValue));
-								break;
-							case DOUBLE :
-								// But need to be changed to appropriate type for the array.set to work.									
-								dimValues[i] = new Double(getDouble(dimValue));
-								break;
-
 						}
 					}
-					// Compatible, so ok.
-				} else if (dimType != MethodHelper.NULL_TYPE && !arrayType.isAssignableFrom(dimType)) {
-					// If it is NULL_TYPE, then this is a pushed null. This is always assignable to a non-primitive.
-					// So we don't enter here in that case. However, a null that was returned from some expression
-					// won't have a NULL_TYPE, it will instead have the expected return type. That must be used
-					// in the assignment instead. That is because in java it uses the expected type to determine
-					// compatibility, not the actual type.
-					throwClassCast(arrayType, dimType);
+					
 				}
+				
+				// Now we finally create the array.
+				Object array = Array.newInstance(arrayType, new int[] {expressionCount});
+				for (int i = 0; i < expressionCount; i++) {
+					Array.set(array, i, dimValues[i]);
+				}
+				
+				pushExpressionValue(array, array.getClass());	// Adjust to true array type, not the incoming type (which is one dimension too small).
+	
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
 			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
 			
-		}
-		
-		// Now we finally create the array.
-		Object array = Array.newInstance(arrayType, new int[] {expressionCount});
-		for (int i = 0; i < expressionCount; i++) {
-			Array.set(array, i, dimValues[i]);
-		}
-		
-		pushExpressionValue(array, array.getClass());	// Adjust to true array type, not the incoming type (which is one dimension too small).
 	}
 
 	/**
@@ -1437,160 +2397,818 @@
 	 * 
 	 * @param type The type to create an instance of
 	 * @param argumentCount The number of arguments (which are stored on the stack).	 * @throws NoExpressionValueException
-	 * @throws EvaluationException
-	 * @throws IllegalArgumentException
-	 * @throws InstantiationException
-	 * @throws IllegalAccessException
-	 * @throws InvocationTargetException
-	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushClassInstanceCreation(Class type, int argumentCount) throws NoExpressionValueException, EvaluationException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
-		if (ignoreExpression>0)
-			return;
-					
-		// We need to pull in the arguments. They are stacked in reverse order.
-		Object value = null;	// The new instance.
-		if (argumentCount > 0) {
-			Object[]  args = new Object[argumentCount];
-			Class[] argTypes = new Class[argumentCount];
-			for (int i = argumentCount - 1; i >= 0; i--) {
-				args[i] = popExpression();
-				argTypes[i] = popExpressionType(false);
-			}
-			
-			// Now we need to find the appropriate constructor.
-			Constructor ctor;
-			try {
-				ctor = MethodHelper.findCompatibleConstructor(type, argTypes);
-			} catch (NoSuchMethodException e) {
-				throw new EvaluationException(e);
-			} catch (AmbiguousMethodException e) {
-				throw new EvaluationException(e);
-			}
-			value = ctor.newInstance(args);
-		} else {
-			// No args, just do default ctor.
-			value = type.newInstance();
-		}
+	public final void pushClassInstanceCreation(Class type, int argumentCount) {
+		boolean ignore = (ignoreExpression != null || errorOccurred);
 		
-		pushExpressionValue(value, type);
+		if (traceOn)
+			printTrace("Create Class: "+type+" (", ignore);
+		try {
+			if (ignore)
+				return;
+						
+			try {
+				// We need to pull in the arguments. They are stacked in reverse order.
+				Object value = null;	// The new instance.
+				if (argumentCount > 0) {
+					Object[]  args = new Object[argumentCount];
+					Class[] argTypes = new Class[argumentCount];
+					for (int i = argumentCount - 1; i >= 0; i--) {
+						args[i] = popExpression();
+						argTypes[i] = popExpressionType(false);
+					}
+					
+					// Now we need to find the appropriate constructor.
+					Constructor ctor;
+					ctor = MethodHelper.findCompatibleConstructor(type, argTypes);
+					if (traceOn) {
+						System.out.print(ctor);
+						System.out.print(')');
+					}
+					value = ctor.newInstance(args);
+				} else {
+					// No args, just do default ctor.
+					if (traceOn) {
+						System.out.print("Default ctor)");
+					}
+					value = type.newInstance();
+				}
+				
+				pushExpressionValue(value, type);
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (InstantiationException e) {
+				processException(e);
+			} catch (IllegalAccessException e) {
+				processException(e);
+			} catch (InvocationTargetException e) {
+				processException(e);
+			} catch (NoSuchMethodException e) {
+				processException(e);
+			} catch (AmbiguousMethodException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+			
 	}
 
 	/**
 	 * Push the field access expression.
-	 * @param fieldName
+	 * @param field String for fieldname, or a java.lang.reflect.Field.
+	 * @param fieldIsString <code>true</code> if field is a string name, and not a java.lang.reflect.Field.
 	 * @param hasReceiver
-	 * @throws NoExpressionValueException
-	 * @throws SecurityException
-	 * @throws NoSuchFieldException
-	 * @throws IllegalArgumentException
-	 * @throws IllegalAccessException
 	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushFieldAccess(String fieldName, boolean hasReceiver) throws NoExpressionValueException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
-		if (ignoreExpression>0)
-			return;
-	
-		// Get the receiver off of the stack.
-		Object receiver = popExpression();
-		Class receiverType = popExpressionType(false);
+	public final void pushFieldAccess(Object field, boolean fieldIsString, boolean hasReceiver) {
+		try {
+			if (ignoreExpression != null || errorOccurred) {
+				if (traceOn)
+					printTrace("Field Access", true);
+				return;
+			}
 		
-		// Find the field.
-		Field field = receiverType.getField(fieldName);
-		// Access the field.
-		Object value = field.get(receiver);
-		Class valueType = field.getType();
-		pushExpressionValue(value, valueType);
+			if (traceOn)
+				printTrace("Field Access: ", false);
+			try {
+				// Get the receiver off of the stack.
+				Object receiver = null;
+				Class receiverType = null;
+				if (hasReceiver) {
+					receiver = popExpression();
+					receiverType = popExpressionType(false);
+				}
+				
+				// Find the field.
+				Field reflectField = fieldIsString ? receiverType.getField((String) field) : (Field) field;
+				// Access the field.
+				Object value = FieldAccessReference.createFieldAccessReference(reflectField, receiver);
+				Class valueType = reflectField.getType();
+				if (traceOn) {
+					System.out.print("Field: ");
+					System.out.print(reflectField);
+					System.out.print(">");
+					printObjectAndType(value, valueType);
+				}
+					
+				pushExpressionValue(value, valueType);
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (NoSuchFieldException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+			
 	}
 
 	/**
 	 * Push the method invocation expression.
-	 * @param methodName
+	 * @param method
+	 * @param methodIsString <code>true</code> if method is a string (so string name) or else it is a java.lang.reflect.Method.
 	 * @param hasReceiver
 	 * @param argCount
-	 * @throws NoExpressionValueException
-	 * @throws EvaluationException
-	 * @throws IllegalArgumentException
-	 * @throws IllegalAccessException
-	 * @throws InvocationTargetException
-	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushMethodInvocation(String methodName, boolean hasReceiver, int argCount) throws NoExpressionValueException, EvaluationException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-		if (ignoreExpression>0)
-			return;
-		
-		// We need to pull in the arguments. They are stacked in reverse order.
-		Object[]  args = new Object[argCount];
-		Class[] argTypes = new Class[argCount];
-		for (int i = argCount - 1; i >= 0; i--) {
-			args[i] = popExpression();
-			argTypes[i] = popExpressionType(false);
-		}
-		
-		// Now get receiver
-		Object receiver = popExpression();
-		Class receiverType = popExpressionType(false);
-		
-		// Now we need to find the appropriate method.
-		Method method;
+	public final void pushMethodInvocation(Object method, boolean methodIsString, boolean hasReceiver, int argCount) {
 		try {
-			method = MethodHelper.findCompatibleMethod(receiverType, methodName, argTypes);
-		} catch (NoSuchMethodException e) {
-			throw new EvaluationException(e);
-		} catch (AmbiguousMethodException e) {
-			throw new EvaluationException(e);
+			if (ignoreExpression != null || errorOccurred) {
+				if (traceOn)
+					printTrace("Invoke", true);
+				return;
+			}
+			
+			if (traceOn)
+				printTrace("Invoke: ", false);
+			
+			try {
+				// We need to pull in the arguments. They are stacked in reverse order.
+				Object[]  args = new Object[argCount];
+				Class[] argTypes = new Class[argCount];
+				for (int i = argCount - 1; i >= 0; i--) {
+					args[i] = popExpression();
+					argTypes[i] = popExpressionType(false);
+				}
+				
+				// Now get receiver
+				Object receiver = null;
+				Class receiverType = null;
+				if (hasReceiver) {
+					receiver = popExpression();
+					receiverType = popExpressionType(false);
+				}
+				
+				// Now we need to find the appropriate method. If it is a string then there must be a receiver, otherwise no way to know.
+				Method reflectMethod;
+				if (methodIsString) {
+					reflectMethod = MethodHelper.findCompatibleMethod(receiverType, (String) method, argTypes);
+				} else
+					reflectMethod = (Method) method;
+				
+				if (traceOn && reflectMethod != null) {
+					System.out.print("Method: ");
+					System.out.print(reflectMethod);					
+				}
+				
+				Object value = reflectMethod.invoke(receiver, args);
+				
+				if (traceOn) {
+					System.out.print(" returns: ");
+					printObjectAndType(value, reflectMethod.getReturnType());
+				}
+				pushExpressionValue(value, reflectMethod.getReturnType());
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (IllegalAccessException e) {
+				processException(e);
+			} catch (InvocationTargetException e) {
+				processException(e);
+			} catch (NoSuchMethodException e) {
+				processException(e);
+			} catch (AmbiguousMethodException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
 		}
-		Object value = method.invoke(receiver, args);
-		
-		pushExpressionValue(value, method.getReturnType());
+			
 	}
 
+	private static final Object CONDITIONAL_IGNORE = "CONDITIONAL IGNORE";	// Flag for conditional in ingore
+	private int conditionalNesting = 0;	// Nesting of conditional expressions.
+	private int conditionalIgnoreNestCount = 0;	// When ignoring conditional expressions, ignore until this nest count.
+	private boolean skipTruePart;
+
 	/**
+	 * Push a conditional expression. It can be any clause of the conditional (test, true, or false clause).
 	 * @param expressionType
 	 * 
 	 * @since 1.0.0
 	 */
-	public final void pushConditional(int expressionType) throws NoExpressionValueException {
-		boolean wasIgnoring = ignoreExpression>0;
-		if (wasIgnoring) {
-			if (expressionType == IExpressionConstants.CONDITIONAL_CONDITION)
-				ignoreExpression+=2;	// Increment it twice so that entire expression is ignored because we already are in an ignore.
-			else
-				ignoreExpression--;	// Decrement it because we have ignored one of the expressions.
-			if (ignoreExpression>0)
-				return;	// We are still ignoring.
-		}
-		
-		switch (expressionType) {
-			case IExpressionConstants.CONDITIONAL_CONDITION:
-				Object condition = popExpression();
-				Class type = popExpressionType(false);
-				if (type != Boolean.TYPE)
-					throwClassCast(Boolean.TYPE, condition);
-				if (((Boolean) condition).booleanValue()) {
-					// Condition was true.
-					// Do nothing. Let true condition be processed.
-				} else {
-					// Condition was false.
-					++ignoreExpression;	// Tell the true condition it should be ignored.
+	public final void pushConditional(InternalConditionalOperandType expressionType) {
+		try {
+			boolean ignore = true;
+			try {
+				if (errorOccurred)
+					return;
+				// Slightly different here in that if an ignoring occurred we still need to process at least part of it so that
+				// we can get the expression grouping correct.
+				switch (expressionType.getValue()) {
+					case InternalConditionalOperandType.CONDITIONAL_TEST_VALUE:
+						conditionalNesting++;
+						break;
+					case InternalConditionalOperandType.CONDITIONAL_TRUE_VALUE:
+						if (skipTruePart && ignoreExpression == CONDITIONAL_IGNORE && conditionalIgnoreNestCount == conditionalNesting) {
+							// stop ignoring, we've ignored the true condition of interest.
+							ignoreExpression = null;
+							return; // However, leave because since this condition was ignored.
+						}
+						break;
+					case InternalConditionalOperandType.CONDITIONAL_FALSE_VALUE:
+						int currentNesting = conditionalNesting--;
+						if (ignoreExpression == CONDITIONAL_IGNORE && conditionalIgnoreNestCount == currentNesting) {
+							// stop ignoring, we've ignored the false condition of interest.
+							ignoreExpression = null;
+							return; // However, leave because since this condition was ignored.
+						}
 				}
-				// We don't put anything back on the stack because the condition test is not ever returned.
-				// The appropriate true or false condition will be left on the stack.
-				break;
-			case IExpressionConstants.CONDITIONAL_TRUE:
-				if (!wasIgnoring) {
-					// true was processed, so now tell false to not process.
-					// The true condition and type will be left on top of the stack.
-					++ignoreExpression;	
+	
+				if (ignoreExpression != null)
+					return;
+				ignore = false;
+			} finally {
+				if (traceOn)
+					printTrace("Conditional "+expressionType, ignore);
+			}
+					
+			try {
+				switch (expressionType.getValue()) {
+					case InternalConditionalOperandType.CONDITIONAL_TEST_VALUE:
+						Object condition = popExpression();
+						Class type = popExpressionType(false);
+						if (type != Boolean.TYPE)
+							throwClassCast(Boolean.TYPE, condition);
+						if (((Boolean) condition).booleanValue()) {
+							// Condition was true.
+							// Do nothing. Let true condition be processed.
+						} else {
+							// Condition was false.
+							skipTruePart = true;	// Tell the true condition should be ignored.
+							ignoreExpression = CONDITIONAL_IGNORE;
+							conditionalIgnoreNestCount = conditionalNesting;
+						}
+						// We don't put anything back on the stack because the condition test is not ever returned.
+						// The appropriate true or false condition evaluation will be left on the stack.
+						break;
+					case InternalConditionalOperandType.CONDITIONAL_TRUE_VALUE:
+						skipTruePart = false;	// Tell the false condition should be ignored.
+						ignoreExpression = CONDITIONAL_IGNORE;
+						conditionalIgnoreNestCount = conditionalNesting;
+						break;
+					case InternalConditionalOperandType.CONDITIONAL_FALSE_VALUE:
+						// There's nothing to do, if it was ignored due to true, we wouldn't of gotton here.
+						// If it wasn't ignored, then the result of the false expression is on the stack, which is what it should be.
+						break;
 				}
-				break;
-			case IExpressionConstants.CONDITIONAL_FALSE:
-				// There's nothing to do, if it was ignored due to true, then true is on the stack.
-				// If it wasn't ignored, then false expression is on the stack, which is what it should be.
-				break;
+			} catch (RuntimeException e) {
+				processException(e);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
 		}
 	}
+	
+	private static final Object BLOCK_IGNORE = "BLOCK IGNORE";
+	private int[] blocks;	// Stack of block numbers currently evaluating.
+	private int topBlock = -1;	// Top block index.
+	private int breakBlock = -1;	// Block number we are breaking to.
+	
+	/**
+	 * Push a begin block.
+	 * @param blockNumber
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushBlockBegin(int blockNumber) {
+		if (traceOn) {
+			printTrace("Begin Block #"+blockNumber, errorOccurred);
+			indent(true);
+		}
+		try {
+			if (errorOccurred)
+				return;
+			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
+			if (blocks == null)
+				blocks = new int[10];
+			if (++topBlock >= blocks.length) {
+				int[] newList = new int[blocks.length*2];
+				System.arraycopy(blocks, 0, newList, 0, blocks.length);
+				blocks = newList;
+			}
+			blocks[topBlock] = blockNumber;
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+	}
+	
+	/**
+	 * Push a block end. The current block must be the given number, or it is an error.
+	 * 
+	 * @param blockNumber
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushBlockEnd(int blockNumber) {
+		try {
+			if (traceOn) {
+				indent(false);
+				printTrace("End Block #"+blockNumber, errorOccurred);
+			}
+			if (errorOccurred)
+				return;
+			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
+			if (blocks == null || topBlock < 0 || blocks[topBlock] != blockNumber) {
+				processSyntaxException(new IllegalStateException("End Blocks received out of order."));
+			} else {
+				topBlock--;
+				if (ignoreExpression == BLOCK_IGNORE && blockNumber == breakBlock) {
+					ignoreExpression = null;
+				}
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}			
+	}
+	
+	/**
+	 * Skip all following until we hit the requested block number.
+	 * @param blockNumber
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushBlockBreak(int blockNumber) {
+		try {
+			if (traceOn)
+				printTrace("Break Block #"+blockNumber, errorOccurred);
+			if (errorOccurred)
+				return;
+			if (ignoreExpression == null) {
+				ignoreExpression = BLOCK_IGNORE;	// Start ignoring expressions until we hit the block number end block.
+				breakBlock = blockNumber;
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+	}
+	
+	private static final Object TRY_THROW_IGNORE = "TRY THROW IGNORE";
+	private static final Object TRY_FINAL_IGNORE = "TRY FINAL IGNORE";
+	private int[] trys;	// Stack of try numbers currently evaluating.
+	// Stack of trys in catch clause (i.e. starting executing a catch/final clause for the try). Corresponds with try from same index in trys. Contains the throwable for the catch.
+	// This is used to know we are executing a catch (entry not null) and for the rethrow short-hand to rethrow the same exception within the catch.
+	private Throwable[] trysInCatch;	
+	private int topTry = -1;	// Top try index.
+	private int breakTry = -1;	// Try number we are breaking to.
+	private Throwable catchThrowable;	// The throwable to check catches against.
+	
+	/**
+	 * Push a try statement.
+	 * @param tryNumber
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushTryBegin(int tryNumber) {
+		try {
+			if (traceOn) {
+				printTrace("Begin Try #"+tryNumber, errorOccurred);
+				indent(true);
+			}
+	
+			if (errorOccurred)
+				return;
+			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
+			if (trys == null) {
+				trys = new int[10];
+				trysInCatch = new Throwable[10];
+			}
+			if (++topTry >= trys.length) {
+				int[] newList = new int[trys.length*2];
+				System.arraycopy(trys, 0, newList, 0, trys.length);
+				trys = newList;
+				Throwable[] newCatches = new Throwable[trys.length];
+				System.arraycopy(trysInCatch, 0, newCatches, 0, trysInCatch.length);
+				trysInCatch = newCatches;
+			}
+			trys[topTry] = tryNumber;
+			trysInCatch[topTry] = null;
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+	}
+
+	/**
+	 * Throw the top stack entry. It must be an exception.
+	 * 
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushThrowException() {
+		try {
+			boolean ignore = (ignoreExpression != null || errorOccurred);
+			if (traceOn)
+				printTrace("Throw exception: ", ignore);
+			
+			if (ignore)
+				return;
+	
+			try {
+				Object t = popExpression();
+				popExpressionType(false);
+				if (traceOn) {
+					System.out.print(t);
+				}
+				throwException((Throwable) t);
+			} catch (NoExpressionValueException e) {
+				processSyntaxException(e);
+			} catch (ClassCastException e) {
+				processException(e);
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}			
+	}
+	
+	/**
+	 * Throw this exception (means throw through the expression being processed, not throw for this thread).
+	 * @param exception
+	 * 
+	 * @since 1.1.0
+	 */
+	protected final void throwException(Throwable exception) {
+		if (topTry == -1) {
+			// There are no tries, so treat this as a syntax error.
+			processSyntaxException(exception);
+		} else if (trysInCatch[topTry] == null) {
+			// We are not in a catch clause of the top try. So do a throw ignore for toptry.
+			ignoreExpression = TRY_THROW_IGNORE;
+			breakTry = trys[topTry];
+			catchThrowable = exception;
+		} else {
+			// We are in a catch of the top try. So do a throw to finally instead.
+			ignoreExpression = TRY_FINAL_IGNORE;
+			trysInCatch[topTry] = FINAL_CATCH;
+			breakTry = trys[topTry];
+			catchThrowable = exception;
+		}
+	}
+	
+	/**
+	 * Push a catch clause
+	 * @param tryNumber
+	 * @param exceptionType
+	 * @param expressionProxy
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushTryCatchClause(int tryNumber, Class exceptionType, InternalExpressionProxy expressionProxy) {
+		try {
+			if (traceOn) {
+				indent(false);
+				if (expressionProxy == null)
+					printTrace("Catch Try #"+tryNumber+" ("+exceptionType+')', errorOccurred);
+				else
+					printTrace("Catch Try #"+tryNumber+" ("+exceptionType+") Return exception in proxy #"+expressionProxy.getProxyID(), errorOccurred);
+				indent(true);
+			}
+			
+			if (errorOccurred)
+				return;
+			
+			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
+			if (trys == null || topTry < 0 || trys[topTry] != tryNumber) {
+				processSyntaxException(new IllegalStateException("Catch received out of order."));
+			} else {
+				if (ignoreExpression == null) {
+					// Normal flow, no throw in progress, so just ignore now until the finally or end try reached.
+					ignoreExpression = TRY_FINAL_IGNORE;
+					breakTry = tryNumber;
+				} else if (ignoreExpression == TRY_THROW_IGNORE && tryNumber == breakTry) {
+					// We are here due to a throw occuring in this try block, see if for us, and if it is, stop ignoring.
+					// Else just continue ignoring.
+					if (exceptionType.isInstance(catchThrowable)) {
+						// For us, so just turn everything back on, except mark that we are in the catch phase.
+						ignoreExpression = null;
+						trysInCatch[topTry] = catchThrowable; // This is so that we know if we throw again that we should not catch anything.
+						breakTry = -1;
+						if (expressionProxy != null) {
+							expressionProxy.setProxy(catchThrowable, catchThrowable.getClass());
+							allocateExpressionProxy(expressionProxy);
+						}
+						if (traceOn) {
+							System.out.print(" Caught: ");
+							System.out.print(catchThrowable);
+						}
+						catchThrowable = null;
+					}
+				}
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}			
+	}
+	
+	// This is used only so that finally clause can indicate it was executing so that end expression knows this.
+	private static final Throwable FINAL_CATCH = new RuntimeException();
+
+	/**
+	 * Push the try finally clause.
+	 * @param tryNumber
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushTryFinallyClause(int tryNumber) {
+		try {
+			if (traceOn) {
+				indent(false);
+				printTrace("Finally Try #"+tryNumber, errorOccurred);
+				indent(true);
+			}
+			if (errorOccurred)
+				return;
+			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
+			if (trys == null || topTry < 0 || trys[topTry] != tryNumber) {
+				processSyntaxException(new IllegalStateException("Finally received out of order."));
+			} else {
+				if (tryNumber == breakTry && (ignoreExpression == TRY_THROW_IGNORE || ignoreExpression == TRY_FINAL_IGNORE)) {
+					// We are here due to a throw occuring in this try block or a catch was reached (in which case all intervening catch's were ignored).
+					// Now do a normal execution. If we are here due to a throw that wasn't cleared (either no catch or another throw occured within the catch)
+					// then we leave it uncleared so that try/end may rethrow it.
+					ignoreExpression = null;
+					trysInCatch[topTry] = FINAL_CATCH; // We are in the finally clause of a exception being thrown within this try.
+					breakTry = -1;
+					if (traceOn)
+						System.out.print(" Executing finally.");
+				}
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}			
+	}
+	
+	/**
+	 * Rethrow the caught exception. This is a shortcut for:
+	 * } catch (Exception e) {
+	 *   ... do stuff ...
+	 *   throw e;
+	 * }
+	 * @param tryNumber
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushTryRethrow(int tryNumber) {
+		if (traceOn)
+			printTrace("Rethrow Try #"+tryNumber, errorOccurred  || ignoreExpression != null);
+		
+		try {
+			if (errorOccurred)
+				return;
+			// We are not checking ignore because we need to make sure this is not called out of order.
+			if (trys == null || topTry < 0 || trys[topTry] != tryNumber) {
+				processSyntaxException(new IllegalStateException("Rethrow received out of order."));
+			} else if (ignoreExpression == null) {
+				if (trysInCatch[topTry] == null || trysInCatch[topTry] == FINAL_CATCH)
+					processSyntaxException(new IllegalStateException("Retry received outside of an executing catch clause"));
+				else {
+					throwException(trysInCatch[topTry]);
+				}
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}		
+	}
+	
+	public final void pushTryEnd(int tryNumber) {
+		if (traceOn) {
+			indent(false);
+			printTrace("End Try #"+tryNumber, errorOccurred);
+		}
+		try {
+			if (errorOccurred)
+				return;
+			// We are not checking ignore because this is a structural concept instead of executable expressions, so we need to keep track of these.
+			if (trys == null || topTry < 0 || trys[topTry] != tryNumber) {
+				processSyntaxException(new IllegalStateException("Try/end received out of order."));
+			} else {
+				boolean inCatch = trysInCatch[topTry] != null;
+				trysInCatch[topTry] = null;
+				topTry--;
+				if (inCatch || (tryNumber == breakTry && (ignoreExpression == TRY_THROW_IGNORE || ignoreExpression == TRY_FINAL_IGNORE))) {
+					// We are here due to a throw or normal flow through a catch. Either way if there is a throwable still pending, we rethrow.
+					ignoreExpression = null;
+					breakTry = -1;
+					if (catchThrowable != null)
+						throwException(catchThrowable);
+				} 
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}			
+	}
+	
+	/**
+	 * Class used to save the state at time of mark. It will
+	 * be used to restore state if error.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected class SaveState {
+		public int markID;
+		
+		// Block state
+		public int topBlock;
+		public int breakBlock;
+		
+		// Try state
+		public int topTry;
+		public int breakTry;
+		public Throwable catchThrowable;
+		
+		// Error state
+		public boolean errorOccurred;
+		public boolean novalueException;
+		public Throwable exception;
+		public Object ignoreExpression;
+		
+		// Expression stack state
+		public int expressionStackPos;
+		
+		// If/else state
+		public int ifElseNesting;
+		public int ifElseIgnoreNestCount;
+		public boolean ifElseSkipTruePart;
+		
+		// Other
+		public int indent;
+		public int expressionProxyPos;
+		
+		/**
+		 * Construct and save the state.
+		 * 
+		 * @param markNumber
+		 * 
+		 * @since 1.1.0
+		 */
+		public SaveState(int markID) {
+			this.markID = markID;
+			
+			ExpressionProcesser ep = ExpressionProcesser.this;
+			this.topBlock = ep.topBlock;
+			this.breakBlock = ep.breakBlock;
+			
+			this.topTry = ep.topTry;
+			this.breakTry = ep.breakTry;
+			this.catchThrowable = ep.catchThrowable;
+			
+			this.errorOccurred = ep.errorOccurred;
+			this.novalueException = ep.novalueException;
+			this.exception = ep.exception;
+			this.ignoreExpression = ep.ignoreExpression;
+			
+			this.expressionStackPos = expressionStack.size()-1;
+			
+			this.ifElseNesting = ep.ifElseNesting;
+			this.ifElseIgnoreNestCount = ep.ifElseIgnoreNestCount;
+			this.ifElseSkipTruePart = ep.ifElseSkipTruePart;
+			
+			this.indent = ep.indent;
+			this.expressionProxyPos = expressionProxies != null ? expressionProxies.size()-1 : -1;
+		}
+		
+		/**
+		 * Restore the state.
+		 * 
+		 * 
+		 * @since 1.1.0
+		 */
+		public void restoreState() {
+			ExpressionProcesser ep = ExpressionProcesser.this;
+			ep.topBlock = this.topBlock;
+			ep.breakBlock = this.breakBlock;
+			
+			ep.topTry = this.topTry;
+			ep.breakTry = this.breakTry;
+			ep.catchThrowable = this.catchThrowable;
+			if (trysInCatch != null) {
+				for (int i = topTry + 1; i < ep.trysInCatch.length; i++) {
+					ep.trysInCatch[i] = null;
+				}
+			}
+			
+			ep.errorOccurred = this.errorOccurred;
+			ep.novalueException = ep.novalueException;
+			ep.exception = this.exception;
+			ep.ignoreExpression = this.ignoreExpression;
+			
+			// Pop stack down to saved state.
+			for (int i = expressionStack.size()-1; i > this.expressionStackPos; i--) {
+				expressionStack.remove(i);
+				expressionTypeStack.remove(i);
+			}
+			
+			ep.ifElseNesting = this.ifElseNesting;
+			ep.ifElseIgnoreNestCount = this.ifElseIgnoreNestCount;
+			ep.ifElseSkipTruePart = this.ifElseSkipTruePart;
+			
+			ep.indent = this.indent;
+			
+			if (expressionProxies != null) {
+				for (int i = expressionProxies.size() - 1; i > this.expressionProxyPos; i--) {
+					expressionProxies.remove(i);
+				}
+			}
+			
+			// These settings can't cross mark boundaries, so reset them to not set. This is in case we were in this state somewhere
+			// in the mark when the restore occurred.
+			ep.conditionalIgnoreNestCount = 0;
+			ep.conditionalNesting = 0;
+			ep.skipTruePart = false;
+			
+			ep.infixIgnoreNestCount = 0;
+			ep.infixNesting = 0;
+		}
+	}
+	
+	/**
+	 * Create the save state with the given id.
+	 * @param markID
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	protected SaveState createSaveState(int markID) {
+		return new SaveState(markID);
+	}
+	
+	/**
+	 * Push the start of a mark.
+	 * @param markNumber
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushMark(int markNumber) {
+		if (traceOn)
+			printTrace("Mark#"+markNumber, false);
+		
+		if (saveStates == null)
+			saveStates = new ArrayList();
+		saveStates.add(createSaveState(markNumber));
+		
+		if (traceOn)
+			printTraceEnd();
+	}
+	
+	/**
+	 * Push the end mark. If there is no error, it will simply
+	 * remove it and all save states in the map after it. If there
+	 * is an error it will do this plus it will restore the state.
+	 * <p>
+	 * It is assumed that the calls are coming in correct order from
+	 * the server so we won't check validity.
+	 * 
+	 * @param markID
+	 * @param restore
+	 * 
+	 * @since 1.1.0
+	 */
+	public final void pushEndmark(int markID, boolean restore) {
+		if (traceOn)
+			printTrace("End Mark#"+markID+" Restored="+restore, false);
+		
+		try {
+			if (saveStates != null) {
+				// Start from the end (since that is where it most likely will be) and start
+				// search, removing the end one until we reach the markID.
+				for (int i = saveStates.size() - 1; i >= 0; i--) {
+					SaveState state = (SaveState) saveStates.remove(i);
+					if (state.markID == markID) {
+						// We found it.
+						if (restore)
+							state.restoreState();
+						return;
+					}
+				}
+				// But to be safe, if we got here, this is bad. We tried restore a mark we didn't have.
+				processSyntaxException(new IllegalStateException("Tried to do an end mark on a non-existing markID (" + markID + ')'));
+			}
+		} finally {
+			if (traceOn)
+				printTraceEnd();
+		}
+	}
+
 }
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/ForExpression.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/ForExpression.java
new file mode 100644
index 0000000..18e1ee0
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/ForExpression.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: ForExpression.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+
+/**
+ * Enum for the forExpression parameters.
+ * <p>
+ * This is not meant to be subclassed by customers.
+ * @since 1.1.0
+ */
+public class ForExpression extends AbstractEnum {
+
+	/**
+	 * forExpression: Creating a root expression
+	 */
+	public static final int ROOTEXPRESSION_VALUE = 0;
+
+	public static final ForExpression ROOTEXPRESSION = new ForExpression(ROOTEXPRESSION_VALUE, "Root");
+
+	/**
+	 * forExpression: Creating the array expression for an array access (i.e. the array to access)
+	 */
+	public static final int ARRAYACCESS_ARRAY_VALUE = 1;
+
+	public static final ForExpression ARRAYACCESS_ARRAY = new ForExpression(ARRAYACCESS_ARRAY_VALUE, "Array Access: Array Operand");
+
+	/**
+	 * forExpression: Creating an index expression for an array access (i.e. one of the expressions within the <code>[]</code>).
+	 */
+	public static final int ARRAYACCESS_INDEX_VALUE = 2;
+
+	public static final ForExpression ARRAYACCESS_INDEX = new ForExpression(ARRAYACCESS_INDEX_VALUE, "Array Access: Index");
+
+	/**
+	 * forExpression: Creating an dimension expression for an array creation (i.e. one of the expressions within the <code>[]</code>).
+	 */
+	public static final int ARRAYCREATION_DIMENSION_VALUE = 3;
+
+	public static final ForExpression ARRAYCREATION_DIMENSION = new ForExpression(ARRAYCREATION_DIMENSION_VALUE, "Array Access: Dimension");
+
+	/**
+	 * forExpression: Creating an expression for an array initializer (i.e. one of the expressions with the <code>{}</code>). Special case is that
+	 * array initializers are valid as an expression within an array initializer and it doesn't use a for expression.
+	 */
+	public static final int ARRAYINITIALIZER_EXPRESSION_VALUE = 4;
+
+	public static final ForExpression ARRAYINITIALIZER_EXPRESSION = new ForExpression(ARRAYINITIALIZER_EXPRESSION_VALUE, "Array Initializer");
+
+	/**
+	 * forExpression: Creating the expression for the cast (i.e. the expresion after the <code>(type)</code>).
+	 */
+	public static final int CAST_EXPRESSION_VALUE = 5;
+
+	public static final ForExpression CAST_EXPRESSION = new ForExpression(CAST_EXPRESSION_VALUE, "Cast");
+
+	/**
+	 * forExpression: Creating the argument expression for the new instance.
+	 */
+	public static final int CLASSINSTANCECREATION_ARGUMENT_VALUE = 6;
+
+	public static final ForExpression CLASSINSTANCECREATION_ARGUMENT = new ForExpression(CLASSINSTANCECREATION_ARGUMENT_VALUE,
+			"Class Instance Creation: Argument");
+
+	/**
+	 * forExpression: Creating the condition for a conditional expression.
+	 */
+	public static final int CONDITIONAL_CONDITION_VALUE = 7;
+
+	public static final ForExpression CONDITIONAL_CONDITION = new ForExpression(CONDITIONAL_CONDITION_VALUE, "Conditional: Condition");
+
+	/**
+	 * forExpression: Creating the true (then) expression for a conditional expression.
+	 */
+	public static final int CONDITIONAL_TRUE_VALUE = 8;
+
+	public static final ForExpression CONDITIONAL_TRUE = new ForExpression(CONDITIONAL_TRUE_VALUE, "Conditional: True");
+
+	/**
+	 * forExpression: Creating the false (else) condition for a conditional expression.
+	 */
+	public static final int CONDITIONAL_FALSE_VALUE = 9;
+
+	public static final ForExpression CONDITIONAL_FALSE = new ForExpression(CONDITIONAL_FALSE_VALUE, "Conditional: False");
+
+	/**
+	 * forExpression: Creating the receiver for a field access (i.e. the expression before the ".")
+	 */
+	public static final int FIELD_RECEIVER_VALUE = 10;
+
+	public static final ForExpression FIELD_RECEIVER = new ForExpression(FIELD_RECEIVER_VALUE, "Field Access: Receiver");
+
+	/**
+	 * forExpression: Creating the left operand of an infix expression.
+	 */
+	public static final int INFIX_LEFT_VALUE = 11;
+
+	public static final ForExpression INFIX_LEFT = new ForExpression(INFIX_LEFT_VALUE, "Infix: Left");
+
+	/**
+	 * forExpression: Creating the right operand of an infix expression.
+	 */
+	public static final int INFIX_RIGHT_VALUE = 12;
+
+	public static final ForExpression INFIX_RIGHT = new ForExpression(INFIX_RIGHT_VALUE, "Infix: Right");
+
+	/**
+	 * forExpression: Creating an extended operand of an infix expression.
+	 */
+	public static final int INFIX_EXTENDED_VALUE = 13;
+
+	public static final ForExpression INFIX_EXTENDED = new ForExpression(INFIX_EXTENDED_VALUE, "Infix: Extended");
+
+	/**
+	 * forExpression: Creating the value expression of an instanceof.
+	 */
+	public static final int INSTANCEOF_VALUE_VALUE = 14;
+
+	public static final ForExpression INSTANCEOF_VALUE = new ForExpression(INSTANCEOF_VALUE_VALUE, "Instanceof");
+
+	/**
+	 * forExpression: Creating a receiver expression for a method invocation.
+	 */
+	public static final int METHOD_RECEIVER_VALUE = 15;
+
+	public static final ForExpression METHOD_RECEIVER = new ForExpression(METHOD_RECEIVER_VALUE, "Method Invoke: Receiver");
+
+	/**
+	 * forExpression: Creating an argument for a method invocation.
+	 */
+	public static final int METHOD_ARGUMENT_VALUE = 16;
+
+	public static final ForExpression METHOD_ARGUMENT = new ForExpression(METHOD_ARGUMENT_VALUE, "Method Invoke: Argument");
+
+	/**
+	 * forExpression: Creating the operand expression for a prefix operator.
+	 */
+	public static final int PREFIX_OPERAND_VALUE = 17;
+
+	public static final ForExpression PREFIX_OPERAND = new ForExpression(PREFIX_OPERAND_VALUE, "Prefix: Operand");
+
+	/**
+	 * forExpression: Creating the right operand of an assignment operator.
+	 * 
+	 * @since 1.1.0
+	 */
+	public static final int ASSIGNMENT_RIGHT_VALUE = 18;
+
+	public static final ForExpression ASSIGNMENT_RIGHT = new ForExpression(ASSIGNMENT_RIGHT_VALUE, "Assignment: Right");
+
+	/**
+	 * forExpression: Creating the left operand of an assignment operator.
+	 * <p>
+	 * Note: The left expression can only be a FieldAccess or ArrayAccess.
+	 */
+	public static final int ASSIGNMENT_LEFT_VALUE = 19;
+
+	public static final ForExpression ASSIGNMENT_LEFT = new ForExpression(ASSIGNMENT_LEFT_VALUE, "Assignment: Left");
+
+	/**
+	 * forExpression: Creating the throw operand of the throw expression.
+	 */
+	public static final int THROW_OPERAND_VALUE = 20;
+
+	public static final ForExpression THROW_OPERAND = new ForExpression(THROW_OPERAND_VALUE, "Throw operand");
+
+	/**
+	 * forExpression: Creating the if conditional operand of the if expression.
+	 */
+	public static final int IF_CONDITION_VALUE = 21;
+
+	public static final ForExpression IF_CONDITION = new ForExpression(IF_CONDITION_VALUE, "If condition");
+
+	/**
+	 * forExpression: Creating the if true clause of the if expression.
+	 */
+	public static final int IF_TRUE_VALUE = 22;
+
+	public static final ForExpression IF_TRUE = new ForExpression(IF_TRUE_VALUE, "If true clause");
+
+	/**
+	 * forExpression: Creating the if else clause of the if expression.
+	 */
+	public static final int IF_ELSE_VALUE = 23;
+
+	public static final ForExpression IF_ELSE = new ForExpression(IF_ELSE_VALUE, "If else clause");
+
+	
+	/**
+	 * This is not private, but protected only so that proxy core can add an internal ForExpression enum.
+	 * <p>
+	 * This is not meant to be subclassed by customers.
+	 * @param value
+	 * @param name
+	 * 
+	 * @since 1.1.0
+	 */
+	protected ForExpression(int value, String name) {
+		super(value, name);
+	}
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/IExpressionConstants.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/IExpressionConstants.java
index 984efa6..8b61eaa 100644
--- a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/IExpressionConstants.java
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/IExpressionConstants.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IExpressionConstants.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:55:20 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.initParser.tree;
  
@@ -22,253 +22,5 @@
  * @since 1.0.0
  */
 public interface IExpressionConstants {
-
-	/**
-	 * The expression (or some nested expression) did not return a value. I.e. it was <code>void</code>.
-	 * This would occur only if the value of expression was being retrieved through getExpressionValue,
-	 * or if a nested expression was used, since in that case the value would of been used as an
-	 * argument or receiver to another expression.
-	 * 
-	 * @since 1.0.0
-	 */
-	public static class NoExpressionValueException extends Exception {
-		
-		/**
-		 * Construct with no arguments.
-		 * 
-		 * @since 1.0.0
-		 */
-		public NoExpressionValueException() {
-			super();
-		}
-	
-		/**
-		 * Construct with a message.
-		 * 
-		 * @param message
-		 * 
-		 * @since 1.0.0
-		 */
-		public NoExpressionValueException(String message) {
-			super(message);
-		}
-	}
-
-	/**
-	 * Infix times "*"
-	 */
-	int IN_TIMES = 0;
-	
-	/**
-	 * Infix divide "/"
-	 */
-	int IN_DIVIDE = 1;
-	
-	/**
-	 * Infix remainder "%"
-	 */
-	int IN_REMAINDER = 2;
-	
-	/**
-	 * Infix plus "+"
-	 */
-	int IN_PLUS = 3;
-	
-	/**
-	 * Infix minus "-"
-	 */
-	int IN_MINUS = 4;
-	
-	/**
-	 * Infix left shift "<<"
-	 */
-	int IN_LEFT_SHIFT = 5;
-	
-	/**
-	 * Infix right shift signed ">>"
-	 */
-	int IN_RIGHT_SHIFT_SIGNED = 6;
-	
-	/**
-	 * Infix right shift unsigned ">>>"
-	 */
-	int IN_RIGHT_SHIFT_UNSIGNED = 7;
-	
-	/**
-	 * Infix less "<"
-	 */
-	int IN_LESS = 8;
-	
-	/**
-	 * Infix greater ">"
-	 */
-	int IN_GREATER = 9;
-	
-	/**
-	 * Infix less than or equals "<="
-	 */
-	int IN_LESS_EQUALS = 10;
-	
-	/**
-	 * Infix Greater than or equlas ">="
-	 */
-	int IN_GREATER_EQUALS = 11;
-	
-	/**
-	 * Infix equals "=="
-	 */
-	int IN_EQUALS = 12;
-	
-	/**
-	 * Infix not equals "!="
-	 */
-	int IN_NOT_EQUALS = 13;
-	
-	/**
-	 * Infix exclusive or "^"
-	 */
-	int IN_XOR = 14;
-	
-	/**
-	 * Infix bitwise and "&"
-	 */
-	int IN_AND = 15;
-	
-	/**
-	 * Infix bitwise or "|"
-	 */
-	int IN_OR = 16;
-	
-	/**
-	 * Infix Conditional logical and "&&"
-	 */
-	int IN_CONDITIONAL_AND = 17;
-	
-	/**
-	 * Infix Conditional logical or "||"
-	 */
-	int IN_CONDITIONAL_OR = 18;
-	
-	/**
-	 * Max value of Infix operators.
-	 */
-	int IN_MAX = 18;
-	
-	/**
-	 * Prefix plus "+"
-	 */
-	int PRE_PLUS = 0;
-	
-	/**
-	 * Prefix minus "-"
-	 */
-	int PRE_MINUS = 1;
-	
-	/**
-	 * Prefix bitwise complement "~"
-	 */
-	int PRE_COMPLEMENT = 2;
-	
-	/**
-	 * Prefix logical not "!"
-	 */
-	int PRE_NOT = 3;
-	
-	/**
-	 * Max value of the Prefix operators.
-	 */
-	int PRE_MAX = 3;
-
-	/**
-	 * forExpression: Creating a root expression
-	 */
-	int ROOTEXPRESSION = 0;
-
-	/**
-	 * forExpression: Creating the array expression for an array access (i.e. the array to access)
-	 */
-	int ARRAYACCESS_ARRAY = 1;
-
-	/**
-	 * forExpression: Creating an index expression for an array access (i.e. one of the expressions within the <code>[]</code>).
-	 */
-	int ARRAYACCESS_INDEX = 2;
-
-	/**
-	 * forExpression: Creating an dimension expression for an array creation (i.e. one of the expressions within the <code>[]</code>).
-	 */
-	int ARRAYCREATION_DIMENSION = 3;
-
-	/**
-	 * forExpression: Creating an expression for an array initializer (i.e. one of the expressions with the <code>{}</code>).
-	 * Special case is that array initializers are valid as an expression within an array initializer and it doesn't use
-	 * a for expression.
-	 */
-	int ARRAYINITIALIZER_EXPRESSION = 4;
-
-	/**
-	 * forExpression: Creating the expression for the cast (i.e. the expresion after the <code>(type)</code>).
-	 */
-	int CAST_EXPRESSION = 5;
-
-	/**
-	 * forExpression: Creating the argument expression for the new instance.
-	 */
-	int CLASSINSTANCECREATION_ARGUMENT = 6;
-
-	/**
-	 * forExpression: Creating the condition for a conditional expression.
-	 */
-	int CONDITIONAL_CONDITION = 7;
-
-	/**
-	 * forExpression: Creating the true (then) expression for a conditional expression.
-	 */
-	int CONDITIONAL_TRUE = 8;
-
-	/**
-	 * forExpression: Creating the false (else) condition for a conditional expression.
-	 */
-	int CONDITIONAL_FALSE = 9;
-
-	/**
-	 * forExpression: Creating the receiver for a field access (i.e. the expression before the ".")
-	 */
-	int FIELD_RECEIVER = 10;
-
-	/**
-	 * forExpression: Creating the left operand of an infix expression.
-	 */
-	int INFIX_LEFT = 11;
-
-	/**
-	 * forExpression: Creating the right operand of an infix expression.
-	 */
-	int INFIX_RIGHT = 12;
-
-	/**
-	 * forExpression: Creating an extended operand of an infix expression.
-	 */
-	int INFIX_EXTENDED = 13;
-
-	/**
-	 * forExpression: Creating the value expression of an instanceof.
-	 */
-	int INSTANCEOF_VALUE = 14;
-
-	/**
-	 * forExpression: Creating a receiver expression for a method invocation.
-	 */
-	int METHOD_RECEIVER = 15;
-
-	/**
-	 * forExpression: Creating an argument for a method invocation.
-	 */
-	int METHOD_ARGUMENT = 16;
-	
-	/**
-	 * forExpression: Creating the operand expression for a prefix operator.
-	 */
-	int PREFIX_OPERAND = 17;
 	
 }
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/IInternalExpressionConstants.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/IInternalExpressionConstants.java
deleted file mode 100644
index 8167b61..0000000
--- a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/IInternalExpressionConstants.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*******************************************************************************
- * 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: IInternalExpressionConstants.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:55:20 $ 
- */
-package org.eclipse.jem.internal.proxy.initParser.tree;
- 
-/**
- * These constants are for communicating between the IDE and the proxy side
- * for expression evaluation.
- * 
- * @since 1.0.0
- */
-public interface IInternalExpressionConstants {
-	
-	/**
-	 * ARRAY ACCESS Expression
-	 */
-	int ARRAY_ACCESS_EXPRESSION = 1;
-	
-	/**
-	 * ARRAY CREATION Expression
-	 */
-	int ARRAY_CREATION_EXPRESSION = 2;
-	
-	/**
-	 * ARRAY INITIALIZER expression
-	 */
-	int ARRAY_INITIALIZER_EXPRESSION = 3;
-	
-	/**
-	 * CAST Expression.
-	 */
-	int CAST_EXPRESSION = 4;
-	
-	/**
-	 * CONDITIONAL expression
-	 */
-	int CONDITIONAL_EXPRESSION = 5;
-	
-	/**
-	 * CLASS INSTANCE CREATION expression
-	 */
-	int CLASS_INSTANCE_CREATION_EXPRESSION = 6;
-	
-	/**
-	 * FIELD ACCESS expression.
-	 */
-	int FIELD_ACCESS_EXPRESSION = 7;
-	
-	/**
-	 * INSTANCEOF Expression.
-	 */
-	int INSTANCEOF_EXPRESSION = 8;
-
-	/**
-	 * Infix expression
-	 */
-	int INFIX_EXPRESSION = 9;
-	
-	/**
-	 * Method expression.
-	 */
-	int METHOD_EXPRESSION = 10;
-	
-	/**
-	 * Prefix expression
-	 */
-	int PREFIX_EXPRESSION = 11;
-	
-	/**
-	 * Push to proxy expression.
-	 */
-	int PUSH_TO_PROXY_EXPRESSION = 12;
-	
-	/**
-	 * Type literal Expression.
-	 */
-	int TYPELITERAL_EXPRESSION = 13;
-	
-	/**
-	 * Type receiver expression.
-	 */
-	int TYPERECEIVER_EXPRESSION = 14;
-
-	
-	/**
-	 * Used in Infix processing. Left operand on expression stack
-	 */
-	int INFIX_LEFT_OPERAND = 0;
-	
-	/**
-	 * Used in Infix processing. Other operand (but not last) on expression stack 
-	 */
-	int INFIX_OTHER_OPERAND = 1;
-	
-	/**
-	 * Used in Infix processing. Rightmost (last) operand on expression stack
-	 */
-	int INFIX_LAST_OPERAND = 2;
-}
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InfixOperator.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InfixOperator.java
new file mode 100644
index 0000000..f74f672
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InfixOperator.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: InfixOperator.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+
+/**
+ * Enum for Infix operator
+ * 
+ * @since 1.1.0
+ */
+public class InfixOperator extends AbstractEnum {
+
+	/**
+	 * Infix times "*"
+	 */
+	public static final int IN_TIMES_VALUE = 0;
+
+	public static final InfixOperator IN_TIMES = new InfixOperator(IN_TIMES_VALUE, "Infix *");
+
+	/**
+	 * Infix divide "/"
+	 */
+	public static final int IN_DIVIDE_VALUE = 1;
+
+	public static final InfixOperator IN_DIVIDE = new InfixOperator(IN_DIVIDE_VALUE, "Infix /");
+
+	/**
+	 * Infix remainder "%"
+	 */
+	public static final int IN_REMAINDER_VALUE = 2;
+
+	public static final InfixOperator IN_REMAINDER = new InfixOperator(IN_REMAINDER_VALUE, "Infix %");
+
+	/**
+	 * Infix plus "+"
+	 */
+	public static final int IN_PLUS_VALUE = 3;
+
+	public static final InfixOperator IN_PLUS = new InfixOperator(IN_PLUS_VALUE, "Infix +");
+
+	/**
+	 * Infix minus "-"
+	 */
+	public static final int IN_MINUS_VALUE = 4;
+
+	public static final InfixOperator IN_MINUS = new InfixOperator(IN_MINUS_VALUE, "Infix -");
+
+	/**
+	 * Infix left shift " < <"
+	 */
+	public static final int IN_LEFT_SHIFT_VALUE = 5;
+
+	public static final InfixOperator IN_LEFT_SHIFT = new InfixOperator(IN_LEFT_SHIFT_VALUE, "Infix <<");
+
+	/**
+	 * Infix right shift signed ">>"
+	 */
+	public static final int IN_RIGHT_SHIFT_SIGNED_VALUE = 6;
+
+	public static final InfixOperator IN_RIGHT_SHIFT_SIGNED = new InfixOperator(IN_RIGHT_SHIFT_SIGNED_VALUE, "Infix >>");
+
+	/**
+	 * Infix right shift unsigned ">>>"
+	 */
+	public static final int IN_RIGHT_SHIFT_UNSIGNED_VALUE = 7;
+
+	public static final InfixOperator IN_RIGHT_SHIFT_UNSIGNED = new InfixOperator(IN_RIGHT_SHIFT_UNSIGNED_VALUE, "Infix >>>");
+
+	/**
+	 * Infix less " <"
+	 */
+	public static final int IN_LESS_VALUE = 8;
+
+	public static final InfixOperator IN_LESS = new InfixOperator(IN_LESS_VALUE, "Infix <");
+
+	/**
+	 * Infix greater ">"
+	 */
+	public static final int IN_GREATER_VALUE = 9;
+
+	public static final InfixOperator IN_GREATER = new InfixOperator(IN_GREATER_VALUE, "Infix >");
+
+	/**
+	 * Infix less than or equals " <="
+	 */
+	public static final int IN_LESS_EQUALS_VALUE = 10;
+
+	public static final InfixOperator IN_LESS_EQUALS = new InfixOperator(IN_LESS_EQUALS_VALUE, "Infix <=");
+
+	/**
+	 * Infix Greater than or equlas ">="
+	 */
+	public static final int IN_GREATER_EQUALS_VALUE = 11;
+
+	public static final InfixOperator IN_GREATER_EQUALS = new InfixOperator(IN_GREATER_EQUALS_VALUE, "Infix >=");
+
+	/**
+	 * Infix equals "=="
+	 */
+	public static final int IN_EQUALS_VALUE = 12;
+
+	public static final InfixOperator IN_EQUALS = new InfixOperator(IN_EQUALS_VALUE, "Infix ==");
+
+	/**
+	 * Infix not equals "!="
+	 */
+	public static final int IN_NOT_EQUALS_VALUE = 13;
+
+	public static final InfixOperator IN_NOT_EQUALS = new InfixOperator(IN_NOT_EQUALS_VALUE, "Infix !=");
+
+	/**
+	 * Infix exclusive or "^"
+	 */
+	public static final int IN_XOR_VALUE = 14;
+
+	public static final InfixOperator IN_XOR = new InfixOperator(IN_XOR_VALUE, "Infix ^");
+
+	/**
+	 * Infix bitwise and "&"
+	 */
+	public static final int IN_AND_VALUE = 15;
+
+	public static final InfixOperator IN_AND = new InfixOperator(IN_AND_VALUE, "Infix &");
+
+	/**
+	 * Infix bitwise or "|"
+	 */
+	public static final int IN_OR_VALUE = 16;
+
+	public static final InfixOperator IN_OR = new InfixOperator(IN_OR_VALUE, "Infix |");
+
+	/**
+	 * Infix Conditional logical and "&&"
+	 */
+	public static final int IN_CONDITIONAL_AND_VALUE = 17;
+
+	public static final InfixOperator IN_CONDITIONAL_AND = new InfixOperator(IN_CONDITIONAL_AND_VALUE, "Infix &&");
+
+	/**
+	 * Infix Conditional logical or "||"
+	 */
+	public static final int IN_CONDITIONAL_OR_VALUE = 18;
+
+	public static final InfixOperator IN_CONDITIONAL_OR = new InfixOperator(IN_CONDITIONAL_OR_VALUE, "Ifnix ||");
+
+	/**
+	 * Return the infix operator for the given enum value.
+	 * @param value
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public static InfixOperator get(int value) {
+		switch (value) {
+			case IN_TIMES_VALUE:
+				return IN_TIMES;
+			case IN_DIVIDE_VALUE:
+				return IN_DIVIDE;
+			case IN_REMAINDER_VALUE:
+				return IN_REMAINDER;
+			case IN_PLUS_VALUE:
+				return IN_PLUS;
+			case IN_MINUS_VALUE:
+				return IN_MINUS;
+			case IN_LEFT_SHIFT_VALUE:
+				return IN_LEFT_SHIFT;
+			case IN_RIGHT_SHIFT_SIGNED_VALUE:
+				return IN_RIGHT_SHIFT_SIGNED;
+			case IN_RIGHT_SHIFT_UNSIGNED_VALUE:
+				return IN_RIGHT_SHIFT_UNSIGNED;
+			case IN_LESS_VALUE:
+				return IN_LESS;
+			case IN_GREATER_VALUE:
+				return IN_GREATER;
+			case IN_LESS_EQUALS_VALUE:
+				return IN_LESS_EQUALS;
+			case IN_GREATER_EQUALS_VALUE:
+				return IN_GREATER_EQUALS;
+			case IN_EQUALS_VALUE:
+				return IN_EQUALS;
+			case IN_NOT_EQUALS_VALUE:
+				return IN_NOT_EQUALS;
+			case IN_XOR_VALUE:
+				return IN_XOR;
+			case IN_AND_VALUE:
+				return IN_AND;
+			case IN_OR_VALUE:
+				return IN_OR;
+			case IN_CONDITIONAL_AND_VALUE:
+				return IN_CONDITIONAL_AND;
+			case IN_CONDITIONAL_OR_VALUE:
+				return IN_CONDITIONAL_OR;
+		}
+		return null;
+	}
+
+	private InfixOperator(int value, String name) {
+		super(value, name);
+	}
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalConditionalOperandType.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalConditionalOperandType.java
new file mode 100644
index 0000000..3723651
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalConditionalOperandType.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: InternalConditionalOperandType.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+
+/**
+ * Internal class for the Conditional operand type. Not meant to be used by customers.
+ * 
+ * @since 1.1.0
+ */
+public class InternalConditionalOperandType extends AbstractEnum {
+
+	/**
+	 * Used in Conditional processing. False operand on expression stack
+	 */
+	public final static int CONDITIONAL_FALSE_VALUE = 0;
+
+	public final static InternalConditionalOperandType CONDITIONAL_FALSE = new InternalConditionalOperandType(CONDITIONAL_FALSE_VALUE,
+			"Conditional False Operand Flag");
+
+	/**
+	 * Used in Conditional processing. True operand on expression stack
+	 */
+	public final static int CONDITIONAL_TRUE_VALUE = 1;
+
+	public final static InternalConditionalOperandType CONDITIONAL_TRUE = new InternalConditionalOperandType(CONDITIONAL_TRUE_VALUE,
+			"Conditional True Operand Flag");
+
+	/**
+	 * Used in Conditional processing. Test operand on expression stack
+	 */
+	public final static int CONDITIONAL_TEST_VALUE = 2;
+
+	public final static InternalConditionalOperandType CONDITIONAL_TEST = new InternalConditionalOperandType(CONDITIONAL_TEST_VALUE,
+			"Conditional Test Operand Flag");
+
+	/**
+	 * Return the enum for the given value.
+	 * @param value
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public static InternalConditionalOperandType get(int value) {
+		switch (value) {
+			case CONDITIONAL_FALSE_VALUE:
+				return CONDITIONAL_FALSE;
+			case CONDITIONAL_TRUE_VALUE:
+				return CONDITIONAL_TRUE;
+			case CONDITIONAL_TEST_VALUE:
+				return CONDITIONAL_TEST;
+		}
+		return null;
+	}
+
+	private InternalConditionalOperandType(int value, String name) {
+		super(value, name);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalExpressionProxy.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalExpressionProxy.java
new file mode 100644
index 0000000..f913089
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalExpressionProxy.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/*
+ *  $RCSfile: InternalExpressionProxy.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+ 
+
+/**
+ * This interface is used for expression proxies in the evaluation side (in {@link org.eclipse.jem.internal.proxy.initParser.tree.ExpressionProcesser}).
+ * <p>
+ * It is meant to be implemented only by users of the ExpressionProcessor.
+ * 
+ * @since 1.1.0
+ */
+public interface InternalExpressionProxy {
+	
+	/**
+	 * Get the id of the proxy.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public int getProxyID();
+	
+	/**
+	 * Called by ExpressionProcesser to give the expression proxy its value and type, i.e. it has been evaluated.
+	 * <p>
+	 * The type may not be the actual type of the value, it may be a superclass of it. It is the type that the proxy
+	 * represents from the return of the expression. For instance it may of returned null but it is supposed to be
+	 * java.lang.String. Or it is supposed to be a primitive int, since we can't store that, we need to store
+	 * an Integer value with the type indicating it is Interger.TYPE.
+	 * 
+	 * @param value
+	 * @param type
+	 * 
+	 * @since 1.1.0
+	 */
+	public void setProxy(Object value, Class type);
+	
+	/**
+	 * Get the value of the proxy. 
+	 * <p>
+	 * Note: The value may be a {@link VariableReference}, in which
+	 * case further dereferencing may be with the returned value.
+	 * @return the value of the proxy, it may be an ExpressionProcesser.VariableReference.
+	 * 
+	 * @since 1.1.0
+	 */
+	public Object getValue();
+	
+	/**
+	 * Get the type of the proxy.
+	 * @return
+	 * 
+	 * @see InternalExpressionProxy#setProxy(Object, Class) for what type means.
+	 * @since 1.1.0
+	 */
+	public Class getType();
+
+	/**
+	 * Return whether the proxy has had a value/class set into it yet.
+	 * @return <code>true</code> if it has been set.
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean isSet();
+}
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalExpressionTypes.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalExpressionTypes.java
new file mode 100644
index 0000000..b6ebbc9
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalExpressionTypes.java
@@ -0,0 +1,276 @@
+package org.eclipse.jem.internal.proxy.initParser.tree;
+
+/**
+ * These constants are for communicating between the IDE and the proxy side for expression evaluation. It is not meant to be used by customers.
+ * 
+ * @since 1.0.0
+ */
+public class InternalExpressionTypes extends AbstractEnum {
+
+	/**
+	 * ARRAY ACCESS Expression
+	 */
+	public final static int ARRAY_ACCESS_EXPRESSION_VALUE = 1;
+
+	public final static InternalExpressionTypes ARRAY_ACCESS_EXPRESSION = new InternalExpressionTypes(ARRAY_ACCESS_EXPRESSION_VALUE,
+			"Array Access Expression");
+
+	/**
+	 * ARRAY CREATION Expression
+	 */
+	public final static int ARRAY_CREATION_EXPRESSION_VALUE = 2;
+
+	public final static InternalExpressionTypes ARRAY_CREATION_EXPRESSION = new InternalExpressionTypes(ARRAY_CREATION_EXPRESSION_VALUE,
+			"Array Creation Expression");
+
+	/**
+	 * ARRAY INITIALIZER expression
+	 */
+	public final static int ARRAY_INITIALIZER_EXPRESSION_VALUE = 3;
+
+	public final static InternalExpressionTypes ARRAY_INITIALIZER_EXPRESSION = new InternalExpressionTypes(ARRAY_INITIALIZER_EXPRESSION_VALUE,
+			"Array Initializer Expression");
+
+	/**
+	 * CAST Expression.
+	 */
+	public final static int CAST_EXPRESSION_VALUE = 4;
+
+	public final static InternalExpressionTypes CAST_EXPRESSION = new InternalExpressionTypes(CAST_EXPRESSION_VALUE, "Cast Expression");
+
+	/**
+	 * CONDITIONAL expression
+	 */
+	public final static int CONDITIONAL_EXPRESSION_VALUE = 5;
+
+	public final static InternalExpressionTypes CONDITIONAL_EXPRESSION = new InternalExpressionTypes(CONDITIONAL_EXPRESSION_VALUE,
+			"Conditional Expression");
+
+	/**
+	 * CLASS INSTANCE CREATION expression
+	 */
+	public final static int CLASS_INSTANCE_CREATION_EXPRESSION_VALUE = 6;
+
+	public final static InternalExpressionTypes CLASS_INSTANCE_CREATION_EXPRESSION = new InternalExpressionTypes(
+			CLASS_INSTANCE_CREATION_EXPRESSION_VALUE, "Class Instance Creation Expression");
+
+	/**
+	 * FIELD ACCESS expression.
+	 */
+	public final static int FIELD_ACCESS_EXPRESSION_VALUE = 7;
+
+	public final static InternalExpressionTypes FIELD_ACCESS_EXPRESSION = new InternalExpressionTypes(FIELD_ACCESS_EXPRESSION_VALUE,
+			"Field Access Expression");
+
+	/**
+	 * INSTANCEOF Expression.
+	 */
+	public final static int INSTANCEOF_EXPRESSION_VALUE = 8;
+
+	public final static InternalExpressionTypes INSTANCEOF_EXPRESSION = new InternalExpressionTypes(INSTANCEOF_EXPRESSION_VALUE,
+			"Instanceof Expression");
+
+	/**
+	 * Infix expression
+	 */
+	public final static int INFIX_EXPRESSION_VALUE = 9;
+
+	public final static InternalExpressionTypes INFIX_EXPRESSION = new InternalExpressionTypes(INFIX_EXPRESSION_VALUE, "Infix Expression");
+
+	/**
+	 * Method expression.
+	 */
+	public final static int METHOD_EXPRESSION_VALUE = 10;
+
+	public final static InternalExpressionTypes METHOD_EXPRESSION = new InternalExpressionTypes(METHOD_EXPRESSION_VALUE, "Method Invoke Expression");
+
+	/**
+	 * Prefix expression
+	 */
+	public final static int PREFIX_EXPRESSION_VALUE = 11;
+
+	public final static InternalExpressionTypes PREFIX_EXPRESSION = new InternalExpressionTypes(PREFIX_EXPRESSION_VALUE, "Prefix Expression");
+
+	/**
+	 * Push to proxy expression.
+	 */
+	public final static int PUSH_TO_PROXY_EXPRESSION_VALUE = 12;
+
+	public final static InternalExpressionTypes PUSH_TO_PROXY_EXPRESSION = new InternalExpressionTypes(PUSH_TO_PROXY_EXPRESSION_VALUE,
+			"Push to Proxy Expression");
+
+	/**
+	 * Push BeanType expression proxy expression.
+	 */
+	public final static int PUSH_BEANTYPE_EXPRESSIONPROXY_EXPRESSION_VALUE = 13;
+	
+	public final static InternalExpressionTypes PUSH_BEANTYPE_EXPRESSIONPROXY_EXPRESSION = new InternalExpressionTypes(PUSH_BEANTYPE_EXPRESSIONPROXY_EXPRESSION_VALUE,
+			"Push BeanType ExpressionProxy Expression");
+
+	
+	/**
+	 * Type receiver expression.
+	 */
+	public final static int TYPERECEIVER_EXPRESSION_VALUE = 14;
+
+	public final static InternalExpressionTypes TYPERECEIVER_EXPRESSION = new InternalExpressionTypes(TYPERECEIVER_EXPRESSION_VALUE,
+			"Type Receiver Expression");
+
+	/**
+	 * Assignment to an ExpressionProxy expression.
+	 */
+	public final static int ASSIGNMENT_PROXY_EXPRESSION_VALUE = 15;
+
+	public final static InternalExpressionTypes ASSIGNMENT_PROXY_EXPRESSION = new InternalExpressionTypes(ASSIGNMENT_PROXY_EXPRESSION_VALUE,
+			"Assignment to Proxy Expression");
+
+	/**
+	 * Push expression proxy value expression.
+	 */
+	public final static int PUSH_TO_EXPRESSION_PROXY_EXPRESSION_VALUE = 16;
+
+	public final static InternalExpressionTypes PUSH_TO_EXPRESSION_PROXY_EXPRESSION = new InternalExpressionTypes(
+			PUSH_TO_EXPRESSION_PROXY_EXPRESSION_VALUE, "Push to Expression Proxy Expression");
+
+	/**
+	 * Assignment expression.
+	 */
+	public final static int ASSIGNMENT_EXPRESSION_VALUE = 17;
+
+	public final static InternalExpressionTypes ASSIGNMENT_EXPRESSION = new InternalExpressionTypes(ASSIGNMENT_EXPRESSION_VALUE,
+			"Assignment Expression");
+
+	/**
+	 * Block End expression.
+	 */
+	public final static int BLOCK_BEGIN_EXPRESSION_VALUE = 18;
+	
+	public final static InternalExpressionTypes BLOCK_BEGIN_EXPRESSION = new InternalExpressionTypes(BLOCK_BEGIN_EXPRESSION_VALUE,
+			"Begin block Expression");
+
+	/**
+	 * Block End expression.
+	 */
+	public final static int BLOCK_BREAK_EXPRESSION_VALUE = 19;
+	
+	public final static InternalExpressionTypes BLOCK_BREAK_EXPRESSION = new InternalExpressionTypes(BLOCK_BREAK_EXPRESSION_VALUE,
+			"Break block Expression");
+
+	/**
+	 * Block End expression.
+	 */
+	public final static int BLOCK_END_EXPRESSION_VALUE = 20;
+	
+	public final static InternalExpressionTypes BLOCK_END_EXPRESSION = new InternalExpressionTypes(BLOCK_END_EXPRESSION_VALUE,
+			"End block Expression");
+
+	/**
+	 * Try Begin expression.
+	 */
+	public final static int TRY_BEGIN_EXPRESSION_VALUE = 21;
+	
+	public final static InternalExpressionTypes TRY_BEGIN_EXPRESSION = new InternalExpressionTypes(TRY_BEGIN_EXPRESSION_VALUE,
+			"Begin try Expression");
+
+	/**
+	 * Try Catch expression.
+	 */
+	public final static int TRY_CATCH_EXPRESSION_VALUE = 22;
+	
+	public final static InternalExpressionTypes TRY_CATCH_EXPRESSION = new InternalExpressionTypes(TRY_CATCH_EXPRESSION_VALUE,
+			"Try catch Expression");
+	
+	/**
+	 * Try Finally expression.
+	 */
+	public final static int TRY_FINALLY_EXPRESSION_VALUE = 23;
+	
+	public final static InternalExpressionTypes TRY_FINALLY_EXPRESSION = new InternalExpressionTypes(TRY_FINALLY_EXPRESSION_VALUE,
+			"Try finally Expression");
+
+	/**
+	 * Try End expression.
+	 */
+	public final static int TRY_END_EXPRESSION_VALUE = 24;
+	
+	public final static InternalExpressionTypes TRY_END_EXPRESSION = new InternalExpressionTypes(TRY_END_EXPRESSION_VALUE,
+			"End try Expression");
+	
+	/**
+	 * Throw expression.
+	 */
+	public final static int THROW_EXPRESSION_VALUE = 25;
+	
+	public final static InternalExpressionTypes THROW_EXPRESSION = new InternalExpressionTypes(THROW_EXPRESSION_VALUE,
+			"Throw Expression");
+
+	/**
+	 * Rethrow expression.
+	 */
+	public final static int RETHROW_EXPRESSION_VALUE = 26;
+	
+	public final static InternalExpressionTypes RETHROW_EXPRESSION = new InternalExpressionTypes(RETHROW_EXPRESSION_VALUE,
+			"Rethrow Expression");
+
+	/**
+	 * Push Method Lookup expression proxy expression.
+	 */
+	public final static int PUSH_METHOD_EXPRESSIONPROXY_EXPRESSION_VALUE = 27;
+	
+	public final static InternalExpressionTypes PUSH_METHOD_EXPRESSIONPROXY_EXPRESSION = new InternalExpressionTypes(PUSH_METHOD_EXPRESSIONPROXY_EXPRESSION_VALUE,
+			"Push Method ExpressionProxy Expression");
+
+	/**
+	 * Push Field Lookup expression proxy expression.
+	 */
+	public final static int PUSH_FIELD_EXPRESSIONPROXY_EXPRESSION_VALUE = 28;
+	
+	public final static InternalExpressionTypes PUSH_FIELD_EXPRESSIONPROXY_EXPRESSION = new InternalExpressionTypes(PUSH_FIELD_EXPRESSIONPROXY_EXPRESSION_VALUE,
+			"Push Field ExpressionProxy Expression");
+
+	/**
+	 * Push If/else (the clauses) expression proxy expression.
+	 */
+	public final static int IF_ELSE_EXPRESSION_VALUE = 29;
+	
+	public final static InternalExpressionTypes IF_ELSE_EXPRESSION = new InternalExpressionTypes(IF_ELSE_EXPRESSION_VALUE,
+			"Push If/else Expression");
+
+	/**
+	 * Push If/else condition test expression proxy expression.
+	 */
+	public final static int IF_TEST_EXPRESSION_VALUE = 30;
+	
+	public final static InternalExpressionTypes IF_TEST_EXPRESSION = new InternalExpressionTypes(IF_TEST_EXPRESSION_VALUE,
+			"Push If Test Expression");
+
+
+	/**
+	 * Push new instance from init string proxy expression.
+	 */
+	public final static int NEW_INSTANCE_VALUE = 31;
+	
+	public final static InternalExpressionTypes NEW_INSTANCE = new InternalExpressionTypes(NEW_INSTANCE_VALUE,
+			"Push New Instance Expression");
+
+
+	/**
+	 * Push mark proxy expression.
+	 */
+	public final static int MARK_VALUE = 32;
+	
+	public final static InternalExpressionTypes MARK = new InternalExpressionTypes(MARK_VALUE,
+			"Push Mark Expression");
+
+	/**
+	 * Push end mark proxy expression.
+	 */
+	public final static int ENDMARK_VALUE = 33;
+	
+	public final static InternalExpressionTypes ENDMARK = new InternalExpressionTypes(ENDMARK_VALUE,
+			"Push End Mark Expression");
+
+	private InternalExpressionTypes(int value, String name) {
+		super(value, name);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalIfElseOperandType.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalIfElseOperandType.java
new file mode 100644
index 0000000..8707a27
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalIfElseOperandType.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: InternalIfElseOperandType.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+
+/**
+ * Internal class for the If/else operand type. Not meant to be used by customers.
+ * 
+ * @since 1.1.0
+ */
+public class InternalIfElseOperandType extends AbstractEnum {
+
+	/**
+	 * Used in If/else processing. False clause on expression stack
+	 */
+	public final static int ELSE_CLAUSE_VALUE = 0;
+
+	public final static InternalIfElseOperandType ELSE_CLAUSE = new InternalIfElseOperandType(ELSE_CLAUSE_VALUE,
+			"Else Clause Flag");
+
+	/**
+	 * Used in If/else processing. If operand on expression stack
+	 */
+	public final static int TRUE_CLAUSE_VALUE = 1;
+
+	public final static InternalIfElseOperandType TRUE_CLAUSE = new InternalIfElseOperandType(TRUE_CLAUSE_VALUE,
+			"If True Clause Flag");
+
+	/**
+	 * Return the enum for the given value.
+	 * @param value
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public static InternalIfElseOperandType get(int value) {
+		switch (value) {
+			case ELSE_CLAUSE_VALUE:
+				return ELSE_CLAUSE;
+			case TRUE_CLAUSE_VALUE:
+				return TRUE_CLAUSE;
+		}
+		return null;
+	}
+
+	private InternalIfElseOperandType(int value, String name) {
+		super(value, name);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalInfixOperandType.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalInfixOperandType.java
new file mode 100644
index 0000000..e4b2e89
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/InternalInfixOperandType.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: InternalInfixOperandType.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+ 
+
+/**
+ * Internal class for the Prefix operand type. Not meant to be used by customers.
+ * @since 1.1.0
+ */
+public class InternalInfixOperandType extends AbstractEnum {
+
+	/**
+	 * Used in Infix processing. Left operand on expression stack
+	 */
+	public final static int INFIX_LEFT_OPERAND_VALUE = 0;
+	public final static InternalInfixOperandType INFIX_LEFT_OPERAND = new InternalInfixOperandType(INFIX_LEFT_OPERAND_VALUE, "Infix Left Operand Flag");
+	/**
+	 * Used in Infix processing. Other operand (but not last) on expression stack
+	 */
+	public final static int INFIX_OTHER_OPERAND_VALUE = 1;
+	public final static InternalInfixOperandType INFIX_OTHER_OPERAND = new InternalInfixOperandType(INFIX_OTHER_OPERAND_VALUE,
+	"Infix Other Operand Flag");
+	/**
+	 * Used in Infix processing. Rightmost (last) operand on expression stack
+	 */
+	public final static int INFIX_LAST_OPERAND_VALUE = 2;
+	public final static InternalInfixOperandType INFIX_LAST_OPERAND = new InternalInfixOperandType(INFIX_LAST_OPERAND_VALUE, "Infix Last Operand Flag");
+
+	/**
+	 * Return the enum for the given value.
+	 * @param value
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public static InternalInfixOperandType get(int value) {
+		switch (value) {
+			case INFIX_LAST_OPERAND_VALUE:
+				return INFIX_LAST_OPERAND;
+			case INFIX_LEFT_OPERAND_VALUE:
+				return INFIX_LEFT_OPERAND;
+			case INFIX_OTHER_OPERAND_VALUE:
+				return INFIX_OTHER_OPERAND;
+		}
+		return null;
+	}
+	
+	private InternalInfixOperandType(int value, String name) {
+		super(value, name);
+	}
+}
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/NoExpressionValueException.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/NoExpressionValueException.java
new file mode 100644
index 0000000..406da02
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/NoExpressionValueException.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: NoExpressionValueException.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+ 
+
+/**
+ * The expression (or some nested expression) did not return a value. I.e. it was <code>void</code>.
+ * This would occur only if the value of expression was being retrieved through getExpressionValue,
+ * or if a nested expression was used, since in that case the value would of been used as an
+ * argument or receiver to another expression.
+ * 
+ * @since 1.0.0
+ */
+public class NoExpressionValueException extends Exception {
+	
+	/**
+	 * Construct with no arguments.
+	 * 
+	 * @since 1.0.0
+	 */
+	public NoExpressionValueException() {
+		super();
+	}
+	
+	public NoExpressionValueException(Throwable e) {
+		super(e);
+	}
+
+	/**
+	 * Construct with a message.
+	 * 
+	 * @param message
+	 * 
+	 * @since 1.0.0
+	 */
+	public NoExpressionValueException(String message) {
+		super(message);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/PrefixOperator.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/PrefixOperator.java
new file mode 100644
index 0000000..6cc2a9c
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/PrefixOperator.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: PrefixOperator.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+
+/**
+ * Enum for prefix operator.
+ * 
+ * @since 1.1.0
+ */
+public class PrefixOperator extends AbstractEnum {
+
+	/**
+	 * Prefix plus "+"
+	 */
+	public static final int PRE_PLUS_VALUE = 0;
+
+	public static final PrefixOperator PRE_PLUS = new PrefixOperator(PRE_PLUS_VALUE, "Prefix +");
+
+	/**
+	 * Prefix minus "-"
+	 */
+	public static final int PRE_MINUS_VALUE = 1;
+
+	public static final PrefixOperator PRE_MINUS = new PrefixOperator(PRE_MINUS_VALUE, "Prefix -");
+
+	/**
+	 * Prefix bitwise complement "~"
+	 */
+	public static final int PRE_COMPLEMENT_VALUE = 2;
+
+	public static final PrefixOperator PRE_COMPLEMENT = new PrefixOperator(PRE_COMPLEMENT_VALUE, "Prefix ~");
+
+	/**
+	 * Prefix logical not "!"
+	 */
+	public static final int PRE_NOT_VALUE = 3;
+
+	public static final PrefixOperator PRE_NOT = new PrefixOperator(PRE_NOT_VALUE, "Prefix !");
+
+	/**
+	 * Return the prefix operator for the given enum value.
+	 * @param value
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public static PrefixOperator get(int value) {
+		switch (value) {
+			case PRE_PLUS_VALUE:
+				return PRE_PLUS;
+			case PRE_MINUS_VALUE:
+				return PRE_MINUS;
+			case PRE_COMPLEMENT_VALUE:
+				return PRE_COMPLEMENT;
+			case PRE_NOT_VALUE:
+				return PRE_NOT;
+		}
+		return null;
+	}
+
+	private PrefixOperator(int value, String name) {
+		super(value, name);
+	}
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/VariableReference.java b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/VariableReference.java
new file mode 100644
index 0000000..a4cd136
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/initParser/org/eclipse/jem/internal/proxy/initParser/tree/VariableReference.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/*
+ *  $RCSfile: VariableReference.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.initParser.tree;
+ 
+
+/**
+ * This represents a Variable Reference value. A variable reference value can be on the left
+ * side of an assignment (e.g. field or array access) or on any side
+ * of any expression. When on the left side of an assignment, then the
+ * value can assigned to. Such as <code>x[3] = 4</code>. Or it is value
+ * that can be used in expressions, such as <code>x[3] + 2</code>.
+ * <p>
+ * When dereferenced, the value is given (see {@link VariableReference#dereference()}) as
+ * the result or it is set with a value and then deferenced (see {@link VariableReference#set(Object, Class)}).
+ * <p>
+ * The type of the reference is the type stored in the corresponding expressionTypeStack entry. This is the type
+ * for assignment, and the type for dereferenced.
+ * @since 1.1.0
+ */
+public abstract class VariableReference {
+
+	/**
+	 * Dereference the value. 
+	 * @return the dereferenced value. Such as the result of <code>x[3]</code>. The type of the reference 
+	 * is the type stored in the corresponding expressionTypeStack entry for this reference.
+	 * @throws IllegalAccessException
+	 * @throws IllegalArgumentException
+	 * 
+	 * @since 1.1.0
+	 */
+	public abstract Object dereference();
+	
+	/**
+	 * Set the value into the variable and dereference it. Once it is set it is
+	 * no longer a reference and must be dereferenced.
+	 * @param value value to set to.
+	 * @param type type of the value being set. It may be of use to the reference or maybe not.
+	 * @return the dereferenced value after being set. The type of the dereferenced value 
+	 * is the type stored in the corresponding expressionTypeStack entry for this reference.
+	 * @throws IllegalAccessException
+	 * @throws IllegalArgumentException
+	 * 
+	 * @since 1.1.0
+	 */
+	public abstract Object set(Object value, Class type) throws IllegalArgumentException, IllegalAccessException;
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IStandardAwtBeanProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IStandardAwtBeanProxyFactory.java
index bcd32d9..43bb8a5 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IStandardAwtBeanProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IStandardAwtBeanProxyFactory.java
@@ -11,10 +11,11 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IStandardAwtBeanProxyFactory.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:47 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
+import org.eclipse.jem.internal.proxy.core.*;
 import org.eclipse.jem.internal.proxy.core.IBeanProxyFactory;
 /**
  * The Standard awt bean proxy factory.
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/JavaStandardAwtBeanConstants.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/JavaStandardAwtBeanConstants.java
index 6405364..c40e9c2 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/JavaStandardAwtBeanConstants.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/JavaStandardAwtBeanConstants.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: JavaStandardAwtBeanConstants.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:47 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -37,7 +37,7 @@
  */
 public final class JavaStandardAwtBeanConstants {
 		
-	public static final String REGISTRY_KEY = "STANDARDPROXYAWTCONSTANTS:"; //$NON-NLS-1$
+	public static final Object REGISTRY_KEY = new Object();
 			
 	final boolean AWTLoaded;	// AWT may not be available. So non-ui JVM's don't have AWT.
 	final boolean AWTRegistered;	// AWT was registered to be used in this VM. It may be registered, but still not available.
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java
index 5f63f80..3b4258b 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java
@@ -10,19 +10,19 @@
  *******************************************************************************/
 /*
  *  $RCSfile: Expression.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.core;
 
 import java.text.MessageFormat;
-import java.util.ArrayList;
+import java.util.*;
 
 import org.eclipse.jem.internal.proxy.initParser.tree.*;
  
 /**
- * This is an internal implementation of Expression. It encapsulates much of the processing required
+ * 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. 
+ * 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,
@@ -31,11 +31,12 @@
  * 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.
+ * 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.
  * 
+ * 
  * @since 1.0.0
  */
 public abstract class Expression implements IExpression {
@@ -107,7 +108,6 @@
 	 * 	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.
 	
 	/*
@@ -126,10 +126,9 @@
 	 * 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.
+	private static final ForExpression ARRAY_INITIALIZER = new ExpressionEnum(Integer.MIN_VALUE+1, "Array Initializer Internal");
 	
 	/*
 	 * ARRAY INITIALIZER expression
@@ -147,7 +146,6 @@
 	 * 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.	
@@ -162,7 +160,6 @@
 	 * 	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.
@@ -179,7 +176,6 @@
 	 * 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.
 
@@ -206,10 +202,6 @@
 	 * 	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.
@@ -221,15 +213,6 @@
 	 * 	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.
@@ -259,33 +242,6 @@
 	 * 	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.
@@ -297,7 +253,6 @@
 	 * 	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.
@@ -310,7 +265,6 @@
 	 * 	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.
@@ -325,10 +279,33 @@
 	 *  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.
 	
+
+	/*
+	 * 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.
@@ -339,39 +316,109 @@
 	 * Since we can't have an array list of ints, will simulate the
 	 * stack here.
 	 */
-	private int[] nextForExpressionStack = new int[30];
+	private ForExpression[] nextForExpressionStack = new ForExpression[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 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 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
+	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(Integer.MIN_VALUE-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(Integer.MIN_VALUE-3, "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(Integer.MIN_VALUE-4, "Catch Expression");
+	
 	
 	/**
 	 * Check the for expression, and if legal, set to the next valid for expression type,
-	 * if it can.
+	 * 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(int forExpression) throws IllegalStateException {
-		if (nextForExpressionStackPos != INVALID) {
+	protected final void checkForExpression(ForExpression forExpression) throws IllegalStateException {
+		if (expressionValid) {
 			if (nextForExpressionStackPos == -1)
-				if (forExpression == IExpressionConstants.ROOTEXPRESSION)
+				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)
-				return;	// Valid, the top expression matched.
+			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.
-		nextForExpressionStackPos = INVALID;
-		throw new IllegalStateException(ProxyMessages.getString("Expression.TypeSentInInvalidOrder_EXC_")); //$NON-NLS-1$
+		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$
 	}
 	
 	/**
@@ -383,10 +430,10 @@
 	 * 
 	 * @since 1.0.0
 	 */
-	protected final boolean peekForExpression(int forExpression) {
-		if (nextForExpressionStackPos != INVALID) {
+	protected final boolean peekForExpression(ForExpression forExpression) {
+		if (expressionValid) {
 			if (nextForExpressionStackPos == -1)
-				if (forExpression == IExpressionConstants.ROOTEXPRESSION)
+				if (forExpression == ForExpression.ROOTEXPRESSION)
 					return true;	// valid. We are at the root (i.e. nothing is waiting).
 				else
 					;	// invalid. drop through
@@ -400,9 +447,7 @@
 	 * Mark this expression as now invalid.
 	 */
 	protected final void markInvalid() {
-		nextForExpressionStackPos = INVALID;
-		controlStack.clear();
-		closeProxy();
+		expressionValid = false;
 	}
 	
 	/**
@@ -417,6 +462,25 @@
 		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
@@ -432,10 +496,10 @@
 	/*
 	 * Push the next expression type.
 	 */
-	private void pushForExpression(int nextExpression) {
+	private void pushForExpression(ForExpression nextExpression) {
 		if (++nextForExpressionStackPos >= nextForExpressionStack.length) {
 			// Increase stack size.
-			int[] newStack = new int[nextForExpressionStackPos*2];	// So room to grow without excessive allocations.
+			ForExpression[] newStack = new ForExpression[nextForExpressionStackPos*2];	// So room to grow without excessive allocations.
 			System.arraycopy(nextForExpressionStack, 0, newStack, 0, nextForExpressionStack.length);
 			nextForExpressionStack = newStack;
 		}
@@ -445,54 +509,69 @@
 	/*
 	 * Check if expression is complete, and if it is, process it.
 	 */
-	private void processExpression() throws ThrowableProxy, NoExpressionValueException {
+	private void processExpression() {
 		while (expressionReady()) {
 			try {
 				// We've received all of the expressions for the expression, so process it.
-				int expType = ((Integer) pop()).intValue();
+				int expType = ((InternalExpressionTypes) pop()).getValue();
 				switch (expType) {
-					case IInternalExpressionConstants.CAST_EXPRESSION:
-						pushCastToProxy(pop());
+					case InternalExpressionTypes.CAST_EXPRESSION_VALUE:
+						pushCastToProxy((IProxyBeanType) pop());
 						break;
-					case IInternalExpressionConstants.INSTANCEOF_EXPRESSION:
-						pushInstanceofToProxy(pop());
+					case InternalExpressionTypes.INSTANCEOF_EXPRESSION_VALUE:
+						pushInstanceofToProxy((IProxyBeanType) pop());
 						break;
-					case IInternalExpressionConstants.PREFIX_EXPRESSION:
-						pushPrefixToProxy(((Integer)pop()).intValue());
+					case InternalExpressionTypes.PREFIX_EXPRESSION_VALUE:
+						pushPrefixToProxy((PrefixOperator)pop());
 						break;
-					case IInternalExpressionConstants.INFIX_EXPRESSION:
-						pushInfixToProxy(((Integer) pop()).intValue(), ((Integer) pop()).intValue());
+					case InternalExpressionTypes.INFIX_EXPRESSION_VALUE:
+						pushInfixToProxy((InfixOperator) pop(), (InternalInfixOperandType) pop());
 						break;
-					case IInternalExpressionConstants.ARRAY_ACCESS_EXPRESSION:
+					case InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION_VALUE:
 						pushArrayAccessToProxy(((Integer) pop()).intValue());
 						break;
-					case IInternalExpressionConstants.ARRAY_CREATION_EXPRESSION:
-						pushArrayCreationToProxy(pop(), ((Integer) pop()).intValue());
+					case InternalExpressionTypes.ARRAY_CREATION_EXPRESSION_VALUE:
+						pushArrayCreationToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue());
 						break;
-					case IInternalExpressionConstants.ARRAY_INITIALIZER_EXPRESSION:
-						pushArrayInitializerToProxy(pop(), ((Integer) pop()).intValue());
+					case InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION_VALUE:
+						pushArrayInitializerToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue(), ((Integer) pop()).intValue());
 						break;
-					case IInternalExpressionConstants.CLASS_INSTANCE_CREATION_EXPRESSION:
-						pushClassInstanceCreationToProxy(pop(), ((Integer) pop()).intValue());
+					case InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION_VALUE:
+						pushClassInstanceCreationToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue());
 						break;
-					case IInternalExpressionConstants.FIELD_ACCESS_EXPRESSION:
-						pushFieldAccessToProxy((String) pop(), ((Boolean) pop()).booleanValue());
+					case InternalExpressionTypes.FIELD_ACCESS_EXPRESSION_VALUE:
+						pushFieldAccessToProxy(pop(), ((Boolean) pop()).booleanValue());
 						break;
-					case IInternalExpressionConstants.METHOD_EXPRESSION:
-						pushMethodInvocationToProxy((String) pop(), ((Boolean) pop()).booleanValue(), ((Integer) pop()).intValue());
+					case InternalExpressionTypes.METHOD_EXPRESSION_VALUE:
+						pushMethodInvocationToProxy(pop(), ((Boolean) pop()).booleanValue(), ((Integer) pop()).intValue());
 						break;
-					case IInternalExpressionConstants.CONDITIONAL_EXPRESSION:
-						pushConditionalToProxy(((Integer) pop()).intValue());
+					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 (ThrowableProxy e) {
-				markInvalid();
-				throw e;
-			} catch (NoExpressionValueException e) {
-				markInvalid();
-				throw e;
 			} catch (RuntimeException e) {
 				markInvalid();
 				throw e;
@@ -500,6 +579,7 @@
 		}
 	}
 	
+
 	private void internalProcessUnknownExpressionType(int expressionType) throws IllegalArgumentException {
 		if (!processUnknownExpressionType(expressionType))
 			throw new IllegalArgumentException();
@@ -532,51 +612,192 @@
 		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(IExpressionConstants.ROOTEXPRESSION); // We are at the root.
-			pushInvoke();
+			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(IExpressionConstants.ROOTEXPRESSION); // We are at the root.
-			return pullProxyValue(); // Get the top value.
+			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.
+			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(int forExpression, int indexCount) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
+	public final void createArrayAccess(ForExpression forExpression, int indexCount) {
 		try {
 			checkForExpression(forExpression);
 			pushForExpression(PROCESS_EXPRESSION);
 			int i = indexCount;
 			while (i-- > 0)
-				pushForExpression(IExpressionConstants.ARRAYACCESS_INDEX);
-			pushForExpression(IExpressionConstants.ARRAYACCESS_ARRAY);
+				pushForExpression(ForExpression.ARRAYACCESS_INDEX);
+			pushForExpression(ForExpression.ARRAYACCESS_ARRAY);
 
 			push(indexCount == 1 ? ARRAYACCESS_INDEX_1 : new Integer(indexCount));
-			push(ARRAYACCESS);
+			push(InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION);
 			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;
@@ -585,84 +806,79 @@
 	/* (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;
-		}		
+	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(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy, int)
+	 * @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(int forExpression, IBeanTypeProxy type, int dimensionExpressionCount)
-		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
+	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);
-			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;
+
+			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;
-		}		
-	}
-
-	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 {
+	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(IExpressionConstants.ARRAYINITIALIZER_EXPRESSION);
-			
-			Object arrayType = peek(2);	// Get the type from the value stack. Do before I mess up the stack.
-			
+				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);
@@ -677,97 +893,87 @@
 					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$
+					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(ARRAYINITIALIZER);
-			
+			push(InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION);
+
 			pushForExpression(PROCESS_EXPRESSION);
-			while(expressionCount-->0)
-				pushForExpression(IExpressionConstants.ARRAYINITIALIZER_EXPRESSION);
-			
-			processExpression();
-		} catch (ThrowableProxy e) {
-			markInvalid();
-			throw e;
-		} catch (NoExpressionValueException e) {
-			markInvalid();
-			throw e;
+			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(int forExpression, String type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
-		pushCast(forExpression, type); // Push this onto the local stack to wait for completion.
+	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(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
+	/*
+	 *  (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(int forExpression, IBeanTypeProxy type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
+	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(int forExpression, Object type) throws ThrowableProxy, NoExpressionValueException {
+	private void pushCast(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException {
 		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;
+			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(int forExpression, String type, int argumentCount)
-		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
-		pushClassInstanceCreation(forExpression, type, argumentCount);	// Push this onto the local stack to wait for completion.
+	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(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy, int)
+	/*
+	 *  (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(int forExpression, IBeanTypeProxy type, int argumentCount)
-		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
+	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(int forExpression, Object type, int argumentCount) throws ThrowableProxy, NoExpressionValueException {
+	private void pushClassInstanceCreation(ForExpression forExpression, IProxyBeanType type, int argumentCount) throws IllegalStateException {
 		try {
 			checkForExpression(forExpression);
 			switch (argumentCount) {
@@ -782,50 +988,38 @@
 					break;
 			}
 			push(type);
-			push(CLASSINSTANCECREATION);
-			
+			push(InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION);
+
 			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;
+			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(int forExpression) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
+	public final void createConditionalExpression(ForExpression forExpression) throws IllegalStateException {
 		try {
 			checkForExpression(forExpression);
 			pushForExpression(PROCESS_EXPRESSION);
-			pushForExpression(IExpressionConstants.CONDITIONAL_FALSE);
+			pushForExpression(ForExpression.CONDITIONAL_FALSE);
 			pushForExpression(PROCESS_EXPRESSION);
-			pushForExpression(IExpressionConstants.CONDITIONAL_TRUE);
+			pushForExpression(ForExpression.CONDITIONAL_TRUE);
 			pushForExpression(PROCESS_EXPRESSION);
-			pushForExpression(IExpressionConstants.CONDITIONAL_CONDITION);
-			
-			push(CONDITIONAL_FALSEXP);
-			push(CONDITIONAL);
-			push(CONDITIONAL_TRUEEXP);
-			push(CONDITIONAL);
-			push(CONDITIONAL_TEST);
-			push(CONDITIONAL);
+			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 (ThrowableProxy e) {
-			markInvalid();
-			throw e;
-		} catch (NoExpressionValueException e) {
-			markInvalid();
-			throw e;
 		} catch (RuntimeException e) {
 			markInvalid();
 			throw e;
@@ -835,26 +1029,73 @@
 	/* (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 {
+	public final void createFieldAccess(ForExpression forExpression, String fieldName, boolean hasReceiver) throws IllegalStateException, IllegalArgumentException {
 		try {
-			checkForExpression(forExpression);
+			// 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(ProxyMessages.getString("Expression.CannotHandleNoReceiveOnFieldAccess_EXC_")); //$NON-NLS-1$
-			
-			push(hasReceiver ? Boolean.TRUE : Boolean.FALSE);	// We have a receiver
-			push(fieldName);
-			push(FIELDACCESS);
+				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(IExpressionConstants.FIELD_RECEIVER);
-			processExpression();	// See if previous expression is ready for processing.
-		} catch (ThrowableProxy e) {
-			markInvalid();
-			throw e;
-		} catch (NoExpressionValueException e) {
-			markInvalid();
-			throw e;
+				pushForExpression(ForExpression.FIELD_RECEIVER);
+			processExpression(); // See if previous expression is ready for processing.
 		} catch (RuntimeException e) {
 			markInvalid();
 			throw e;
@@ -864,39 +1105,32 @@
 	/* (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 {
+	public final void createInfixExpression(ForExpression forExpression, InfixOperator operator, int extendedOperandCount) throws IllegalStateException {
 		try {
 			checkForExpression(forExpression);
-			Integer inoperator = INFIX_OPERATORS[operator];
-			push(IN_LAST);
-			push(inoperator);
-			push(INFIX);
+			push(InternalInfixOperandType.INFIX_LAST_OPERAND);
+			push(operator);
+			push(InternalExpressionTypes.INFIX_EXPRESSION);
 			int i = extendedOperandCount;
-			while(i-->0) {
-				push(IN_OTHER);
-				push(inoperator);
-				push(INFIX);
+			while (i-- > 0) {
+				push(InternalInfixOperandType.INFIX_OTHER_OPERAND);
+				push(operator);
+				push(InternalExpressionTypes.INFIX_EXPRESSION);
 			}
-			push(IN_LEFT);
-			push(inoperator);
-			push(INFIX);
-		
+			push(InternalInfixOperandType.INFIX_LEFT_OPERAND);
+			push(operator);
+			push(InternalExpressionTypes.INFIX_EXPRESSION);
+
 			i = extendedOperandCount;
-			while(i-->0) {
-				pushForExpression(PROCESS_EXPRESSION);			
-				pushForExpression(IExpressionConstants.INFIX_EXTENDED);
+			while (i-- > 0) {
+				pushForExpression(PROCESS_EXPRESSION);
+				pushForExpression(ForExpression.INFIX_EXTENDED);
 			}
 			pushForExpression(PROCESS_EXPRESSION);
-			pushForExpression(IExpressionConstants.INFIX_RIGHT);
+			pushForExpression(ForExpression.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;
+			pushForExpression(ForExpression.INFIX_LEFT);
+			processExpression(); // See if previous expression is ready for processing.
 		} catch (RuntimeException e) {
 			markInvalid();
 			throw e;
@@ -906,99 +1140,129 @@
 	/* (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.
+	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(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
+	/*
+	 *  (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(int forExpression, IBeanTypeProxy type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
+	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(int forExpression, Object type) throws ThrowableProxy, NoExpressionValueException {
+	private void pushInstanceof(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException {
 		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;
+			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(int forExpression, String name, boolean hasReceiver, int argumentCount)
-		throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
+	public final void createMethodInvocation(ForExpression forExpression, String name, boolean hasReceiver, int argumentCount)
+		throws IllegalStateException, IllegalArgumentException {
 		try {
-			checkForExpression(forExpression);
+			// 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$
+				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;
+			pushMethodInvocation(forExpression, name, hasReceiver, argumentCount);
 		} catch (RuntimeException e) {
 			markInvalid();
 			throw e;
 		}
 	}
 	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrefixExpression(int, int)
+	/**
+	 * @param forExpression
+	 * @param method String for method name, IMethodProxy otherwise.
+	 * @param hasReceiver 
+	 * @param argumentCount
+	 * @throws ThrowableProxy
+	 * @throws NoExpressionValueException
+	 * 
+	 * @since 1.1.0
 	 */
-	public final void createPrefixExpression(int forExpression, int operator) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
+	private void pushMethodInvocation(ForExpression forExpression, Object method, boolean hasReceiver, int argumentCount) throws IllegalArgumentException, IllegalStateException {
 		try {
 			checkForExpression(forExpression);
-			push(PREFIX_OPERATORS[operator]);
-			push(PREFIX);
-			
+			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);
-			pushForExpression(IExpressionConstants.PREFIX_OPERAND);
-			processExpression();	// See if previous expression is ready for processing.
-		} catch (ThrowableProxy e) {
-			throw e;
-		} catch (NoExpressionValueException e) {
+			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.
+	 * @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;
@@ -1008,17 +1272,11 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createNull(int)
 	 */
-	public final void createNull(int forExpression) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
+	public final void createNull(ForExpression forExpression) throws IllegalStateException {
 		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;
@@ -1028,34 +1286,22 @@
 	/* (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;
-		}
+	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 ThrowableProxy, IllegalStateException, NoExpressionValueException {
-		pushTypeReceiver(type);
+	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.IBeanTypeProxy)
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeReceiver(org.eclipse.jem.internal.proxy.core.IProxyBeanType)
 	 */
-	public final void createTypeReceiver(IBeanTypeProxy type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
+	public final void createTypeReceiver(IProxyBeanType type) throws IllegalStateException {
 		pushTypeReceiver(type);
 	}
 
@@ -1065,24 +1311,18 @@
 	 * 
 	 * @since 1.0.0
 	 */
-	private void pushTypeReceiver(Object type) throws ThrowableProxy, NoExpressionValueException {
+	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(FIELD_RECEIVER))
-				checkForExpression(FIELD_RECEIVER);
+			if (peekForExpression(ForExpression.FIELD_RECEIVER))
+				checkForExpression(ForExpression.FIELD_RECEIVER);
 			else
-				checkForExpression(METHOD_RECEIVER);
+				checkForExpression(ForExpression.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;
@@ -1098,17 +1338,11 @@
 	/* (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 {
+	public final void createPrimitiveLiteral(ForExpression forExpression, boolean value) throws IllegalStateException {
 		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;
@@ -1118,17 +1352,11 @@
 	/* (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 {
+	public final void createPrimitiveLiteral(ForExpression forExpression, char value) throws IllegalStateException {
 		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;
@@ -1138,17 +1366,11 @@
 	/* (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 {
+	public final void createPrimitiveLiteral(ForExpression forExpression, byte value) throws IllegalStateException {
 		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;
@@ -1158,17 +1380,11 @@
 	/* (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 {
+	public final void createPrimitiveLiteral(ForExpression forExpression, double value) throws IllegalStateException {
 		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;
@@ -1178,17 +1394,11 @@
 	/* (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 {
+	public final void createPrimitiveLiteral(ForExpression forExpression, float value) throws IllegalStateException {
 		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;
@@ -1198,17 +1408,11 @@
 	/* (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 {
+	public final void createPrimitiveLiteral(ForExpression forExpression, int value) throws IllegalStateException {
 		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;
@@ -1218,17 +1422,11 @@
 	/* (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 {
+	public final void createPrimitiveLiteral(ForExpression forExpression, long value) throws IllegalStateException {
 		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;
@@ -1238,17 +1436,11 @@
 	/* (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 {
+	public final void createPrimitiveLiteral(ForExpression forExpression, short value) throws IllegalStateException {
 		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;
@@ -1258,17 +1450,306 @@
 	/* (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 {
+	public final void createStringLiteral(ForExpression forExpression, String value) throws IllegalStateException {
 		try {
 			checkForExpression(forExpression);
 			pushToProxy(beanProxyFactory.createBeanProxyWith(value));
 			processExpression();
-		} catch (ThrowableProxy e) {
+		} catch (RuntimeException e) {
 			markInvalid();
 			throw e;
-		} catch (NoExpressionValueException 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.
+	 * 
+	 * @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.
+	 * 
+	 * @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.
+	 * @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;
@@ -1276,41 +1757,214 @@
 	}
 
 	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createProxyExpression(int, org.eclipse.jem.internal.proxy.core.IBeanProxy)
+	 * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryEnd()
 	 */
-	public final void createProxyExpression(int forExpression, IBeanProxy proxy) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
+	public final void createTryEnd() throws IllegalStateException {
 		try {
-			checkForExpression(forExpression);
-			pushToProxy(proxy);
+			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 (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#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.
+	}
+	
+	
+	/**
+	 * 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
-	 * @throws ThrowableProxy
 	 * 
 	 * @since 1.0.0
 	 */
-	protected abstract void pushToProxy(IBeanProxy proxy) throws ThrowableProxy;
-	
+	protected abstract void pushToProxy(IProxy proxy);
+
 	/**
-	 * Tell the other side we are complete. This is only called for invoked expressions,
-	 * i.e. no return value.
+	 * 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
 	 * 
@@ -1320,177 +1974,324 @@
 	
 	/**
 	 * 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() throws ThrowableProxy, NoExpressionValueException;
+	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. 
+	 * 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() throws ThrowableProxy, NoExpressionValueException;
+	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. 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
+	 * @param type Cast type. 
 	 * 
 	 * @since 1.0.0
 	 */
-	protected abstract void pushCastToProxy(Object type) throws ThrowableProxy, NoExpressionValueException;
+	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. 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
+	 * @param type Instanceof type.
 	 * 
 	 * @since 1.0.0
 	 */
-	protected abstract void pushInstanceofToProxy(Object type) throws ThrowableProxy, NoExpressionValueException;
+	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, 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
+	 * @param operator The operator.
+	 * @param operandType The operand type. left, other, or last.
 	 * 
-	 * @see IExpressionConstants#IN_AND
-	 * @see IInternalExpressionConstants#INFIX_LAST_OPERAND
 	 * @since 1.0.0
 	 */
-	protected abstract void pushInfixToProxy(int operator, int operandType) throws ThrowableProxy, NoExpressionValueException;
+	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 The operator, the values are from IExpressionConstants prefix operators.
-	 * @throws ThrowableProxy
-	 * @throws NoExpressionValueException
+	 * @param operator 
 	 * 
 	 * @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;
+	protected abstract void pushPrefixToProxy(PrefixOperator operator);	
+
 	
 	/**
 	 * 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;
+	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. (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 type The array type. 
 	 * @param dimensionCount
-	 * @throws ThrowableProxy
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	protected abstract void pushArrayCreationToProxy(Object type, int dimensionCount) throws ThrowableProxy, NoExpressionValueException;
+	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 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 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
-	 * @throws ThrowableProxy
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	protected abstract void pushArrayInitializerToProxy(Object type, int expressionCount) throws ThrowableProxy, NoExpressionValueException;
+	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. 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 type Class type. 
 	 * @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;
+	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. 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
+	 * @param type Class type. 
 	 * 
 	 * @since 1.0.0
 	 */
-	protected abstract void pushTypeReceiverToProxy(Object type) throws ThrowableProxy;
+	protected abstract void pushTypeReceiverToProxy(IProxyBeanType type);
 
 	/**
 	 * Push to proxy the field access. The result value will be placed onto the evaluation stack.
-	 * @param fieldName The name of the field.
+	 * @param field The name of the field if string, or an IFieldProxy.
 	 * @param hasReceiver Has receiver flag.
-	 * @throws ThrowableProxy
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	protected abstract void pushFieldAccessToProxy(String fieldName, boolean hasReceiver) throws ThrowableProxy, NoExpressionValueException;
+	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 methodName
+	 * @param method String for method name or IProxyMethod
 	 * @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;
+	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, one of IExpressionConstants.CONDITIONAL_* constants.
-	 * @throws ThrowableProxy
-	 * @throws NoExpressionValueException
+	 * @param expressionType The expression type.
 	 * 
-	 * @see IExpressionConstants#CONDITIONAL_CONDITION
 	 * @since 1.0.0
 	 */
-	protected abstract void pushConditionalToProxy(int expressionType) throws ThrowableProxy, NoExpressionValueException;
+	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);
+	
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ExpressionProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ExpressionProxy.java
new file mode 100644
index 0000000..9b816ab
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ExpressionProxy.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/*
+ *  $RCSfile: ExpressionProxy.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.core;
+
+import java.util.EventObject;
+import java.util.logging.Level;
+ 
+
+/**
+ * This is a proxy for an IExpression evaluation value. It is used as a place holder proxy value for result of an expression, and
+ * then the value can be used in a later expression, or at the end, it can callback and return a proxy in the IDE 
+ * side in a callback for usage later on outside of the IExpression.
+ * <p>
+ * After receiving the resolved event, listeners should not hold onto the ExpressionProxy because it would then be invalid. At that
+ * point they should instead hold onto the resolved bean proxy.
+ * 
+ * @see org.eclipse.jem.internal.proxy.core.IExpression#assignExpressionProxy()
+ * @see org.eclipse.jem.internal.proxy.core.IExpression#createExpressionProxyExpression(int, ExpressionProxy)
+ * @since 1.1.0
+ */
+public class ExpressionProxy implements IProxy {
+
+	/**
+	 * The event object for the resolved event of the proxy listener.
+	 * <p>
+	 * The source will be the ExpressionProxy that is being resolved.
+	 * @since 1.1.0
+	 */
+	public static class ProxyEvent extends EventObject {
+		
+		private final IBeanProxy proxy;
+
+		/**
+		 * @param source the expression proxy for the event.
+		 * @param proxy the bean proxy the expression proxy (source) resolved to.
+		 * 
+		 * @since 1.1.0
+		 */
+		public ProxyEvent(ExpressionProxy source, IBeanProxy proxy) {
+			super(source);
+			this.proxy = proxy;
+		}
+		
+		/**
+		 * Construct the event with no proxy. Used for not resolved and void.
+		 * @param source
+		 * 
+		 * @since 1.1.0
+		 */
+		public ProxyEvent(ExpressionProxy source) {
+			this(source, null);
+		}
+		
+		/**
+		 * Get the proxy value that the expression proxy (source) resolved to.
+		 * @return
+		 * 
+		 * @since 1.1.0
+		 */
+		public IBeanProxy getProxy() {
+			return proxy;
+		}
+	}
+	
+	/**
+	 * Listener for expression proxy events.
+	 * 
+	 * @since 1.1.0
+	 */
+	public interface ProxyListener {
+		/**
+		 * The expression proxy has been resolved. The event contains the resolved proxy.
+		 * At this point, any listeners should no longer hold onto the ExpressionProxy
+		 * because it is now invalid. They should hold onto the resolved bean proxy instead.
+		 * 
+		 * @param event
+		 * 
+		 * @since 1.1.0
+		 */
+		public void proxyResolved(ProxyEvent event);
+		
+		/**
+		 * This is called for ExpressionProxies that have a callback listener, but the proxy 
+		 * was never resolved. This means that the expression that assigns to the proxy was
+		 * not executed. In this case the event does not have a bean proxy in it.
+		 * 
+		 * @param event
+		 * 
+		 * @since 1.1.0
+		 */
+		public void proxyNotResolved(ProxyEvent event);
+		
+		/**
+		 * This is called for ExpressionProxies that were assigned to an expression that
+		 * had a <code>VOID</code> return type. This is usually for method invocations that
+		 * have a void return type. In this case the event does not have a bean proxy in it.
+		 * @param event
+		 * 
+		 * @since 1.1.0
+		 */
+		public void proxyVoid(ProxyEvent event);
+	}
+	
+	/**
+	 * An implementation of ProxyListener that does nothing. It can be
+	 * used as a superclass for individual listeners that are only interested
+	 * in some of the events.
+	 * 
+	 * @since 1.1.0
+	 */
+	public static class ProxyAdapter implements ProxyListener {
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyListener#proxyNotResolved(org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent)
+		 */
+		public void proxyNotResolved(ProxyEvent event) {
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyListener#proxyResolved(org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent)
+		 */
+		public void proxyResolved(ProxyEvent event) {
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyListener#proxyVoid(org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent)
+		 */
+		public void proxyVoid(ProxyEvent event) {
+		}
+	}
+	
+	final private int proxyID;
+	final private int proxyType;
+	private ListenerList listenerList;
+	private Expression expression;
+	
+	/**
+	 * Create with the given proxy id.
+	 * @param proxyid
+	 * 
+	 * @since 1.1.0
+	 */
+	public ExpressionProxy(int proxyid, int proxyType, Expression expression) {
+		this.proxyID = proxyid;
+		this.proxyType = proxyType;
+		this.expression = expression;
+	}
+	
+	/**
+	 * Get the expression this proxy is for. 
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public Expression getExpression() {
+		return expression;
+	}
+	
+	/**
+	 * Used internally in expression to get the proxy type. 
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	protected final int getProxyType() {
+		return proxyType;
+	}
+	
+	/**
+	 * Return the proxy id.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public final int getProxyID() {
+		return proxyID;
+	}
+	
+	/**
+	 * Add a listener. If listener already added, it has no effect.
+	 * @param listener
+	 * 
+	 * @since 1.1.0
+	 */
+	public void addProxyListener(ProxyListener listener) {
+		if (listenerList == null)
+			listenerList = new ListenerList();
+		listenerList.add(listener);
+	}
+	
+	/**
+	 * Remove a listener. If listener not already added, then no error.
+	 * @param listener
+	 * 
+	 * @since 1.1.0
+	 */
+	public void removeProxyListener(ProxyListener listener) {
+		if (listenerList != null)
+			listenerList.remove(listener);
+	}
+	
+	/**
+	 * Used by internal subclasses or Expression to know if anyone is listening.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	protected final boolean hasListeners() {
+		return listenerList != null && !listenerList.isEmpty();
+	}
+	
+	/**
+	 * The proxy has been fired (one of the events has occurred). Subclasses should clean
+	 * up and not hold onto anything that would be expensive in case the proxy is still
+	 * held onto be someone. For example the default clears the listener list.
+	 * <p>
+	 * <b>Note:</b> Subclasses must call super.dispose().
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void dispose() {
+		listenerList = null;
+		expression = null;
+	}
+	
+	/**
+	 * Used by internal subclasses  or by Expression to fire the resolved event. Once fired all listeners are removed.
+	 * This is because only one kind of firing can be done for a expression proxy and then the proxy is dead. This
+	 * prevents listeners from being held on to if any one accidently still holds the proxy.
+	 * @param proxy
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void fireResolved(IBeanProxy proxy) {
+		if (hasListeners()) {
+			ProxyEvent event = new ProxyEvent(this, proxy);
+			Object[] listeners = listenerList.getListeners();
+			for (int i = 0; i < listeners.length; i++) {
+				try {
+					((ProxyListener) listeners[i]).proxyResolved(event);
+				} catch (RuntimeException e) {
+					ProxyPlugin.getPlugin().getLogger().log(e, Level.WARNING);
+				}
+			}
+		}
+		dispose();
+	}
+	
+	/**
+	 * Used by internal subclasses or by Expression to fire the not resolved event. Once fired all listeners are removed.
+	 * This is because only one kind of firing can be done for a expression proxy and then the proxy is dead. This
+	 * prevents listeners from being held on to if any one accidently still holds the proxy.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void fireNotResolved() {
+		if (hasListeners()) {
+			ProxyEvent event = new ProxyEvent(this);
+			Object[] listeners = listenerList.getListeners();
+			for (int i = 0; i < listeners.length; i++) {
+				try {
+					((ProxyListener) listeners[i]).proxyNotResolved(event);
+				} catch (RuntimeException e) {
+					ProxyPlugin.getPlugin().getLogger().log(e, Level.WARNING);
+				}
+				
+			}
+		}
+		dispose();
+	}
+	
+	/**
+	 * Used by internal subclasses or by Expression to fire the void resolved event. Once fired all listeners are removed.
+	 * This is because only one kind of firing can be done for a expression proxy and then the proxy is dead. This
+	 * prevents listeners from being held on to if any one accidently still holds the proxy.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void fireVoidResolved() {
+		if (hasListeners()) {
+			ProxyEvent event = new ProxyEvent(this);
+			Object[] listeners = listenerList.getListeners();
+			for (int i = 0; i < listeners.length; i++) {
+				try {
+					((ProxyListener) listeners[i]).proxyVoid(event);
+				} catch (RuntimeException e) {
+					ProxyPlugin.getPlugin().getLogger().log(e, Level.WARNING);
+				}
+				
+			}
+		}
+		dispose();
+	}	
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isBeanProxy()
+	 */
+	public final boolean isBeanProxy() {
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isExpressionProxy()
+	 */
+	public final boolean isExpressionProxy() {
+		return true;
+	}
+	
+	/**
+	 * Is this proxy valid for reassignment. By default only if the type is NORMAL_EXPRESSION_PROXY.
+	 * Subclasses may override and return true in their cases.
+	 * 
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean isValidForReassignment() {
+		return getProxyType() == Expression.NORMAL_EXPRESSION_PROXY;
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return super.toString()+": "+getProxyID();
+	}
+}
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanProxy.java
index 923ccfd..bbdda08 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanProxy.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IBeanProxy.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -21,7 +21,7 @@
  * Creation date: (12/3/99 11:37:01 AM)
  * @author: Joe Winchester
  */
-public interface IBeanProxy {
+public interface IBeanProxy extends IProxy {
 /**
  * equals: Equal if:
  *         1) This proxy == (identity) to the other object
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanTypeExpressionProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanTypeExpressionProxy.java
new file mode 100644
index 0000000..2726d05
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanTypeExpressionProxy.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: IBeanTypeExpressionProxy.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.core;
+ 
+
+/**
+ * An internal interface for the registries to create the appropriate beantype expression proxy.
+ * Not to be implemented or referenced by customers.
+ * @since 1.1.0
+ */
+public interface IBeanTypeExpressionProxy extends IProxyBeanType {
+
+	/**
+	 * Allow the expression to set the type name.
+	 * @param typeName
+	 * 
+	 * @since 1.1.0
+	 */
+	public void setTypeName(String typeName);
+}
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanTypeProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanTypeProxy.java
index 4617cf1..596b688 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanTypeProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IBeanTypeProxy.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IBeanTypeProxy.java,v $
- *  $Revision: 1.6 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.7 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.core;
 
@@ -21,7 +21,7 @@
  * 
  * @author: Joe Winchester
  */
-public interface IBeanTypeProxy extends IBeanProxy {
+public interface IBeanTypeProxy extends IBeanProxy, IProxyBeanType {
 	
 	/**
 	 * Find the most compatible constructor (out of the declared constructors). This means it will
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ICallback.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ICallback.java
index 47a6ae8..c95e775 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ICallback.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ICallback.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.core;
 /*
  *  $RCSfile: ICallback.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:53:45 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.io.InputStream;
@@ -33,13 +33,13 @@
 	 * It will be called whenever the callback
 	 * occurred. It will be on its own thread.
 	 * A particular thread cannot be requested.
-	 *
+	 * <p>
 	 * The implementation MUST return. This is 
 	 * because the callback will not be completed
 	 * until it is returned, and the process will
 	 * not continue on the remote vm until it is
 	 * returned.
-	 * 
+	 * <p>
 	 * The value returned must either be an
 	 * IBeanProxy or IBeanProxy[]. It is typed
 	 * to Object to allow either one, but it
@@ -60,20 +60,20 @@
 	 * It will be called whenever the callback
 	 * occurred. It will be on its own thread.
 	 * A particular thread cannot be requested.
-	 *
+	 * <p>
 	 * The parms will be an array of IBeanProxys,
 	 * or an entry could be another array of IBeanProxys,
 	 * or null if null was sent to callBackWithParms.
 	 * The final component of any entry will be an
 	 * IBeanProxy. It is up to the developers to
 	 * agree on the format of the parms.
-	 *
+	 * <p>
 	 * The implementation MUST return. This is 
 	 * because the callback will not be completed
 	 * until it is returned, and the process will
 	 * not continue on the remote vm until it is
 	 * returned.
-	 * 
+	 * <p>
 	 * The value returned must either be an
 	 * IBeanProxy or IBeanProxy[]. It is typed
 	 * to Object to allow either one, but it
@@ -95,20 +95,20 @@
 	 * It will be called whenever the callback
 	 * occurred. It will be on its own thread.
 	 * A particular thread cannot be requested.
-	 *
+	 * <p>
 	 * The parm will be an object. This occurs
 	 * if remote vm just wanted to send some objects.
 	 * They will not be proxies. It is recommended
 	 * that this be used only for small items. For
 	 * anything large, the callbackStream should be
 	 * used instead.
-	 *
+	 * <p>
 	 * The implementation MUST return. This is 
 	 * because the callback will not be completed
 	 * until it is returned, and the process will
 	 * not continue on the remote vm until it is
 	 * returned.
-	 * 
+	 * <p>
 	 * The value returned must either be an
 	 * IBeanProxy or IBeanProxy[]. It is typed
 	 * to Object to allow either one, but it
@@ -130,13 +130,13 @@
 	 * It will be called whenever the callback stream
 	 * occurred. It will be on its own thread.
 	 * A particular thread cannot be requested.
-	 *
+	 * <p>
 	 * The callback should continue to read from the InputStream
 	 * until it returns -1 indicating no more data. The stream can
 	 * be closed. In that case the next time the remote vm wants to
 	 * send data it will first check that the stream has not been closed.
 	 * If it has, it will raise an exception on that side.
-	 *
+	 * <p>
 	 * The implementation MUST return. This is 
 	 * because the callback will not be completed
 	 * until it is returned, and the process will
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ICallbackRegistry.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ICallbackRegistry.java
index d9ede51..2b2b16d 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ICallbackRegistry.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ICallbackRegistry.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: ICallbackRegistry.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 /**
@@ -50,6 +50,18 @@
 	public void registerCallback(IBeanProxy callbackProxy, ICallback cb);
 	
 	/**
+	 * Same as {@link ICallbackRegistry#registerCallback(IBeanProxy, ICallback) registerCallback} except that
+	 * it is deferred off into an expression.
+	 *  
+	 * @param callbackProxy
+	 * @param cb
+	 * @param expression
+	 * 
+	 * @since 1.1.0
+	 */
+	public void registerCallback(IProxy callbackProxy, ICallback cb, IExpression expression);
+	
+	/**
 	 * Deregister the callback proxy. This will remove it from the
 	 * registry and release the callback.
 	 *
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IConstructorProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IConstructorProxy.java
index 9fbc11e..c7bc36a 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IConstructorProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IConstructorProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.core;
 /*
  *  $RCSfile: IConstructorProxy.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -37,4 +37,6 @@
 IBeanProxy newInstanceCatchThrowableExceptions();
 IBeanProxy newInstanceCatchThrowableExceptions(IBeanProxy[] creationArguments);
 
+IBeanTypeProxy[] getParameterTypes();
+
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IDimensionBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IDimensionBeanProxy.java
similarity index 81%
rename from plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IDimensionBeanProxy.java
rename to plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IDimensionBeanProxy.java
index c119743..56c1264 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IDimensionBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IDimensionBeanProxy.java
@@ -1,4 +1,4 @@
-package org.eclipse.jem.internal.proxy.awt;
+package org.eclipse.jem.internal.proxy.core;
 /*******************************************************************************
  * Copyright (c)  2001, 2003 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials 
@@ -11,14 +11,16 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IDimensionBeanProxy.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:47 $ 
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
 
-import org.eclipse.jem.internal.proxy.core.IBeanProxy;
 /**
  * Interface to a Dimension bean proxy.
+ * <p>
+ * These are common for different windowing systems, e.g. AWT and SWT. So this here
+ * is common interface for them.
  * Creation date: (4/7/00 3:46:39 PM)
  * @author: Administrator
  */
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IExpression.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IExpression.java
index 97abdfb..bff0663 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IExpression.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IExpression.java
@@ -10,11 +10,13 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IExpression.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.core;
 
+import org.eclipse.jem.internal.proxy.initParser.tree.*;
 import org.eclipse.jem.internal.proxy.initParser.tree.IExpressionConstants;
+import org.eclipse.jem.internal.proxy.initParser.tree.NoExpressionValueException;
  
 /**
  * This is an expression. It will be evaluated on the other side. The difference between an
@@ -35,7 +37,7 @@
  * we build the expression.
  * <p>
  * To use, you call the IStandardBeanProxyFactory's createExpression method. An IExpression is
- * returned. From there you will start creating the contents of the expression. Any then you will
+ * returned. From there you will start creating the contents of the expression. And then you will
  * finally either getExpressionValue() to get the final value of the expression, or use
  * invokeExpression() to just execute the expression(s). If you use getExpressionValue(), there can
  * only be one root expression. If you use invokeExpression there can be more than one root
@@ -44,9 +46,6 @@
  * Since sequence is so important, it will be tested and if anything is done out of order an
  * IllegalStateException will be thrown.
  * <p>
- * Also, it is up to the implementation, but it may start executing ahead of completion, and so you
- * may get a ThrowableProxy from any of the calls during build up.
- * <p>
  * Each time an expression is created, one argument passed in will be <code>forExpression</code> flag.
  * This is a set of constants used as a clue for what expression this expression is being created.
  * This is for a sanity check on the state. For example, when creating the array expression for an
@@ -55,7 +54,12 @@
  * Without this flag, it would be easy to accidently create the wrong expression at the wrong time.
  * Once such an error occurs, this IExpression will no longer be valid. IllegalStateException will be thrown
  * for any type of access.
- * 
+ * <p>
+ * It is guarenteed that the entire stack of commands will be sent without stopping except for IllegalStateException
+ * due to out of order expressions.
+ * <p>
+ * <b>Note:</b> This call is not meant to be instantiated by customers. It is the interface into the expression processing.
+ *  
  * @see org.eclipse.jem.internal.proxy.core.IStandardBeanProxyFactory#createExpression()
  * @see java.lang.IllegalStateException
  * @since 1.0.0
@@ -63,6 +67,14 @@
 public interface IExpression extends IExpressionConstants {
 	
 	/**
+	 * Return the registry this expression is working against.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public ProxyFactoryRegistry getRegistry();
+	
+	/**
 	 * Invoke the expression(s). If there is more than one root expression, it will invoke them
 	 * in the order created. If the expression stack is not complete, then <code>IllegalStateException</code>
 	 * will be thrown.
@@ -76,6 +88,27 @@
 	public void invokeExpression() throws ThrowableProxy, NoExpressionValueException, IllegalStateException;
 	
 	/**
+	 * Return whether the expression is valid. It would be invalid if any of the create... calls had thrown an
+	 * exception or if the expression has already been evaluated (invoked or getExpressionValue()).
+	 * 
+	 * @return <code>true</code> if expression is valid, <code>false</code> if there had been some error, or if the expression has already been evaluated.
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean isValid();
+	
+	/**
+	 * Close the expression. This needs to be called if for some reason {@link IExpression#invokeExpression()} or {@link IExpression#getExpressionValue()}
+	 * were not called. It is not an error to always call this after these calls. It will not have any problems with the expression already
+	 * being closed. invoke and getvalue automatically call close for you. If you don't call close in case of an error, the resources
+	 * for the expression will not be freed up. 
+	 * 
+	 * 
+	 * @since 1.1.0
+	 */
+	public void close();
+	
+	/**
 	 * Invoke the root expression and return the value of the expression. If the expression stack
 	 * is not complete, or if there is more than one root expression, then <code>IllegalStateException</code>
 	 * will be thrown.
@@ -93,20 +126,20 @@
 	/**
 	 * Create an Array Access (e.g. x[3]).
 	 * This must be followed by create expressions for:
-	 * 	<code>ARRAYACCESS_ARRAY</code>
-	 *  indexCount times an: <code>ARRAYACCESS_INDEX</code>
+	 * <pre>
+	 *  <code>ARRAYACCESS_ARRAY</code>
+	 *  <code>ARRAYACCESS_INDEX</code> an indexCount times. 
+	 * </pre>
 	 * <p>
 	 * So the array access must be followed by 1+indexCount expressions.
 	 * 
 	 * @param forExpression This is for what expression this expression is being created.
 	 * @param indexCount The number of index expressions that will be created.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createArrayAccess(int forExpression, int indexCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createArrayAccess(ForExpression forExpression, int indexCount) throws IllegalStateException;
 	
 	/**
 	 * Create an Array Creation (e.g. <code>new int[3]</code> or <code>new int[3][]</code> or <code>new int[] {3, 4}</code>).
@@ -119,20 +152,19 @@
 	 * <code>new int []</code> will have a count of 0.
 	 * <p>
 	 * This must be followed by create expressions for:
-	 * 	dimensionExpressionCount times an: <code>ARRAYCREATION_DIMENSION</code>
-	 *  or an createArrayInitializer if dimension count is 0.
+	 * <pre>
+	 *  <code>ARRAYCREATION_DIMENSION</code> a dimensionExpressionCount times, 
+	 *  or an <code>createArrayInitializer()</code> if dimension count is 0.
+	 * </pre>
 	 *  
 	 * @param forExpression
 	 * @param type This is the type. It must be fully-qualified and if an inner class, it must have the "$" format. It must also include the correct number of  <code>[]</code> at the end.
 	 * @param dimensionExpressionCount
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
-	 * @throws IllegalArgumentException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createArrayCreation(int forExpression, String type, int dimensionExpressionCount) throws ThrowableProxy, IllegalStateException, IllegalArgumentException, NoExpressionValueException;
+	public void createArrayCreation(ForExpression forExpression, String type, int dimensionExpressionCount) throws IllegalStateException;
 
 	/**
 	 * Create an Array Creation (e.g. <code>new int[3]</code> or <code>new int[3][]</code> or <code>new int[] {3, 4}</code>).
@@ -151,13 +183,11 @@
 	 * @param forExpression
 	 * @param type This is the type.
 	 * @param dimensionExpressionCount
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createArrayCreation(int forExpression, IBeanTypeProxy type, int dimensionExpressionCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createArrayCreation(ForExpression forExpression, IProxyBeanType type, int dimensionExpressionCount) throws IllegalStateException;
 	
 	/**
 	 * Create an array initializer. (e.g. <code>{2,3}</code>).
@@ -170,13 +200,11 @@
 	 * 		but it does count as one of the expressionCounts.
 	 * 
 	 * @param expressionCount Number of expressions, may be 0.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createArrayInitializer(int expressionCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createArrayInitializer(int expressionCount) throws IllegalStateException;
 		
 	/**
 	 * Create a cast expression (e.g. <code>(short)10</code> or <code>(java.lang.String) "asd"</code>)
@@ -186,13 +214,11 @@
 	 *  
 	 * @param forExpression
 	 * @param type This is the type. It must be fully-qualified and if an inner class, it must have the "$" format.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createCastExpression(int forExpression, String type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createCastExpression(ForExpression forExpression, String type) throws IllegalStateException;
 
 	/**
 	 * Create a cast expression (e.g. <code>(short)10</code> or <code>(java.lang.String) "asd"</code>)
@@ -202,13 +228,11 @@
 	 *  
 	 * @param forExpression
 	 * @param type This is the type.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createCastExpression(int forExpression, IBeanTypeProxy type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createCastExpression(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException;
 		
 	/**
 	 * Create a new class instance expression (e.g. <code>new java.lang.Integer(5)</code>)
@@ -219,13 +243,11 @@
 	 * @param forExpression
 	 * @param type This is the type. It must be fully-qualified and if an inner class, it must have the "$" format.
 	 * @param argumentCount
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createClassInstanceCreation(int forExpression, String type, int argumentCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createClassInstanceCreation(ForExpression forExpression, String type, int argumentCount) throws IllegalStateException;
 
 	/**
 	 * Create a new class instance expression (e.g. <code>new java.lang.Integer(5)</code>)
@@ -236,13 +258,11 @@
 	 * @param forExpression
 	 * @param type This is the type.
 	 * @param argumentCount
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createClassInstanceCreation(int forExpression, IBeanTypeProxy type, int argumentCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createClassInstanceCreation(ForExpression forExpression, IProxyBeanType type, int argumentCount) throws IllegalStateException;
 	
 	/**
 	 * Create a conditional expression (e.g. <code>x != 3 ? 4 : 5</code>)
@@ -253,13 +273,11 @@
 	 * 	<code>CONDITIONAL_FALSE</code>	
 	 * 
 	 * @param forExpression
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createConditionalExpression(int forExpression) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createConditionalExpression(ForExpression forExpression) throws IllegalStateException;
 	
 	/**
 	 * Create a field access (e.g. <code>java.awt.Color.red</code>)
@@ -273,15 +291,53 @@
 	 * 
 	 * @param forExpression
 	 * @param fieldName The name of the field.
-	 * @param hasReceiver Has a receiver flag. Currently this must always be true.
-	 * @throws ThrowableProxy
+	 * @param hasReceiver Has a receiver flag. Currently this must always be true. This is because can't tell what class to look into for the field without a receiver.
+	 * @throws IllegalArgumentException
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @see IExpression#createTypeReceiver(String)
 	 * @since 1.0.0
 	 */
-	public void createFieldAccess(int forExpression, String fieldName, boolean hasReceiver) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createFieldAccess(ForExpression forExpression, String fieldName, boolean hasReceiver) throws IllegalArgumentException, IllegalStateException;
+
+	/**
+	 * Create a field access (e.g. <code>java.awt.Color.red</code>)
+	 * <p>
+	 * Note: At this time we require a receiver for non-static access. In the future it may be possible to not have one, but
+	 * for that we need a <code>this</code> object to know who the receiver implicitly is.
+	 * The receiver may be a "type receiver" if it is a type, e.g. <code>java.awt.Color</code>.
+	 * <p>
+	 * This must be followed by createExpressions for:
+	 * <pre>
+	 * 	<code>FIELD_RECEIVER</code> if hasReceiver is <code>true</code>
+	 * </pre>
+	 * 
+	 * @param forExpression
+	 * @param fieldProxy The field proxy for the field.
+	 * @param hasReceiver Has a receiver flag.
+	 * @throws IllegalStateException
+	 * 
+	 * @see IExpression#createTypeReceiver(String)
+	 * @since 1.0.0
+	 */
+	public void createFieldAccess(ForExpression forExpression, IProxyField fieldProxy, boolean hasReceiver) throws IllegalStateException;
+
+	/**
+	 * Create an if/else stmt. Since this is a statment, there is no ForExpression. ROOT_EXPRESSION must be the next expression type.
+	 * <p<
+	 * This must be followed by createExpressions for:
+	 * <pre>
+	 *   <code>IF_CONDITION</code> The if test, must return boolean.
+	 *   <code>IF_TRUE</code> The if condition is true clause. The clause may be an expression, or a block.
+	 *   <code>IF_ELSE</code>  if hasElseClause is <code>true</code>. The else clause. The clause may be an expression, or a block.
+	 * </pre>
+	 * 
+	 * @param hasElseClause
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public void createIfElse(boolean hasElseClause) throws IllegalStateException;
 	
 	/**
 	 * Create an infix expression (e.g. <code>3 + 4</code> or <code>3 + 4 + 5</code>).
@@ -290,22 +346,22 @@
 	 * the expression can be done in one expression than requiring several, one for each operator.
 	 * If they are different operators, then different expressions will be required.
 	 * <p>
+	 * <pre>
 	 * This must be followed by createExpressions for:
 	 * 	<code>INFIX_LEFT</code>
 	 * 	<code>INFIX_RIGHT</code>
 	 * 	extendedOperandCount times an: <code>INFIX_EXTENDED</code>
+	 * </pre>
 	 * 
 	 * @param forExpression
-	 * @param operator The operator. The values come from IExpressionConstants, the infix constants.
+	 * @param operator The operator.
 	 * @param extendedOperandCount The number of extended operands. May be zero.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @see org.eclipse.jem.internal.proxy.common.IExpressionConstants#IN_AND
 	 * @since 1.0.0
 	 */
-	public void createInfixExpression(int forExpression, int operator, int extendedOperandCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createInfixExpression(ForExpression forExpression, InfixOperator operator, int extendedOperandCount) throws IllegalStateException;
 	
 	/**
 	 * Create an instanceof expression (e.g. <code>x instanceof java.lang.String</code>
@@ -314,13 +370,11 @@
 	 * 	<code>INSTANCEOF_VALUE</code>
 	 * @param forExpression
 	 * @param type This is the type. It must be fully-qualified and if an inner class, it must have the "$" format.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createInstanceofExpression(int forExpression, String type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createInstanceofExpression(ForExpression forExpression, String type) throws IllegalStateException;
 	
 	/**
 	 * Create an instanceof expression (e.g. <code>x instanceof java.lang.String</code>
@@ -329,16 +383,17 @@
 	 * 	<code>INSTANCEOF_VALUE</code>
 	 * @param forExpression
 	 * @param type This is the type.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createInstanceofExpression(int forExpression, IBeanTypeProxy type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createInstanceofExpression(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException;
 	
 	/**
-	 * Create a method invocation expression (e.g. <code>java.lang.String.valueOf(10)</code>)
+	 * Create a method invocation expression (e.g. <code>java.lang.String.valueOf(10)</code>).
+	 * When using a string the method invoked will be the one most compatible with the arguments sent. 
+	 * This allows overloading a method to occur when coming in from a parse tree, since the parse tree
+	 * doesn't know the exact method to use.
 	 * <p>
 	 * Note: At this time we require a receiver. In the future it may be possible to not have one, but
 	 * for that we need a <code>this</code> object to know who the receiver implicitly is.
@@ -352,196 +407,195 @@
 	 * @param name The name of the method
 	 * @param hasReceiver Has a receiver flag. Currently this must always be true.
 	 * @param argumentCount Count of number of arguments. May be zero.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
+	 * @throws IllegalArgumentException
 	 * 
 	 * @see IExpression#createTypeReceiver(String)
 	 * @since 1.0.0
 	 */
-	public void createMethodInvocation(int forExpression, String name, boolean hasReceiver, int argumentCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
-	
+	public void createMethodInvocation(ForExpression forExpression, String name, boolean hasReceiver, int argumentCount) throws IllegalStateException, IllegalArgumentException;
+
+	/**
+	 * Create a method invocation expression (e.g. <code>java.lang.String.valueOf(10)</code>)
+	 * <p>
+	 * Note: At this time we require a receiver. In the future it may be possible to not have one, but
+	 * for that we need a <code>this</code> object to know who the receiver implicitly is.
+	 * The receiver may be a "type receiver" if it is a type, e.g. <code>java.awt.Color</code>.
+	 * <p>
+	 * This must be followed by createExpression for:
+	 * 	<code>METHOD_RECEIVER</code>
+	 * 	argumentCounts times expressions for: <code>METHOD_ARGUMENT</code>
+	 * 
+	 * @param forExpression
+	 * @param methodProxy The proxy of the method
+	 * @param hasReceiver Has a receiver flag. Currently this must always be true.
+	 * @param argumentCount Count of number of arguments. May be zero.
+	 * @throws IllegalStateException
+	 * @throws IllegalArgumentException
+	 * 
+	 * @see IExpression#createTypeReceiver(String)
+	 * @since 1.0.0
+	 */
+	public void createMethodInvocation(ForExpression forExpression, IProxyMethod methodProxy, boolean hasReceiver, int argumentCount) throws IllegalStateException, IllegalArgumentException;
+
 	/**
 	 * Create a prefix expression (e.g. <code>!flag</code> or <code>-(3+4)</code>).
 	 * If you are just trying to create a signed numeric literal, just use the createPrimitiveLiteral passing in a
 	 * negative value. You don't need to use prefix expression for that.
 	 * <p>
+	 * <pre>
 	 * This must be followed by createExpressions for:
 	 * 	<code>PREFIX_OPERAND</code>
+	 * </pre>
 	 * @param forExpression
 	 * @param operator The operator. The values come from IExpressionConstants, the prefix constants.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @see org.eclipse.jem.internal.proxy.common.IExpressionConstants#PRE_PLUS
 	 * @since 1.0.0
 	 */
-	public void createPrefixExpression(int forExpression, int operator) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrefixExpression(ForExpression forExpression, PrefixOperator operator) throws IllegalStateException;
 	
 	/**
 	 * Create a reference to <code>null</code>.
 	 * 
 	 * @param forExpression
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createNull(int forExpression) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createNull(ForExpression forExpression) throws IllegalStateException;
 	
 	/**
-	 * Create a type literal (e.g. <code>java.lang.String.class</code>).\
+	 * Create a type literal (e.g. <code>java.lang.String.class</code>). This is used when the type is being used as value itself, not
+	 * as a receiver for a field or method or constructor or instanceof. Like as an argument to a method.
 	 * <p>
-	 * Note: If you want a type literal to a IBeanTypeProxy, just use createProxyExpression and pass in the
-	 * IBeanTypeProxy.
+	 * Note: If you want a type literal to be an IProxyBeanType, just use {@link IExpression#createProxyExpression(ForExpression, IProxy)} and pass in the
+	 * IProxyBeanType.
 	 * 
 	 * @param forExpression
 	 * @param type This is the type. It must be fully-qualified and if an inner class, it must have the "$" format.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createTypeLiteral(int forExpression, String type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createTypeLiteral(ForExpression forExpression, String type) throws IllegalStateException;
 	
 	/**
 	 * Create a type receiver. This is where a type is used as the receiver of a field access or a method invocation.
-	 * (e.g. <code>java.lang.String.valueOf(10)</code>). 
+	 * (e.g. <code>java.lang.String.valueOf(10)</code>). For this the "java.lang.String" IBeanTypeProxy is the type receiver.
 	 * <p>
 	 * This is unusual in that there is no forExpression. It isn't needed because these are only valid
 	 * in certain situations (method or field receiver) and if used anywhere else it is an error.
 	 * 
 	 * @param type This is the type. It must be fully-qualified and if an inner class, it must have the "$" format.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createTypeReceiver(String type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createTypeReceiver(String type) throws IllegalStateException;
 
 	/**
 	 * Create a type receiver. This is where a type is used as the receiver of a field access or a method invocation.
-	 * (e.g. <code>java.lang.String.valueOf(10)</code>). 
+	 * (e.g. <code>java.lang.String.valueOf(10)</code>). For this the "java.lang.String" IProxyBeanType is the type receiver.
 	 * <p>
 	 * This is unusual in that there is no forExpression. It isn't needed because these are only valid
 	 * in certain situations (method or field receiver) and if used anywhere else it is an error.
 	 * 
 	 * @param type This is the type proxy.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createTypeReceiver(IBeanTypeProxy type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createTypeReceiver(IProxyBeanType type) throws IllegalStateException;
 	
 	/**
 	 * Create a boolean primitive literal (e.g. <code>true</code>).
 	 * 
 	 * @param forExpression
 	 * @param value The boolean value for the literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createPrimitiveLiteral(int forExpression, boolean value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrimitiveLiteral(ForExpression forExpression, boolean value) throws IllegalStateException;
 	
 	/**
 	 * Create a character literal (e.g. <code>'a'</code> or <code>'\n'</code>)
 	 * 
 	 * @param forExpression
 	 * @param value The character value for this literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createPrimitiveLiteral(int forExpression, char value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrimitiveLiteral(ForExpression forExpression, char value) throws IllegalStateException;
 
 	/**
 	 * Create a byte literal (e.g. <code>(byte)10</code>)
 	 * 
 	 * @param forExpression
 	 * @param value The byte value for this literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createPrimitiveLiteral(int forExpression, byte value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrimitiveLiteral(ForExpression forExpression, byte value) throws IllegalStateException;
 
 	/**
 	 * Create a double literal (e.g. <code>10d</code>)
 	 * 
 	 * @param forExpression
 	 * @param value The double value for this literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createPrimitiveLiteral(int forExpression, double value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrimitiveLiteral(ForExpression forExpression, double value) throws IllegalStateException;
 
 	/**
 	 * Create a float literal (e.g. <code>10f</code>)
 	 * 
 	 * @param forExpression
 	 * @param value The float value for this literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createPrimitiveLiteral(int forExpression, float value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrimitiveLiteral(ForExpression forExpression, float value) throws IllegalStateException;
 	
 	/**
 	 * Create a int literal (e.g. <code>100000</code>)
 	 * 
 	 * @param forExpression
 	 * @param value The int value for this literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createPrimitiveLiteral(int forExpression, int value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrimitiveLiteral(ForExpression forExpression, int value) throws IllegalStateException;
 	
 	/**
 	 * Create a long literal (e.g. <code>10l</code>)
 	 * 
 	 * @param forExpression
 	 * @param value The long value for this literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createPrimitiveLiteral(int forExpression, long value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrimitiveLiteral(ForExpression forExpression, long value) throws IllegalStateException;
 	
 	/**
 	 * Create a short literal (e.g. <code>(short)10</code>)
 	 * 
 	 * @param forExpression
 	 * @param value The short value for this literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createPrimitiveLiteral(int forExpression, short value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createPrimitiveLiteral(ForExpression forExpression, short value) throws IllegalStateException;
 	
 	/**
 	 * Create a string literal (e.g. <code>"asdf"</code>). The value is the actual string, with escapes already
@@ -549,24 +603,332 @@
 	 *  
 	 * @param forExpression
 	 * @param value The string value for this literal.
-	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
-	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void createStringLiteral(int forExpression, String value) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createStringLiteral(ForExpression forExpression, String value) throws IllegalStateException;
 	
 	/**
 	 * Create an expression that has an existing bean proxy as its value.
 	 * 
 	 * @param forExpression This is for what expression this expression is being created.
-	 * @param proxy The proxy that should be used as a value.
+	 * @param proxy The proxy that should be used as a value, either a bean proxy or an expression proxy.
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.0.0
+	 */
+	public void createProxyExpression(ForExpression forExpression, IProxy proxy) throws IllegalStateException;
+		
+	/**
+	 * Create an assignment expression between a VariableReference and an expression. The left operand must be a variable reference (e.g. FieldAccess or
+	 * ArrayAccess). The right operand may be any expression that results in a value.
+	 * <p>
+	 * <pre>
+	 * This must be followed by createExpressions for:
+	 *  <code>ASSIGNMENT_LEFT</code>
+	 * 	<code>ASSIGNMENT_RIGHT</code>
+	 * </pre>
+	 * @param forExpression
 	 * @throws ThrowableProxy
 	 * @throws IllegalStateException
 	 * @throws NoExpressionValueException
 	 * 
-	 * @since 1.0.0
+	 * @since 1.1.0
 	 */
-	public void createProxyExpression(int forExpression, IBeanProxy proxy) throws ThrowableProxy, IllegalStateException, NoExpressionValueException;
+	public void createAssignmentExpression(ForExpression forExpression) throws IllegalStateException;
+	
+	/**
+	 * Create an assignment expression (e.g. x = 3+4) where x will be assigned to the ExpressionProxy. 
+	 * It may be used later on as a value in {@link IExpression#createExpressionProxyExpression(int, ExpressionProxy)}.
+	 * Or if callbacks were added, the callbacks would be called to return the true IBeanProxy value of the expression proxy when the complete
+	 * IExpression has been evaluated. The value of the assignment expression (e.g. x) will be passed on into the next expression.
+	 * <p>
+	 * <pre>
+	 * This must be followed by createExpressions for:
+	 * 	<code>ASSIGNMENT_RIGHT</code>
+	 * </pre>
+	 * <p>
+	 * <b>Note:</b> It is guarenteed as part of the contract that expression proxies will be notified through the listeners of the final state in the
+	 * order the expression proxies were created. 
+	 * @param forExpression This is for what expression this expression is being created.
+	 * @return a proxy to the expression value. 
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public ExpressionProxy createProxyAssignmentExpression(ForExpression forExpression) throws IllegalStateException;
+	
+	/**
+	 * Create a reassignment expression. This is like the original proxy assignment except that instead of returning a new proxy, it
+	 * reassigns the new value to the existing proxy. This cannot be used on IBeanTypeExpressionProxy's. That is because
+	 * they are controlled by the registry and severe errors would occur if they were reassigned.
+	 * <p>
+	 * <pre>
+	 * This must be followed by createExpressions for:
+	 * 	<code>ASSIGNMENT_RIGHT</code>
+	 * </pre>
+	 * <p>
+	 * <b>Note:</b> Since we are not creating a new proxy, the notification on the callbacks will be in the original order of proxies. This
+	 * does not change the notification position of this proxy.
+	 * 
+	 * @param forExpression
+	 * @param proxy
+	 * @throws IllegalStateException
+	 * @throws IllegalArgumentException if the expression proxy is for a BeanType instead of just a standard expression proxy.
+	 * 
+	 * @since 1.1.0
+	 */
+	public void createProxyReassignmentExpression(ForExpression forExpression, ExpressionProxy proxy) throws IllegalStateException, IllegalArgumentException;
+	
+	/**
+	 * A simple method invocation. This is a helper to make it easier for a simple method invoke. It uses only the 
+	 * method proxy (not a string to look it up), it uses a IBeanProxy receiver (not a complicated expression), and the
+	 * arguments are a mixture of IBeanProxies and ExpressionProxies. Also it can be called only when the next
+	 * expression must be a RootExpression.
+	 * 
+	 * @param method methodproxy of the method
+	 * @param receiver the receiver proxy or <code>null</code> if a static method
+	 * @param arguments array of arguments, where each element can only be either <code>null</code> for a null argument, <code>IProxy</code>. The array can be <code>null</code> if no arguments.
+	 * @param wantResult <code>true</code> if you want an ExpressionProxy back, otherwise it will return <code>null</code>. For performance reasons, only use <code>true</code> if you really need the expression proxy.
+	 * @return expression proxy if "wantResult" was true, else <code>null</code>.
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public ExpressionProxy createSimpleMethodInvoke(IProxyMethod method, IProxy receiver, IProxy[] arguments, boolean wantResult) throws IllegalStateException;
+
+	/**
+	 * A simple field access. This is a helper to make it easier for a simple field access. It uses only the 
+	 * field proxy (not a string to look it up), and the bean proxy that is the receiver. Also it can be called only when the next
+	 * expression must be a RootExpression. It doesn't allow complicated field access, such as <code>fielda.fieldb.fieldc</code>.
+	 * Since this is a field access, it will always return an ExpressionProxy. It doesn't make sense to have a simple field access
+	 * that doesn't return one.
+	 * 
+	 * @param field field proxy of the field.
+	 * @param receiver the receiver proxy. It may be <code>null</code> for static fields.
+	 * @return expression proxy to the result of the access.
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public ExpressionProxy createSimpleFieldAccess(IProxyField field, IProxy receiver) throws IllegalStateException;
+
+	/**
+	 * A simple field set. This is a helper to make it easier for a simple field access. It uses only the 
+	 * field proxy (not a string to look it up), and the bean proxy that is the receiver. Also it can be called only when the next
+	 * expression must be a RootExpression. It doesn't allow complicated field access setting, such as <code>fielda.fieldb.fieldc = 3</code>.
+	 * 
+	 * @param field field proxy of the field.
+	 * @param receiver the receiver proxy. It may be <code>null</code> if this is a static field.
+	 * @param value the value proxy to set it to or <code>null</code> if set to null value.
+	 * @param wantResult <code>true</code> if you want an ExpressionProxy back, otherwise it will return <code>null</code>. For performance reasons, only use <code>true</code> if you really need the expression proxy.
+	 * @return expression proxy if "wantResult" was true, else <code>null</code>.
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public ExpressionProxy createSimpleFieldSet(IProxyField field, IProxy receiver, IProxy value, boolean wantResult) throws IllegalStateException;
+
+	/**
+	 * Begin a block. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * <p>
+	 * Eventually {@link Expression#createBlockEnd()} must be called. You should use this pattern:
+	 * <pre><code>
+	 * exp.createBeginBlock();
+	 * try {
+	 *   exp.create something else.
+	 *   ...
+	 * } finally {
+	 *   exp.createEndBlock();
+	 * }
+	 * </code></pre>
+	 * 
+	 * @return blocknumber for the block just opened. Can be used in {@link Expression#createBlockBreak(int)}.
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public int createBlockBegin() throws IllegalStateException;
+	
+	/**
+	 * Does a break for the specified block number. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * @param blockNumber
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public void createBlockBreak(int blockNumber) throws IllegalStateException;
+
+	/**
+	 * End a block. It will always end the inner most block that currently is on the stack. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * @throws IllegalStateException
+	 * 
+	 * @see Expression#createBlockBegin()
+	 * @since 1.1.0
+	 */
+	public void createBlockEnd() throws IllegalStateException;
+	
+	/**
+	 * Create a try/catch statement. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * There must be at least one catch or finally clause before try end or this is invalid.
+	 * <p>
+	 * This should be executed in the following way:
+	 * <pre><code>
+	 * exp.createTry();
+	 * try {
+	 *   ... create other exceptions ...
+	 *   ... create catch/finally clauses as needed.
+	 * } finally {
+	 *   if (exp.isValid())
+	 *     exp.createTryEnd();
+	 * }
+	 * </code></pre>
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public void createTry() throws IllegalStateException;
+	
+
+	/**
+	 * Create a catch clause for the inner most try statement. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * <p>
+	 * Using this you can get just the exception as a proxy and/or execute some expressions as part of the catch clause.
+	 * <p>
+	 * This can be followed by RootExpressions, or another catch, or a finally, or a try end.
+	 *  
+	 * @param exceptionType the type of the exception to catch on.
+	 * @param wantExceptionReturned <code>true</code> if you want an expression proxy for the exception.
+	 * @return the ExpressionProxy for the exception if <code>wantExceptionReturned</code> is <code>true</code>, <code>null</code> otherwise.
+	 * 
+	 * @throws IllegalStateException
+	 * @since 1.1.0
+	 */
+	public ExpressionProxy createTryCatchClause(IProxyBeanType exceptionType, boolean wantExceptionReturned) throws IllegalStateException;;
+
+	/**
+	 * Create a catch clause for the inner most try statement. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * <p>
+	 * Using this you can get just the exception as a proxy and/or execute some expressions as part of the catch clause.
+	 * <p>
+	 * This can be followed by RootExpressions, or another catch, or a finally, or a try end.
+	 *  
+	 * @param exceptionType the type of the exception to catch on.
+	 * @param wantExceptionReturned <code>true</code> if you want an expression proxy for the exception.
+	 * @return the ExpressionProxy for the exception if <code>wantExceptionReturned</code> is <code>true</code>, <code>null</code> otherwise.
+	 * 
+	 * @throws IllegalStateException
+	 * @since 1.1.0
+	 */
+	public ExpressionProxy createTryCatchClause(String exceptionType, boolean wantExceptionReturned) throws IllegalStateException;;
+
+	/**
+	 * Create a finally clause for the inner most try statement. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * There must be no more catch clauses for the try statement after this finally clause.
+	 * 
+	 * @throws IllegalStateException
+	 * @since 1.1.0
+	 */
+	public void createTryFinallyClause() throws IllegalStateException;;
+	
+	/**
+	 * Create the end of the inner most try statement. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * There must be no more catch/finally clauses after this except if a new try statement is started.
+	 * 
+	 * @throws IllegalStateException
+	 * @since 1.1.0
+	 */
+	public void createTryEnd() throws IllegalStateException;;
+	
+	/**
+	 * Create a throw. No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * The next expression is the exception to be thrown.
+	 * <p>
+	 * This must be followed by createExpression for:
+	 * 	<code>THROW_OPERAND</code>
+	 *  
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public void createThrow() throws IllegalStateException;
+	
+	/**
+	 * Create a rethrow. This must be within a catch clause or there is an error.
+	 * <p> 
+	 * This is a shortcut for:
+	 * <pre><code>
+	 * try {
+	 *   .. do something ..
+	 * } catch (AnException e) {
+	 *   .. do something ..
+	 *   throw e;
+	 * }
+	 * </code></pre>
+	 * @throws IllegalStateException
+	 * 
+	 * @since 1.1.0
+	 */
+	public void createRethrow() throws IllegalStateException;
+
+	
+	/**
+	 * Mark the expression stack so that if there are IllegalStateExceptions errors that would make the
+	 * expression invalid, you can restore back to this mark point and the expression will now be valid
+	 * again and at the state it was when mark was created. All marks must be ended, and at the same nesting
+	 * level.
+	 * <p>
+	 * No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * <p>
+	 * It must be used in conjunction with endMark. You must use <code>mark;try/finally{endMark;}</code> because
+	 * the mark/endMark must match up. 
+	 * <pre><code>
+	 * int mark = expression.mark();
+	 * try {
+	 *   expression.create ...
+	 * } catch (IllegalStateException e) {
+	 *   process the error.
+	 * } finally {
+	 *   expression.endMark(mark); // After this, the expression will be valid again.
+	 * }
+	 * </code></pre>
+	 * <p>
+	 * However, the following code would be invalid nesting, and will throw an IllegalStateException on the createTryEnd. This is because
+	 * we tried to end the Try statement within the mark. This is invalid because if we let it go through it would
+	 * of popped the stack and when we got to the endMark the stack would of been popped past it and it could not
+	 * be restored to the same state as it was at the time of the mark. The try would of already been ended.
+	 * <pre><code>
+	 * expression.createTry();
+	 * int mark = expression.mark();
+	 * try {
+	 *   expression.create ...
+	 *   expression.createTryEnd();
+	 * } catch (IllegalStateException e) {
+	 *   process the error. The expression is now invalid.
+	 * } finally {
+	 *   expression.endMark(mark); // After this, the expression will be valid again, if it had gone invalid.
+	 * }
+	 * </code></pre>
+	 * <p>
+	 * If not at RootExpression at time of mark() request, an IllegalStateException will be thrown.
+	 * @return mark number, this number will be used in the cooresponding endMark.
+	 * @throws IllegalStateException
+	 * 
+	 * @see IExpression#endMark(int)
+	 * @since 1.1.0
+	 */
+	public int mark() throws IllegalStateException;
+	
+	/**
+	 * The end mark for a mark. 
+	 * <p>
+	 * No need for a forExpression because it must currently be at ROOTEXPRESSION.
+	 * @param markNumber
+	 * @throws IllegalStateException
+	 * 
+	 * @see IExpression#mark()
+	 * @since 1.1.0
+	 */
+	public void endMark(int markNumber) throws IllegalStateException;
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IFieldProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IFieldProxy.java
index 48f0a88..d6e9967 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IFieldProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IFieldProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.core;
 /*
  *  $RCSfile: IFieldProxy.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -22,7 +22,7 @@
  * Creation date: (1/17/00 12:17:52 PM)
  * @author: Joe Winchester
  */
-public interface IFieldProxy extends IAccessibleObjectProxy {
+public interface IFieldProxy extends IAccessibleObjectProxy, IProxyField {
 /**
  * Return the type of the field.
  */
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IMethodProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IMethodProxy.java
index c14a1a5..7fd5bb6 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IMethodProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IMethodProxy.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IMethodProxy.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.core;
 
@@ -19,7 +19,7 @@
  * 
  * @author: Joe Winchester
  */
-public interface IMethodProxy extends IAccessibleObjectProxy, IInvokable {
+public interface IMethodProxy extends IAccessibleObjectProxy, IInvokable, IProxyMethod {
 
 	/**
 	 * Answer the class the method is defined in. Creation date: (12/3/99 11:37:12 AM)
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IMethodProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IMethodProxyFactory.java
index 0e123c3..5d41541 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IMethodProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IMethodProxyFactory.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IMethodProxyFactory.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.core;
 
@@ -37,8 +37,32 @@
 	 * @since 1.0.0
 	 */
 	IMethodProxy getMethodProxy(String className, String methodName, String[] parameterTypes);
+	
+	/**
+	 * Return an IProxyMethod for the specified name, arguments from the given class.
+	 * @param expression
+	 * @param className
+	 * @param methodName
+	 * @param parameterTypes
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	IProxyMethod getMethodProxy(IExpression expression, String className, String methodName, String[] parameterTypes);
 
 	/**
+	 * Return an IProxyField for the specified name, arguments from the given class.
+	 * @param expression
+	 * @param className
+	 * @param fieldName
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	IProxyField getFieldProxy(IExpression expression, String className, String fieldName);
+
+	
+	/**
 	 * Return an invokable for the specified name, arguments from the class. The method proxy is not retrieved. Instead the method will be looked up
 	 * each time on the vm. Because of this these are suitable only for one-shot invokations. If it is to be invoked often, then a method proxy should
 	 * be retrieved instead.
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IPointBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IPointBeanProxy.java
similarity index 80%
rename from plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IPointBeanProxy.java
rename to plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IPointBeanProxy.java
index 0344584..9b6c7c5 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IPointBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IPointBeanProxy.java
@@ -1,4 +1,4 @@
-package org.eclipse.jem.internal.proxy.awt;
+package org.eclipse.jem.internal.proxy.core;
 /*******************************************************************************
  * Copyright (c)  2001, 2003 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials 
@@ -11,13 +11,15 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IPointBeanProxy.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:47 $ 
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
-import org.eclipse.jem.internal.proxy.core.IBeanProxy;
 /**
  * Interface to a Point bean proxy.
+ * <p>
+ * These are common for different windowing systems, e.g. AWT and SWT. So this here
+ * is common interface for them.
  * Creation date: (4/7/00 3:46:39 PM)
  * @author: Administrator
  */
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxy.java
new file mode 100644
index 0000000..be45338
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxy.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/*
+ *  $RCSfile: IProxy.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.core;
+ 
+
+/**
+ * A common interface for proxies. It is used by the expression processor to easily distinquish between
+ * a proxy and an Expression proxy. 
+ * @since 1.1.0
+ */
+public interface IProxy {
+	
+	/**
+	 * Is this a bean proxy (including all of the subinterfaces of it, like IMethodProxy).
+	 * @return <code>true</code> if this is a bean proxy.
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean isBeanProxy();
+
+	/**
+	 * Is this an expression proxy.
+	 * @return <code>true</code> if this is an expression proxy.
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean isExpressionProxy();
+}
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyBeanType.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyBeanType.java
new file mode 100644
index 0000000..cecb136
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyBeanType.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: IProxyBeanType.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.core;
+ 
+
+/**
+ * This interface is for IBeanTypeProxy's and BeanTypeExpressionProxy's so that we can lazily
+ * get the beantype proxy and have the expression process it when needed.
+ * 
+ * @since 1.1.0
+ */
+public interface IProxyBeanType extends IProxy {
+
+	/**
+	 * Answer the name of the type we are proxying This is the fully qualified name. For arrays it will return the format: [Lclassname; 
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public String getTypeName();
+	
+	/**
+	 * Get the IProxyMethod for the method from this beantype. It may be either a resolved method proxy (if already resolved) or
+	 * it may be an ExpressionProxy if not yet resolved.
+	 * 
+	 * @param expression
+	 * @param methodName
+	 * @param parameterTypes array of parameter types or <code>null</code> if no parameters.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String methodName, IProxyBeanType[] parameterTypes);
+	
+	/**
+	 * Get the IProxyMethod for the method from this beantype. It may be either a resolved method proxy (if already resolved) or
+	 * it may be an ExpressionProxy if not yet resolved.
+	 * 
+	 * @param expression
+	 * @param methodName
+	 * @param parameterTypes array of parameter types or <code>null</code> if no parameters.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String methodName, String[] parameterTypes);
+	
+	/**
+	 * Get the IProxyyField for the field from this beantype. It may be either a resolved field proxy (if already resolved) or
+	 * it may be an ExpressionProxy if not yet resolved.
+	 * 
+	 * @param expression
+	 * @param fieldName
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyField getFieldProxy(IExpression expression, String fieldName);
+}
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyField.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyField.java
new file mode 100644
index 0000000..24ef953
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyField.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: IProxyField.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.core;
+ 
+
+/**
+ * This interface is for IFieldProxy's and FieldExpressionProxy's so that we can lazily
+ * get the field proxy and have the expression process it when needed.
+ * @since 1.1.0
+ */
+public interface IProxyField extends IProxy {
+
+}
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyMethod.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyMethod.java
new file mode 100644
index 0000000..2268869
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IProxyMethod.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: IProxyMethod.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.core;
+ 
+
+/**
+ * This interface is for IMethodProxy's and MethodExpressionProxy's so that we can lazily
+ * get the method proxy and have the expression process it when needed.
+ * 
+ * @since 1.1.0
+ */
+public interface IProxyMethod extends IProxy {
+
+}
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IRectangleBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IRectangleBeanProxy.java
similarity index 85%
rename from plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IRectangleBeanProxy.java
rename to plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IRectangleBeanProxy.java
index 88cfd67..257ff06 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/awt/IRectangleBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IRectangleBeanProxy.java
@@ -1,4 +1,4 @@
-package org.eclipse.jem.internal.proxy.awt;
+package org.eclipse.jem.internal.proxy.core;
 /*******************************************************************************
  * Copyright (c)  2001, 2003 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials 
@@ -11,13 +11,15 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IRectangleBeanProxy.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:47 $ 
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
-import org.eclipse.jem.internal.proxy.core.IBeanProxy;
 /**
  * Interface to a Rectangle bean proxy.
+ * <p>
+ * These are common for different windowing systems, e.g. AWT and SWT. So this here
+ * is common interface for them.
  * Creation date: (4/7/00 3:46:39 PM)
  * @author: Administrator
  */
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IStandardBeanTypeProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IStandardBeanTypeProxyFactory.java
index 377560a..c6d7ddb 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IStandardBeanTypeProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/IStandardBeanTypeProxyFactory.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IStandardBeanTypeProxyFactory.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.util.Set;
@@ -23,18 +23,36 @@
  * @author: Richard Lee Kulp
  */
 public interface IStandardBeanTypeProxyFactory extends IBeanProxyFactory {
+	
 /**
  * Used by other registered bean type proxy factories to
  * register their bean type proxies with the standard factory
  * so that it will be cached there. 
- *
- * The permanent flag indicates that beantype will never be released,
+ * <p><b>Note:</b> This is not meant to be called by customers. It is here for the usage
+ * of registry extensions.
+ * @param aBeanTypeProxy
+ * @param permanent indicates that beantype will never be released,
  * not even if explicit request is made.
- * Creation date: (3/10/00 11:02:11 AM)
+ * 
+ * @since 1.1.0
  */
 void registerBeanTypeProxy(IBeanTypeProxy aBeanTypeProxy, boolean permanent);
 
 /**
+ * Used by other registered bean type proxy factories to
+ * register their proxy bean type with the standard factory
+ * so that it will be cached there. 
+ * <p><b>Note:</b> This is not meant to be called by customers. It is here for the usage
+ * of registry extensions.
+ * @param aBeanTypeProxy
+ * @param permanent indicates that beantype will never be released,
+ * not even if explicit request is made.
+ * 
+ * @since 1.1.0
+ */
+void registerBeanTypeProxy(IProxyBeanType aBeanTypeProxy, boolean permanent);
+
+/**
  * Return the beanType proxy for the given class name.
  * It must be fully qualified. And for arrays it can handle
  * either the jni type ([Ljava.lang.Object;) or the Java EMF Model
@@ -43,6 +61,17 @@
 IBeanTypeProxy getBeanTypeProxy(String className);
 
 /**
+ * Get the beantype proxy suitable for an expression.
+ * 
+ * @param expression
+ * @param typeName
+ * @return
+ * 
+ * @since 1.1.0
+ */
+IProxyBeanType getBeanTypeProxy(IExpression expression, String typeName);
+
+/**
  * Return an Array type proxy for the given class name of
  * the specified dimensions. This is a helper method. The
  * same result can be gotton from getBeanTypeProxy.
@@ -67,6 +96,37 @@
 IBeanTypeProxy getBeanTypeProxy(String componentClassName, int dimensions);
 
 /**
+ * Return an Array type proxy for the given class name of
+ * the specified dimensions. This is a helper method. The
+ * same result can be gotton from getBeanTypeProxy.
+ * e.g.
+ *      getBeanTypeProxy("java.lang.Object", 3)
+ *    is the same as:
+ *      getBeanTypeProxy("[[[Ljava.lang.Object;")
+ *
+ *    They both result in a type of:
+ *      Object [][][]
+ * 
+ *    or if using the JNI format (proxy format)
+ *      getBeanTypeProxy("[Ljava.langObject;", 3)
+ *    becomes
+ *      Object [][][][] 
+ * 
+ *    or if using the standard java format (as in actual code)
+ *      getBeanTypeProxy("java.langObject[];", 3)
+ *    becomes
+ *      Object [][][][]
+ * 
+ * @param expression
+ * @param componentClassName
+ * @param dimensions
+ * @return
+ * 
+ * @since 1.1.0
+ */
+IProxyBeanType getBeanTypeProxy(IExpression expression, String componentClassName, int dimensions);
+
+/**
  * Test if a specific bean type has been registered. Don't access and create
  * if it isn't currently registered.
  */
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/JavaStandardBeanProxyConstants.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/JavaStandardBeanProxyConstants.java
index bb473b6..fb7b400 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/JavaStandardBeanProxyConstants.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/JavaStandardBeanProxyConstants.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: JavaStandardBeanProxyConstants.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -36,7 +36,7 @@
  * @author: Administrator
  */
 public final class JavaStandardBeanProxyConstants {
-	public static final String REGISTRY_KEY = "STANDARDPROXYCONSTANTS:"; //$NON-NLS-1$
+	public static final Object REGISTRY_KEY = new Object();
 		
 	final IBeanTypeProxy fCollectionType;
 	final IBeanTypeProxy fListType;
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ListenerList.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ListenerList.java
index 2d887a0..5511b35 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ListenerList.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ListenerList.java
@@ -10,13 +10,13 @@
  *******************************************************************************/
 /*
  *  $RCSfile: ListenerList.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.core;
 
 /**
  * This class is used to maintain a list of listeners, and
- * is used in the implementations of several classes within JFace
+ * is used in the implementations of several classes within jem
  * which allow you to register listeners of various kinds.
  * It is a fairly lightweight object, occupying minimal space when
  * no listeners are registered.
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/MapJNITypes.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/MapJNITypes.java
index 2d704a7..e1be81d 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/MapJNITypes.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/MapJNITypes.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: MapJNITypes.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.core;
 
@@ -56,4 +56,17 @@
 	public static boolean isFormalTypePrimitive(String formalType) {
 		return MapTypes.MAP_TYPENAME_TO_SHORTSIG.get(formalType) != null;
 	}
+	
+	/**
+	 * Convert the formal type name, with the given number of dimensions,
+	 * to an array JNI type.
+	 * @param finalComponent final component name, should not be an array type.
+	 * @param dimensions number of dimensions for the array.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public static String getJNITypeName(String finalComponent, int dimensions) {
+		return MapTypes.getJNITypeName(finalComponent, dimensions);
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ProxyLaunchSupport.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ProxyLaunchSupport.java
index 688cf72..df36db4 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ProxyLaunchSupport.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ProxyLaunchSupport.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: ProxyLaunchSupport.java,v $
- *  $Revision: 1.21 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.22 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.core;
 
@@ -54,6 +54,15 @@
 	// If the property is trully not set, then there is no default and there are no configurations for it.
 	public static final String NOT_SET = "...not..set..";	  //$NON-NLS-1$
 		
+	public static final String EXPRESSION_TRACING = "/debug/traceexpressions";	// Trace IExpressions.
+	
+	/**
+	 * Timer threshold for indicating any expressions that took longer than this.
+	 * If not set, then threshold will default to 100ms.
+	 * It will only be used if traceexpressions is true.
+	 */
+	public static final String EXPRESSION_TRACEING_TIMER_THRESHOLD = "/debug/traceexpressionstimethreshold";	
+	
 	/*
 	 * Registry of launch key to LaunchInfo classes.
 	 */
@@ -619,6 +628,7 @@
 	 */
 	public static String ATTR_PRIVATE;
 	private static IUIRunner UI_RUNNER = null;
+
 	static {
 		ATTR_PRIVATE = null;
 		try {
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ThrowableProxy.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ThrowableProxy.java
index 5bb3d8f..38af2fa 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ThrowableProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/ThrowableProxy.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: ThrowableProxy.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:53:46 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -29,6 +29,23 @@
 		super();
    }
 
+	/**
+	 * @param message
+	 * @param cause
+	 * 
+	 * @since 1.1.0
+	 */
+	protected ThrowableProxy(String message, Throwable cause) {
+		super(message, cause);
+	}
+	/**
+	 * @param cause
+	 * 
+	 * @since 1.1.0
+	 */
+	protected ThrowableProxy(Throwable cause) {
+		super(cause);
+	}
    /**
     * Constructs an <code>Exception</code> with the specified detail message. 
     *
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/messages.properties b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/messages.properties
index fb3e9f4..df25b76 100644
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/messages.properties
+++ b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/messages.properties
@@ -10,7 +10,7 @@
 ###############################################################################
 #
 # $Source: /cvsroot/webtools/jeetools.move/webtools.javaee.git/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/messages.properties,v $
-# $Revision: 1.7 $  $Date: 2005/02/15 22:53:46 $
+# $Revision: 1.8 $  $Date: 2005/05/11 19:01:12 $
 #
 
 
@@ -38,9 +38,10 @@
 ProxyWaitForBuild                                           = Waiting for build to complete
 Expression.InInvalidStateDueTo_EXC_                         = IWAV0162E Expression is in invalid state due to "{0}"
 Expression.InInvalidState_EXC_                              = IWAV0163E Expression is in invalid state
-Expression.TypeSentInInvalidOrder_EXC_                      = IWAV0164E Expression type sent in invalid order
+Expression.TypeSentInInvalidOrder_EXC_                      = IWAV0164E Expression type sent in invalid order, received: {0}, expected {1}.
 Expression.ArrayTypeNotAnArray_EXC_                         = IWAV0165E ArrayType "{0}" is not an array.
-Expression.CannotHandleNoReceiveOnFieldAccess_EXC_          = IWAV0166E Currently cannot handle no receiver on field access.
-Expression.MethodsNeedReceiver_EXC_                         = IWAV0167E Currently methods need receiver ({0})
+Expression.CannotHandleNoReceiveOnFieldAccess_EXC_          = IWAV0166E Access by field name ({0}) (not by proxy) requires a receiver.
+Expression.MethodsNeedReceiver_EXC_                         = IWAV0167E Access by method name ({0}) (not by proxy) requires a receiver.
+Expression.InvalidMarkNesting                               = IWAV0168E Improper nesting of mark statements in Expression. Tried to pop or endMark to before current mark. Tried to go past Mark# {0}.
 ProxyPlugin.CleanupDefaultProxyLaunchConfigurations         = Clean up default proxy launch configurations.
 ProxyLaunchSupport.RegistryCouldNotStartForSomeReason_WARN_ = IWAV0168W Registry could not be started for some reason.
diff --git a/plugins/org.eclipse.jem.proxy/proxyCommon/org/eclipse/jem/internal/proxy/common/ICallbackHandler.java b/plugins/org.eclipse.jem.proxy/proxyCommon/org/eclipse/jem/internal/proxy/common/ICallbackHandler.java
index 31dbc27..8a449ba 100644
--- a/plugins/org.eclipse.jem.proxy/proxyCommon/org/eclipse/jem/internal/proxy/common/ICallbackHandler.java
+++ b/plugins/org.eclipse.jem.proxy/proxyCommon/org/eclipse/jem/internal/proxy/common/ICallbackHandler.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.common;
 /*
  *  $RCSfile: ICallbackHandler.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:54:34 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 /**
@@ -30,9 +30,9 @@
 	 * client. Also you don't want to send big objects. It must
 	 * be constants that don't need to be sent back for any reason
 	 * since their identity will be lost in the transfer.
-	 *
+	 * <p>
 	 * This should be used if there are no parms (i.e. it is null).
-	 * 
+	 * <p>
 	 * To send big objects, use the callback stream.
 	 * 
 	 * @param callbackID
@@ -48,32 +48,43 @@
 
 	/**
 	 * Callback to registered client.
-	 *
-	 * callbackID - The id of the callback. This will be given
-	 *    to the callback when it is created, and it must pass
-	 *    on to the handler. That way it is know which callback
-	 *    to call on the client.
-	 * msgID - The id of the message for the callback. This is an
-	 *    agreed upon id of the developers of the callback on both
-	 *    sides.
-	 * parms - Null if no parms, or an array of objects to send to the client vm. They
+	 * <p>
+	 *  The parms can be <code>null</code> if no parms, or it is an array of parms.
+	 * The parms
 	 *    will be turned into proxies on the client vm. So the callback
 	 *    will recieve an array of proxies to the values in the parms.
 	 *    If any of the entries in the array is itself an array, a
 	 *    proxy to the array will be created and sent. The array itself
 	 *    will not be sent.
-	 *
+	 * <p>
 	 *    If an array entry should go across as an array of proxies and
 	 *    not as one proxy to an array, then the entry needs to be an
-	 *    instance of ICallbackHandler.TransmitableArray. This will flag
+	 *    instance of {@link ICallbackHandler.TransmitableArray transmitableArray}. This will flag
 	 *    that it should transmit the entire entry as proxies. This should
 	 *    be used sparingly, only if there isn't much data in the array and
 	 *    all of the array would be used on the client. That way transmitting
 	 *    the entire array will be faster than accessing individual components.
+	 *
+	 * @param callbackID The id of the callback. This will be given
+	 *    to the callback when it is created, and it must pass
+	 *    on to the handler. That way it is know which callback
+	 *    to call on the client.
+	 * @param msgID The id of the message for the callback. This is an
+	 *    agreed upon id of the developers of the callback on both
+	 *    sides.
+	 * @param parms Null if no parms, or an array of objects to send to the client vm. See the comments 
+	 * above for a complete description of the parameter.
 	 * 
+	 * @see ICallbackHandler.TransmitableArray
 	 */
 	public Object callbackWithParms(int callbackID, int msgID, Object[] parms) throws CommandException;
 
+	/**
+	 * Array wrapper that turns an array for parameters into a transmittable array.
+	 * 
+	 * @see ICallbackHandler#callbackWithParms(int, int, Object[])
+	 * @since 1.1.0
+	 */
 	public static class TransmitableArray {
 		protected final Object[] fArray;
 		public TransmitableArray(Object[] array) {
diff --git a/plugins/org.eclipse.jem.proxy/proxyCommon/org/eclipse/jem/internal/proxy/common/MapTypes.java b/plugins/org.eclipse.jem.proxy/proxyCommon/org/eclipse/jem/internal/proxy/common/MapTypes.java
index 54951a8..b59e9d7 100644
--- a/plugins/org.eclipse.jem.proxy/proxyCommon/org/eclipse/jem/internal/proxy/common/MapTypes.java
+++ b/plugins/org.eclipse.jem.proxy/proxyCommon/org/eclipse/jem/internal/proxy/common/MapTypes.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: MapTypes.java,v $
- *  $Revision: 1.3 $  $Date: 2005/02/15 22:54:34 $ 
+ *  $Revision: 1.4 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.common;
 
@@ -129,4 +129,31 @@
 		// If got here then just a name as is.
 		return jniName;
 	}
+	
+	/**
+	 * Convert the formal type name, with the given number of dimensions,
+	 * to an array JNI type.
+	 * @param finalComponent final component name, should not be an array type.
+	 * @param dimensions number of dimensions for the array.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public static String getJNITypeName(String finalComponent, int dimensions) {
+		StringBuffer jni = new StringBuffer(finalComponent.length()+dimensions+2);
+		while (dimensions-- > 0) {
+			jni.append('[');
+		}
+		
+		String shortSig = (String) MapTypes.MAP_TYPENAME_TO_SHORTSIG.get(finalComponent);
+		if (shortSig == null) {
+			jni.append('L');
+			jni.append(finalComponent);
+			jni.append(';');
+		} else {
+			jni.append(shortSig);
+		}
+		
+		return jni.toString();
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/BeanProxyValueSender.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/BeanProxyValueSender.java
index 8aabf89..2631d13 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/BeanProxyValueSender.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/BeanProxyValueSender.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: BeanProxyValueSender.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.remote;
 
@@ -28,8 +28,8 @@
  * @since 1.1.0
  */
 public class BeanProxyValueSender implements Commands.ValueSender {
-	private int index = 0;
-	private Object[] array;
+	protected int index = 0;
+	protected Object[] array;
 	private Exception exception;
 	private final REMStandardBeanProxyFactory factory;
 	
@@ -64,7 +64,7 @@
 		index = 0;
 	}
 	
-	public Object getArray() {
+	public Object[] getArray() {
 		return array;
 	}
 				
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMBeanTypeProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMBeanTypeProxyFactory.java
index cecf8c6..b81805d 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMBeanTypeProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMBeanTypeProxyFactory.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IREMBeanTypeProxyFactory.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -41,6 +41,28 @@
 public IREMBeanTypeProxy getExtensionBeanTypeProxy(String typeName);	
 
 /**
+ * Return a bean type proxy for the class name.
+ * Return null if the extension factory doesn't handle this class.
+ * Don't register any proxies returned, they will automatically be registered.
+ * This should only return bean type proxies where the factory can determine
+ * everything it needs, such as supertype and classID.
+ * NOTE: This is implemented for the usage of the
+ *       standard BeanType proxy factory. It should
+ *       NOT be called by anyone else. They should
+ *       go through the IStandardBeanTypeFactory
+ *       instead. The standard bean type factory
+ *       will call this method on the appropriate
+ *       extension when it needs to.
+ 
+ * @param typeName
+ * @param expression
+ * @return
+ * 
+ * @since 1.1.0
+ */
+public IProxyBeanType getExtensionBeanTypeProxy(String typeName, IExpression expression);
+
+/**
  * Return a bean type proxy for the class id and class name.
  * Return null if the extension factory doesn't handle this class. 
  * Don't register any proxies returned, they will automatically be registered. 
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMConnection.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMConnection.java
index ce5528d..3dea82f 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMConnection.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMConnection.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: IREMConnection.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -93,13 +93,14 @@
 	
 	/**
 	 * Read array values as BeanProxies into valueSender.
-	 * 
 	 * @param returnValue
 	 * @param valueSender
+	 * @param allowFlag <code>true</code> to allow FLAG values, <code>false</code> if not allow flag values.
+	 * 
 	 * @throws CommandException
 	 * 
 	 * @since 1.1.0
 	 */
-	public void readProxyArrayValues(Commands.ValueObject returnValue, Commands.ValueSender valueSender) throws CommandException;
+	public void readProxyArrayValues(Commands.ValueObject returnValue, Commands.ValueSender valueSender, boolean allowFlag) throws CommandException;
 	
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMExpressionConnection.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMExpressionConnection.java
index 5051142..b38fae6 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMExpressionConnection.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/IREMExpressionConnection.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IREMExpressionConnection.java,v $
- *  $Revision: 1.3 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.4 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.remote;
 
@@ -35,7 +35,7 @@
 	
 	/**
 	 * Start expression processing.
-	 * @param expressionID TODO
+	 * @param expressionID 
 	 * 
 	 * @throws IOException
 	 * 
@@ -46,7 +46,7 @@
 	/**
 	 * Push an expression command. This is the common portion of the
 	 * subcommand. The actual data of the command will be separately done.
-	 * @param expressionID TODO
+	 * @param expressionID 
 	 * @param subcommand The subcommand being sent. From IInternalExpressionConstants.
 	 * 
 	 * @throws IOException
@@ -106,38 +106,55 @@
 	public void pushBoolean(boolean aBool) throws IOException;
 	
 	/**
-	 * Pull the return value and put into the parameter value object. If an error
-	 * occurs, command exception is thrown. The value codes are either <code>ExpressionNoExpressionValueException</code> or
-	 * <code>ThrowableSent</code>
-	 * @param expressionID TODO
-	 * @param returnValue
+	 * Get the final value. It must be called after processing the proxy id resolutions even for sync (so that we can get
+	 * any thrown errors).
 	 * 
+	 * @param result
 	 * @throws CommandException
 	 * 
-	 * @since 1.0.0
+	 * @since 1.1.0
 	 */
-	public void pullValue(int expressionID, Commands.ValueObject returnValue) throws CommandException;
+	public void getFinalValue(Commands.ValueObject result) throws CommandException;
 	
 	/**
-	 * Send the sync command and put the return value into the parameter value object. If an error
-	 * occurs, command exception is thrown. The value codes are either <code>ExpressionNoExpressionValueException</code> or
-	 * <code>ThrowableSent</code>
-	 * @param expressionID TODO
-	 * @param returnValue
+	 * Send the pull value command, with the proxyids of intereset. If an error
+	 * occurs, command exception is thrown. 
+	 * <p>
+	 * After the pull value call, if no errors, the proxyids must be read, and then getFinalValue call must be sent.
+	 * @param expressionID
+	 * @param proxyids expression proxyids that request feedback or <code>null</code> if no proxy ids.
+	 * @param sender sender to use to process the returned proxy ids, or <code>null</code> if expecting no proxy resolutions.
 	 * 
 	 * @throws CommandException
 	 * 
 	 * @since 1.0.0
 	 */
-	public void sync(int expressionID, Commands.ValueObject returnValue) throws CommandException;	
+	public void pullValue(int expressionID, Commands.ValueObject proxyids, Commands.ValueSender sender) throws CommandException;
+	
+	/**
+	 * Send the sync command, with the proxyids of intereset. If an error
+	 * occurs, command exception is thrown.
+	 * <p>
+	 * After the sync call, if no errors, the returned proxyids must be processed and then the final endValue call must be sent.
+	 * 
+	 * @param expressionID 
+	 * @param proxyids expression proxyids that request feedback or <code>null</code> if no proxy ids.
+	 * @param sender sender to use to process the proxy id resolutions, or <code>null</code> if expecting no proxy ids.
+	 * 
+	 * @throws CommandException
+	 * 
+	 * @since 1.0.0
+	 */
+	public void sync(int expressionID, Commands.ValueObject proxyids, Commands.ValueSender sender) throws CommandException;	
 	
 	/**
 	 * Stop expression processing.
-	 * @param expressionID TODO
+	 * @param expressionID 
 	 * 
 	 * @throws IOException
 	 * 
 	 * @since 1.0.0
 	 */
 	public void stopExpressionProcessing(int expressionID) throws IOException;
+
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/LocalProxyLaunchDelegate.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/LocalProxyLaunchDelegate.java
index 579ce5b..9878d68 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/LocalProxyLaunchDelegate.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/LocalProxyLaunchDelegate.java
@@ -9,7 +9,7 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 /*
- * $RCSfile: LocalProxyLaunchDelegate.java,v $ $Revision: 1.21 $ $Date: 2005/02/15 22:56:10 $
+ * $RCSfile: LocalProxyLaunchDelegate.java,v $ $Revision: 1.22 $ $Date: 2005/05/11 19:01:12 $
  */
 package org.eclipse.jem.internal.proxy.remote;
 
@@ -25,11 +25,13 @@
 import java.util.logging.Level;
 
 import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.debug.core.*;
 import org.eclipse.debug.core.model.*;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.launching.*;
 
+import org.eclipse.jem.internal.proxy.common.remote.ExpressionCommands;
 import org.eclipse.jem.internal.proxy.core.*;
 import org.eclipse.jem.internal.proxy.remote.awt.REMRegisterAWT;
 import org.eclipse.jem.util.TimerTests;
@@ -185,6 +187,21 @@
 			extraArgs+=4;	// Number of extra args added for debug mode (if number changes below, this must change).
 		if(useNoverify)
 			extraArgs++; // An extra arg added for '-noverify' flag (if number changes below, this must change).
+		
+		boolean useExpressionTracing = "true".equalsIgnoreCase(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyLaunchSupport.EXPRESSION_TRACING));
+		long expressionTracingThreshold = -1;
+		if (useExpressionTracing) {
+			extraArgs++;
+			String thresholdString = Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyLaunchSupport.EXPRESSION_TRACEING_TIMER_THRESHOLD);
+			if (thresholdString != null) {
+				try {
+					expressionTracingThreshold = Long.valueOf(thresholdString).longValue();
+					extraArgs++;
+				} catch (NumberFormatException e) {
+				}
+			}
+		}
+		
 		List javaLibPaths = controller.getFinalJavaLibraryPath();
 		int existingLibpaths = -1;
 		if (!javaLibPaths.isEmpty()) {
@@ -211,6 +228,12 @@
 		
 		if(useNoverify)
 			cvmArgs[cvmArgsCount++] = "-noverify"; //$NON-NLS-1$
+		
+		if (useExpressionTracing) {
+			cvmArgs[cvmArgsCount++] = "-D"+ExpressionCommands.EXPRESSIONTRACE+"=true";
+			if (expressionTracingThreshold != -1)
+				cvmArgs[cvmArgsCount++] = "-D"+ExpressionCommands.EXPRESSIONTRACE_TIMER_THRESHOLD+'='+String.valueOf(expressionTracingThreshold);
+		}
 
 		// If in debug mode, we need to find a port for it to use.
 		int dport = -1;
@@ -292,34 +315,77 @@
 			final String traceName = name;
 			IStreamsProxy fStreamsProxy = process.getStreamsProxy();
 
+			/**
+			 * StreamListener. Should not be created if ProxyPlugin logger is not logging the requested level.
+			 * 
+			 * @since 1.1.0
+			 */
 			class StreamListener implements IStreamListener {
 				String tracePrefix;
 				Level level;
+				Job printJob;	// Job to try to gather printing together.
+				Logger logger;
+				StringBuffer gatheredText = new StringBuffer(100);
+				{
+					logger = ProxyPlugin.getPlugin().getLogger();
+					printJob = new Job("") {
 
-				public StreamListener(String type, Level level) {
-					tracePrefix = traceName + ':' + type + '>';
+						protected IStatus run(IProgressMonitor monitor) {
+							monitor.beginTask("Print remote vm trace output", 1);
+							while(true) {
+								String output = null;
+								synchronized (gatheredText) {
+									if (gatheredText.length() <= tracePrefix.length())
+										break;	// We've reached the end, no more to print.
+									output = gatheredText.toString();
+									gatheredText.setLength(tracePrefix.length());	// Reset the length to the prefix.
+								}
+								logger.log(output, level);
+							}
+							monitor.done();
+							return Status.OK_STATUS;
+						}
+					};
+					printJob.setPriority(Job.SHORT);
+					printJob.setSystem(true);
+				}
+				
+				public StreamListener(String type, Level level, Logger logger) {
+					tracePrefix = traceName + ':' + type + '>' + System.getProperty("line.separator");
+					gatheredText.append(tracePrefix);
 					this.level = level;
+					this.logger = logger;
 				}
 
 				public void streamAppended(String newText, IStreamMonitor monitor) {
-					Logger logger = ProxyPlugin.getPlugin().getLogger();
-					if (logger.isLoggingLevel(level))
-						logger.log(tracePrefix + newText, level);
+					synchronized(gatheredText) {
+						gatheredText.append(newText);
+					}
+					printJob.schedule(100L);	// Wait tenth of second to gather as much as can together.
 				}
 			};
 
-			// Always listen to System.err output.
-			IStreamMonitor monitor = fStreamsProxy.getErrorStreamMonitor();
-			if (monitor != null)
-				monitor.addListener(new StreamListener("err", Level.WARNING)); //$NON-NLS-1$
+			Logger logger = ProxyPlugin.getPlugin().getLogger();
+			if (logger.isLoggingLevel(Level.WARNING)) {
+				// Always listen to System.err output if we are at least logging warnings.
+				IStreamMonitor monitor = fStreamsProxy.getErrorStreamMonitor();
+				if (monitor != null)
+					monitor.addListener(new StreamListener("err", Level.WARNING, logger)); //$NON-NLS-1$
+			}
 
 			// If debug trace is requested, then attach trace listener for System.out
-			if ("true".equalsIgnoreCase(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyRemoteUtil.DEBUG_VM_TRACEOUT))) { //$NON-NLS-1$
-				// Want to trace the output of the remote vm's.
-
-				monitor = fStreamsProxy.getOutputStreamMonitor();
-				if (monitor != null)
-					monitor.addListener(new StreamListener("out", Level.INFO)); //$NON-NLS-1$							
+			// Expression tracing requires debug trace too because it prints to sysout. However, it requesting expressionTracing, change logging level to INFO,
+			// we want them to show if this true. It is confusing to also have to change logging level in .options file.
+			if (useExpressionTracing)
+				if (!logger.isLoggingLevel(Level.INFO))
+					logger.setLevel(Level.INFO);
+			if (useExpressionTracing || "true".equalsIgnoreCase(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyRemoteUtil.DEBUG_VM_TRACEOUT))) { //$NON-NLS-1$
+				// Want to trace the output of the remote vm's. And we are logging at least level info.
+				if (logger.isLoggingLevel(Level.INFO)) {
+					IStreamMonitor monitor = fStreamsProxy.getOutputStreamMonitor();
+					if (monitor != null)
+						monitor.addListener(new StreamListener("out", Level.INFO, logger)); //$NON-NLS-1$							
+				}							
 			}
 		}
 
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/ProxyRemoteUtil.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/ProxyRemoteUtil.java
index d5477b0..47ce3ff 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/ProxyRemoteUtil.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/ProxyRemoteUtil.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: ProxyRemoteUtil.java,v $
- *  $Revision: 1.9 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.10 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -27,8 +27,8 @@
 	public static final String DEBUG_VM = "/remote/debug/debugvm", // Bring up debugger on remote vm's. //$NON-NLS-1$
 		IO_CONSOLE = "/remote/debug/ioconsole", // IO Through console (system in and out) for asking questions. //$NON-NLS-1$
 		DEBUG_VM_TRACEOUT = "/remote/debug/vmtraceout", // Trace the output from the remote vm's. //$NON-NLS-1$
-		NO_TIMEOUTS = "/remote/debug/notimeouts";	// No socket timeouts when talking to remote vm. Turn this on when doing callback testing. Not needed otherwise. //$NON-NLS-1$ 
-
+		NO_TIMEOUTS = "/remote/debug/notimeouts";	// No socket timeouts when talking to remote vm. Turn this on when doing callback testing. Not needed otherwise. //$NON-NLS-1$
+	
 	private static REMRegistryController pluginRegistryController;
 	
 	/**
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMAbstractBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMAbstractBeanProxy.java
index 8ce2273..3469485 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMAbstractBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMAbstractBeanProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMAbstractBeanProxy.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -119,4 +119,16 @@
 		value.setObjectID(isValid() ? getID().intValue() : Commands.VOID);	// No longer exists, so send over null.
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isBeanProxy()
+	 */
+	public final boolean isBeanProxy() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isExpressionProxy()
+	 */
+	public final boolean isExpressionProxy() {
+		return false;
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMAbstractBeanTypeProxy.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMAbstractBeanTypeProxy.java
index 02dbc20..dd803ea 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMAbstractBeanTypeProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMAbstractBeanTypeProxy.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: REMAbstractBeanTypeProxy.java,v $
- *  $Revision: 1.11 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.12 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.remote;
 
@@ -301,6 +301,15 @@
 	public IFieldProxy getFieldProxy(String fieldName) {
 		return ((REMStandardBeanTypeProxyFactory) fRegistry.getBeanTypeProxyFactory()).proxyConstants.getFieldProxy(this,fieldName);
 	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String)
+	 */
+	public IProxyField getFieldProxy(IExpression expression, String fieldName) {
+		REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry();
+		return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getFieldProxy(expression, this, fieldName);
+	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.IBeanTypeProxy#getConstructors()
@@ -357,6 +366,24 @@
 	public IMethodProxy getMethodProxy(String methodName, String[] argumentClassNames) {
 		return ((REMStandardBeanTypeProxyFactory) fRegistry.getBeanTypeProxyFactory()).proxyConstants.getMethodProxy(this,methodName,argumentClassNames);
 	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[])
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String methodName, IProxyBeanType[] parameterTypes) {
+		REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry();
+		return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getMethodProxy(expression, this, methodName, parameterTypes);
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String[])
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String methodName, String[] parameterTypes) {
+		REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry();
+		return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getMethodProxy(expression, this, methodName, parameterTypes);
+	}
 
 	/*
 	 * (non-Javadoc)
@@ -656,4 +683,16 @@
 			}
 		}
 	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isBeanProxy()
+	 */
+	public final boolean isBeanProxy() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isExpressionProxy()
+	 */
+	public final boolean isExpressionProxy() {
+		return false;
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMArrayBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMArrayBeanProxy.java
index 13967a9..2d5cc55 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMArrayBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMArrayBeanProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMArrayBeanProxy.java,v $
- *  $Revision: 1.6 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.7 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.lang.reflect.Array;
@@ -234,7 +234,7 @@
 		// However it will become IBeanProxy[]. That is because if ID's
 		// they must be proxies over here.
 		BeanProxyValueSender valueSender = new BeanProxyValueSender((REMStandardBeanProxyFactory) fFactory.getBeanProxyFactory(), returnValue);
-		connection.readProxyArrayValues(returnValue, valueSender);
+		connection.readProxyArrayValues(returnValue, valueSender, false);
 		Exception e = valueSender.getException();
 		if (e != null) {
 			if (e instanceof ThrowableProxy)
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMCallbackRegistry.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMCallbackRegistry.java
index 8ca5224..487b3b2 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMCallbackRegistry.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMCallbackRegistry.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMCallbackRegistry.java,v $
- *  $Revision: 1.3 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.4 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.net.Socket;
@@ -19,6 +19,7 @@
 
 import org.eclipse.jem.internal.proxy.common.remote.Commands;
 import org.eclipse.jem.internal.proxy.core.*;
+import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent;
 
 /**
  * This registry will handle callbacks.
@@ -30,9 +31,9 @@
 	final String fNamePostfix;
 	List fThreads = Collections.synchronizedList(new LinkedList());	// List of active callback threads.	
 	
-	HashMap fIdToCallback = new HashMap(5);	// ID to Callback map.
-	HashSet fRegisteredCallbackProxies = new HashSet(5);	// Hold onto registered proxies so they aren't released as long as call back is registered.
-	
+	Map fIdToCallback = new HashMap(5);	// ID to Callback map.
+	Map fCallbackProxyToId = new HashMap(5);	// Callback to ID map. This will also hold onto the callback proxies so that they don't get GC'd while the callback is registered.
+		
 	IREMMethodProxy fInitializeCallback;
 	IREMBeanProxy fRemoteServer;
 	
@@ -109,37 +110,80 @@
 			
 		fThreads.clear();
 		fIdToCallback.clear();
-		fRegisteredCallbackProxies.clear();
+		fCallbackProxyToId.clear();
 		fInitializeCallback = null;
 		fRemoteServer = null;
 			
 	}		
 	
-	
 	public ICallback getRegisteredCallback(int id) {
 		synchronized(fIdToCallback)	{	
 			return (ICallback) fIdToCallback.get(new Integer(id));
 		}
 	}
 		
-	/**
-	 * The public interface for registering callbacks
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.ICallbackRegistry#registerCallback(org.eclipse.jem.internal.proxy.core.IBeanProxy, org.eclipse.jem.internal.proxy.core.ICallback)
 	 */
 	public void registerCallback(IBeanProxy callbackProxy, ICallback cb) {
 		synchronized(fIdToCallback) {
 			fIdToCallback.put(((IREMBeanProxy) callbackProxy).getID(), cb);
-			fRegisteredCallbackProxies.add(callbackProxy);
+			fCallbackProxyToId.put(callbackProxy, ((IREMBeanProxy) callbackProxy).getID());
 			fInitializeCallback.invokeCatchThrowableExceptions(callbackProxy, new IBeanProxy[] {fRemoteServer, fFactory.getBeanProxyFactory().createBeanProxyWith(((IREMBeanProxy) callbackProxy).getID().intValue())});
 		}
 	}
 	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.ICallbackRegistry#registerCallback(org.eclipse.jem.internal.proxy.core.IProxy, org.eclipse.jem.internal.proxy.core.ICallback, org.eclipse.jem.internal.proxy.core.IExpression)
+	 */
+	public void registerCallback(IProxy callbackProxy, final ICallback cb, IExpression expression) {
+		final Integer id;
+		if (callbackProxy.isBeanProxy()) {
+			id = ((IREMBeanProxy) callbackProxy).getID();
+			synchronized(fIdToCallback) {
+				fIdToCallback.put(id, cb);
+				fCallbackProxyToId.put(callbackProxy, id);
+			}
+		} else {
+			id = new Integer(callbackProxy.hashCode());
+			synchronized (fIdToCallback) {
+				fIdToCallback.put(id, cb);	// This is so that it is registered in case callback is invoked from remote vm during expression processing.
+			}
+			((ExpressionProxy) callbackProxy).addProxyListener(new ExpressionProxy.ProxyListener() {
+				public void proxyResolved(ProxyEvent event) {
+					synchronized(fIdToCallback) {
+						fCallbackProxyToId.put(event.getProxy(), id);
+					}
+				}
+				
+				public void proxyNotResolved(ProxyEvent event) {
+					// Failed, so remove registration completely.
+					synchronized (fIdToCallback) {
+						fIdToCallback.remove(id);
+					}
+				}
+				
+				public void proxyVoid(ProxyEvent event) {
+					// Failed, so remove registration completely.
+					synchronized (fIdToCallback) {
+						fIdToCallback.remove(id);
+					}
+				}
+				
+			});
+		}
+		expression.createSimpleMethodInvoke(fInitializeCallback, callbackProxy, new IProxy[] {fRemoteServer, fFactory.getBeanProxyFactory().createBeanProxyWith(id.intValue())}, false);
+	}
+	
 	/**
 	 * The public interface for deregistering callbacks.
 	 */
 	public void deregisterCallback(IBeanProxy callbackProxy) {
 		synchronized(fIdToCallback)	{
-			fIdToCallback.remove(((IREMBeanProxy) callbackProxy).getID());
-			fRegisteredCallbackProxies.remove(callbackProxy);	// Release it.
+			Integer id = (Integer) fCallbackProxyToId.remove(callbackProxy);
+			fIdToCallback.remove(id);
 		}
 	}
 	
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMCallbackThread.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMCallbackThread.java
index dedd874..cbe2a4b 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMCallbackThread.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMCallbackThread.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMCallbackThread.java,v $
- *  $Revision: 1.12 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.13 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.io.*;
@@ -36,8 +36,30 @@
 	final REMStandardBeanTypeProxyFactory fTypeFactory;
 	final REMProxyFactoryRegistry registry;
 	protected boolean shuttingDown;
+	protected boolean inTransaction;	// Is this thread currently participating in a transaction, (i.e. reading/writing), if so then we can't use it for another transaction.
 	
 
+	/**
+	 * Is this callback thread currently participating in a transaction (reading/writing). If so then it can't be used for an
+	 * independent new transaction.
+	 * 
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean inTransaction() {
+		return inTransaction;
+	}
+	
+	/**
+	 * Set whether this callback thread is in a transaction or not.
+	 * @param inTransaction
+	 * 
+	 * @since 1.1.0
+	 */
+	public void setIntransaction(boolean inTransaction) {
+		this.inTransaction = inTransaction;
+	}
 	
 	// Kludge: Bug in Linux 1.3.xxx of JVM. Closing a socket while the socket is being read/accept will not interrupt the
 	// wait. Need to timeout to the socket read/accept before the socket close will be noticed. This has been fixed
@@ -127,6 +149,7 @@
 							// The register callback handler will know how to handle the parm,
 							// it will know if it is an array of proxies, or an object of some kind.
 							fFactory.startTransaction();	// Start a transaction.
+							setIntransaction(true);	// Also tell ourselves that we are in a transaction.
 							boolean isProxies = true;							
 							try {
 								Commands.readValue(in, valueObject);
@@ -135,7 +158,7 @@
 									// However it will become IBeanProxy[]. That is because if ID's
 									// they must be proxies over here.
 									valueSender.initialize(valueObject);
-									Commands.readArray(in, valueObject.anInt, valueSender, valueObject);
+									Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
 									if (valueSender.getException() != null) {
 										close();	// Something wrong, close the thread so next time we get a new one.
 									}
@@ -146,6 +169,7 @@
 									parm = valueObject.getAsObject();
 								}
 							} finally {
+								setIntransaction(false);
 								fFactory.stopTransaction();
 							}
 							// Now perform the callback.
@@ -178,33 +202,30 @@
 											}
 
 											public Commands.ValueObject nextValue() {
-												if (index < array.length) {
-													Object retParm = array[index++];
-													if (retParm != null)
-														if (retParm instanceof IREMBeanProxy)
-															 ((IREMBeanProxy) retParm).renderBean(worker);
-														else if (retParm instanceof TransmitableArray) {
-															// It is another array, create a new
-															// retriever.
-															worker.setArrayIDS(
-																new Retriever(((TransmitableArray) retParm).array),
-																((TransmitableArray) retParm).array.length,
-																((TransmitableArray) retParm).componentTypeID);
-														} else {
-															// It's an object. Need to get bean
-															// type so that we can send it.
-															IREMBeanProxy type =
-																(IREMBeanProxy) fTypeFactory.getBeanTypeProxy(retParm.getClass().getName());
-															if (type == null)
-																throw new IllegalArgumentException();
-															int classID = type.getID().intValue();
-															worker.setAsObject(retParm, classID);
-														}
-													else
-														worker.set();
-													return worker;
-												} else
-													return null;
+												Object retParm = array[index++];
+												if (retParm != null)
+													if (retParm instanceof IREMBeanProxy)
+														 ((IREMBeanProxy) retParm).renderBean(worker);
+													else if (retParm instanceof TransmitableArray) {
+														// It is another array, create a new
+														// retriever.
+														worker.setArrayIDS(
+															new Retriever(((TransmitableArray) retParm).array),
+															((TransmitableArray) retParm).array.length,
+															((TransmitableArray) retParm).componentTypeID);
+													} else {
+														// It's an object. Need to get bean
+														// type so that we can send it.
+														IREMBeanProxy type =
+															(IREMBeanProxy) fTypeFactory.getBeanTypeProxy(retParm.getClass().getName());
+														if (type == null)
+															throw new IllegalArgumentException();
+														int classID = type.getID().intValue();
+														worker.setAsObject(retParm, classID);
+													}
+												else
+													worker.set();
+												return worker; 
 											}
 										};
 
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConnection.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConnection.java
index a37880e..f0b8756 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConnection.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConnection.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMConnection.java,v $
- *  $Revision: 1.15 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.16 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -32,6 +32,7 @@
  * It uses the property "proxyvm.bufsize" to determine the buffer size to use. If not specified, it uses the system default
  */
 public class REMConnection implements IREMConnection, IREMExpressionConnection {
+	
 	public final static String INVOKE_STEP = "Invoke";
 	public final static String INVOKE_METHOD_STEP = "Invoke Method";
 	protected Socket fSocket = null;
@@ -291,26 +292,41 @@
 			ExpressionCommands.sendBoolean(out, aBool);
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pullValue(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
-	 */
-	public void pullValue(int expressionID, ValueObject returnValue) throws CommandException {
-		if (isConnected())
-			ExpressionCommands.sendPullValueCommand(expressionID, out, in, returnValue);
-	}
+	
 	
 	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#sync(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
+	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#getFinalValue(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
 	 */
-	public void sync(int expressionID, ValueObject returnValue) throws CommandException {
+	public void getFinalValue(ValueObject result) throws CommandException {
 		if (isConnected())
-			ExpressionCommands.sendSyncCommand(expressionID, out, in, returnValue);
+			Commands.readBackValue(in, result, Commands.NO_TYPE_CHECK);
 	}
 	
-	
-	public void readProxyArrayValues(Commands.ValueObject returnValue, Commands.ValueSender valueSender) throws CommandException {
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pullValue(int, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
+	 */
+	public void pullValue(int expressionID, ValueObject proxyids, ValueSender sender) throws CommandException {
 		if (isConnected())
-			Commands.readArray(in, returnValue.anInt, valueSender, returnValue);
+			ExpressionCommands.sendPullValueCommand(expressionID, out, in, proxyids, sender);
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#sync(int, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
+	 */
+	public void sync(int expressionID, ValueObject proxyids, ValueSender sender) throws CommandException {
+		if (isConnected())
+			ExpressionCommands.sendSyncCommand(expressionID, out, in, proxyids, sender);
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.remote.IREMConnection#readProxyArrayValues(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueSender, boolean)
+	 */
+	public void readProxyArrayValues(Commands.ValueObject returnValue, Commands.ValueSender valueSender, boolean allowFlag) throws CommandException {
+		if (isConnected())
+			Commands.readArray(in, returnValue.anInt, valueSender, returnValue, allowFlag);
 	}
 
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConstantBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConstantBeanProxy.java
index 3444a37..5a04a28 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConstantBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConstantBeanProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMConstantBeanProxy.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -85,4 +85,16 @@
 	}
 
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isBeanProxy()
+	 */
+	public final boolean isBeanProxy() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isExpressionProxy()
+	 */
+	public final boolean isExpressionProxy() {
+		return false;
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConstructorProxy.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConstructorProxy.java
index 492bc5b..be4a841 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConstructorProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMConstructorProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMConstructorProxy.java,v $
- *  $Revision: 1.6 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.7 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import org.eclipse.core.runtime.IStatus;
@@ -78,4 +78,32 @@
 			return null;
 		}
 	}
+	
+	private IBeanTypeProxy[] fParameterTypes;
+	
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IConstructorProxy#getParameterTypes()
+	 */
+	public synchronized IBeanTypeProxy[] getParameterTypes() {
+		if (fParameterTypes == null) {
+			IArrayBeanProxy parmTypes = (IArrayBeanProxy) REMStandardBeanProxyConstants.getConstants(fFactory)
+					.getConstructorParameterTypesMessage().invokeCatchThrowableExceptions(this);
+			if (parmTypes == null)
+				fParameterTypes = new IBeanTypeProxy[0]; // There was some error, only way null is returned
+			else {
+				int len = parmTypes.getLength();
+				fParameterTypes = new IBeanTypeProxy[len];
+				for (int i = 0; i < len; i++)
+					try {
+						fParameterTypes[i] = (IBeanTypeProxy) parmTypes.get(i);
+					} catch (ThrowableProxy e) {
+					}
+				fFactory.releaseProxy(parmTypes); // Don't need the array on the server anymore.
+			}
+		}
+
+		return fParameterTypes;
+	}
+	
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java
index f1a19ab..3c137b5 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java
@@ -10,17 +10,21 @@
  *******************************************************************************/
 /*
  *  $RCSfile: REMExpression.java,v $
- *  $Revision: 1.7 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.8 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.remote;
 
-import java.io.IOException;
+import java.io.*;
+import java.util.*;
+import java.util.Iterator;
+import java.util.List;
 import java.util.logging.Level;
 
 import org.eclipse.jem.internal.proxy.common.CommandException;
 import org.eclipse.jem.internal.proxy.common.remote.*;
+import org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject;
 import org.eclipse.jem.internal.proxy.core.*;
-import org.eclipse.jem.internal.proxy.initParser.tree.IInternalExpressionConstants;
+import org.eclipse.jem.internal.proxy.initParser.tree.*;
  
 /**
  * The Remote proxy version of Expression.
@@ -29,9 +33,52 @@
  */
 public class REMExpression extends Expression {
 
-	protected IREMExpressionConnection connection;
+	private IREMExpressionConnection connection;
+	private boolean closed;	// Are we closed.
 	
-	protected Commands.ValueObject workerValue = new Commands.ValueObject();	// A worker object so that we don't need to keep creating one and throwing it away.
+	protected Commands.ValueObject workerValue;	// A worker object so that we don't need to keep creating one and throwing it away.
+	
+	protected Map beanTypeCache;	// Use to cache pending BeanTypes. Used in conjunction with REMStandardBeanTypeFactory.
+	protected Map methodsCache;	// Use to cache pending expression method proxies. Used in conjunction with REMProxyConsants.
+	protected Map fieldsCache;	// Use to cache pending expression field proxies. Used in conjunction with REMProxyConsants.
+	
+	/*
+	 * This is very special list. It tries to eliminate unneeded traffic. For example a mark immediately followed by an endmark does
+	 * not need to be sent. Many expressions can look like: mark, endmark, endtransaction. This is a do nothing and we don't want
+	 * to create a connection to just send this. So this list is used to queue up these and remove them too when found as not needed.
+	 * 
+	 *  However, this is very tricky because all pushToProxy transactions that actually do something MUST call the processPending() method 
+	 *  first to make sure any pending transactions are submitted. Because once a real type transaction, such as assignment occurs, any
+	 *  pending transaction is a valid transaction, and no longer a do-nothing transaction.
+	 *  
+	 *  Each transaction type uses a subclass of PendingTransaction to be an entry on the list.
+	 *  
+	 *  The pendings currently supported are:
+	 *  mark/endmark
+	 *  try/catch/endtry
+	 *  block/endblock
+	 *  
+	 *  See each individual transaction type to see how it is handled.
+	 */
+	protected List pendingTransactions;
+	
+	/**
+	 * PendingTransaction entry.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected abstract static class PendingTransaction {
+		
+		/**
+		 * The transaction is now being pushed. The implementation should
+		 * actually do the push.
+		 * 
+		 * @param remExpression The REMExpression for this transaction.
+		 * 
+		 * @since 1.1.0
+		 */
+		public abstract void pushTransaction(REMExpression remExpression);
+	}
 	
 	/**
 	 * @param registry
@@ -40,17 +87,65 @@
 	 */
 	public REMExpression(REMProxyFactoryRegistry registry) {
 		super(registry);
-		connection = (IREMExpressionConnection) registry.getFreeConnection();
-		try {
-			connection.startExpressionProcessing(this.hashCode());
-		} catch (IOException e) {
-			connection.close();
-			ProxyPlugin.getPlugin().getLogger().log(e);
-			throwIllegalStateException(IO_EXCEPTION_MSG);
-		}
 	}
 	
 	/**
+	 * Return the expression id for this REMExpression. This id is used on the remote vm to
+	 * identify who the request is for.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	protected int getREMExpressionID() {
+		return this.hashCode();
+	}
+	/**
+	 * Get the pending transactions list.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	protected List getPendingTransactions() {
+		if (pendingTransactions == null)
+			pendingTransactions = new ArrayList();
+		return pendingTransactions;
+	}
+	
+	// Use this flag when debugging to test if errors are due to improper pending processing.
+	// If true they will be treated as if not pending and will be executed immediately.
+	private static final boolean EXECUTE_PENDING_IMMEDIATELY = false;
+	protected void addPendingTransaction(PendingTransaction pending) {
+		if (!EXECUTE_PENDING_IMMEDIATELY)
+			getPendingTransactions().add(pending);
+		else
+			pending.pushTransaction(this);
+	}
+
+	/**
+	 * @return Returns the connection.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected IREMExpressionConnection getConnection() {
+		if (connection == null) {
+			connection = (IREMExpressionConnection) getREMRegistry().getFreeConnection();
+			// This will actually not be stopped until closeproxy. There could be a slight problem if the expression is never closed.
+			// But that shouldn't happen. This is to prevent any proxy that was released during the execution but was used by
+			// the expression from being released on the remote vm until after the expression is finished.
+			getREMBeanProxyFactory().startTransaction();	
+			try {
+				connection.startExpressionProcessing(getREMExpressionID());
+				workerValue = new Commands.ValueObject();
+			} catch (IOException e) {
+				connection.close();
+				ProxyPlugin.getPlugin().getLogger().log(e);
+				throwIllegalStateException(IO_EXCEPTION_MSG);
+			}	
+		}
+		return connection;
+	}
+
+	/**
 	 * General IOException occurred msg.
 	 */
 	protected static final String IO_EXCEPTION_MSG = ProxyRemoteMessages.getString("REMExpression.IOExceptionSeeLog_INFO_"); //$NON-NLS-1$
@@ -90,15 +185,76 @@
 		return (REMStandardBeanProxyFactory) beanProxyFactory;
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushToProxy(org.eclipse.jem.internal.proxy.core.IBeanProxy)
+	/**
+	 * Process any pending transactions.
+	 * <p>
+	 * <b>Note: </b>It is required that all non-pending-participating transactions must
+	 * call this method first to make sure pending transactions are sent. If this is
+	 * not done, there will be errors in the expression.
+	 * 
+	 * 
+	 * @since 1.1.0
 	 */
-	protected void pushToProxy(IBeanProxy proxy) throws ThrowableProxy {
+	protected void processPendingTransactions() {
+		if (pendingTransactions != null && !pendingTransactions.isEmpty()) {
+			try {
+				for (int i = 0; i < pendingTransactions.size(); i++) {
+					((PendingTransaction) pendingTransactions.get(i)).pushTransaction(this);
+				}
+			} finally {
+				pendingTransactions.clear();
+			}
+		}
+	}
+	
+	/**
+	 * Get the pending entry from top. If top is 1, then get top entry (i.e. last one added), 2 is next one. 
+	 * @param fromTop
+	 * @return entry requested, or <code>null</code> if no such entry.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected PendingTransaction getPendingEntryFromTop(int fromTop) {
+		if (pendingTransactions != null && pendingTransactions.size() >= fromTop) {
+			return (PendingTransaction) pendingTransactions.get(pendingTransactions.size()-fromTop);
+		} else
+			return null;
+	}
+	
+	/**
+	 * Pop up the top entry from the pending transactions queue.
+	 * @param fromTop how many entries to pop from the pending transaction list.
+	 * 
+	 * 
+	 * @since 1.1.0
+	 */
+	protected void popPendingEntry(int fromTop) {
+		if (pendingTransactions != null)
+			if (pendingTransactions.size() > fromTop) {
+				while(fromTop-- >0)
+					pendingTransactions.remove(pendingTransactions.size()-1);
+			} else
+				pendingTransactions.clear();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushToProxy(org.eclipse.jem.internal.proxy.core.IProxy)
+	 */
+	protected void pushToProxy(IProxy proxy) {
+		if (proxy == null || proxy.isBeanProxy())
+			pushToProxy((IBeanProxy) proxy);
+		else
+			pushToExpressionProxy((ExpressionProxy) proxy);
+	}
+	
+	private void pushToProxy(IBeanProxy proxy) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push proxy command is:
 			//	PushExpressionCommand(push to proxy) followed by:
 			//		ValueObject containing the rendered proxy.
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.PUSH_TO_PROXY_EXPRESSION);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_TO_PROXY_EXPRESSION_VALUE);
 			if (proxy == null)
 				workerValue.set();
 			else
@@ -123,32 +279,130 @@
 	 * @see org.eclipse.jem.internal.proxy.core.Expression#closeProxy()
 	 */
 	protected void closeProxy() {
-		try {
+		if (connection != null && !closed) {
 			try {
-				connection.stopExpressionProcessing(this.hashCode());
-			} catch (IOException e) {
-				connection.close();
-				ProxyPlugin.getPlugin().getLogger().log(e, Level.INFO);
-				// Not throwing an illegal state here because we don't care, other than logging and not 
-				// returning the connection to the registry that there was an error on close.
+				try {
+					if (connection.isConnected()) {
+						connection.stopExpressionProcessing(getREMExpressionID());
+					}
+				} catch (IOException e) {
+					connection.close();
+					ProxyPlugin.getPlugin().getLogger().log(e, Level.INFO);
+					// Not throwing an illegal state here because we don't care, other than logging and not 
+					// returning the connection to the registry that there was an error on close.
+				} finally {
+					getREMBeanProxyFactory().stopTransaction();	// Resume proxy releases.
+					getREMRegistry().returnConnection(connection);
+				}
+			} finally {
+				closed = true;
 			}
-		} finally {
-			getREMRegistry().returnConnection(connection);
+		}
+		methodsCache = null;
+		fieldsCache = null;
+		beanTypeCache = null;
+		pendingTransactions = null;
+	}
+	
+	private static final Object VOIDTYPE = new Object();	// A void type was sent in expression proxy resolution.
+	private static final Object NOTRESOLVED = new Object();	// A not resolved type was sent in expression proxy resolution.
+	
+	/*
+	 * Get the sender to use for pulling the expression proxy resolutions.
+	 */
+	private BeanProxyValueSender getExpressionProxiesSender() {
+		return new BeanProxyValueSender(getREMBeanProxyFactory()) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.jem.internal.proxy.remote.BeanProxyValueSender#sendValue(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
+			 */
+			public void sendValue(ValueObject value) {
+				if (value.getType() == Commands.FLAG) {
+					switch (value.anInt) {
+						case ExpressionCommands.EXPRESSIONPROXY_NOTRESOLVED:
+							array[index++] = NOTRESOLVED;
+							break;
+						case ExpressionCommands.EXPRESSIONPROXY_VOIDTYPE:
+							array[index++] = VOIDTYPE;
+							break;
+						default:
+							// Shouldn't happen.
+							break;
+					}
+				} else
+					super.sendValue(value);
+			}
+		};
+	}
+		
+	/*
+	 * Process the pulled expression proxy resolutions.
+	 */
+	private void processpulledExpressionProxies(List expressionProxies, BeanProxyValueSender sender) {
+
+		// It is expected that each entry will coorespond to the next non-null expression proxy and will be the bean proxy or one of the special
+		// types.
+		int len = expressionProxies.size();
+		int j = 0;
+		Object[] resolveds = sender.getArray();
+		for (int i = 0; i < len; i++) {
+			ExpressionProxy ep = (ExpressionProxy) expressionProxies.get(i);
+			if (ep != null) {
+				Object resolved = resolveds[j++];
+				if (resolved == NOTRESOLVED)
+					fireProxyNotResolved(ep);
+				else if (resolved == VOIDTYPE)
+					fireProxyVoid(ep);
+				else
+					fireProxyResolved(ep, (IBeanProxy) resolved);
+			}
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pullProxyValue()
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pullProxyValue(int, java.util.List)
 	 */
-	protected IBeanProxy pullProxyValue() throws ThrowableProxy, NoExpressionValueException {
+	protected IBeanProxy pullProxyValue(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException {
+		if (connection == null) {
+			markAllProxiesNotResolved(expressionProxies);
+			return null;	// We haven't pushed any commands, so there is nothing to do. Don't create a connection for this.
+		}
+		// If there are any pending transactions at this point in time, there is no need to send them. They would be do nothings anyway.
+		
+		boolean processedExpressionProxies = false;
+		IREMExpressionConnection connection = getConnection();
+		markInTransaction();
 		try {
-			connection.pullValue(this.hashCode(), workerValue);
+			Commands.ValueObject proxyids = null;
+			BeanProxyValueSender sender = null;
+			if (proxycount > 0) {
+				proxyids = createExpressionProxiesValueObject(proxycount, expressionProxies);
+				sender = getExpressionProxiesSender();
+			}
+			
+			connection.pullValue(getREMExpressionID(), proxyids, sender);
+			// If we got this far, then if there are proxies, we need to process these too.
+			if (proxycount > 0)
+				processpulledExpressionProxies(expressionProxies, sender);
+			processedExpressionProxies =true;
+			connection.getFinalValue(workerValue);	// Get the returned value.
 			return getREMBeanProxyFactory().getBeanProxy(workerValue);
 		} catch (CommandErrorException e) {
-			if (e.getErrorCode() == ExpressionCommands.ExpressionNoExpressionValueException) {
-				throw new NoExpressionValueException((String) e.getErrorObject());
-			}
 			try {
+				if (e.getErrorCode() == ExpressionCommands.EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION) {
+					// Need to turn it into a Throwable.
+					ThrowableProxy t = null;
+					try {
+						getREMBeanProxyFactory().getBeanProxy(e.getValue());	// This will cause a throw to occur, but we don't want it going out, we want to capture it.
+					} catch (ThrowableProxy e1) {
+						t = e1;
+					}
+					throw new REMNoExpressionValueException(t);
+				}
 				getREMBeanProxyFactory().processErrorReturn(e);
 			} catch (CommandException e1) {
 				ProxyPlugin.getPlugin().getLogger().log(e);
@@ -163,23 +417,102 @@
 				connection.close();
 				throwIllegalStateException(COMMAND_EXCEPTION_MSG);
 			}			
+		} finally {
+			markEndTransaction();
+			if (!processedExpressionProxies)
+				markAllProxiesNotResolved(expressionProxies);	// We failed before we could process the expression proxies. So mark all as not resolved.
 		}
 		return null;
 	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushCastToProxy(java.lang.Object)
+	
+	/**
+	 * This is called by commands that write some data and will be reading data back immediately 
+	 * (i.e. pull value and invoke expression). If we are on a callback thread and have the 
+	 * used the connection from the callback thread, we need to tell the callback thread that
+	 * it is in a transaction. This is needed because while reading data back there are
+	 * sometimes calls back to the vm to get beantype data for new classes. This would 
+	 * normally be through a new connection so that it doesn't get stuck in the middle of the
+	 * data being sent back. But when running on a callback the same connection is used. So it
+	 * would stick data in the middle of the return stream of data. To prevent this we need
+	 * to tell the callback thread that it is in a transaction during this call so that any
+	 * such new connection requests will get a new connection.
+	 * <p>
+	 * markEndTransaction must be called in ALL cases, such use try/finally.
+	 * 
+	 * 
+	 * @since 1.1.0
 	 */
-	protected void pushCastToProxy(Object type) throws ThrowableProxy, NoExpressionValueException {
+	protected void markInTransaction() {
+		Thread thread = Thread.currentThread();
+		if (thread instanceof REMCallbackThread) {
+			// We are in a callback, and the callback connection is our connection, tell the callback that it is in transaction.
+			REMCallbackThread callbackThread = (REMCallbackThread) thread;
+			if (callbackThread.getConnection() == connection) {
+				callbackThread.setIntransaction(true);
+			}
+		}
+	}
+	
+	/**
+	 * Mark end of transaction.
+	 * 
+	 * @see REMExpression#markInTransaction()
+	 * @since 1.1.0
+	 */
+	protected void markEndTransaction() {
+		Thread thread = Thread.currentThread();
+		if (thread instanceof REMCallbackThread) {
+			// We are in a callback, and the callback connection is our connection, tell the callback that it is in transaction.
+			REMCallbackThread callbackThread = (REMCallbackThread) thread;
+			if (callbackThread.getConnection() == connection) {
+				callbackThread.setIntransaction(false);
+			}
+		}		
+	}
+
+	/**
+	 * @param expressionProxies
+	 * 
+	 * @since 1.1.0
+	 */
+	private Commands.ValueObject createExpressionProxiesValueObject(int actualCount, List expressionProxies) {
+		class ExpressionProxyRetriever implements Commands.ValueRetrieve {
+			Iterator expressionProxiesItr;
+			Commands.ValueObject worker = new Commands.ValueObject();
+
+			public ExpressionProxyRetriever(List expressionProxies) {
+				this.expressionProxiesItr = expressionProxies.iterator();
+			}
+
+			public Commands.ValueObject nextValue() {
+				worker.set(-1);
+				while (expressionProxiesItr.hasNext()) {
+					Object parm = expressionProxiesItr.next();
+					if (parm != null) {
+						worker.set(((ExpressionProxy) parm).getProxyID());
+						break;
+					}
+				} 
+				return worker;
+			}
+		};
+
+		workerValue.setArrayIDS(new ExpressionProxyRetriever(expressionProxies), actualCount, Commands.INT);
+		return workerValue;
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushCastToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType)
+	 */
+	protected void pushCastToProxy(IProxyBeanType type) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push cast to proxy command is:
 			//	PushExpressionCommand(push cast to proxy) followed by:
-			//		ValueObject containing the rendered bean type proxy or the String representing the name of class.
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.CAST_EXPRESSION);
-			if (type instanceof String)
-				workerValue.set((String) type);
-			else
-				((IREMBeanProxy) type).renderBean(workerValue);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.CAST_EXPRESSION_VALUE);
+			fillProxy(type, workerValue);
 			connection.pushValueObject(workerValue);
 		} catch (IOException e) {
 			connection.close();			
@@ -196,19 +529,36 @@
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInstanceofToProxy(java.lang.Object)
+	/**
+	 * Push the proxy bean type in the format depending on expression proxy or beantype proxy.
+	 * @param type
+	 * @throws IOException
+	 * 
+	 * @since 1.1.0
 	 */
-	protected void pushInstanceofToProxy(Object type) throws ThrowableProxy, NoExpressionValueException {
+	protected void fillProxy(IProxy type, Commands.ValueObject value) throws IOException {
+		//		ValueObject containing the rendered bean type proxy if IBeanTypeProxy or int (for expression proxy id) if expression proxy.
+		if (type.isBeanProxy()) {
+			((IREMBeanProxy) type).renderBean(value);
+		} else {
+			ExpressionProxy ep = (ExpressionProxy) type;
+			value.set(ep.getProxyID());
+		}
+	}
+	
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInstanceofToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType)
+	 */
+	protected void pushInstanceofToProxy(IProxyBeanType type) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push instanceof to proxy command is:
 			//	PushExpressionCommand(push instanceof to proxy) followed by:
 			//		ValueObject containing the rendered bean type proxy or the String representing the name of class.
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.INSTANCEOF_EXPRESSION);
-			if (type instanceof String)
-				workerValue.set((String) type);
-			else
-				((IREMBeanProxy) type).renderBean(workerValue);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.INSTANCEOF_EXPRESSION_VALUE);
+			fillProxy(type, workerValue);
 			connection.pushValueObject(workerValue);
 		} catch (IOException e) {
 			connection.close();
@@ -225,18 +575,21 @@
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInfixToProxy(int, int)
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInfixToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InfixOperator, int)
 	 */
-	protected void pushInfixToProxy(int operator, int operandType) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushInfixToProxy(InfixOperator operator, InternalInfixOperandType operandType) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push infix to proxy command is:
 			//	PushExpressionCommand(push infix to proxy) followed by:
 			//		byte: operator
 			//		byte: operandType
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.INFIX_EXPRESSION);
-			connection.pushByte((byte) operator);
-			connection.pushByte((byte) operandType);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.INFIX_EXPRESSION_VALUE);
+			connection.pushByte((byte) operator.getValue());
+			connection.pushByte((byte) operandType.getValue());
 		} catch (IOException e) {
 			connection.close();
 			ProxyPlugin.getPlugin().getLogger().log(e);
@@ -245,16 +598,19 @@
 		}		
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushPrefixToProxy(int)
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushPrefixToProxy(org.eclipse.jem.internal.proxy.initParser.tree.PrefixOperator)
 	 */
-	protected void pushPrefixToProxy(int operator) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushPrefixToProxy(PrefixOperator operator) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push prefix to proxy command is:
 			//	PushExpressionCommand(push prefix to proxy) followed by:
 			//		byte: operator
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.PREFIX_EXPRESSION);
-			connection.pushByte((byte) operator);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PREFIX_EXPRESSION_VALUE);
+			connection.pushByte((byte) operator.getValue());
 		} catch (IOException e) {
 			connection.close();
 			ProxyPlugin.getPlugin().getLogger().log(e);
@@ -264,40 +620,16 @@
 	}
 
 	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTypeLiteralToProxy(java.lang.String)
-	 */
-	protected void pushTypeLiteralToProxy(String type) throws ThrowableProxy {
-		try {
-			// Format of push type literal to proxy command is:
-			//	PushExpressionCommand(push typeliteral to proxy) followed by:
-			//		ValueObject containing the String representing the name of class.
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.TYPELITERAL_EXPRESSION);
-			workerValue.set((String) type);
-			connection.pushValueObject(workerValue);
-		} catch (IOException e) {
-			connection.close();
-			ProxyPlugin.getPlugin().getLogger().log(e);
-			markInvalid(e.getLocalizedMessage());
-			throwIllegalStateException(IO_EXCEPTION_MSG);
-		} catch (CommandException e) {
-			ProxyPlugin.getPlugin().getLogger().log(e);
-			markInvalid(e.getLocalizedMessage());
-			if (!e.isRecoverable()) {
-				connection.close();
-				throwIllegalStateException(COMMAND_EXCEPTION_MSG);
-			}			
-		}
-	}
-
-	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayAccessToProxy(int)
 	 */
-	protected void pushArrayAccessToProxy(int indexCount) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushArrayAccessToProxy(int indexCount) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push array access to proxy command is:
 			//	PushExpressionCommand(push array acces to proxy) followed by:
 			//		int: indexCount
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.ARRAY_ACCESS_EXPRESSION);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION_VALUE);
 			connection.pushInt(indexCount);
 		} catch (IOException e) {
 			connection.close();
@@ -307,20 +639,20 @@
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayCreationToProxy(java.lang.Object, int)
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayCreationToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType, int)
 	 */
-	protected void pushArrayCreationToProxy(Object type, int dimensionCount) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushArrayCreationToProxy(IProxyBeanType type, int dimensionCount) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push array creation to proxy command is:
 			//	PushExpressionCommand(push array creation to proxy) followed by:
-			//		ValueObject containing the rendered bean type proxy or the String representing the name of class.
+			//		ValueObject containing the rendered bean type proxy or the expression proxy.
 			//		int: dimension count
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.ARRAY_CREATION_EXPRESSION);
-			if (type instanceof String)
-				workerValue.set((String) type);
-			else
-				((IREMBeanProxy) type).renderBean(workerValue);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ARRAY_CREATION_EXPRESSION_VALUE);
+			fillProxy(type, workerValue);
 			connection.pushValueObject(workerValue);
 			connection.pushInt(dimensionCount);
 		} catch (IOException e) {
@@ -338,21 +670,19 @@
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayInitializerToProxy(java.lang.Object, int)
-	 */
-	protected void pushArrayInitializerToProxy(Object type, int expressionCount) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushArrayInitializerToProxy(IProxyBeanType type, int stripCount, int expressionCount) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push array initializer to proxy command is:
 			//	PushExpressionCommand(push array initializer to proxy) followed by:
-			//		ValueObject containing the rendered bean type proxy or the String representing the name of class.
+			//		ValueObject containing the rendered bean type proxy or expression proxy.
+			//		int: strip count
 			//		int: expression count
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.ARRAY_INITIALIZER_EXPRESSION);
-			if (type instanceof String)
-				workerValue.set((String) type);
-			else
-				((IREMBeanProxy) type).renderBean(workerValue);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION_VALUE);
+			fillProxy(type, workerValue);
 			connection.pushValueObject(workerValue);
+			connection.pushInt(stripCount);
 			connection.pushInt(expressionCount);
 		} catch (IOException e) {
 			connection.close();
@@ -369,20 +699,20 @@
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushClassInstanceCreationToProxy(java.lang.Object, int)
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushClassInstanceCreationToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType, int)
 	 */
-	protected void pushClassInstanceCreationToProxy(Object type, int argumentCount) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushClassInstanceCreationToProxy(IProxyBeanType type, int argumentCount) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push class instance creation to proxy command is:
 			//	PushExpressionCommand(push class instance creation to proxy) followed by:
-			//		ValueObject containing the rendered bean type proxy or the String representing the name of class.
+			//		ValueObject containing the rendered bean type proxy or the expression proxy
 			//		int: argument count
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.CLASS_INSTANCE_CREATION_EXPRESSION);
-			if (type instanceof String)
-				workerValue.set((String) type);
-			else
-				((IREMBeanProxy) type).renderBean(workerValue);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION_VALUE);
+			fillProxy(type, workerValue);
 			connection.pushValueObject(workerValue);
 			connection.pushInt(argumentCount);
 		} catch (IOException e) {
@@ -400,19 +730,19 @@
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTypeReceiverToProxy(java.lang.Object)
-	 */
-	protected void pushTypeReceiverToProxy(Object type) throws ThrowableProxy {
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTypeReceiverToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType)
+	 */ 
+	protected void pushTypeReceiverToProxy(IProxyBeanType type) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push type receiver to proxy command is:
 			//	PushExpressionCommand(push type receiver to proxy) followed by:
-			//		ValueObject containing the rendered bean type proxy or the String representing the name of class.
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.TYPERECEIVER_EXPRESSION);
-			if (type instanceof String)
-				workerValue.set((String) type);
-			else
-				((IREMBeanProxy) type).renderBean(workerValue);
+			//		ValueObject containing the rendered bean type proxy or the expression proxy.
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.TYPERECEIVER_EXPRESSION_VALUE);
+			fillProxy(type, workerValue);
 			connection.pushValueObject(workerValue);
 		} catch (IOException e) {
 			connection.close();
@@ -432,36 +762,56 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushFieldAccessToProxy(java.lang.String, boolean)
 	 */
-	protected void pushFieldAccessToProxy(String fieldName, boolean hasReceiver) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushFieldAccessToProxy(Object field, boolean hasReceiver) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push field access to proxy command is:
 			//	PushExpressionCommand(push field access to proxy) followed by:
-			//		String: fieldName
+			//		Commands.Value: fieldName or IProxyField
 			//		boolean: hasReceiver
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.FIELD_ACCESS_EXPRESSION);
-			connection.pushString(fieldName);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.FIELD_ACCESS_EXPRESSION_VALUE);
+			if (field instanceof String) {
+				workerValue.set((String) field);
+			} else {
+				fillProxy((IProxy) field, workerValue);
+			}
+			connection.pushValueObject(workerValue);
 			connection.pushBoolean(hasReceiver);
 		} catch (IOException e) {
 			connection.close();
 			ProxyPlugin.getPlugin().getLogger().log(e);
 			markInvalid(e.getLocalizedMessage());
 			throwIllegalStateException(IO_EXCEPTION_MSG);
+		} catch (CommandException e) {
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			if (!e.isRecoverable()) {
+				connection.close();
+				throwIllegalStateException(COMMAND_EXCEPTION_MSG);
+			}			
 		}
 	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushMethodInvocationToProxy(java.lang.String, boolean, int)
 	 */
-	protected void pushMethodInvocationToProxy(String methodName, boolean hasReceiver, int argCount)
-		throws ThrowableProxy, NoExpressionValueException {
+	protected void pushMethodInvocationToProxy(Object method, boolean hasReceiver, int argCount) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push method invocation to proxy command is:
 			//	PushExpressionCommand(push method invocation to proxy) followed by:
-			//		String: methodName
+			//		Commands.ValueObject: methodName or IMethodProxy
 			//		boolean: hasReceiver
 			//		int: argCount
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.METHOD_EXPRESSION);
-			connection.pushString(methodName);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.METHOD_EXPRESSION_VALUE);
+			if (method instanceof String) {
+				workerValue.set((String) method);
+			} else {
+				fillProxy((IProxy) method, workerValue);
+			}
+			connection.pushValueObject(workerValue);
 			connection.pushBoolean(hasReceiver);
 			connection.pushInt(argCount);
 		} catch (IOException e) {
@@ -469,19 +819,28 @@
 			ProxyPlugin.getPlugin().getLogger().log(e);
 			markInvalid(e.getLocalizedMessage());
 			throwIllegalStateException(IO_EXCEPTION_MSG);
+		} catch (CommandException e) {
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			if (!e.isRecoverable()) {
+				connection.close();
+				throwIllegalStateException(COMMAND_EXCEPTION_MSG);
+			}			
 		}
 	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushConditionalToProxy(int)
 	 */
-	protected void pushConditionalToProxy(int expressionType) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushConditionalToProxy(InternalConditionalOperandType expressionType) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
 		try {
 			// Format of push conditional to proxy command is:
 			//	PushExpressionCommand(push conditional to proxy) followed by:
 			//		byte: expression type
-			connection.pushExpressionCommand(this.hashCode(), (byte)IInternalExpressionConstants.CONDITIONAL_EXPRESSION);
-			connection.pushByte((byte) expressionType);
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.CONDITIONAL_EXPRESSION_VALUE);
+			connection.pushByte((byte) expressionType.getValue());
 		} catch (IOException e) {
 			connection.close();
 			ProxyPlugin.getPlugin().getLogger().log(e);
@@ -490,18 +849,100 @@
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInvoke()
+	/*
+	 * A special one that takes the ThrowableProxy for no expression value and 
+	 * wrappers it prints its stack trace instead, but still makes it a subclass
+	 * of NoExpressionValueException.
+	 * 
+	 * @since 1.1.0
 	 */
-	protected void pushInvoke() throws ThrowableProxy, NoExpressionValueException {
+	private static class REMNoExpressionValueException extends NoExpressionValueException {
+		public REMNoExpressionValueException(ThrowableProxy e) {
+			super(e);
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see java.lang.Throwable#getLocalizedMessage()
+		 */
+		public String getLocalizedMessage() {
+			return ((ThrowableProxy) getCause()).getProxyLocalizedMessage();
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see java.lang.Throwable#getMessage()
+		 */
+		public String getMessage() {
+			return ((ThrowableProxy) getCause()).getProxyMessage();
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see java.lang.Throwable#printStackTrace()
+		 */
+		public void printStackTrace() {
+			getCause().printStackTrace();
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
+		 */
+		public void printStackTrace(PrintStream s) {
+			getCause().printStackTrace(s);
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
+		 */
+		public void printStackTrace(PrintWriter s) {
+			getCause().printStackTrace(s);
+		}
+	}
+	
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInvoke(int, java.util.List)
+	 */
+	protected void pushInvoke(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException {
+		if (connection == null) {
+			markAllProxiesNotResolved(expressionProxies);
+			return;	// We haven't pushed any commands, so there is nothing to do. Don't create a connection for this.
+		}
+		// If at this point there are pending transactions, there is no need to send them because they would all be do-nothings.
+		
+		boolean processedExpressionProxies = false;
+		IREMExpressionConnection connection = getConnection();
+		markInTransaction();
 		try {
-			connection.sync(this.hashCode(), workerValue);
-			getREMBeanProxyFactory().getBeanProxy(workerValue);	// This processes the return. It will be either true or an error. If true we don't care and if error the catch will handle it.
-		} catch (CommandErrorException e) {
-			if (e.getErrorCode() == ExpressionCommands.ExpressionNoExpressionValueException) {
-				throw new NoExpressionValueException((String) e.getErrorObject());
+			Commands.ValueObject proxyids = null;
+			BeanProxyValueSender sender = null;
+			if (proxycount > 0) {
+				proxyids = createExpressionProxiesValueObject(proxycount, expressionProxies);
+				sender = getExpressionProxiesSender();
 			}
+
+			connection.sync(getREMExpressionID(), proxyids, sender);
+			
+			// If we got this far, then if there are proxies, we need to process these too.
+			if (proxycount > 0)
+				processpulledExpressionProxies(expressionProxies, sender);
+			processedExpressionProxies = true;
+			connection.getFinalValue(workerValue);	// We don't care what it is, we just need to see if there is an error.
+		} catch (CommandErrorException e) {
 			try {
+				if (e.getErrorCode() == ExpressionCommands.EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION) {
+					// Need to turn it into a Throwable.
+					ThrowableProxy t = null;
+					try {
+						getREMBeanProxyFactory().getBeanProxy(e.getValue());	// This will cause a throw to occur, but we don't want it going out, we want to capture it.
+					} catch (ThrowableProxy e1) {
+						t = e1;
+					}
+					throw new REMNoExpressionValueException(t);
+				}
 				getREMBeanProxyFactory().processErrorReturn(e);
 			} catch (CommandException e1) {
 				ProxyPlugin.getPlugin().getLogger().log(e);
@@ -516,7 +957,772 @@
 				connection.close();
 				throwIllegalStateException(COMMAND_EXCEPTION_MSG);
 			}			
+		} finally {
+			markEndTransaction();
+			if (!processedExpressionProxies)
+				markAllProxiesNotResolved(expressionProxies);	// We failed before we could process the expression proxies. So mark all as not resolved.
 		}
 	}
 
+	private static class REMBeanTypeExpressionProxy extends ExpressionProxy implements IBeanTypeExpressionProxy {
+		
+		private String typeName;
+		
+		/**
+		 * @param proxyid
+		 * 
+		 * @since 1.1.0
+		 */
+		private REMBeanTypeExpressionProxy(int proxyid, Expression expression) {
+			super(proxyid, BEANTYPE_EXPRESSION_PROXY, expression);
+		}
+		
+		public void setTypeName(String typeName) {
+			this.typeName = typeName;
+		}
+		
+		public String getTypeName() {
+			return typeName;
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#toString()
+		 */
+		public String toString() {
+			return super.toString()+" - "+getTypeName();
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[])
+		 */
+		public IProxyMethod getMethodProxy(IExpression expression, String methodName, IProxyBeanType[] parameterTypes) {
+			REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry();
+			return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getMethodProxy(expression, this, methodName, parameterTypes);
+		}
+		
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String[])
+		 */
+		public IProxyMethod getMethodProxy(IExpression expression, String methodName, String[] parameterTypes) {
+			REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry();
+			return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getMethodProxy(expression, this, methodName, parameterTypes);
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String)
+		 */
+		public IProxyField getFieldProxy(IExpression expression, String fieldName) {
+			REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry();
+			return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getFieldProxy(expression, this, fieldName);
+		}
+	}
+	
+	private static class REMMethodExpressionProxy extends ExpressionProxy implements IProxyMethod {
+		
+			/**
+		 * @param proxyid
+		 * @param proxyType
+		 * @param expression
+		 * 
+		 * @since 1.1.0
+		 */
+		private REMMethodExpressionProxy(int proxyid, Expression expression) {
+			super(proxyid, METHOD_EXPRESSION_PROXY, expression);
+		}
+	}
+	
+	private static class REMFieldExpressionProxy extends ExpressionProxy implements IProxyField {
+		
+			/**
+		 * @param proxyid
+		 * @param proxyType
+		 * @param expression
+		 * 
+		 * @since 1.1.0
+		 */
+		private REMFieldExpressionProxy(int proxyid, Expression expression) {
+			super(proxyid, FIELD_EXPRESSION_PROXY, expression);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#createExpressionProxy(int)
+	 */
+	protected ExpressionProxy createExpressionProxy(int proxyType, int proxyID) {
+		switch (proxyType) {
+			case NORMAL_EXPRESSION_PROXY:
+			default:
+				return new ExpressionProxy(proxyID, NORMAL_EXPRESSION_PROXY, this);
+			
+			case BEANTYPE_EXPRESSION_PROXY:
+				return new REMBeanTypeExpressionProxy(proxyID, this);
+				
+			case METHOD_EXPRESSION_PROXY:
+				return new REMMethodExpressionProxy(proxyID, this);
+				
+			case FIELD_EXPRESSION_PROXY:
+				return new REMFieldExpressionProxy(proxyID, this);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushAssignmentToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy)
+	 */
+	protected void pushAssignmentToProxy(ExpressionProxy proxy) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push assignment to proxy command is:
+			//	PushExpressionCommand(push assignment to proxy) followed by:
+			//		int: proxy id
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION_VALUE);
+			connection.pushInt(proxy.getProxyID());
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushAssignmentToProxy()
+	 */
+	protected void pushAssignmentToProxy() {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of the push assignment command is:
+			//   PushAssignmentCommand.
+			connection.pushExpressionCommand(getREMExpressionID(), (byte) InternalExpressionTypes.ASSIGNMENT_EXPRESSION_VALUE);
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+	
+
+	private void pushToExpressionProxy(ExpressionProxy proxy) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push to expression proxy command is:
+			//	PushExpressionCommand(push expression proxy to proxy) followed by:
+			//		int: proxy id
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_TO_EXPRESSION_PROXY_EXPRESSION_VALUE);
+			connection.pushInt(proxy.getProxyID());
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+
+	}
+	
+	private static class BlockBegin extends PendingTransaction {
+		public int blockNumber;
+		
+		public BlockBegin(int blockNumber) {
+			this.blockNumber = blockNumber;
+		}
+		
+		public void pushTransaction(REMExpression remExpression) {
+			IREMExpressionConnection connection = remExpression.getConnection();
+			try {
+				// Format of push to block begin proxy command is:
+				//	PushExpressionCommand(push block begin proxy to proxy) followed by:
+				//		int: block id
+				connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.BLOCK_BEGIN_EXPRESSION_VALUE);
+				connection.pushInt(blockNumber);
+			} catch (IOException e) {
+				connection.close();
+				ProxyPlugin.getPlugin().getLogger().log(e);
+				remExpression.markInvalid(e.getLocalizedMessage());
+				remExpression.throwIllegalStateException(IO_EXCEPTION_MSG);
+			}			
+		}
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockBeginToProxy(int)
+	 */
+	protected void pushBlockBeginToProxy(int blockNumber) {
+		addPendingTransaction(new BlockBegin(blockNumber));
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockEndToProxy(int)
+	 */
+	protected void pushBlockEndToProxy(int blockNumber) {
+		// See if the top pending transactions is BreakBlock(blockNumber). If it is then the BreakBlock can be thrown away.
+		PendingTransaction topEntry = getPendingEntryFromTop(1);
+		if (topEntry instanceof BlockBreak && ((BlockBreak) topEntry).blockNumber == blockNumber) {
+			popPendingEntry(1);
+			topEntry = getPendingEntryFromTop(1);
+		}
+		// See if the top pending transaction is now BeginBlock(blockNumber). If it is, then this transaction and the block begin
+		// can be thrown away because they are an empty block.
+		if (topEntry instanceof BlockBegin && ((BlockBegin) topEntry).blockNumber == blockNumber) {
+			popPendingEntry(1);
+			return;
+		}
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push to block end proxy command is:
+			//	PushExpressionCommand(push block end proxy to proxy) followed by:
+			//		int: block id
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.BLOCK_END_EXPRESSION_VALUE);
+			connection.pushInt(blockNumber);
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+	
+	private static class BlockBreak extends PendingTransaction {
+		public int blockNumber;
+		
+		public BlockBreak(int blockNumber) {
+			this.blockNumber = blockNumber;
+		}
+		
+		public void pushTransaction(REMExpression remExpression) {
+			IREMExpressionConnection connection = remExpression.getConnection();
+			try {
+				// Format of push to block break proxy command is:
+				//	PushExpressionCommand(push block break proxy to proxy) followed by:
+				//		int: block id
+				connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.BLOCK_BREAK_EXPRESSION_VALUE);
+				connection.pushInt(blockNumber);
+			} catch (IOException e) {
+				connection.close();
+				ProxyPlugin.getPlugin().getLogger().log(e);
+				remExpression.markInvalid(e.getLocalizedMessage());
+				remExpression.throwIllegalStateException(IO_EXCEPTION_MSG);
+			}
+		}		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockBreakToProxy(int)
+	 */
+	protected void pushBlockBreakToProxy(int blockNumber) {
+		// Even if there is no pending block begin for this block, we will pend the break.
+		// This is so that if the break occurred just before the block end, then it can be ignored.
+		addPendingTransaction(new BlockBreak(blockNumber));
+	}
+
+	private static class TryBegin extends PendingTransaction {
+
+		public final int tryNumber;
+		
+		public TryBegin(int tryNumber) {
+			this.tryNumber = tryNumber;
+			
+		}
+		public void pushTransaction(REMExpression remExpression) {
+			IREMExpressionConnection connection = remExpression.getConnection();
+			try {
+				// Format of push to try begin proxy command is:
+				//	PushExpressionCommand(push try begin to proxy) followed by:
+				//		int: try id
+				connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.TRY_BEGIN_EXPRESSION_VALUE);
+				connection.pushInt(tryNumber);
+			} catch (IOException e) {
+				connection.close();
+				ProxyPlugin.getPlugin().getLogger().log(e);
+				remExpression.markInvalid(e.getLocalizedMessage());
+				remExpression.throwIllegalStateException(IO_EXCEPTION_MSG);
+			}
+		}
+		
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryBeginToProxy(int)
+	 */
+	protected void pushTryBeginToProxy(int tryNumber) {
+		addPendingTransaction(new TryBegin(tryNumber));
+	}
+
+	private static class TryCatch extends PendingTransaction {
+
+		public final int tryNumber;
+		private final IProxyBeanType exceptionType;
+		private final ExpressionProxy ep;
+
+		public TryCatch(int tryNumber, IProxyBeanType exceptionType, ExpressionProxy ep) {
+			this.tryNumber = tryNumber;
+			this.exceptionType = exceptionType;
+			this.ep = ep;
+		}
+		
+		public void pushTransaction(REMExpression remExpression) {
+			IREMExpressionConnection connection = remExpression.getConnection();
+			try {
+				// Format of push to try begin proxy command is:
+				//	PushExpressionCommand(push try begin to proxy) followed by:
+				//		int: try id
+				//		object: expression type (as beantype or as expression proxy)
+				//		int: proxy id or (-1 if null).
+				connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.TRY_CATCH_EXPRESSION_VALUE);
+				connection.pushInt(tryNumber);
+				remExpression.fillProxy(exceptionType, remExpression.workerValue);
+				connection.pushValueObject(remExpression.workerValue);
+				if (ep != null)
+					connection.pushInt(ep.getProxyID());
+				else
+					connection.pushInt(-1);
+			} catch (IOException e) {
+				connection.close();
+				ProxyPlugin.getPlugin().getLogger().log(e);
+				remExpression.markInvalid(e.getLocalizedMessage());
+				remExpression.throwIllegalStateException(IO_EXCEPTION_MSG);
+			} catch (CommandException e) {
+				ProxyPlugin.getPlugin().getLogger().log(e);
+				remExpression.markInvalid(e.getLocalizedMessage());
+				if (!e.isRecoverable()) {
+					connection.close();
+					remExpression.throwIllegalStateException(COMMAND_EXCEPTION_MSG);
+				}			
+			}
+		}
+		
+	}
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryCatchClauseToProxy(int, org.eclipse.jem.internal.proxy.core.IProxyBeanType, org.eclipse.jem.internal.proxy.core.ExpressionProxy)
+	 */
+	protected void pushTryCatchClauseToProxy(int tryNumber, IProxyBeanType exceptionType, ExpressionProxy ep) {
+		addPendingTransaction(new TryCatch(tryNumber, exceptionType, ep));
+	}
+
+	private static class TryFinally extends PendingTransaction {
+		
+		public final int tryNumber;
+
+		public TryFinally(int tryNumber) {
+			this.tryNumber = tryNumber;
+			
+		}
+
+		public void pushTransaction(REMExpression remExpression) {
+			IREMExpressionConnection connection = remExpression.getConnection();
+			try {
+				// Format of push to try begin proxy command is:
+				//	PushExpressionCommand(push try finally to proxy) followed by:
+				//		int: try id
+				connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.TRY_FINALLY_EXPRESSION_VALUE);
+				connection.pushInt(tryNumber);
+			} catch (IOException e) {
+				connection.close();
+				ProxyPlugin.getPlugin().getLogger().log(e);
+				remExpression.markInvalid(e.getLocalizedMessage());
+				remExpression.throwIllegalStateException(IO_EXCEPTION_MSG);
+			}
+		}
+		
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryFinallyClauseToProxy(int)
+	 */
+	protected void pushTryFinallyClauseToProxy(int tryNumber) {
+		addPendingTransaction(new TryFinally(tryNumber));
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryEndToProxy(int)
+	 */
+	protected void pushTryEndToProxy(int tryNumber) {
+		// This is a little tricky. We need to find if there is nothing but try/catch/finally for this tryNumber on the pending
+		// transactions up to the try begin, if there is nothing else, then we can throw the entire try away. That
+		// means there was no code at all in any of the try/catch/finally blocks.
+		int fromTop = 0;
+		while (true) {
+			PendingTransaction topEntry = getPendingEntryFromTop(++fromTop);
+			if (topEntry instanceof TryFinally) {
+				if (((TryFinally) topEntry).tryNumber != tryNumber)
+					break;	// We met a finally that wasn't ours, so entire try group must be sent.
+			} else if (topEntry instanceof TryCatch) {
+				if (((TryCatch) topEntry).tryNumber != tryNumber)
+					break;	// We met a catch that wasn't ours, so entire try group must be sent.
+			} else if (topEntry instanceof TryBegin) {
+				if (((TryBegin) topEntry).tryNumber == tryNumber) {
+					// We've met our try begin, and nothing but empty catch/finally in between, so the entire group can be thrown away
+					popPendingEntry(fromTop);
+					return;
+				} else
+					break;	// We've hit a try begin that wasn't ours, so the entire try group must be sent.	
+			} else
+				break;	// We've hit something other than our try group, so process everything.
+		}
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push to try begin proxy command is:
+			//	PushExpressionCommand(push try end to proxy) followed by:
+			//		int: try id
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.TRY_END_EXPRESSION_VALUE);
+			connection.pushInt(tryNumber);
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushThrowToProxy()
+	 */
+	protected void pushThrowToProxy() {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push to try begin proxy command is:
+			//	PushExpressionCommand(push throw to proxy)
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.THROW_EXPRESSION_VALUE);
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushRethrowToProxy(int)
+	 */
+	protected void pushRethrowToProxy(int tryNumber) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push to rethow proxy command is:
+			//	PushExpressionCommand(push rethrow to proxy)
+			//		int: try id
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.RETHROW_EXPRESSION_VALUE);
+			connection.pushInt(tryNumber);
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushBeanTypeToProxy(org.eclipse.jem.internal.proxy.core.IBeanTypeExpressionProxy)
+	 */
+	protected void pushBeanTypeToProxy(IBeanTypeExpressionProxy proxy) {
+		// Push beantype to proxy is sent out of sequence without respect to where in expression we are,
+		// so no need to handle pending transactions at this point. They would not affect the result
+		// of this call.
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push to beanType proxy command is:
+			//	PushExpressionCommand(push bean type expression proxy)
+			//		int: proxy id
+			//		string: typename
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_BEANTYPE_EXPRESSIONPROXY_EXPRESSION_VALUE);
+			REMBeanTypeExpressionProxy ep = (REMBeanTypeExpressionProxy) proxy;
+			connection.pushInt(ep.getProxyID());
+			connection.pushString(ep.getTypeName());
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushMethodToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy, org.eclipse.jem.internal.proxy.core.IProxyBeanType, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[])
+	 */
+	protected void pushMethodToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes) {
+		// Push method to proxy is sent out of sequence without respect to where in expression we are,
+		// so no need to handle pending transactions at this point. They would not affect the result
+		// of this call.
+
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push to method proxy command is:
+			//	PushExpressionCommand(push method type expression proxy)
+			//		int: proxy id
+			//		ValueObject: containing the rendered bean type proxy or the expression proxy for the declaring type
+			//		string: method name
+			//		int: number of parameter types
+			//		ValueObject(s): containing the rendered bean type proxy or the expression proxy for the parameter types.
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_METHOD_EXPRESSIONPROXY_EXPRESSION_VALUE);
+			connection.pushInt(proxy.getProxyID());
+			fillProxy(declaringType, workerValue);
+			connection.pushValueObject(workerValue);
+			connection.pushString(methodName);
+			if (parameterTypes == null || parameterTypes.length == 0)
+				connection.pushInt(0);
+			else {
+				connection.pushInt(parameterTypes.length);
+				for (int i = 0; i < parameterTypes.length; i++) {
+					fillProxy(parameterTypes[i], workerValue);
+					connection.pushValueObject(workerValue);					
+				}
+			}
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		} catch (CommandException e) {
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			if (!e.isRecoverable()) {
+				connection.close();
+				throwIllegalStateException(COMMAND_EXCEPTION_MSG);
+			}			
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushFieldToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy, org.eclipse.jem.internal.proxy.core.IProxyBeanType, java.lang.String)
+	 */
+	protected void pushFieldToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String fieldName) {
+		// Push field to proxy is sent out of sequence without respect to where in expression we are,
+		// so no need to handle pending transactions at this point. They would not affect the result
+		// of this call.
+
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push to field proxy command is:
+			//	PushExpressionCommand(push field type expression proxy)
+			//		int: proxy id
+			//		ValueObject: containing the rendered bean type proxy or the expression proxy for the declaring type
+			//		string: field name
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_FIELD_EXPRESSIONPROXY_EXPRESSION_VALUE);
+			connection.pushInt(proxy.getProxyID());
+			fillProxy(declaringType, workerValue);
+			connection.pushValueObject(workerValue);
+			connection.pushString(fieldName);
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		} catch (CommandException e) {
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			if (!e.isRecoverable()) {
+				connection.close();
+				throwIllegalStateException(COMMAND_EXCEPTION_MSG);
+			}			
+		}
+	}
+	
+	/**
+	 * Get the map of IProxyMethods for a beantype. Meant to be used only in conjunction with REMProxyConstants.
+	 * It is here so the REMProxyConstants can store pending proxies per expression.
+	 * 
+	 * @param beanType
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public Map getMethods(IProxyBeanType beanType) {
+		if (methodsCache == null)
+			methodsCache = new HashMap();
+		Map methods = (Map) methodsCache.get(beanType.getTypeName());
+		if(methods == null){
+			methods = new HashMap(20);
+			methodsCache.put(beanType.getTypeName(),methods);
+		}
+		return methods;	
+	}
+	
+	/**
+	 * Get the map of IProxyFields for a beantype. Meant to be used only in conjunction with REMProxyConstants.
+	 * It is here so the REMProxyConstants can store pending proxies per expression.
+	 * 
+	 * @param beanType
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public Map getFields(IProxyBeanType beanType) {
+		if (fieldsCache == null)
+			fieldsCache = new HashMap();
+		Map fields = (Map) fieldsCache.get(beanType.getTypeName());
+		if(fields == null){
+			fields = new HashMap(20);
+			fieldsCache.put(beanType.getTypeName(),fields);
+		}
+		return fields;	
+	}
+	
+	/**
+	 * Get the map of IProxyBeanTypes for a beantype name. Meant to be used only in conjunction with REMSgtandardBeanTypeFactory.
+	 * It is here so the REMStandardBeanTypeFactory can store pending proxies per expression.
+	 * 
+	 * @param beanType
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyBeanType getBeanType(String beanTypeName) {
+		if (beanTypeCache == null)
+			beanTypeCache = new HashMap();
+		return (IProxyBeanType) beanTypeCache.get(beanTypeName);
+	}
+	
+	/**
+	 * Add the beantype expression proxy to the map of bean type expression proxies. Used in conjunction with REMStandardBeanTypeFactory.
+	 * It is here so the REMStandardBeanTypeFactory can store pending proxies per expression.
+	 * @param beanTypeName
+	 * @param beantype
+	 * 
+	 * @since 1.1.0
+	 */
+	public void addBeanType(String beanTypeName, IProxyBeanType beantype) {
+		beanTypeCache.put(beanTypeName, beantype);
+	}
+	
+	/**
+	 * Remove the beantype expression proxy from the map. This is called because there was a rollback due to an endmark.
+	 * @param beanTypeName
+	 * 
+	 * @since 1.1.0
+	 */
+	public void removeBeanType(String beanTypeName) {
+		beanTypeCache.remove(beanTypeName);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushIfTestToProxy()
+	 */
+	protected void pushIfTestToProxy() {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push if test to proxy command is:
+			//	PushExpressionCommand(push if test to proxy)
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.IF_TEST_EXPRESSION_VALUE);
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushIfElseToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InternalIfElseOperandType)
+	 */
+	protected void pushIfElseToProxy(InternalIfElseOperandType clauseType) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push conditional to proxy command is:
+			//	PushExpressionCommand(push if/else clause to proxy) followed by:
+			//		byte: clause type
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.IF_ELSE_EXPRESSION_VALUE);
+			connection.pushByte((byte) clauseType.getValue());
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushNewInstanceToProxy(java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType)
+	 */
+	protected void pushNewInstanceToProxy(String initializationString, IProxyBeanType resultType) {
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push new instance from initstring to proxy command is:
+			//	PushExpressionCommand(push new instance to proxy) followed by:
+			//		string: init string
+			//		ValueObject: containing the rendered bean type proxy or the expression proxy for the declaring type
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.NEW_INSTANCE_VALUE);
+			connection.pushString(initializationString);
+			fillProxy(resultType, workerValue);
+			connection.pushValueObject(workerValue);			
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		} catch (CommandException e) {
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			if (!e.isRecoverable()) {
+				connection.close();
+				throwIllegalStateException(COMMAND_EXCEPTION_MSG);
+			}			
+		}
+	}
+
+	private static class Mark extends PendingTransaction {
+		public int markID;
+		
+		public Mark(int markID) {
+			this.markID = markID;
+		}
+		
+		public void pushTransaction(REMExpression remExpression) {
+			IREMExpressionConnection connection = remExpression.getConnection();
+			try {
+				// Format of push mark to proxy command is:
+				//	PushExpressionCommand(push mark to proxy) followed by:
+				//		int: markID
+				connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.MARK_VALUE);
+				connection.pushInt(markID);
+			} catch (IOException e) {
+				connection.close();
+				ProxyPlugin.getPlugin().getLogger().log(e);
+				remExpression.markInvalid(e.getLocalizedMessage());
+				remExpression.throwIllegalStateException(IO_EXCEPTION_MSG);
+			}
+		}
+		
+	}
+	
+	protected void pushMarkToProxy(int markID) {
+		addPendingTransaction(new Mark(markID));
+	}
+
+	protected void pushEndmarkToProxy(int markID, boolean restore) {
+		// See if the top pending transaction is now Mark(markID). If it is, then this transaction and the mark begin
+		// can be thrown away because they are an empty block.
+		PendingTransaction topEntry = getPendingEntryFromTop(1);
+		if (topEntry instanceof Mark && ((Mark) topEntry).markID == markID) {
+			popPendingEntry(1);
+			return;
+		}
+		processPendingTransactions();
+		IREMExpressionConnection connection = getConnection();
+		try {
+			// Format of push end mark to proxy command is:
+			//	PushExpressionCommand(push end mark to proxy) followed by:
+			//		int: markID
+			//		boolean: restore
+			connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ENDMARK_VALUE);
+			connection.pushInt(markID);
+			connection.pushBoolean(restore);
+		} catch (IOException e) {
+			connection.close();
+			ProxyPlugin.getPlugin().getLogger().log(e);
+			markInvalid(e.getLocalizedMessage());
+			throwIllegalStateException(IO_EXCEPTION_MSG);
+		}
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMInitErrorBeanTypeProxy.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMInitErrorBeanTypeProxy.java
index 6106117..ba76e0d 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMInitErrorBeanTypeProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMInitErrorBeanTypeProxy.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: REMInitErrorBeanTypeProxy.java,v $
- *  $Revision: 1.7 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.8 $  $Date: 2005/05/11 19:01:12 $ 
  */package org.eclipse.jem.internal.proxy.remote;
 
 import org.eclipse.jem.internal.proxy.core.*;
@@ -427,4 +427,41 @@
 	public IMethodProxy getCompatibleMethod(String methodName, IBeanTypeProxy[] argumentTypes) {
 		return null;
 	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isBeanProxy()
+	 */
+	public final boolean isBeanProxy() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isExpressionProxy()
+	 */
+	public final boolean isExpressionProxy() {
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[])
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String methodName, IProxyBeanType[] parameters) {
+		return null;	// Since this guy is invalid, we can't return a method.
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String[])
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String methodName, String[] parameterTypes) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String)
+	 */
+	public IProxyField getFieldProxy(IExpression expression, String fieldName) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMInvokable.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMInvokable.java
index 47c5af5..9f5945c 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMInvokable.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMInvokable.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: REMInvokable.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.remote;
 
@@ -87,12 +87,9 @@
 					}
 
 					public Commands.ValueObject nextValue() {
-						if (index < array.length) {
-							Object parm = array[index++];
-							((IREMBeanTypeProxy) parm).renderBean(worker);
-							return worker;
-						} else
-							return null;
+						Object parm = array[index++];
+						((IREMBeanTypeProxy) parm).renderBean(worker);
+						return worker;
 					}
 				};
 
@@ -123,30 +120,27 @@
 					}
 
 					public Commands.ValueObject nextValue() {
-						if (index < array.length) {
-							Object parm = array[index++];
-							if (parm != null)
-								if (parm instanceof IREMBeanProxy)
-									 ((IREMBeanProxy) parm).renderBean(worker);
-								else if (parm instanceof TransmitableArray) {
-									// It is another array, create a new retriever.
-									worker.setArrayIDS(
-										new Retriever(((TransmitableArray) parm).array),
-										((TransmitableArray) parm).array.length,
-										((TransmitableArray) parm).componentTypeID);
-								} else {
-									// It's an object. Need to get bean type so that we can send it.
-									IREMBeanProxy type = (IREMBeanProxy) typeFactory.getBeanTypeProxy(parm.getClass().getName());
-									if (type == null)
-										throw new IllegalArgumentException();
-									int classID = type.getID().intValue();
-									worker.setAsObject(parm, classID);
-								}
-							else
-								worker.set();
-							return worker;
-						} else
-							return null;
+						Object parm = array[index++];
+						if (parm != null)
+							if (parm instanceof IREMBeanProxy)
+								 ((IREMBeanProxy) parm).renderBean(worker);
+							else if (parm instanceof TransmitableArray) {
+								// It is another array, create a new retriever.
+								worker.setArrayIDS(
+									new Retriever(((TransmitableArray) parm).array),
+									((TransmitableArray) parm).array.length,
+									((TransmitableArray) parm).componentTypeID);
+							} else {
+								// It's an object. Need to get bean type so that we can send it.
+								IREMBeanProxy type = (IREMBeanProxy) typeFactory.getBeanTypeProxy(parm.getClass().getName());
+								if (type == null)
+									throw new IllegalArgumentException();
+								int classID = type.getID().intValue();
+								worker.setAsObject(parm, classID);
+							}
+						else
+							worker.set();
+						return worker; 
 					}
 				};
 
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMMethodProxy.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMMethodProxy.java
index 5bbe882..f343a04 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMMethodProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMMethodProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMMethodProxy.java,v $
- *  $Revision: 1.9 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.10 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import org.eclipse.core.runtime.IStatus;
@@ -140,30 +140,27 @@
 					}
 
 					public Commands.ValueObject nextValue() {
-						if (index < array.length) {
-							Object parm = array[index++];
-							if (parm != null)
-								if (parm instanceof IREMBeanProxy)
-									 ((IREMBeanProxy) parm).renderBean(worker);
-								else if (parm instanceof TransmitableArray) {
-									// It is another array, create a new retriever.
-									worker.setArrayIDS(
-										new Retriever(((TransmitableArray) parm).array),
-										((TransmitableArray) parm).array.length,
-										((TransmitableArray) parm).componentTypeID);
-								} else {
-									// It's an object. Need to get bean type so that we can send it.
-									IREMBeanProxy type = (IREMBeanProxy) typeFactory.getBeanTypeProxy(parm.getClass().getName());
-									if (type == null)
-										throw new IllegalArgumentException();
-									int classID = type.getID().intValue();
-									worker.setAsObject(parm, classID);
-								}
-							else
-								worker.set();
-							return worker;
-						} else
-							return null;
+						Object parm = array[index++];
+						if (parm != null)
+							if (parm instanceof IREMBeanProxy)
+								 ((IREMBeanProxy) parm).renderBean(worker);
+							else if (parm instanceof TransmitableArray) {
+								// It is another array, create a new retriever.
+								worker.setArrayIDS(
+									new Retriever(((TransmitableArray) parm).array),
+									((TransmitableArray) parm).array.length,
+									((TransmitableArray) parm).componentTypeID);
+							} else {
+								// It's an object. Need to get bean type so that we can send it.
+								IREMBeanProxy type = (IREMBeanProxy) typeFactory.getBeanTypeProxy(parm.getClass().getName());
+								if (type == null)
+									throw new IllegalArgumentException();
+								int classID = type.getID().intValue();
+								worker.setAsObject(parm, classID);
+							}
+						else
+							worker.set();
+						return worker; 
 					}
 				};
 
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMMethodProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMMethodProxyFactory.java
index c67d2e1..75bdc5f 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMMethodProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMMethodProxyFactory.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: REMMethodProxyFactory.java,v $
- *  $Revision: 1.8 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.9 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.remote;
 
@@ -72,8 +72,103 @@
 		IBeanTypeProxy clsProxy = typeFactory.getBeanTypeProxy(className);
 		if (clsProxy == null)
 			return null;
+		// This will redirect to the beantype, which will go through the method cache.
 		return clsProxy.getMethodProxy(methodName, parameterTypes);
 	}
+	
+	/**
+	 * A helper method to get the method proxy for the expression. This is used by registries and beantype proxies. It will go through
+	 * the method cache to make sure we get only one.
+	 * 
+	 * @param expression
+	 * @param aBeanTypeProxy
+	 * @param methodName
+	 * @param parmTypes
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, IProxyBeanType aBeanTypeProxy, String methodName, IProxyBeanType[] parmTypes){
+		return ((REMStandardBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactory()).proxyConstants.getMethodProxy(expression, aBeanTypeProxy, methodName, parmTypes);
+	}
+	
+	/**
+	 * A helper method to get the field proxy for the expression. This is used by registries and beantype proxies. It will go through
+	 * the method cache to make sure we get only one.
+	 * @param expression
+	 * @param aBeanTypeProxy
+	 * @param fieldName
+	 * 
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyField getFieldProxy(IExpression expression, IProxyBeanType aBeanTypeProxy, String fieldName){
+		return ((REMStandardBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactory()).proxyConstants.getFieldProxy(expression, aBeanTypeProxy, fieldName);
+	}
+	
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IMethodProxyFactory#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String)
+	 */
+	public IProxyField getFieldProxy(IExpression expression, String className, String fieldName) {
+		// We are getting the class resolved through the expression. Might as well because it probably will
+		// be needed again and this way when the expression is finished it will be resolved for later usage.
+		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fFactoryRegistry.getBeanTypeProxyFactory();
+		IProxyBeanType beanType = beanTypeProxyFactory.getBeanTypeProxy(expression, className);
+		return beanType.getFieldProxy(expression, fieldName);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IMethodProxyFactory#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String, java.lang.String[])
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String className, String methodName, String[] parameterTypes) {
+		// We are getting the class and parmtypes resolved through the expression. Might as well because they probably will
+		// be needed again and this way when the expression is finished they will be resolved for later usage.
+		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fFactoryRegistry.getBeanTypeProxyFactory();
+		IProxyBeanType beanType = beanTypeProxyFactory.getBeanTypeProxy(expression, className);
+		IProxyBeanType[] parmTypes = getParameterTypes(expression, parameterTypes, beanTypeProxyFactory);
+		return beanType.getMethodProxy(expression, methodName, parmTypes);
+	}
+	
+	/**
+	 * Helper method for BeanTypes and proxy Beantypes. So they don't need to have common code to convert string to proxy bean type.
+	 * @param expression
+	 * @param classType
+	 * @param methodName
+	 * @param parameterTypes
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, IProxyBeanType classType, String methodName, String[] parameterTypes) {
+		// We are getting the class and parmtypes resolved through the expression. Might as well because they probably will
+		// be needed again and this way when the expression is finished they will be resolved for later usage.
+		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fFactoryRegistry.getBeanTypeProxyFactory();
+		IProxyBeanType[] parmTypes = getParameterTypes(expression, parameterTypes, beanTypeProxyFactory);
+		return classType.getMethodProxy(expression, methodName, parmTypes);
+	}
+
+	/**
+	 * @param expression
+	 * @param parameterTypes
+	 * @param beanTypeProxyFactory
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	protected IProxyBeanType[] getParameterTypes(IExpression expression, String[] parameterTypes, IStandardBeanTypeProxyFactory beanTypeProxyFactory) {
+		IProxyBeanType[] parmTypes;
+		if (parameterTypes == null || parameterTypes.length == 0)
+			parmTypes = null;
+		else {
+			parmTypes = new IProxyBeanType[parameterTypes.length];
+			for (int i = 0; i < parameterTypes.length; i++) {
+				parmTypes[i] = beanTypeProxyFactory.getBeanTypeProxy(expression, parameterTypes[i]);
+			}
+		}
+		return parmTypes;
+	}
 
 	/*
 	 * (non-Javadoc)
@@ -118,6 +213,7 @@
 	
 	/**
 	 * Get the method id from the remote system and create the method proxy.
+	 * This does not go through the method cache. It goes direct to the remote vm.
 	 * 
 	 * NOTE: It is public ONLY so that IBeanTypeProxy implementations can call it. It must not be used by anyone else.
 	 */
@@ -155,6 +251,8 @@
 	
 	/**
 	 * Get the method id from the remote system and create the method proxy.
+	 * <p>
+	 * This does not go through the method cache. It goes direct to the remote vm.
 	 * 
 	 * NOTE: It is public ONLY so that IBeanTypeProxy implementations can call it. It must not be used by anyone else.
 	 */
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyConstants.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyConstants.java
index d38961c..bff0693 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyConstants.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyConstants.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: REMProxyConstants.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.remote;
 
@@ -18,6 +18,7 @@
 import java.util.Map.Entry;
 
 import org.eclipse.jem.internal.proxy.core.*;
+import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent;
 
 
 
@@ -35,6 +36,12 @@
 	private Map invokablesCache = new HashMap(80);	
 	private Map fieldsCache = new HashMap(80);
 	
+	private REMProxyFactoryRegistry registry;
+	
+	public REMProxyConstants(REMProxyFactoryRegistry registry) {
+		this.registry = registry;
+	}
+	
 	/*
 	 * Used as the key to the methodCache and invokablesCache when there are parms.
 	 * It allows the parms to be either strings or IBeanTypeProxies without the
@@ -53,7 +60,7 @@
 			this.methodName = methodName;
 		}
 				
-		protected abstract boolean compareParms(IBeanTypeProxy[] parms);
+		protected abstract boolean compareParms(IProxyBeanType[] parms);
 		protected abstract boolean compareParms(String[] parms);
 		
 		
@@ -101,7 +108,7 @@
 		/* (non-Javadoc)
 		 * @see org.eclipse.jem.internal.proxy.remote.REMProxyConstants.MethodKey#compareParms(org.eclipse.jem.internal.proxy.core.IBeanTypeProxy[])
 		 */
-		protected boolean compareParms(IBeanTypeProxy[] parms) {
+		protected boolean compareParms(IProxyBeanType[] parms) {
 			if (parms.length != parmNames.length)
 				return false;
 			for (int i = 0; i < parms.length; i++) {
@@ -121,13 +128,21 @@
 	}
 	
 	private static class MethodKeyProxyParms extends MethodKey {
-		public IBeanTypeProxy[] parmTypes;
+		public IProxyBeanType[] parmTypes;
 		
-		public MethodKeyProxyParms(String methodName, IBeanTypeProxy[] parmTypes) {
+		public MethodKeyProxyParms(String methodName, IProxyBeanType[] parmTypes) {
 			super(methodName);
 			this.parmTypes = parmTypes;
 		}
 		
+		public Object toMethodKeyStringParms() {
+			String[] parms = new String[parmTypes.length];
+			for (int i = 0; i < parmTypes.length; i++) {
+				parms[i] = parmTypes[i].getTypeName();
+			}
+			return new MethodKeyStringParms(methodName, parms);
+		}
+		
 		/* (non-Javadoc)
 		 * @see java.lang.Object#equals(java.lang.Object)
 		 */
@@ -169,8 +184,14 @@
 		/* (non-Javadoc)
 		 * @see org.eclipse.jem.internal.proxy.remote.REMProxyConstants.MethodKey#compareParms(java.lang.String[])
 		 */
-		protected boolean compareParms(IBeanTypeProxy[] parms) {
-			return Arrays.equals(parms, parmTypes);
+		protected boolean compareParms(IProxyBeanType[] parms) {
+			if (parms.length != parmTypes.length)
+				return false;
+			for (int i = 0; i < parms.length; i++) {
+				if (!parmTypes[i].getTypeName().equals(parms[i].getTypeName()))
+					return false;
+			}
+			return true;
 		}		
 	}
 		
@@ -275,41 +296,53 @@
  * @param parmTypes = array of qualified type names for the method arguments, null if no methods
  */ 
 	public IMethodProxy getMethodProxy(IBeanTypeProxy aBeanTypeProxy, String methodName, String[] parmTypes){
+		if (!registry.isValid())
+			return null;
 
-		REMMETHODCOUNT++;		
-		// The classCache map is keyed by the BeanTypeProxy and holds a further map of cache'd methods
-		Map methods = getMethods(aBeanTypeProxy);
-		
-		// The syntax of the key is methodName(parmType1,parmType2)
-		Object key = null; 
-		if(parmTypes == null || parmTypes.length == 0){
-			key = methodName;
-		} else {
-			key = new MethodKeyStringParms(methodName, parmTypes);
+		REMMETHODCOUNT++;
+		Map methods;
+		Object key;
+		synchronized (this) {
+			// The classCache map is keyed by the BeanTypeProxy and holds a further map of cache'd methods
+			methods = getMethods(aBeanTypeProxy);
+
+			// The syntax of the key is methodName(parmType1,parmType2)
+			if (parmTypes == null || parmTypes.length == 0) {
+				key = methodName;
+			} else {
+				key = new MethodKeyStringParms(methodName, parmTypes);
+			}
+
+			IMethodProxy result = (IMethodProxy) methods.get(key);
+			if (result != null)
+				return result;
 		}
 		
-		// Lookup the cache'd method proxy
-		IMethodProxy result = (IMethodProxy) methods.get(key);
-		// Do we have it, and is still valid (in case someone did a release on it).
-		if(result != null && result.isValid()) return result;
-		
 		UNIQUEMETHODCOUNT++;
 		// Get the method proxy and cache this before returning it
-		REMMethodProxyFactory proxyFactory = (REMMethodProxyFactory) aBeanTypeProxy.getProxyFactoryRegistry().getMethodProxyFactory();
-		result = proxyFactory.getMethodProxy((IREMBeanTypeProxy)aBeanTypeProxy,methodName,parmTypes);
-		methods.put(key,result);
-		return result;
-		
+		// Get the method proxy and cache this before returning it
+		REMMethodProxyFactory proxyFactory = (REMMethodProxyFactory) registry.getMethodProxyFactory();
+		IMethodProxy result = proxyFactory.getMethodProxy((IREMBeanTypeProxy)aBeanTypeProxy,methodName,parmTypes);
+		synchronized (this) {
+			// Get it again to make sure it hasn't changed due to a race condition. We don't sync for the getMethodProxy because that goes to the remote vm and could deadlock.
+			IMethodProxy mValue = (IMethodProxy) methods.get(key);
+			if (mValue != null && mValue != result) {
+				registry.releaseProxy(result); // Don't need the result now, got it through a race condition.
+				return mValue; // We have a real value now.
+			}
+			methods.put(key, result);
+		}		
+		return result;				
 	}
 /**
  * @param aBeanTypeProxy
  * @return Map of cache'd methods
  */
-private Map getMethods(IBeanTypeProxy aBeanTypeProxy) {
-	Map methods = (Map) methodsCache.get(aBeanTypeProxy);
+private Map getMethods(IProxyBeanType aBeanTypeProxy) {
+	Map methods = (Map) methodsCache.get(aBeanTypeProxy.getTypeName());
 	if(methods == null){
 		methods = new HashMap(20);
-		methodsCache.put(aBeanTypeProxy,methods);
+		methodsCache.put(aBeanTypeProxy.getTypeName(),methods);
 	}
 	return methods;
 }
@@ -329,11 +362,11 @@
  * @param aBeanTypeProxy
  * @return Map of cache'd fields
  */
-private Map getFields(IBeanTypeProxy aBeanTypeProxy) {
-	Map fields = (Map) fieldsCache.get(aBeanTypeProxy);
+private Map getFields(IProxyBeanType aBeanTypeProxy) {
+	Map fields = (Map) fieldsCache.get(aBeanTypeProxy.getTypeName());
 	if(fields == null){
 		fields = new HashMap(20);
-		fieldsCache.put(aBeanTypeProxy,fields);
+		fieldsCache.put(aBeanTypeProxy.getTypeName(),fields);
 	}
 	return fields;
 }
@@ -403,31 +436,124 @@
  * @param parmTypes = array of qualified type names for the method arguments, null if no methods
  */ 
 	public IMethodProxy getMethodProxy(IBeanTypeProxy aBeanTypeProxy, String methodName, IBeanTypeProxy[] parmTypes){
+		if (!registry.isValid())
+			return null;
 		
 		REMMETHODCOUNT++;		
 		// The classCache map is keyed by the BeanTypeProxy and holds a further map of cache'd methods
-		Map methods = getMethods(aBeanTypeProxy);	
-				
-		Object key = null; 
-		if(parmTypes == null || parmTypes.length == 0){
-			key = methodName;
-		} else {
-			key = new MethodKeyProxyParms(methodName, parmTypes);
-		}	
-		
-		// Lookup the cache'd method proxy
-		IMethodProxy result = (IMethodProxy) methods.get(key);
-		if(result != null) return result;
+		Map methods;
+		Object key;
+		synchronized (this) {
+			methods = getMethods(aBeanTypeProxy);
+
+			key = null;
+			if (parmTypes == null || parmTypes.length == 0) {
+				key = methodName;
+			} else {
+				key = new MethodKeyProxyParms(methodName, parmTypes);
+			}
+
+			IMethodProxy result = (IMethodProxy) methods.get(key);
+			if (result != null)
+				return result;
+		}
 		
 		UNIQUEMETHODCOUNT++;
 		// Get the method proxy and cache this before returning it
 		// Get the method proxy and cache this before returning it
-		REMMethodProxyFactory proxyFactory = (REMMethodProxyFactory) aBeanTypeProxy.getProxyFactoryRegistry().getMethodProxyFactory();
-		result = proxyFactory.getMethodProxy((IREMBeanTypeProxy)aBeanTypeProxy,methodName,parmTypes);
-		methods.put(key,result);		
+		REMMethodProxyFactory proxyFactory = (REMMethodProxyFactory) registry.getMethodProxyFactory();
+		IMethodProxy result = proxyFactory.getMethodProxy((IREMBeanTypeProxy)aBeanTypeProxy,methodName,parmTypes);
+		synchronized (this) {
+			// Get it again to make sure it hasn't changed due to a race condition. We don't sync for the getMethodProxy because that goes to the remote vm and could deadlock.
+			IMethodProxy mValue = (IMethodProxy) methods.get(key);
+			if (mValue != null && mValue != result) {
+				registry.releaseProxy(result); // Don't need result now, got it already through a race condition.
+				return mValue; // We have a real value now.
+			}
+			methods.put(key, result);
+		}		
+
 		return result;				
 	}
 
+	/**
+	 * Return the proxy method for the method through the expression. 
+	 * @param expression
+	 * @param aBeanTypeProxy
+	 * @param methodName
+	 * @param parmTypes
+	 * @return either the IMethodProxy if already resolved or an ExpressionProxy if not yet resolved.
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, IProxyBeanType aBeanTypeProxy, String methodName, IProxyBeanType[] parmTypes){
+		if (!registry.isValid())
+			return null;
+		
+		REMMETHODCOUNT++;	
+		Map methods;
+		Map epMethods;
+		Object key;
+		boolean isKey;
+		synchronized (this) {
+			// The classCache map is keyed by the BeanTypeProxy name and holds a further map of cache'd methods
+			methods = getMethods(aBeanTypeProxy);
+
+			if (parmTypes == null || parmTypes.length == 0) {
+				key = methodName;
+				isKey = false;
+			} else {
+				key = new MethodKeyProxyParms(methodName, parmTypes);
+				isKey = true;
+			}
+
+			IProxyMethod result = (IProxyMethod) methods.get(key);
+			if (result != null)
+				return result;
+			
+			// See if stored in the expression.
+			epMethods = ((REMExpression) expression).getMethods(aBeanTypeProxy);
+			result = (IProxyMethod) epMethods.get(key);
+			if (result != null)
+				return result;
+		}
+		
+		UNIQUEMETHODCOUNT++;
+		// Get the method expression proxy and cache this before returning it
+		IProxyMethod result = ((Expression) expression).createMethodExpressionProxy(aBeanTypeProxy,methodName,parmTypes);
+		epMethods.put(key, result);
+		final Object epKey = key;
+		final Map rMethods = methods; 
+		final Map fepMethods = epMethods;
+		final boolean isKeyType = isKey;
+		((ExpressionProxy) result).addProxyListener(new ExpressionProxy.ProxyAdapter() {
+			public void proxyResolved(ProxyEvent event) {
+				synchronized (REMProxyConstants.this) {
+					if (rMethods.containsKey(epKey))
+						return;	// We already have a true method proxy in there. A race condition occurred.
+					
+					// Now put this resolved guy into the methods.
+					// We don't want the key to contain expression proxies in the final map, so if it is a key type
+					// we will turn it into a string type key.
+					Object key;
+					if (isKeyType) {
+						key = ((MethodKeyProxyParms) epKey).toMethodKeyStringParms();	// So that we don't put a ket that contains expression proxy parm types into the main map.
+					} else
+						key = epKey;
+					
+					rMethods.put(key, event.getProxy());
+				}
+			}
+			
+			public void proxyNotResolved(ExpressionProxy.ProxyEvent event) {
+				synchronized (REMProxyConstants.this) {
+					fepMethods.remove(epKey);
+				}
+				}
+			
+		});
+		return result;				
+	}
 
 	/**
 	 * @param proxy
@@ -474,21 +600,80 @@
 	 * @return The field proxy that is cache'd for performance
 	 */
 	public IFieldProxy getFieldProxy(REMAbstractBeanTypeProxy aBeanTypeProxy, String fieldName) {
-
-		REMFIELDCOUNT++;		
-		// The field map is keyed by the BeanTypeProxy and holds a further map of cache'd fields
-		Map fields = getFields(aBeanTypeProxy);	
+		if (!registry.isValid())
+			return null;
+		
+		REMFIELDCOUNT++;
+		Map fields;
+		synchronized (this) {
+			// The field map is keyed by the BeanTypeProxy and holds a further map of cache'd fields
+			fields = getFields(aBeanTypeProxy);	
 				
-		// Lookup the cache'd Field proxy
-		IFieldProxy result = (IFieldProxy) fields.get(fieldName);
-		if(result != null && result.isValid()) return result;
+			// Lookup the cache'd Field proxy
+			IFieldProxy result = (IFieldProxy) fields.get(fieldName);
+			if (result != null)
+				return result;
+		}
 		
 		UNIQUEFIELDCOUNT++;
-		
-		result = (IFieldProxy) REMStandardBeanProxyConstants.getConstants(aBeanTypeProxy.getProxyFactoryRegistry()).getClassGetField().invokeCatchThrowableExceptions(
+		IFieldProxy result = (IFieldProxy) REMStandardBeanProxyConstants.getConstants(aBeanTypeProxy.getProxyFactoryRegistry()).getClassGetField().invokeCatchThrowableExceptions(
 				aBeanTypeProxy,
-				aBeanTypeProxy.getProxyFactoryRegistry().getBeanProxyFactory().createBeanProxyWith(fieldName));		
-		fields.put(fieldName,result);		
+				registry.getBeanProxyFactory().createBeanProxyWith(fieldName));	
+		synchronized (this) {
+			IFieldProxy fValue = (IFieldProxy) fields.get(fieldName);
+			if (fValue != null) {
+				registry.releaseProxy(result);	// Don't need it now. A race had put another one in.
+				return fValue;
+			}
+			fields.put(fieldName,result);
+		}
 		return result;				
-	}			
+	}
+	
+	public IProxyField getFieldProxy(IExpression expression, IProxyBeanType aBeanTypeProxy, final String fieldName){
+		if (!registry.isValid())
+			return null;
+		
+		REMFIELDCOUNT++;
+		Map fields;
+		Map epFields;
+		synchronized (this) {
+			// The classCache map is keyed by the BeanTypeProxy name and holds a further map of cache'd methods
+			fields = getFields(aBeanTypeProxy);	
+		
+			IProxyField result = (IProxyField) fields.get(fieldName);
+			if (result != null)
+				return result;
+			
+			// See if stored in the expression.
+			epFields = ((REMExpression) expression).getFields(aBeanTypeProxy);
+			result = (IProxyField) epFields.get(fieldName);
+			if (result != null)
+				return result;			
+		}
+		
+		UNIQUEFIELDCOUNT++;
+		// Get the field expression proxy and cache this before returning it
+		IProxyField result = ((REMExpression) expression).createFieldExpressionProxy(aBeanTypeProxy, fieldName);
+		epFields.put(fieldName, result);
+		final Map fpFields = fields;
+		final Map fepFields = epFields;
+		((ExpressionProxy) result).addProxyListener(new ExpressionProxy.ProxyAdapter() {
+
+			public void proxyResolved(ProxyEvent event) {
+				synchronized (REMProxyConstants.this) {
+					if (fpFields.containsKey(fieldName))
+						return;	// Already set to resolved value by someone else.
+					fpFields.put(fieldName, event.getProxy());
+				}
+			}
+			 public void proxyNotResolved(ExpressionProxy.ProxyEvent event) {
+				 synchronized (REMProxyConstants.this) {
+					 fepFields.remove(fieldName);
+				}
+			 }
+		});
+		
+		return result;				
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java
index e27b9cd..ff41049 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMProxyFactoryRegistry.java,v $
- *  $Revision: 1.16 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.17 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -122,7 +122,7 @@
 			waitRegistrationThread = new WaitForRegistrationThread();
 			waitRegistrationThread.start();
 			
-			// Now we will wait until the connection pool has been locked. The thread will
+			// Now we will wait until the registration callback has been done. The thread will
 			// signal us when that is done. This is so that we don't continue on and let
 			// a work connection be requested before we even got a chance to start waiting
 			// for the registration.
@@ -329,10 +329,12 @@
 			// The current thread is a call back thread, so just reuse the connection.
 			// But this thread could actually be trying to access another registry.
 			// So if this thread is for this registry, use it, if not for this registry, create a new connection.
-			if (((REMCallbackThread) thread).registry == this) {
+			// But if for this registry AND is already in a transaction, we need a fresh connection.
+			REMCallbackThread callbackThread = (REMCallbackThread) thread;
+			if (callbackThread.registry == this && !callbackThread.inTransaction()) {
 				// This way any calls out to the remote vm will be on same thread as callback caller
 				// on remote vm because that thread is waiting on this connection for commands.
-				IREMConnection c = ((REMCallbackThread) thread).getConnection();
+				IREMConnection c = (callbackThread).getConnection();
 				if (c.isConnected())
 					return c;
 				else
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanProxyConstants.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanProxyConstants.java
index 940c929..4d2df21 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanProxyConstants.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanProxyConstants.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMStandardBeanProxyConstants.java,v $
- *  $Revision: 1.6 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.7 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -34,7 +34,7 @@
  * @author: Administrator
  */
 public final class REMStandardBeanProxyConstants {
-	public static final String REGISTRY_KEY = "REMSTANDARDPROXYCONSTANTS:"; //$NON-NLS-1$
+	public static final Object REGISTRY_KEY = new Object();
 		
 	private final ProxyFactoryRegistry fRegistry;
 	
@@ -83,6 +83,7 @@
 	private IMethodProxy fFieldSet;
 	
 	private IMethodProxy fConstructorNewInstance;	
+	private IMethodProxy fConstructorParameterTypesMessage;
 	
 	private IMethodProxy fArrayNewInstanceOneDimension;
 	private IMethodProxy fArrayNewInstanceMultiDimensions;
@@ -299,6 +300,12 @@
 	return fConstructorNewInstance;
 }
 
+public IMethodProxy getConstructorParameterTypesMessage() {
+	if (fConstructorParameterTypesMessage == null)
+		fConstructorParameterTypesMessage = fRegistry.getMethodProxyFactory().getMethodProxy("java.lang.reflect.Constructor", "getParameterTypes", null); //$NON-NLS-1$ //$NON-NLS-2$
+	return fConstructorParameterTypesMessage;
+}
+
 public IMethodProxy getArrayNewInstanceOneDimension() {
 	if (fArrayNewInstanceOneDimension == null)
 		fArrayNewInstanceOneDimension = fRegistry.getMethodProxyFactory().getMethodProxy("java.lang.reflect.Array", "newInstance", new String[] {"java.lang.Class", "int"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanProxyFactory.java
index 9985128..3713eab 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanProxyFactory.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMStandardBeanProxyFactory.java,v $
- *  $Revision: 1.10 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.11 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -191,13 +191,13 @@
 		// Synced in here so that we will remove it before some one else from a different thread may try
 		// to access it again.
 		if (id.intValue() != Commands.NOT_AN_ID) {
-			ProxyRef ref = (ProxyRef) fIDToProxiesMap.remove(id);
+			ProxyRef ref = (ProxyRef) fIDToProxiesMap.get(id);
 			if (ref == null || ref.decrUseCnt() <= 0) {
 				// No usage, so do actual release.
+				fIDToProxiesMap.remove(id);
 				((IREMBeanProxy) proxy).release();
-				releaseID(id.intValue());
 				if (ref != null)
-					ref.clear();	// So the proxy will GC with out queuing up.
+					ref.enqueue();	// Queue it up so that on next release cycle it will go away.
 			} 
 		} else {
 			((IREMBeanProxy) proxy).release();			
@@ -734,6 +734,12 @@
 	}
 }
 
+public boolean inTransaction() {
+	synchronized (fIDToProxiesMap) {
+		return transactionLockCount != 0;
+	}
+}
+
 /**
  * Stop Transaction: During the time between start/stop transaction,
  * proxies will not be cleaned up. This prevents the case of a two step
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanTypeProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanTypeProxyFactory.java
index c02533a..2476bd5 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanTypeProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMStandardBeanTypeProxyFactory.java
@@ -9,573 +9,681 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jem.internal.proxy.remote;
+
 /*
  *  $RCSfile: REMStandardBeanTypeProxyFactory.java,v $
- *  $Revision: 1.9 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.10 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
-
 import java.text.MessageFormat;
 import java.util.*;
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jem.internal.proxy.core.*;
+import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent;
 import org.eclipse.jem.internal.proxy.common.CommandException;
 import org.eclipse.jem.internal.proxy.common.MapTypes;
 import org.eclipse.jem.internal.proxy.common.remote.CommandErrorException;
 import org.eclipse.jem.internal.proxy.common.remote.Commands;
 
 /**
- * We are a beanTypeProxyFactory for creating REMBeanTypeProxy objects
- * Primitive types as well as common types like String are cached for speed
- * of lookup.
- * We are the standard one that the VCE uses.
- * Creation date: (12/3/99 2:32:48 PM)
+ * We are a beanTypeProxyFactory for creating REMBeanTypeProxy objects Primitive types as well as common types like String are cached for speed of
+ * lookup. We are the standard one that the VCE uses. Creation date: (12/3/99 2:32:48 PM)
+ * 
  * @author: Joe Winchester
  */
 public final class REMStandardBeanTypeProxyFactory implements IStandardBeanTypeProxyFactory {
-	
+
 	protected final REMProxyFactoryRegistry fFactoryRegistry;
+
 	protected REMStandardBeanProxyFactory fBeanFactory;
-	
-	
+
 	// Hashtable to cache proxies for classes so they are found on second and subsequent lookups
 	protected Map fBeanProxies = new HashMap(1000);
-	
-	// A Cache of bean type proxies that should not ever be released.	These are the standard ones
+
+	// A Cache of bean type proxies that should not ever be released. These are the standard ones
 	// that we create here. They are never released because they wouldn't be correctly re-created
 	// if they were. Also they are standard ones with standard ID's that don't change so they
 	// don't need to be re-created later.
 	protected Set fPermanentProxies = new HashSet(30);
-	
+
 	// Cache of requested but not found bean types. If not maintaining the list, this variable will be null.
 	// The values are strings (classnames in JNI format).
-	protected Set fNotFoundTypes = null; 
+	protected Set fNotFoundTypes = null;
 
 	// Cached copy of a few typical bean type proxies.
 	REMBeanTypeProxy objectClass;
-	REMClassBeanTypeProxy classClass;	
+
+	REMClassBeanTypeProxy classClass;
+
 	REMVoidBeanTypeProxy voidType;
+
 	REMBooleanTypeBeanTypeProxy booleanType;
+
 	REMBooleanClassBeanTypeProxy booleanClass;
+
 	REMIntegerTypeBeanTypeProxy intType;
+
 	REMIntegerClassBeanTypeProxy integerClass;
+
 	REMByteTypeBeanTypeProxy byteType;
-	REMByteClassBeanTypeProxy byteClass;		
-	REMShortClassBeanTypeProxy shortClass;	
+
+	REMByteClassBeanTypeProxy byteClass;
+
+	REMShortClassBeanTypeProxy shortClass;
+
 	REMShortTypeBeanTypeProxy shortType;
-	REMLongClassBeanTypeProxy longClass;	
-	REMLongTypeBeanTypeProxy longType;	
-	REMDoubleClassBeanTypeProxy doubleClass;	
-	REMDoubleTypeBeanTypeProxy doubleType;	
-	REMFloatClassBeanTypeProxy floatClass;	
-	REMFloatTypeBeanTypeProxy floatType;	
-	REMBigDecimalBeanTypeProxy bigDecimalClass;		
-	REMBigIntegerBeanTypeProxy bigIntegerClass;		
+
+	REMLongClassBeanTypeProxy longClass;
+
+	REMLongTypeBeanTypeProxy longType;
+
+	REMDoubleClassBeanTypeProxy doubleClass;
+
+	REMDoubleTypeBeanTypeProxy doubleType;
+
+	REMFloatClassBeanTypeProxy floatClass;
+
+	REMFloatTypeBeanTypeProxy floatType;
+
+	REMBigDecimalBeanTypeProxy bigDecimalClass;
+
+	REMBigIntegerBeanTypeProxy bigIntegerClass;
+
 	REMCharacterTypeBeanTypeProxy charType;
-	REMCharacterClassBeanTypeProxy characterClass;	
+
+	REMCharacterClassBeanTypeProxy characterClass;
+
 	REMStringBeanTypeProxy stringClass;
-	
+
 	/**
 	 * Available to all REM beantypes.
 	 */
 	public REMProxyConstants proxyConstants;
 
-/**
- * IDEBeanTypeProxyFactory constructor comment.
- */
-REMStandardBeanTypeProxyFactory(REMProxyFactoryRegistry aRegistry) {
-	fFactoryRegistry = aRegistry;
-	aRegistry.registerBeanTypeProxyFactory(this);
-	
-	proxyConstants = new REMProxyConstants();
+	/**
+	 * IDEBeanTypeProxyFactory constructor comment.
+	 */
+	REMStandardBeanTypeProxyFactory(REMProxyFactoryRegistry aRegistry) {
+		fFactoryRegistry = aRegistry;
+		aRegistry.registerBeanTypeProxyFactory(this);
 
-	// Now initialize the cache.
-	objectClass = new REMBeanTypeProxy(fFactoryRegistry, new Integer(Commands.OBJECT_CLASS), Object.class.getName(), null);
-	classClass = new REMClassBeanTypeProxy(fFactoryRegistry, objectClass);		
-	voidType = new REMVoidBeanTypeProxy(fFactoryRegistry);
-	booleanType = new REMBooleanTypeBeanTypeProxy(fFactoryRegistry);
-	booleanClass = new REMBooleanClassBeanTypeProxy(fFactoryRegistry, objectClass);
-	IBeanTypeProxy numberClass = objectClass.newBeanTypeForClass(new Integer(Commands.NUMBER_CLASS), Number.class.getName(), true);
-	intType = new REMIntegerTypeBeanTypeProxy(fFactoryRegistry);
-	integerClass = new REMIntegerClassBeanTypeProxy(fFactoryRegistry, numberClass);
-	byteType = new REMByteTypeBeanTypeProxy(fFactoryRegistry);
-	byteClass = new REMByteClassBeanTypeProxy(fFactoryRegistry, numberClass);	
-	shortType = new REMShortTypeBeanTypeProxy(fFactoryRegistry);
-	shortClass = new REMShortClassBeanTypeProxy(fFactoryRegistry, numberClass);
-	longType = new REMLongTypeBeanTypeProxy(fFactoryRegistry);
-	longClass = new REMLongClassBeanTypeProxy(fFactoryRegistry, numberClass);
-	doubleType = new REMDoubleTypeBeanTypeProxy(fFactoryRegistry);
-	doubleClass = new REMDoubleClassBeanTypeProxy(fFactoryRegistry, numberClass);
-	floatType = new REMFloatTypeBeanTypeProxy(fFactoryRegistry);
-	floatClass = new REMFloatClassBeanTypeProxy(fFactoryRegistry, numberClass);					
-	bigDecimalClass = new REMBigDecimalBeanTypeProxy(fFactoryRegistry, numberClass);	
-	bigIntegerClass = new REMBigIntegerBeanTypeProxy(fFactoryRegistry, numberClass);		
-	charType = new REMCharacterTypeBeanTypeProxy(fFactoryRegistry);	
-	characterClass = new REMCharacterClassBeanTypeProxy(fFactoryRegistry, objectClass);
-	stringClass = new REMStringBeanTypeProxy(fFactoryRegistry, objectClass);
-	IBeanTypeProxy throwableClass = new REMThrowableBeanTypeProxy(fFactoryRegistry, new Integer(Commands.THROWABLE_CLASS), Throwable.class.getName(), objectClass);
-	IBeanTypeProxy threadClass = objectClass.newBeanTypeForClass(new Integer(Commands.THREAD_CLASS), Thread.class.getName(), false);
+		proxyConstants = new REMProxyConstants(aRegistry);
 
-	// Initialize the hashtable with the primitives, their lang equivalents, and also common classes like String
+		// Now initialize the cache.
+		objectClass = new REMBeanTypeProxy(fFactoryRegistry, new Integer(Commands.OBJECT_CLASS), Object.class.getName(), null);
+		classClass = new REMClassBeanTypeProxy(fFactoryRegistry, objectClass);
+		voidType = new REMVoidBeanTypeProxy(fFactoryRegistry);
+		booleanType = new REMBooleanTypeBeanTypeProxy(fFactoryRegistry);
+		booleanClass = new REMBooleanClassBeanTypeProxy(fFactoryRegistry, objectClass);
+		IBeanTypeProxy numberClass = objectClass.newBeanTypeForClass(new Integer(Commands.NUMBER_CLASS), Number.class.getName(), true);
+		intType = new REMIntegerTypeBeanTypeProxy(fFactoryRegistry);
+		integerClass = new REMIntegerClassBeanTypeProxy(fFactoryRegistry, numberClass);
+		byteType = new REMByteTypeBeanTypeProxy(fFactoryRegistry);
+		byteClass = new REMByteClassBeanTypeProxy(fFactoryRegistry, numberClass);
+		shortType = new REMShortTypeBeanTypeProxy(fFactoryRegistry);
+		shortClass = new REMShortClassBeanTypeProxy(fFactoryRegistry, numberClass);
+		longType = new REMLongTypeBeanTypeProxy(fFactoryRegistry);
+		longClass = new REMLongClassBeanTypeProxy(fFactoryRegistry, numberClass);
+		doubleType = new REMDoubleTypeBeanTypeProxy(fFactoryRegistry);
+		doubleClass = new REMDoubleClassBeanTypeProxy(fFactoryRegistry, numberClass);
+		floatType = new REMFloatTypeBeanTypeProxy(fFactoryRegistry);
+		floatClass = new REMFloatClassBeanTypeProxy(fFactoryRegistry, numberClass);
+		bigDecimalClass = new REMBigDecimalBeanTypeProxy(fFactoryRegistry, numberClass);
+		bigIntegerClass = new REMBigIntegerBeanTypeProxy(fFactoryRegistry, numberClass);
+		charType = new REMCharacterTypeBeanTypeProxy(fFactoryRegistry);
+		characterClass = new REMCharacterClassBeanTypeProxy(fFactoryRegistry, objectClass);
+		stringClass = new REMStringBeanTypeProxy(fFactoryRegistry, objectClass);
+		IBeanTypeProxy throwableClass = new REMThrowableBeanTypeProxy(fFactoryRegistry, new Integer(Commands.THROWABLE_CLASS), Throwable.class
+				.getName(), objectClass);
+		IBeanTypeProxy threadClass = objectClass.newBeanTypeForClass(new Integer(Commands.THREAD_CLASS), Thread.class.getName(), false);
 
-	// Primitives
-	fBeanProxies.put(voidType.getTypeName(), voidType);
-	fBeanProxies.put(intType.getTypeName(), intType);
-	fBeanProxies.put(booleanType.getTypeName(), booleanType);
-	fBeanProxies.put(charType.getTypeName(), charType);
-	fBeanProxies.put(byteType.getTypeName(), byteType);
-	fBeanProxies.put(shortType.getTypeName(), shortType);
-	fBeanProxies.put(longType.getTypeName(), longType);
-	fBeanProxies.put(floatType.getTypeName(), floatType);
-	fBeanProxies.put(doubleType.getTypeName(), doubleType);
+		// Initialize the hashtable with the primitives, their lang equivalents, and also common classes like String
 
-	// java.lang primitive peers
-	// Note that special classes are used for some of these which allow the IDE to get the
-	// lang objects from the objects that are holding proxies
-	fBeanProxies.put(integerClass.getTypeName(), integerClass);
-	fBeanProxies.put(booleanClass.getTypeName(), booleanClass);
-	fBeanProxies.put(characterClass.getTypeName(), characterClass);
-	fBeanProxies.put(byteClass.getTypeName(), byteClass);
-	fBeanProxies.put(shortClass.getTypeName(), shortClass);
-	fBeanProxies.put(longClass.getTypeName(), longClass);
-	fBeanProxies.put(floatClass.getTypeName(), floatClass);
-	fBeanProxies.put(doubleClass.getTypeName(), doubleClass);
-	fBeanProxies.put(bigDecimalClass.getTypeName(), bigDecimalClass);
-	fBeanProxies.put(bigIntegerClass.getTypeName(), bigIntegerClass);
-	fBeanProxies.put(stringClass.getTypeName(), stringClass);
-	fBeanProxies.put(throwableClass.getTypeName(), throwableClass);
-	fBeanProxies.put(objectClass.getTypeName(), objectClass);
-	fBeanProxies.put(classClass.getTypeName(), classClass);
-	fBeanProxies.put(numberClass.getTypeName(), numberClass);	
-	fBeanProxies.put(threadClass.getTypeName(), threadClass);
-	
-	// Mark these as permanent.
-	fPermanentProxies.addAll(fBeanProxies.values());
-}
+		// Primitives
+		fBeanProxies.put(voidType.getTypeName(), voidType);
+		fBeanProxies.put(intType.getTypeName(), intType);
+		fBeanProxies.put(booleanType.getTypeName(), booleanType);
+		fBeanProxies.put(charType.getTypeName(), charType);
+		fBeanProxies.put(byteType.getTypeName(), byteType);
+		fBeanProxies.put(shortType.getTypeName(), shortType);
+		fBeanProxies.put(longType.getTypeName(), longType);
+		fBeanProxies.put(floatType.getTypeName(), floatType);
+		fBeanProxies.put(doubleType.getTypeName(), doubleType);
 
-/**
- * Initialize AFTER BeanProxyFactory has been created. This is REQUIRED!
- * NOTE: It is package protected so that only REMStandardBeanProxyFactory can call it when ready.
- */
-synchronized void initialize(REMStandardBeanProxyFactory proxyFactory) {
-	fBeanFactory = proxyFactory;
-	fBeanFactory.registerProxies(fBeanProxies.values());
-}
-	
-	
-/*
- * This is called when we know we don't have the class registered, so
- * we need to create the proxy. We have a connection passed in and will reuse it as necessary
- * 
- * It is important that this be called only from within a transaction.
- */
-private synchronized IREMBeanTypeProxy createBeanTypeProxy(String typeName, IREMConnection connection) throws CommandException {
-	
-	// We don't have the beantype proxy, so create it.	
-	IREMBeanTypeProxy beanTypeProxy = null;
-	Commands.GetClassReturn ret = null;
-	try {
-		ret = getClassReturn(connection, typeName);
-	} catch (ThrowableProxy ep) {
-		// Print out the trace and return proxy with init error.
-		ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", ep)); //$NON-NLS-1$
-		IREMBeanTypeProxy proxy = new REMInitErrorBeanTypeProxy(fFactoryRegistry, MessageFormat.format(ProxyRemoteMessages.getString("ExceptionErrorMsg_EXC_"), new Object[] {ep.getTypeProxy().getTypeName(), ep.getProxyLocalizedMessage()}), typeName); //$NON-NLS-1$
-		registerBeanTypeProxy(proxy, false);
-		return proxy;
-	}
-	if (ret == null) {
-		if (fNotFoundTypes != null)
-			fNotFoundTypes.add(typeName);
-		return null;	// The class doesn't even exist on the server.
+		// java.lang primitive peers
+		// Note that special classes are used for some of these which allow the IDE to get the
+		// lang objects from the objects that are holding proxies
+		fBeanProxies.put(integerClass.getTypeName(), integerClass);
+		fBeanProxies.put(booleanClass.getTypeName(), booleanClass);
+		fBeanProxies.put(characterClass.getTypeName(), characterClass);
+		fBeanProxies.put(byteClass.getTypeName(), byteClass);
+		fBeanProxies.put(shortClass.getTypeName(), shortClass);
+		fBeanProxies.put(longClass.getTypeName(), longClass);
+		fBeanProxies.put(floatClass.getTypeName(), floatClass);
+		fBeanProxies.put(doubleClass.getTypeName(), doubleClass);
+		fBeanProxies.put(bigDecimalClass.getTypeName(), bigDecimalClass);
+		fBeanProxies.put(bigIntegerClass.getTypeName(), bigIntegerClass);
+		fBeanProxies.put(stringClass.getTypeName(), stringClass);
+		fBeanProxies.put(throwableClass.getTypeName(), throwableClass);
+		fBeanProxies.put(objectClass.getTypeName(), objectClass);
+		fBeanProxies.put(classClass.getTypeName(), classClass);
+		fBeanProxies.put(numberClass.getTypeName(), numberClass);
+		fBeanProxies.put(threadClass.getTypeName(), threadClass);
+
+		// Mark these as permanent.
+		fPermanentProxies.addAll(fBeanProxies.values());
 	}
 
-	if (typeName.charAt(0) != '[') {
-		// It is not an array.
-		IREMBeanTypeProxy superTypeProxy = null;
-		if (!ret.isInterface && ret.superClassname.length() != 0) {
-			// Get the beantype proxy of the superclass.
-			superTypeProxy = getBeanTypeProxy(ret.superClassname, connection);
-		}
-			
-		// First check with the factory for the package of the class.
-		// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
-		// the package ended and the class started. This check is here in case the
-		// extension factory can handle this class but needs the id from the server to
-		// create it.
-		int packageIndex = typeName.lastIndexOf('.');
-		if (packageIndex != -1) {
-			String packageName = typeName.substring(0, packageIndex);
-			IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
-			if (packageFactory != null) {
-				beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName, new Integer(ret.classID), superTypeProxy);
-				if (beanTypeProxy != null) {
-					registerBeanTypeProxy(beanTypeProxy, false);
-					return beanTypeProxy;
-				}
-			}
-		}							
-		
-		if (ret.isInterface) {
-			// Interface never have a super type, so we will create a specific type.
-			beanTypeProxy = new REMInterfaceBeanTypeProxy(fFactoryRegistry, new Integer(ret.classID), typeName);
-		} else {		
-			// Ask the supertype
-			// to create a beantype proxy of the same beantype proxy class.
-			// This is so that any subclasses will get the same beantype proxy class
-			// for it if it is special.			
-			if (superTypeProxy != null)
-				beanTypeProxy = superTypeProxy.newBeanTypeForClass(new Integer(ret.classID), typeName, ret.isAbstract);
-		}
-	} else
-		beanTypeProxy = new REMArrayBeanTypeProxy(fFactoryRegistry, new Integer(ret.classID), typeName, objectClass);
-	 	
-	// Cache the instance so we can re-use it again
-	if (beanTypeProxy != null) 		
-		registerBeanTypeProxy(beanTypeProxy, false);
-	return beanTypeProxy;
-}
-/**
- * Using the helper class to find a class by name, then create the proxy.
- */
-public IBeanTypeProxy getBeanTypeProxy(String typeName) {
-	try {
-		return getBeanTypeProxy(MapTypes.getJNIFormatName(typeName), (IREMConnection) null);
-	} catch (CommandException e) {
-		// Try once more (we won't have received recoverable exceptions here, they were already caught and handled)
+	/**
+	 * Initialize AFTER BeanProxyFactory has been created. This is REQUIRED! NOTE: It is package protected so that only REMStandardBeanProxyFactory
+	 * can call it when ready.
+	 */
+	synchronized void initialize(REMStandardBeanProxyFactory proxyFactory) {
+		fBeanFactory = proxyFactory;
+		fBeanFactory.registerProxies(fBeanProxies.values());
+	}
+
+	/*
+	 * This is called when we know we don't have the class registered, so we need to create the proxy. We have a connection passed in and will reuse
+	 * it as necessary
+	 * 
+	 * It is important that this be called only from within a transaction.
+	 */
+	private synchronized IREMBeanTypeProxy createBeanTypeProxy(String typeName, IREMConnection connection) throws CommandException {
+
+		// We don't have the beantype proxy, so create it.
+		IREMBeanTypeProxy beanTypeProxy = null;
+		Commands.GetClassReturn ret = null;
 		try {
-			return getBeanTypeProxy(typeName, (IREMConnection) null);
-		} catch (CommandException eAgain) {
-			// Failed again.
-			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$
+			ret = getClassReturn(connection, typeName);
+		} catch (ThrowableProxy ep) {
+			// Print out the trace and return proxy with init error.
+			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", ep)); //$NON-NLS-1$
+			IREMBeanTypeProxy proxy = new REMInitErrorBeanTypeProxy(fFactoryRegistry, MessageFormat.format(ProxyRemoteMessages
+					.getString("ExceptionErrorMsg_EXC_"), new Object[] { ep.getTypeProxy().getTypeName(), ep.getProxyLocalizedMessage()}), typeName); //$NON-NLS-1$
+			registerBeanTypeProxy(proxy, false);
+			return proxy;
 		}
-	}
-	return null;
-}
-	
-/**
- * One that internally allows that we already have a connection to work with.
- * If the connection is null, then one will be created.
- * 
- * It is important that if the connection is not null, then we are in a transaction.
- */
-private synchronized IREMBeanTypeProxy getBeanTypeProxy(String typeName, IREMConnection inConnect) throws CommandException {	
+		if (ret == null) {
+			if (fNotFoundTypes != null)
+				fNotFoundTypes.add(typeName);
+			return null; // The class doesn't even exist on the server.
+		}
 
-	// See whether we already have the proxy for the argument name
-	IREMBeanTypeProxy beanTypeProxy = (IREMBeanTypeProxy) fBeanProxies.get(typeName);
-	if (beanTypeProxy != null) {
-		return beanTypeProxy;
-	}
+		if (typeName.charAt(0) != '[') {
+			// It is not an array.
+			IREMBeanTypeProxy superTypeProxy = null;
+			if (!ret.isInterface && ret.superClassname.length() != 0) {
+				// Get the beantype proxy of the superclass.
+				superTypeProxy = getBeanTypeProxy(ret.superClassname, connection);
+			}
 
-	// If not an array, then see if the package extension mechanism can find it.
-	// Do this here so that if it is found in the package extension we won't necessarily create an
-	// extra connection when not needed.
-	if (typeName.charAt(0) != '[') {
-		// It is not an array
-		// First check with the factory for the package of the class.
-		// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
-		// the package ended and the class started.
-		int packageIndex = typeName.lastIndexOf('.');
-		if (packageIndex != -1) {
-			String packageName = typeName.substring(0, packageIndex);
-			IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
-			if (packageFactory != null) {
-				beanTypeProxy = (IREMBeanTypeProxy) packageFactory.getExtensionBeanTypeProxy(typeName);
-				if (beanTypeProxy != null) {
-					registerBeanTypeProxy(beanTypeProxy, false);
-					return beanTypeProxy;
+			// First check with the factory for the package of the class.
+			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
+			// the package ended and the class started. This check is here in case the
+			// extension factory can handle this class but needs the id from the server to
+			// create it.
+			int packageIndex = typeName.lastIndexOf('.');
+			if (packageIndex != -1) {
+				String packageName = typeName.substring(0, packageIndex);
+				IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
+				if (packageFactory != null) {
+					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName, new Integer(ret.classID), superTypeProxy);
+					if (beanTypeProxy != null) {
+						registerBeanTypeProxy(beanTypeProxy, false);
+						return beanTypeProxy;
+					}
 				}
 			}
-		}
-	}
-	
-	IREMConnection connect = inConnect != null ? inConnect : fFactoryRegistry.getFreeConnection();
-	if (inConnect == null)
-		fBeanFactory.startTransaction();	// Start a transation.
-	try {
-		return createBeanTypeProxy(typeName, connect);
-	} catch (CommandException e) {
-		if (inConnect == null) {
-			// Need to close the connection, not return it.
-			fFactoryRegistry.closeConnection(connect);
-			connect = null;	// So that it won't be returned.
-		}
-		throw e;	// Pass it on up
-	} finally {
-		if (inConnect == null)
-			fBeanFactory.stopTransaction();
-		if (inConnect == null && connect != null)
-			fFactoryRegistry.returnConnection(connect);
-	}
-}
 
-/*
- * It is important this be called only from within a transaction.
- */
-private Commands.GetClassReturn getClassReturn(IREMConnection connection, String className) throws CommandException, ThrowableProxy {
-	try {
-		return connection.getClass(className);
-	} catch (CommandErrorException e) {
-		fBeanFactory.processErrorReturn(e);	// Let proxy factory handle the error return
-	}
-	return null;
-}
-
-/**
- * Return an Array type proxy for the given class name of
- * the specified dimensions. This is a helper method. The
- * same result can be gotton from getBeanTypeProxy.
- * e.g.
- *      getBeanTypeProxy("java.lang.Object", 3)
- *    is the same as:
- *      getBeanTypeProxy("[[[Ljava.lang.Object;")
- *
- *    They both result in a type of:
- *      Object [][][]
- *
- *    or
- *      getBeanTypeProxy("[Ljava.langObject;", 3)
- *    becomes
- *      Object [][][][]
- */
-public IBeanTypeProxy getBeanTypeProxy(String componentClassName, int dimensions) {
-	String jniComponentClassName = MapTypes.getJNIFormatName(componentClassName);
-	String compType = jniComponentClassName;
-	if (jniComponentClassName.charAt(0) != '[') {
-		// We're not already an array, so create correct template.
-		compType = (String) MapTypes.MAP_TYPENAME_TO_SHORTSIG.get(jniComponentClassName);
-		if (compType == null) {
-			// It is a class, and not a type.
-			compType = "L"+jniComponentClassName+";"; //$NON-NLS-1$ //$NON-NLS-2$
-		}
-	}
-	
-	// Now create it with the appropriate number of '[' in front.
-	StringBuffer buffer = new StringBuffer(dimensions+compType.length());
-	for (int i=0; i<dimensions; i++)
-		buffer.append('[');
-	buffer.append(compType);
-	return getBeanTypeProxy(buffer.toString());
-}
-
-/**
- * Get the bean type proxy from a class id. This means that a new class id
- * was sent back from the server that we don't have yet. We need to go ask
- * the server for information on this type so that we can create it.
- *
- * NOTE: This is package protected so that only the standard bean proxy factory
- * can call it. 
- * 
- * It is important that this has been called within a transaction.
- */
-IREMBeanTypeProxy createBeanTypeProxy(Integer classID) {
-	IREMConnection connect = fFactoryRegistry.getFreeConnection();	
-	try {
-		return createBeanTypeProxy(classID, connect);
-	} catch (CommandException e) {
-		if (e.isRecoverable()) {
-			// It is recoverable, print message, keep connection live and return it.
-			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
-		} else {
-			// Try again, close connection, get a new one.
-			fFactoryRegistry.closeConnection(connect);
-			connect = null;
-			connect = fFactoryRegistry.getFreeConnection();
-			try {
-				return createBeanTypeProxy(classID, connect);
-			} catch (CommandException eAgain) {
-				// Failed again. Close connection, don't return it.
-				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$
-				fFactoryRegistry.closeConnection(connect);
-				connect = null;
+			if (ret.isInterface) {
+				// Interface never have a super type, so we will create a specific type.
+				beanTypeProxy = new REMInterfaceBeanTypeProxy(fFactoryRegistry, new Integer(ret.classID), typeName);
+			} else {
+				// Ask the supertype
+				// to create a beantype proxy of the same beantype proxy class.
+				// This is so that any subclasses will get the same beantype proxy class
+				// for it if it is special.
+				if (superTypeProxy != null)
+					beanTypeProxy = superTypeProxy.newBeanTypeForClass(new Integer(ret.classID), typeName, ret.isAbstract);
 			}
-		}
-	} finally {
-		if (connect != null)
-			fFactoryRegistry.returnConnection(connect);
-	}
-	return null;
-}
+		} else
+			beanTypeProxy = new REMArrayBeanTypeProxy(fFactoryRegistry, new Integer(ret.classID), typeName, objectClass);
 
-/*
- * One that internally allows that we already have a connection to work with.
- * If the connection is null, then one will be created.
- * 
- * It is important this be called only from within a transaction.
- */
-private synchronized IREMBeanTypeProxy createBeanTypeProxy(Integer classID, IREMConnection connect) throws CommandException {	
-	// We don't have the beantype proxy, so create it.
-	IREMBeanTypeProxy beanTypeProxy = null;
-
-	Commands.GetClassIDReturn ret = null;
-	try {
-		ret = getClassIDReturn(connect, classID);
-	} catch (ThrowableProxy ep) {
-		// Just print out the trace and return proxy not found.
-		ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", ep)); //$NON-NLS-1$
-		return null;
-	}
-	
-	// If the signature is that of a class.
-	if (ret.className.charAt(0) != '[') {
-		// It is not an array.
-		IREMBeanTypeProxy superTypeProxy = null;
-		if (!ret.isInterface && ret.superClassname.length() != 0) {
-			// Get the beantype proxy of the superclass.
-			superTypeProxy = getBeanTypeProxy(ret.superClassname, connect);
-		}
-		
-		// First check with the factory for the package of the class.
-		// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
-		// the package ended and the class started.
-		int packageIndex = ret.className.lastIndexOf('.');
-		if (packageIndex != -1) {
-			String packageName = ret.className.substring(0, packageIndex);
-			IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
-			if (packageFactory != null) {
-				beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(ret.className, classID, superTypeProxy);
-				if (beanTypeProxy != null) {
-					registerBeanTypeProxy(beanTypeProxy, false);
-					return beanTypeProxy;
-				}
-			}
-		}	
-			
-		if (ret.isInterface) {
-			// Interface never have a super type, so we will let the object class do it for us.
-			beanTypeProxy = new REMInterfaceBeanTypeProxy(fFactoryRegistry, classID, ret.className);	
-		} else {		
-			// Ask the beantype proxy of the superclass 
-			// to create a beantype proxy of the same beantype proxy class.
-			// This is so that any subclasses will get the same beantype proxy class
-			// for it if it is special.			
-			if (superTypeProxy != null)
-				beanTypeProxy = superTypeProxy.newBeanTypeForClass(classID, ret.className, ret.isAbstract);
-		}
- 
 		// Cache the instance so we can re-use it again
-		if (beanTypeProxy != null)		
+		if (beanTypeProxy != null)
 			registerBeanTypeProxy(beanTypeProxy, false);
 		return beanTypeProxy;
-	} else {		
-		// It is an array.
-		beanTypeProxy = new REMArrayBeanTypeProxy(fFactoryRegistry, classID, ret.className, objectClass );
+	}
+
+	/**
+	 * Using the helper class to find a class by name, then create the proxy.
+	 */
+	public IBeanTypeProxy getBeanTypeProxy(String typeName) {
+		try {
+			return getBeanTypeProxy(MapTypes.getJNIFormatName(typeName), (IREMConnection) null);
+		} catch (CommandException e) {
+			// Try once more (we won't have received recoverable exceptions here, they were already caught and handled)
+			try {
+				return getBeanTypeProxy(typeName, (IREMConnection) null);
+			} catch (CommandException eAgain) {
+				// Failed again.
+				ProxyPlugin.getPlugin().getLogger().log(
+						new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IExpression,
+	 *      java.lang.String)
+	 */
+	public synchronized IProxyBeanType getBeanTypeProxy(IExpression expression, String typeName) {
+		typeName = MapTypes.getJNIFormatName(typeName);
+		// See whether we already have the proxy for the argument name
+		IProxyBeanType beanTypeProxy = (IProxyBeanType) fBeanProxies.get(typeName);
+		if (beanTypeProxy != null)
+			return beanTypeProxy;
+		
+		// Now see if an expression proxy cached.
+		beanTypeProxy = ((REMExpression) expression).getBeanType(typeName);
+		if (beanTypeProxy != null)
+			return beanTypeProxy;		
+
+		// If not an array, then see if the package extension mechanism can find it.
+		// Do this here so that if it is found in the package extension we won't necessarily create an
+		// extra connection when not needed.
+		if (typeName.charAt(0) != '[') {
+			// It is not an array
+			// First check with the factory for the package of the class.
+			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
+			// the package ended and the class started.
+			int packageIndex = typeName.lastIndexOf('.');
+			if (packageIndex != -1) {
+				String packageName = typeName.substring(0, packageIndex);
+				IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
+				if (packageFactory != null) {
+					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName, expression);
+					if (beanTypeProxy != null) {
+						registerBeanTypeProxy(beanTypeProxy, false);
+						return beanTypeProxy;
+					}
+				}
+			}
+		}
+
+		// Need to create the expression proxy for it.
+		beanTypeProxy = ((Expression) expression).createBeanTypeExpressionProxy(typeName);
 		registerBeanTypeProxy(beanTypeProxy, false);
 		return beanTypeProxy;
-	}	
-}
 
-/*
- * It is important that this be called only from within a transaction.
- */
-private Commands.GetClassIDReturn getClassIDReturn(IREMConnection connection, Integer classID) throws CommandException, ThrowableProxy {
-	try {
-		return connection.getClassFromID(classID.intValue());
-	} catch (CommandErrorException e) {
-		fBeanFactory.processErrorReturn(e);	// Let proxy factory handle the error return
 	}
-	return null;
-}
 
+	/**
+	 * One that internally allows that we already have a connection to work with. If the connection is null, then one will be created.
+	 * 
+	 * It is important that if the connection is not null, then we are in a transaction.
+	 */
+	private synchronized IREMBeanTypeProxy getBeanTypeProxy(String typeName, IREMConnection inConnect) throws CommandException {
 
+		// See whether we already have the proxy for the argument name
+		IProxyBeanType beanTypeProxy = (IProxyBeanType) fBeanProxies.get(typeName);
+		// See if there and resolved, if so, return it. If not resolved, that means we need it NOW
+		// so we must go for it. When finally resolved the original ExpressionProxy will be deregistered and
+		// the resolved beantypeproxy will be in its place.
+		if (beanTypeProxy != null && beanTypeProxy.isBeanProxy()) { return (IREMBeanTypeProxy) beanTypeProxy; }
 
-/**
- * registerBeanTypeProxy.
- * Register this bean type proxy on behalf of the
- * custom factory. This is so that during initializations,
- * the custom factory can cache specific bean type proxies
- * ahead of time. 
- *
- * The permanent flag indicates whether this bean type should never be
- * released (i.e. not even explicitly released).
- */
-public synchronized void registerBeanTypeProxy(IBeanTypeProxy aBeanTypeProxy, boolean permanent) {
-	fBeanProxies.put(aBeanTypeProxy.getTypeName(), aBeanTypeProxy);
-	fBeanFactory.registerProxy((IREMBeanProxy) aBeanTypeProxy);
-	if (permanent)
-		fPermanentProxies.add(aBeanTypeProxy);
-}
+		// If not an array, then see if the package extension mechanism can find it.
+		// Do this here so that if it is found in the package extension we won't necessarily create an
+		// extra connection when not needed.
+		if (typeName.charAt(0) != '[') {
+			// It is not an array
+			// First check with the factory for the package of the class.
+			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
+			// the package ended and the class started.
+			int packageIndex = typeName.lastIndexOf('.');
+			if (packageIndex != -1) {
+				String packageName = typeName.substring(0, packageIndex);
+				IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
+				if (packageFactory != null) {
+					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName);
+					if (beanTypeProxy != null) {
+						registerBeanTypeProxy((IREMBeanTypeProxy) beanTypeProxy, false);
+						return (IREMBeanTypeProxy) beanTypeProxy;
+					}
+				}
+			}
+		}
 
-/**
- * A beantype proxy is asked to be released. We can only
- * release ones that were not in the permanent set that we 
- * initialized with. Those in the permanent set can't be changed
- * so we can't release them. 
- *
- * Answer whether it can be released from the server
- * too.
- *
- * NOTE: Package protected since only REMStandardBeanProxyFactory should call it.
- */
-boolean releaseProxy(IBeanTypeProxy proxy) {
-/** Currently we won't allow any bean type proxies to be released. We don't have a good
- *  strategy for handling that there may be hard refs from subtypes. One thought is that
- *  beanproxies table should store SoftReferences so that only when space is needed, 
- *  that any beantype that doesn't have a subtype (since subtypes hold a strong ref) or,
- *  is in the permanent table (since that is hardref) could be GC'd. Then what would happen
- *  is on releaseProxy we don't actually release, we change it to a WeakRef so that it would
- *  definitely be released on a GC. These are complicated arch. and we're not sure if it
- *  should be allowed or not. So for now, we don't allow them to be released.
-	if (!fPermanentProxies.contains(proxy)) {
-		// We can release it. It is not one of the permanent ones.
-		synchronized(this) {
-			fBeanProxies.remove(proxy.getTypeName());
-			return true;
+		IREMConnection connect = inConnect != null ? inConnect : fFactoryRegistry.getFreeConnection();
+		if (inConnect == null)
+			fBeanFactory.startTransaction(); // Start a transation.
+		try {
+			return createBeanTypeProxy(typeName, connect);
+		} catch (CommandException e) {
+			if (inConnect == null) {
+				// Need to close the connection, not return it.
+				fFactoryRegistry.closeConnection(connect);
+				connect = null; // So that it won't be returned.
+			}
+			throw e; // Pass it on up
+		} finally {
+			if (inConnect == null)
+				fBeanFactory.stopTransaction();
+			if (inConnect == null && connect != null)
+				fFactoryRegistry.returnConnection(connect);
 		}
 	}
-*/	
-	return false;
-}
 
-/*
- * Terminate this factory. Since all of the proxies are registered in the
- * proxy factory, there is no need to release them here. There is no
- * need to clear out any fields since this factory will not be held onto
- * by anything and so it will be GC'd.
- */
-public void terminateFactory(boolean wait) {
-}
+	/*
+	 * It is important this be called only from within a transaction.
+	 */
+	private Commands.GetClassReturn getClassReturn(IREMConnection connection, String className) throws CommandException, ThrowableProxy {
+		try {
+			return connection.getClass(className);
+		} catch (CommandErrorException e) {
+			fBeanFactory.processErrorReturn(e); // Let proxy factory handle the error return
+		}
+		return null;
+	}
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeRegistered(String)
- */
-public synchronized boolean isBeanTypeRegistered(String className) {
-	return fBeanProxies.containsKey(MapTypes.getJNIFormatName(className));
-}
+	/**
+	 * Return an Array type proxy for the given class name of the specified dimensions. This is a helper method. The same result can be gotton from
+	 * getBeanTypeProxy. e.g. getBeanTypeProxy("java.lang.Object", 3) is the same as: getBeanTypeProxy("[[[Ljava.lang.Object;")
+	 * 
+	 * They both result in a type of: Object [][][]
+	 * 
+	 * or getBeanTypeProxy("[Ljava.langObject;", 3) becomes Object [][][][]
+	 */
+	public IBeanTypeProxy getBeanTypeProxy(String componentClassName, int dimensions) {
+		return getBeanTypeProxy(getArrayClassName(componentClassName, dimensions));
+	}
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registeredTypes()
- */
-public Set registeredTypes() {
-	return fBeanProxies.keySet();
-}
+	/**
+	 * @param componentClassName
+	 * @param dimensions
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	private String getArrayClassName(String componentClassName, int dimensions) {
+		String jniComponentClassName = MapTypes.getJNIFormatName(componentClassName);
+		String compType = jniComponentClassName;
+		if (jniComponentClassName.charAt(0) != '[') {
+			// We're not already an array, so create correct template.
+			compType = (String) MapTypes.MAP_TYPENAME_TO_SHORTSIG.get(jniComponentClassName);
+			if (compType == null) {
+				// It is a class, and not a type.
+				compType = "L" + jniComponentClassName + ";"; //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeNotFound(String)
- */
-public synchronized boolean isBeanTypeNotFound(String className) {
-	return fNotFoundTypes != null && fNotFoundTypes.contains(MapTypes.getJNIFormatName(className));
-}
+		// Now create it with the appropriate number of '[' in front.
+		StringBuffer buffer = new StringBuffer(dimensions + compType.length());
+		for (int i = 0; i < dimensions; i++)
+			buffer.append('[');
+		buffer.append(compType);
+		return buffer.toString();
+	}
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isMaintainNotFoundTypes()
- */
-public synchronized boolean isMaintainNotFoundTypes() {
-	return fNotFoundTypes != null;
-}
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IExpression,
+	 *      java.lang.String, int)
+	 */
+	public IProxyBeanType getBeanTypeProxy(IExpression expression, String componentClassName, int dimensions) {
+		return getBeanTypeProxy(expression, getArrayClassName(componentClassName, dimensions));
+	}
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#setMaintainNotFoundTypes(boolean)
- */
-public synchronized void setMaintainNotFoundTypes(boolean maintain) {
-	if (maintain) {
-		if (fNotFoundTypes == null)
-			fNotFoundTypes = new HashSet();
-	} else
-		fNotFoundTypes = null;
-}
+	/**
+	 * Get the bean type proxy from a class id. This means that a new class id was sent back from the server that we don't have yet. We need to go ask
+	 * the server for information on this type so that we can create it.
+	 * 
+	 * NOTE: This is package protected so that only the standard bean proxy factory can call it.
+	 * 
+	 * It is important that this has been called within a transaction.
+	 */
+	IREMBeanTypeProxy createBeanTypeProxy(Integer classID) {
+		IREMConnection connect = fFactoryRegistry.getFreeConnection();
+		try {
+			return createBeanTypeProxy(classID, connect);
+		} catch (CommandException e) {
+			if (e.isRecoverable()) {
+				// It is recoverable, print message, keep connection live and return it.
+				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
+			} else {
+				// Try again, close connection, get a new one.
+				fFactoryRegistry.closeConnection(connect);
+				connect = null;
+				connect = fFactoryRegistry.getFreeConnection();
+				try {
+					return createBeanTypeProxy(classID, connect);
+				} catch (CommandException eAgain) {
+					// Failed again. Close connection, don't return it.
+					ProxyPlugin.getPlugin().getLogger().log(
+							new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$
+					fFactoryRegistry.closeConnection(connect);
+					connect = null;
+				}
+			}
+		} finally {
+			if (connect != null)
+				fFactoryRegistry.returnConnection(connect);
+		}
+		return null;
+	}
+
+	/*
+	 * One that internally allows that we already have a connection to work with. If the connection is null, then one will be created.
+	 * 
+	 * It is important this be called only from within a transaction.
+	 */
+	private synchronized IREMBeanTypeProxy createBeanTypeProxy(Integer classID, IREMConnection connect) throws CommandException {
+		// We don't have the beantype proxy, so create it.
+		IREMBeanTypeProxy beanTypeProxy = null;
+
+		Commands.GetClassIDReturn ret = null;
+		try {
+			ret = getClassIDReturn(connect, classID);
+		} catch (ThrowableProxy ep) {
+			// Just print out the trace and return proxy not found.
+			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", ep)); //$NON-NLS-1$
+			return null;
+		}
+
+		// If the signature is that of a class.
+		if (ret.className.charAt(0) != '[') {
+			// It is not an array.
+			IREMBeanTypeProxy superTypeProxy = null;
+			if (!ret.isInterface && ret.superClassname.length() != 0) {
+				// Get the beantype proxy of the superclass.
+				superTypeProxy = getBeanTypeProxy(ret.superClassname, connect);
+			}
+
+			// First check with the factory for the package of the class.
+			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
+			// the package ended and the class started.
+			int packageIndex = ret.className.lastIndexOf('.');
+			if (packageIndex != -1) {
+				String packageName = ret.className.substring(0, packageIndex);
+				IREMBeanTypeProxyFactory packageFactory = (IREMBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
+				if (packageFactory != null) {
+					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(ret.className, classID, superTypeProxy);
+					if (beanTypeProxy != null) {
+						registerBeanTypeProxy(beanTypeProxy, false);
+						return beanTypeProxy;
+					}
+				}
+			}
+
+			if (ret.isInterface) {
+				// Interface never have a super type, so we will let the object class do it for us.
+				beanTypeProxy = new REMInterfaceBeanTypeProxy(fFactoryRegistry, classID, ret.className);
+			} else {
+				// Ask the beantype proxy of the superclass
+				// to create a beantype proxy of the same beantype proxy class.
+				// This is so that any subclasses will get the same beantype proxy class
+				// for it if it is special.
+				if (superTypeProxy != null)
+					beanTypeProxy = superTypeProxy.newBeanTypeForClass(classID, ret.className, ret.isAbstract);
+			}
+
+			// Cache the instance so we can re-use it again
+			if (beanTypeProxy != null)
+				registerBeanTypeProxy(beanTypeProxy, false);
+			return beanTypeProxy;
+		} else {
+			// It is an array.
+			beanTypeProxy = new REMArrayBeanTypeProxy(fFactoryRegistry, classID, ret.className, objectClass);
+			registerBeanTypeProxy(beanTypeProxy, false);
+			return beanTypeProxy;
+		}
+	}
+
+	/*
+	 * It is important that this be called only from within a transaction.
+	 */
+	private Commands.GetClassIDReturn getClassIDReturn(IREMConnection connection, Integer classID) throws CommandException, ThrowableProxy {
+		try {
+			return connection.getClassFromID(classID.intValue());
+		} catch (CommandErrorException e) {
+			fBeanFactory.processErrorReturn(e); // Let proxy factory handle the error return
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registerBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IBeanTypeProxy,
+	 *      boolean)
+	 */
+	public synchronized void registerBeanTypeProxy(IBeanTypeProxy aBeanTypeProxy, boolean permanent) {
+		fBeanProxies.put(aBeanTypeProxy.getTypeName(), aBeanTypeProxy);
+		fBeanFactory.registerProxy((IREMBeanProxy) aBeanTypeProxy);
+		if (permanent)
+			fPermanentProxies.add(aBeanTypeProxy);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registerBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType,
+	 *      boolean)
+	 */
+	public void registerBeanTypeProxy(IProxyBeanType aProxyBeanType, final boolean permanent) {
+		if (aProxyBeanType.isBeanProxy())
+			registerBeanTypeProxy((IBeanTypeProxy) aProxyBeanType, permanent); // A regular kind, do regular registration.
+		else {
+			ExpressionProxy beanExpressionProxy = ((ExpressionProxy) aProxyBeanType);
+			final String typeName = aProxyBeanType.getTypeName();
+			((REMExpression) beanExpressionProxy.getExpression()).addBeanType(typeName, aProxyBeanType);
+			beanExpressionProxy.addProxyListener(new ExpressionProxy.ProxyAdapter() {
+
+				public void proxyResolved(ProxyEvent event) {
+					String typeName = ((IProxyBeanType) event.getSource()).getTypeName();
+					synchronized (REMStandardBeanTypeProxyFactory.this) {
+						if (!fBeanProxies.containsKey(typeName)) {
+							// It hasn't been resolved through some other means. So this is good. Actually this should never
+							// occur because upon resolution we've already registered the bean type proxy through the
+							// normal mechanisms. But to be safe, we'll do it here.
+							fBeanProxies.put(typeName, event.getProxy());
+							if (permanent)
+								fPermanentProxies.add(event.getProxy());
+						}
+					}
+				}
+				
+				public void proxyNotResolved(ExpressionProxy.ProxyEvent event) {
+					((REMExpression) ((ExpressionProxy) event.getSource()).getExpression()).removeBeanType(typeName);
+				}
+			});
+		}
+
+	}
+
+	/**
+	 * A beantype proxy is asked to be released. We can only release ones that were not in the permanent set that we initialized with. Those in the
+	 * permanent set can't be changed so we can't release them.
+	 * 
+	 * Answer whether it can be released from the server too.
+	 * 
+	 * NOTE: Package protected since only REMStandardBeanProxyFactory should call it.
+	 */
+	boolean releaseProxy(IBeanTypeProxy proxy) {
+		/**
+		 * Currently we won't allow any bean type proxies to be released. We don't have a good strategy for handling that there may be hard refs from
+		 * subtypes. One thought is that beanproxies table should store SoftReferences so that only when space is needed, that any beantype that
+		 * doesn't have a subtype (since subtypes hold a strong ref) or, is in the permanent table (since that is hardref) could be GC'd. Then what
+		 * would happen is on releaseProxy we don't actually release, we change it to a WeakRef so that it would definitely be released on a GC. These
+		 * are complicated arch. and we're not sure if it should be allowed or not. So for now, we don't allow them to be released. if
+		 * (!fPermanentProxies.contains(proxy)) { // We can release it. It is not one of the permanent ones. synchronized(this) {
+		 * fBeanProxies.remove(proxy.getTypeName()); return true; } }
+		 */
+		return false;
+	}
+
+	/*
+	 * Terminate this factory. Since all of the proxies are registered in the proxy factory, there is no need to release them here. There is no need
+	 * to clear out any fields since this factory will not be held onto by anything and so it will be GC'd.
+	 */
+	public void terminateFactory(boolean wait) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeRegistered(String)
+	 */
+	public synchronized boolean isBeanTypeRegistered(String className) {
+		return fBeanProxies.containsKey(MapTypes.getJNIFormatName(className));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registeredTypes()
+	 */
+	public Set registeredTypes() {
+		return fBeanProxies.keySet();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeNotFound(String)
+	 */
+	public synchronized boolean isBeanTypeNotFound(String className) {
+		return fNotFoundTypes != null && fNotFoundTypes.contains(MapTypes.getJNIFormatName(className));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isMaintainNotFoundTypes()
+	 */
+	public synchronized boolean isMaintainNotFoundTypes() {
+		return fNotFoundTypes != null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#setMaintainNotFoundTypes(boolean)
+	 */
+	public synchronized void setMaintainNotFoundTypes(boolean maintain) {
+		if (maintain) {
+			if (fNotFoundTypes == null)
+				fNotFoundTypes = new HashSet();
+		} else
+			fNotFoundTypes = null;
+	}
 
 }
 
-
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMThrowableBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMThrowableBeanProxy.java
index 7c1f4c7..dc1df12 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMThrowableBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMThrowableBeanProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.remote;
 /*
  *  $RCSfile: REMThrowableBeanProxy.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -193,4 +193,16 @@
 		value.setObjectID(getID().intValue());
 	}
 	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isBeanProxy()
+	 */
+	public final boolean isBeanProxy() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isExpressionProxy()
+	 */
+	public final boolean isExpressionProxy() {
+		return false;
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/awt/REMRegisterAWT.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/awt/REMRegisterAWT.java
index e2a50c6..f32af80 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/awt/REMRegisterAWT.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/awt/REMRegisterAWT.java
@@ -11,9 +11,11 @@
  *******************************************************************************/
 /*
  *  $RCSfile: REMRegisterAWT.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
+import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
+import org.eclipse.jem.internal.proxy.core.IMethodProxy;
 import org.eclipse.jem.internal.proxy.remote.REMProxyFactoryRegistry;
 /**
  * This class is used to register the AWT factories. It is not
@@ -23,5 +25,14 @@
 	public static void registerAWT(REMProxyFactoryRegistry registry) {
 		new REMStandardAWTBeanTypeProxyFactory(registry);
 		new REMStandardAWTBeanProxyFactory(registry);
+		
+		// If we are doing AWT, get the AWT event queue going. This is trying to be a time-saver
+		// by having it up right away.
+		IBeanTypeProxy starterBeanType = registry.getBeanTypeProxyFactory().getBeanTypeProxy("org.eclipse.jem.internal.proxy.vm.remote.AWTStarter");
+		if (starterBeanType != null) {
+			IMethodProxy starter = starterBeanType.getMethodProxy("startAWT");
+			if (starter != null)
+				starter.invokeCatchThrowableExceptions(null);
+		}
 	}
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/awt/REMStandardAWTBeanTypeProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/awt/REMStandardAWTBeanTypeProxyFactory.java
index d857878..263068d 100644
--- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/awt/REMStandardAWTBeanTypeProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/awt/REMStandardAWTBeanTypeProxyFactory.java
@@ -1,4 +1,3 @@
-package org.eclipse.jem.internal.proxy.remote.awt;
 /*******************************************************************************
  * Copyright (c)  2001, 2003, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials 
@@ -11,56 +10,73 @@
  *******************************************************************************/
 /*
  *  $RCSfile: REMStandardAWTBeanTypeProxyFactory.java,v $
- *  $Revision: 1.3 $  $Date: 2005/02/15 22:56:10 $ 
+ *  $Revision: 1.4 $  $Date: 2005/05/11 19:01:12 $ 
  */
+package org.eclipse.jem.internal.proxy.remote.awt;
 
+
+import org.eclipse.jem.internal.proxy.core.*;
 import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
 import org.eclipse.jem.internal.proxy.remote.*;
+
 /**
- * BeanType factory standard AWT bean types.
- * This is package protected because it shouldn't be
- * referenced outside the package. It should only be accessed through
- * the interface.
+ * BeanType factory standard AWT bean types. This is package protected because it shouldn't be referenced outside the package. It should only be
+ * accessed through the interface.
  */
 class REMStandardAWTBeanTypeProxyFactory implements IREMBeanTypeProxyFactory {
 
 	static final String BEAN_TYPE_FACTORY_KEY = "java.awt"; //$NON-NLS-1$
-	
+
 	protected final REMProxyFactoryRegistry fFactoryRegistry;
-	
+
 	REMStandardAWTBeanTypeProxyFactory(REMProxyFactoryRegistry aRegistry) {
-		fFactoryRegistry = aRegistry;	
+		fFactoryRegistry = aRegistry;
 		fFactoryRegistry.registerBeanTypeProxyFactory(BEAN_TYPE_FACTORY_KEY, this);
 	}
-	
-	/**
-	 * We don't pre-cache any types. We need to have the
-	 * id from the server to create types.
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.remote.IREMBeanTypeProxyFactory#getExtensionBeanTypeProxy(java.lang.String)
 	 */
-	public IREMBeanTypeProxy getExtensionBeanTypeProxy(String className){
+	public IREMBeanTypeProxy getExtensionBeanTypeProxy(String className) {
 		return null;
 	}
-	
-	/**
-	 * Create the correct beantype from the class and id passed in.
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.remote.IREMBeanTypeProxyFactory#getExtensionBeanTypeProxy(java.lang.String, java.lang.Integer,
+	 *      org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
 	 */
-	public IREMBeanTypeProxy getExtensionBeanTypeProxy(String className, Integer classID, IBeanTypeProxy superType){
-		
+	public IREMBeanTypeProxy getExtensionBeanTypeProxy(String className, Integer classID, IBeanTypeProxy superType) {
+
 		if ("java.awt.Dimension".equals(className)) //$NON-NLS-1$
 			return new REMDimensionBeanTypeProxy(fFactoryRegistry, classID, className, superType);
 		else if ("java.awt.Point".equals(className)) //$NON-NLS-1$
-			return new REMPointBeanTypeProxy(fFactoryRegistry, classID, className, superType);			
+			return new REMPointBeanTypeProxy(fFactoryRegistry, classID, className, superType);
 		else if ("java.awt.Rectangle".equals(className)) //$NON-NLS-1$
 			return new REMRectangleBeanTypeProxy(fFactoryRegistry, classID, className, superType);
-		else 
+		else
 			return null;
 	}
-	
+
 	/*
-	 * Terminate this factory. Since it doesn't hold onto anything other than the registry,
-	 * and nothing will be holding onto this factory, nothing needs to be done. It will be GC'd.
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.remote.IREMBeanTypeProxyFactory#getExtensionBeanTypeProxy(java.lang.String,
+	 *      org.eclipse.jem.internal.proxy.core.IExpression)
+	 */
+	public IProxyBeanType getExtensionBeanTypeProxy(String typeName, IExpression expression) {
+		return getExtensionBeanTypeProxy(typeName);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IBeanProxyFactory#terminateFactory(boolean)
 	 */
 	public void terminateFactory(boolean wait) {
-	}	
+	}
 
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEBeanProxy.java
index 5307b78..6e8f886 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEBeanProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.ide;
 /*
  *  $RCSfile: IDEBeanProxy.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import org.eclipse.jem.internal.proxy.core.*;
@@ -70,6 +70,11 @@
 		}
 		return false;
 	}
+	
+	public int hashCode() {
+		return 12345 + (getBean() != null ? getBean().hashCode() : 0); 
+	}
+	
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.IBeanProxy#sameAs(org.eclipse.jem.internal.proxy.core.IBeanProxy)
 	 */
@@ -81,4 +86,16 @@
 		return false;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isBeanProxy()
+	 */
+	public final boolean isBeanProxy() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isExpressionProxy()
+	 */
+	public final boolean isExpressionProxy() {
+		return false;
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEBeanTypeProxy.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEBeanTypeProxy.java
index 7975efa..b17587b 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEBeanTypeProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEBeanTypeProxy.java
@@ -9,7 +9,7 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 /*
- * $RCSfile: IDEBeanTypeProxy.java,v $ $Revision: 1.10 $ $Date: 2005/02/16 00:59:27 $
+ * $RCSfile: IDEBeanTypeProxy.java,v $ $Revision: 1.11 $ $Date: 2005/05/11 19:01:12 $
  */
 package org.eclipse.jem.internal.proxy.ide;
 
@@ -411,4 +411,37 @@
 		}
 		return ((IDEMethodProxyFactory) fProxyFactoryRegistry.getMethodProxyFactory()).getCompatibleMethod(fClass, methodName, argClasses);
 	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[])
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String methodName, IProxyBeanType[] parameterTypes) {
+		IProxyMethod method = ((IDEExpression) expression).getMethodExpressionProxy(this, methodName, parameterTypes);
+		if (method == null) {
+			// Need to go to the expression and create it.
+			method = ((Expression) expression).createMethodExpressionProxy(this, methodName, parameterTypes);
+		}
+		return method;
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String[])
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String methodName, String[] parameterTypes) {
+		return ((IDEMethodProxyFactory) fProxyFactoryRegistry.getMethodProxyFactory()).getMethodProxy(expression, this, methodName, parameterTypes);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String)
+	 */
+	public IProxyField getFieldProxy(IExpression expression, String fieldName) {
+		IProxyField field = ((IDEExpression) expression).getFieldExpressionProxy(this, fieldName);
+		if (field == null) {
+			// Need to go to the expression and create it.
+			field = ((Expression) expression).createFieldExpressionProxy(this, fieldName);
+		}
+		return field;
+	}
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDECallbackRegistry.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDECallbackRegistry.java
index a4c0d4c..3dbeb33 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDECallbackRegistry.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDECallbackRegistry.java
@@ -11,10 +11,11 @@
 package org.eclipse.jem.internal.proxy.ide;
 /*
  *  $RCSfile: IDECallbackRegistry.java,v $
- *  $Revision: 1.6 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.7 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.io.*;
+import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -22,6 +23,7 @@
 import org.eclipse.core.runtime.Status;
 
 import org.eclipse.jem.internal.proxy.core.*;
+import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent;
 
 public class IDECallbackRegistry implements ICallbackRegistry {
 	
@@ -31,10 +33,24 @@
 	Map fCallbackIDToCallback = new HashMap(25);
 	Map fBeanProxyToCallbackID = new HashMap(25);
 	Map fCallbackIDToStream = new HashMap(25);
+	private IProxyMethod initializeCallbackMethodProxy;
+	private IProxy vmServerProxy;
 	
 IDECallbackRegistry(IDEProxyFactoryRegistry aRegistry){
 	fProxyFactoryRegistry = aRegistry;
 	fVMServer = new IDEVMServer(this);
+	
+	vmServerProxy = aRegistry.getBeanProxy(fVMServer.getClass(), fVMServer);
+	
+	try {
+		Method initializeCallbackMethod = org.eclipse.jem.internal.proxy.common.ICallback.class.getMethod("initializeCallback", new Class[] {org.eclipse.jem.internal.proxy.common.IVMServer.class, Integer.TYPE});
+		initializeCallbackMethodProxy = (IProxyMethod) aRegistry.getBeanProxy(Method.class, initializeCallbackMethod);
+	} catch (SecurityException e) {
+		e.printStackTrace();
+	} catch (NoSuchMethodException e) {
+		e.printStackTrace();
+	}
+	
 }
 /**
  * Add a callback.  aBeanProxy is running on the target VM and ICallback runs on our VM
@@ -55,6 +71,26 @@
 
 }
 
+
+/* (non-Javadoc)
+ * @see org.eclipse.jem.internal.proxy.core.ICallbackRegistry#registerCallback(org.eclipse.jem.internal.proxy.core.IProxy, org.eclipse.jem.internal.proxy.core.ICallback, org.eclipse.jem.internal.proxy.core.IExpression)
+ */
+public void registerCallback(IProxy callbackProxy, final ICallback cb, IExpression expression) {
+	final Integer callbackID = new Integer(++fNextCallbackID);
+	fCallbackIDToCallback.put(callbackID, cb);
+	if (callbackProxy.isBeanProxy()) {
+		fBeanProxyToCallbackID.put(callbackProxy, callbackID);		
+	} else {
+		((ExpressionProxy) callbackProxy).addProxyListener(new ExpressionProxy.ProxyAdapter() {
+			public void proxyResolved(ProxyEvent event) {
+				fBeanProxyToCallbackID.put(event.getProxy(), callbackID);		
+			}
+		});
+	}
+	expression.createSimpleMethodInvoke(initializeCallbackMethodProxy, callbackProxy, new IProxy[] {vmServerProxy, fProxyFactoryRegistry.getBeanProxyFactory().createBeanProxyWith(callbackID.intValue())}, false);
+	
+}
+
 OutputStream requestStream(final int aCallbackID, final int aMsgID){
 	final PipedOutputStream result = new PipedOutputStream();
 	PipedInputStream tempStream = null;
@@ -106,8 +142,7 @@
 public void deregisterCallback(IBeanProxy aBeanProxy){
 	// Remove the callback from both maps.  The actual unregistering of the callback
 	// on the target VM is done separately by the object that added the event handler on the target VM
-	Integer callbackID = (Integer) fBeanProxyToCallbackID.get(aBeanProxy);
-	fBeanProxyToCallbackID.remove(aBeanProxy);
+	Integer callbackID = (Integer) fBeanProxyToCallbackID.remove(aBeanProxy);
 	fCallbackIDToCallback.remove(callbackID);
 }
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEConstructorProxy.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEConstructorProxy.java
index 99d386e..03fb443 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEConstructorProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEConstructorProxy.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.ide;
 /*
  *  $RCSfile: IDEConstructorProxy.java,v $
- *  $Revision: 1.7 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.8 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.lang.reflect.Constructor;
@@ -101,4 +101,19 @@
 		}
 
 	}
+	
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IConstructorProxy#getParameterTypes()
+	 */
+	public IBeanTypeProxy[] getParameterTypes() {
+		Class[] parmClasses = ((Constructor) getBean()).getParameterTypes();
+		IBeanTypeProxy[] parmTypes = new IBeanTypeProxy[parmClasses.length];
+		IDEStandardBeanTypeProxyFactory factory = (IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory();
+		for (int i = 0; i < parmClasses.length; i++) {
+			parmTypes[i] = factory.getBeanTypeProxy(parmClasses[i]);
+		}
+		return parmTypes;
+	}
+
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEExpression.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEExpression.java
index e560e99..7209df6 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEExpression.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEExpression.java
@@ -9,16 +9,18 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 /*
- * $RCSfile: IDEExpression.java,v $ $Revision: 1.4 $ $Date: 2005/02/16 14:38:04 $
+ * $RCSfile: IDEExpression.java,v $ $Revision: 1.5 $ $Date: 2005/05/11 19:01:12 $
  */
 package org.eclipse.jem.internal.proxy.ide;
 
-import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+import org.eclipse.core.runtime.Platform;
 
 import org.eclipse.jem.internal.proxy.common.MethodHelper;
 import org.eclipse.jem.internal.proxy.core.*;
-import org.eclipse.jem.internal.proxy.initParser.EvaluationException;
-import org.eclipse.jem.internal.proxy.initParser.tree.ExpressionProcesser;
+import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent;
+import org.eclipse.jem.internal.proxy.initParser.tree.*;
 
 /**
  * IDE expression processing.
@@ -28,8 +30,27 @@
 public class IDEExpression extends Expression {
 
 	private final IDEStandardBeanTypeProxyFactory beantypefactory;
-	protected final ExpressionProcesser eproc = new ExpressionProcesser();
+	protected final ExpressionProcesser eproc;
+	{
+		boolean useTracing = "true".equalsIgnoreCase(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyLaunchSupport.EXPRESSION_TRACING));
+		long threshold = Long.getLong(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyLaunchSupport.EXPRESSION_TRACEING_TIMER_THRESHOLD), -1L).longValue();
+		eproc = new ExpressionProcesser(useTracing, threshold);
+	}
+	
 
+	private void processExpressionError() throws ThrowableProxy, NoExpressionValueException {
+		if (!eproc.noErrors())
+			if (eproc.isNoExpressionValue())
+				throw (NoExpressionValueException) eproc.getErrorThrowable();
+			else {
+				Throwable t = eproc.getErrorThrowable();
+				if (t instanceof ThrowableProxy)
+					throw (ThrowableProxy) t;
+				else
+					throw new IDEThrowableProxy(eproc.getErrorThrowable(), beantypefactory.getBeanTypeProxy(t.getClass()));
+			}
+	}
+	
 	/**
 	 * Create the IDEExpression
 	 * 
@@ -51,15 +72,16 @@
 	}
 
 	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushToProxy(org.eclipse.jem.internal.proxy.core.IBeanProxy)
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushToProxy(org.eclipse.jem.internal.proxy.core.IProxy)
 	 */
-	protected void pushToProxy(IBeanProxy proxy) throws ThrowableProxy {
+	protected void pushToProxy(IProxy proxy) {
 		if (proxy == null)
 			eproc.pushExpression(null, MethodHelper.NULL_TYPE);
+		else if (proxy.isBeanProxy())
+			eproc.pushExpression(((IDEBeanProxy) proxy).getBean(), ((IDEBeanTypeProxy) ((IBeanProxy) proxy).getTypeProxy()).getTypeClass());
 		else
-			eproc.pushExpression(((IDEBeanProxy) proxy).getBean(), ((IDEBeanTypeProxy) proxy.getTypeProxy()).getTypeClass());
+			eproc.pushExpressionProxy(((ExpressionProxy) proxy).getProxyID());
 	}
 
 	/*
@@ -68,69 +90,83 @@
 	 * @see org.eclipse.jem.internal.proxy.core.Expression#closeProxy()
 	 */
 	protected void closeProxy() {
+		methodExpressionProxies = fieldExpressionProxies = null;
 		eproc.close();
 	}
 
 	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pullProxyValue()
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pullProxyValue(int, java.util.List)
 	 */
-	protected IBeanProxy pullProxyValue() throws NoExpressionValueException {
+	protected IBeanProxy pullProxyValue(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException {
+		processExtensionProxies(proxycount, expressionProxies);
+		processExpressionError();
 		Object result[] = new Object[2];
 		eproc.pullValue(result);
-		return getIDERegistry().getBeanProxy((Class) result[1], result[0]);
+		IBeanProxy resultProxy = getIDERegistry().getBeanProxy((Class) result[1], result[0]);
+		return resultProxy;
 	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushCastToProxy(java.lang.Object)
-	 */
-	protected void pushCastToProxy(Object type) throws ThrowableProxy, NoExpressionValueException {
-		try {
-			eproc.pushCast(getBeanTypeProxy(type).getTypeClass());
-		} catch (ClassCastException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
+	
+	private void processExtensionProxies(int proxycount, List expressionProxies) {
+		if (proxycount > 0) {
+			int len = expressionProxies.size();
+			Object[] proxyResolution = new Object[2];
+			for (int i = 0; i < len; i++) {
+				ExpressionProxy ep = (ExpressionProxy) expressionProxies.get(i);
+				if (ep != null) {
+					try {
+						eproc.pullExpressionProxyValue(ep.getProxyID(), proxyResolution);
+						if (proxyResolution[1] != Void.TYPE)
+							fireProxyResolved(ep, getIDERegistry().getBeanProxy((Class) proxyResolution[1], proxyResolution[0]));
+						else
+							fireProxyVoid(ep);
+					} catch (NoExpressionValueException e) {
+						fireProxyNotResolved(ep);
+					}
+				}
+			}
 		}
 	}
 
 	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInstanceofToProxy(java.lang.Object)
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushCastToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType)
 	 */
-	protected void pushInstanceofToProxy(Object type) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushCastToProxy(IProxyBeanType type) {
 		try {
-			eproc.pushInstanceof(getBeanTypeProxy(type).getTypeClass());
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
+			eproc.pushCast(getIDEBeanTypeProxy(type).getTypeClass());
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
 		}
 	}
 
 	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTypeLiteralToProxy(java.lang.String)
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInstanceofToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType)
 	 */
-	protected void pushTypeLiteralToProxy(String type) throws ThrowableProxy {
-		eproc.pushExpression(getBeanTypeProxy(type).getTypeClass(), Class.class);
+	protected void pushInstanceofToProxy(IProxyBeanType type) {
+		try {
+			eproc.pushInstanceof(getIDEBeanTypeProxy(type).getTypeClass());
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
+		}
 	}
 	
 	/**
 	 * Get the BeanType proxy and test if valid. Throw ThrowableProxy if not valid.
 	 * 
-	 * @param type Must be either String or an IDEBeanTypeProxy. If String, it will look it up.
+	 * @param type 
 	 * @return 
 	 * @throws ThrowableProxy
 	 * 
 	 * @since 1.0.0
 	 */
-	protected IDEBeanTypeProxy getBeanTypeProxy(Object type) throws ThrowableProxy {
-		IDEBeanTypeProxy typeProxy = null;
-		if (type instanceof String)		
-			typeProxy = (IDEBeanTypeProxy) registry.getBeanTypeProxyFactory().getBeanTypeProxy((String) type);
-		else
+	protected IDEBeanTypeProxy getIDEBeanTypeProxy(IProxyBeanType type) throws ThrowableProxy {
+		IDEBeanTypeProxy typeProxy;
+		if (type.isExpressionProxy()) {
+			// It should already be resolved at this point.
+			typeProxy = ((IDEBeanTypeExpressionProxy) type).getBeanTypeProxy();
+		} else
 			typeProxy = (IDEBeanTypeProxy) type;
 		if (!typeProxy.isValid()) {
 			throw new IDEThrowableProxy(
@@ -140,147 +176,873 @@
 			return typeProxy;
 	}
 
-	/*
-	 * (non-Javadoc)
+	
+	/**
+	 * Get the BeanType proxy and test if valid. Throw ThrowableProxy if not valid.
+	 * @param type
+	 * @return
+	 * @throws ThrowableProxy
 	 * 
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushPrefixToProxy(int)
+	 * @since 1.1.0
 	 */
-	protected void pushPrefixToProxy(int operator) throws ThrowableProxy, NoExpressionValueException {
-		try {
-			eproc.pushPrefix(operator);
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		}
+	protected IDEBeanTypeProxy getIDEBeanTypeProxy(String type) throws ThrowableProxy {
+		return (IDEBeanTypeProxy) registry.getBeanTypeProxyFactory().getBeanTypeProxy(type);
 	}
 
 	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInfixToProxy(int, int)
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushPrefixToProxy(org.eclipse.jem.internal.proxy.initParser.tree.PrefixOperator)
 	 */
-	protected void pushInfixToProxy(int operator, int operandType) throws ThrowableProxy, NoExpressionValueException {
-		try {
-			eproc.pushInfix(operator, operandType);
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		}
+	protected void pushPrefixToProxy(PrefixOperator operator) {
+		eproc.pushPrefix(operator);
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInfixToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InfixOperator, org.eclipse.jem.internal.proxy.initParser.tree.InternalInfixOperandType)
+	 */
+	protected void pushInfixToProxy(InfixOperator operator, InternalInfixOperandType operandType) {
+		eproc.pushInfix(operator, operandType);
 	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayAccessToProxy(int)
 	 */
-	protected void pushArrayAccessToProxy(int indexCount) throws ThrowableProxy, NoExpressionValueException {
-		try {
-			eproc.pushArrayAccess(indexCount);
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		}
+	protected void pushArrayAccessToProxy(int indexCount) {
+		eproc.pushArrayAccess(indexCount);
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayCreationToProxy(java.lang.Object, int)
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayCreationToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType, int)
 	 */
-	protected void pushArrayCreationToProxy(Object type, int dimensionCount) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushArrayCreationToProxy(IProxyBeanType type, int dimensionCount) {
 		try {
-			eproc.pushArrayCreation(getBeanTypeProxy(type).getTypeClass(), dimensionCount);
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		}
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayInitializerToProxy(java.lang.Object, int)
-	 */
-	protected void pushArrayInitializerToProxy(Object type, int expressionCount) throws ThrowableProxy, NoExpressionValueException {
-		try {
-			eproc.pushArrayInitializer(getBeanTypeProxy(type).getTypeClass(), expressionCount);
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushClassInstanceCreationToProxy(java.lang.Object, int)
-	 */
-	protected void pushClassInstanceCreationToProxy(Object type, int argumentCount) throws ThrowableProxy, NoExpressionValueException {
-		try {
-			eproc.pushClassInstanceCreation(getBeanTypeProxy(type).getTypeClass(), argumentCount);
-		} catch (InvocationTargetException e) {
-			throw new IDEThrowableProxy(e.getTargetException(), getIDEBeanTypeFactory().getBeanTypeProxy(e.getTargetException().getClass()));
-		} catch (NoExpressionValueException e) {
-			throw e;
+			eproc.pushArrayCreation(getIDEBeanTypeProxy(type).getTypeClass(), dimensionCount);
 		} catch (ThrowableProxy e) {
-			throw e;
-		} catch (EvaluationException e) {
-			throw new IDEThrowableProxy(e.getOriginalException(), getIDEBeanTypeFactory().getBeanTypeProxy(e.getOriginalException().getClass()));
-		} catch (Exception e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
+			eproc.processException(e);
+		}
+	}
+
+	protected void pushArrayInitializerToProxy(IProxyBeanType type, int stripCount, int expressionCount) {
+		try {
+			eproc.pushArrayInitializer(getIDEBeanTypeProxy(type).getTypeClass(), stripCount, expressionCount);
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
+		}
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushClassInstanceCreationToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType, int)
+	 */
+	protected void pushClassInstanceCreationToProxy(IProxyBeanType type, int argumentCount) {
+		try {
+			eproc.pushClassInstanceCreation(getIDEBeanTypeProxy(type).getTypeClass(), argumentCount);
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
+		}
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTypeReceiverToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType)
+	 */
+	protected void pushTypeReceiverToProxy(IProxyBeanType type) {
+		try {
+			Class c = getIDEBeanTypeProxy(type).getTypeClass();
+			eproc.pushExpression(c, c);	// When as a receiver, the type is the same as the receiver. 
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
+		} catch (RuntimeException e) {
+			eproc.processException(e);
 		}
 	}
 
 	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pustTypeReceiverToProxy(java.lang.Object)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushFieldAccessToProxy(java.lang.Object, boolean)
 	 */
-	protected void pushTypeReceiverToProxy(Object type) throws ThrowableProxy {
-		Class c = getBeanTypeProxy(type).getTypeClass();
-		// The expressionType is used for receivers in field/method invocation to find the field/method. So we want the type to be type we have.
-		// Also then the receiver to invoke against is the expression value, which is the type.
-		eproc.pushExpression(c, c);	
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushFieldAccessToProxy(java.lang.String, boolean)
-	 */
-	protected void pushFieldAccessToProxy(String fieldName, boolean hasReceiver) throws ThrowableProxy, NoExpressionValueException {
+	protected void pushFieldAccessToProxy(Object field, boolean hasReceiver) {
+		boolean isString = field instanceof String;
 		try {
-			eproc.pushFieldAccess(fieldName, hasReceiver);
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		} catch (NoExpressionValueException e) {
-			throw e;
-		} catch (NoSuchFieldException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		} catch (IllegalAccessException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
+			eproc.pushFieldAccess(isString ? field : getIDEFieldProxy((IProxyField) field).getBean(), isString, hasReceiver);
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
 		}		
 	}
 
 	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushMethodInvocationToProxy(java.lang.String, boolean, int)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushMethodInvocationToProxy(java.lang.Object, boolean, int)
 	 */
-	protected void pushMethodInvocationToProxy(String methodName, boolean hasReceiver, int argCount)
-		throws ThrowableProxy, NoExpressionValueException {
+	protected void pushMethodInvocationToProxy(Object method, boolean hasReceiver, int argCount) {
+		boolean isString = method instanceof String;
 		try {
-			eproc.pushMethodInvocation(methodName, hasReceiver, argCount);
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		} catch (NoExpressionValueException e) {
-			throw e;
-		} catch (EvaluationException e) {
-			throw new IDEThrowableProxy(e.getOriginalException(), getIDEBeanTypeFactory().getBeanTypeProxy(e.getOriginalException().getClass()));
-		} catch (IllegalAccessException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		} catch (InvocationTargetException e) {
-			throw new IDEThrowableProxy(e.getTargetException(), getIDEBeanTypeFactory().getBeanTypeProxy(e.getTargetException().getClass()));
+			eproc.pushMethodInvocation(isString ? method : getIDEMethodProxy((IProxyMethod) method).getBean(), isString, hasReceiver, argCount);
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushConditionalToProxy(int)
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushConditionalToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InternalConditionalOperandType)
 	 */
-	protected void pushConditionalToProxy(int expressionType) throws ThrowableProxy, NoExpressionValueException {
-		try {
-			eproc.pushConditional(expressionType);
-		} catch (RuntimeException e) {
-			throw new IDEThrowableProxy(e, getIDEBeanTypeFactory().getBeanTypeProxy(e.getClass()));
-		}
+	protected void pushConditionalToProxy(InternalConditionalOperandType expressionType) {
+		eproc.pushConditional(expressionType);
 	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushInvoke()
 	 */
-	protected void pushInvoke() {
-		// In the IDE case do nothing. Nothing is pending.
+	protected void pushInvoke(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException {
+		// In the IDE case do nothing. Nothing is pending. But still need to handle proxy resolution.
+		processExtensionProxies(proxycount, expressionProxies);
+		processExpressionError(); 
+	}
+	
+	/**
+	 * This is used as both an ExpressionProxy (i.e. IDE side) and the Expressions expression proxy result on the other side.
+	 * This makes it easier to just use same instance on both sides.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected static class IDEExpressionProxy extends ExpressionProxy implements InternalExpressionProxy {
+		
+		protected IDEExpressionProxy(int proxyid, int proxyType, Expression expression) {
+			super(proxyid, proxyType, expression);
+		}
+		
+		private Object value;
+		private Class type;
+		private boolean set;
+		
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#dispose()
+		 */
+		protected void dispose() {
+			super.dispose();
+			value = null;
+			type = null;
+			set = false;
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#getType()
+		 */
+		public Class getType() {
+			return type;
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#getValue()
+		 */
+		public Object getValue() {
+			return value;
+		}
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#setProxy(java.lang.Object, java.lang.Class)
+		 */
+		public void setProxy(Object value, Class type) {
+			this.value = value;
+			this.type = type;
+			set = true;
+		}
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#isSet()
+		 */
+		public boolean isSet() {
+			return set;
+		}
+	}
+	
+	/**
+	 * The Expression proxy for IDE BeanTypes.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected static class IDEBeanTypeExpressionProxy extends IDEExpressionProxy implements IBeanTypeExpressionProxy {
+		
+		private String typeName;
+		private IDEBeanTypeProxy resolvedProxy;
+
+		/**
+		 * @param proxyid
+		 * 
+		 * @since 1.1.0
+		 */
+		public IDEBeanTypeExpressionProxy(int proxyid, Expression expression) {
+			super(proxyid, BEANTYPE_EXPRESSION_PROXY, expression);
+		}
+		
+		/*
+		 *  (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.IBeanTypeExpressionProxy#setTypeName(java.lang.String)
+		 */
+		public void setTypeName(String typeName) {
+			this.typeName = typeName;
+		}
+		
+		/*
+		 *  (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getTypeName()
+		 */
+		public String getTypeName() {
+			return typeName;
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#toString()
+		 */
+		public String toString() {
+			return super.toString()+" - "+getTypeName();
+		}
+
+		/**
+		 * Called by IDEExpression to resolve the beantype.
+		 * @param beantypeProxy
+		 * 
+		 * @since 1.1.0
+		 */
+		void setProxy(IDEBeanTypeProxy beantypeProxy) {
+			this.resolvedProxy = beantypeProxy;
+			setProxy(resolvedProxy.getTypeClass(), Class.class);
+		}
+		
+		/**
+		 * Called by IDEExpression to get the resolved beantype proxy.
+		 * @return
+		 * 
+		 * @since 1.1.0
+		 */
+		IDEBeanTypeProxy getBeanTypeProxy() {
+			return resolvedProxy;
+		}
+
+		/*
+		 *  (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[])
+		 */
+		public IProxyMethod getMethodProxy(IExpression expression, String methodName, IProxyBeanType[] parameterTypes) {
+			IProxyMethod method = ((IDEExpression) expression).getMethodExpressionProxy(this, methodName, parameterTypes);
+			if (method == null) {
+				// Need to go to the expression and create it.
+				method = ((Expression) expression).createMethodExpressionProxy(this, methodName, parameterTypes);
+			}
+			return method;
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String[])
+		 */
+		public IProxyMethod getMethodProxy(IExpression expression, String methodName, String[] parameterTypes) {
+			return ((IDEMethodProxyFactory) expression.getRegistry().getMethodProxyFactory()).getMethodProxy(expression, this, methodName, parameterTypes);
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String)
+		 */
+		public IProxyField getFieldProxy(IExpression expression, String fieldName) {
+			IProxyField field = ((IDEExpression) expression).getFieldExpressionProxy(this, fieldName);
+			if (field == null) {
+				// Need to go to the expression and create it.
+				field = ((Expression) expression).createFieldExpressionProxy(this, fieldName);
+			}
+			return field;
+		}
+	}
+	
+	/**
+	 * The Expression proxy for IDE BeanTypes.
+	 * 
+	 * @since 1.1.0
+	 */
+	protected static class IDEMethodExpressionProxy extends IDEExpressionProxy implements IProxyMethod {
+		
+		private String methodName;
+		private IDEMethodProxy resolvedProxy;
+		private ThrowableProxy errorThrowable;
+
+		/**
+		 * @param proxyid
+		 * 
+		 * @since 1.1.0
+		 */
+		public IDEMethodExpressionProxy(int proxyid, Expression expression) {
+			super(proxyid, METHOD_EXPRESSION_PROXY, expression);
+		}
+		
+		/**
+		 * Set by IDEExpression with the method name.
+		 * @param methodName
+		 * 
+		 * @since 1.1.0
+		 */
+		void setMethodName(String methodName) {
+			this.methodName = methodName;
+		}
+				
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#toString()
+		 */
+		public String toString() {
+			return super.toString()+" - "+methodName;
+		}
+
+		/**
+		 * Called by IDEExpression to resolve the beantype.
+		 * @param methodProxy
+		 * 
+		 * @since 1.1.0
+		 */
+		void setProxy(IDEMethodProxy methodProxy) {
+			this.resolvedProxy = methodProxy;
+			setProxy(resolvedProxy.getBean(), Class.class);
+		}
+		
+		/**
+		 * Called by IDEExpression to say there was error in creating the proxy.
+		 * @param errorThrowable
+		 * 
+		 * @since 1.1.0
+		 */
+		void setThrowable(ThrowableProxy errorThrowable) {
+			this.errorThrowable = errorThrowable;
+		}
+		
+		/**
+		 * Called by IDEExpression to get the resolved method proxy.
+		 * @return
+		 * @throws ThrowableProxy
+		 * 
+		 * @since 1.1.0
+		 */
+		IDEMethodProxy getMethodProxy() throws ThrowableProxy {
+			if (errorThrowable != null)
+				throw errorThrowable;
+			return resolvedProxy;
+		}
+	}
+	
+	protected static class IDEFieldExpressionProxy extends IDEExpressionProxy implements IProxyField {
+		
+		private String fieldName;
+		private IDEFieldProxy resolvedProxy;
+		private ThrowableProxy errorThrowable;
+
+		/**
+		 * @param proxyid
+		 * 
+		 * @since 1.1.0
+		 */
+		public IDEFieldExpressionProxy(int proxyid, Expression expression) {
+			super(proxyid, FIELD_EXPRESSION_PROXY, expression);
+		}
+		
+		/**
+		 * Set by IDEExpression with the method name.
+		 * @param fieldName
+		 * 
+		 * @since 1.1.0
+		 */
+		void setField(String fieldName) {
+			this.fieldName = fieldName;
+		}
+				
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#toString()
+		 */
+		public String toString() {
+			return super.toString()+" - "+fieldName;
+		}
+
+		/**
+		 * Called by IDEExpression to resolve the beantype.
+		 * @param fieldProxy
+		 * 
+		 * @since 1.1.0
+		 */
+		void setProxy(IDEFieldProxy fieldProxy) {
+			this.resolvedProxy = fieldProxy;
+			setProxy(resolvedProxy.getBean(), Class.class);
+		}
+		
+		/**
+		 * Called by IDEExpression to say there was error in creating the proxy.
+		 * @param errorThrowable
+		 * 
+		 * @since 1.1.0
+		 */
+		void setThrowable(ThrowableProxy errorThrowable) {
+			this.errorThrowable = errorThrowable;
+		}
+		
+		/**
+		 * Called by IDEExpression to get the resolved field proxy.
+		 * @return
+		 * @throws ThrowableProxy
+		 * 
+		 * @since 1.1.0
+		 */
+		IDEFieldProxy getFieldProxy() throws ThrowableProxy {
+			if (errorThrowable != null)
+				throw errorThrowable;
+			return resolvedProxy;
+		}
+	}
+	
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#createExpressionProxy(int, int)
+	 */
+	protected ExpressionProxy createExpressionProxy(int proxyType, int proxyID) {
+		switch (proxyType) {
+			case NORMAL_EXPRESSION_PROXY:
+			default:
+				return new IDEExpressionProxy(proxyID, NORMAL_EXPRESSION_PROXY, this);
+			
+			case BEANTYPE_EXPRESSION_PROXY:
+				return new IDEBeanTypeExpressionProxy(proxyID, this);
+				
+			case METHOD_EXPRESSION_PROXY:
+				return new IDEMethodExpressionProxy(proxyID, this);
+				
+			case FIELD_EXPRESSION_PROXY:
+				return new IDEFieldExpressionProxy(proxyID, this);
+		}
+		
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushAssignmentToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy)
+	 */
+	protected void pushAssignmentToProxy(ExpressionProxy proxy) {
+		eproc.pushAssignment((InternalExpressionProxy) proxy);
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushAssignmentToProxy()
+	 */
+	protected void pushAssignmentToProxy() {
+		eproc.pushAssignment();
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockBeginToProxy(int)
+	 */
+	protected void pushBlockBeginToProxy(int blockNumber) {
+		eproc.pushBlockBegin(blockNumber);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockEndToProxy(int)
+	 */
+	protected void pushBlockEndToProxy(int blockNumber) {
+		eproc.pushBlockEnd(blockNumber);
+	}
+	
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockBreakToProxy(int)
+	 */
+	protected void pushBlockBreakToProxy(int blockNumber) {
+		eproc.pushBlockBreak(blockNumber);
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryBeginToProxy(int)
+	 */
+	protected void pushTryBeginToProxy(int tryNumber) {
+		eproc.pushTryBegin(tryNumber);
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryCatchClauseToProxy(int, org.eclipse.jem.internal.proxy.core.IProxyBeanType, org.eclipse.jem.internal.proxy.core.ExpressionProxy)
+	 */
+	protected void pushTryCatchClauseToProxy(int tryNumber, IProxyBeanType exceptionType, ExpressionProxy ep) {
+		try {
+			eproc.pushTryCatchClause(tryNumber, getIDEBeanTypeProxy(exceptionType).getTypeClass(), (InternalExpressionProxy) ep);
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryFinallyClauseToProxy(int)
+	 */
+	protected void pushTryFinallyClauseToProxy(int tryNumber) {
+		eproc.pushTryFinallyClause(tryNumber);
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryEndToProxy(int)
+	 */
+	protected void pushTryEndToProxy(int tryNumber) {
+		eproc.pushTryEnd(tryNumber);
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushThrowToProxy()
+	 */
+	protected void pushThrowToProxy() {
+		eproc.pushThrowException();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushRethrowToProxy(int)
+	 */
+	protected void pushRethrowToProxy(int tryNumber) {
+		eproc.pushTryRethrow(tryNumber);
+	}
+	
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushBeanTypeToProxy(org.eclipse.jem.internal.proxy.core.IBeanTypeExpressionProxy)
+	 */
+	protected void pushBeanTypeToProxy(IBeanTypeExpressionProxy proxy) {
+		try {
+			IDEBeanTypeExpressionProxy ep = (IDEBeanTypeExpressionProxy) proxy;
+			IDEBeanTypeProxy typeProxy = getIDEBeanTypeProxy(proxy.getTypeName());
+			ep.setProxy(typeProxy);
+			eproc.allocateExpressionProxy(ep);
+			if (!typeProxy.isValid()) {
+				throw new IDEThrowableProxy(
+						new Exception(typeProxy.getInitializationError()),
+						getIDEBeanTypeFactory().getBeanTypeProxy(Exception.class));
+			}
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
+		}
+	}
+	
+	/**
+	 * Get the map of IProxyBeanTypes for a beantype name. Meant to be used only in conjunction with IDEStandardBeanTypeFactory.
+	 * It is here so the IDDEStandardBeanTypeFactory can store pending proxies per expression.
+	 * 
+	 * @param beanType
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyBeanType getBeanType(String beanTypeName) {
+		if (beanTypeCache == null)
+			beanTypeCache = new HashMap();
+		return (IProxyBeanType) beanTypeCache.get(beanTypeName);
+	}
+	
+	/**
+	 * Add the beantype expression proxy to the map of bean type expression proxies. Used in conjunction with IDEStandardBeanTypeFactory.
+	 * It is here so the IDEStandardBeanTypeFactory can store pending proxies per expression.
+	 * @param beanTypeName
+	 * @param beantype
+	 * 
+	 * @since 1.1.0
+	 */
+	public void addBeanType(String beanTypeName, IProxyBeanType beantype) {
+		beanTypeCache.put(beanTypeName, beantype);
+	}
+	
+	/**
+	 * Remove the beantype expression proxy from the map. This is called because there was a rollback due to an endmark.
+	 * @param beanTypeName
+	 * 
+	 * @since 1.1.0
+	 */
+	public void removeBeanType(String beanTypeName) {
+		beanTypeCache.remove(beanTypeName);
+	}
+
+	/**
+	 * Keeping a local map of Method Expression Proxies so that we don't keep recreating them for each request from within this expression.
+	 * The map will be:  declaringTypeName->(Map) methodName or IDEMethodKey -> method expression proxy. 
+	 * @see IDEExpression#pushMethodToProxy(ExpressionProxy, IProxyBeanType, String, IProxyBeanType[]) for the actual implementation. 
+	 */
+	protected Map methodExpressionProxies;
+	
+	/**
+	 * Keeping a local map of Field Expression Proxies so that we don't keep recreating them for each request from within this expression.
+	 * The map will be:  declaringTypeName->(Map) fieldname -> field expression proxy. 
+	 * @see IDEExpression#pushFieldToProxy(ExpressionProxy, IProxyBeanType, String) 
+	 */
+	protected Map fieldExpressionProxies;
+	
+	/**
+	 * Keeping a local map of BeanType expression proxies so that we don't keep recreating them for each request from within this expression.
+	 * The map will be: typename->beanTypeExpressionProxy
+	 */
+	protected Map beanTypeCache;	// Use to cache pending BeanTypes. Used in conjunction with IDEStandardBeanTypeFactory.
+
+	/*
+	 * Used as the key to the methodCache when there are parms.
+	 * It allows the parms to be either IProxyBeanType without the
+	 * overhead of creating complicated strings.
+	 * 
+	 * It will compare method name and each individual parm name without fluffing
+	 * up a string and building it up.
+	 * 
+	 * For no parm methods, just the name of the method as a string will be the key.
+	 * 
+	 * @since 1.1.0
+	 */
+	private static class MethodKey {
+		public String methodName;
+		public IProxyBeanType[] parmTypes;
+		public MethodKey(String methodName, IProxyBeanType[] parmTypes) {
+			this.methodName = methodName;
+			this.parmTypes = parmTypes;
+		}
+				
+				
+		/* (non-Javadoc)
+		 * @see java.lang.Object#equals(java.lang.Object)
+		 */
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			try {
+				return ((MethodKey) obj).compareParms(parmTypes);
+			} catch (ClassCastException e) {
+				return false;
+			}
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.remote.REMProxyConstants.MethodKey#hashCode()
+		 */
+		public int hashCode() {
+			int h = methodName.hashCode();;
+			for (int i = 0; i < parmTypes.length; i++) {
+				h += parmTypes[i].getTypeName().hashCode();
+			}
+			return h;
+		}
+				
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.remote.REMProxyConstants.MethodKey#compareParms(java.lang.String[])
+		 */
+		protected boolean compareParms(IProxyBeanType[] parms) {
+			if (parms.length != parmTypes.length)
+				return false;
+			for (int i = 0; i < parms.length; i++) {
+				if (!parmTypes[i].getTypeName().equals(parms[i].getTypeName()))
+					return false;
+			}
+			return true;
+		}		
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushMethodToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy, org.eclipse.jem.internal.proxy.core.IProxyBeanType, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[])
+	 */
+	protected void pushMethodToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes) {
+		try {
+			final Map methods = getMethods(declaringType);
+			final Object key = getMethodKey(methodName, parameterTypes); 
+			methods.put(key, proxy);
+			proxy.addProxyListener(new ExpressionProxy.ProxyAdapter() {
+			
+				public void proxyNotResolved(ProxyEvent event) {
+					methods.remove(key);	// Back it out. tis could happen due to endmark rollback.
+				}
+			
+			});
+			
+			IDEMethodExpressionProxy ep = (IDEMethodExpressionProxy) proxy;
+			ep.setMethodName(methodName);
+			// We resolve immediately. Any expression proxies should also be resolved at this point too.
+			Class declaringClass = getIDEBeanTypeProxy(declaringType).getTypeClass();
+			Class[] parameterClasses;
+			if (parameterTypes == null || parameterTypes.length == 0)
+				parameterClasses = null;
+			else {
+				parameterClasses = new Class[parameterTypes.length];
+				for (int i = 0; i < parameterClasses.length; i++) {
+					parameterClasses[i] = getIDEBeanTypeProxy(parameterTypes[i]).getTypeClass();
+				}
+			}
+			IDEMethodProxy methodProxy = ((IDEMethodProxyFactory) registry.getMethodProxyFactory()).getMethodProxy(declaringClass, methodName, parameterClasses);
+			if (methodProxy == null) {
+				String parms = "";
+				if (parameterTypes != null || parameterTypes.length > 0) {
+					StringBuffer st = new StringBuffer(100);
+					for (int i = 0; i < parameterClasses.length; i++) {
+						if (i > 0)
+							st.append(',');
+						st.append(parameterTypes[i].getTypeName());
+					}
+					parms = st.toString();
+				}
+				throw new IDEThrowableProxy(new NoSuchMethodException("No method: "+declaringType+'.'+methodName+"("+parms+')'),
+					getIDEBeanTypeFactory().getBeanTypeProxy(NoSuchMethodException.class));
+			}
+			
+			ep.setProxy(methodProxy);
+			eproc.allocateExpressionProxy(ep);
+		} catch (ThrowableProxy e) {
+			((IDEMethodExpressionProxy) proxy).setThrowable(e);	// So we don't recreate throwable all of the time.
+			eproc.processException(e);
+		}		
+	}
+	
+	private Map getMethods(IProxyBeanType classtype) {
+		if (methodExpressionProxies == null)
+			methodExpressionProxies = new HashMap();
+		Map methods = (Map) methodExpressionProxies.get(classtype.getTypeName());
+		if (methods == null)
+			methodExpressionProxies.put(classtype.getTypeName(), methods = new HashMap());
+		return methods;
+	}
+	
+	private Object getMethodKey(String methodName, IProxyBeanType[] parameterTypes) {
+		if (parameterTypes == null || parameterTypes.length == 0)
+			return methodName;
+		else
+			return new MethodKey(methodName, parameterTypes);
+	}
+	
+	private Map getFields(IProxyBeanType classtype) {
+		if (fieldExpressionProxies == null)
+			fieldExpressionProxies = new HashMap();
+		Map fields = (Map) fieldExpressionProxies.get(classtype.getTypeName());
+		if (fields == null)
+			fieldExpressionProxies.put(classtype.getTypeName(), fields = new HashMap());
+		return fields;
+	}
+	
+	/**
+	 * This is used by IDEBeanTypes and IDEBeanTypeExpressionProxy to access any already created Method Expression Proxies.
+	 * 
+	 * @param declaringType
+	 * @param methodName
+	 * @param parameterTypes
+	 * @return IProxyMethod or <code>null</code> if not yet created.
+	 * 
+	 * @since 1.1.0
+	 */
+	IProxyMethod getMethodExpressionProxy(IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes) {
+		Map methods = getMethods(declaringType);
+		Object key = getMethodKey(methodName, parameterTypes); 
+		return (IProxyMethod) methods.get(key);
+	}
+	
+	/**
+	 * This is used by IDEBeanTypes and IDEBeanTypeExpressionProxy to access any already created Field Expression Proxies.
+	 * @param declaringType
+	 * @param fieldName
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	IProxyField getFieldExpressionProxy(IProxyBeanType declaringType, String fieldName) {
+		Map fields = getFields(declaringType);
+		return (IProxyField) fields.get(fieldName);
+	}
+	
+	/**
+	 * Get the IDEMethodProxy out of the already resolved Expression Proxy or IDEMethodProxy itself.
+	 * @param method
+	 * @return
+	 * @throws ThrowableProxy
+	 * 
+	 * @since 1.1.0
+	 */
+	protected IDEMethodProxy getIDEMethodProxy(IProxyMethod method) throws ThrowableProxy {
+		IDEMethodProxy methodProxy;
+		if (method.isExpressionProxy()) {
+			// It should already be resolved at this point.
+			methodProxy = ((IDEMethodExpressionProxy) method).getMethodProxy();
+		} else
+			methodProxy = (IDEMethodProxy) method;
+		return methodProxy;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushFieldToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy, org.eclipse.jem.internal.proxy.core.IProxyBeanType, java.lang.String)
+	 */
+	protected void pushFieldToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, final String fieldName) {
+
+		try {
+			final Map fields = getFields(declaringType);
+			fields.put(fieldName, proxy);
+			proxy.addProxyListener(new ExpressionProxy.ProxyAdapter(){
+				public void proxyNotResolved(ExpressionProxy.ProxyEvent event) {
+					fields.remove(fieldName);	// this can happen due to an endmark. It could be one of the ones that are rolled back.
+				}
+			});
+			
+			
+			IDEFieldExpressionProxy ep = (IDEFieldExpressionProxy) proxy;
+			// We resolve immediately. Any expression proxies should also be resolved at this point too.
+			IDEFieldProxy fieldProxy = (IDEFieldProxy) getIDEBeanTypeProxy(declaringType).getFieldProxy(fieldName);
+			if (fieldProxy == null) {
+			throw new IDEThrowableProxy(new NoSuchFieldException("No field: "+declaringType+'.'+fieldName),
+					getIDEBeanTypeFactory().getBeanTypeProxy(NoSuchFieldException.class));
+			}
+			
+			ep.setProxy(fieldProxy);
+			eproc.allocateExpressionProxy(ep);
+		} catch (ThrowableProxy e) {
+			((IDEFieldExpressionProxy) proxy).setThrowable(e);	// So we don't recreate throwable all of the time.
+			eproc.processException(e);
+		}		
+
+	}
+	
+	/**
+	 * Get the IDEFieldProxy out of the already resolved Expression Proxy or IDEFieldProxy itself.
+	 * @param field
+	 * @return
+	 * @throws ThrowableProxy
+	 * 
+	 * @since 1.1.0
+	 */
+	protected IDEFieldProxy getIDEFieldProxy(IProxyField field) throws ThrowableProxy {
+		IDEFieldProxy fieldProxy;
+		if (field.isExpressionProxy()) {
+			// It should already be resolved at this point.
+			fieldProxy = ((IDEFieldExpressionProxy) field).getFieldProxy();
+		} else
+			fieldProxy = (IDEFieldProxy) field;
+		return fieldProxy;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushIfTestToProxy()
+	 */
+	protected void pushIfTestToProxy() {
+		eproc.pushIfElse();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushIfElseToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InternalIfElseOperandType)
+	 */
+	protected void pushIfElseToProxy(InternalIfElseOperandType clauseType) {
+		eproc.pushIfElse(clauseType);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.Expression#pushNewInstanceToProxy(java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType)
+	 */
+	protected void pushNewInstanceToProxy(String initializationString, IProxyBeanType resultType) {
+		try {
+			eproc.pushNewInstanceFromString(initializationString, getIDEBeanTypeProxy(resultType).getTypeClass(), getIDERegistry().fClassLoader);
+		} catch (ThrowableProxy e) {
+			eproc.processException(e);
+		}
+	}
+
+	protected void pushMarkToProxy(int markID) {
+		eproc.pushMark(markID);
+	}
+
+	protected void pushEndmarkToProxy(int markID, boolean restore) {
+		eproc.pushEndmark(markID, restore);
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEExtensionBeanTypeProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEExtensionBeanTypeProxyFactory.java
index 58bd344..c4a28ca 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEExtensionBeanTypeProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEExtensionBeanTypeProxyFactory.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IDEExtensionBeanTypeProxyFactory.java,v $
- *  $Revision: 1.2 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.3 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import org.eclipse.jem.internal.proxy.core.*;
@@ -22,5 +22,7 @@
 
 public IDEBeanTypeProxy getExtensionBeanTypeProxy(String typeName, IBeanTypeProxy superType);	
 
+public IProxyBeanType getExtensionBeanTypeProxy(String typeName, IExpression expression);
+
 
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEMethodProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEMethodProxyFactory.java
index 93600ac..0ada52c 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEMethodProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEMethodProxyFactory.java
@@ -9,7 +9,7 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 /*
- * $RCSfile: IDEMethodProxyFactory.java,v $ $Revision: 1.9 $ $Date: 2005/02/15 22:57:26 $
+ * $RCSfile: IDEMethodProxyFactory.java,v $ $Revision: 1.10 $ $Date: 2005/05/11 19:01:12 $
  */
 package org.eclipse.jem.internal.proxy.ide;
 
@@ -134,6 +134,17 @@
 		return (IFieldProxy) fieldType.newBeanProxy(aField);
 
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IMethodProxyFactory#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String)
+	 */
+	public IProxyField getFieldProxy(IExpression expression, String className, String fieldName) {
+		// We are getting the class resolved through the expression. Might as well because it probably will
+		// be needed again and this way when the expression is finished they will be resolved for later usage.
+		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fProxyFactoryRegistry.getBeanTypeProxyFactory();
+		IProxyBeanType beanType = beanTypeProxyFactory.getBeanTypeProxy(expression, className);
+		return beanType.getFieldProxy(expression, fieldName);
+	}
 
 	/**
 	 * Return an instance of an IDEMethodProxy This is package protected because the only people who can use this are priveledge objects that have the
@@ -141,9 +152,9 @@
 	 * method proxy you must use the interface methods on IMethodProxyFactory to do lookup by string or else on IBeanTypeProxy that has
 	 * getMethod(String) as well
 	 */
-	IMethodProxy getMethodProxy(Method aMethod) {
+	IDEMethodProxy getMethodProxy(Method aMethod) {
 
-		return (IMethodProxy) methodType.newBeanProxy(aMethod);
+		return (IDEMethodProxy) methodType.newBeanProxy(aMethod);
 
 	}
 
@@ -156,6 +167,58 @@
 			return null;
 		}
 	}
+	
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IMethodProxyFactory#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String, java.lang.String[])
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, String className, String methodName, String[] parameterTypes) {
+		// We are getting the class and parmtypes resolved through the expression. Might as well because they probably will
+		// be needed again and this way when the expression is finished they will be resolved for later usage.
+		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fProxyFactoryRegistry.getBeanTypeProxyFactory();
+		IProxyBeanType beanType = beanTypeProxyFactory.getBeanTypeProxy(expression, className);
+		IProxyBeanType[] parmTypes = getParameterTypes(expression, parameterTypes, beanTypeProxyFactory);
+		return beanType.getMethodProxy(expression, methodName, parmTypes);
+	}	
+	
+	/**
+	 * Helper method for Beantypes and Proxy bean types to get the proxy.
+	 * @param expression
+	 * @param classType
+	 * @param methodName
+	 * @param parameterTypes
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public IProxyMethod getMethodProxy(IExpression expression, IProxyBeanType classType, String methodName, String[] parameterTypes) {
+		// We are getting the parmtypes resolved through the expression. Might as well because they probably will
+		// be needed again and this way when the expression is finished they will be resolved for later usage.
+		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fProxyFactoryRegistry.getBeanTypeProxyFactory();
+		IProxyBeanType[] parmTypes = getParameterTypes(expression, parameterTypes, beanTypeProxyFactory);
+		return classType.getMethodProxy(expression, methodName, parmTypes);
+	}
+
+	/**
+	 * @param expression
+	 * @param parameterTypes
+	 * @param beanTypeProxyFactory
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	protected IProxyBeanType[] getParameterTypes(IExpression expression, String[] parameterTypes, IStandardBeanTypeProxyFactory beanTypeProxyFactory) {
+		IProxyBeanType[] parmTypes;
+		if (parameterTypes == null || parameterTypes.length == 0)
+			parmTypes = null;
+		else {
+			parmTypes = new IProxyBeanType[parameterTypes.length];
+			for (int i = 0; i < parameterTypes.length; i++) {
+				parmTypes[i] = beanTypeProxyFactory.getBeanTypeProxy(expression, parameterTypes[i]);
+			}
+		}
+		return parmTypes;
+	}
 
 	public IMethodProxy getMethodProxy(Class cls, String methodName, String[] parameterTypes) {
 		try {
@@ -199,7 +262,7 @@
 		return null;
 	}	
 
-	IMethodProxy getMethodProxy(Class aClass, String methodName, Class[] args) {
+	IDEMethodProxy getMethodProxy(Class aClass, String methodName, Class[] args) {
 		try {
 			Method method = aClass.getMethod(methodName, args);
 			return getMethodProxy(method);
@@ -270,4 +333,5 @@
 	 */
 	public void terminateFactory(boolean wait) {
 	}
+
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEStandardBeanTypeProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEStandardBeanTypeProxyFactory.java
index 9e16478..018bf5e 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEStandardBeanTypeProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEStandardBeanTypeProxyFactory.java
@@ -1,17 +1,13 @@
-/*******************************************************************************
- * Copyright (c) 2001, 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
+/*****************************************************************************************************************************************************
+ * Copyright (c) 2001, 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
- *******************************************************************************/
+ * Contributors: IBM Corporation - initial API and implementation
+ ****************************************************************************************************************************************************/
 package org.eclipse.jem.internal.proxy.ide;
+
 /*
- *  $RCSfile: IDEStandardBeanTypeProxyFactory.java,v $
- *  $Revision: 1.8 $  $Date: 2005/02/15 22:57:26 $ 
+ * $RCSfile: IDEStandardBeanTypeProxyFactory.java,v $ $Revision: 1.9 $ $Date: 2005/05/11 19:01:12 $
  */
 
 import java.lang.reflect.Array;
@@ -25,312 +21,441 @@
 
 import org.eclipse.jem.internal.proxy.common.MapTypes;
 import org.eclipse.jem.internal.proxy.core.*;
+import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent;
 
 public class IDEStandardBeanTypeProxyFactory implements IStandardBeanTypeProxyFactory {
-	
+
 	protected final IDEProxyFactoryRegistry fFactoryRegistry;
 
 	// Hashtable to cache proxies for classes so they are found on second and subsequent lookups
 	protected Map beanProxies;
-			
+
 	public static Map MAP_SHORTSIG_TO_TYPE = new HashMap(8);
-	public static Map MAP_TYPENAME_TO_SHORTSIG = new HashMap(8);	
-	
+
+	public static Map MAP_TYPENAME_TO_SHORTSIG = new HashMap(8);
+
 	static {
 		MAP_SHORTSIG_TO_TYPE.put("B", Byte.TYPE); //$NON-NLS-1$
 		MAP_SHORTSIG_TO_TYPE.put("C", Character.TYPE); //$NON-NLS-1$
-		MAP_SHORTSIG_TO_TYPE.put("D", Double.TYPE);		 //$NON-NLS-1$
+		MAP_SHORTSIG_TO_TYPE.put("D", Double.TYPE); //$NON-NLS-1$
 		MAP_SHORTSIG_TO_TYPE.put("F", Float.TYPE); //$NON-NLS-1$
 		MAP_SHORTSIG_TO_TYPE.put("I", Integer.TYPE); //$NON-NLS-1$
 		MAP_SHORTSIG_TO_TYPE.put("J", Long.TYPE); //$NON-NLS-1$
 		MAP_SHORTSIG_TO_TYPE.put("S", Short.TYPE); //$NON-NLS-1$
 		MAP_SHORTSIG_TO_TYPE.put("Z", Boolean.TYPE); //$NON-NLS-1$
-		
-		MAP_TYPENAME_TO_SHORTSIG.put("byte","B"); //$NON-NLS-1$ //$NON-NLS-2$
-		MAP_TYPENAME_TO_SHORTSIG.put("char","C"); //$NON-NLS-1$ //$NON-NLS-2$
-		MAP_TYPENAME_TO_SHORTSIG.put("double","D"); //$NON-NLS-1$ //$NON-NLS-2$
-		MAP_TYPENAME_TO_SHORTSIG.put("float","F"); //$NON-NLS-1$ //$NON-NLS-2$
-		MAP_TYPENAME_TO_SHORTSIG.put("int","I"); //$NON-NLS-1$ //$NON-NLS-2$
-		MAP_TYPENAME_TO_SHORTSIG.put("long","J"); //$NON-NLS-1$ //$NON-NLS-2$
-		MAP_TYPENAME_TO_SHORTSIG.put("short","S"); //$NON-NLS-1$ //$NON-NLS-2$
-		MAP_TYPENAME_TO_SHORTSIG.put("boolean","Z"); //$NON-NLS-1$ //$NON-NLS-2$
+
+		MAP_TYPENAME_TO_SHORTSIG.put("byte", "B"); //$NON-NLS-1$ //$NON-NLS-2$
+		MAP_TYPENAME_TO_SHORTSIG.put("char", "C"); //$NON-NLS-1$ //$NON-NLS-2$
+		MAP_TYPENAME_TO_SHORTSIG.put("double", "D"); //$NON-NLS-1$ //$NON-NLS-2$
+		MAP_TYPENAME_TO_SHORTSIG.put("float", "F"); //$NON-NLS-1$ //$NON-NLS-2$
+		MAP_TYPENAME_TO_SHORTSIG.put("int", "I"); //$NON-NLS-1$ //$NON-NLS-2$
+		MAP_TYPENAME_TO_SHORTSIG.put("long", "J"); //$NON-NLS-1$ //$NON-NLS-2$
+		MAP_TYPENAME_TO_SHORTSIG.put("short", "S"); //$NON-NLS-1$ //$NON-NLS-2$
+		MAP_TYPENAME_TO_SHORTSIG.put("boolean", "Z"); //$NON-NLS-1$ //$NON-NLS-2$
 	}
-	
+
 	// Cached copy of a few typical bean type proxies.
 	IDEBeanTypeProxy objectClass;
+
 	IDEBooleanTypeBeanTypeProxy booleanType;
+
 	IDEBooleanClassBeanTypeProxy booleanClass;
+
 	IDEIntegerTypeBeanTypeProxy intType;
+
 	IDEIntegerClassBeanTypeProxy integerClass;
+
 	IDEFloatTypeBeanTypeProxy floatType;
-	IDEFloatClassBeanTypeProxy floatClass;	
+
+	IDEFloatClassBeanTypeProxy floatClass;
+
 	IDELongTypeBeanTypeProxy longType;
+
 	IDELongClassBeanTypeProxy longClass;
+
 	IDEShortTypeBeanTypeProxy shortType;
+
 	IDEShortClassBeanTypeProxy shortClass;
+
 	IDEByteTypeBeanTypeProxy byteType;
-	IDEByteClassBeanTypeProxy byteClass;	
+
+	IDEByteClassBeanTypeProxy byteClass;
+
 	IDECharTypeBeanTypeProxy charType;
-	IDECharacterClassBeanTypeProxy charClass;	
+
+	IDECharacterClassBeanTypeProxy charClass;
+
 	IDEDoubleTypeBeanTypeProxy doubleType;
-	IDEDoubleClassBeanTypeProxy doubleClass;	
-	
+
+	IDEDoubleClassBeanTypeProxy doubleClass;
+
 	IDEStringBeanTypeProxy stringClass;
+
 	IDEClassBeanTypeProxy classClass;
+
 	IDEBeanTypeProxy voidType;
 
-public IDEStandardBeanTypeProxyFactory(IDEProxyFactoryRegistry aRegistry) {
-	fFactoryRegistry = aRegistry;
-	aRegistry.registerBeanTypeProxyFactory(this);
+	public IDEStandardBeanTypeProxyFactory(IDEProxyFactoryRegistry aRegistry) {
+		fFactoryRegistry = aRegistry;
+		aRegistry.registerBeanTypeProxyFactory(this);
 
-	// Now initialize the cache.
-	objectClass = new IDEBeanTypeProxy(fFactoryRegistry,Object.class);
-	booleanType = new IDEBooleanTypeBeanTypeProxy(fFactoryRegistry, Boolean.TYPE);
-	booleanClass = new IDEBooleanClassBeanTypeProxy(fFactoryRegistry, Boolean.class);	
-	intType = new IDEIntegerTypeBeanTypeProxy(fFactoryRegistry, Integer.TYPE);
-	integerClass = new IDEIntegerClassBeanTypeProxy(fFactoryRegistry, Integer.class);
-	floatType = new IDEFloatTypeBeanTypeProxy(fFactoryRegistry,Float.TYPE);
-	floatClass = new IDEFloatClassBeanTypeProxy(fFactoryRegistry,Float.class);
-	longType = new IDELongTypeBeanTypeProxy(fFactoryRegistry,Long.TYPE);
-	longClass = new IDELongClassBeanTypeProxy(fFactoryRegistry,Long.class);
-	shortType = new IDEShortTypeBeanTypeProxy(fFactoryRegistry,Short.TYPE);
-	shortClass = new IDEShortClassBeanTypeProxy(fFactoryRegistry,Short.class);
-	byteType = new IDEByteTypeBeanTypeProxy(fFactoryRegistry,Byte.TYPE);
-	byteClass = new IDEByteClassBeanTypeProxy(fFactoryRegistry,Byte.class);
-	charType = new IDECharTypeBeanTypeProxy(fFactoryRegistry,Character.TYPE);
-	charClass = new IDECharacterClassBeanTypeProxy(fFactoryRegistry,Character.class);
-	doubleType = new IDEDoubleTypeBeanTypeProxy(fFactoryRegistry,Double.TYPE);
-	doubleClass = new IDEDoubleClassBeanTypeProxy(fFactoryRegistry,Double.class);
-	stringClass = new IDEStringBeanTypeProxy(fFactoryRegistry, String.class);
-	classClass = new IDEClassBeanTypeProxy(fFactoryRegistry,java.lang.Class.class);
-	voidType = new IDEBeanTypeProxy(fFactoryRegistry, Void.TYPE);
+		// Now initialize the cache.
+		objectClass = new IDEBeanTypeProxy(fFactoryRegistry, Object.class);
+		booleanType = new IDEBooleanTypeBeanTypeProxy(fFactoryRegistry, Boolean.TYPE);
+		booleanClass = new IDEBooleanClassBeanTypeProxy(fFactoryRegistry, Boolean.class);
+		intType = new IDEIntegerTypeBeanTypeProxy(fFactoryRegistry, Integer.TYPE);
+		integerClass = new IDEIntegerClassBeanTypeProxy(fFactoryRegistry, Integer.class);
+		floatType = new IDEFloatTypeBeanTypeProxy(fFactoryRegistry, Float.TYPE);
+		floatClass = new IDEFloatClassBeanTypeProxy(fFactoryRegistry, Float.class);
+		longType = new IDELongTypeBeanTypeProxy(fFactoryRegistry, Long.TYPE);
+		longClass = new IDELongClassBeanTypeProxy(fFactoryRegistry, Long.class);
+		shortType = new IDEShortTypeBeanTypeProxy(fFactoryRegistry, Short.TYPE);
+		shortClass = new IDEShortClassBeanTypeProxy(fFactoryRegistry, Short.class);
+		byteType = new IDEByteTypeBeanTypeProxy(fFactoryRegistry, Byte.TYPE);
+		byteClass = new IDEByteClassBeanTypeProxy(fFactoryRegistry, Byte.class);
+		charType = new IDECharTypeBeanTypeProxy(fFactoryRegistry, Character.TYPE);
+		charClass = new IDECharacterClassBeanTypeProxy(fFactoryRegistry, Character.class);
+		doubleType = new IDEDoubleTypeBeanTypeProxy(fFactoryRegistry, Double.TYPE);
+		doubleClass = new IDEDoubleClassBeanTypeProxy(fFactoryRegistry, Double.class);
+		stringClass = new IDEStringBeanTypeProxy(fFactoryRegistry, String.class);
+		classClass = new IDEClassBeanTypeProxy(fFactoryRegistry, java.lang.Class.class);
+		voidType = new IDEBeanTypeProxy(fFactoryRegistry, Void.TYPE);
 
-	// Initialize the hashtable with the primitives, their lang equivalents, and also common classes like String
-	beanProxies = new HashMap(20);
+		// Initialize the hashtable with the primitives, their lang equivalents, and also common classes like String
+		beanProxies = new HashMap(20);
 
-	// Primitives
-	beanProxies.put(intType.getTypeName(), intType);
-	beanProxies.put(booleanType.getTypeName(), booleanType);
-	beanProxies.put(charType.getTypeName(), charType); 
-	beanProxies.put(byteType.getTypeName(), byteType); 
-	beanProxies.put(shortType.getTypeName(), shortType); 
-	beanProxies.put(longType.getTypeName(), longType); 
-	beanProxies.put(floatType.getTypeName(), floatType); 
-	beanProxies.put(doubleType.getTypeName(), doubleType); 
+		// Primitives
+		beanProxies.put(intType.getTypeName(), intType);
+		beanProxies.put(booleanType.getTypeName(), booleanType);
+		beanProxies.put(charType.getTypeName(), charType);
+		beanProxies.put(byteType.getTypeName(), byteType);
+		beanProxies.put(shortType.getTypeName(), shortType);
+		beanProxies.put(longType.getTypeName(), longType);
+		beanProxies.put(floatType.getTypeName(), floatType);
+		beanProxies.put(doubleType.getTypeName(), doubleType);
 
-	// java.lang primitive peers
-	// Note that special classes are used for some of these which allow the IDE to get the
-	// lang objects from the objects that are holding proxies
-	beanProxies.put(integerClass.getTypeName(), integerClass);
-	beanProxies.put(booleanClass.getTypeName(), booleanClass);
-	beanProxies.put(charClass.getTypeName(), charClass); 
-	beanProxies.put(byteClass.getTypeName(), byteClass); 
-	beanProxies.put(shortClass.getTypeName(), shortClass);
-	beanProxies.put(longClass.getTypeName(), longClass); 
-	beanProxies.put(floatClass.getTypeName(), floatClass); 
-	beanProxies.put(doubleClass.getTypeName(), doubleClass);
-	beanProxies.put(BigDecimal.class.getName(), new IDEBigDecimalBeanTypeProxy(fFactoryRegistry, BigDecimal.class));//$NON-NLS-1$
-	beanProxies.put(BigInteger.class.getName(), new IDEBigIntegerBeanTypeProxy(fFactoryRegistry, BigInteger.class));//$NON-NLS-1$		
-	beanProxies.put(stringClass.getTypeName(), stringClass);
-	
-	beanProxies.put(classClass.getTypeName(), classClass); 
-	beanProxies.put(voidType.getTypeName(), voidType); 
-}
-/**
- * We are an IDE proxy and know that the type is in the same VM as the IDE.
- * the IDEBeanTypeProxy object
- * NOTE This is package protected because the only person who can call it are priveledged classes
- * that are also creating things in an IDEProxy environment.
- * If anyone needs to make this method public they are doing the wrong thing as they should use the
- * public method getBeanTypeProxy(String) that is on the interface.  The only other object that can
- * guarantee that they have the class for the argument are those that are part of the idevm package
- */
-IBeanTypeProxy getBeanTypeProxy(Class anIDEClass) {
-	return getBeanTypeProxy(anIDEClass.getName());
+		// java.lang primitive peers
+		// Note that special classes are used for some of these which allow the IDE to get the
+		// lang objects from the objects that are holding proxies
+		beanProxies.put(integerClass.getTypeName(), integerClass);
+		beanProxies.put(booleanClass.getTypeName(), booleanClass);
+		beanProxies.put(charClass.getTypeName(), charClass);
+		beanProxies.put(byteClass.getTypeName(), byteClass);
+		beanProxies.put(shortClass.getTypeName(), shortClass);
+		beanProxies.put(longClass.getTypeName(), longClass);
+		beanProxies.put(floatClass.getTypeName(), floatClass);
+		beanProxies.put(doubleClass.getTypeName(), doubleClass);
+		beanProxies.put(BigDecimal.class.getName(), new IDEBigDecimalBeanTypeProxy(fFactoryRegistry, BigDecimal.class));//$NON-NLS-1$
+		beanProxies.put(BigInteger.class.getName(), new IDEBigIntegerBeanTypeProxy(fFactoryRegistry, BigInteger.class));//$NON-NLS-1$		
+		beanProxies.put(stringClass.getTypeName(), stringClass);
 
-}
-/**
- * We are an IDE proxy and know that the type is in the same VM as the IDE.
- * the IDEBeanTypeProxy object
- */
-public synchronized IBeanTypeProxy getBeanTypeProxy(String typeName) {
-	typeName = MapTypes.getJNIFormatName(typeName);
-
-	// See whether we already have the proxy for the argument name
-	IBeanTypeProxy beanTypeProxy = (IBeanTypeProxy) beanProxies.get(typeName);
-	if (beanTypeProxy != null) {
-		return beanTypeProxy;
+		beanProxies.put(classClass.getTypeName(), classClass);
+		beanProxies.put(voidType.getTypeName(), voidType);
 	}
-	
-	// If not an array, then see if the package extension mechanism can find it.
-	// Do this here so that if it is found in the package extension we won't necessarily create an
-	// extra connection when not needed.
-	if (typeName.charAt(0) != '[') {
-		// It is not an array
-		// First check with the factory for the package of the class.
-		// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
-		// the package ended and the class started.
-		int packageIndex = typeName.lastIndexOf('.');
-		if (packageIndex != -1) {
-			String packageName = typeName.substring(0, packageIndex);
-			IDEExtensionBeanTypeProxyFactory packageFactory = (IDEExtensionBeanTypeProxyFactory)fFactoryRegistry.getBeanTypeProxyFactoryExtension(packageName);
-			if (packageFactory != null) {
-				beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName);
-				if (beanTypeProxy != null) {
-					registerBeanTypeProxy(beanTypeProxy, false);
-					return beanTypeProxy;
+
+	/**
+	 * We are an IDE proxy and know that the type is in the same VM as the IDE. the IDEBeanTypeProxy object NOTE This is package protected because the
+	 * only person who can call it are priveledged classes that are also creating things in an IDEProxy environment. If anyone needs to make this
+	 * method public they are doing the wrong thing as they should use the public method getBeanTypeProxy(String) that is on the interface. The only
+	 * other object that can guarantee that they have the class for the argument are those that are part of the idevm package
+	 */
+	IBeanTypeProxy getBeanTypeProxy(Class anIDEClass) {
+		return getBeanTypeProxy(anIDEClass.getName());
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(java.lang.String)
+	 */
+	public synchronized IBeanTypeProxy getBeanTypeProxy(String typeName) {
+		typeName = MapTypes.getJNIFormatName(typeName);
+
+		// See whether we already have the proxy for the argument name
+		IProxyBeanType beanTypeProxy = (IProxyBeanType) beanProxies.get(typeName);
+		// See if there and resolved, if so, return it. If not resolved, that means we need it NOW
+		// so we must go for it. When finally resolved the original ExpressionProxy will be deregistered and
+		// the resolved beantypeproxy will be in its place.
+		if (beanTypeProxy != null && beanTypeProxy.isBeanProxy()) {
+			return (IBeanTypeProxy) beanTypeProxy;
+		}
+
+		// If not an array, then see if the package extension mechanism can find it.
+		// Do this here so that if it is found in the package extension we won't necessarily create an
+		// extra connection when not needed.
+		if (typeName.charAt(0) != '[') {
+			// It is not an array
+			// First check with the factory for the package of the class.
+			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
+			// the package ended and the class started.
+			int packageIndex = typeName.lastIndexOf('.');
+			if (packageIndex != -1) {
+				String packageName = typeName.substring(0, packageIndex);
+				IDEExtensionBeanTypeProxyFactory packageFactory = (IDEExtensionBeanTypeProxyFactory) fFactoryRegistry
+						.getBeanTypeProxyFactoryExtension(packageName);
+				if (packageFactory != null) {
+					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName);
+					if (beanTypeProxy != null) {
+						registerBeanTypeProxy((IBeanTypeProxy) beanTypeProxy, false);
+						return (IBeanTypeProxy) beanTypeProxy;
+					}
+				}
+			}
+			// There was not a registered factory that dealt with the class. Load it using the factory
+			// registry which has the plugin's class loader
+			try {
+				Class ideClass = fFactoryRegistry.loadClass(typeName);
+				IDEBeanTypeProxy superTypeProxy = null;
+				if (ideClass.getSuperclass() != null) {
+					// Get the beantype proxy of the superclass.
+					superTypeProxy = (IDEBeanTypeProxy) getBeanTypeProxy(ideClass.getSuperclass());
+				}
+
+				// Ask the supertype
+				// to create a beantype proxy of the same beantype proxy class.
+				// This is so that any subclasses will get the same beantype proxy class
+				// for it if it is special.
+				if (superTypeProxy != null)
+					beanTypeProxy = superTypeProxy.newBeanTypeForClass(ideClass);
+
+				if (beanTypeProxy == null)
+					beanTypeProxy = new IDEBeanTypeProxy(fFactoryRegistry, ideClass);
+			} catch (ClassNotFoundException e) {
+				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.INFO, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e));
+				String msg = MessageFormat.format("{0}({1})", new Object[] { e.getClass(), e.getMessage()}); //$NON-NLS-1$
+				beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg);
+			} catch (ExceptionInInitializerError e) {
+				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e));
+				String msg = MessageFormat.format("{0}({1})", new Object[] { e.getClass(), e.getMessage()}); //$NON-NLS-1$
+				beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg);
+			} catch (LinkageError e) {
+				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e));
+				String msg = MessageFormat.format("{0}({1})", new Object[] { e.getClass(), e.getMessage()}); //$NON-NLS-1$
+				beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg);
+			}
+
+			// Cache the instance so we can re-use it again
+			beanProxies.put(typeName, beanTypeProxy);
+			return (IBeanTypeProxy) beanTypeProxy;
+		} else {
+			// need to create a array of this many dimensions so that we can get the appropriate class for it.
+			int dims = typeName.lastIndexOf('[') + 1;
+			Class finalComponentType = null;
+			if (typeName.charAt(dims) == 'L') {
+				// It is a class.
+				// Strip off up to the 'L', and the trailing ';'. That is the class name.
+				IDEBeanTypeProxy finalType = (IDEBeanTypeProxy) getBeanTypeProxy(typeName.substring(dims + 1, typeName.length() - 1));
+				if (finalType != null)
+					finalComponentType = finalType.fClass;
+			} else {
+				// It is a type. Need to map it.
+				finalComponentType = (Class) IDEStandardBeanTypeProxyFactory.MAP_SHORTSIG_TO_TYPE.get(typeName.substring(dims, dims + 1));
+			}
+
+			if (finalComponentType != null) {
+				Object dummyArray = Array.newInstance(finalComponentType, new int[dims]);
+				beanTypeProxy = new IDEArrayBeanTypeProxy(fFactoryRegistry, typeName, dummyArray.getClass());
+				beanProxies.put(typeName, beanTypeProxy);
+			}
+			return (IBeanTypeProxy) beanTypeProxy;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IExpression,
+	 *      java.lang.String)
+	 */
+	public synchronized IProxyBeanType getBeanTypeProxy(IExpression expression, String typeName) {
+		typeName = MapTypes.getJNIFormatName(typeName);
+
+		// See whether we already have the proxy for the argument name
+		IProxyBeanType beanTypeProxy = (IProxyBeanType) beanProxies.get(typeName);
+		if (beanTypeProxy != null) { return beanTypeProxy; }
+		
+		// Now see if an expression proxy cached.
+		beanTypeProxy = ((IDEExpression) expression).getBeanType(typeName);
+		if (beanTypeProxy != null)
+			return beanTypeProxy;		
+
+
+		// If not an array, then see if the package extension mechanism can find it.
+		// Do this here so that if it is found in the package extension we won't necessarily create an
+		// extra connection when not needed.
+		if (typeName.charAt(0) != '[') {
+			// It is not an array
+			// First check with the factory for the package of the class.
+			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
+			// the package ended and the class started.
+			int packageIndex = typeName.lastIndexOf('.');
+			if (packageIndex != -1) {
+				String packageName = typeName.substring(0, packageIndex);
+				IDEExtensionBeanTypeProxyFactory packageFactory = (IDEExtensionBeanTypeProxyFactory) fFactoryRegistry
+						.getBeanTypeProxyFactoryExtension(packageName);
+				if (packageFactory != null) {
+					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName, expression);
+					if (beanTypeProxy != null) {
+						registerBeanTypeProxy(beanTypeProxy, false);
+						return beanTypeProxy;
+					}
 				}
 			}
 		}
-		// There was not a registered factory that dealt with the class.  Load it using the factory
-		// registry which has the plugin's class loader
-		try {
-			Class ideClass = fFactoryRegistry.loadClass(typeName);
-			IDEBeanTypeProxy superTypeProxy = null;
-			if (ideClass.getSuperclass() != null) {
-				// Get the beantype proxy of the superclass.
-				superTypeProxy = (IDEBeanTypeProxy) getBeanTypeProxy(ideClass.getSuperclass());
-			}
-			
-			// Ask the supertype
-			// to create a beantype proxy of the same beantype proxy class.
-			// This is so that any subclasses will get the same beantype proxy class
-			// for it if it is special.			
-			if (superTypeProxy != null)
-				beanTypeProxy = superTypeProxy.newBeanTypeForClass(ideClass);
-			
-			if (beanTypeProxy == null) 
-				beanTypeProxy = new IDEBeanTypeProxy(fFactoryRegistry, ideClass);
-		} catch (ClassNotFoundException e) {
-			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.INFO, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e));
-			String msg = MessageFormat.format("{0}({1})", new Object[] {e.getClass(), e.getMessage()}); //$NON-NLS-1$
-			beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg);
-		} catch (ExceptionInInitializerError e) {
-			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e));
-			String msg = MessageFormat.format("{0}({1})", new Object[] {e.getClass(), e.getMessage()}); //$NON-NLS-1$
-			beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg);
-		} catch (LinkageError e) {
-			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e));
-			String msg = MessageFormat.format("{0}({1})", new Object[] {e.getClass(), e.getMessage()}); //$NON-NLS-1$
-			beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg);
-		}
 
-		// Cache the instance so we can re-use it again
-		beanProxies.put(typeName, beanTypeProxy);
+		// There was not a registered factory that dealt with the class. So create the expression proxy.
+		beanTypeProxy = ((Expression) expression).createBeanTypeExpressionProxy(typeName);
+		registerBeanTypeProxy(beanTypeProxy, false);
 		return beanTypeProxy;
-	} else {
-		// need to create a array of this many dimensions so that we can get the appropriate class for it.
-		int dims = typeName.lastIndexOf('[')+1;
-		Class finalComponentType = null;
-		if (typeName.charAt(dims) == 'L') {
-			// It is a class.
-			// Strip off up to the 'L', and the trailing ';'. That is the class name.
-			IDEBeanTypeProxy finalType = (IDEBeanTypeProxy) getBeanTypeProxy(typeName.substring(dims+1, typeName.length()-1));
-			if (finalType != null)
-				finalComponentType = finalType.fClass;
-		} else {
-			// It is a type. Need to map it.
-			finalComponentType = (Class) IDEStandardBeanTypeProxyFactory.MAP_SHORTSIG_TO_TYPE.get(typeName.substring(dims, dims+1));
-		}
-		
-		if (finalComponentType != null) {
-			Object dummyArray = Array.newInstance(finalComponentType, new int[dims]);
-			beanTypeProxy = new IDEArrayBeanTypeProxy(fFactoryRegistry, typeName, dummyArray.getClass());
-			beanProxies.put(typeName,beanTypeProxy);
-		}
-		return beanTypeProxy;
+
 	}
-}
-/**
- * Return an Array type proxy for the given class name of
- * the specified dimensions. This is a helper method. The
- * same result can be gotton from getBeanTypeProxy.
- * e.g.
- *      getBeanTypeProxy("java.lang.Object", 3)
- *    is the same as:
- *      getBeanTypeProxy("[[[Ljava.lang.Object;")
- *
- *    They both result in a type of:
- *      Object [][][]
- *
- *    or
- *      getBeanTypeProxy("[Ljava.langObject;", 3)
- *    becomes
- *      Object [][][][]
- */
-public IBeanTypeProxy getBeanTypeProxy(String componentClassName, int dimensions) {
-	String jniComponentTypeName = MapTypes.getJNIFormatName(componentClassName);
-	String compType = jniComponentTypeName;
-	if (jniComponentTypeName.charAt(0) != '[') {
-		// We're not already an array, so create correct template.
-		compType = (String) MAP_TYPENAME_TO_SHORTSIG.get(componentClassName);
-		if (compType == null) {
-			// It is a class, and not a type.
-			compType = "L"+jniComponentTypeName+";"; //$NON-NLS-1$ //$NON-NLS-2$
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(java.lang.String, int)
+	 */
+	public IBeanTypeProxy getBeanTypeProxy(String componentClassName, int dimensions) {
+		return getBeanTypeProxy(getArrayClassname(componentClassName, dimensions));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IExpression,
+	 *      java.lang.String, int)
+	 */
+	public IProxyBeanType getBeanTypeProxy(IExpression expression, String componentClassName, int dimensions) {
+		return getBeanTypeProxy(expression, getArrayClassname(componentClassName, dimensions));
+	}
+
+	/**
+	 * @param componentClassName
+	 * @param dimensions
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	protected String getArrayClassname(String componentClassName, int dimensions) {
+		String jniComponentTypeName = MapTypes.getJNIFormatName(componentClassName);
+		String compType = jniComponentTypeName;
+		if (jniComponentTypeName.charAt(0) != '[') {
+			// We're not already an array, so create correct template.
+			compType = (String) MAP_TYPENAME_TO_SHORTSIG.get(componentClassName);
+			if (compType == null) {
+				// It is a class, and not a type.
+				compType = "L" + jniComponentTypeName + ";"; //$NON-NLS-1$ //$NON-NLS-2$
+			}
 		}
-	}	
-	// Now create it with the appropriate number of '[' in front.
-	StringBuffer buffer = new StringBuffer(dimensions+compType.length());
-	for (int i=0; i<dimensions; i++)
-		buffer.append('[');
-	buffer.append(compType);
-	return getBeanTypeProxy(buffer.toString());
-}
+		// Now create it with the appropriate number of '[' in front.
+		StringBuffer buffer = new StringBuffer(dimensions + compType.length());
+		for (int i = 0; i < dimensions; i++)
+			buffer.append('[');
+		buffer.append(compType);
+		return buffer.toString();
+	}
 
-/*
- *  (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IBeanProxyFactory#terminateFactory(boolean)
- */
-public void terminateFactory(boolean wait){
-}
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IBeanProxyFactory#terminateFactory(boolean)
+	 */
+	public void terminateFactory(boolean wait) {
+	}
 
-/**
- * registerBeanTypeProxy.
- * Register this bean type proxy on behalf of the
- * custom factory. This is so that during initializations,
- * the custom factory can cache specific bean type proxies
- * ahead of time. 
- */
-public synchronized void registerBeanTypeProxy(IBeanTypeProxy aBeanTypeProxy,boolean permanent){
-	beanProxies.put(aBeanTypeProxy.getTypeName(), aBeanTypeProxy);
-}
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeRegistered(String)
- */
-public synchronized boolean isBeanTypeRegistered(String className) {
-	return beanProxies.containsKey(MapTypes.getJNIFormatName(className));
-}
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registerBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IBeanTypeProxy,
+	 *      boolean)
+	 */
+	public synchronized void registerBeanTypeProxy(IBeanTypeProxy aBeanTypeProxy, boolean permanent) {
+		beanProxies.put(aBeanTypeProxy.getTypeName(), aBeanTypeProxy);
+	}
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registeredTypes()
- */
-public Set registeredTypes() {
-	return beanProxies.keySet();
-}
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registerBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType,
+	 *      boolean)
+	 */
+	public void registerBeanTypeProxy(IProxyBeanType aProxyBeanType, boolean permanent) {
+		if (aProxyBeanType.isBeanProxy())
+			registerBeanTypeProxy((IBeanTypeProxy) aProxyBeanType, permanent); // A regular kind, do regular registration.
+		else {
+			ExpressionProxy beanExpressionProxy = ((ExpressionProxy) aProxyBeanType);
+			final String typeName = aProxyBeanType.getTypeName();
+			((IDEExpression) beanExpressionProxy.getExpression()).addBeanType(typeName, aProxyBeanType);
+			beanExpressionProxy.addProxyListener(new ExpressionProxy.ProxyAdapter() {
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeNotFound(String)
- */
-public boolean isBeanTypeNotFound(String className) {
-	// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found. 
-	// In that case an IDEInitErrorBeanTypeProxy will be created.
-	return false;
-}
+				public void proxyResolved(ProxyEvent event) {
+					String typeName = ((IProxyBeanType) event.getSource()).getTypeName();
+					synchronized (IDEStandardBeanTypeProxyFactory.this) {
+						if (!beanProxies.containsKey(typeName)) {
+							// It hasn't been resolved through some other means. So this is good. Actually this should never
+							// occur because upon resolution we've already registered the bean type proxy through the
+							// normal mechanisms. But to be safe, we'll do it here.
+							beanProxies.put(typeName, event.getProxy());
+						}
+					}
+				}
+				
+				public void proxyNotResolved(ExpressionProxy.ProxyEvent event) {
+					((IDEExpression) ((ExpressionProxy) event.getSource()).getExpression()).removeBeanType(typeName);
+				}
+			});
+		}
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isMaintainNotFoundTypes()
- */
-public boolean isMaintainNotFoundTypes() {
-	// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found. 
-	// In that case an IDEInitErrorBeanTypeProxy will be created.
-	return false;
-}
+	}
 
-/* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#setMaintainNotFoundTypes(boolean)
- */
-public void setMaintainNotFoundTypes(boolean maintain) {
-	// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found. 
-	// In that case an IDEInitErrorBeanTypeProxy will be created.
-}
-}
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeRegistered(String)
+	 */
+	public synchronized boolean isBeanTypeRegistered(String className) {
+		return beanProxies.containsKey(MapTypes.getJNIFormatName(className));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registeredTypes()
+	 */
+	public Set registeredTypes() {
+		return beanProxies.keySet();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeNotFound(String)
+	 */
+	public boolean isBeanTypeNotFound(String className) {
+		// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found.
+		// In that case an IDEInitErrorBeanTypeProxy will be created.
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isMaintainNotFoundTypes()
+	 */
+	public boolean isMaintainNotFoundTypes() {
+		// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found.
+		// In that case an IDEInitErrorBeanTypeProxy will be created.
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#setMaintainNotFoundTypes(boolean)
+	 */
+	public void setMaintainNotFoundTypes(boolean maintain) {
+		// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found.
+		// In that case an IDEInitErrorBeanTypeProxy will be created.
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEThrowableProxy.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEThrowableProxy.java
index 7e4a1da..f1ccaa1 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEThrowableProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/IDEThrowableProxy.java
@@ -11,18 +11,17 @@
 package org.eclipse.jem.internal.proxy.ide;
 /*
  *  $RCSfile: IDEThrowableProxy.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import org.eclipse.jem.internal.proxy.core.*;
 
 public class IDEThrowableProxy extends ThrowableProxy implements IIDEBeanProxy {
 
-	protected Throwable fExc;
 	protected IBeanTypeProxy fBeanTypeProxy;
 
 	protected IDEThrowableProxy(Throwable exc, IBeanTypeProxy aBeanTypeProxy) {
-		fExc = exc;
+		super(exc);
 		fBeanTypeProxy = aBeanTypeProxy;
 	}
 
@@ -30,7 +29,7 @@
 		if (super.equals(obj))
 			return true;
 		if (obj instanceof IIDEBeanProxy) {
-			return fExc.equals(((IIDEBeanProxy) obj).getBean());
+			return getCause().equals(((IIDEBeanProxy) obj).getBean());
 		}
 		return false;
 	}
@@ -42,24 +41,24 @@
 		if (this == aBeanProxy)
 			return true;
 		if (aBeanProxy instanceof IIDEBeanProxy)
-			return fExc == ((IIDEBeanProxy) aBeanProxy).getBean();
+			return getCause() == ((IIDEBeanProxy) aBeanProxy).getBean();
 		return false;
 	}
 
 	public String getProxyLocalizedMessage() {
-		return fExc.getLocalizedMessage();
+		return getCause().getLocalizedMessage();
 	}
 	public String getProxyMessage() {
-		return fExc.getMessage();
+		return getCause().getMessage();
 	}
 	public void printProxyStackTrace(java.io.PrintWriter writer) {
-		fExc.printStackTrace(writer);
+		getCause().printStackTrace(writer);
 	}
 	public void printProxyStackTrace(java.io.PrintStream stream) {
-		fExc.printStackTrace(stream);
+		getCause().printStackTrace(stream);
 	}
 	public void printProxyStackTrace() {
-		fExc.printStackTrace();
+		getCause().printStackTrace();
 	}
 	public IBeanTypeProxy getTypeProxy() {
 		return fBeanTypeProxy;
@@ -68,7 +67,7 @@
 		return fBeanTypeProxy.getProxyFactoryRegistry();
 	}
 	public String toBeanString() {
-		return fExc.toString();
+		return getCause().toString();
 	}
 	public boolean isValid() {
 		return true;
@@ -77,7 +76,19 @@
 	 * Return the exception which is the live bean
 	 */
 	public Object getBean() {
-		return fExc;
+		return getCause();
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isBeanProxy()
+	 */
+	public final boolean isBeanProxy() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IProxy#isExpressionProxy()
+	 */
+	public final boolean isExpressionProxy() {
+		return false;
+	}
 }
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEDimensionBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEDimensionBeanProxy.java
index 67d9327..8d039a8 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEDimensionBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEDimensionBeanProxy.java
@@ -11,14 +11,16 @@
 package org.eclipse.jem.internal.proxy.ide.awt;
 /*
  *  $RCSfile: IDEDimensionBeanProxy.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
-import org.eclipse.jem.internal.proxy.core.*;
-import org.eclipse.jem.internal.proxy.ide.*;
-import org.eclipse.jem.internal.proxy.awt.*;
 import java.awt.Dimension;
 
+import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
+import org.eclipse.jem.internal.proxy.core.IDimensionBeanProxy;
+import org.eclipse.jem.internal.proxy.ide.IDEObjectBeanProxy;
+import org.eclipse.jem.internal.proxy.ide.IDEProxyFactoryRegistry;
+
 public class IDEDimensionBeanProxy extends IDEObjectBeanProxy implements IDimensionBeanProxy {
 	
 	protected Dimension fDimension;
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEPointBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEPointBeanProxy.java
index 61ba3f9..149ad21 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEPointBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEPointBeanProxy.java
@@ -11,14 +11,16 @@
 package org.eclipse.jem.internal.proxy.ide.awt;
 /*
  *  $RCSfile: IDEPointBeanProxy.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
-import org.eclipse.jem.internal.proxy.core.*;
-import org.eclipse.jem.internal.proxy.ide.*;
-import org.eclipse.jem.internal.proxy.awt.*;
 import java.awt.Point;
 
+import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
+import org.eclipse.jem.internal.proxy.core.IPointBeanProxy;
+import org.eclipse.jem.internal.proxy.ide.IDEObjectBeanProxy;
+import org.eclipse.jem.internal.proxy.ide.IDEProxyFactoryRegistry;
+
 public class IDEPointBeanProxy extends IDEObjectBeanProxy implements IPointBeanProxy {
 	
 	protected Point fPoint;
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDERectangleBeanProxy.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDERectangleBeanProxy.java
index 3a4fa41..b566391 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDERectangleBeanProxy.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDERectangleBeanProxy.java
@@ -11,14 +11,15 @@
 package org.eclipse.jem.internal.proxy.ide.awt;
 /*
  *  $RCSfile: IDERectangleBeanProxy.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
-import org.eclipse.jem.internal.proxy.core.*;
-import org.eclipse.jem.internal.proxy.ide.*;
-import org.eclipse.jem.internal.proxy.awt.*;
 import java.awt.Rectangle;
 
+import org.eclipse.jem.internal.proxy.core.*;
+import org.eclipse.jem.internal.proxy.ide.IDEObjectBeanProxy;
+import org.eclipse.jem.internal.proxy.ide.IDEProxyFactoryRegistry;
+
 public class IDERectangleBeanProxy extends IDEObjectBeanProxy implements IRectangleBeanProxy {
 	
 	protected Rectangle fRectangle;
diff --git a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEStandardAWTBeanTypeProxyFactory.java b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEStandardAWTBeanTypeProxyFactory.java
index 35ef089..53707b9 100644
--- a/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEStandardAWTBeanTypeProxyFactory.java
+++ b/plugins/org.eclipse.jem.proxy/proxyide/org/eclipse/jem/internal/proxy/ide/awt/IDEStandardAWTBeanTypeProxyFactory.java
@@ -1,4 +1,3 @@
-package org.eclipse.jem.internal.proxy.ide.awt;
 /*******************************************************************************
  * Copyright (c)  2001, 2003, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials 
@@ -11,56 +10,76 @@
  *******************************************************************************/
 /*
  *  $RCSfile: IDEStandardAWTBeanTypeProxyFactory.java,v $
- *  $Revision: 1.3 $  $Date: 2005/02/15 22:57:26 $ 
+ *  $Revision: 1.4 $  $Date: 2005/05/11 19:01:12 $ 
  */
+package org.eclipse.jem.internal.proxy.ide.awt;
 
-import org.eclipse.jem.internal.proxy.ide.*;
 import org.eclipse.jem.internal.proxy.core.*;
+import org.eclipse.jem.internal.proxy.ide.*;
+
 /**
- * BeanType factory standard AWT bean types.
- * This is package protected because it shouldn't be
- * referenced outside the package. It should only be accessed through
- * the interface.
+ * BeanType factory standard AWT bean types. This is package protected because it shouldn't be referenced outside the package. It should only be
+ * accessed through the interface.
  */
 class IDEStandardAWTBeanTypeProxyFactory implements IDEExtensionBeanTypeProxyFactory {
 
 	static final String BEAN_TYPE_FACTORY_KEY = "java.awt"; //$NON-NLS-1$
-	
+
 	protected final IDEProxyFactoryRegistry fFactoryRegistry;
+
 	protected final IDEDimensionBeanTypeProxy dimensionType;
+
 	protected final IDEPointBeanTypeProxy pointType;
+
 	protected final IDERectangleBeanTypeProxy rectangleType;
-	
-IDEStandardAWTBeanTypeProxyFactory(IDEProxyFactoryRegistry aRegistry) {
-	fFactoryRegistry = aRegistry;	
-	fFactoryRegistry.registerBeanTypeProxyFactory(BEAN_TYPE_FACTORY_KEY, this);
-	dimensionType = new IDEDimensionBeanTypeProxy(fFactoryRegistry);
-	pointType = new IDEPointBeanTypeProxy(fFactoryRegistry);
-	rectangleType = new IDERectangleBeanTypeProxy(fFactoryRegistry);
-}
-/**
- * Create the correct beantype from the class and id passed in.
- */
-public IDEBeanTypeProxy getExtensionBeanTypeProxy(String className){
-	
-	if ("java.awt.Dimension".equals(className)) //$NON-NLS-1$
-		return dimensionType;
-	else if ("java.awt.Point".equals(className)) //$NON-NLS-1$
-		return pointType;
-	else if ("java.awt.Rectangle".equals(className)) //$NON-NLS-1$
-		return rectangleType;
-	else 
-		return null;
-}
 
-/**
- * Create the correct beantype from the class and id passed in.
- */
-public IDEBeanTypeProxy getExtensionBeanTypeProxy(String className, IBeanTypeProxy beanTypeProxy){
+	IDEStandardAWTBeanTypeProxyFactory(IDEProxyFactoryRegistry aRegistry) {
+		fFactoryRegistry = aRegistry;
+		fFactoryRegistry.registerBeanTypeProxyFactory(BEAN_TYPE_FACTORY_KEY, this);
+		dimensionType = new IDEDimensionBeanTypeProxy(fFactoryRegistry);
+		pointType = new IDEPointBeanTypeProxy(fFactoryRegistry);
+		rectangleType = new IDERectangleBeanTypeProxy(fFactoryRegistry);
+	}
 
-	return getExtensionBeanTypeProxy(className);
-}
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.ide.IDEExtensionBeanTypeProxyFactory#getExtensionBeanTypeProxy(java.lang.String)
+	 */
+	public IDEBeanTypeProxy getExtensionBeanTypeProxy(String className) {
 
-public void terminateFactory(boolean wait){
-}
-}
+		if ("java.awt.Dimension".equals(className)) //$NON-NLS-1$
+			return dimensionType;
+		else if ("java.awt.Point".equals(className)) //$NON-NLS-1$
+			return pointType;
+		else if ("java.awt.Rectangle".equals(className)) //$NON-NLS-1$
+			return rectangleType;
+		else
+			return null;
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.ide.IDEExtensionBeanTypeProxyFactory#getExtensionBeanTypeProxy(java.lang.String, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
+	 */
+	public IDEBeanTypeProxy getExtensionBeanTypeProxy(String className, IBeanTypeProxy beanTypeProxy) {
+
+		return getExtensionBeanTypeProxy(className);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.internal.proxy.ide.IDEExtensionBeanTypeProxyFactory#getExtensionBeanTypeProxy(java.lang.String,
+	 *      org.eclipse.jem.internal.proxy.core.IExpression)
+	 */
+	public IProxyBeanType getExtensionBeanTypeProxy(String typeName, IExpression expression) {
+		return getExtensionBeanTypeProxy(typeName);
+	}
+
+	/*
+	 *  (non-Javadoc)
+	 * @see org.eclipse.jem.internal.proxy.core.IBeanProxyFactory#terminateFactory(boolean)
+	 */
+	public void terminateFactory(boolean wait) {
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/CommandErrorException.java b/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/CommandErrorException.java
index 14e21c5..c3042e7 100644
--- a/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/CommandErrorException.java
+++ b/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/CommandErrorException.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.common.remote;
 /*
  *  $RCSfile: CommandErrorException.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:56:39 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import org.eclipse.jem.internal.proxy.common.CommandException;
@@ -32,7 +32,7 @@
 	}
 	
 	public CommandErrorException(String msg, int errorCode, Commands.ValueObject errorData, Object errorObject) {
-		super(msg, errorData);
+		super(msg, errorData.clone());
 		fErrorObject = errorObject;
 		fErrorCode = errorCode;		
 	}
diff --git a/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/Commands.java b/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/Commands.java
index 8038136..ed834c3 100644
--- a/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/Commands.java
+++ b/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/Commands.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.common.remote;
 /*
  *  $RCSfile: Commands.java,v $
- *  $Revision: 1.12 $  $Date: 2005/02/15 22:56:39 $ 
+ *  $Revision: 1.13 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.io.*;
@@ -149,9 +149,10 @@
 		OBJECT_ID = 50,	// Object identity key - writeInt
 		NEW_OBJECT_ID = 51,	// New Object identity (this is a new object that didn't exist before)
 		THROW = 52,	// An exception occured. The value is a throwable, it is of the same format as NEW_OBJECT_ID.
-		ARRAY_IDS = 53;	// An array of values, where there are at least one ID in the array. If there were no
+		ARRAY_IDS = 53,	// An array of values, where there are at least one ID in the array. If there were no
 						// ID's (i.e. all just values), then use OBJECT type intead and have it written as
 						// writeObject.
+		FLAG = 54;	// The value is a flag int. If this is allowed on a read, the anInt field will contain the flag value.
 				
 		
 		
@@ -355,6 +356,11 @@
 	 * sent, then the primitive field will be set instead, though the type
 	 * will still be the Object type (i.e. if type = L_BYTE, the aByte will
 	 * have the value in it).
+	 * 
+	 * Note: Also flags can be send back. The type will be FLAG and the anInt field will be the
+	 * flag value. This is used to indicate special things that aren't values. Most useful in
+	 * arrays where one of the entries is not a value. This can only be used if readValue
+	 * is passed a flag indicating flags are valid, otherwise it will be treated as not valie.
 	 */
 	public static class ValueObject implements Cloneable {
 		public byte type;	// Same as the types above
@@ -424,6 +430,16 @@
 		}
 		
 		/**
+		 * Get the type as one of the valid Commands.Types. VOID, BYTE, L_BYTE, etc.
+		 * @return
+		 * 
+		 * @since 1.1.0
+		 */
+		public int getType() {
+			return type;
+		}
+		
+		/**
 		 * Special getter to get the type as an Object, this is used by invoke for example.
 		 */
 		public Object getAsObject() {
@@ -509,6 +525,12 @@
 			type = VOID;
 			anObject = null;
 		}
+		
+		public void setFlag(int flag) {
+			type = FLAG;
+			anInt = flag;
+		}
+		
 		public void set(byte value) {
 			type = BYTE;
 			aByte = value;
@@ -681,9 +703,34 @@
 	public static final Object SOME_UNEXPECTED_EXCEPTION = "SOME_UNEXPECTED_EXCEPTION";	// There was some kind of exception that wasn't expected. The data will be the exception. //$NON-NLS-1$
 	public static final Object TOO_MANY_BYTES = "TOO_MANY_BYTES";			// Too many bytes were sent on a writeBytes. It was //$NON-NLS-1$
 																		// more than could be read into the buffer. The data will be the size sent.
-	
-	
-	public static void readValue(DataInputStream is, ValueObject value) throws CommandException {
+
+	/**
+	 * Read a value from the stream into the value object. It will not allow values of type FLAG.
+	 * 
+	 * @param is
+	 * @param value
+	 * @param allowFlag
+	 * @return the value object sent in. This allows <code>value = Commands.readValue(is, new Commands.ValueObject());</code> 
+	 * @throws CommandException
+	 * 
+	 * 
+	 * @since 1.0.0
+	 */
+	public static ValueObject readValue(DataInputStream is, ValueObject value) throws CommandException {
+		readValue(is, value, false);
+		return value;
+	}
+
+	/**
+	 * Read a value from the stream into the value object. It will allow values of type FLAG if allowFlag is true.
+	 * @param is
+	 * @param value
+	 * @param allowFlag <code>true</code> if values of type flag are allow.
+	 * @throws CommandException
+	 * 
+	 * @since 1.1.0
+	 */
+	public static void readValue(DataInputStream is, ValueObject value, boolean allowFlag) throws CommandException {
 		try {
 			value.anObject = null;
 			value.type = is.readByte();
@@ -748,6 +795,12 @@
 					break;
 				case VOID:
 					break;
+				case FLAG:
+					if (allowFlag) {
+						value.anInt = is.readInt();
+						break;
+					}
+					// Flags not allowed, so drop into default.
 				default:
 					throw new UnexpectedCommandException(UNKNOWN_READ_TYPE, false, new Byte(value.type));
 			}
@@ -764,28 +817,48 @@
 	 * Special interface used to read back arrays. It will be called when 
 	 */
 	public static interface ValueSender {
-		// This is called for each entry from the array. It is assumed that the ValueSender has
-		// the array that is being built.
+		/**
+		 * This is called for each entry from the array. It is assumed that the ValueSender has
+		 * the array that is being built.
+		 * @param value
+		 * 
+		 * @since 1.1.0
+		 */
 		public void sendValue(ValueObject value);
-		
-		// This is called when an ARRAY_IDS is found within the reading of the array (i.e. nested arrays)
-		// It is asking for a new ValueSender to use while this nested array. The arrayValue contains
-		// the valueobject for the array header (i.e. the class id of the array and the number of elements).
-		// It is the responsibility of the ValueSender to store this array in the array that is being built.
+
+		/**
+		 * This is called when an ARRAY_IDS is found within the reading of the array (i.e. nested arrays)
+		 * It is asking for a new ValueSender to use while this nested array. The arrayValue contains
+		 * the valueobject for the array header (i.e. the class id of the array and the number of elements).
+		 * It is the responsibility of the ValueSender to store this array in the array that is being built.
+		 * @param arrayValue
+		 * @return
+		 * 
+		 * @since 1.1.0
+		 */
 		public ValueSender nestedArray(ValueObject arrayValue);
 		
+		/**
+		 * Called to initialize the sender with the given array header. This is not always called, each usage
+		 * knows whether it can be called or not. For example the implementation of nestedArray may not need to call initialize.
+		 * @param arrayHeader
+		 * 
+		 * @since 1.1.0
+		 */
+		public void initialize(ValueObject arrayHeader);
+		
 	}	
 	
 	/*
 	 * NOTE: It is important that on the IDE side that this is called within a transaction. 
 	 * If not, there could be some corruption if proxy cleanup occurs in the middle.
 	 */
-	public static void readArray(DataInputStream is, int arraySize, ValueSender valueSender, ValueObject value) throws CommandException {
+	public static void readArray(DataInputStream is, int arraySize, ValueSender valueSender, ValueObject value, boolean allowFlag) throws CommandException {
 		// Anything exception other than a CommandException, we will try to flush the input so that
 		// it can continue with the next command and not close the connection.
 		RuntimeException exception = null;
 		for (int i=0; i<arraySize; i++) {
-			readValue(is, value);
+			readValue(is, value, allowFlag);
 			if (exception == null) 
 				try {
 					if (value.type != ARRAY_IDS)
@@ -805,9 +878,11 @@
 								public ValueSender nestedArray(ValueObject arrayValue) {
 									return this;
 								}
+								public void initialize(ValueObject arrayHeader) {
+								}
 							};
 						}
-						readArray(is, value.anInt, nestedSender, value);
+						readArray(is, value.anInt, nestedSender, value, allowFlag);
 						if (exception != null)
 							throw exception;	// An exception ocurred in new sender request.
 					}
@@ -820,19 +895,31 @@
 			throw exception;
 	}
 				
-	
+
 	/**
 	 * Special interface to handle writing the ARRAY_IDS type.
 	 * An instance of this object will be in the valueObject sent to writeValue when the type of the value
 	 * is ARRAY_IDS. Then write value will know to call this interface to write out the values.
+	 * 
+	 * @since 1.1.0
 	 */
 	public static interface ValueRetrieve {
-		// This interface is used to retreive the next value object so that it can be written to the output stream.
-		// Return null when there are no more.
+		/**
+		 * Returns the next value object to send. It will be called the number of times that the size of 
+		 * the array was set to be send. 
+		 * @return The value object to send.
+		 * @throws EOFException
+		 * 
+		 * @since 1.1.0
+		 */
 		public ValueObject nextValue() throws EOFException;
 	}	
-	
+
 	public static void writeValue(DataOutputStream os, ValueObject value, boolean asValueCommand) throws CommandException  {
+		writeValue(os, value, asValueCommand, asValueCommand ? true : false);
+	}
+	
+	public static void writeValue(DataOutputStream os, ValueObject value, boolean asValueCommand, boolean flush) throws CommandException  {
 		try {
 			if (asValueCommand)
 				os.writeByte(VALUE);
@@ -907,23 +994,27 @@
 					// We are writing out an array with ID's in it. The fields of the vale object will be:
 					// 	classID: The class id of the component type of the array.
 					//  anObject: Contains the ValueRetriever to get the next value.
-					os.writeByte(value.type);
+					os.writeByte(ARRAY_IDS);	
 					os.writeInt(value.classID);
-					os.writeInt(value.anInt);
+					os.writeInt(value.anInt);	// The size of the array.
 					// Now comes the kludgy part, writing the values.
 					ValueRetrieve retriever = (ValueRetrieve) value.anObject;
-					ValueObject nextEntry = null;
-					while ((nextEntry = retriever.nextValue()) != null)
-						writeValue(os, nextEntry, false);
+					int len = value.anInt;
+					while (len-- > 0)
+						writeValue(os, retriever.nextValue(), false);
 					break;
 				case VOID:
 					os.writeByte(value.type);			
 					break;
+				case FLAG:
+					os.writeByte(FLAG);
+					os.writeInt(value.anInt);
+					break;
 				default:
 					os.writeByte(VOID);
 					throw new UnexpectedCommandException(UNKNOWN_WRITE_TYPE, true, value);					
 			}
-			if (asValueCommand)
+			if (flush)
 				os.flush();
 		} catch (CommandException e) {
 			// rethrow this exception since we want these to go on out.
diff --git a/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/ExpressionCommands.java b/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/ExpressionCommands.java
index a91ebdb..204c35c 100644
--- a/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/ExpressionCommands.java
+++ b/plugins/org.eclipse.jem.proxy/remoteCommon/org/eclipse/jem/internal/proxy/common/remote/ExpressionCommands.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: ExpressionCommands.java,v $
- *  $Revision: 1.3 $  $Date: 2005/02/15 22:56:39 $ 
+ *  $Revision: 1.4 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.common.remote;
 
@@ -34,10 +34,18 @@
 		END_EXPRESSION_TREE_PROCESSING = 2,
 		SYNC_REQUEST = 3,
 		PULL_VALUE_REQUEST = 4;
-	
+		
 	// These are the expression specific error codes (it can also send back general ones. See SYNC_REQUEST docs lower down).
 	public static final int
-		ExpressionNoExpressionValueException = Commands.MAX_ERROR_CODE+1;	// No expression value occurred.
+		EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION = Commands.MAX_ERROR_CODE+1;	// No expression value occurred.
+	
+	// These are the flag values sent in proxy resolution when doesn't resolve to proxy.
+	public static final int
+		EXPRESSIONPROXY_VOIDTYPE = 0,	// Expression proxy resolves to void type.
+		EXPRESSIONPROXY_NOTRESOLVED = 1;	// Expression proxy not resolved.
+
+	public static final String EXPRESSIONTRACE = "proxyvm.expressionTrace";	// The system property for turning on expression tracing.
+	public static final String EXPRESSIONTRACE_TIMER_THRESHOLD = "proxyvm.expressionTraceTimerThreshold";	// The system property for timer threshold.
 	
 	/*
 	 * The format of the commands are:
@@ -63,7 +71,7 @@
 	 * 	IDE will wait for it to complete and read back the value. It will send back:
 	 * 		1: VALUE command with boolean true as the value.
 	 * 		2: ERROR command with code of ExpressionClassNotFound, with value of String with message from exception.
-	 * 		3: ERROR command with code of ExpressionNoExpressionValueException, with value of String with message from exception.
+	 * 		3: ERROR command with code of EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION, with value of String with message from exception.
 	 * 		4: THROWABLE command with the actual exception that occurred.
 	 * 
 	 *
@@ -80,7 +88,7 @@
 	
 	/**
 	 * Send the start expression processing command.
-	 * @param expressionID TODO
+	 * @param expressionID 
 	 * @param os
 	 * 
 	 * @throws IOException
@@ -95,7 +103,7 @@
 	
 	/**
 	 * Send the end expression processing command.
-	 * @param expressionID TODO
+	 * @param expressionID 
 	 * @param os
 	 * 
 	 * @throws IOException
@@ -111,7 +119,7 @@
 	
 	/**
 	 * Send an expression subcommand.
-	 * @param expressionID TODO
+	 * @param expressionID 
 	 * @param os
 	 * @param subcommand
 	 * 
@@ -162,7 +170,7 @@
 	 * @since 1.0.0
 	 */
 	public static void sendString(DataOutputStream os, String aString) throws IOException {
-		os.writeUTF(aString);
+		Commands.sendStringData(os, aString);
 	}
 	
 	/**
@@ -179,26 +187,32 @@
 	}
 	
 	/**
-	 * Send the pull value command. Return either the value or an error (NoValueExpressionException or a Throwable)>
-	 * @param expressionID TODO
+	 * Send the pull value command. After processing the proxies, caller should call getFinalValue() to get the value.
+	 * @param expressionID 
 	 * @param os
 	 * @param is
-	 * @param valueReturn
+	 * @param proxyids if not <code>null</code>, then this is the list of expression proxy ids that need to be returned as rendered.
+	 * @param sender sender used to process the resolved proxy ids, or <code>null</code> if no proxy ids.
 	 * @throws CommandException
 	 * 
 	 * @since 1.0.0
 	 */
-	public static void sendPullValueCommand(int expressionID, DataOutputStream os, DataInputStream is, Commands.ValueObject valueReturn) throws CommandException {
+	public static void sendPullValueCommand(int expressionID, DataOutputStream os, DataInputStream is, Commands.ValueObject proxyids, Commands.ValueSender sender) throws CommandException {
 		try {
 			os.writeByte(Commands.EXPRESSION_TREE_COMMAND);
 			os.writeInt(expressionID);
 			os.writeByte(PULL_VALUE_REQUEST);
+			sendProxyIDs(os, proxyids);
 			os.flush();
-			Commands.readBackValue(is, valueReturn, Commands.NO_TYPE_CHECK);
+			if (proxyids != null) {
+				Commands.readBackValue(is, proxyids, Commands.ARRAY_IDS);	// Read the array header.
+				sender.initialize(proxyids);
+				Commands.readArray(is, proxyids.anInt, sender, proxyids, true);	// Read the array.
+			}
 		} catch (CommandException e) {
 			// rethrow this exception since we want these to go on out.
 			throw e;
-		} catch (Exception e) {
+		} catch (IOException e) {
 			// Wrapper this one.
 			throw new UnexpectedExceptionCommandException(false, e);
 		}		
@@ -206,24 +220,30 @@
 	
 	/**
 	 * Send a sync command. This does a synchronize with the remote expression processor. It makes sure that the
-	 * stream is caught and doesn't return until everything on the stream has been processed. It will then return a
-	 * value. The value should <code>true</code> if everything is OK, it could be an error return,
-	 * @param expressionID TODO
+	 * stream is caught and doesn't return until everything on the stream has been processed. Should then call
+	 * getFinalValue() to verify the expression is valid.
+	 * @param expressionID 
 	 * @param os
 	 * @param is
-	 * @param returnValue
+	 * @param proxyids if not <code>null</code>, then this is the list of expression proxy ids that need to be returned as rendered.
+	 * @param sender the sender used for reading back the proxyid resolutions, or <code>null</code> if no proxy ids.
 	 * 
 	 * @throws CommandException
 	 * 
 	 * @since 1.0.0
 	 */
-	public static void sendSyncCommand(int expressionID, DataOutputStream os, DataInputStream is, Commands.ValueObject returnValue) throws CommandException {
+	public static void sendSyncCommand(int expressionID, DataOutputStream os, DataInputStream is, Commands.ValueObject proxyids, Commands.ValueSender sender) throws CommandException {
 		try {
 			os.writeByte(Commands.EXPRESSION_TREE_COMMAND);
 			os.writeInt(expressionID);
 			os.writeByte(SYNC_REQUEST);
+			sendProxyIDs(os, proxyids);
 			os.flush();
-			Commands.readBackValue(is, returnValue, Commands.NO_TYPE_CHECK);
+			if (proxyids != null) {
+				Commands.readBackValue(is, proxyids, Commands.ARRAY_IDS);	// Read the array header.
+				sender.initialize(proxyids);
+				Commands.readArray(is, proxyids.anInt, sender, proxyids, true);	// Read the array.
+			}
 		} catch (CommandException e) {
 			// rethrow this exception since we want these to go on out.
 			throw e;
@@ -233,6 +253,23 @@
 		}		
 	}	
 	
+	/**
+	 * Send the proxyids (if not null) as part of a command. Used by sync and pullValue.
+	 * @param os
+	 * @param proxyids <code>null</code> if not requesting proxy ids.
+	 * @throws IOException
+	 * @throws CommandException
+	 * 
+	 * @since 1.1.0
+	 */
+	private static void sendProxyIDs(DataOutputStream os, Commands.ValueObject proxyids) throws IOException, CommandException {
+		if (proxyids != null) {
+			os.writeBoolean(true);	// Indicates proxy ids being sent.
+			Commands.writeValue(os, proxyids, false, false);
+		} else
+			os.writeBoolean(false);	// No proxyids being sent.
+	}
+
 	private ExpressionCommands() {
 		// Never intended to be instantiated.
 	}
diff --git a/plugins/org.eclipse.jem.proxy/schema/contributors.exsd b/plugins/org.eclipse.jem.proxy/schema/contributors.exsd
index cface6b..972d3fb 100644
--- a/plugins/org.eclipse.jem.proxy/schema/contributors.exsd
+++ b/plugins/org.eclipse.jem.proxy/schema/contributors.exsd
@@ -106,7 +106,7 @@
   &lt;contributor
    class=&quot;com.example.ContributorImplementation&quot;
    container=&quot;MY_CONTAINER&quot;&gt;
-  &lt;contributor&gt;
+  &lt;/contributor&gt;
  &lt;/extension&gt;
 &lt;/pre&gt;
 &lt;/p&gt;
diff --git a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/AWTStarter.java b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/AWTStarter.java
new file mode 100644
index 0000000..761f48e
--- /dev/null
+++ b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/AWTStarter.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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: AWTStarter.java,v $
+ *  $Revision: 1.1 $  $Date: 2005/05/11 19:01:12 $ 
+ */
+package org.eclipse.jem.internal.proxy.vm.remote;
+
+import java.awt.Toolkit;
+ 
+
+/**
+ * This class is used to do start the AWT eventqueue ahead of time to try to parallel process it.
+ * @since 1.1.0
+ */
+public class AWTStarter {
+
+	public static void startAWT() {
+		Thread t = new Thread() {
+			public void run() {
+				Thread.yield();	// So as not to possibly hold up the guy doing the starting.
+				Toolkit.getDefaultToolkit();
+			}
+		};
+		t.start();
+	}
+}
diff --git a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/CallbackHandler.java b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/CallbackHandler.java
index 3568630..73d50b7 100644
--- a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/CallbackHandler.java
+++ b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/CallbackHandler.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.vm.remote;
 /*
  *  $RCSfile: CallbackHandler.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:57:54 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 import java.net.Socket;
@@ -106,24 +106,21 @@
 		}
 		
 		public Commands.ValueObject nextValue() {
-			if (index < array.length) {
-				Object parm = array[index++];
-				if (parm != null) {
-					if (parm instanceof ICallbackHandler.TransmitableArray) {
-						// It is another array, create a new retriever.
-						worker.setArrayIDS(new Retriever(((ICallbackHandler.TransmitableArray) parm).getArray()), ((ICallbackHandler.TransmitableArray) parm).getArray().length, Commands.OBJECT_CLASS);
-					} else {
-						// They may add some new ID's and if there is an error, they
-						// won't get released, but that is a slight chance we will have
-						// to take because we don't know which ones were new and which
-						// ones weren't.
-						fillInValue(parm, NOT_A_PRIMITIVE, worker);
-					}
-				} else
-					worker.set();
-				return worker;
+			Object parm = array[index++];
+			if (parm != null) {
+				if (parm instanceof ICallbackHandler.TransmitableArray) {
+					// It is another array, create a new retriever.
+					worker.setArrayIDS(new Retriever(((ICallbackHandler.TransmitableArray) parm).getArray()), ((ICallbackHandler.TransmitableArray) parm).getArray().length, Commands.OBJECT_CLASS);
+				} else {
+					// They may add some new ID's and if there is an error, they
+					// won't get released, but that is a slight chance we will have
+					// to take because we don't know which ones were new and which
+					// ones weren't.
+					fillInValue(parm, NOT_A_PRIMITIVE, worker);
+				}
 			} else
-				return null;
+				worker.set();
+			return worker;
 		}
 	};
 		
diff --git a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java
index 33123f5..bc2b08d 100644
--- a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java
+++ b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.proxy.vm.remote;
 /*
  *  $RCSfile: ConnectionHandler.java,v $
- *  $Revision: 1.10 $  $Date: 2005/02/15 22:57:54 $ 
+ *  $Revision: 1.11 $  $Date: 2005/05/11 19:01:12 $ 
  */
 
 
@@ -24,6 +24,7 @@
 import org.eclipse.jem.internal.proxy.common.CommandException;
 import org.eclipse.jem.internal.proxy.common.remote.*;
 import org.eclipse.jem.internal.proxy.initParser.*;
+import org.eclipse.jem.internal.proxy.initParser.tree.NoExpressionValueException;
 
 /**
  * This handles one connection.
@@ -304,7 +305,7 @@
 							if (valueObject.type == Commands.ARRAY_IDS) {
 								// It is an array containing IDs, as it normally would be.
 								valueSender.initialize(valueObject);
-								Commands.readArray(in, valueObject.anInt, valueSender, valueObject);
+								Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
 								parms = (Object[]) valueSender.getArray();
 							} else {
 								// It is all objects or null, so it should be an Object[] or null. If not, then this is an error.
@@ -365,7 +366,7 @@
 							if (valueObject.type == Commands.ARRAY_IDS) {
 								// It is an array containing IDs, as it normally would be.
 								valueSender.initialize(valueObject);
-								Commands.readArray(in, valueObject.anInt, valueSender, valueObject);
+								Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
 								parmTypes = (Class[]) valueSender.getArray();
 							} else {
 								// It null, so it should be an null. If not, then this is an error.
@@ -380,7 +381,7 @@
 							if (valueObject.type == Commands.ARRAY_IDS) {
 								// It is an array containing IDs, as it normally would be.
 								valueSender.initialize(valueObject);
-								Commands.readArray(in, valueObject.anInt, valueSender, valueObject);
+								Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
 								parms = (Object[]) valueSender.getArray();
 							} else {
 								// It is all objects or null, so it should be an Object[] or null. If not, then this is an error.
@@ -454,7 +455,7 @@
 									if (valueObject.type == Commands.ARRAY_IDS) {
 										// It is an array containing IDs, as it normally would be.
 										valueSender.initialize(valueObject);
-										Commands.readArray(in, valueObject.anInt, valueSender, valueObject);
+										Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
 										result = (Object[]) valueSender.getArray();
 									} else {
 										result = getInvokableObject(valueObject);
@@ -488,7 +489,12 @@
 						break;
 					
 					case Commands.EXPRESSION_TREE_COMMAND:
-						processExpressionCommand(valueObject);						
+						try {
+							processExpressionCommand(valueObject, valueSender);
+						} finally {
+							valueObject.set();
+							valueSender.clear();
+						}
 						break;
 						
 					default:
@@ -563,16 +569,13 @@
 		}
 		
 		public Commands.ValueObject nextValue() {
-			if (index < length) {
-				fillInValue(Array.get(array, index++), componentType, worker);
-				return worker;
-			} else
-				return null;
+			fillInValue(Array.get(array, index++), componentType, worker);
+			return worker;
 		}
 	};
 
 	
-	private void processExpressionCommand(Commands.ValueObject valueObject) throws IOException, CommandException {
+	private void processExpressionCommand(Commands.ValueObject valueObject, InvokableValueSender valueSender) throws IOException, CommandException {
 		Integer expressionID = new Integer(in.readInt());
 		byte cmdType = in.readByte();
 		ExpressionProcesserController exp = null;
@@ -586,41 +589,51 @@
 				exp.process(in);
 				break;
 			case ExpressionCommands.SYNC_REQUEST:
+				boolean haveProxies = in.readBoolean();	// See if we expression proxy ids that need to be resolved 
+				if (haveProxies) {
+					Commands.readValue(in, valueObject);
+					valueSender.initialize(valueObject);
+					Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
+				}
+
 				exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
+				if (haveProxies)
+					sendExpressionProxyResolutions(valueObject, (int[]) valueSender.getArray(), exp);
 				if (exp.noErrors()) {
 					valueObject.set(true); // Mark that all is good.
-					try {
-						Commands.writeValue(out, valueObject, true);
-					} finally {
-						valueObject.set();
-					}
+					Commands.writeValue(out, valueObject, true, true);
 				} else {
 					processExpressionError(exp, valueObject);
 				}
 				break;
 			case ExpressionCommands.PULL_VALUE_REQUEST:
-				exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
-				if (exp.noErrors()) {
-					Object[] pulledValue = exp.pullValue();
-					if (pulledValue != null) {
-						// No errors during pulling either.
-						try {
-							if (((Class) pulledValue[1]).isPrimitive()) {
-								int returnTypeID = server.getIdentityID((Class) pulledValue[1]);
-								// Need to tell sendObject the correct primitive type.
-								sendObject(pulledValue[0], returnTypeID, valueObject, out, true);
-								
-							} else {
-								sendObject(pulledValue[0], NOT_A_PRIMITIVE, valueObject, out, true);	// Just send the object back. sendObject knows how to iterpret the type
-							}
-							break;	// We sent good return, so leave.
-						} finally {
-							valueObject.set();
-							pulledValue = null;
-						}
-					}
+				haveProxies = in.readBoolean();	// See if we expression proxy ids that need to be resolved
+				if (haveProxies) {
+					Commands.readValue(in, valueObject);
+					valueSender.initialize(valueObject);
+					Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
 				}
-				processExpressionError(exp, valueObject);
+
+				exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
+				if (haveProxies)
+					sendExpressionProxyResolutions(valueObject, (int[]) valueSender.getArray(), exp);
+				if (exp.noErrors()) {
+					try {
+						Object[] pulledValue = exp.pullValue();
+						// Send back the command code for pull value. Don't flush. We will flush when all done.
+						if (((Class) pulledValue[1]).isPrimitive()) {
+							int returnTypeID = server.getIdentityID((Class) pulledValue[1]);
+							// Need to tell sendObject the correct primitive type.
+							sendObject(pulledValue[0], returnTypeID, valueObject, out, true, true);
+							
+						} else {
+							sendObject(pulledValue[0], NOT_A_PRIMITIVE, valueObject, out, true, true);	// Just send the object back. sendObject knows how to iterpret the type
+						}
+					} catch (NoExpressionValueException e) {
+						sendNoValueErrorCommand(exp, valueObject);
+					}
+				} else 
+					processExpressionError(exp, valueObject);
 				break;
 			case ExpressionCommands.END_EXPRESSION_TREE_PROCESSING:
 				exp = (ExpressionProcesserController) expressionProcessors.remove(expressionID);
@@ -629,24 +642,60 @@
 		}
 	}
 
-	private void processExpressionError(ExpressionProcesserController exp, Commands.ValueObject valueObject) throws CommandException {
-		try {
-			int code = exp.getErrorCode();
-			if (code != 0) {
-				// We have an error code to send back.
-				String emsg = exp.getErrorMsg();
-				if (emsg != null)
-					valueObject.set(emsg);
-				else
-					valueObject.set();
-				Commands.sendErrorCommand(out, code, valueObject);
-			} else {
-				// It must be an exception.
-				sendException(exp.getErrorThrowable(), valueObject, out);
+	/*
+	 * @param is
+	 * @param exp
+	 * 
+	 * @since 1.1.0
+	 */
+	private void sendExpressionProxyResolutions(Commands.ValueObject valueObject, final int[] proxyIDs, final ExpressionProcesserController exp) throws CommandException {
+		class ExpressionProxyRetriever implements Commands.ValueRetrieve {
+			int index = 0;
+			Object[] proxyResolution = new Object[2];
+			Commands.ValueObject worker = new Commands.ValueObject();
+
+			public Commands.ValueObject nextValue() {
+				int proxyID = proxyIDs[index++];
+				if (exp.pullExpressionProxyValue(proxyID, proxyResolution)) {
+					if (proxyResolution[1] != Void.TYPE) {
+						if (((Class) proxyResolution[1]).isPrimitive()) {
+							int returnTypeID = server.getIdentityID((Class) proxyResolution[1]);
+							// Need to tell worker the correct primitive type.
+							fillInValue(proxyResolution[0], returnTypeID, worker);
+						} else {
+							fillInValue(proxyResolution[0], NOT_A_PRIMITIVE, worker);
+						}
+					} else
+						worker.setFlag(ExpressionCommands.EXPRESSIONPROXY_VOIDTYPE);	// It was resolved, but to not set due to void type of expression.
+				} else
+					worker.setFlag(ExpressionCommands.EXPRESSIONPROXY_NOTRESOLVED);	// It wasn't resolved.
+				
+				return worker;
 			}
-		} finally {
-			valueObject.set();
-		}
+		};
+
+		valueObject.setArrayIDS(new ExpressionProxyRetriever(), proxyIDs.length, Commands.OBJECT_CLASS);
+		Commands.writeValue(out, valueObject, true, false);	// Write it back as a value command.
+
+	}
+
+	private void processExpressionError(ExpressionProcesserController exp, Commands.ValueObject valueObject) throws CommandException {
+		if (exp.isNoExpressionValue()) {
+			sendNoValueErrorCommand(exp, valueObject);
+		} else
+			sendException(exp.getErrorThrowable(), valueObject, out);
+	}
+
+	/*
+	 * @param exp
+	 * @param valueObject
+	 * @throws CommandException
+	 * 
+	 * @since 1.1.0
+	 */
+	private void sendNoValueErrorCommand(ExpressionProcesserController exp, Commands.ValueObject valueObject) throws CommandException {
+		setExceptionIntoValue(exp.getErrorThrowable(), valueObject);
+		Commands.sendErrorCommand(out, ExpressionCommands.EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION, valueObject);
 	}
 
 protected static final int NOT_A_PRIMITIVE = Commands.NOT_AN_ID;
@@ -765,11 +814,14 @@
 	return added;
 }
 
-public void sendObject(Object object, int primitiveTypeID, Commands.ValueObject valueObject, DataOutputStream out, boolean writeAsCommand) throws CommandException {			
+public void sendObject(Object object, int primitiveTypeID, Commands.ValueObject valueObject, DataOutputStream out, boolean writeAsCommand) throws CommandException {
+	sendObject(object, primitiveTypeID, valueObject, out, writeAsCommand, writeAsCommand);
+}
+public void sendObject(Object object, int primitiveTypeID, Commands.ValueObject valueObject, DataOutputStream out, boolean writeAsCommand, boolean flush) throws CommandException {			
 	int added = fillInValue(object, primitiveTypeID, valueObject);
 	boolean sent = false;
 	try {
-		Commands.writeValue(out, valueObject, writeAsCommand);	// Write it back as a value command.
+		Commands.writeValue(out, valueObject, writeAsCommand, flush);	// Write it back as a value command.
 		sent = true;
 	} finally {
 		if (!sent) {
diff --git a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ExpressionProcesserController.java b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ExpressionProcesserController.java
index 347b804..de89505 100644
--- a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ExpressionProcesserController.java
+++ b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ExpressionProcesserController.java
@@ -10,25 +10,21 @@
  *******************************************************************************/
 /*
  *  $RCSfile: ExpressionProcesserController.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:57:54 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:12 $ 
  */
 package org.eclipse.jem.internal.proxy.vm.remote;
 
 import java.io.DataInputStream;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
 
 import org.eclipse.jem.internal.proxy.common.*;
-import org.eclipse.jem.internal.proxy.common.CommandException;
-import org.eclipse.jem.internal.proxy.common.MapTypes;
 import org.eclipse.jem.internal.proxy.common.remote.Commands;
 import org.eclipse.jem.internal.proxy.common.remote.ExpressionCommands;
-import org.eclipse.jem.internal.proxy.initParser.EvaluationException;
-import org.eclipse.jem.internal.proxy.initParser.tree.ExpressionProcesser;
-import org.eclipse.jem.internal.proxy.initParser.tree.IInternalExpressionConstants;
-import org.eclipse.jem.internal.proxy.initParser.tree.IExpressionConstants.NoExpressionValueException;
+import org.eclipse.jem.internal.proxy.initParser.tree.*;
 
  
 /**
@@ -54,6 +50,7 @@
  */
 public class ExpressionProcesserController {
 
+	
 	protected final RemoteVMServerThread server;
 	protected final ConnectionHandler connHandler;	
 	protected final ExpressionProcesser exp;
@@ -61,24 +58,13 @@
 	private ClassLoader classLoader;
 	
 	/**
-	 * An error has occurred. At this point all subcommands will simply make sure they flush the input stream
-	 * correctly, but they do not process it.
-	 * 
-	 * @since 1.0.0
-	 */
-	protected boolean errorOccurred = false;
-	
-	private String novalueMsg = null;	// If NoExpressionValueException then this is the msg. 
-	private Throwable exception = null;	// Was there another kind of exception that was caught.
-	
-	/**
 	 * Create with a default expression processer.
 	 * @param server
 	 * 
 	 * @since 1.0.0
 	 */
 	public ExpressionProcesserController(RemoteVMServerThread server, ConnectionHandler connHandler) {
-		this(server, connHandler, new ExpressionProcesser());
+		this(server, connHandler, new ExpressionProcesser(Boolean.getBoolean(ExpressionCommands.EXPRESSIONTRACE), Long.getLong(ExpressionCommands.EXPRESSIONTRACE_TIMER_THRESHOLD, -1L).longValue()));
 	}
 	
 	/**
@@ -152,6 +138,8 @@
 	 */
 	public void process(DataInputStream in) throws CommandException, IOException {
 		// In the following subcommand processing, we always read the entire subcommand from the stream.
+		// This is so that any errors during processing will not mess up the stream with unread data.
+		//
 		// Then we check if an error has occurred in the past. If it has, we simply break. This is because
 		// once an error occurred we don't want to continue wasting time evaluating, however we need to make
 		// sure that the stream is read completely so that we don't have a corrupted input stream. That way
@@ -159,11 +147,9 @@
 		byte subcommand = in.readByte();
 		try {
 			switch (subcommand) {
-				case IInternalExpressionConstants.PUSH_TO_PROXY_EXPRESSION :
+				case InternalExpressionTypes.PUSH_TO_PROXY_EXPRESSION_VALUE:
 					// Getting a proxy push. The value is sent as valueObject, so use that to read it in.
 					Commands.readValue(in, workerValue);
-					if (errorOccurred)
-						break;
 					Object value = connHandler.getInvokableObject(workerValue);
 					if (value == null)
 						exp.pushExpression(null, MethodHelper.NULL_TYPE);
@@ -173,364 +159,495 @@
 						exp.pushExpression(value, value.getClass());
 					break;
 
-				case IInternalExpressionConstants.CAST_EXPRESSION :
+				case InternalExpressionTypes.CAST_EXPRESSION_VALUE:
 					// Get a cast request. The type is sent as valueObject.
 					Commands.readValue(in, workerValue);
-					if (errorOccurred)
-						break;
-					value = connHandler.getInvokableObject(workerValue);
 					try {
-						if (value instanceof String)
-							value = loadClass((String) value);
-						exp.pushCast((Class) value);
-					} catch (NoExpressionValueException e) {
-						processException(e);
+						Class classValue = getBeanTypeValue(workerValue);
+						exp.pushCast(classValue);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
 					} catch (ClassNotFoundException e) {
-						processException(e);
-					}
+						// Do nothing, already processed.
+					} 
 					break;
 
-				case IInternalExpressionConstants.INSTANCEOF_EXPRESSION :
+				case InternalExpressionTypes.INSTANCEOF_EXPRESSION_VALUE:
 					// Get a instanceof request. The type is sent as valueObject.
 					Commands.readValue(in, workerValue);
-					if (errorOccurred)
-						break;
-					value = connHandler.getInvokableObject(workerValue);
 					try {
-						if (value instanceof String)
-							value = loadClass((String) value);
-						exp.pushInstanceof((Class) value);
+						Class classValue = getBeanTypeValue(workerValue);
+						exp.pushInstanceof(classValue);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
 					} catch (ClassNotFoundException e) {
-						processException(e);
-					} catch (NoExpressionValueException e) {
-						processException(e);
-					}
+						// Do nothing, already processed.
+					} 
 					break;
 
-				case IInternalExpressionConstants.INFIX_EXPRESSION :
+				case InternalExpressionTypes.INFIX_EXPRESSION_VALUE:
 					// Get an infix request. The operator and operand type are sent as bytes.
 					byte infix_operator = in.readByte();
 					byte infix_operandType = in.readByte();
-					if (errorOccurred)
-						break;
-					try {
-						exp.pushInfix(infix_operator, infix_operandType);
-					} catch (NoExpressionValueException e1) {
-						processException(e1);
-					}
+					exp.pushInfix(InfixOperator.get(infix_operator), InternalInfixOperandType.get(infix_operandType));
 					break;
 
-				case IInternalExpressionConstants.PREFIX_EXPRESSION :
+				case InternalExpressionTypes.PREFIX_EXPRESSION_VALUE:
 					// Get a prefix request. The operator is sent as byte.
 					byte prefix_operandType = in.readByte();
-					if (errorOccurred)
-						break;
-					try {
-						exp.pushPrefix(prefix_operandType);
-					} catch (NoExpressionValueException e2) {
-						processException(e2);
-					}
+					exp.pushPrefix(PrefixOperator.get(prefix_operandType));
 					break;
 
-				case IInternalExpressionConstants.TYPELITERAL_EXPRESSION :
-					// Get a type literal request. The type string is sent as valueObject.
-					Commands.readValue(in, workerValue);
-					if (errorOccurred)
-						break;
-					value = connHandler.getInvokableObject(workerValue);
-					try {
-						value = loadClass((String) value);
-						exp.pushExpression((Class) value, Class.class);
-					} catch (ClassNotFoundException e) {
-						processException(e);
-					}
-					break;
-
-				case IInternalExpressionConstants.ARRAY_ACCESS_EXPRESSION :
+				case InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION_VALUE:
 					// Get an array access request. The index cound is sent as int.
 					int arrayAccess_Indexcount = in.readInt();
-					if (errorOccurred)
-						break;
-					try {
-						exp.pushArrayAccess(arrayAccess_Indexcount);
-					} catch (NoExpressionValueException e3) {
-						processException(e3);
-					}
+					exp.pushArrayAccess(arrayAccess_Indexcount);
 					break;
 
-				case IInternalExpressionConstants.ARRAY_CREATION_EXPRESSION :
+				case InternalExpressionTypes.ARRAY_CREATION_EXPRESSION_VALUE:
 					// Get an array creation request. The type is sent as valueObject, followed by int dimension count.
 					Commands.readValue(in, workerValue);
 					int arrayCreation_dimCount = in.readInt();
-					if (errorOccurred)
-						break;
-					value = connHandler.getInvokableObject(workerValue);
 					try {
-						if (value instanceof String)
-							value = loadClass((String) value);
-						exp.pushArrayCreation((Class) value, arrayCreation_dimCount);
+						Class classValue = getBeanTypeValue(workerValue);
+						exp.pushArrayCreation(classValue, arrayCreation_dimCount);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
 					} catch (ClassNotFoundException e) {
-						processException(e);
-					} catch (NoExpressionValueException e) {
-						processException(e);
-					}
+						// Do nothing, already processed.
+					} 
+
 					break;
 
-				case IInternalExpressionConstants.ARRAY_INITIALIZER_EXPRESSION :
+				case InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION_VALUE:
 					// Get an array initializer request. The type is sent as valueObject, followed by int expression count.
 					Commands.readValue(in, workerValue);
+					int stripCount = in.readInt();
 					int arrayInitializer_expressionCount = in.readInt();
-					if (errorOccurred)
-						break;
-					value = connHandler.getInvokableObject(workerValue);
 					try {
-						if (value instanceof String)
-							value = loadClass((String) value);
-						exp.pushArrayInitializer((Class) value, arrayInitializer_expressionCount);
+						Class classValue = getBeanTypeValue(workerValue);
+						exp.pushArrayInitializer(classValue, stripCount, arrayInitializer_expressionCount);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
 					} catch (ClassNotFoundException e) {
-						processException(e);
-					} catch (NoExpressionValueException e) {
-						processException(e);
+						// Do nothing, already processed.
 					}
 					break;
 
-				case IInternalExpressionConstants.CLASS_INSTANCE_CREATION_EXPRESSION :
+				case InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION_VALUE:
 					// Get a class instance creation request. The type is sent as valueObject, followed by int argument count.
 					Commands.readValue(in, workerValue);
 					int newInstance_argCount = in.readInt();
-					if (errorOccurred)
-						return;
-					value = connHandler.getInvokableObject(workerValue);
 					try {
-						if (value instanceof String)
-							value = loadClass((String) value);
-						exp.pushClassInstanceCreation((Class) value, newInstance_argCount);
+						Class classValue = getBeanTypeValue(workerValue);
+						exp.pushClassInstanceCreation(classValue, newInstance_argCount);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
 					} catch (ClassNotFoundException e) {
-						processException(e);
-					} catch (EvaluationException e) {
-						processException(e);
-					} catch (NoExpressionValueException e) {
-						processException(e);
-					} catch (InstantiationException e) {
-						processException(e);
-					} catch (IllegalAccessException e) {
-						processException(e);
-					} catch (InvocationTargetException e) {
-						processException(e);
-					} catch (LinkageError e) {
-						processError(e);
+						// Do nothing, already processed.
 					}
 					break;
 
-				case IInternalExpressionConstants.TYPERECEIVER_EXPRESSION :
+				case InternalExpressionTypes.TYPERECEIVER_EXPRESSION_VALUE:
 					// Get a type receiver request. The type is sent as valueObject.
 					Commands.readValue(in, workerValue);
-					if (errorOccurred)
-						break;
-					value = connHandler.getInvokableObject(workerValue);
 					try {
-						if (value instanceof String)
-							value = loadClass((String) value);
-						exp.pushExpression(value, (Class) value);
+						Class classValue = getBeanTypeValue(workerValue);
+						exp.pushExpression(classValue, classValue);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
 					} catch (ClassNotFoundException e) {
-						processException(e);
+						// Do nothing, already processed.
 					}
 					break;
 
-				case IInternalExpressionConstants.FIELD_ACCESS_EXPRESSION :
-					// Get a field access request. The field name sent as string, followed by hasReceiver as boolean.
-					String fieldAccess_name = in.readUTF();
-					boolean fieldAccess_receiver = in.readBoolean();
-					if (errorOccurred)
-						break;
+				case InternalExpressionTypes.FIELD_ACCESS_EXPRESSION_VALUE:
+					// Get a field access request. Command.ValueObject, followed by hasReceiver as boolean.
+					Commands.readValue(in, workerValue);
+					boolean has_fieldAccess_receiver = in.readBoolean();
 					try {
-						exp.pushFieldAccess(fieldAccess_name, fieldAccess_receiver);
-					} catch (NoExpressionValueException e4) {
-						processException(e4);
-					} catch (NoSuchFieldException e4) {
-						processException(e4);
-					} catch (IllegalAccessException e4) {
-						processException(e4);
+						Object fieldAccess = getFieldValue(workerValue);
+						exp.pushFieldAccess(fieldAccess, workerValue.getType() == Commands.STRING, has_fieldAccess_receiver);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.						
+					} catch (NoSuchFieldException e1) {
+						// Do nothing, already processed.
 					}
 					break;
 
-				case IInternalExpressionConstants.METHOD_EXPRESSION :
-					// Get a method invocation request. The method name sent as string, followed by hasReceiver as boolean, and argCount as int.
-					String method_name = in.readUTF();
-					boolean method_receiver = in.readBoolean();
+				case InternalExpressionTypes.METHOD_EXPRESSION_VALUE:
+					// Get a method invocation request. Sent as Commands.ValueObject, followed by hasReceiver as boolean., and argCount as int.
+					Commands.readValue(in, workerValue);
+					boolean has_method_receiver = in.readBoolean();
 					int method_argCount = in.readInt();
-					if (errorOccurred)
-						break;
 					try {
-						exp.pushMethodInvocation(method_name, method_receiver, method_argCount);
-					} catch (EvaluationException e5) {
-						processException(e5);
-					} catch (NoExpressionValueException e5) {
-						processException(e5);
-					} catch (IllegalAccessException e5) {
-						processException(e5);
-					} catch (InvocationTargetException e5) {
-						processException(e5);
-					}
+						Object method = getMethodValue(workerValue);					
+						exp.pushMethodInvocation(method, workerValue.getType() == Commands.STRING, has_method_receiver, method_argCount);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
+					} catch (NoSuchMethodException e) {
+						// Do nothing, already processed.
+					}						
 					break;
 
-				case IInternalExpressionConstants.CONDITIONAL_EXPRESSION :
+				case InternalExpressionTypes.CONDITIONAL_EXPRESSION_VALUE:
 					// Get a conditional expression request. The expression type (ie. condition/true/false) is sent as a byte
-					byte conditional_type = in.readByte();
-					if (errorOccurred)
-						break;
+					exp.pushConditional(InternalConditionalOperandType.get(in.readByte()));
+					break;
+					
+				case InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION_VALUE:
+					// Get an assignment expression request. The proxy id is sent as an int.
+					int proxyid = in.readInt();
+					exp.pushAssignment(new RemoteExpressionProxy(proxyid));
+					break;
+					
+				case InternalExpressionTypes.ASSIGNMENT_EXPRESSION_VALUE:
+					// Get an assignment expression request. Nothing else to read from stream.
+					exp.pushAssignment();
+					break;
+					
+				case InternalExpressionTypes.PUSH_TO_EXPRESSION_PROXY_EXPRESSION_VALUE:
+					// Get a push expression proxy expression. The proxy id is sent as an int.
+					exp.pushExpressionProxy(in.readInt());
+					break;
+				
+				case InternalExpressionTypes.BLOCK_BEGIN_EXPRESSION_VALUE:
+					// Get a begin block proxy expression. The block id is sent as an int.
+					exp.pushBlockBegin(in.readInt());
+					break;
+					
+				case InternalExpressionTypes.BLOCK_BREAK_EXPRESSION_VALUE:
+					// Get a break block proxy expression. The block id is sent as an int.
+					exp.pushBlockBreak(in.readInt());
+					break;
+					
+				case InternalExpressionTypes.BLOCK_END_EXPRESSION_VALUE:
+					// Get a end block proxy expression. The block id is sent as an int.
+					exp.pushBlockEnd(in.readInt());
+					break;
+					
+				case InternalExpressionTypes.TRY_BEGIN_EXPRESSION_VALUE:
+					// Get a try begin proxy expression. The try id is sent as an int.
+					exp.pushTryBegin(in.readInt());
+					break;
+					
+				case InternalExpressionTypes.TRY_CATCH_EXPRESSION_VALUE:
+					int tryNumber = in.readInt();
+					Commands.readValue(in, workerValue);
+					proxyid = in.readInt();
 					try {
-						exp.pushConditional(conditional_type);
-					} catch (NoExpressionValueException e6) {
-						processException(e6);
+						Class classValue = getBeanTypeValue(workerValue);
+						exp.pushTryCatchClause(tryNumber, classValue, proxyid != -1 ? new RemoteExpressionProxy(proxyid) : null);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
+					} catch (ClassNotFoundException e) {
+						// Do nothing, already processed.
+					}					
+					break;
+
+				case InternalExpressionTypes.TRY_FINALLY_EXPRESSION_VALUE:
+					// Get a try finally proxy expression. The try id is sent as an int.
+					exp.pushTryFinallyClause(in.readInt());
+					break;
+
+				case InternalExpressionTypes.TRY_END_EXPRESSION_VALUE:
+					// Get a try end proxy expression. The try id is sent as an int.
+					exp.pushTryEnd(in.readInt());
+					break;
+					
+				case InternalExpressionTypes.THROW_EXPRESSION_VALUE:
+					exp.pushThrowException();
+					break;
+
+				case InternalExpressionTypes.RETHROW_EXPRESSION_VALUE:
+					// Get a rethrow proxy expression. The try id is sent as an int.
+					exp.pushTryRethrow(in.readInt());
+					break;
+
+				case InternalExpressionTypes.PUSH_BEANTYPE_EXPRESSIONPROXY_EXPRESSION_VALUE:
+					// Get the beantype expression proxy and resolve it.
+					proxyid = in.readInt();
+					String typeName = Commands.readStringData(in);
+					try {
+						Class classValue = loadClass(typeName);
+						RemoteExpressionProxy rep = new RemoteExpressionProxy(proxyid);
+						rep.setProxy(classValue, Class.class);
+						exp.allocateExpressionProxy(rep);
+					} catch (ClassNotFoundException e) {
+						exp.processException(e);
+					} catch (LinkageError e) {
+						exp.processException(e);
 					}
 					break;
+					
+				case InternalExpressionTypes.PUSH_METHOD_EXPRESSIONPROXY_EXPRESSION_VALUE:
+					// Get the Method expression proxy and resolve it.
+					// Comes over as:
+					//   int for proxy id for the method
+					//   beanTypeValue for declaring class (either beantype or expression proxy)
+					//   string for method name
+					//   int for arg count
+					//   beanTypeValue(s) for arg types (as many as arg count).
+					proxyid = in.readInt();
+					Commands.ValueObject decClassValue =  Commands.readValue(in, new Commands.ValueObject());
+					String methodName = Commands.readStringData(in);
+					int argCount = in.readInt();
+					Commands.ValueObject[] args = null;
+					if (argCount > 0) {
+						args = new Commands.ValueObject[argCount];
+						for (int i = 0; i < argCount; i++) {
+							args[i] = Commands.readValue(in, new Commands.ValueObject());
+						}
+					}
+					try {
+						Class decClass = getBeanTypeValue(decClassValue);
+						Class[] argClasses = null;
+						if (argCount>0) {
+							argClasses = new Class[argCount];
+							for (int i = 0; i < argCount; i++) {
+								argClasses[i] = getBeanTypeValue(args[i]);
+							}
+						}
+						// Now get the method itself.
+						Method m = decClass.getMethod(methodName, argClasses);
+						RemoteExpressionProxy rep = new RemoteExpressionProxy(proxyid);
+						rep.setProxy(m, Method.class);
+						exp.allocateExpressionProxy(rep);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
+					} catch (ClassNotFoundException e) {
+						// Do nothing, already processed.
+					} catch (NoSuchMethodException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
+					}					
+					break;
+					
+				case InternalExpressionTypes.PUSH_FIELD_EXPRESSIONPROXY_EXPRESSION_VALUE:
+					// Get the Filed expression proxy and resolve it.
+					// Comes over as:
+					//   int for proxy id for the field
+					//   beanTypeValue for declaring class (either beantype or expression proxy)
+					//   string for field name
+					proxyid = in.readInt();
+					decClassValue =  Commands.readValue(in, new Commands.ValueObject());
+					String fieldName = Commands.readStringData(in);
+					try {
+						Class decClass = getBeanTypeValue(decClassValue);
+						// Now get the field itself.
+						Field f = decClass.getField(fieldName);
+						RemoteExpressionProxy rep = new RemoteExpressionProxy(proxyid);
+						rep.setProxy(f, Method.class);
+						exp.allocateExpressionProxy(rep);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
+					} catch (ClassNotFoundException e) {
+						// Do nothing, already processed.
+					} catch (NoSuchFieldException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
+					}					
+					break;					
+					
+				case InternalExpressionTypes.IF_TEST_EXPRESSION_VALUE:
+					// Get a if test expression request. 
+					exp.pushIfElse();
+					break;
+					
+				case InternalExpressionTypes.IF_ELSE_EXPRESSION_VALUE:
+					// Get a if/else expression clause request. The clause type (ie. true/false) is sent as a byte
+					exp.pushIfElse(InternalIfElseOperandType.get(in.readByte()));
+					break;
+					
+				case InternalExpressionTypes.NEW_INSTANCE_VALUE:
+					// Get a new instance from string.
+					String initString = Commands.readStringData(in);
+					workerValue =  Commands.readValue(in, new Commands.ValueObject());
+					try {
+						Class classValue = getBeanTypeValue(workerValue);
+						exp.pushNewInstanceFromString(initString, classValue, classLoader);
+					} catch (ClassCastException e) {
+						exp.processException(e);	// Let the processor know we have a stopping error.
+					} catch (ClassNotFoundException e) {
+						// Do nothing, already processed.
+					}
+					break;
+					
+				case InternalExpressionTypes.MARK_VALUE:
+					// Do a mark.
+					int markID = in.readInt();
+					exp.pushMark(markID);
+					break;
+					
+				case InternalExpressionTypes.ENDMARK_VALUE:
+					// Do an end mark.
+					markID = in.readInt();
+					boolean restore = in.readBoolean();
+					exp.pushEndmark(markID, restore);
+					break;
 			}
 			
 		} catch (RuntimeException e) {
-			processException(e);
+			exp.processException(e);
 		}
 		
 		workerValue.set();	// Clear it out so nothing being held onto.
 	}
 	
-
 	/**
-	 * Pull the value. If an error occurred during this, then <code>null</code> is returned, and
-	 * caller should do normal error processing.
+	 * Get the beantype (class) out of the value object sent in. It can handle the beantype sent or
+	 * as an expression proxy to a beantype expression proxy.
 	 * 
-	 * @return r[0] is the value, r[1] is the type of the value. <code>null</code> if there was an error.
+	 * @param value
+	 * @return
+	 * @throws ClassCastException means either not a type sent in, or proxy was not a type.
+	 * @throws ClassNotFoundException the expression proxy did not resolve. In that case it has already been processed by the expression processor.
 	 * 
-	 * @since 1.0.0
+	 * @since 1.1.0
 	 */
-	public Object[] pullValue() {
-		Object[] result = new Object[2];
-		try {
-			exp.pullValue(result);
-			return result;
-		} catch (NoExpressionValueException e) {
-			processException(e);
+	protected Class getBeanTypeValue(Commands.ValueObject value) throws ClassCastException, ClassNotFoundException {
+		Object beantype = connHandler.getInvokableObject(value);
+		// It is either a type directly or is an expression proxy.
+		if (value.type == Commands.INT) {
+			// It is an expression proxy request.
+			Object[] expvalue = new Object[2];
+			if (exp.getExpressionProxyValue(((Integer) beantype).intValue(), expvalue)) {
+				beantype = expvalue[0]; 
+			} else
+				throw new ClassNotFoundException();
 		}
-		return null;
+		return (Class) beantype;
 	}
-	
+		
 	/**
-	 * Process all other exceptions then the NoExpressionValueException, InvocationTargetException, and EvaluationException. This is
-	 * for exceptions that are not related to the input stream and shouldn't
-	 * cause the input stream to be closed.
+	 * Get the method out of the value object sent in. It can handle the method sent or
+	 * as an expression proxy to a method expression proxy.
+	 * @param value
+	 * @return method if a method or string if a string or get the method if an expression proxy.
+	 * @throws NoSuchMethodException the expression proxy did not resolve. In that case it has already been processed by the expression processor.
+	 * @throws ClassCastException means either not a method sent in, or proxy was not a method.
 	 * 
-	 * @param e
-	 * 
-	 * @since 1.0.0
+	 * @since 1.1.0
 	 */
-	protected final void processException(Exception e) {
-		// Process all other exceptions.
-		errorOccurred = true;
-		exception = e;
-	}
-	
-	/**
-	 * Process certain errors. Should not be called for general errors. Should be called for specific java.lang.Errors that
-	 * are not related to the input stream and shouldn't cause the input stream to be closed.
-	 *  
-	 * @param e
-	 * 
-	 * @since 1.0.2
-	 */
-	protected final void processError(Error e) {
-		// Process specific errors
-		errorOccurred = true;
-		exception = e;		
-	}
-	
-	/**
-	 * Process InvocationTargetException to retrieve the actual target.
-	 * @param e
-	 * 
-	 * @since 1.0.0
-	 */
-	protected final void processException(InvocationTargetException e) {
-		errorOccurred = true;
-		exception = e.getTargetException();
-	}
-	
-	/**
-	 * Process EvaluationException to retrieve the actual target.
-	 * @param e
-	 * 
-	 * @since 1.0.0
-	 */
-	protected final void processException(EvaluationException e) {
-		errorOccurred = true;
-		exception = e.getOriginalException();
+	protected Object getMethodValue(Commands.ValueObject value) throws NoSuchMethodException, ClassCastException {
+		Object method = connHandler.getInvokableObject(value);
+		// It is either a method directly or is an expression proxy.
+		if (value.type == Commands.INT) {
+			// It is an expression proxy request.
+			Object[] expvalue = new Object[2];
+			if (exp.getExpressionProxyValue(((Integer) method).intValue(), expvalue)) {
+				method = expvalue[0]; 
+			} else
+				throw new NoSuchMethodException();
+		}
+		return method;
 	}	
 
 	/**
-	 * Special case for NoExpressionValueException caught.
-	 * @param e
+	 * Get the field out of the value object sent in. It can handle the field sent or
+	 * as an expression proxy to a field expression proxy.
+	 * @param value
+	 * @return field if a field or string if a string or get the field if an expression proxy.
+	 * @throws NoSuchFieldException the expression proxy did not resolve. In that case it has already been processed by the expression processor.
+	 * @throws ClassCastException means either not a field sent in, or proxy was not a field.
 	 * 
-	 * @since 1.0.0
+	 * @since 1.1.0
 	 */
-	protected final void processException(NoExpressionValueException e) {
-		errorOccurred = true;
-		novalueMsg = e.getLocalizedMessage();
-		if (novalueMsg == null)
-			novalueMsg = "";	// It was null, so just default of empty string so we know it had occurred.
+	protected Object getFieldValue(Commands.ValueObject value) throws NoSuchFieldException, ClassCastException {
+		Object field = connHandler.getInvokableObject(value);
+		// It is either a field directly or is an expression proxy.
+		if (value.type == Commands.INT) {
+			// It is an expression proxy request.
+			Object[] expvalue = new Object[2];
+			if (exp.getExpressionProxyValue(((Integer) field).intValue(), expvalue)) {
+				field = expvalue[0]; 
+			} else
+				throw new NoSuchFieldException();
+		}
+		return field;
+	}	
+	
+	/**
+	 * Pull the Expression Proxy value into the result object.
+	 * @param proxyID
+	 * @param result
+	 * @return <code>true</code> if value could be returned, <code>false</code> if it was no expression value assigned.
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean pullExpressionProxyValue(int proxyID, Object[] result) {
+		try {
+			exp.pullExpressionProxyValue(proxyID, result);
+			return true;
+		} catch (NoExpressionValueException e) {
+		}
+		return false;
 	}
+	
+	private static class RemoteExpressionProxy implements InternalExpressionProxy {
+
+		
+		private final int proxyID;
+		private Object value;
+		private Class type;
+		private boolean set;
+		
+		public RemoteExpressionProxy(int proxyID) {
+			this.proxyID = proxyID;
+			
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#getProxyID()
+		 */
+		public int getProxyID() {
+			return proxyID;
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#getType()
+		 */
+		public Class getType() {
+			return type;
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#getValue()
+		 */
+		public Object getValue() {
+			return value;
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#isSet()
+		 */
+		public boolean isSet() {
+			return set;
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#setProxy(java.lang.Object, java.lang.Class)
+		 */
+		public void setProxy(Object value, Class type) {
+			this.value = value;
+			this.type = type;
+			set = true;
+		}
+	}
+	
 
 	/**
-	 * Return whether there are any errors.
+	 * Pull the value. 
 	 * 
-	 * @return <code>true</code> if no errors.
+	 * @return r[0] is the value, r[1] is the type of the value.
+	 * @throws NoExpressionValueException
 	 * 
 	 * @since 1.0.0
 	 */
-	public boolean noErrors() {
-		return !errorOccurred;
+	public Object[] pullValue() throws NoExpressionValueException {
+		Object[] result = new Object[2];
+		exp.pullValue(result);
+		return result;
 	}
-	
-	/**
-	 * Return the error code from ExpressionCommands if non-exception error occurred.
-	 * Return zero if no error.
-	 * 
-	 * @return Zero if no error code to return, else error code from ExpressionCommands.
-	 * 
-	 * @see org.eclipse.jem.internal.proxy.common.remote.ExpressionCommands#ExpressionNoExpressionValueException
-	 * 
-	 * @since 1.0.0
-	 */
-	public int getErrorCode() {
-		if (novalueMsg != null)
-			return ExpressionCommands.ExpressionNoExpressionValueException;
-		else
-			return 0;
-	}
-	
-	/**
-	 * Return the error message, should only be called if <code>getErrorCode()</code> returned non-zero.
-	 * 
-	 * @return The error message if any. <code>null</code> otherwise.
-	 * 
-	 * @since 1.0.0
-	 */
-	public String getErrorMsg() {
-		if (novalueMsg != null && novalueMsg.length() > 0)
-			return novalueMsg;
-		else
-			return null;
-	}
-	
-	/**
-	 * Return the throwable if a Throwable was caught.
-	 * 
-	 * @return The throwable, or <code>null</code> if not set.
-	 * 
-	 * @since 1.0.0
-	 */
-	public Throwable getErrorThrowable() {
-		return exception;
-	}
-	
+				
 	/**
 	 * Close out things.
 	 * 
@@ -539,5 +656,35 @@
 	public void close() {
 		exp.close();
 	}
+	
+	/**
+	 * Get the throwable error.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public Throwable getErrorThrowable() {
+		return exp.getErrorThrowable();
+	}
+	
+	/**
+	 * Return whether there were no errors or not.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean noErrors() {
+		return exp.noErrors();
+	}
+	
+	/**
+	 * Return whether there is a no expression value exception or not.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public boolean isNoExpressionValue() {
+		return exp.isNoExpressionValue();
+	}
 
 }
diff --git a/plugins/org.eclipse.jem.workbench/workbench/org/eclipse/jem/internal/adapters/jdom/JDOMSearchHelper.java b/plugins/org.eclipse.jem.workbench/workbench/org/eclipse/jem/internal/adapters/jdom/JDOMSearchHelper.java
index 5946a98..75175de 100644
--- a/plugins/org.eclipse.jem.workbench/workbench/org/eclipse/jem/internal/adapters/jdom/JDOMSearchHelper.java
+++ b/plugins/org.eclipse.jem.workbench/workbench/org/eclipse/jem/internal/adapters/jdom/JDOMSearchHelper.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: JDOMSearchHelper.java,v $
- *  $Revision: 1.3 $  $Date: 2005/03/15 23:21:02 $ 
+ *  $Revision: 1.4 $  $Date: 2005/05/11 19:01:23 $ 
  */
 
 import java.io.File;
@@ -347,10 +347,7 @@
 	public static IType findType(String packageName, String qualifiedTypeName, IJavaProject javaProject) {
 		try {
 			if (javaProject != null) {
-				String typeName = qualifiedTypeName;
-				if (qualifiedTypeName.indexOf('$') != -1)
-					typeName = qualifiedTypeName.replace('$', '.');
-				return javaProject.findType(packageName, typeName);
+				return javaProject.findType(packageName, qualifiedTypeName.replace('$', '.'));
 			}
 		} catch (JavaModelException jme) {
 			System.out.println(ResourceHandler.getString("Error_Looking_Up_Type_ERROR_", (new Object[] { packageName + "." + qualifiedTypeName, jme.getMessage()}))); //$NON-NLS-1$ = "Error looking up type: "
diff --git a/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/FeatureValueProvider.java b/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/FeatureValueProvider.java
index d647525..f1e40f4 100644
--- a/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/FeatureValueProvider.java
+++ b/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/FeatureValueProvider.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.instantiation.base;
 /*
  *  $RCSfile: FeatureValueProvider.java,v $
- *  $Revision: 1.3 $  $Date: 2005/02/15 22:36:09 $ 
+ *  $Revision: 1.4 $  $Date: 2005/05/11 19:01:16 $ 
  */
 
 import org.eclipse.emf.ecore.EStructuralFeature;
@@ -35,17 +35,17 @@
 		 * 
 		 * @param feature
 		 * @param value
-		 * 
+		 * @return <code>null</code> to continue to next setting, or a value to stop visiting and return that value be the real exception.
 		 * @since 1.1.0
 		 */
-		void isSet(EStructuralFeature feature, Object value);
+		Object isSet(EStructuralFeature feature, Object value);
 	}	
 
 	/**
 	 * Visit the set features.
 	 * @param aVisitor
-	 * 
+	 * @param <code>null</code> if all settings visited, or the value returned from the visit (isSet) that returned a non-nullSe.
 	 * @since 1.1.0
 	 */
-	void visitSetFeatures(Visitor aVisitor);
+	Object visitSetFeatures(Visitor aVisitor);
 }
diff --git a/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/JavaObjectInstance.java b/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/JavaObjectInstance.java
index bb6cada..002d477 100644
--- a/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/JavaObjectInstance.java
+++ b/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/JavaObjectInstance.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.instantiation.base;
 /*
  *  $RCSfile: JavaObjectInstance.java,v $
- *  $Revision: 1.13 $  $Date: 2005/02/15 22:36:09 $ 
+ *  $Revision: 1.14 $  $Date: 2005/05/11 19:01:16 $ 
  */
 
 import java.util.List;
@@ -44,7 +44,8 @@
 	 * Visit the argument with all of the set features in an optimized fashion 
 	 */
 	private final static Object NIL = EStructuralFeatureImpl.InternalSettingDelegateSingle.NIL;
-	public void visitSetFeatures(Visitor aVisitor) {
+	public Object visitSetFeatures(Visitor aVisitor) {
+		Object result = null;
 		if (eHasSettings()) {
 			JavaObjectInstancePropertiesHolder settings = (JavaObjectInstancePropertiesHolder) eProperties();
 
@@ -57,11 +58,13 @@
 						// <null> is handled by the placeholder NIL. A setting of true null means not set. A setting of NIL means set to null.
 						if (propertyValue == NIL)
 							propertyValue = null;
-						aVisitor.isSet((EStructuralFeature) allFeatures.get(i), propertyValue);
+						if ((result = aVisitor.isSet((EStructuralFeature) allFeatures.get(i), propertyValue)) != null)
+							break;
 					}
 				}
 			} 
-		}												
+		}
+		return result;
 	}
 		
 	public boolean isSetAllocation() {
diff --git a/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/ParseTreeAllocationInstantiationVisitor.java b/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/ParseTreeAllocationInstantiationVisitor.java
index 0f7ce5b..dcaecc7 100644
--- a/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/ParseTreeAllocationInstantiationVisitor.java
+++ b/plugins/org.eclipse.jem/javainst/org/eclipse/jem/internal/instantiation/base/ParseTreeAllocationInstantiationVisitor.java
@@ -10,17 +10,15 @@
  *******************************************************************************/
 /*
  *  $RCSfile: ParseTreeAllocationInstantiationVisitor.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:36:09 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:16 $ 
  */
 package org.eclipse.jem.internal.instantiation.base;
 
 import java.util.List;
 
 import org.eclipse.jem.internal.instantiation.*;
-import org.eclipse.jem.internal.instantiation.ParseVisitor;
 import org.eclipse.jem.internal.proxy.core.*;
-import org.eclipse.jem.internal.proxy.initParser.tree.IExpressionConstants;
-import org.eclipse.jem.internal.proxy.initParser.tree.IExpressionConstants.NoExpressionValueException;
+import org.eclipse.jem.internal.proxy.initParser.tree.*;
  
 /**
  * This is the standard parse visitor for instantiating a bean proxy from a java parse tree allocation.
@@ -29,12 +27,7 @@
  * @since 1.0.0
  */
 public class ParseTreeAllocationInstantiationVisitor extends ParseVisitor {
-	
-	/**
-	 * Registry for processing the expressions against.
-	 */
-	private ProxyFactoryRegistry registry;
-	
+		
 	/**
 	 * The expression that is being created and evaluated.
 	 */
@@ -45,7 +38,7 @@
 	 * visitation to the next expression. It will set this to what that expression should be using. This
 	 * is necessary because the next expression doesn't know what it should be.
 	 */
-	private int nextExpression = IExpression.ROOTEXPRESSION;
+	private ForExpression nextExpression = ForExpression.ROOTEXPRESSION;
 	
 	/**
 	 * An exception occurred during processing. It is a RuntimeException because
@@ -67,28 +60,28 @@
 		}
 	}
 	
-	static final int[] INFIXTOPROXY;
+	static final InfixOperator[] INFIXTOPROXY;
 	static {
-		INFIXTOPROXY = new int[PTInfixOperator.VALUES.size()];
-		INFIXTOPROXY[PTInfixOperator.AND] = IExpressionConstants.IN_AND;
-		INFIXTOPROXY[PTInfixOperator.CONDITIONAL_AND] = IExpressionConstants.IN_CONDITIONAL_AND;
-		INFIXTOPROXY[PTInfixOperator.CONDITIONAL_OR] = IExpressionConstants.IN_CONDITIONAL_OR;
-		INFIXTOPROXY[PTInfixOperator.DIVIDE] = IExpressionConstants.IN_DIVIDE;
-		INFIXTOPROXY[PTInfixOperator.EQUALS] = IExpressionConstants.IN_EQUALS;
-		INFIXTOPROXY[PTInfixOperator.GREATER] = IExpressionConstants.IN_GREATER;
-		INFIXTOPROXY[PTInfixOperator.GREATER_EQUALS] = IExpressionConstants.IN_GREATER_EQUALS;
-		INFIXTOPROXY[PTInfixOperator.LEFT_SHIFT] = IExpressionConstants.IN_LEFT_SHIFT;
-		INFIXTOPROXY[PTInfixOperator.LESS] = IExpressionConstants.IN_LESS;
-		INFIXTOPROXY[PTInfixOperator.LESS_EQUALS] = IExpressionConstants.IN_LESS_EQUALS;
-		INFIXTOPROXY[PTInfixOperator.MINUS] = IExpressionConstants.IN_MINUS;
-		INFIXTOPROXY[PTInfixOperator.NOT_EQUALS] = IExpressionConstants.IN_NOT_EQUALS;
-		INFIXTOPROXY[PTInfixOperator.OR] = IExpressionConstants.IN_OR;
-		INFIXTOPROXY[PTInfixOperator.PLUS] = IExpressionConstants.IN_PLUS;
-		INFIXTOPROXY[PTInfixOperator.REMAINDER] = IExpressionConstants.IN_REMAINDER;
-		INFIXTOPROXY[PTInfixOperator.RIGHT_SHIFT_SIGNED] = IExpressionConstants.IN_RIGHT_SHIFT_SIGNED;
-		INFIXTOPROXY[PTInfixOperator.RIGHT_SHIFT_UNSIGNED] = IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED;
-		INFIXTOPROXY[PTInfixOperator.TIMES] = IExpressionConstants.IN_TIMES;
-		INFIXTOPROXY[PTInfixOperator.XOR] = IExpressionConstants.IN_XOR;
+		INFIXTOPROXY = new InfixOperator[PTInfixOperator.VALUES.size()];
+		INFIXTOPROXY[PTInfixOperator.AND] = InfixOperator.IN_AND;
+		INFIXTOPROXY[PTInfixOperator.CONDITIONAL_AND] = InfixOperator.IN_CONDITIONAL_AND;
+		INFIXTOPROXY[PTInfixOperator.CONDITIONAL_OR] = InfixOperator.IN_CONDITIONAL_OR;
+		INFIXTOPROXY[PTInfixOperator.DIVIDE] = InfixOperator.IN_DIVIDE;
+		INFIXTOPROXY[PTInfixOperator.EQUALS] = InfixOperator.IN_EQUALS;
+		INFIXTOPROXY[PTInfixOperator.GREATER] = InfixOperator.IN_GREATER;
+		INFIXTOPROXY[PTInfixOperator.GREATER_EQUALS] = InfixOperator.IN_GREATER_EQUALS;
+		INFIXTOPROXY[PTInfixOperator.LEFT_SHIFT] = InfixOperator.IN_LEFT_SHIFT;
+		INFIXTOPROXY[PTInfixOperator.LESS] = InfixOperator.IN_LESS;
+		INFIXTOPROXY[PTInfixOperator.LESS_EQUALS] = InfixOperator.IN_LESS_EQUALS;
+		INFIXTOPROXY[PTInfixOperator.MINUS] = InfixOperator.IN_MINUS;
+		INFIXTOPROXY[PTInfixOperator.NOT_EQUALS] = InfixOperator.IN_NOT_EQUALS;
+		INFIXTOPROXY[PTInfixOperator.OR] = InfixOperator.IN_OR;
+		INFIXTOPROXY[PTInfixOperator.PLUS] = InfixOperator.IN_PLUS;
+		INFIXTOPROXY[PTInfixOperator.REMAINDER] = InfixOperator.IN_REMAINDER;
+		INFIXTOPROXY[PTInfixOperator.RIGHT_SHIFT_SIGNED] = InfixOperator.IN_RIGHT_SHIFT_SIGNED;
+		INFIXTOPROXY[PTInfixOperator.RIGHT_SHIFT_UNSIGNED] = InfixOperator.IN_RIGHT_SHIFT_UNSIGNED;
+		INFIXTOPROXY[PTInfixOperator.TIMES] = InfixOperator.IN_TIMES;
+		INFIXTOPROXY[PTInfixOperator.XOR] = InfixOperator.IN_XOR;
 	}
 	
 	/**
@@ -99,17 +92,17 @@
 	 * 
 	 * @since 1.0.0
 	 */
-	public static int convertPTInfixOperatorToProxyInfixOperator(PTInfixOperator operator) {
+	public static InfixOperator convertPTInfixOperatorToProxyInfixOperator(PTInfixOperator operator) {
 		return INFIXTOPROXY[operator.getValue()];
 	}
 
-	static final int[] PREFIXTOPROXY;
+	static final PrefixOperator[] PREFIXTOPROXY;
 	static {
-		PREFIXTOPROXY = new int[PTPrefixOperator.VALUES.size()];
-		PREFIXTOPROXY[PTPrefixOperator.COMPLEMENT] = IExpressionConstants.PRE_COMPLEMENT;
-		PREFIXTOPROXY[PTPrefixOperator.MINUS] = IExpressionConstants.PRE_MINUS;
-		PREFIXTOPROXY[PTPrefixOperator.NOT] = IExpressionConstants.PRE_NOT;
-		PREFIXTOPROXY[PTPrefixOperator.PLUS] = IExpressionConstants.PRE_PLUS;
+		PREFIXTOPROXY = new PrefixOperator[PTPrefixOperator.VALUES.size()];
+		PREFIXTOPROXY[PTPrefixOperator.COMPLEMENT] = PrefixOperator.PRE_COMPLEMENT;
+		PREFIXTOPROXY[PTPrefixOperator.MINUS] = PrefixOperator.PRE_MINUS;
+		PREFIXTOPROXY[PTPrefixOperator.NOT] = PrefixOperator.PRE_NOT;
+		PREFIXTOPROXY[PTPrefixOperator.PLUS] = PrefixOperator.PRE_PLUS;
 	}
 	
 	/**
@@ -120,7 +113,7 @@
 	 * 
 	 * @since 1.0.0
 	 */
-	public static int convertPTPrefixOperatorToProxyPrefixOperator(PTPrefixOperator operator) {
+	public static PrefixOperator convertPTPrefixOperatorToProxyPrefixOperator(PTPrefixOperator operator) {
 		return PREFIXTOPROXY[operator.getValue()];
 	}
 	
@@ -142,7 +135,7 @@
 	 * @since 1.0.0
 	 */
 	protected final ProxyFactoryRegistry getRegistry() {
-		return registry;
+		return expression.getRegistry();
 	}
 	
 	/**
@@ -157,7 +150,7 @@
 	}	
 
 	/**
-	 * Get the beanproxy for the given expression and registry.
+	 * Get the beanproxy for the given expression and registry. It will evaluate immediately.
 	 * 
 	 * @param expression
 	 * @param registry
@@ -170,18 +163,17 @@
 	 * @since 1.0.0
 	 */
 	public IBeanProxy getBeanProxy(PTExpression expression, ProxyFactoryRegistry registry) throws IllegalStateException, IllegalArgumentException, ThrowableProxy, NoExpressionValueException, ProcessingException {
-		this.registry = registry;
 		this.expression = registry.getBeanProxyFactory().createExpression();
-		setNextExpression(IExpression.ROOTEXPRESSION);
+		setNextExpression(ForExpression.ROOTEXPRESSION);
 		try {
 			expression.accept(this);
 		} catch (ProcessingException e) {
 			// Handle the most common that make sense to be know distinctly and throw them instead of ProcessingException.
 			Throwable t = e.getCause();
-			if (t instanceof ThrowableProxy)
-				throw (ThrowableProxy) t;
-			else if (t instanceof NoExpressionValueException)
+			if (t instanceof NoExpressionValueException)
 				throw (NoExpressionValueException) t;
+			else if (t instanceof IllegalStateException)
+				throw (IllegalStateException) t;
 			else
 				throw e;
 		}
@@ -190,6 +182,35 @@
 	}
 	
 	/**
+	 * Using the given expression processor allocate the proxy. It will not evaluate immediately, but just push onto the expression.
+	 * @param expression
+	 * @param expressionProcessor
+	 * @return the ExpressionProxy for the allocation.
+	 * @throws IllegalStateException
+	 * @throws IllegalArgumentException
+	 * @throws ProcessingException
+	 * 
+	 * @since 1.1.0
+	 */
+	public ExpressionProxy getProxy(PTExpression expression, IExpression expressionProcessor) throws IllegalStateException, IllegalArgumentException, ProcessingException {
+		this.expression = expressionProcessor;
+		try {
+			ExpressionProxy proxy = expressionProcessor.createProxyAssignmentExpression(ForExpression.ROOTEXPRESSION);
+			setNextExpression(ForExpression.ASSIGNMENT_RIGHT);
+			expression.accept(this);
+			return proxy;
+		} catch (ProcessingException e) {
+			// Handle the most common that make sense to be know distinctly and throw them instead of ProcessingException.
+			Throwable t = e.getCause();
+			if (t instanceof IllegalStateException)
+				throw (IllegalStateException) t;
+			else
+				throw e;
+		}
+	}
+
+	
+	/**
 	 * Set the next expression type. (i.e. the <code>forExpression</code> field of most of the create expression methods.
 	 * 
 	 * @param nextExpression
@@ -197,7 +218,7 @@
 	 * @see IExpression#createInfixExpression(int, int, int)
 	 * @since 1.0.0
 	 */
-	protected final void setNextExpression(int nextExpression) {
+	protected final void setNextExpression(ForExpression nextExpression) {
 		this.nextExpression = nextExpression;
 	}
 
@@ -209,7 +230,7 @@
 	 * @see IExpression#createInfixExpression(int, int, int)
 	 * @since 1.0.0
 	 */
-	protected final int getNextExpression() {
+	protected final ForExpression getNextExpression() {
 		return nextExpression;
 	}
 
@@ -217,20 +238,14 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTArrayAccess)
 	 */
 	public boolean visit(PTArrayAccess node) {
-		try {
-			getExpression().createArrayAccess(getNextExpression(), node.getIndexes().size());
-			setNextExpression(IExpression.ARRAYACCESS_ARRAY);
-			node.getArray().accept(this);
-			List idx = node.getIndexes();
-			int s = idx.size();
-			for (int i = 0; i < s; i++) {
-				setNextExpression(IExpression.ARRAYACCESS_INDEX);
-				((PTExpression) idx.get(i)).accept(this);
-			}
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
+		getExpression().createArrayAccess(getNextExpression(), node.getIndexes().size());
+		setNextExpression(ForExpression.ARRAYACCESS_ARRAY);
+		node.getArray().accept(this);
+		List idx = node.getIndexes();
+		int s = idx.size();
+		for (int i = 0; i < s; i++) {
+			setNextExpression(ForExpression.ARRAYACCESS_INDEX);
+			((PTExpression) idx.get(i)).accept(this);
 		}
 		return false;
 	}
@@ -239,22 +254,16 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTArrayCreation)
 	 */
 	public boolean visit(PTArrayCreation node) {
-		try {
-			getExpression().createArrayCreation(getNextExpression(), node.getType(), node.getDimensions().size());
-			if (node.getDimensions().isEmpty()) {
-				node.getInitializer().accept(this);	// Array initializer doesn't require a next expression.
-			} else {
-				List dims = node.getDimensions();
-				int s = dims.size();
-				for (int i = 0; i < s; i++) {
-					setNextExpression(IExpression.ARRAYCREATION_DIMENSION);
-					((PTExpression) dims.get(i)).accept(this);
-				}
+		getExpression().createArrayCreation(getNextExpression(), node.getType(), node.getDimensions().size());
+		if (node.getDimensions().isEmpty()) {
+			node.getInitializer().accept(this);	// Array initializer doesn't require a next expression.
+		} else {
+			List dims = node.getDimensions();
+			int s = dims.size();
+			for (int i = 0; i < s; i++) {
+				setNextExpression(ForExpression.ARRAYCREATION_DIMENSION);
+				((PTExpression) dims.get(i)).accept(this);
 			}
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
 		}
 		return false;
 	}
@@ -263,18 +272,12 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTArrayInitializer)
 	 */
 	public boolean visit(PTArrayInitializer node) {
-		try {
-			getExpression().createArrayInitializer(node.getExpressions().size());
-			List exps = node.getExpressions();
-			int s = exps.size();
-			for (int i = 0; i < s; i++) {
-				setNextExpression(IExpression.ARRAYINITIALIZER_EXPRESSION);
-				((PTExpression) exps.get(i)).accept(this);
-			}
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
+		getExpression().createArrayInitializer(node.getExpressions().size());
+		List exps = node.getExpressions();
+		int s = exps.size();
+		for (int i = 0; i < s; i++) {
+			setNextExpression(ForExpression.ARRAYINITIALIZER_EXPRESSION);
+			((PTExpression) exps.get(i)).accept(this);
 		}
 		return false;
 	}
@@ -283,13 +286,7 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTBooleanLiteral)
 	 */
 	public boolean visit(PTBooleanLiteral node) {
-		try {
-			getExpression().createPrimitiveLiteral(getNextExpression(), node.isBooleanValue());
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		getExpression().createPrimitiveLiteral(getNextExpression(), node.isBooleanValue());
 		return false;
 	}
 
@@ -297,15 +294,9 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTCastExpression)
 	 */
 	public boolean visit(PTCastExpression node) {
-		try {
-			getExpression().createCastExpression(getNextExpression(), node.getType());
-			setNextExpression(IExpression.CAST_EXPRESSION);
-			node.getExpression().accept(this);
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		getExpression().createCastExpression(getNextExpression(), node.getType());
+		setNextExpression(ForExpression.CAST_EXPRESSION);
+		node.getExpression().accept(this);
 		return false;
 	}
 
@@ -313,13 +304,7 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTCharacterLiteral)
 	 */
 	public boolean visit(PTCharacterLiteral node) {
-		try {
-			getExpression().createPrimitiveLiteral(getNextExpression(), node.getCharValue());
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		getExpression().createPrimitiveLiteral(getNextExpression(), node.getCharValue());
 		return false;
 	}
 
@@ -327,18 +312,12 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTClassInstanceCreation)
 	 */
 	public boolean visit(PTClassInstanceCreation node) {
-		try {
-			getExpression().createClassInstanceCreation(getNextExpression(), node.getType(), node.getArguments().size());
-			List args = node.getArguments();
-			int s = args.size();
-			for (int i = 0; i < s; i++) {
-				setNextExpression(IExpression.CLASSINSTANCECREATION_ARGUMENT);
-				((PTExpression) args.get(i)).accept(this);
-			}
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
+		getExpression().createClassInstanceCreation(getNextExpression(), node.getType(), node.getArguments().size());
+		List args = node.getArguments();
+		int s = args.size();
+		for (int i = 0; i < s; i++) {
+			setNextExpression(ForExpression.CLASSINSTANCECREATION_ARGUMENT);
+			((PTExpression) args.get(i)).accept(this);
 		}
 		return false;
 	}
@@ -347,19 +326,13 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTConditionalExpression)
 	 */
 	public boolean visit(PTConditionalExpression node) {
-		try {
-			getExpression().createConditionalExpression(getNextExpression());
-			setNextExpression(IExpression.CONDITIONAL_CONDITION);
-			node.getCondition().accept(this);
-			setNextExpression(IExpression.CONDITIONAL_TRUE);
-			node.getTrue().accept(this);
-			setNextExpression(IExpression.CONDITIONAL_FALSE);
-			node.getFalse().accept(this);			
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		getExpression().createConditionalExpression(getNextExpression());
+		setNextExpression(ForExpression.CONDITIONAL_CONDITION);
+		node.getCondition().accept(this);
+		setNextExpression(ForExpression.CONDITIONAL_TRUE);
+		node.getTrue().accept(this);
+		setNextExpression(ForExpression.CONDITIONAL_FALSE);
+		node.getFalse().accept(this);
 		return false;
 	}
 
@@ -367,16 +340,10 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTFieldAccess)
 	 */
 	public boolean visit(PTFieldAccess node) {
-		try {
-			getExpression().createFieldAccess(getNextExpression(), node.getField(), node.getReceiver() != null);
-			if (node.getReceiver() != null) {
-				setNextExpression(IExpression.FIELD_RECEIVER);
-				node.getReceiver().accept(this);
-			}
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
+		getExpression().createFieldAccess(getNextExpression(), node.getField(), node.getReceiver() != null);
+		if (node.getReceiver() != null) {
+			setNextExpression(ForExpression.FIELD_RECEIVER);
+			node.getReceiver().accept(this);
 		}
 		return false;
 	}
@@ -385,22 +352,16 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTInfixExpression)
 	 */
 	public boolean visit(PTInfixExpression node) {
-		try {
-			getExpression().createInfixExpression(getNextExpression(), convertPTInfixOperatorToProxyInfixOperator(node.getOperator()), node.getExtendedOperands().size());
-			setNextExpression(IExpression.INFIX_LEFT);
-			node.getLeftOperand().accept(this);
-			setNextExpression(IExpression.INFIX_RIGHT);
-			node.getRightOperand().accept(this);
-			List extended = node.getExtendedOperands();
-			int s = extended.size();
-			for (int i = 0; i < s; i++) {
-				setNextExpression(IExpression.INFIX_EXTENDED);
-				((PTExpression) extended.get(i)).accept(this);
-			}
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
+		getExpression().createInfixExpression(getNextExpression(), convertPTInfixOperatorToProxyInfixOperator(node.getOperator()), node.getExtendedOperands().size());
+		setNextExpression(ForExpression.INFIX_LEFT);
+		node.getLeftOperand().accept(this);
+		setNextExpression(ForExpression.INFIX_RIGHT);
+		node.getRightOperand().accept(this);
+		List extended = node.getExtendedOperands();
+		int s = extended.size();
+		for (int i = 0; i < s; i++) {
+			setNextExpression(ForExpression.INFIX_EXTENDED);
+			((PTExpression) extended.get(i)).accept(this);
 		}
 		return false;
 	}
@@ -409,15 +370,9 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTInstanceof)
 	 */
 	public boolean visit(PTInstanceof node) {
-		try {
-			getExpression().createInstanceofExpression(getNextExpression(), node.getType());
-			setNextExpression(IExpression.INSTANCEOF_VALUE);
-			node.getOperand().accept(this);
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		getExpression().createInstanceofExpression(getNextExpression(), node.getType());
+		setNextExpression(ForExpression.INSTANCEOF_VALUE);
+		node.getOperand().accept(this);
 		return false;
 	}
 
@@ -432,22 +387,16 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTMethodInvocation)
 	 */
 	public boolean visit(PTMethodInvocation node) {
-		try {
-			getExpression().createMethodInvocation(getNextExpression(), node.getName(), node.getReceiver() != null, node.getArguments().size());
-			if (node.getReceiver() != null) {
-				setNextExpression(IExpression.METHOD_RECEIVER);
-				node.getReceiver().accept(this);
-			}
-			List args = node.getArguments();
-			int s = args.size();
-			for (int i = 0; i < s; i++) {
-				setNextExpression(IExpression.METHOD_ARGUMENT);
-				((PTExpression) args.get(i)).accept(this);
-			}			
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
+		getExpression().createMethodInvocation(getNextExpression(), node.getName(), node.getReceiver() != null, node.getArguments().size());
+		if (node.getReceiver() != null) {
+			setNextExpression(ForExpression.METHOD_RECEIVER);
+			node.getReceiver().accept(this);
+		}
+		List args = node.getArguments();
+		int s = args.size();
+		for (int i = 0; i < s; i++) {
+			setNextExpression(ForExpression.METHOD_ARGUMENT);
+			((PTExpression) args.get(i)).accept(this);
 		}
 		return false;
 	}
@@ -456,14 +405,8 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTName)
 	 */
 	public boolean visit(PTName node) {
-		try {
-			// This is special in the PTName can only be used as a type receiver at this time.
-			getExpression().createTypeReceiver(node.getName());
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		// This is special in the PTName can only be used as a type receiver at this time.
+		getExpression().createTypeReceiver(node.getName());
 		return false;
 	}
 
@@ -471,14 +414,8 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTNullLiteral)
 	 */
 	public boolean visit(PTNullLiteral node) {
-		try {
-			// This is special in the PTName can only be used as a type receiver at this time.
-			getExpression().createNull(getNextExpression());
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		// This is special in the PTName can only be used as a type receiver at this time.
+		getExpression().createNull(getNextExpression());
 		return false;
 	}
 
@@ -486,31 +423,25 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTNumberLiteral)
 	 */
 	public boolean visit(PTNumberLiteral node) {
-		try {
-			// It is assumed the tokens are trimmed.
-			String lit = node.getToken();
-			char lastChar = lit.charAt(lit.length()-1);
-			if (lastChar == 'l' || lastChar == 'L' ) {
-				// It is definitely a long.
-				// Using decode so that things like 0x3 will be parsed. parseLong won't recognize those.
-				getExpression().createPrimitiveLiteral(getNextExpression(), Long.decode(lit.substring(0, lit.length()-1)).longValue());
-			} else if (lastChar == 'F' || lastChar == 'f') {
-				// It is definitely a float.
-				getExpression().createPrimitiveLiteral(getNextExpression(), Float.parseFloat(lit.substring(0, lit.length()-1)));
-			} else if (lastChar == 'D' || lastChar == 'd')  {
-				// It is definitely a double.
-				getExpression().createPrimitiveLiteral(getNextExpression(), Double.parseDouble(lit.substring(0, lit.length()-1)));
-			} else if (lit.indexOf('.') != -1 || lit.indexOf('e') != -1 || lit.indexOf('E') != -1) {
-					// It is definitely a double. (has a period or an exponent, but does not have an 'f' on the end is always a double).
-					getExpression().createPrimitiveLiteral(getNextExpression(), Double.parseDouble(lit.substring(0, lit.length())));
-			} else {
-				// Using decode so that things like 0x3 will be parsed. parseInt won't recognize those.
-				getExpression().createPrimitiveLiteral(getNextExpression(), Integer.decode(lit).intValue());
-			}
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
+		// It is assumed the tokens are trimmed.
+		String lit = node.getToken();
+		char lastChar = lit.charAt(lit.length()-1);
+		if (lastChar == 'l' || lastChar == 'L' ) {
+			// It is definitely a long.
+			// Using decode so that things like 0x3 will be parsed. parseLong won't recognize those.
+			getExpression().createPrimitiveLiteral(getNextExpression(), Long.decode(lit.substring(0, lit.length()-1)).longValue());
+		} else if (lastChar == 'F' || lastChar == 'f') {
+			// It is definitely a float.
+			getExpression().createPrimitiveLiteral(getNextExpression(), Float.parseFloat(lit.substring(0, lit.length()-1)));
+		} else if (lastChar == 'D' || lastChar == 'd')  {
+			// It is definitely a double.
+			getExpression().createPrimitiveLiteral(getNextExpression(), Double.parseDouble(lit.substring(0, lit.length()-1)));
+		} else if (lit.indexOf('.') != -1 || lit.indexOf('e') != -1 || lit.indexOf('E') != -1) {
+				// It is definitely a double. (has a period or an exponent, but does not have an 'f' on the end is always a double).
+				getExpression().createPrimitiveLiteral(getNextExpression(), Double.parseDouble(lit.substring(0, lit.length())));
+		} else {
+			// Using decode so that things like 0x3 will be parsed. parseInt won't recognize those.
+			getExpression().createPrimitiveLiteral(getNextExpression(), Integer.decode(lit).intValue());
 		}
 		return false;
 	}
@@ -527,15 +458,9 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTPrefixExpression)
 	 */
 	public boolean visit(PTPrefixExpression node) {
-		try {
-			getExpression().createPrefixExpression(getNextExpression(), convertPTPrefixOperatorToProxyPrefixOperator(node.getOperator()));
-			setNextExpression(IExpression.PREFIX_OPERAND);
-			node.getExpression().accept(this);
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		getExpression().createPrefixExpression(getNextExpression(), convertPTPrefixOperatorToProxyPrefixOperator(node.getOperator()));
+		setNextExpression(ForExpression.PREFIX_OPERAND);
+		node.getExpression().accept(this);
 		return false;
 	}
 
@@ -543,13 +468,7 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTStringLiteral)
 	 */
 	public boolean visit(PTStringLiteral node) {
-		try {
-			getExpression().createProxyExpression(getNextExpression(), getRegistry().getBeanProxyFactory().createBeanProxyWith(node.getLiteralValue()));
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		getExpression().createProxyExpression(getNextExpression(), getRegistry().getBeanProxyFactory().createBeanProxyWith(node.getLiteralValue()));
 		return false;
 	}
 
@@ -564,13 +483,7 @@
 	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTTypeLiteral)
 	 */
 	public boolean visit(PTTypeLiteral node) {
-		try {
-			getExpression().createTypeLiteral(getNextExpression(), node.getType());
-		} catch (ThrowableProxy e) {
-			throw new ProcessingException(e);
-		} catch (NoExpressionValueException e) {
-			throw new ProcessingException(e);
-		}
+		getExpression().createTypeLiteral(getNextExpression(), node.getType());
 		return false;
 	}
 
diff --git a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/internal/java/adapters/JavaReflectionKey.java b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/internal/java/adapters/JavaReflectionKey.java
index cb05c13..3ef0435 100644
--- a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/internal/java/adapters/JavaReflectionKey.java
+++ b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/internal/java/adapters/JavaReflectionKey.java
@@ -11,13 +11,12 @@
 package org.eclipse.jem.internal.java.adapters;
 /*
  *  $RCSfile: JavaReflectionKey.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:37:02 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:16 $ 
  */
 import java.util.*;
 
 import org.eclipse.emf.ecore.*;
 import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.xmi.XMIResource;
 
 import org.eclipse.jem.java.*;
 
@@ -51,50 +50,10 @@
 
 	static { initializePrimitivesCollection(); }
 	
-	protected XMIResource resource; //FB
+	protected JavaXMIFactoryImpl.JavaXMIResource resource; //FB
 	protected List extensions;
-//FB /**
-//FB  * JavaReflectionKey constructor comment.
-//FB  */
-//FB public JavaReflectionKey() {
-//FB 	super();
-//FB }
 
-//FB /**
-//FB  * Method JavaReflectionKey.
-//FB  * @param extensions
-//FB  */
-//FB public JavaReflectionKey(List extensions) {
-//FB 	super();
-//FB 	setExtensions(extensions);
-//FB }
-
-//FB /**
-//FB  * Method JavaReflectionKey.
-//FB  * @param extensions
-//FB  * @param extent
-//FB  */
-//FB public JavaReflectionKey(List extensions, Extent extent) {
-//FB 	this(extent);
-//FB 	setExtensions(extensions);
-//FB }
-
-//FB /**
-//FB  * JavaReflectionKey constructor comment.
-//FB  * @param e com.ibm.etools.emf.ref.Extent
-//FB  */
-//FB public JavaReflectionKey(com.ibm.etools.emf.ref.Extent e) {
-//FB 	super(e);
-//FB }
-//FB /**
-//FB  * Set the extensions to use. Typically only called by JavaXMIFactoryImpl.
-//FB  */
-//FB public void setExtensions(List extensions) {
-//FB 	this.extensions = extensions;
-//FB }
-
-//FB ADDED
-public JavaReflectionKey(List extensions, XMIResource resource) {
+public JavaReflectionKey(List extensions, JavaXMIFactoryImpl.JavaXMIResource resource) {
   this.extensions = extensions;
   this.resource = resource;
 }
@@ -389,7 +348,7 @@
  * The Key must be an ID for it to be found.
  */
 public Object primGet(String key) {
-	return resource.getIDToEObjectMap().get(key);
+	return resource.primGetEObject(key);
 }
 protected EPackage getPackage() {
 	//FB return (EPackage) super.get(JavaPackage.PACKAGE_ID);
diff --git a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/internal/java/adapters/JavaXMIFactoryImpl.java b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/internal/java/adapters/JavaXMIFactoryImpl.java
index 7896eab..622c04a 100644
--- a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/internal/java/adapters/JavaXMIFactoryImpl.java
+++ b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/internal/java/adapters/JavaXMIFactoryImpl.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.internal.java.adapters;
 /*
  *  $RCSfile: JavaXMIFactoryImpl.java,v $
- *  $Revision: 1.5 $  $Date: 2005/02/15 22:37:02 $ 
+ *  $Revision: 1.6 $  $Date: 2005/05/11 19:01:16 $ 
  */
 import java.io.IOException;
 import java.util.*;
@@ -110,6 +110,20 @@
 			}
 			return result;
 		}
+		
+		/**
+		 * Used by JavaReflectionKey to look directly into ID table to bypass an infinite loop. It will 
+		 * call here because it may not of first been found, but then added, so now is found.
+		 * 
+		 * @param uriFragment
+		 * @return
+		 * 
+		 * @since 1.1.0
+		 */
+		EObject primGetEObject(String uriFragment) {
+			return super.getEObject(uriFragment);
+		}
+		
 		/* (non-Javadoc)
 		 * @see org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl#useIDAttributes()
 		 */
diff --git a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/JavaHelpers.java b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/JavaHelpers.java
index 998120f..b3cc8c1 100644
--- a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/JavaHelpers.java
+++ b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/JavaHelpers.java
@@ -12,7 +12,7 @@
 
 /*
  *  $RCSfile: JavaHelpers.java,v $
- *  $Revision: 1.4 $  $Date: 2005/02/15 22:37:02 $ 
+ *  $Revision: 1.5 $  $Date: 2005/05/11 19:01:16 $ 
  */
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EClassifier;
@@ -39,6 +39,17 @@
 	static final String PRIM_INTEGER_NAME = "int";
 	static final String PRIM_LONG_NAME = "long";
 	static final String PRIM_SHORT_NAME = "short";
+	
+	static final int PRIM_NOT_ID = 0;
+	static final int PRIM_BOOLEAN_ID = 1;
+	static final int PRIM_CHARACTER_ID = 2;
+	static final int PRIM_BYTE_ID = 3;
+	static final int PRIM_DOUBLE_ID = 4;
+	static final int PRIM_FLOAT_ID = 5;
+	static final int PRIM_INTEGER_ID = 6;
+	static final int PRIM_LONG_ID = 7;
+	static final int PRIM_SHORT_ID = 8;
+	
 	/**
 	 * Get the qualified name (with using '.' for inner classes). Will return the name if primitive too (e.g. "boolean")
 	 * Note: This should of been get the simple name and not the qualifed name, but it is too late and has been established
@@ -56,7 +67,24 @@
 	 * @since 1.0.0
 	 */
 	public String getSimpleName();
+
+	/**
+	 * Get the primitive type that this helper wrappers or is (e.g. "java.lang.Integer" and "int" types return "int" type). If not a primitive
+	 * or a wrapper for a primitive, then return null.
+	 * @return
+	 * 
+	 * @since 1.0.0
+	 */
 	public JavaDataType getPrimitive();
+	
+	/**
+	 * Get the primitive id that this helper wrappers or is (e.g. "java.lang.Integer" and "int" will return {@link JavaHelpers#PRIM_INTEGER_ID}). If
+	 * not a wrapper for a primitive then return {@link JavaHelpers#PRIM_NOT_ID}.
+	 * @return
+	 * 
+	 * @since 1.1.0
+	 */
+	public int getPrimitiveID();
 	/**
 	 * To be used by people that need to get the qualified name. This would use '.' for inner classes
 	 * and include the package name.
diff --git a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/impl/JavaClassImpl.java b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/impl/JavaClassImpl.java
index ce1219f..faba2ad 100644
--- a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/impl/JavaClassImpl.java
+++ b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/impl/JavaClassImpl.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 /*
  *  $RCSfile: JavaClassImpl.java,v $
- *  $Revision: 1.14 $  $Date: 2005/04/14 19:05:33 $ 
+ *  $Revision: 1.15 $  $Date: 2005/05/11 19:01:16 $ 
  */
 package org.eclipse.jem.java.impl;
 
@@ -619,6 +619,31 @@
 		}
 		return null;
 	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.java.JavaHelpers#getPrimitiveID()
+	 */
+	public int getPrimitiveID() {
+		String myName = getQualifiedName();
+		if (myName.equals(INTEGER_NAME))
+			return PRIM_INTEGER_ID;
+		if (myName.equals(BOOLEAN_NAME))
+			return PRIM_BOOLEAN_ID;
+		if (myName.equals(BYTE_NAME))
+			return PRIM_BYTE_ID;
+		if (myName.equals(SHORT_NAME))
+			return PRIM_SHORT_ID;
+		if (myName.equals(LONG_NAME))
+			return PRIM_LONG_ID;
+		if (myName.equals(FLOAT_NAME))
+			return PRIM_FLOAT_ID;
+		if (myName.equals(DOUBLE_NAME))
+			return PRIM_DOUBLE_ID;
+		if (myName.equals(CHARACTER_NAME))
+			return PRIM_CHARACTER_ID;
+		return PRIM_NOT_ID;
+	}
 
 	/**
 	 * Return the primitive name for this type if one exists.
diff --git a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/impl/JavaDataTypeImpl.java b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/impl/JavaDataTypeImpl.java
index dd79ff5..a6912a6 100644
--- a/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/impl/JavaDataTypeImpl.java
+++ b/plugins/org.eclipse.jem/mofjava/org/eclipse/jem/java/impl/JavaDataTypeImpl.java
@@ -11,7 +11,7 @@
 package org.eclipse.jem.java.impl;
 /*
  *  $RCSfile: JavaDataTypeImpl.java,v $
- *  $Revision: 1.7 $  $Date: 2005/04/14 19:05:33 $ 
+ *  $Revision: 1.8 $  $Date: 2005/05/11 19:01:16 $ 
  */
 
 import java.util.Collection;
@@ -42,9 +42,13 @@
 	static final String FLOAT_ZERO = "0.0f";
 	static final String CHAR_ZERO = "'0'";
 	static final String ZERO = "0";
+	
+	private int primitive_type = PRIM_NOT_ID;
+	
 	protected JavaDataTypeImpl() {
 		super();
 	}
+	
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -59,13 +63,13 @@
 	 */
 	public String getDefaultValueString() {
 		String typeName = getJavaName();
-		if (typeName.equals(Boolean.TYPE.getName()))
+		if (typeName.equals(PRIM_BOOLEAN_NAME))
 			return FALSE;
-		if (typeName.equals(Double.TYPE.getName()))
+		if (typeName.equals(PRIM_DOUBLE_NAME))
 			return DOUBLE_ZERO;
-		if (typeName.equals(Float.TYPE.getName()))
+		if (typeName.equals(PRIM_FLOAT_NAME))
 			return FLOAT_ZERO;			
-		if (typeName.equals(Character.TYPE.getName()))
+		if (typeName.equals(PRIM_CHARACTER_NAME))
 			return CHAR_ZERO;
 		return ZERO;
 	}
@@ -76,6 +80,33 @@
 		return this;
 	}
 	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jem.java.JavaHelpers#getPrimitiveID()
+	 */
+	public int getPrimitiveID() {
+		if (primitive_type == PRIM_NOT_ID) {
+			String name = getName();
+			if (name.equals(PRIM_BOOLEAN_NAME))
+				primitive_type = PRIM_BOOLEAN_ID;
+			if (name.equals(PRIM_CHARACTER_NAME))
+				primitive_type = PRIM_CHARACTER_ID;
+			if (name.equals(PRIM_BYTE_NAME))
+				primitive_type = PRIM_BYTE_ID;
+			if (name.equals(PRIM_SHORT_NAME))
+				primitive_type = PRIM_SHORT_ID;
+			if (name.equals(PRIM_INTEGER_NAME))
+				primitive_type = PRIM_INTEGER_ID;
+			if (name.equals(PRIM_LONG_NAME))
+				primitive_type = PRIM_LONG_ID;
+			if (name.equals(PRIM_FLOAT_NAME))
+				primitive_type = PRIM_FLOAT_ID;
+			if (name.equals(PRIM_DOUBLE_NAME))
+				primitive_type = PRIM_DOUBLE_ID;
+		}
+		return primitive_type;
+	}
+	
 	public String getSimpleName() {
 		return getName();
 	}
@@ -93,24 +124,26 @@
 	 * getWrapper method comment.
 	 */
 	protected String getWrapperQualifiedName() {
-		String myName = getJavaName();
-		if (myName.equals(PRIM_INTEGER_NAME))
-			return INTEGER_NAME;
-		if(myName.equals(PRIM_CHARACTER_NAME))
-			return CHARACTER_NAME;
-		if(myName.equals(PRIM_BOOLEAN_NAME))
-			return BOOLEAN_NAME;
-		if(myName.equals(PRIM_BYTE_NAME))
-			return BYTE_NAME;
-		if(myName.equals(PRIM_SHORT_NAME))
-			return SHORT_NAME;
-		if(myName.equals(PRIM_LONG_NAME))
-			return LONG_NAME;
-		if(myName.equals(PRIM_FLOAT_NAME))
-			return FLOAT_NAME;
-		if(myName.equals(PRIM_DOUBLE_NAME))
-			return DOUBLE_NAME;
-		return null;
+		switch (getPrimitiveID()) {
+			case PRIM_INTEGER_ID:
+				return INTEGER_NAME;
+			case PRIM_CHARACTER_ID:
+				return CHARACTER_NAME;
+			case PRIM_BOOLEAN_ID:
+				return BOOLEAN_NAME;
+			case PRIM_BYTE_ID:
+				return BYTE_NAME;
+			case PRIM_SHORT_ID:
+				return SHORT_NAME;
+			case PRIM_LONG_ID:
+				return LONG_NAME;
+			case PRIM_FLOAT_ID:
+				return FLOAT_NAME;
+			case PRIM_DOUBLE_ID:
+				return DOUBLE_NAME;
+			default:
+				return null;
+		}
 	}
 	/*
 	 * JavaHelpers.isArray() - array types are always JavaClasses, even if their component type is