class AppletServer extends Webserver {
    private StubGenerator stubGen;
    private Map<String,ExportedObject> exportedNames;
    private List<ExportedObject> exportedObjects;

    private static final byte[] okHeader
                                = "HTTP/1.0 200 OK\r\n\r\n".getBytes();

    /**
     * Constructs a web server.
     *
     * @param port      port number
     */
    public AppletServer(String port)
        throws IOException, NotFoundException, CannotCompileException
    {
        this(Integer.parseInt(port));
    }

    /**
     * Constructs a web server.
     *
     * @param port      port number
     */
    public AppletServer(int port)
        throws IOException, NotFoundException, CannotCompileException
    {
        this(ClassPool.getDefault(), new StubGenerator(), port);
    }

    /**
     * Constructs a web server.
     *
     * @param port      port number
     * @param src       the source of classs files.
     */
    public AppletServer(int port, ClassPool src)
        throws IOException, NotFoundException, CannotCompileException
    {
        this(new ClassPool(src), new StubGenerator(), port);
    }

    private AppletServer(ClassPool loader, StubGenerator gen, int port)
        throws IOException, NotFoundException, CannotCompileException
    {
        super(port);
        exportedNames = new Hashtable<String,ExportedObject>();
        exportedObjects = new Vector<ExportedObject>();
        stubGen = gen;
        addTranslator(loader, gen);
    }

    /**
     * Begins the HTTP service.
     */
    @Override
    public void run() {
        super.run();
    }

    /**
     * Exports an object.
     * This method produces the bytecode of the proxy class used
     * to access the exported object.  A remote applet can load
     * the proxy class and call a method on the exported object.
     *
     * @param name      the name used for looking the object up.
     * @param obj       the exported object.
     * @return          the object identifier
     *
     * @see javassist.tools.rmi.ObjectImporter#lookupObject(String)
     */
    public synchronized int exportObject(String name, Object obj)
        throws CannotCompileException
    {
        Class<?> clazz = obj.getClass();
        ExportedObject eo = new ExportedObject();
        eo.object = obj;
        eo.methods = clazz.getMethods();
        exportedObjects.add(eo);
        eo.identifier = exportedObjects.size() - 1;
        if (name != null)
            exportedNames.put(name, eo);

        try {
            stubGen.makeProxyClass(clazz);
        }
        catch (NotFoundException e) {
            throw new CannotCompileException(e);
        }

        return eo.identifier;
    }

    /**
     * Processes a request from a web browser (an ObjectImporter).
     */
    @Override
    public void doReply(InputStream in, OutputStream out, String cmd)
        throws IOException, BadHttpRequest
    {
        if (cmd.startsWith("POST /rmi "))
            processRMI(in, out);
        else if (cmd.startsWith("POST /lookup "))
            lookupName(cmd, in, out);
        else
            super.doReply(in, out, cmd);
    }

    private void processRMI(InputStream ins, OutputStream outs)
        throws IOException
    {
        ObjectInputStream in = new ObjectInputStream(ins);

        int objectId = in.readInt();
        int methodId = in.readInt();
        Exception err = null;
        Object rvalue = null;
        try {
            ExportedObject eo = exportedObjects.get(objectId);
            Object[] args = readParameters(in);
            rvalue = convertRvalue(eo.methods[methodId].invoke(eo.object,
                                                               args));
        }
        catch(Exception e) {
            err = e;
            logging2(e.toString());
        }

        outs.write(okHeader);
        ObjectOutputStream out = new ObjectOutputStream(outs);
        if (err != null) {
            out.writeBoolean(false);
            out.writeUTF(err.toString());
        }
        else
            try {
                out.writeBoolean(true);
                out.writeObject(rvalue);
            }
            catch (NotSerializableException e) {
                logging2(e.toString());
            }
            catch (InvalidClassException e) {
                logging2(e.toString());
            }

        out.flush();
        out.close();
        in.close();
    }

    private Object[] readParameters(ObjectInputStream in)
        throws IOException, ClassNotFoundException
    {
        int n = in.readInt();
        Object[] args = new Object[n];
        for (int i = 0; i < n; ++i) {
            Object a = in.readObject();
            if (a instanceof RemoteRef) {
                RemoteRef ref = (RemoteRef)a;
                ExportedObject eo = exportedObjects.get(ref.oid);
                a = eo.object;
            }

            args[i] = a;
        }

        return args;
    }

    private Object convertRvalue(Object rvalue)
        throws CannotCompileException
    {
        if (rvalue == null)
            return null;        // the return type is void.

        String classname = rvalue.getClass().getName();
        if (stubGen.isProxyClass(classname))
            return new RemoteRef(exportObject(null, rvalue), classname);
        return rvalue;
    }

    private void lookupName(String cmd, InputStream ins, OutputStream outs)
        throws IOException
    {<FILL_FUNCTION_BODY>}
}

        ObjectInputStream in = new ObjectInputStream(ins);
        String name = DataInputStream.readUTF(in);
        ExportedObject found = exportedNames.get(name);
        outs.write(okHeader);
        ObjectOutputStream out = new ObjectOutputStream(outs);
        if (found == null) {
            logging2(name + "not found.");
            out.writeInt(-1);           // error code
            out.writeUTF("error");
        }
        else {
            logging2(name);
            out.writeInt(found.identifier);
            out.writeUTF(found.object.getClass().getName());
        }

        out.flush();
        out.close();
        in.close();
    
<methods>public void <init>(java.lang.String) throws java.io.IOException,public void <init>(int) throws java.io.IOException,public void addTranslator(org.hotswap.agent.javassist.ClassPool, org.hotswap.agent.javassist.Translator) throws org.hotswap.agent.javassist.NotFoundException, org.hotswap.agent.javassist.CannotCompileException,public void doReply(java.io.InputStream, java.io.OutputStream, java.lang.String) throws java.io.IOException, org.hotswap.agent.javassist.tools.web.BadHttpRequest,public void end() throws java.io.IOException,public void logging(java.lang.String) ,public void logging(java.lang.String, java.lang.String) ,public void logging(java.lang.String, java.lang.String, java.lang.String) ,public void logging2(java.lang.String) ,public static void main(java.lang.String[]) throws java.io.IOException,public void run() ,public void setClassPool(org.hotswap.agent.javassist.ClassPool) <variables>private org.hotswap.agent.javassist.ClassPool classPool,public java.lang.String debugDir,private static final byte[] endofline,public java.lang.String htmlfileBase,private java.net.ServerSocket socket,protected org.hotswap.agent.javassist.Translator translator,private static final int typeClass,private static final int typeGif,private static final int typeHtml,private static final int typeJpeg,private static final int typeText