dumpElementln("no, got EOFException");
if(dump) dumpElementln("no, got EOFException");
  public final Object readObject() throws ClassNotFoundException, IOException  {    if (this.useSubclassMethod)      return readObjectOverride();    boolean was_deserializing;    Object ret_val;    was_deserializing = this.isDeserializing;    boolean is_consumed = false;    boolean old_mode = setBlockDataMode(false);    this.isDeserializing = true;    byte marker = this.realInputStream.readByte();    dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");    try      {	switch (marker)	  {	  case TC_ENDBLOCKDATA:	    {	      ret_val = null;	      is_consumed = true;	      break;	    }	  case TC_BLOCKDATA:	  case TC_BLOCKDATALONG:	    {	      if (marker == TC_BLOCKDATALONG)		dumpElementln("BLOCKDATALONG");	      else		dumpElementln("BLOCKDATA");	      readNextBlock(marker);	      throw new StreamCorruptedException("Unexpected blockData");	    }	  case TC_NULL:	    {	      dumpElementln("NULL");	      ret_val = null;	      break;	    }	  case TC_REFERENCE:	    {	      dumpElement("REFERENCE ");	      Integer oid = new Integer(this.realInputStream.readInt());	      dumpElementln(Integer.toHexString(oid.intValue()));	      ret_val = ((ObjectIdentityWrapper)			 this.objectLookupTable.get(oid)).object;	      break;	    }	  case TC_CLASS:	    {	      dumpElementln("CLASS");	      ObjectStreamClass osc = (ObjectStreamClass)readObject();	      Class clazz = osc.forClass();	      assignNewHandle(clazz);	      ret_val = clazz;	      break;	    }	  case TC_PROXYCLASSDESC:	    {	      dumpElementln("PROXYCLASS");	      int n_intf = this.realInputStream.readInt();	      String[] intfs = new String[n_intf];	      for (int i = 0; i < n_intf; i++)		{		  intfs[i] = this.realInputStream.readUTF();		  System.out.println(intfs[i]);		}	      	      boolean oldmode = setBlockDataMode(true);	      Class cl = resolveProxyClass(intfs);	      setBlockDataMode(oldmode);	      	      ObjectStreamClass osc = lookupClass(cl);	      assignNewHandle(osc);	      	      if (!is_consumed)		{		  byte b = this.realInputStream.readByte();		  if (b != TC_ENDBLOCKDATA)		    throw new IOException("Data annotated to class was not consumed." + b);		}	      else		is_consumed = false;	      ObjectStreamClass superosc = (ObjectStreamClass)readObject();	      osc.setSuperclass(superosc);	      ret_val = osc;	      break;	    }	  case TC_CLASSDESC:	    {	      ObjectStreamClass osc = readClassDescriptor();	      	      if (!is_consumed)		{		  byte b = this.realInputStream.readByte();		  if (b != TC_ENDBLOCKDATA)		    throw new IOException("Data annotated to class was not consumed." + b);		}	      else		is_consumed = false;	      	      osc.setSuperclass ((ObjectStreamClass)readObject());	      ret_val = osc;	      break;	    }	  case TC_STRING:	  case TC_LONGSTRING:	    {	      dumpElement("STRING=");	      String s = this.realInputStream.readUTF();	      dumpElementln(s);	      ret_val = processResolution(s, assignNewHandle(s));	      break;	    }	  case TC_ARRAY:	    {	      dumpElementln("ARRAY");	      ObjectStreamClass osc = (ObjectStreamClass)readObject();	      Class componentType = osc.forClass().getComponentType();	      dumpElement("ARRAY LENGTH=");	      int length = this.realInputStream.readInt();	      dumpElementln (length + "; COMPONENT TYPE=" + componentType);	      Object array = Array.newInstance(componentType, length);	      int handle = assignNewHandle(array);	      readArrayElements(array, componentType);	      for (int i = 0, len = Array.getLength(array); i < len; i++)		dumpElementln("  ELEMENT[" + i + "]=" + Array.get(array, i));	      ret_val = processResolution(array, handle);	      break;	    }	  case TC_OBJECT:	    {	      dumpElementln("OBJECT");	      ObjectStreamClass osc = (ObjectStreamClass)readObject();	      Class clazz = osc.forClass();	      	      if (!Serializable.class.isAssignableFrom(clazz))		throw new NotSerializableException		  (clazz + " is not Serializable, and thus cannot be deserialized.");	      	      if (Externalizable.class.isAssignableFrom(clazz))		{		  Externalizable obj = null;		  		  try		    {		      obj = (Externalizable)clazz.newInstance();		    }		  catch (InstantiationException e)		    {		      throw new ClassNotFoundException			("Instance of " + clazz + " could not be created");		    }		  catch (IllegalAccessException e)		    {		      throw new ClassNotFoundException			("Instance of " + clazz + " could not be created because class or "			 + "zero-argument constructor is not accessible");		    }		  catch (NoSuchMethodError e)		    {		      throw new ClassNotFoundException			("Instance of " + clazz			 + " could not be created because zero-argument constructor is not defined");		    }		  		  int handle = assignNewHandle(obj);		  		  boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);		  		  boolean oldmode = this.readDataFromBlock;		  if (read_from_blocks)		    setBlockDataMode(true);		  		  obj.readExternal(this);		  		  if (read_from_blocks)		    setBlockDataMode(oldmode);		  		  ret_val = processResolution(obj, handle);		  break;		} // end if (Externalizable.class.isAssignableFrom (clazz))	      	      // find the first non-serializable, non-abstract	      // class in clazz's inheritance hierarchy	      Class first_nonserial = clazz.getSuperclass();	      while (Serializable.class.isAssignableFrom(first_nonserial)		     || Modifier.isAbstract(first_nonserial.getModifiers()))		first_nonserial = first_nonserial.getSuperclass();	      	      Object obj = null;	      obj = newObject(clazz, first_nonserial);	      	      if (obj == null)		throw new ClassNotFoundException		  ("Instance of " + clazz + " could not be created");	      	      int handle = assignNewHandle(obj);	      this.currentObject = obj;	      ObjectStreamClass[] hierarchy =		inputGetObjectStreamClasses(clazz);	      	      for (int i = 0; i < hierarchy.length; i++)		{		  this.currentObjectStreamClass = hierarchy[i];		  		  dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());		  // XXX: should initialize fields in classes in the hierarchy		  // that aren't in the stream		  // should skip over classes in the stream that aren't in the		  // real classes hierarchy		  		  if (this.currentObjectStreamClass.hasReadMethod())		    {		      fieldsAlreadyRead = false;		      boolean oldmode = setBlockDataMode(true);		      callReadMethod(obj, this.currentObjectStreamClass);		      setBlockDataMode(oldmode);		      dumpElement("ENDBLOCKDATA? ");		      try			{			  // FIXME: XXX: This try block is to catch EOF which is			  // thrown for some objects.  That indicates a bug in the logic.			  if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)			    throw new IOException			      ("No end of block data seen for class with readObject (ObjectInputStream) method.");			  dumpElementln("yes");			}		      catch (EOFException e)			{			  dumpElementln("no, got EOFException");			}		      catch (IOException e)			{			  dumpElementln("no, got IOException");			}		    }		  else		    {		      readFields(obj, currentObjectStreamClass);		    }		}	      this.currentObject = null;	      this.currentObjectStreamClass = null;	      ret_val = processResolution(obj, handle);	      break;	    }	  case TC_RESET:	    dumpElementln("RESET");	    clearHandles();	    ret_val = readObject();	    break;	  case TC_EXCEPTION:	    {	      dumpElement("EXCEPTION=");	      Exception e = (Exception)readObject();	      dumpElementln(e.toString());	      clearHandles();	      throw new WriteAbortedException("Exception thrown during writing of stream", e);	    }	  default:	    throw new IOException("Unknown marker on stream: " + marker);	  }      }    finally      {	setBlockDataMode(old_mode);		this.isDeserializing = was_deserializing;		if (! was_deserializing)	  {	    if (validators.size() > 0)	      invokeValidators();	  }      }        return ret_val;  }