private void writeExternalData(Externalizable obj) throws IOException {
    Object oldObj = curObj;
    ObjectStreamClass oldDesc = curDesc;
    PutFieldImpl oldPut = curPut;
    curObj = obj;
    curDesc = null;
    curPut = null;

    obj.writeExternal(this);
    dos.writeMarker();

    curObj = oldObj;
    curDesc = oldDesc;
    curPut = oldPut;
  }
 private InteropObjectOutputStream(
     SerializationInfo info, Object obj, Class cl, ObjectStreamClass desc) throws IOException {
   dos = new ObjectDataOutputStream(info);
   if (obj instanceof ObjectStreamClass) {
     ObjectStreamClass osc = (ObjectStreamClass) obj;
     if (osc.isProxy()) {
       writeProxyDesc(osc);
     } else {
       writeNonProxyDesc(osc);
     }
   } else if (obj instanceof Serializable) {
     if (desc.isDynamicClass()) {
       info.SetType(ikvm.runtime.Util.getInstanceTypeFromClass(DynamicProxy.class));
     }
     writeOrdinaryObject(obj, desc);
   } else {
     throw new NotSerializableException(cl.getName());
   }
   dos.close();
 }
 private void writeSerialData(Object obj, ObjectStreamClass desc) throws IOException {
   ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
   for (int i = 0; i < slots.length; i++) {
     ObjectStreamClass slotDesc = slots[i].desc;
     if (slotDesc.hasWriteObjectMethod()) {
       Object oldObj = curObj;
       ObjectStreamClass oldDesc = curDesc;
       PutFieldImpl oldPut = curPut;
       curObj = obj;
       curDesc = slotDesc;
       curPut = null;
       slotDesc.invokeWriteObject(obj, this);
       dos.writeMarker();
       curObj = oldObj;
       curDesc = oldDesc;
       curPut = oldPut;
     } else {
       defaultWriteFields(obj, slotDesc);
     }
   }
 }
 @Override
 public void writeUTF(String str) throws IOException {
   dos.writeUTF(str);
 }
 @Override
 public void writeShort(int val) throws IOException {
   dos.writeShort(val);
 }
 @Override
 public void writeLong(long val) throws IOException {
   dos.writeLong(val);
 }
 @Override
 public void writeFloat(float val) throws IOException {
   dos.writeFloat(val);
 }
 @Override
 public void writeDouble(double val) throws IOException {
   dos.writeDouble(val);
 }
 @Override
 public void writeChar(int val) throws IOException {
   dos.writeChar(val);
 }
 @Override
 public void writeByte(int val) throws IOException {
   dos.writeByte(val);
 }
 @Override
 public void writeBoolean(boolean val) throws IOException {
   dos.writeBoolean(val);
 }
 @Override
 public void write(byte[] buf, int off, int len) throws IOException {
   dos.write(buf, off, len);
 }
 @Override
 protected void writeObjectOverride(Object obj) {
   // TODO consider tagging ghost arrays
   dos.writeObject(obj);
 }