public void writeObject(Object obj, AbstractHessianOutput out)
    throws IOException
  {
    if (out.addRef(obj)) {
      return;
    }
    
    Class cl = obj.getClass();

    try {
      if (_writeReplace != null) {
	Object repl;

	if (_writeReplaceFactory != null)
	  repl = _writeReplace.invoke(_writeReplaceFactory, obj);
	else
	  repl = _writeReplace.invoke(obj);

	out.removeRef(obj);

	out.writeObject(repl);

	out.replaceRef(repl, obj);

	return;
      }
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      // log.log(Level.FINE, e.toString(), e);
      throw new RuntimeException(e);
    }

    int ref = out.writeObjectBegin(cl.getName());

    if (ref < -1) {
      writeObject10(obj, out);
    }
    else {
      if (ref == -1) {
	writeDefinition20(out);
	out.writeObjectBegin(cl.getName());
      }

      writeInstance(obj, out);
    }
  }