/*******************************************************************************
 * 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: ExpressionProcesserController.java,v $
 *  $Revision: 1.10 $  $Date: 2005/06/22 21:05:17 $ 
 */
package org.eclipse.jem.internal.proxy.vm.remote;

import java.io.DataInputStream;
import java.io.IOException;
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.remote.Commands;
import org.eclipse.jem.internal.proxy.common.remote.ExpressionCommands;
import org.eclipse.jem.internal.proxy.initParser.tree.*;

 
/**
 * This processes the commands for expression processing and sends them over
 * to the common expression processer.
 * 
 * This will be instantiated on the start of an expression. And then
 * each expression request from the IDE will be sent into here. The
 * reason this guy doesn't hold onto the connection and process the
 * entire expression is because we need to return to the connection
 * handler to keep the connection live (there is timeouts and stuff
 * in there that we don't want to duplicate here).
 * <p>
 * If there are any expression processing errors (versus hard io errors) we
 * will save up the error but don't do any more processing other than to make
 * sure we read the complete subcommand. This is so that the inputstream is left
 * in a valid state without standed data.
 * <p>
 * The at the sync point (either get value or sync subcommand) we will send back
 * the error.
 *  
 * @since 1.0.0
 */
public class ExpressionProcesserController {

	
	protected final RemoteVMServerThread server;
	protected final ConnectionHandler connHandler;	
	protected final ExpressionProcesser exp;
	protected Commands.ValueObject workerValue = new Commands.ValueObject();	// A worker value object so we don't need to keep creating them and releasing them.
	private ClassLoader classLoader;
	
	/**
	 * Create with a default expression processer and use default flag for trace.
	 * @param server
	 * 
	 * @since 1.0.0
	 */
	public ExpressionProcesserController(RemoteVMServerThread server, ConnectionHandler connHandler) {
		this(server, connHandler, new ExpressionProcesser(Boolean.getBoolean(ExpressionCommands.EXPRESSIONTRACE), Long.getLong(ExpressionCommands.EXPRESSIONTRACE_TIMER_THRESHOLD, -1L).longValue()));
	}
	
	/**
	 * Construct with a default expression processer.
	 * @param server
	 * @param connHandler
	 * @param trace
	 * 
	 * @since 1.1.0
	 */
	public ExpressionProcesserController(RemoteVMServerThread server, ConnectionHandler connHandler, boolean trace) {
		this(server, connHandler, new ExpressionProcesser(trace, Long.getLong(ExpressionCommands.EXPRESSIONTRACE_TIMER_THRESHOLD, -1L).longValue()));
	}
	
	/**
	 * Create from a subclass with a given expression processer.
	 * 
	 * @param server
	 * @param exp
	 * 
	 * @since 1.0.0
	 */
	protected ExpressionProcesserController(RemoteVMServerThread server, ConnectionHandler connHandler, ExpressionProcesser exp) {
		this.server = server;
		this.connHandler = connHandler;
		this.exp = exp;
	}
	
	/**
	 * Set the class loader to use for finding classes. If never set, or if <code>null</code>, then
	 * <code>Class.forName</code> will be used.
	 * 
	 * @param classLoader
	 * 
	 * @since 1.0.0
	 */
	public void setClassLoader(ClassLoader classLoader) {
		this.classLoader = classLoader;
	}
	
	/*
	 * Array of primitive type names. Used to look up primtive types in primitive types array. 
	 * 
	 * @since 1.0.0
	 */
	private static final List PRIMITIVE_NAMES = Arrays.asList(new String[] {"byte", "char", "short", "int", "long", "float", "double"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
	private static final Class[] PRIMITIVE_TYPES = new Class[] {Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE};
	/**
	 * Load the class given the name. If not found, return null.
	 * 
	 * @param className
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected Class loadClass(String className) throws ClassNotFoundException {
		if (className == null)
			return null;
		else if (className.endsWith("[]")) { //$NON-NLS-1$
			// We have an array request instead. This is trickier.
			return loadClass(MapTypes.getJNIFormatName(className));
		} else {
			int primIndex = PRIMITIVE_NAMES.indexOf(className);
			if (primIndex >= 0)
				return PRIMITIVE_TYPES[primIndex];
			else if (classLoader == null) {
				return Class.forName(className);
			} else {
				return classLoader.loadClass(className);
			}
		}
	}

	/**
	 * Now process the input stream. If either throws occurs, this is a hard error and we must terminate
	 * the entire connection. The input stream is in an unknown state.
	 * 
	 * @param in The input stream to get the data for the current sub-command.
	 * 
	 * @throws CommandException
	 * @throws IOException
	 * @since 1.0.0
	 */
	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
		// when all is done we can return the error and still have a valid connection socket.
		byte subcommand = in.readByte();
		try {
			switch (subcommand) {
				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);
					Object value = connHandler.getInvokableObject(workerValue);
					if (value == null)
						exp.pushExpression(null, MethodHelper.NULL_TYPE);
					else if (workerValue.isPrimitive())
						exp.pushExpression(value, workerValue.getPrimitiveType());
					else
						exp.pushExpression(value, value.getClass());
					break;

				case InternalExpressionTypes.CAST_EXPRESSION_VALUE:
					// Get a cast request. The type is sent as valueObject.
					Commands.readValue(in, workerValue);
					try {
						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) {
						// Do nothing, already processed.
					} 
					break;

				case InternalExpressionTypes.INSTANCEOF_EXPRESSION_VALUE:
					// Get a instanceof request. The type is sent as valueObject.
					Commands.readValue(in, workerValue);
					try {
						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) {
						// Do nothing, already processed.
					} 
					break;

				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();
					exp.pushInfix(InfixOperator.get(infix_operator), InternalInfixOperandType.get(infix_operandType));
					break;

				case InternalExpressionTypes.PREFIX_EXPRESSION_VALUE:
					// Get a prefix request. The operator is sent as byte.
					byte prefix_operandType = in.readByte();
					exp.pushPrefix(PrefixOperator.get(prefix_operandType));
					break;

				case InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION_VALUE:
					// Get an array access request. The index cound is sent as int.
					int arrayAccess_Indexcount = in.readInt();
					exp.pushArrayAccess(arrayAccess_Indexcount);
					break;

				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();
					try {
						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) {
						// Do nothing, already processed.
					} 

					break;

				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();
					try {
						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) {
						// Do nothing, already processed.
					}
					break;

				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();
					try {
						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) {
						// Do nothing, already processed.
					}
					break;

				case InternalExpressionTypes.TYPERECEIVER_EXPRESSION_VALUE:
					// Get a type receiver request. The type is sent as valueObject.
					Commands.readValue(in, workerValue);
					try {
						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) {
						// Do nothing, already processed.
					}
					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 {
						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 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();
					try {
						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 InternalExpressionTypes.CONDITIONAL_EXPRESSION_VALUE:
					// Get a conditional expression request. The expression type (ie. condition/true/false) is sent as a byte
					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 {
						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());
						}
					}
					Class decClass = null;
					Class[] argClasses = null;
					try {
						decClass = getBeanTypeValue(decClassValue);
						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) {
						// The default trace doesn't show what method was being searched for, so recreate with that.
						StringBuffer s = new StringBuffer();
						s.append(decClass.getName());
						s.append('.');
						s.append(methodName);
						s.append('(');
						if (argClasses != null) {
							for (int i = 0; i < argClasses.length; i++) {
								if (i > 0)
									s.append(',');
								s.append(argClasses[i].getName());
							}
						}
						s.append(')');
						NoSuchMethodException ne = new NoSuchMethodException(s.toString());
						ne.setStackTrace(e.getStackTrace());
						exp.processException(ne);	// 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 {
						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;
					
				case InternalExpressionTypes.SUBEXPRESSION_BEGIN_EXPRESSION_VALUE:
					// Get a begin subexpression proxy expression. The subexpression id is sent as an int.
					exp.pushSubexpressionBegin(in.readInt());
					break;
					
				case InternalExpressionTypes.SUBEXPRESSION_END_EXPRESSION_VALUE:
					// Get a end subexpression proxy expression. The subexpression id is sent as an int.
					exp.pushSubexpressionEnd(in.readInt());
					break;
					
			}
			
		} catch (RuntimeException e) {
			exp.processException(e);
		}
		
		workerValue.set();	// Clear it out so nothing being held onto.
	}
	
	/**
	 * 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.
	 * 
	 * @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.1.0
	 */
	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 (Class) beantype;
	}
		
	/**
	 * 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.
	 * 
	 * @since 1.1.0
	 */
	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;
	}	

	/**
	 * 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.1.0
	 */
	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;
		}
	}
	

	/**
	 * Pull the value. 
	 * 
	 * @return r[0] is the value, r[1] is the type of the value.
	 * @throws NoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	public Object[] pullValue() throws NoExpressionValueException {
		Object[] result = new Object[2];
		exp.pullValue(result);
		return result;
	}
				
	/**
	 * Close out things.
	 * 
	 * @since 1.0.0
	 */
	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();
	}

}
