public static void writeObject(Object obj, SerializationInfo info) {
   try {
     boolean replaced = false;
     Class cl = obj.getClass();
     ObjectStreamClass desc;
     for (; ; ) {
       Class repCl;
       desc = ObjectStreamClass.lookup(cl, true);
       if (!desc.hasWriteReplaceMethod()
           || (obj = desc.invokeWriteReplace(obj)) == null
           || (repCl = obj.getClass()) == cl) {
         break;
       }
       cl = repCl;
       replaced = true;
     }
     if (replaced) {
       info.AddValue("obj", obj);
       info.SetType(ikvm.runtime.Util.getInstanceTypeFromClass(ReplaceProxy.class));
     } else {
       new InteropObjectOutputStream(info, obj, cl, desc);
     }
   } catch (IOException x) {
     ikvm.runtime.Util.throwException(new SerializationException(x.getMessage(), x));
   }
 }
 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();
 }