/*******************************************************************************
 * Copyright (c) 2001, 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
 *******************************************************************************/
package org.eclipse.jem.internal.proxy.vm.remote;
/*


 */


import java.io.*;
import java.lang.reflect.Array;
import java.net.Socket;
import java.net.SocketException;
import java.util.*;

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

public class ConnectionHandler {	
		
	protected Socket socket;
	final protected RemoteVMServerThread server;
	final protected Thread connectionThread;
	protected DataInputStream in;
	protected DataOutputStream out;
	
	// 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
	// in Linux 1.4. So on Linux 1.3 need to put timeouts in on those sockets that can be separately closed while reading/accepting.
	static boolean LINUX_1_3 = "linux".equalsIgnoreCase(System.getProperty("os.name")) && System.getProperty("java.version","").startsWith("1.3");	 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
	
	
	static {
		try{
			Class.forName("java.awt.Dialog");
		}
		catch (ExceptionInInitializerError e){}
		catch (LinkageError e){}
		catch (ClassNotFoundException e) {}
		
		try{
			Class.forName("sun.awt.windows.WToolkit");			
		}
		catch (ExceptionInInitializerError e){}
		catch (LinkageError e){}
		catch (ClassNotFoundException e) {}
		
		try{
			Class.forName("java.awt.Component");
		}
		catch (ExceptionInInitializerError e){}
		catch (LinkageError e){}
		catch (ClassNotFoundException e) {}	
	}
	
	/**
	 * This may be running as a callback, in that case there is no connectionThread.
	 */
	public ConnectionHandler(Socket sc, RemoteVMServerThread svr, Thread connectionThread) {
		socket = sc;
		server = svr;
		this.connectionThread = connectionThread;
		
		Integer bufSize = Integer.getInteger("proxyvm.bufsize"); //$NON-NLS-1$
		if (bufSize == null)
			bufSize = new Integer(5000);
			
		try {
			out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), bufSize.intValue()));
			in = new DataInputStream(new BufferedInputStream(socket.getInputStream(), bufSize.intValue()));
		} catch (IOException e) {
		}
			
	}
	
	/**
	 * Did this construct correctly.
	 * This is needed because an exception could be thrown in the ctor and
	 * that's not a good thing to do.
	 */
	public boolean isConnected() {
		return socket != null;
	}	
	
	/**
	 * Request the thread to close down.
	 */
	public void close() {
		if (socket != null) {
			try {
				Socket s = socket;
				socket = null;
				s.close();
			} catch (Exception e) {
			}
		}
	}
	
	// Map of ID to expression processers that are currently being processed.
	private Map expressionProcessors = new HashMap();
	
	/**
	 * Process and loop until told to stop. A callback_done will stop
	 * the loop and will return a result. Otherwise null is returned.
	 */
	public Object run() throws CommandException {
		Object result = null;		
		boolean shutdown = false;
		boolean closeWhenDone = true;
		Commands.ValueObject valueObject = new Commands.ValueObject();	// Working value object so not continually recreated.
		InvokableValueSender valueSender = new InvokableValueSender();	// Working valuesender so not continually recreated. 
		try {
			boolean doLoop = true;

			/**
			 * Note: In the cases below you will see a lot of finally clauses that null variables out.
			 * This is because this is a long running loop, and variables declared within blocks are not
			 * garbage collected until the method is terminated, so these variables once set would never
			 * be GC'd. The nulling at the end of the case makes sure that any of those objects set are
			 * now available for garbage collection when necessary.
			 */		
			while(doLoop && isConnected()) {
				byte cmd = 0;
				try {
					if (LINUX_1_3)
						socket.setSoTimeout(1000);	// Linux 1.3 bug, see comment on LINUX_1_3
					cmd = in.readByte();
					if (LINUX_1_3 && isConnected())
						socket.setSoTimeout(0);	// Linux 1.3 bug, see comment on LINUX_1_3
				} catch (InterruptedIOException e) {
					continue;	// Timeout, try again
				}
				switch (cmd) {
					case Commands.QUIT_CONNECTION:				
						doLoop = false;	
						break;	// Close this connection
						
					case Commands.TERMINATE_SERVER:
						doLoop = false;		
						shutdown = true;	// Shutdown everything
						break;
						
					case Commands.GET_CLASS:
						String className = in.readUTF();
						Class aClass = null;
						Class superClass = null;
						String superClassName = null;
						boolean added = false;
						try {
							aClass = Class.forName(className);	// Turns out using JNI format for array type will work fine.
								
							added = server.getIdentityID(aClass, valueObject);
							boolean isInterface = aClass.isInterface();
							boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers());
							superClass = aClass.getSuperclass();
							superClassName = (superClass != null) ? superClass.getName() : ""; //$NON-NLS-1$
							out.writeByte(Commands.GET_CLASS_RETURN);
							out.writeInt(valueObject.objectID);
							out.writeBoolean(isInterface);
							out.writeBoolean(isAbstract);
							out.writeUTF(superClassName);
							out.flush();
						} catch (ClassNotFoundException e) {
							valueObject.set();
							Commands.sendErrorCommand(out, Commands.GET_CLASS_NOT_FOUND, valueObject);						
						} catch (ExceptionInInitializerError e) {
							sendException(e.getException(), valueObject, out);								
						} catch (LinkageError e) {
							sendException(e, valueObject, out);								
						} catch (Throwable e) {
							// Something bad, did we add a class? If we did remove it from the table.
							if (added)
								server.removeObject(server.getObject(valueObject.objectID));
							throw e;
						} finally {
							// clear out for GC to work.
							className = null;
							aClass = null;
							superClass = null;
							superClassName = null;
							valueObject.set();
						}
						break;
						
					case Commands.GET_CLASS_FROM_ID:
						int classID = in.readInt();
						try {
							aClass = (Class) server.getObject(classID);
							boolean isInterface = aClass.isInterface();
							boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers());							
							superClass = aClass.getSuperclass();
							superClassName = (superClass != null) ? superClass.getName() : ""; //$NON-NLS-1$
							out.writeByte(Commands.GET_CLASS_ID_RETURN);
							out.writeUTF(aClass.getName());
							out.writeBoolean(isInterface);
							out.writeBoolean(isAbstract);
							out.writeUTF(superClassName);
							out.flush();
						} catch (ClassCastException e) {
							valueObject.set();
							Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
						} finally {	
							// clear out for GC to work.
							aClass = null;
							superClass = null;
							superClassName = null;
							valueObject.set();							
						}
						break;

					case Commands.GET_OBJECT_DATA:
						int objectID = in.readInt();
						Object anObject = null;
						try {
							anObject = server.getObject(objectID);
							valueObject.setObjectID(objectID, server.getIdentityID(anObject.getClass()));
							Commands.writeValue(out, valueObject, true);
						} catch (ClassCastException e) {
							valueObject.set();
							Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
						} finally {
							anObject = null;	// Clear out for GC to work
							valueObject.set();							
						}
						break;												
						
					case Commands.RELEASE_OBJECT:
						int id = in.readInt();
						server.removeObject(server.getObject(id));
						break;						

					case Commands.NEW_INIT_STRING:
						classID = in.readInt();	// ID Of class to do new upon.
						String initString = in.readUTF();	// The init string.
						Object newValue = null;
						Class theClass = null;
						try {
							theClass = (Class) server.getObject(classID);
							if (theClass == null) {
								// The class wasn't found. So imply ClassNotFound exception.
								throw new ClassNotFoundException();
							}
							
							InitializationStringParser parser = null;
							try {
								parser = InitializationStringParser.createParser(initString);
								newValue = parser.evaluate();								
								boolean primitive = parser.isPrimitive();
								// If expected class is Void.TYPE, that means don't test the type of the result
								// to verify if correct type, just return what it really is.
								if (theClass != Void.TYPE && primitive != theClass.isPrimitive()) {
									valueObject.set();
									Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
									continue;	// Goto next command.
								} 
								if (primitive) {
									try {
										// Need to do special tests for compatibility and assignment.
										sendObject(newValue, classID != Commands.VOID_TYPE ? classID : server.getIdentityID(parser.getExpectedType()), valueObject, out, true);	// This will make sure it goes out as the correct primitive type
									} catch (ClassCastException e) {
										// The returned type is not of the correct type for what is expected.
										valueObject.set();
										Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
										continue;	// Goto next command
									}									
								} else {
									if (newValue != null) {
										// Test to see if they are compatible. (Null can be assigned to any object,
										// so that is why it was tested out above).
										// If expected class is Void.TYPE, that means don't test the type of the result
										// to verify if correct type, just return what it really is.
										if (theClass != Void.TYPE && !theClass.isInstance(newValue)) {
											// The returned type is not of the correct type for what is expected.
											valueObject.set();
											Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
											continue;	// Goto next command
										}
									}
									sendObject(newValue, NOT_A_PRIMITIVE, valueObject, out, true);	// Send out as an object.
								}
							} catch (InitializationStringEvaluationException e) {
								if (e instanceof EvaluationException) {
									// Want to return the real exception.
									sendException(e.getOriginalException(), valueObject, out);
								} else {
									// Couldn't be evaluated, return an error for this.
									setExceptionIntoValue(e.getOriginalException(), valueObject);
									Commands.sendErrorCommand(out, Commands.CANNOT_EVALUATE_STRING, valueObject);
								}
							} finally {
								parser = null;	// Clear out for GC to work
							}									
						} catch (Throwable e) {
							sendException(e, valueObject, out);
						} finally {
							// Clear out for GC to work
							initString = null;
							theClass = null;
							newValue = null;
							valueObject.set();							
						}	
						break;						
												
					case Commands.INVOKE:
						Object target = null;
						Object[] parms = null;						
						Class returnType = null;
						java.lang.reflect.Method aMethod = null;						
						try {					
							int methodID = in.readInt();	// ID of method to invoke
							aMethod = (java.lang.reflect.Method) server.getObject(methodID);	// Method to invoke
							Commands.readValue(in, valueObject);
							target = getInvokableObject(valueObject);	
							Commands.readValue(in, valueObject);
							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, 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.
								parms = (Object[]) valueObject.anObject;
							}
							
							if (!aMethod.isAccessible())
								aMethod.setAccessible(true);	// We will allow all to occur. Let access control be handled by IDE and compiler.
							newValue = aMethod.invoke(target, parms);
							returnType = aMethod.getReturnType();
							if (returnType.isPrimitive()) {
								int returnTypeID = server.getIdentityID(returnType);
								// Need to tell sendObject the correct primitive type.
								sendObject(newValue, returnTypeID, valueObject, out, true);
				
							} else {
								sendObject(newValue, NOT_A_PRIMITIVE, valueObject, out, true);	// Just send the object back. sendObject knows how to iterpret the type
							}									
						} catch (CommandException e) {
							throw e;	// Throw it again. These we don't want to come up as an exception proxy. These should end the thread.
						} catch (java.lang.reflect.InvocationTargetException e) {
							// This is a wrappered exception. Return the wrappered one so it looks like
							// it was the real one. (Sometimes the method being invoked is on a java.lang.reflect.Constructor.newInstance,
							// which in turn is an InvocationTargetException, so we will go until we don't have an InvocationTargetException.
							Throwable t = e;
							do {
								t = ((java.lang.reflect.InvocationTargetException) t).getTargetException();
							} while (t instanceof java.lang.reflect.InvocationTargetException);
							sendException(t, valueObject, out);
						} catch (Throwable e) {
							sendException(e, valueObject, out);	// Turn it into a exception proxy on the client.
						} finally {
							// Clear out for GC to work
							valueObject.set();
							parms = null;
							target = null;
							aMethod = null;
							returnType = null;
							newValue = null;
							valueSender.clear();
						}					
						break;
						
					case Commands.INVOKE_WITH_METHOD_PASSED:
						aClass = null;
						String methodName = null;
						Class[] parmTypes = null;
						target = null;
						parms = null;						
						returnType = null;
						aMethod = null;						
						
						try {
							Commands.readValue(in, valueObject);
							aClass = (Class) getInvokableObject(valueObject); // The class that has the method.
							methodName = in.readUTF();
							Commands.readValue(in, valueObject);
							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, false);
								parmTypes = (Class[]) valueSender.getArray();
							} else {
								// It null, so it should be an null. If not, then this is an error.
								parmTypes = null;
							}
							aMethod = aClass.getMethod(methodName, parmTypes);

							// Now we get the info for the invocation of the method and execute it.
							Commands.readValue(in, valueObject);
							target = getInvokableObject(valueObject);	
							Commands.readValue(in, valueObject);
							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, 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.
								parms = (Object[]) valueObject.anObject;
							}
							
							if (!aMethod.isAccessible())
								aMethod.setAccessible(true);	// We will allow all to occur. Let access control be handled by IDE and compiler.
							newValue = aMethod.invoke(target, parms);
							returnType = aMethod.getReturnType();
							if (returnType.isPrimitive()) {
								int returnTypeID = server.getIdentityID(returnType);
								// Need to tell sendObject the correct primitive type.
								sendObject(newValue, returnTypeID, valueObject, out, true);
				
							} else {
								sendObject(newValue, NOT_A_PRIMITIVE, valueObject, out, true);	// Just send the object back. sendObject knows how to iterpret the type
							}									
						} catch (CommandException e) {
							throw e;	// Throw it again. These we don't want to come up as an exception proxy. These should end the thread.
						} catch (java.lang.reflect.InvocationTargetException e) {
							// This is a wrappered exception. Return the wrappered one so it looks like
							// it was the real one. (Sometimes the method being invoked is on a java.lang.reflect.Constructor.newInstance,
							// which in turn is an InvocationTargetException, so we will go until we don't have an InvocationTargetException.
							Throwable t = e;
							do {
								t = ((java.lang.reflect.InvocationTargetException) t).getTargetException();
							} while (t instanceof java.lang.reflect.InvocationTargetException);
							sendException(t, valueObject, out);

						} catch (Throwable e) {
								sendException(e, valueObject, out);	// Turn it into a exception proxy on the client.
						} finally {
							aClass = null;
							methodName = null;
							parmTypes = null;
							// Clear out for GC to work
							valueObject.set();
							parms = null;
							target = null;
							aMethod = null;
							returnType = null;
							newValue = null;
							valueSender.clear();							
						}
						break;
						
					case Commands.GET_ARRAY_CONTENTS:
						try {
							target = server.getObject(in.readInt());	// Array to get the ids for.
							valueObject.setArrayIDS(new ArrayContentsRetriever(target), Array.getLength(target), Commands.OBJECT_CLASS);
							Commands.writeValue(out, valueObject, true);	// Write it back as a value command.
						} catch (CommandException e) {
							throw e;	// Throw it again. These we don't want to come up as an exception proxy. These should end the thread.
						} catch (Throwable e) {
							sendException(e, valueObject, out);	// Turn it into a exception proxy on the client.
						} finally {
							target = null;
							valueObject.set();
						}
						break;
						
					case Commands.CALLBACK_DONE:
						try {
							if (connectionThread != null) {
								valueObject.set();
								Commands.sendErrorCommand(out, Commands.UNKNOWN_COMMAND_SENT, valueObject);
							} else {
								try {
									Commands.readBackValue(in, valueObject, Commands.NO_TYPE_CHECK);
									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, false);
										result = valueSender.getArray();
									} else {
										result = getInvokableObject(valueObject);
									}
									doLoop = false; // We need to terminate and return result
									closeWhenDone = false; // Don't close, we will continue.
								} catch (CommandErrorException e) {
									// There was an command error on the other side. This means 
									// connection still good, but don't continue the callback processing.
									doLoop = false; // We need to terminate and return result
									closeWhenDone = false; // Don't close, we will continue.
									throw e;	// Let it go on out.
								}
							}
						} finally {
							valueObject.set();
							valueSender.clear();
						}
						break;
						
					case Commands.ERROR:
						try {
							// Got an error command. Don't know what to do but read the
							// value and simply print it out.
							Commands.readValue(in, valueObject);
							result = getInvokableObject(valueObject);
							System.out.println("Error sent to server: Result=" + result); //$NON-NLS-1$
						} finally {
							valueObject.set();
						}
						break;
					
					case Commands.EXPRESSION_TREE_COMMAND:
						try {
							processExpressionCommand(valueObject, valueSender);
						} finally {
							valueObject.set();
							valueSender.clear();
						}
						break;
						
					default:
						// Unknown command. We don't know how long it is, so we need to shut the connection down.
						System.err.println("Error: Invalid cmd send to server: Cmd=" + cmd); //$NON-NLS-1$
						doLoop = false;
						closeWhenDone = true;
						break;
				}
			}
		} catch (EOFException e) {
			// This is ok. It means that the connection on the other side was terminated.
			// So just accept this and go down.
		} catch (CommandException e) {
			throw e;
		} catch (SocketException e) {
			if (socket != null)
				throw new UnexpectedExceptionCommandException(false, e);	// socket null means a valid close request
		} catch (Throwable e) {
			e.printStackTrace();
		} finally {
			if (closeWhenDone) {
				try {
					for (Iterator itr = expressionProcessors.values().iterator(); itr.hasNext();) {
						ExpressionProcesserController exp = (ExpressionProcesserController) itr.next();
						exp.close();
					}
				} finally {
					expressionProcessors.clear();
				}

				if (in != null)
					try {
						in.close();
					} catch (Exception e) {
					}
				in = null;
				if (out != null)
					try {
						out.close();
					} catch (Exception e) {
					}
				out = null;
				close();
			}
		}
		
		if (closeWhenDone && connectionThread != null)
			server.removeConnectionThread(connectionThread);
		if (shutdown)
			server.requestShutdown();
			
		return result;
	}
	
	// A retriever is what handles the array get contents.
	private class ArrayContentsRetriever implements Commands.ValueRetrieve {
		int index=0;
		Object array;
		int componentType;
		Commands.ValueObject worker = new Commands.ValueObject();
		
		
		public ArrayContentsRetriever(Object anArray) {
			array = anArray;
			if (anArray.getClass().getComponentType().isPrimitive()) {
				componentType = server.getIdentityID(anArray.getClass().getComponentType());
			} else
				componentType = NOT_A_PRIMITIVE;
		}
		
		public Commands.ValueObject nextValue() {
			fillInValue(Array.get(array, index++), componentType, worker);
			return worker;
		}
	};

	
	private void processExpressionCommand(Commands.ValueObject valueObject, InvokableValueSender valueSender) throws IOException, CommandException {
		Integer expressionID = new Integer(in.readInt());
		byte cmdType = in.readByte();
		ExpressionProcesserController exp = null;
		switch (cmdType) {
			case ExpressionCommands.START_EXPRESSION_TREE_PROCESSING:
				byte trace = in.readByte();
				if (trace == ExpressionCommands.TRACE_DEFAULT)
					exp = new ExpressionProcesserController(server, this);
				else
					exp = new ExpressionProcesserController(server, this, trace == ExpressionCommands.TRACE_ON);
				expressionProcessors.put(expressionID, exp);
				break;
			case ExpressionCommands.TRANSFER_EXPRESSION_REQUEST:
				exp = (ExpressionProcesserController) expressionProcessors.remove(expressionID); 
				sendObject(exp, NOT_A_PRIMITIVE, valueObject, out, true);
				break;
			case ExpressionCommands.RESUME_EXPRESSION_REQUEST:
				Commands.readValue(in, valueObject);
				exp = (ExpressionProcesserController) getInvokableObject(valueObject); 
				expressionProcessors.put(expressionID, exp);
				break;
			case ExpressionCommands.PUSH_EXPRESSION:
				exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
				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.
					Commands.writeValue(out, valueObject, true, true);
				} else {
					processExpressionError(exp, valueObject);
				}
				break;
			case ExpressionCommands.PULL_VALUE_REQUEST:
				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()) {
					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(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);
				exp.close();
				break;
		}
	}

	/*
	 * @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(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;
			}
		};

		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;
protected static final int SEND_AS_IS = -2;	// This means sends as an object not as an id.
	
public static final int CLASS_ADDED = 1;
public static final int OBJECT_ADDED = 2;
public int fillInValue(Object object, int primitiveTypeID, Commands.ValueObject valueObject) {
	int added = 0;
	if (object == null) {
		valueObject.set();
	} else {
		int classID = 0;
		if (primitiveTypeID != NOT_A_PRIMITIVE && primitiveTypeID != SEND_AS_IS) {
			classID = primitiveTypeID;	// The object is really supposed to be a primitive of this type
			switch (classID) {
				case Commands.BOOLEAN_TYPE:
					valueObject.set(((Boolean) object).booleanValue());
					break;
				case Commands.INTEGER_TYPE:
					if (object instanceof Character)
						valueObject.set((int) ((Character) object).charValue());	// Because char can be widened to an int
					else
						valueObject.set(((Number) object).intValue());					
					break;
				case Commands.BYTE_TYPE:
					valueObject.set(((Number) object).byteValue());
					break;
				case Commands.CHARACTER_TYPE:
					valueObject.set(((Character) object).charValue());
					break;
				case Commands.DOUBLE_TYPE:
					if (object instanceof Character)
						valueObject.set((double) ((Character) object).charValue());	// Because char can be widened to a double
					else
						valueObject.set(((Number) object).doubleValue());					
					break;
				case Commands.FLOAT_TYPE:
					if (object instanceof Character)
						valueObject.set((float) ((Character) object).charValue());	// Because char can be widened to a float
					else
						valueObject.set(((Number) object).floatValue());					
					break;
				case Commands.SHORT_TYPE:
					valueObject.set(((Number) object).shortValue());
					break;
				case Commands.LONG_TYPE:
					if (object instanceof Character)
						valueObject.set((long) ((Character) object).charValue());	// Because char can be widened to a long
					else
						valueObject.set(((Number) object).longValue());					
					break;
			}
		} else {
			// It's not a primitive.
			boolean addObject = false, addClass = false;			
			Class objClass = object.getClass();
			classID = server.getIdentityID(objClass);
			if (classID == RemoteVMServerThread.ID_NOT_FOUND) {
				Commands.ValueObject classValue = new Commands.ValueObject();
				addClass = server.getIdentityID(objClass, classValue);
				if (addClass)
					added |= CLASS_ADDED;
				classID = classValue.objectID;
			}
		
			switch (classID) {
				case Commands.BYTE_CLASS:
					valueObject.set((Byte) object);
					break;
				case Commands.CHARACTER_CLASS:
					valueObject.set((Character) object);
					break;
				case Commands.DOUBLE_CLASS:
					valueObject.set((Double) object);
					break;
				case Commands.FLOAT_CLASS:
					valueObject.set((Float) object);
					break;
				case Commands.INTEGER_CLASS:
					valueObject.set((Integer) object);
					break;
				case Commands.LONG_CLASS:
					valueObject.set((Long) object);
					break;
				case Commands.SHORT_CLASS:
					valueObject.set((Short) object);
					break;
				case Commands.BOOLEAN_CLASS:
					valueObject.set((Boolean) object);
					break;
				case Commands.STRING_CLASS:
					valueObject.set((String) object);
					break;
				case Commands.BIG_DECIMAL_CLASS:
					valueObject.set(object, Commands.BIG_DECIMAL_CLASS);
					break;
				case Commands.BIG_INTEGER_CLASS:
					valueObject.set(object, Commands.BIG_INTEGER_CLASS);
					break;
				default:
					if (primitiveTypeID != SEND_AS_IS) {
						addObject = server.getIdentityID(object, valueObject);
						if (addObject) {
							added |= OBJECT_ADDED;			
							valueObject.setObjectID(valueObject.objectID, classID);
						} else
							valueObject.setObjectID(valueObject.objectID);
					} else
						valueObject.set(object, classID);
					break;
			}
		}
	}
	
	return added;
}

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, flush);	// Write it back as a value command.
		sent = true;
	} finally {
		if (!sent) {
			// Ending due to some problem, so clean up any added objects from the id table.
			if ((added & OBJECT_ADDED) != 0)
				server.removeObject(valueObject.objectID);
			if ((added & CLASS_ADDED) != 0)
				server.removeObject(valueObject.classID);
		}
	}
}
		
	
	public void sendException(Throwable e, Commands.ValueObject value, DataOutputStream out) throws CommandException {
		// Exception ocurred, return a value command with the exception within it.
		setExceptionIntoValue(e, value);
		Commands.sendErrorCommand(out, Commands.THROWABLE_SENT, value);		
	}

	public void setExceptionIntoValue(Throwable e, Commands.ValueObject value) {		
		server.getIdentityID(e, value);	// It should always create it so we don't need to know.
		int eID = value.objectID;
		Class eClass = e.getClass();							
		server.getIdentityID(eClass, value);
		int eClassID = value.objectID;
		value.setException(eID, eClassID);
	}
	
	/**
	 * From the valueObject, get an Object that is invokable (i.e. can be the target of an invoke, or one of its parms).
	 * If it is an array type, the a ValueSender is returned. The invoker needs to then cast this
	 * to a ValueSender and call the readArray routine.
	 */
	public Object getInvokableObject(final Commands.ValueObject value) {
		switch (value.type) {
			case Commands.NEW_OBJECT_ID:
			case Commands.OBJECT_ID:
				// These need to have access to the server to get the real object
				return server.getObject(value.objectID);						
			default:
				// These have all the info needed within the value object itself, so ask it.
				return value.getAsObject();
		}
	}
	
	// Helper class for getting an array.
	private class InvokableValueSender implements Commands.ValueSender {
		int index = 0;
		Object array;

		public InvokableValueSender() {
		}
				
		public InvokableValueSender(Commands.ValueObject arrayHeader) {
			initialize(arrayHeader);
		}
		
		public void initialize(Commands.ValueObject arrayHeader) {
			index = 0;
			Class arrayType = (Class) server.getObject(arrayHeader.classID);
			array = java.lang.reflect.Array.newInstance(arrayType, arrayHeader.anInt);
		}
		
		public void clear() {
			array = null;
			index = 0;
		}
		
		public Object getArray() {
			return array;
		}
					
		// A new value is being sent to the array
		public void sendValue(Commands.ValueObject value) {
			java.lang.reflect.Array.set(array, index++, getInvokableObject(value));	// add it to the array
		}
					
		// The next entry is an array too!
		public Commands.ValueSender nestedArray(Commands.ValueObject arrayHeader) {
			InvokableValueSender sender = new InvokableValueSender(arrayHeader);
			// Take the newly created array and put it into the current array.
			java.lang.reflect.Array.set(array, index++, sender.getArray());
			return sender;
		}
	}

}


