/*******************************************************************************
 * 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.common.remote;
/*


 */

import java.io.*;

import org.eclipse.jem.internal.proxy.common.CommandException;
/**
 * The commands that can be passed back and forth between
 * client and server. And other constants.
 *
 * - Contains helper methods for reading/writing commands.
 */
public class Commands {
	// The commands will be written in writeByte format .
	public final static byte
		GET_CLASS = 1,		// Get the class object,
		VALUE = 2,		// Returning a value
		QUIT_CONNECTION = 4,	// Close this connection
		TERMINATE_SERVER = 5,	// Terminate the entire server.
		ERROR = 6,		// Returning an error
		RELEASE_OBJECT = 7,	// An object is no longer needed on the client side, so
					// it can be removed from the server id table and released.
		GET_CLASS_RETURN = 8,	// The return command from GET_CLASS
		// Obsolete, not used anymore GET_METHOD = 9,	// Return the id for a method
		// Obsolete, not used anymore GET_CTOR = 10,		// Return the id for a constructor		
		NEW_INIT_STRING = 11,	// Create a new bean using the init string
		GET_CLASS_FROM_ID = 12,	// We have an ID, return the class info for this id.
		GET_CLASS_ID_RETURN = 13,	// The return command from GET_CLASS_FROM_ID
		GET_OBJECT_DATA = 14,	// We have an ID, but we don't have the info, return it. This is a 
					// corrective command only. This would happen if for some strange
					// reason the proxy has been removed but has not been released. This
					// really shouldn't happen except as a possible race condition between
					// GC and returning id from the server.
		INVOKE = 15,		// Invoke a method.
	
	
		// These commands are to the Master Server thread in the IDE.
		ALIVE = 16,	// Are you alive?
		REMOTE_STARTED = 17,	// Remote VM has started.
		ATTACH_CALLBACK = 18,	// Attach to a callback thread on the IDE side. The remote vm will use its socket as the callback socket.
								// it will return boolean <code>true</code> if attach worked or <code>false</code> if it failed.

		// These are more regular commands. They were historically added after the master server thread commands, so
		// they are shown here after them and with numbers greater than them.
		EXPRESSION_TREE_COMMAND = 19,	// An expression tree subcommand has come in.
		INVOKE_WITH_METHOD_PASSED = 20,	// Invoke where the description of the method is passed in with the command.
		GET_ARRAY_CONTENTS = 21;	// Get the first dimension contents as an array of ids and send them back.
	
		
	// Callback commands
	public final static byte
		CALLBACK = (byte) 255,	// A callback has come in.
		CALLBACK_DONE = (byte) 254,	// A callback done command, sent to the remote vm upon callback completion.
		CALLBACK_STREAM = (byte) 253,	// A callback for a byte stream has come in.
								// This is a special callback. When this comes in a special
								// input stream will be created that will take over control of
								// the connection until the stream is terminated on the remote
								// side. At this time the connection will be returned.
		CALLBACK_STREAM_TERMINATE = (byte) 252;	// A callback stream is asked to terminate early.
		
	// The error values from the command on the server.
	public final static int
		NO_ERROR = 0,				// No error status.
		UNKNOWN_COMMAND_SENT = 1,	// An unknown command was sent to the server. Value is void.
		GET_CLASS_NOT_FOUND = 2,	// The class was not found in GetClass. Value is void.
		CANNOT_EVALUATE_STRING = 3,	// Evaluator couldn't evaluate the init string. Too complicated. Value is a throwable of the wrappered Init string error.
		CLASS_CAST_EXCEPTION = 4,	// The result is not assignable to the expected type. Value is void.
		GET_METHOD_NOT_FOUND = 5,	// Method requested wasn't found. Value is void.
		THROWABLE_SENT = 6,			// A Throwable is being sent back as the error, not as just data for the error. Value is the Throwable.
		CALLBACK_RUNTIME_EXCEPTION = 7,	// A runtime exception occurred during a callback. The data is the message.
		CALLBACK_NOT_REGISTERED = 8,
		MAX_ERROR_CODE = CALLBACK_NOT_REGISTERED;	// This is just the max code. Not actually sent. Used as a flag.
		
	// Predefined standard id's for standard classes/objects. Both sides will assume these id's have been assigned
	// to these classes/types/objects
	public final static int
		NOT_AN_ID = -1,	// This value means it is not an id. It is never a valid id.
		VOID_TYPE = 0,
		BOOLEAN_TYPE = 1,
		BOOLEAN_CLASS = 2,
		INTEGER_TYPE = 3,
		INTEGER_CLASS = 4,
		BYTE_TYPE = 5,
		BYTE_CLASS = 6,
		CHARACTER_TYPE = 7,
		CHARACTER_CLASS = 8,
		DOUBLE_TYPE = 9,
		DOUBLE_CLASS = 10,
		FLOAT_TYPE = 11,
		FLOAT_CLASS = 12,
		SHORT_TYPE = 13,
		SHORT_CLASS = 14,
		LONG_TYPE = 15,
		LONG_CLASS = 16,
		STRING_CLASS = 17,
		BIG_DECIMAL_CLASS = 18,
		BIG_INTEGER_CLASS = 19,
		NUMBER_CLASS = 20,
		THROWABLE_CLASS = 21,
		CLASS_CLASS = 22,
		OBJECT_CLASS = 23,
		ACCESSIBLEOBJECT_CLASS = 24,
		METHOD_CLASS = 25,
		FIELD_CLASS = 26,
		CONSTRUCTOR_CLASS = 27,
		GET_METHOD_ID = 28,	// Class.getMethod(...) predefined id.
		IVMSERVER_CLASS = 29,	// IVMServer.class
		ICALLBACK_CLASS = 30,	// ICallback.class
		REMOTESERVER_ID = 31,	// id of RemoteVMServerThread instance.
		REMOTEVMSERVER_CLASS = 32,	// RemoteVMServer.class
		INITIALIZECALLBACK_METHOD_ID = 33,	// ICallback.initializeCallback method.
		THREAD_CLASS = 34,
		EXPRESSIONPROCESSERCONTROLLER_CLASS = 35,
		FIRST_FREE_ID = 36;
				
	// The type flags written in writeByte format
	public final static byte
		VOID = VOID_TYPE,	// null - nothing follows
		BYTE = BYTE_TYPE,	// byte - writeByte
		L_BYTE = BYTE_CLASS,	// java.lang.Byte - writeByte
		CHAR = CHARACTER_TYPE,	// char - writeChar
		L_CHAR = CHARACTER_CLASS,	// java.lang.Character - writeChar
		DOUBLE = DOUBLE_TYPE,	// double - writeDouble
		L_DOUBLE = DOUBLE_CLASS,	// java.lang.Double - writeDouble
		FLOAT = FLOAT_TYPE,	// float - writeFloat
		L_FLOAT = FLOAT_CLASS,	// java.lang.Float - writeFloat
		INT = INTEGER_TYPE,	// int - writeInt
		L_INT = INTEGER_CLASS,	// java.lang.Integer - writeInt
		LONG = LONG_TYPE,	// long - writeLong
		L_LONG = LONG_CLASS,	// java.lang.Long - writeLong
		SHORT = SHORT_TYPE,	// short - writeShort
		L_SHORT = SHORT_CLASS,	// java.lang.Short - writeShort
		BOOL = BOOLEAN_TYPE,	// boolean - writeBoolean
		L_BOOL = BOOLEAN_CLASS,	// java.lang.Boolean - writeBoolean
		STRING = STRING_CLASS,	// java.lang.String - writeUTF
		OBJECT = OBJECT_CLASS,	// Object - special, see below (Object can be used to return an array (except if the array contains any object_ids, that has a special type)
		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
						// 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.
				
		
		
	// Unless specified below, the commands are one byte long.
	// Also, unless specified below, the commands do not return a confirmation response.
	//
	// NOTE: VERY IMPORTANT, after every command, flush() should be used so that the
	// the data is immediately sent to the server. 	
	//
	// n means int (e.g. 1)
	// nb means byte (e.g. 1b)
	// 'x' means Unicode char (i.e. writeChar())
	// "xxx" means UTF8 string (i.e. writeUTF)
	// bool means a one byte boolean value
	//
	// The commas aren't actually written, they are used as separaters in the comments below
	//
	// GET_CLASS: 1b, "classname"
	//		Will return on the output stream GET_CLASS_RETURN command:
	//		8b, n1, bool1, bool2, "superclassname"
	//		The "n1" is the class id.
	//		The bool1 is whether this class is an interface (true if it is).
	//		The bool2 is whether this class is abstract (true if it is).	
	//		The "superclassname" is the class name of the super class (0 length if no superclass)
	//		If the class is not found, then it will return an error with a value for the error.
	//
	// GET_CLASS_FROM_ID: 12b, n
	//		Where "n" is the class id.
	//		Will return on the output stream GET_CLASS_ID_RETURN command:	
	//		13b, "classname", bool1, bool2, "superclassname"
	//		The bool1 is whether this class is an interface (true if it is).
	//		The bool2 is whether this class is abstract (true if it is).	
	//
	// VALUE: 2b, tb, value
	//		Where tb is the type in byte, and value is the appropriate value shown in
	//		table above.
	//		OBJECT_ID: 50b, n
	//			Where "n" is the object id.
	//		NEW_OBJECT_ID: 51b, n1, n2
	//			Where "n1" is class ObjectID of the object that the object_id ("n2") is made of.
	//		OBJECT: 19b, n, writeObject
	//			Where "n" is the classObjectID of the class of the type of the object.
	//			NOTE: Object should be used only very rarely. Identity is lost, i.e.
	//			a copy is made each time and it can't be referenced back on the remote
	//			VM.
	//		ARRAY_IDS: 52b, id, n, [tb, value, ...]
	//			This is a very special array. It contains at least one ID. Therefor all of the 
	//			First level entries are value objects. 
	//			"id" is the id of the component type of the array(e.g. id for Object, or if multi-dimensional String[] (this will produce String[][]).
	//			"n" is the number of entries in the array. Followed by the values, one of the
	//			values could be an ARRAY_IDS too. The reading/writing of these are special because
	//			there is a callback mechanism to process the individual entries. This is so that
	//			temp arrays of ValueObjects won't need to be created to handle this, so it can
	//			go directly from the array to/from the stream.
	//		
	// RELEASE_OBJECT: 7b, n
	//		Where the n is the object id to release. There is no confirmation to read back.
	//
	// ERROR: 6b, n, tb, ...
	//      n is the error code for this error.
	//		tb is a type flag, followed by the value. The value is dependent upon
	//		the command that this is error is from. If a THROW, then the THROW is ALWAYS a new
	//		ID, it can never be an existing id.
	//      
	//
	// TO_BEAN_STRING: 9b, n
	//		Where n is the object id to produce the bean string for.
	//		It will return a VALUE command where the type is String.
	//
	// NEW_INSTANCE: 10b, n
	//		Where n is the class object id of the class to create a new instance of using the default ctor.
	//		It will return either a VALUE command containing the new value (of type OBJECT_ID/NEW_OBJECT_ID if not
	//		one of the constant types with the true classID in it) or an ERROR command. (The ERROR could
	//		be a THROW type). If the object created is not assignable to the type passed in, then
	//		an ERROR is returned with CLASS_CAST_EXCEPTION flag.
	//
	// NEW_INIT_STRING: 11b, n, "initstring"
	//		Where n is the class object id of the class this initstring is supposed to create for.
	//		It will return either a VALUE command containing the new value (of type OBJECT_ID/NEW_OBJECT_ID if not
	//		one of the constant types with the true classID in it) or an ERROR command. (The ERROR could
	//		be a THROW type). The error could also be CANNOT_EVALUATE_STRING. This means that the string was too
	//		complicated for the evaluator and needs to be compiled and tried again. (TBD)
 	//		If the object created is not assignable to the type passed in, then
	//		an ERROR is returned with CLASS_CAST_EXCEPTION flag.
	//
	// GET_OBJECT_DATA: 14b, n
	//		Where n is the id of the object being requested. It will return a NEW_OBJECT_ID value with the info.
	//
	// GET_METHOD: 9b, classId, "methodName", n1, [n2]...
	//		Where classID is the id of the class the method should be found in.
	//		Where n1 is the number of parm types following, and n2 is replicated that many times,
	//		each entry is the id of class for the parm type. (0 is valid which means there are no parms).
	//		The return will be a VALUE command containing the OBJECT_ID of the method.
	//
	// GET_CTOR: 10b, classId, n1, [n2]...
	//		Where classID is the id of the class the method should be found in.
	//		Where n1 is the number of parm types following, and n2 is replicated that many times,
	//		each entry is the id of class for the parm type. (0 is valid which means there are no parms).
	//		The return will be a VALUE command containing the OBJECT_ID of the method.
	//	
	// GET_FIELD:
	//
	// GET_CTOR:
	//
	// INVOKE: 15b, n1, tb, value1, value2
	//		Where "n1" is the id of the method to invoke.
	//		tb, value1 is the value of who to invoke against (it is usually an OBJECT_ID for tb)
	//      value2 is an ARRAY_IDS type or an OBJECT array of values if all constants.
	//		What is returned is a VALUE command containing the return value, (the value will be null (VOID) if
	//		there is no return type (i.e. the method was void). So null can be returned either if the value
	//		was null or if the return type was void.
	//
	// EXPRESSION_TREE_COMMAND: 20b, n, b
	//		Receiving an expression tree subcommand. Where "n" is a unique id number of the
	//		expression being processed. Where "b" is byte code, defined in ExpressionCommands, that
	//		determines the type of expression tree commands.
	//		There can be more data following, but it is read by the 
	//		ExpressionProcesserController, not by the connection. See the controller for the subcommands.
	//
	//		The id number is the id of the expression being processed. This allows more than one expression
	//		to be processed at a time from this connection.
	//
	//		@see ExpressionCommands
	//		@see ExpressionProcessController
	//
	// INVOKE_WITH_METHOD_PASSED: 20b,  classId, "methodName", value0, tb, value1, value2
	//		Where classID is the id of the class the method should be found in.
	//		value0 is an ARRAY_IDS type for the type of the parms, or null type for no parms.  
	//		tb, value1 is the value of who to invoke against (it is usually an OBJECT_ID for tb)
	//      value2 is an ARRAY_IDS type or an OBJECT array of values if all constants.
	//		What is returned is a VALUE command containing the return value, (the value will be null (VOID) if
	//		there is no return type (i.e. the method was void). So null can be returned either if the value
	//		was null or if the return type was void.
	//
	// GET_ARRAY_CONTENTS: 21b, arrayId
	//		Where arrayID is the id of the array to get the contents of. What is returned is a value command
	//		containing an array of ids of the first dimension contents.
	//
	// Callback commands:
	//
	// CALLBACK: 255b, n1, n2, value1
	//      Where
	//        "n1" is the id of callback type (these are registered with the callback server)
	//        "n2" is the msgId for the callback (These are entirely callback dependent and are maintained by the callback developer)
	//        value1 is an ARRAY_IDS type or an OBJECT array of values if all constants. These are
	//          parms to send to the callback msg.
	//      It will return a CALLBACK_DONE.
	//
	// CALLBACK_DONE: 254b, value command.
	//		What comes back is a value command (i.e. Commands.VALUE followed by value). This allows
	//		ERRORS to be sent back too.
	//
	// CALLBACK_STREAM: 253b, n1, n2
	//      Where
	//        "n1" is the id of callback type (these are registered with the callback server)
	//        "n2" is the msgId for the callback (These are entirely callback dependent and are maintained by the callback developer)
	//		It will create a CallbackInputStream and notify the registered callback that the
	//		stream is available. It will send a callback_done when it has accepted the request
	//		but before it notifies the registered callback with the stream. This lets the remote
	//		vm know that it can start sending data.
	

	// To the MasterServer socket:
	// The MasterServer socket will expect input in DataInputStream format, and DataOutputStream for return.
	// The socket will be short-lived. It will be for one transaction only. Each request will return a new socket.
	//
	// ALIVE: 16b, n1
	//      Where
	//        "n1" is the id of the registry this is asking to test for aliveness
	//      Will return bool, where false if registry is not alive, true if it is alive.
	// REMOTE_STARTED: 17b, n1, n2
	//      Where
	//        "n1" is the id of the registry this is telling that it is started
	//        "n2" is the serversocket port number of the server socket in this remote vm.
	//      Will return bool, where false if registry is not alive, true if it is alive. If false, then terminate the server because nothing to talk to.
	// GET_CALLBACK_PORT: 18b, n1
	//      Where
	//        "n1" is the id of the registry this is asking for the callback server port.
	//      Will return int, where the value is the callback server port number. -1 if there is no callback server port.		
	
	/**
	 * This class is the return from a read value. It contains the
	 * type of the value and the value itself. Since primitives can be
	 * returned also, there is a slot for each one and the type should
	 * be checked to see which one is set.
	 *
	 * Also, if the type is OBJECT, then the anObject has the object in it, AND
	 * the classID field has the object_id of the class of the object so that the
	 * appropriate beantypeproxy can be found to use that object. Also, only
	 * IREMConstantBeanTypeProxies can be of type OBJECT. That is because those
	 * are the only ones that know how to take the value object and interpret it.
	 *
	 * If the type is OBJECT_ID or NEW_OBJECT_ID, then the objectID field will be set with
	 * the id.
	 * If the type is NEW_OBJECT_ID, then the classID field will
	 * have the class objectID of the class of the object for which object_id proxies.
	 *
	 * THROW is treated like NEW_OBJECT_ID in what fields are set since it is a new object.
	 *
	 * Note: so as not to create unnecessary objects, if the Object type of the primitive is being
	 * 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
		public byte aByte;
		public char aChar;
		public double aDouble;
		public float aFloat;
		public int anInt;
		public short aShort;
		public long aLong;
		public boolean aBool;
		public int objectID;	// The object id for either OBJECT_ID or NEW_OBJECT_ID.
		public int classID;		// The class object id of the value in Object if the type is Object
		public Object anObject;	// String also will be in here
		
		public ValueObject() {
			type = VOID;
		}
		
		public Object clone() {
			try {
				return super.clone();
			} catch (CloneNotSupportedException e) {
				return null;
			}
		}
		
		/**
		 * Return whether the value stored here is a primitive.
		 * 
		 * @return <code>true</code> if value is a primitive type.
		 * 
		 * @since 1.0.0
		 */
		public boolean isPrimitive() {
			return getPrimitiveType().isPrimitive();
		}
		
		/**
		 * Get the primitive type of the value. 
		 * @return The primitive type, or if not primitive, it returns simply <code>Object.class</code>.
		 * 
		 * @since 1.0.0
		 */
		public Class getPrimitiveType() {
			switch (type) {
				case BYTE:
					return Byte.TYPE;
				case CHAR:
					return Character.TYPE;
				case DOUBLE:
					return Double.TYPE;
				case FLOAT:
					return Float.TYPE;
				case INT:
					return Integer.TYPE;
				case SHORT:
					return Short.TYPE;
				case LONG:
					return Long.TYPE;
				case BOOL:
					return Boolean.TYPE;
				default:
					return Object.class;
			}	
			
		}
		
		/**
		 * 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() {
			switch (type) {
				case VOID:
					return null;
				case BYTE:
				case L_BYTE:
					return new Byte(aByte);
				case CHAR:
				case L_CHAR:
					return new Character(aChar);
				case DOUBLE:
				case L_DOUBLE:
					return new Double(aDouble);
				case FLOAT:
				case L_FLOAT:
					return new Float(aFloat);
				case INT:
				case L_INT:
					return new Integer(anInt);
				case SHORT:
				case L_SHORT:
					return new Short(aShort);
				case LONG:
				case L_LONG:
					return new Long(aLong);
				case BOOL:
				case L_BOOL:
					return aBool ? Boolean.TRUE : Boolean.FALSE;
				case STRING:
					return anObject;
				case OBJECT:
					return anObject;
				
				default: 
					return null;	// Can't handle others. Those need to be checked before calling.
			}
		}
		
		/**
		 * Special setter to set the value depending upon the type.
		 */
		public void setAsObject(Object value, int valueClassID) {
			switch (valueClassID) {
				case VOID:
					set();
					break;
				case BYTE_CLASS:
					set((Byte) value);
					break;
				case CHARACTER_CLASS:
					set((Character) value);
					break;
				case DOUBLE_CLASS:
					set((Double) value);
					break;
				case FLOAT_CLASS:
					set((Float) value);
					break;
				case INTEGER_CLASS:
					set((Integer) value);
					break;
				case SHORT_CLASS:
					set((Short) value);
					break;
				case LONG_CLASS:
					set((Long) value);
					break;
				case BOOLEAN_CLASS:
					set((Boolean) value);
					break;
				case STRING_CLASS:
					set((String) value);
					break;
				default:
					set(value, valueClassID);
					break;
			}
		}
			
		public void set() {
			type = VOID;
			anObject = null;
		}
		
		public void setFlag(int flag) {
			type = FLAG;
			anInt = flag;
		}
		
		public void set(byte value) {
			type = BYTE;
			aByte = value;
			anObject = null;
		}
		public void set(Byte value) {
			if (value != null) {
				type = L_BYTE;
				aByte = value.byteValue();
				anObject = null;
			} else
				set();
		}
		public void set(char value) {
			type = CHAR;
			aChar = value;
			anObject = null;
		}
		public void set(Character value) {
			if (value != null) {
				type = L_CHAR;
				aChar = value.charValue();
				anObject = null;
			} else
				set();
		}
		public void set(double value) {
			type = DOUBLE;
			aDouble = value;
			anObject = null;
		}
		public void set(Double value) {
			if (value != null) {
				type = L_DOUBLE;
				aDouble = value.doubleValue();
				anObject = null;
			} else
				set();
		}
		public void set(float value) {
			type = FLOAT;
			aFloat = value;
			anObject = null;
		}
		public void set(Float value) {
			if (value != null) {
				type = L_FLOAT;
				aFloat = value.floatValue();
				anObject = null;
			} else
				set();
		}
		public void set(int value) {
			type = INT;
			anInt = value;
			anObject = null;
		}
		public void set(Integer value) {
			if (value != null) {
				type = L_INT;
				anInt = value.intValue();
				anObject = null;
			} else
				set();
		}
		public void set(short value) {
			type = SHORT;
			aShort = value;
			anObject = null;
		}
		public void set(Short value) {
			if (value != null) {
				type = L_SHORT;
				aShort = value.shortValue();
				anObject = null;
			} else
				set();
		}
		public void set(long value) {
			type = LONG;
			aLong = value;
			anObject = null;
		}
		public void set(Long value) {
			type = L_LONG;
			aLong = value.longValue();
			anObject = null;
		}
		public void set(boolean value) {
			type = BOOL;
			aBool = value;
			anObject = null;
		}
		public void set(Boolean value) {
			if (value != null) {
				type = L_BOOL;
				aBool = value.booleanValue();
				anObject = null;
			} else
				set();
		}
		public void set(String value) {
			if (value != null) {
				type = STRING;
				anObject = value;
			} else
				set();
		}				
		public void set(Object value, int classObjectID) {
			if (value != null) {
				type = OBJECT;
				classID = classObjectID;
				anObject = value;
			} else
				set();
		}
		public void setObjectID(int value) {
			type = OBJECT_ID;
			objectID = value;
			anObject = null;
		}
		
		// Use this if the object is an array containing IDs. The retriever
		// will be used to get the next value to write to the stream.
		public void setArrayIDS(ValueRetrieve retriever, int arraySize, int componentType) {
			type = ARRAY_IDS;
			classID = componentType;
			anInt = arraySize;
			anObject = retriever;
		}
		
		
		// Use this if this is a new object so that we can get the correct class type.
		public void setObjectID(int value, int classObjectID) {
			type = NEW_OBJECT_ID;
			objectID = value;
			classID = classObjectID;
			anObject = null;
		}									
		
		// Use this to indicate an exception occured.
		public void setException(int throwID, int throwClassID) {
			type = THROW;
			objectID = throwID;
			classID = throwClassID;
			anObject = null;
		}
	}
	
	/************************
	 * Helpful commands.
	 * - If a command throws any exception except CommandErrorException, or
	 *   UnexpectedCommandException with recoverable true, then the connection is in a bad state
	 *   and needs to be closed.
	 ************************/
	
	/**
	 * Use this to read a value (inputstream should be pointing to the type byte as the next byte to read).
	 * The primitive fields of "value" will not be changed if they are not the
	 * type of the value being read. However, anObject will be set to null.
	 */
	 
	/**
	 * Error flags for UnexpectedCommandExceptions that can be thrown.
	 */
	public static final Object UNKNOWN_READ_TYPE = "UNKNOWN_READ_TYPE";		// The read type byte was not a valid type //$NON-NLS-1$
	public static final Object UNKNOWN_WRITE_TYPE = "UNKNOWN_WRITE_TYPE";		// The write type byte was not a valid type	 //$NON-NLS-1$
	public static final Object TYPE_INVALID_FOR_COMMAND = "TYPE_INVALID_FOR_COMMAND";		// The data type read is not valid for this command //$NON-NLS-1$
	public static final Object UNKNOWN_COMMAND = "UNKNOWN_COMMAND";			// The command flag is unknown //$NON-NLS-1$
	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.

	/**
	 * 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();
			switch (value.type) {
				case BYTE:
				case L_BYTE:
					value.aByte = is.readByte();
					break;
				case CHAR:
				case L_CHAR:
					value.aChar = is.readChar();
					break;
				case DOUBLE:
				case L_DOUBLE:
					value.aDouble = is.readDouble();
					break;
				case FLOAT:
				case L_FLOAT:
					value.aFloat = is.readFloat();
					break;
				case INT:
				case L_INT:
					value.anInt = is.readInt();
					break;
				case OBJECT_ID:
					value.objectID = is.readInt();
					break;					
				case NEW_OBJECT_ID:
					value.classID = is.readInt();
					value.objectID = is.readInt();
					break;
				case THROW:
					value.classID = is.readInt();
					value.objectID = is.readInt();
					break;				
				case SHORT:
				case L_SHORT:
					value.aShort = is.readShort();
					break;
				case LONG:
				case L_LONG:
					value.aLong = is.readLong();
					break;
				case BOOL:
				case L_BOOL:
					value.aBool = is.readBoolean();
					break;
				case STRING:
					value.anObject = readStringData(is);
					break;
				case OBJECT:
					value.classID = is.readInt();	// Read the class id
					ObjectInputStream oi = new ObjectInputStream(is);
					value.anObject = oi.readObject();	// Read the object itself
					oi = null;	// Don't close it, that would close the stream itself.
					break;
				case ARRAY_IDS:
					// The header for an array of ids.
					value.classID = is.readInt();	// The component type of the array
					value.anInt = is.readInt();	// The size of the array.
					// At this point, it is the responsibility of the caller to use readArray to read in the array.
					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));
			}
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}
	}
	
	/**
	 * 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.
		 * @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.
		 * @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, 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, allowFlag);
			if (exception == null) 
				try {
					if (value.type != ARRAY_IDS)
						valueSender.sendValue(value);
					else {
						// We have a nested array.
						ValueSender nestedSender = null;
						try {
							nestedSender = valueSender.nestedArray(value);
						} catch (RuntimeException e) {
							// We still need to read in the array to flush. Create
							// a dummy sender that accepts everything sent to it.
							exception = e;
							nestedSender = new ValueSender() {
								public void sendValue(ValueObject value) {
								}
								public ValueSender nestedArray(ValueObject arrayValue) {
									return this;
								}
								public void initialize(ValueObject arrayHeader) {
								}
							};
						}
						readArray(is, value.anInt, nestedSender, value, allowFlag);
						if (exception != null)
							throw exception;	// An exception ocurred in new sender request.
					}
				} catch (RuntimeException e) {
					// We want to flush the queue, so save the exception for later.
					exception = e;
				}
		}
		if (exception != null)
			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 {
		/**
		 * 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);
			switch (value.type) {
				case BYTE:
				case L_BYTE:
					os.writeByte(value.type);
					os.writeByte(value.aByte);
					break;
				case CHAR:
				case L_CHAR:
					os.writeByte(value.type);			
					os.writeChar(value.aChar);
					break;
				case DOUBLE:
				case L_DOUBLE:
					os.writeByte(value.type);			
					os.writeDouble(value.aDouble);
					break;
				case FLOAT:
				case L_FLOAT:
					os.writeByte(value.type);			
					os.writeFloat(value.aFloat);
					break;
				case INT:
				case L_INT:
					os.writeByte(value.type);			
					os.writeInt(value.anInt);
					break;
				case OBJECT_ID:
					os.writeByte(value.type);
					os.writeInt(value.objectID);
					break;					
				case NEW_OBJECT_ID:
					os.writeByte(value.type);
					os.writeInt(value.classID);
					os.writeInt(value.objectID);
					break;
				case THROW:
					os.writeByte(value.type);
					os.writeInt(value.classID);
					os.writeInt(value.objectID);
					break;
				case SHORT:
				case L_SHORT:
					os.writeByte(value.type);			
					os.writeShort(value.aShort);
					break;
				case LONG:
				case L_LONG:
					os.writeByte(value.type);			
					os.writeLong(value.aLong);
					break;
				case BOOL:
				case L_BOOL:
					os.writeByte(value.type);			
					os.writeBoolean(value.aBool);
					break;
				case STRING:
					os.writeByte(value.type);			
					sendStringData(os, (String) value.anObject);
					break;
				case OBJECT:
					os.writeByte(value.type);
					os.writeInt(value.classID);	// Write the class ID.
					ObjectOutputStream oos = new ObjectOutputStream(os);
					oos.writeObject(value.anObject);
					oos.flush();
					oos = null;	// Don't close it, that would close the stream itself.
					break;					
				case ARRAY_IDS:
					// 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(ARRAY_IDS);	
					os.writeInt(value.classID);
					os.writeInt(value.anInt);	// The size of the array.
					// Now comes the kludgy part, writing the values.
					ValueRetrieve retriever = (ValueRetrieve) value.anObject;
					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 (flush)
				os.flush();
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}	
	
	/**
	 * For reading a large number of bytes. This is a value type, not a command. The command 
	 * needs to be handled separately. It returns the number of bytes read. -1 if there
	 * is no more data to send and the stream should closed. If read something but not all,
	 * then just what it could read will be returned. The next read will return -1 for EOF.
	 *
	 * It will read from the format:
	 *   int - number of bytes to read (retrieved from the stream).
	 *   bytes - the actual bytes.
	 *
	 * Note: A command exception will be thrown if the number of bytes to read
	 *       is larger than the size of the byte array.
	 */
	public static int readBytes(DataInputStream is, byte[] bytes) throws CommandException  {
		try {
			int bytesToRead = -1;
			try {
				bytesToRead = is.readInt();
			} catch (EOFException e) {
			}
			if (bytesToRead == -1)
				return -1;
			if (bytesToRead > bytes.length)
				throw new UnexpectedCommandException(TOO_MANY_BYTES, false, new Integer(bytesToRead));
			int start = 0;
			int toRead = bytesToRead;
			while (toRead > 0) {
				int bytesRead = is.read(bytes, start, toRead);
				if (bytesRead == -1)
					return bytesToRead != toRead ? bytesToRead-toRead : -1;	// Actual number read, or if none read, then EOF
				start+=bytesRead;
				toRead-=bytesRead;
			}
			return bytesToRead;
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}
		
	/**
	 * For writing a large number of bytes. This is a value type, not a command. The command 
	 * needs to be handled separately.
	 *
	 * It will write it in the format:
	 *   int - number of bytes
	 *   bytes - the actual bytes.
	 *
	 */
	public static void writeBytes(DataOutputStream os, byte[] bytes, int bytesToWrite) throws CommandException  {
		try {
			os.writeInt(bytesToWrite);
			os.write(bytes, 0, bytesToWrite);
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}	
		
	/************************
	 * Send command helpers
	 ************************/
	 
	public static void sendQuitCommand(DataOutputStream os) throws IOException {
		os.writeByte(QUIT_CONNECTION);
		os.flush();
			
	}
	
	public static void sendTerminateCommand(DataOutputStream os) throws IOException {
		os.writeByte(TERMINATE_SERVER);
		os.flush();
	}
	
	
	public static void releaseObjectCommand(DataOutputStream os, int id) throws IOException {
		os.writeByte(Commands.RELEASE_OBJECT);
		os.writeInt(id);
		os.flush();
	}

	/**
	 * Send a callback request. The value is to be send separately.
	 */
	public static void sendCallbackCommand(DataOutputStream os, int callbackID, int msgID) throws CommandException {
		try {
			os.writeByte(CALLBACK);
			os.writeInt(callbackID);
			os.writeInt(msgID);
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}
		
	public static void sendCallbackDoneCommand(DataOutputStream os, ValueObject value, int errorCode) throws CommandException {
		try {
			os.writeByte(CALLBACK_DONE);
			if (errorCode == NO_ERROR) {
				writeValue(os, value, true);
				os.flush();
			} else
				sendErrorCommand(os, errorCode, value);
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}
	
	/**
	 * Send a start callback stream request. The data will be written separately.
	 * There will not be a callback done command. It will return as soon as the command
	 * is sent.
	 */
	public static void sendCallbackStreamCommand(DataOutputStream os, int callbackID, int msgID) throws CommandException {
		try {
			os.writeByte(CALLBACK_STREAM);
			os.writeInt(callbackID);
			os.writeInt(msgID);
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}
	
	protected static final byte STRING_NOT_CHUNKED = 0;
	protected static final byte STRING_CHUNKED = 1;
	protected static final byte MORE_CHUNKS = 2;
	protected static final byte LAST_CHUNK = 3;
	protected static final int CHUNK_SIZE = 65000/3; 
	
	/**
	 * Send string data. This is for general string data. It makes sure that if the string is too big (there is a UTF-8 limit)
	 * that it will send it in chunks. Use the corresponding <code>readStringData</code> to read such data in.
	 * @param os
	 * @param string
	 * @throws IOException
	 * 
	 * @since 1.0.0
	 */
	public static void sendStringData(DataOutputStream os, String string) throws IOException {
		// UTF-8 can take up to three bytes for each char. To be on safe side we will
		// not send a string larger than 65K/3 as one chunk.
		if (string.length() <= CHUNK_SIZE) {
			// Less than the limit, send byte to indicate not chunked.
			os.writeByte(STRING_NOT_CHUNKED);
			os.writeUTF(string);
		} else {
			// Over limit, need to chunk it.
			// send byte to indicate chunked, then send true length so that other side knows how big to create.
			os.writeByte(STRING_CHUNKED);
			os.writeInt(string.length());
			// Now send first chunk
			for(int i=0; i<string.length(); i+=CHUNK_SIZE) {
				int endIndex = i+CHUNK_SIZE;
				if (i == 0) {
					// The first chunk is just written as is. We know endIndex will be ok because we wouldn't get here unless LARGER than chunksize.
					os.writeUTF(string.substring(i, endIndex));
				} else {
					// Following chunks have either byte MORE_CHUNKS or LAST_CHUNK
					if (endIndex >= string.length()) {
						// This is last chunk.
						os.writeByte(LAST_CHUNK);
						os.writeUTF(string.substring(i));
					} else {
						// This is an intermediate chunk.
						os.writeByte(MORE_CHUNKS);
						os.writeUTF(string.substring(i, endIndex));
					}
				}
			}
		}
	}
	
	/**
	 * Read a string that was sent using the sendStringData command.
	 * @param in
	 * @return
	 * @throws IOException
	 * 
	 * @since 1.0.0
	 */
	public static String readStringData(DataInputStream is) throws IOException {
		byte chunked = is.readByte();
		if (chunked == STRING_NOT_CHUNKED)
			return is.readUTF();	// Not chunk, just read it.
		else {
			// It is chunked.
			int totalLength = is.readInt();	// Get the total length.
			StringBuffer sbr = new StringBuffer(totalLength);
			while(true) {
				sbr.append(is.readUTF());
				if (chunked != LAST_CHUNK)
					chunked = is.readByte();
				else
					break;
			}
			return sbr.toString();
		}
	}
	
	/**
	 * Read back command, expecting either a VALUE or an ERROR. You can request that
	 * it be of a specific type (if any type can be accepted then enter -1 for the type).
	 */
	public static final byte NO_TYPE_CHECK = -1;
	public static void readBackValue(DataInputStream is, ValueObject value, byte expectedType) throws CommandException {
		try {		
			byte v = is.readByte();
			switch (v) {
				case VALUE:
					readValue(is, value);
					if (expectedType != NO_TYPE_CHECK && 
							!(expectedType == value.type || (expectedType == Commands.OBJECT_ID && value.type == NEW_OBJECT_ID)))
						throw new UnexpectedCommandException(TYPE_INVALID_FOR_COMMAND, true, value);
					break;
				case ERROR:
					int code = is.readInt();
					readValue(is, value);
					throw new CommandErrorException(code, value);
				default:
					throw new UnexpectedCommandException(UNKNOWN_COMMAND, false, new Byte(v));
			}
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}				
	}
		
	
	/**
	 * GetClass command returns a GetClassReturn object.
	 */
	public static class GetClassReturn {
		public int classID;
		public boolean isInterface;
		public boolean isAbstract;
		public String superClassname;
	}
	
	public static GetClassReturn sendGetClassCommand(DataOutputStream os, DataInputStream is, String className) throws CommandException {
		try {
			os.writeByte(GET_CLASS);
			os.writeUTF(className);
			os.flush();
			
			GetClassReturn ret = new GetClassReturn();
			byte v = is.readByte();
			switch (v) {
				case GET_CLASS_RETURN:
					ret.classID = is.readInt();	// Get the new class id.
					ret.isInterface = is.readBoolean();	// Get the isInterface flag
					ret.isAbstract = is.readBoolean();	// Get the isAbstract flag.					
					ret.superClassname = is.readUTF();	// Get the super class name.
					return ret;
				case ERROR:
					int code = is.readInt();
					ValueObject value = new ValueObject();
					readValue(is, value);
					throw new CommandErrorException(code, value);
				default:
					throw new UnexpectedCommandException(UNKNOWN_COMMAND, false, new Byte(v));
			}
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}
	
	/**
	 * GetClassFromID command returns a GetClassIDReturn object.
	 */
	public static class GetClassIDReturn {
		public String className;
		public boolean isInterface;
		public boolean isAbstract;
		public String superClassname;
	}
		
	public static GetClassIDReturn sendGetClassFromIDCommand(DataOutputStream os, DataInputStream is, int classID) throws CommandException {
		try {
			os.writeByte(GET_CLASS_FROM_ID);
			os.writeInt(classID);
			os.flush();
			
			GetClassIDReturn ret = new GetClassIDReturn();
			byte v = is.readByte();
			switch (v) {
				case GET_CLASS_ID_RETURN:
					ret.className = is.readUTF();	// Get the new class name.
					ret.isInterface = is.readBoolean();	// Get the isInterface flag
					ret.isAbstract = is.readBoolean();	// Get the isAbstract flag.
					ret.superClassname = is.readUTF();	// Get the super class name.
					return ret;
				case ERROR:
					int code = is.readInt();
					ValueObject value = new ValueObject();
					readValue(is, value);
					throw new CommandErrorException(code, value);
				default:
					throw new UnexpectedCommandException(UNKNOWN_COMMAND, false, new Byte(v));
			}
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}
		
	public static void sendGetObjectData(DataOutputStream os, DataInputStream is, int objectID, ValueObject valueReturn) throws CommandException {
		try {
			os.writeByte(GET_OBJECT_DATA);
			os.writeInt(objectID);
			os.flush();
			readBackValue(is, valueReturn, NEW_OBJECT_ID);
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}		
	
	public static void sendErrorCommand(DataOutputStream os, int code, ValueObject errorValue) throws CommandException {
		try {
			os.writeByte(ERROR);
			os.writeInt(code);
			writeValue(os, errorValue, false);
			os.flush();
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}		
	
	public static void sendNewInstance(DataOutputStream os, DataInputStream is, int classId, String initializationString, ValueObject newValueReturn) throws CommandException {
		try {
			os.writeByte(NEW_INIT_STRING);
			os.writeInt(classId);
			os.writeUTF(initializationString);
			os.flush();
			readBackValue(is, newValueReturn, NO_TYPE_CHECK);
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}	
	
	
	public static void sendInvokeMethodCommand(DataOutputStream os, DataInputStream is, int methodID, ValueObject invokeOn, ValueObject parms, ValueObject valueReturn) throws CommandException {
		try {
			os.writeByte(INVOKE);
			os.writeInt(methodID);
			writeValue(os, invokeOn, false);
			writeValue(os, parms, false);
			os.flush();
			readBackValue(is, valueReturn, NO_TYPE_CHECK);
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}

	public static void sendInvokeMethodCommand(DataOutputStream os, DataInputStream is, ValueObject classType, String methodName, ValueObject parmTypes, ValueObject invokeOn, ValueObject parms, ValueObject valueReturn) throws CommandException {
		try {
			os.writeByte(INVOKE_WITH_METHOD_PASSED);
			writeValue(os, classType, false);
			os.writeUTF(methodName);
			writeValue(os, parmTypes, false);
			writeValue(os, invokeOn, false);
			writeValue(os, parms, false);
			os.flush();
			readBackValue(is, valueReturn, NO_TYPE_CHECK);
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}
	
	public static void sendGetArrayContentsCommand(DataOutputStream os, DataInputStream is, int arrayID, ValueObject valueReturn) throws CommandException {
		try {
			os.writeByte(GET_ARRAY_CONTENTS);
			os.writeInt(arrayID);
			os.flush();
			readBackValue(is, valueReturn, NO_TYPE_CHECK);
		} catch (CommandException e) {
			// rethrow this exception since we want these to go on out.
			throw e;
		} catch (Exception e) {
			// Wrapper this one.
			throw new UnexpectedExceptionCommandException(false, e);
		}		
	}
	
	private Commands() {
		// Never intended to be instantiated.
	}
}
