class AviatorObjectOutputStream extends ObjectOutputStream {

  private Map<String, byte[]> classBytesCache = new HashMap<String, byte[]>();

  public AviatorObjectOutputStream(OutputStream out) throws IOException {
    super(out);
    this.enableReplaceObject(true);
  }


  @Override
  protected Object replaceObject(Object obj) throws IOException {
    if (obj instanceof ClassExpression) {
      this.classBytesCache.put(obj.getClass().getName(), ((ClassExpression) obj).getClassBytes());
    }

    return super.replaceObject(obj);
  }

  @Override
  protected void annotateClass(Class<?> cl) throws IOException {<FILL_FUNCTION_BODY>}

}

    if (ClassExpression.class.isAssignableFrom(cl) && cl != ClassExpression.class) {
      byte[] classBytes = this.classBytesCache.get(cl.getName());
      if (classBytes == null) {
        throw new IllegalArgumentException("Class bytes not found: " + cl.getName()
            + ", forgot to enable Options.SERIALIZABLE before compiling the script?");
      }
      this.writeInt(classBytes.length);
      this.write(classBytes);

    }
  
<methods>public void <init>(java.io.OutputStream) throws java.io.IOException,public void close() throws java.io.IOException,public void defaultWriteObject() throws java.io.IOException,public void flush() throws java.io.IOException,public java.io.ObjectOutputStream.PutField putFields() throws java.io.IOException,public void reset() throws java.io.IOException,public void useProtocolVersion(int) throws java.io.IOException,public void write(int) throws java.io.IOException,public void write(byte[]) throws java.io.IOException,public void write(byte[], int, int) throws java.io.IOException,public void writeBoolean(boolean) throws java.io.IOException,public void writeByte(int) throws java.io.IOException,public void writeBytes(java.lang.String) throws java.io.IOException,public void writeChar(int) throws java.io.IOException,public void writeChars(java.lang.String) throws java.io.IOException,public void writeDouble(double) throws java.io.IOException,public void writeFields() throws java.io.IOException,public void writeFloat(float) throws java.io.IOException,public void writeInt(int) throws java.io.IOException,public void writeLong(long) throws java.io.IOException,public final void writeObject(java.lang.Object) throws java.io.IOException,public void writeShort(int) throws java.io.IOException,public void writeUTF(java.lang.String) throws java.io.IOException,public void writeUnshared(java.lang.Object) throws java.io.IOException<variables>static final boolean $assertionsDisabled,private final java.io.ObjectOutputStream.BlockDataOutputStream bout,private java.io.SerialCallbackContext curContext,private java.io.ObjectOutputStream.PutFieldImpl curPut,private final java.io.ObjectOutputStream.DebugTraceInfoStack debugInfoStack,private int depth,private final boolean enableOverride,private boolean enableReplace,private static final boolean extendedDebugInfo,private final java.io.ObjectOutputStream.HandleTable handles,private byte[] primVals,private int protocol,private final java.io.ObjectOutputStream.ReplaceTable subs