/* ClassRmicCompiler.java --
   Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

package gnu.classpath.tools.rmic;

import gnu.java.rmi.server.RMIHashes;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.rmi.MarshalException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.UnexpectedException;
import java.rmi.UnmarshalException;
import java.rmi.server.Operation;
import java.rmi.server.RemoteCall;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteRef;
import java.rmi.server.RemoteStub;
import java.rmi.server.Skeleton;
import java.rmi.server.SkeletonMismatchException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;

public class ClassRmicCompiler
  implements RmicBackend
{
  private String[] args;
  private int next;
  private List errors = new ArrayList();
  private boolean keep = false;
  private boolean need11Stubs = true;
  private boolean need12Stubs = true;
  private boolean compile = true;
  private boolean verbose;
  private boolean noWrite;
  private String destination;
  private String classpath;
  private ClassLoader loader;
  private int errorCount = 0;

  private Class clazz;
  private String classname;
  private String classInternalName;
  private String fullclassname;
  private MethodRef[] remotemethods;
  private String stubname;
  private String skelname;
  private List mRemoteInterfaces;

  /**
   * @return true if run was successful
   */
  public boolean run(String[] inputFiles)
  {
    args = inputFiles;

    if (next >= args.length)
      return false;

    for (int i = next; i < args.length; i++)
      {
	try
	  {
            if (verbose)
	      System.out.println("[Processing class " + args[i] + ".class]");
	    processClass(args[i].replace(File.separatorChar, '.'));
	  }
        catch (IOException e)
          {
            errors.add(e);
          }
        catch (RMICException e)
          {
            errors.add(e);
          }
      }
    if (errors.size() > 0)
      {
        for (Iterator it = errors.iterator(); it.hasNext(); )
          {
            Exception ex = (Exception) it.next();
            logError(ex);
          }
      }

    return errorCount == 0;
  }

  private void processClass(String cls) throws IOException, RMICException
  {
    // reset class specific vars
    clazz = null;
    classname = null;
    classInternalName = null;
    fullclassname = null;
    remotemethods = null;
    stubname = null;
    skelname = null;
    mRemoteInterfaces = new ArrayList();

    analyzeClass(cls);
    generateStub();
    if (need11Stubs)
      generateSkel();
  }

  private void analyzeClass(String cname)
    throws RMICException
  {
    if (verbose)
      System.out.println("[analyze class " + cname + "]");
    int p = cname.lastIndexOf('.');
    if (p != -1)
      classname = cname.substring(p + 1);
    else
      classname = cname;
    fullclassname = cname;

    findClass();
    findRemoteMethods();
  }

  /**
   * @deprecated
   */
  public Exception getException()
  {
    return errors.size() == 0 ? null : (Exception) errors.get(0);
  }

  private void findClass()
    throws RMICException
  {
    ClassLoader cl = (loader == null
                      ? ClassLoader.getSystemClassLoader()
                      : loader);
    try
      {
        clazz = Class.forName(fullclassname, false, cl);
      }
    catch (ClassNotFoundException cnfe)
      {
        throw new RMICException
          ("Class " + fullclassname + " not found in classpath", cnfe);
      }

    if (! Remote.class.isAssignableFrom(clazz))
      {
        throw new RMICException
          ("Class " + clazz.getName()
           + " does not implement a remote interface.");
      }
  }

  private static Type[] typeArray(Class[] cls)
  {
    Type[] t = new Type[cls.length];
    for (int i = 0; i < cls.length; i++)
      {
        t[i] = Type.getType(cls[i]);
      }

    return t;
  }

  private static String[] internalNameArray(Type[] t)
  {
    String[] s = new String[t.length];
    for (int i = 0; i < t.length; i++)
      {
        s[i] = t[i].getInternalName();
      }

    return s;
  }

  private static String[] internalNameArray(Class[] c)
  {
    return internalNameArray(typeArray(c));
  }

  private static final String forName = "class$";

  private static Object param(Method m, int argIndex)
  {
    List l = new ArrayList();
    l.add(m);
    l.add(new Integer(argIndex));
    return l;
  }

  private static void generateClassForNamer(ClassVisitor cls)
  {
    MethodVisitor cv =
      cls.visitMethod
      (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, forName,
       Type.getMethodDescriptor
       (Type.getType(Class.class), new Type[] { Type.getType(String.class) }),
       null, null);

    Label start = new Label();
    cv.visitLabel(start);
    cv.visitVarInsn(Opcodes.ALOAD, 0);
    cv.visitMethodInsn
      (Opcodes.INVOKESTATIC,
       Type.getInternalName(Class.class),
       "forName",
       Type.getMethodDescriptor
       (Type.getType(Class.class), new Type[] { Type.getType(String.class) }));
    cv.visitInsn(Opcodes.ARETURN);

    Label handler = new Label();
    cv.visitLabel(handler);
    cv.visitVarInsn(Opcodes.ASTORE, 1);
    cv.visitTypeInsn(Opcodes.NEW, typeArg(NoClassDefFoundError.class));
    cv.visitInsn(Opcodes.DUP);
    cv.visitVarInsn(Opcodes.ALOAD, 1);
    cv.visitMethodInsn
      (Opcodes.INVOKEVIRTUAL,
       Type.getInternalName(ClassNotFoundException.class),
       "getMessage",
       Type.getMethodDescriptor(Type.getType(String.class), new Type[] {}));
    cv.visitMethodInsn
      (Opcodes.INVOKESPECIAL,
       Type.getInternalName(NoClassDefFoundError.class),
       "<init>",
       Type.getMethodDescriptor
       (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
    cv.visitInsn(Opcodes.ATHROW);
    cv.visitTryCatchBlock
      (start, handler, handler,
       Type.getInternalName(ClassNotFoundException.class));
    cv.visitMaxs(-1, -1);
  }

  private void generateClassConstant(MethodVisitor cv, Class cls) {
    if (cls.isPrimitive())
      {
        Class boxCls;
        if (cls.equals(Boolean.TYPE))
          boxCls = Boolean.class;
        else if (cls.equals(Character.TYPE))
          boxCls = Character.class;
        else if (cls.equals(Byte.TYPE))
          boxCls = Byte.class;
        else if (cls.equals(Short.TYPE))
          boxCls = Short.class;
        else if (cls.equals(Integer.TYPE))
          boxCls = Integer.class;
        else if (cls.equals(Long.TYPE))
          boxCls = Long.class;
        else if (cls.equals(Float.TYPE))
          boxCls = Float.class;
        else if (cls.equals(Double.TYPE))
          boxCls = Double.class;
        else if (cls.equals(Void.TYPE))
          boxCls = Void.class;
        else
          throw new IllegalArgumentException("unknown primitive type " + cls);

        cv.visitFieldInsn
          (Opcodes.GETSTATIC, Type.getInternalName(boxCls), "TYPE",
           Type.getDescriptor(Class.class));
        return;
      }
    cv.visitLdcInsn(cls.getName());
    cv.visitMethodInsn
      (Opcodes.INVOKESTATIC, classInternalName, forName,
       Type.getMethodDescriptor
       (Type.getType(Class.class),
        new Type[] { Type.getType(String.class) }));
  }

  private void generateClassArray(MethodVisitor code, Class[] classes)
  {
    code.visitLdcInsn(new Integer(classes.length));
    code.visitTypeInsn(Opcodes.ANEWARRAY, typeArg(Class.class));
    for (int i = 0; i < classes.length; i++)
      {
        code.visitInsn(Opcodes.DUP);
        code.visitLdcInsn(new Integer(i));
        generateClassConstant(code, classes[i]);
        code.visitInsn(Opcodes.AASTORE);
      }
  }

  private void fillOperationArray(MethodVisitor clinit)
  {
    // Operations array
    clinit.visitLdcInsn(new Integer(remotemethods.length));
    clinit.visitTypeInsn(Opcodes.ANEWARRAY, typeArg(Operation.class));
    clinit.visitFieldInsn
      (Opcodes.PUTSTATIC, classInternalName, "operations",
       Type.getDescriptor(Operation[].class));

    for (int i = 0; i < remotemethods.length; i++)
      {
        Method m = remotemethods[i].meth;

        StringBuilder desc = new StringBuilder();
        desc.append(getPrettyName(m.getReturnType()) + " ");
        desc.append(m.getName() + "(");

        // signature
        Class[] sig = m.getParameterTypes();
        for (int j = 0; j < sig.length; j++)
          {
            desc.append(getPrettyName(sig[j]));
            if (j + 1 < sig.length)
                desc.append(", ");
          }

        // push operations array
        clinit.visitFieldInsn
          (Opcodes.GETSTATIC, classInternalName, "operations",
           Type.getDescriptor(Operation[].class));

        // push array index
        clinit.visitLdcInsn(new Integer(i));

        // instantiate operation and leave a copy on the stack
        clinit.visitTypeInsn(Opcodes.NEW, typeArg(Operation.class));
        clinit.visitInsn(Opcodes.DUP);
        clinit.visitLdcInsn(desc.toString());
        clinit.visitMethodInsn
          (Opcodes.INVOKESPECIAL,
           Type.getInternalName(Operation.class),
           "<init>",
           Type.getMethodDescriptor
           (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));

        // store in operations array
        clinit.visitInsn(Opcodes.AASTORE);
      }
  }

  private void generateStaticMethodObjs(MethodVisitor clinit)
  {
    for (int i = 0; i < remotemethods.length; i++)
      {
        Method m = remotemethods[i].meth;

        /*
         * $method_<i>m.getName()</i>_<i>i</i> =
         *   <i>m.getDeclaringClass()</i>.class.getMethod
         *     (m.getName(), m.getParameterType())
         */
        String methodVar = "$method_" + m.getName() + "_" + i;
        generateClassConstant(clinit, m.getDeclaringClass());
        clinit.visitLdcInsn(m.getName());
        generateClassArray(clinit, m.getParameterTypes());
        clinit.visitMethodInsn
          (Opcodes.INVOKEVIRTUAL,
           Type.getInternalName(Class.class),
           "getMethod",
           Type.getMethodDescriptor
           (Type.getType(Method.class),
            new Type[] { Type.getType(String.class),
                         Type.getType(Class[].class) }));

        clinit.visitFieldInsn
          (Opcodes.PUTSTATIC, classInternalName, methodVar,
           Type.getDescriptor(Method.class));
      }
  }

  private void generateStub()
    throws IOException
  {
    stubname = fullclassname + "_Stub";
    String stubclassname = classname + "_Stub";
    File file = new File((destination == null ? "." : destination)
                         + File.separator
                         + stubname.replace('.', File.separatorChar)
                         + ".class");

    if (verbose)
      System.out.println("[Generating class " + stubname + "]");

    final ClassWriter stub = new ClassWriter(true);
    classInternalName = stubname.replace('.', '/');
    final String superInternalName =
      Type.getType(RemoteStub.class).getInternalName();

    String[] remoteInternalNames =
      internalNameArray((Class[]) mRemoteInterfaces.toArray(new Class[] {}));
    stub.visit
      (Opcodes.V1_2, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, classInternalName,
       null, superInternalName, remoteInternalNames);

    if (need12Stubs)
      {
        stub.visitField
          (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "serialVersionUID",
           Type.LONG_TYPE.getDescriptor(), null, new Long(2L));
      }

    if (need11Stubs)
      {
        stub.visitField
          (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL,
           "interfaceHash", Type.LONG_TYPE.getDescriptor(), null,
           new Long(RMIHashes.getInterfaceHash(clazz)));

        if (need12Stubs)
          {
            stub.visitField
              (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC, "useNewInvoke",
               Type.BOOLEAN_TYPE.getDescriptor(), null, null);
          }

        stub.visitField
          (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL,
           "operations", Type.getDescriptor(Operation[].class), null, null);
      }

    // Set of method references.
    if (need12Stubs)
      {
        for (int i = 0; i < remotemethods.length; i++)
          {
            Method m = remotemethods[i].meth;
            String slotName = "$method_" + m.getName() + "_" + i;
            stub.visitField
              (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC, slotName,
               Type.getDescriptor(Method.class), null, null);
          }
      }

    MethodVisitor clinit = stub.visitMethod
      (Opcodes.ACC_STATIC, "<clinit>",
       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);

    if (need11Stubs)
      {
        fillOperationArray(clinit);
        if (! need12Stubs)
          clinit.visitInsn(Opcodes.RETURN);
      }

    if (need12Stubs)
      {
        // begin of try
        Label begin = new Label();

        // beginning of catch
        Label handler = new Label();
        clinit.visitLabel(begin);

        // Initialize the methods references.
        if (need11Stubs)
          {
            /*
             * RemoteRef.class.getMethod("invoke", new Class[] {
             *   Remote.class, Method.class, Object[].class, long.class })
             */
            generateClassConstant(clinit, RemoteRef.class);
            clinit.visitLdcInsn("invoke");
            generateClassArray
              (clinit, new Class[] { Remote.class, Method.class,
                                     Object[].class, long.class });
            clinit.visitMethodInsn
              (Opcodes.INVOKEVIRTUAL,
               Type.getInternalName(Class.class),
               "getMethod",
               Type.getMethodDescriptor
               (Type.getType(Method.class),
                new Type[] { Type.getType(String.class),
                             Type.getType(Class[].class) }));

            // useNewInvoke = true
            clinit.visitInsn(Opcodes.ICONST_1);
            clinit.visitFieldInsn
              (Opcodes.PUTSTATIC, classInternalName, "useNewInvoke",
               Type.BOOLEAN_TYPE.getDescriptor());
          }

        generateStaticMethodObjs(clinit);

        // jump past handler
        clinit.visitInsn(Opcodes.RETURN);
        clinit.visitLabel(handler);
        if (need11Stubs)
          {
            // useNewInvoke = false
            clinit.visitInsn(Opcodes.ICONST_0);
            clinit.visitFieldInsn
              (Opcodes.PUTSTATIC, classInternalName, "useNewInvoke",
               Type.BOOLEAN_TYPE.getDescriptor());
            clinit.visitInsn(Opcodes.RETURN);
          }
        else
          {
            // throw NoSuchMethodError
            clinit.visitTypeInsn(Opcodes.NEW, typeArg(NoSuchMethodError.class));
            clinit.visitInsn(Opcodes.DUP);
            clinit.visitLdcInsn("stub class initialization failed");
            clinit.visitMethodInsn
              (Opcodes.INVOKESPECIAL,
               Type.getInternalName(NoSuchMethodError.class),
               "<init>",
               Type.getMethodDescriptor
               (Type.VOID_TYPE,
                new Type[] { Type.getType(String.class) }));
            clinit.visitInsn(Opcodes.ATHROW);
          }

        clinit.visitTryCatchBlock
          (begin, handler, handler,
           Type.getInternalName(NoSuchMethodException.class));

      }

    clinit.visitMaxs(-1, -1);

    generateClassForNamer(stub);

    // Constructors
    if (need11Stubs)
      {
        // no arg public constructor
        MethodVisitor code = stub.visitMethod
          (Opcodes.ACC_PUBLIC, "<init>",
           Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}),
           null, null);
        code.visitVarInsn(Opcodes.ALOAD, 0);
        code.visitMethodInsn
          (Opcodes.INVOKESPECIAL, superInternalName, "<init>",
           Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
        code.visitInsn(Opcodes.RETURN);

        code.visitMaxs(-1, -1);
      }

    // public RemoteRef constructor
    MethodVisitor constructor = stub.visitMethod
      (Opcodes.ACC_PUBLIC, "<init>",
       Type.getMethodDescriptor
       (Type.VOID_TYPE, new Type[] {Type.getType(RemoteRef.class)}),
       null, null);
    constructor.visitVarInsn(Opcodes.ALOAD, 0);
    constructor.visitVarInsn(Opcodes.ALOAD, 1);
    constructor.visitMethodInsn
      (Opcodes.INVOKESPECIAL, superInternalName, "<init>",
       Type.getMethodDescriptor
       (Type.VOID_TYPE, new Type[] {Type.getType(RemoteRef.class)}));
    constructor.visitInsn(Opcodes.RETURN);
    constructor.visitMaxs(-1, -1);

    // Method implementations
    for (int i = 0; i < remotemethods.length; i++)
      {
        Method m = remotemethods[i].meth;
        Class[] sig = m.getParameterTypes();
        Class returntype = m.getReturnType();
        Class[] except = sortExceptions
          ((Class[]) remotemethods[i].exceptions.toArray(new Class[0]));

        MethodVisitor code = stub.visitMethod
          (Opcodes.ACC_PUBLIC,
           m.getName(),
           Type.getMethodDescriptor(Type.getType(returntype), typeArray(sig)),
           null,
           internalNameArray(typeArray(except)));

        final Variables var = new Variables();

        // this and parameters are the declared vars
        var.declare("this");
        for (int j = 0; j < sig.length; j++)
          var.declare(param(m, j), size(sig[j]));

        Label methodTryBegin = new Label();
        code.visitLabel(methodTryBegin);

        if (need12Stubs)
          {
            Label oldInvoke = new Label();
            if (need11Stubs)
              {
                // if not useNewInvoke jump to old invoke
                code.visitFieldInsn
                  (Opcodes.GETSTATIC, classInternalName, "useNewInvoke",
                   Type.getDescriptor(boolean.class));
                code.visitJumpInsn(Opcodes.IFEQ, oldInvoke);
              }

            // this.ref
            code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
            code.visitFieldInsn
              (Opcodes.GETFIELD, Type.getInternalName(RemoteObject.class),
               "ref", Type.getDescriptor(RemoteRef.class));

            // "this" is first arg to invoke
            code.visitVarInsn(Opcodes.ALOAD, var.get("this"));

            // method object is second arg to invoke
            String methName = "$method_" + m.getName() + "_" + i;
            code.visitFieldInsn
              (Opcodes.GETSTATIC, classInternalName, methName,
               Type.getDescriptor(Method.class));

            // args to remote method are third arg to invoke
            if (sig.length == 0)
              code.visitInsn(Opcodes.ACONST_NULL);
            else
              {
                // create arg Object[] (with boxed primitives) and push it
                code.visitLdcInsn(new Integer(sig.length));
                code.visitTypeInsn(Opcodes.ANEWARRAY, typeArg(Object.class));

                var.allocate("argArray");
                code.visitVarInsn(Opcodes.ASTORE, var.get("argArray"));

                for (int j = 0; j < sig.length; j++)
                  {
                    int size = size(sig[j]);
                    int insn = loadOpcode(sig[j]);
                    Class box = sig[j].isPrimitive() ? box(sig[j]) : null;

                    code.visitVarInsn(Opcodes.ALOAD, var.get("argArray"));
                    code.visitLdcInsn(new Integer(j));

                    // put argument on stack
                    if (box != null)
                      {
                        code.visitTypeInsn(Opcodes.NEW, typeArg(box));
                        code.visitInsn(Opcodes.DUP);
                        code.visitVarInsn(insn, var.get(param(m, j)));
                        code.visitMethodInsn
                          (Opcodes.INVOKESPECIAL,
                           Type.getInternalName(box),
                           "<init>",
                           Type.getMethodDescriptor
                           (Type.VOID_TYPE,
                            new Type[] { Type.getType(sig[j]) }));
                      }
                    else
                      code.visitVarInsn(insn, var.get(param(m, j)));

                    code.visitInsn(Opcodes.AASTORE);
                  }

                code.visitVarInsn(Opcodes.ALOAD, var.deallocate("argArray"));
              }

            // push remote operation opcode
            code.visitLdcInsn(new Long(remotemethods[i].hash));
            code.visitMethodInsn
              (Opcodes.INVOKEINTERFACE,
               Type.getInternalName(RemoteRef.class),
               "invoke",
               Type.getMethodDescriptor
               (Type.getType(Object.class),
                new Type[] { Type.getType(Remote.class),
                             Type.getType(Method.class),
                             Type.getType(Object[].class),
                             Type.LONG_TYPE }));

            if (! returntype.equals(Void.TYPE))
              {
                int retcode = returnOpcode(returntype);
                Class boxCls =
                  returntype.isPrimitive() ? box(returntype) : null;
                code.visitTypeInsn
                  (Opcodes.CHECKCAST, typeArg(boxCls == null ? returntype : boxCls));
                if (returntype.isPrimitive())
                  {
                    // unbox
                    code.visitMethodInsn
                      (Opcodes.INVOKEVIRTUAL,
                       Type.getType(boxCls).getInternalName(),
                       unboxMethod(returntype),
                       Type.getMethodDescriptor
                       (Type.getType(returntype), new Type[] {}));
                  }

                code.visitInsn(retcode);
              }
            else
              code.visitInsn(Opcodes.RETURN);


            if (need11Stubs)
              code.visitLabel(oldInvoke);
          }

        if (need11Stubs)
          {

            // this.ref.newCall(this, operations, index, interfaceHash)
            code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
            code.visitFieldInsn
              (Opcodes.GETFIELD,
               Type.getInternalName(RemoteObject.class),
               "ref",
               Type.getDescriptor(RemoteRef.class));

            // "this" is first arg to newCall
            code.visitVarInsn(Opcodes.ALOAD, var.get("this"));

            // operations is second arg to newCall
            code.visitFieldInsn
              (Opcodes.GETSTATIC, classInternalName, "operations",
               Type.getDescriptor(Operation[].class));

            // method index is third arg
            code.visitLdcInsn(new Integer(i));

            // interface hash is fourth arg
            code.visitFieldInsn
              (Opcodes.GETSTATIC, classInternalName, "interfaceHash",
               Type.LONG_TYPE.getDescriptor());

            code.visitMethodInsn
              (Opcodes.INVOKEINTERFACE,
               Type.getInternalName(RemoteRef.class),
               "newCall",
               Type.getMethodDescriptor
               (Type.getType(RemoteCall.class),
                new Type[] { Type.getType(RemoteObject.class),
                             Type.getType(Operation[].class),
                             Type.INT_TYPE,
                             Type.LONG_TYPE }));

            // store call object on stack and leave copy on stack
            var.allocate("call");
            code.visitInsn(Opcodes.DUP);
            code.visitVarInsn(Opcodes.ASTORE, var.get("call"));

            Label beginArgumentTryBlock = new Label();
            code.visitLabel(beginArgumentTryBlock);

            // ObjectOutput out = call.getOutputStream();
            code.visitMethodInsn
              (Opcodes.INVOKEINTERFACE,
               Type.getInternalName(RemoteCall.class),
               "getOutputStream",
               Type.getMethodDescriptor
               (Type.getType(ObjectOutput.class), new Type[] {}));

            for (int j = 0; j < sig.length; j++)
              {
                // dup the ObjectOutput
                code.visitInsn(Opcodes.DUP);

                // get j'th arg to remote method
                code.visitVarInsn(loadOpcode(sig[j]), var.get(param(m, j)));

                Class argCls =
                  sig[j].isPrimitive() ? sig[j] : Object.class;

                // out.writeFoo
                code.visitMethodInsn
                  (Opcodes.INVOKEINTERFACE,
                   Type.getInternalName(ObjectOutput.class),
                   writeMethod(sig[j]),
                   Type.getMethodDescriptor
                   (Type.VOID_TYPE,
                    new Type[] { Type.getType(argCls) }));
              }

            // pop ObjectOutput
            code.visitInsn(Opcodes.POP);

            Label iohandler = new Label();
            Label endArgumentTryBlock = new Label();
            code.visitJumpInsn(Opcodes.GOTO, endArgumentTryBlock);
            code.visitLabel(iohandler);

            // throw new MarshalException(msg, ioexception);
            code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
            code.visitTypeInsn(Opcodes.NEW, typeArg(MarshalException.class));
            code.visitInsn(Opcodes.DUP);
            code.visitLdcInsn("error marshalling arguments");
            code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
            code.visitMethodInsn
              (Opcodes.INVOKESPECIAL,
               Type.getInternalName(MarshalException.class),
               "<init>",
               Type.getMethodDescriptor
               (Type.VOID_TYPE,
                new Type[] { Type.getType(String.class),
                             Type.getType(Exception.class) }));
            code.visitInsn(Opcodes.ATHROW);

            code.visitLabel(endArgumentTryBlock);
            code.visitTryCatchBlock
              (beginArgumentTryBlock, iohandler, iohandler,
               Type.getInternalName(IOException.class));

            // this.ref.invoke(call)
            code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
            code.visitFieldInsn
              (Opcodes.GETFIELD, Type.getInternalName(RemoteObject.class),
               "ref", Type.getDescriptor(RemoteRef.class));
            code.visitVarInsn(Opcodes.ALOAD, var.get("call"));
            code.visitMethodInsn
              (Opcodes.INVOKEINTERFACE,
               Type.getInternalName(RemoteRef.class),
               "invoke",
               Type.getMethodDescriptor
               (Type.VOID_TYPE,
                new Type[] { Type.getType(RemoteCall.class) }));

            // handle return value
            boolean needcastcheck = false;

            Label beginReturnTryCatch = new Label();
            code.visitLabel(beginReturnTryCatch);

            int returncode = returnOpcode(returntype);

            if (! returntype.equals(Void.TYPE))
              {
                // call.getInputStream()
                code.visitVarInsn(Opcodes.ALOAD, var.get("call"));
                code.visitMethodInsn
                  (Opcodes.INVOKEINTERFACE,
                   Type.getInternalName(RemoteCall.class),
                   "getInputStream",
                   Type.getMethodDescriptor
                   (Type.getType(ObjectInput.class), new Type[] {}));

                Class readCls =
                  returntype.isPrimitive() ? returntype : Object.class;
                code.visitMethodInsn
                  (Opcodes.INVOKEINTERFACE,
                   Type.getInternalName(ObjectInput.class),
                   readMethod(returntype),
                   Type.getMethodDescriptor
                   (Type.getType(readCls), new Type[] {}));

                boolean castresult = false;

                if (! returntype.isPrimitive())
                  {
                    if (! returntype.equals(Object.class))
                      castresult = true;
                    else
                      needcastcheck = true;
                  }

                if (castresult)
                  code.visitTypeInsn(Opcodes.CHECKCAST, typeArg(returntype));

                // leave result on stack for return
              }

            // this.ref.done(call)
            code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
            code.visitFieldInsn
              (Opcodes.GETFIELD,
               Type.getInternalName(RemoteObject.class),
               "ref",
               Type.getDescriptor(RemoteRef.class));
            code.visitVarInsn(Opcodes.ALOAD, var.deallocate("call"));
            code.visitMethodInsn
              (Opcodes.INVOKEINTERFACE,
               Type.getInternalName(RemoteRef.class),
               "done",
               Type.getMethodDescriptor
               (Type.VOID_TYPE,
                new Type[] { Type.getType(RemoteCall.class) }));

            // return; or return result;
            code.visitInsn(returncode);

            // exception handler
            Label handler = new Label();
            code.visitLabel(handler);
            code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));

            // throw new UnmarshalException(msg, e)
            code.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class));
            code.visitInsn(Opcodes.DUP);
            code.visitLdcInsn("error unmarshalling return");
            code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
            code.visitMethodInsn
              (Opcodes.INVOKESPECIAL,
               Type.getInternalName(UnmarshalException.class),
               "<init>",
               Type.getMethodDescriptor
               (Type.VOID_TYPE,
                new Type[] { Type.getType(String.class),
                             Type.getType(Exception.class) }));
            code.visitInsn(Opcodes.ATHROW);

            Label endReturnTryCatch = new Label();

            // catch IOException
            code.visitTryCatchBlock
              (beginReturnTryCatch, handler, handler,
               Type.getInternalName(IOException.class));

            if (needcastcheck)
              {
                // catch ClassNotFoundException
                code.visitTryCatchBlock
                  (beginReturnTryCatch, handler, handler,
                   Type.getInternalName(ClassNotFoundException.class));
              }
          }

        Label rethrowHandler = new Label();
        code.visitLabel(rethrowHandler);
        // rethrow declared exceptions
        code.visitInsn(Opcodes.ATHROW);

        boolean needgeneral = true;
        for (int j = 0; j < except.length; j++)
          {
            if (except[j] == Exception.class)
              needgeneral = false;
          }

        for (int j = 0; j < except.length; j++)
          {
            code.visitTryCatchBlock
              (methodTryBegin, rethrowHandler, rethrowHandler,
               Type.getInternalName(except[j]));
          }

        if (needgeneral)
          {
            // rethrow unchecked exceptions
            code.visitTryCatchBlock
              (methodTryBegin, rethrowHandler, rethrowHandler,
               Type.getInternalName(RuntimeException.class));

            Label generalHandler = new Label();
            code.visitLabel(generalHandler);
            String msg = "undeclared checked exception";

            // throw new java.rmi.UnexpectedException(msg, e)
            code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
            code.visitTypeInsn(Opcodes.NEW, typeArg(UnexpectedException.class));
            code.visitInsn(Opcodes.DUP);
            code.visitLdcInsn(msg);
            code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
            code.visitMethodInsn
              (Opcodes.INVOKESPECIAL,
               Type.getInternalName(UnexpectedException.class),
               "<init>",
               Type.getMethodDescriptor
               (Type.VOID_TYPE,
                new Type [] { Type.getType(String.class),
                              Type.getType(Exception.class) }));
            code.visitInsn(Opcodes.ATHROW);

            code.visitTryCatchBlock
              (methodTryBegin, rethrowHandler, generalHandler,
               Type.getInternalName(Exception.class));
          }

        code.visitMaxs(-1, -1);
      }

    stub.visitEnd();
    byte[] classData = stub.toByteArray();
    if (!noWrite)
      {
        if (file.exists())
          file.delete();
        if (file.getParentFile() != null)
          file.getParentFile().mkdirs();
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(classData);
        fos.flush();
        fos.close();
      }
  }

  private void generateSkel() throws IOException
  {
    skelname = fullclassname + "_Skel";
    String skelclassname = classname + "_Skel";
    File file = new File(destination == null ? "" : destination
                         + File.separator
                         + skelname.replace('.', File.separatorChar)
                         + ".class");
    if (verbose)
      System.out.println("[Generating class " + skelname + "]");

    final ClassWriter skel = new ClassWriter(true);
    classInternalName = skelname.replace('.', '/');
    skel.visit
      (Opcodes.V1_1, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL,
       classInternalName, Type.getInternalName(Object.class), null,
       new String[] { Type.getType(Skeleton.class).getInternalName() });

    skel.visitField
      (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "interfaceHash",
       Type.LONG_TYPE.getDescriptor(), null,
       new Long(RMIHashes.getInterfaceHash(clazz)));

    skel.visitField
      (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "operations",
       Type.getDescriptor(Operation[].class), null, null);

    MethodVisitor clinit = skel.visitMethod
      (Opcodes.ACC_STATIC, "<clinit>",
       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);

    fillOperationArray(clinit);
    clinit.visitInsn(Opcodes.RETURN);

    clinit.visitMaxs(-1, -1);

    // no arg public constructor
    MethodVisitor init = skel.visitMethod
      (Opcodes.ACC_PUBLIC, "<init>",
       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);
    init.visitVarInsn(Opcodes.ALOAD, 0);
    init.visitMethodInsn
      (Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>",
       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
    init.visitInsn(Opcodes.RETURN);
    init.visitMaxs(-1, -1);

    /*
     * public Operation[] getOperations()
     * returns a clone of the operations array
     */
    MethodVisitor getOp = skel.visitMethod
      (Opcodes.ACC_PUBLIC, "getOperations",
       Type.getMethodDescriptor
       (Type.getType(Operation[].class), new Type[] {}),
       null, null);
    getOp.visitFieldInsn
      (Opcodes.GETSTATIC, classInternalName, "operations",
       Type.getDescriptor(Operation[].class));
    getOp.visitMethodInsn
      (Opcodes.INVOKEVIRTUAL, Type.getInternalName(Object.class),
       "clone", Type.getMethodDescriptor(Type.getType(Object.class),
                                         new Type[] {}));
    getOp.visitTypeInsn(Opcodes.CHECKCAST, typeArg(Operation[].class));
    getOp.visitInsn(Opcodes.ARETURN);
    getOp.visitMaxs(-1, -1);

    // public void dispatch(Remote, RemoteCall, int opnum, long hash)
    MethodVisitor dispatch = skel.visitMethod
      (Opcodes.ACC_PUBLIC,
       "dispatch",
       Type.getMethodDescriptor
       (Type.VOID_TYPE,
        new Type[] { Type.getType(Remote.class),
                     Type.getType(RemoteCall.class),
                     Type.INT_TYPE, Type.LONG_TYPE }), null,
       new String[] { Type.getInternalName(Exception.class) });

    Variables var = new Variables();
    var.declare("this");
    var.declare("remoteobj");
    var.declare("remotecall");
    var.declare("opnum");
    var.declareWide("hash");

    /*
     * if opnum >= 0
     * XXX it is unclear why there is handling of negative opnums
     */
    dispatch.visitVarInsn(Opcodes.ILOAD, var.get("opnum"));
    Label nonNegativeOpnum = new Label();
    Label opnumSet = new Label();
    dispatch.visitJumpInsn(Opcodes.IFGE, nonNegativeOpnum);

    for (int i = 0; i < remotemethods.length; i++)
      {
        // assign opnum if hash matches supplied hash
        dispatch.visitVarInsn(Opcodes.LLOAD, var.get("hash"));
        dispatch.visitLdcInsn(new Long(remotemethods[i].hash));
        Label notIt = new Label();
        dispatch.visitInsn(Opcodes.LCMP);
        dispatch.visitJumpInsn(Opcodes.IFNE, notIt);

        // opnum = <opnum>
        dispatch.visitLdcInsn(new Integer(i));
        dispatch.visitVarInsn(Opcodes.ISTORE, var.get("opnum"));
        dispatch.visitJumpInsn(Opcodes.GOTO, opnumSet);
        dispatch.visitLabel(notIt);
      }

    // throw new SkeletonMismatchException
    Label mismatch = new Label();
    dispatch.visitJumpInsn(Opcodes.GOTO, mismatch);

    dispatch.visitLabel(nonNegativeOpnum);

    // if opnum is already set, check that the hash matches the interface
    dispatch.visitVarInsn(Opcodes.LLOAD, var.get("hash"));
    dispatch.visitFieldInsn
      (Opcodes.GETSTATIC, classInternalName,
       "interfaceHash", Type.LONG_TYPE.getDescriptor());
    dispatch.visitInsn(Opcodes.LCMP);
    dispatch.visitJumpInsn(Opcodes.IFEQ, opnumSet);

    dispatch.visitLabel(mismatch);
    dispatch.visitTypeInsn
      (Opcodes.NEW, typeArg(SkeletonMismatchException.class));
    dispatch.visitInsn(Opcodes.DUP);
    dispatch.visitLdcInsn("interface hash mismatch");
    dispatch.visitMethodInsn
      (Opcodes.INVOKESPECIAL,
       Type.getInternalName(SkeletonMismatchException.class),
       "<init>",
       Type.getMethodDescriptor
       (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
    dispatch.visitInsn(Opcodes.ATHROW);

    // opnum has been set
    dispatch.visitLabel(opnumSet);

    dispatch.visitVarInsn(Opcodes.ALOAD, var.get("remoteobj"));
    dispatch.visitTypeInsn(Opcodes.CHECKCAST, typeArg(clazz));
    dispatch.visitVarInsn(Opcodes.ASTORE, var.get("remoteobj"));

    Label deflt = new Label();
    Label[] methLabels = new Label[remotemethods.length];
    for (int i = 0; i < methLabels.length; i++)
      methLabels[i] = new Label();

    // switch on opnum
    dispatch.visitVarInsn(Opcodes.ILOAD, var.get("opnum"));
    dispatch.visitTableSwitchInsn
      (0, remotemethods.length - 1, deflt, methLabels);

    // Method dispatch
    for (int i = 0; i < remotemethods.length; i++)
      {
        dispatch.visitLabel(methLabels[i]);
        Method m = remotemethods[i].meth;
        generateMethodSkel(dispatch, m, var);
      }

    dispatch.visitLabel(deflt);
    dispatch.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class));
    dispatch.visitInsn(Opcodes.DUP);
    dispatch.visitLdcInsn("invalid method number");
    dispatch.visitMethodInsn
      (Opcodes.INVOKESPECIAL,
       Type.getInternalName(UnmarshalException.class),
       "<init>",
       Type.getMethodDescriptor
       (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
    dispatch.visitInsn(Opcodes.ATHROW);

    dispatch.visitMaxs(-1, -1);

    skel.visitEnd();
    byte[] classData = skel.toByteArray();
    if (!noWrite)
      {
        if (file.exists())
          file.delete();
        if (file.getParentFile() != null)
          file.getParentFile().mkdirs();
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(classData);
        fos.flush();
        fos.close();
      }
  }

  private void generateMethodSkel(MethodVisitor cv, Method m, Variables var)
  {
    Class[] sig = m.getParameterTypes();

    Label readArgs = new Label();
    cv.visitLabel(readArgs);

    boolean needcastcheck = false;

    // ObjectInput in = call.getInputStream();
    cv.visitVarInsn(Opcodes.ALOAD, var.get("remotecall"));
    cv.visitMethodInsn
      (Opcodes.INVOKEINTERFACE,
       Type.getInternalName(RemoteCall.class), "getInputStream",
       Type.getMethodDescriptor
       (Type.getType(ObjectInput.class), new Type[] {}));
    cv.visitVarInsn(Opcodes.ASTORE, var.allocate("objectinput"));

    for (int i = 0; i < sig.length; i++)
      {
        // dup input stream
        cv.visitVarInsn(Opcodes.ALOAD, var.get("objectinput"));

        Class readCls = sig[i].isPrimitive() ? sig[i] : Object.class;

        // in.readFoo()
        cv.visitMethodInsn
          (Opcodes.INVOKEINTERFACE,
           Type.getInternalName(ObjectInput.class),
           readMethod(sig[i]),
           Type.getMethodDescriptor
           (Type.getType(readCls), new Type [] {}));

        if (! sig[i].isPrimitive() && ! sig[i].equals(Object.class))
          {
            needcastcheck = true;
            cv.visitTypeInsn(Opcodes.CHECKCAST, typeArg(sig[i]));
          }

        // store arg in variable
        cv.visitVarInsn
          (storeOpcode(sig[i]), var.allocate(param(m, i), size(sig[i])));
      }

    var.deallocate("objectinput");

    Label doCall = new Label();
    Label closeInput = new Label();

    cv.visitJumpInsn(Opcodes.JSR, closeInput);
    cv.visitJumpInsn(Opcodes.GOTO, doCall);

    // throw new UnmarshalException
    Label handler = new Label();
    cv.visitLabel(handler);
    cv.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
    cv.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class));
    cv.visitInsn(Opcodes.DUP);
    cv.visitLdcInsn("error unmarshalling arguments");
    cv.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
    cv.visitMethodInsn
      (Opcodes.INVOKESPECIAL,
       Type.getInternalName(UnmarshalException.class),
       "<init>",
       Type.getMethodDescriptor
       (Type.VOID_TYPE, new Type[] { Type.getType(String.class),
                                     Type.getType(Exception.class) }));
    cv.visitVarInsn(Opcodes.ASTORE, var.allocate("toThrow"));
    cv.visitJumpInsn(Opcodes.JSR, closeInput);
    cv.visitVarInsn(Opcodes.ALOAD, var.get("toThrow"));
    cv.visitInsn(Opcodes.ATHROW);

    cv.visitTryCatchBlock
      (readArgs, handler, handler, Type.getInternalName(IOException.class));
    if (needcastcheck)
      {
        cv.visitTryCatchBlock
          (readArgs, handler, handler,
           Type.getInternalName(ClassCastException.class));
      }

    // finally block
    cv.visitLabel(closeInput);
    cv.visitVarInsn(Opcodes.ASTORE, var.allocate("retAddress"));
    cv.visitVarInsn(Opcodes.ALOAD, var.get("remotecall"));
    cv.visitMethodInsn
      (Opcodes.INVOKEINTERFACE,
       Type.getInternalName(RemoteCall.class),
       "releaseInputStream",
       Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
    cv.visitVarInsn(Opcodes.RET, var.deallocate("retAddress"));
    var.deallocate("toThrow");

    // do the call using args stored as variables
    cv.visitLabel(doCall);
    cv.visitVarInsn(Opcodes.ALOAD, var.get("remoteobj"));
    for (int i = 0; i < sig.length; i++)
      cv.visitVarInsn(loadOpcode(sig[i]), var.deallocate(param(m, i)));
    cv.visitMethodInsn
      (Opcodes.INVOKEVIRTUAL, Type.getInternalName(clazz), m.getName(),
       Type.getMethodDescriptor(m));

    Class returntype = m.getReturnType();
    if (! returntype.equals(Void.TYPE))
      {
        cv.visitVarInsn
          (storeOpcode(returntype), var.allocate("result", size(returntype)));
      }

    // write result to result stream
    Label writeResult = new Label();
    cv.visitLabel(writeResult);
    cv.visitVarInsn(Opcodes.ALOAD, var.get("remotecall"));
    cv.visitInsn(Opcodes.ICONST_1);
    cv.visitMethodInsn
      (Opcodes.INVOKEINTERFACE,
       Type.getInternalName(RemoteCall.class),
       "getResultStream",
       Type.getMethodDescriptor
       (Type.getType(ObjectOutput.class),
        new Type[] { Type.BOOLEAN_TYPE }));

    if (! returntype.equals(Void.TYPE))
      {
        // out.writeFoo(result)
        cv.visitVarInsn(loadOpcode(returntype), var.deallocate("result"));
        Class writeCls = returntype.isPrimitive() ? returntype : Object.class;
        cv.visitMethodInsn
          (Opcodes.INVOKEINTERFACE,
           Type.getInternalName(ObjectOutput.class),
           writeMethod(returntype),
           Type.getMethodDescriptor
           (Type.VOID_TYPE, new Type[] { Type.getType(writeCls) }));
      }

    cv.visitInsn(Opcodes.RETURN);

    // throw new MarshalException
    Label marshalHandler = new Label();
    cv.visitLabel(marshalHandler);
    cv.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
    cv.visitTypeInsn(Opcodes.NEW, typeArg(MarshalException.class));
    cv.visitInsn(Opcodes.DUP);
    cv.visitLdcInsn("error marshalling return");
    cv.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
    cv.visitMethodInsn
      (Opcodes.INVOKESPECIAL,
       Type.getInternalName(MarshalException.class),
       "<init>",
       Type.getMethodDescriptor
       (Type.VOID_TYPE, new Type[] { Type.getType(String.class),
                                     Type.getType(Exception.class) }));
    cv.visitInsn(Opcodes.ATHROW);
    cv.visitTryCatchBlock
      (writeResult, marshalHandler, marshalHandler,
       Type.getInternalName(IOException.class));
  }

  private static String typeArg(Class cls)
  {
    if (cls.isArray())
      return Type.getDescriptor(cls);

    return Type.getInternalName(cls);
  }

  private static String readMethod(Class cls)
  {
    if (cls.equals(Void.TYPE))
      throw new IllegalArgumentException("can not read void");

    String method;
    if (cls.equals(Boolean.TYPE))
      method = "readBoolean";
    else if (cls.equals(Byte.TYPE))
      method = "readByte";
    else if (cls.equals(Character.TYPE))
      method = "readChar";
    else if (cls.equals(Short.TYPE))
      method = "readShort";
    else if (cls.equals(Integer.TYPE))
      method = "readInt";
    else if (cls.equals(Long.TYPE))
      method = "readLong";
    else if (cls.equals(Float.TYPE))
      method = "readFloat";
    else if (cls.equals(Double.TYPE))
      method = "readDouble";
    else
      method = "readObject";

    return method;
  }

  private static String writeMethod(Class cls)
  {
    if (cls.equals(Void.TYPE))
      throw new IllegalArgumentException("can not read void");

    String method;
    if (cls.equals(Boolean.TYPE))
      method = "writeBoolean";
    else if (cls.equals(Byte.TYPE))
      method = "writeByte";
    else if (cls.equals(Character.TYPE))
      method = "writeChar";
    else if (cls.equals(Short.TYPE))
      method = "writeShort";
    else if (cls.equals(Integer.TYPE))
      method = "writeInt";
    else if (cls.equals(Long.TYPE))
      method = "writeLong";
    else if (cls.equals(Float.TYPE))
      method = "writeFloat";
    else if (cls.equals(Double.TYPE))
      method = "writeDouble";
    else
      method = "writeObject";

    return method;
  }

  private static int returnOpcode(Class cls)
  {
    int returncode;
    if (cls.equals(Boolean.TYPE))
      returncode = Opcodes.IRETURN;
    else if (cls.equals(Byte.TYPE))
      returncode = Opcodes.IRETURN;
    else if (cls.equals(Character.TYPE))
      returncode = Opcodes.IRETURN;
    else if (cls.equals(Short.TYPE))
      returncode = Opcodes.IRETURN;
    else if (cls.equals(Integer.TYPE))
      returncode = Opcodes.IRETURN;
    else if (cls.equals(Long.TYPE))
      returncode = Opcodes.LRETURN;
    else if (cls.equals(Float.TYPE))
      returncode = Opcodes.FRETURN;
    else if (cls.equals(Double.TYPE))
      returncode = Opcodes.DRETURN;
    else if (cls.equals(Void.TYPE))
      returncode = Opcodes.RETURN;
    else
      returncode = Opcodes.ARETURN;

    return returncode;
  }

  private static int loadOpcode(Class cls)
  {
    if (cls.equals(Void.TYPE))
      throw new IllegalArgumentException("can not load void");

    int loadcode;
    if (cls.equals(Boolean.TYPE))
      loadcode = Opcodes.ILOAD;
    else if (cls.equals(Byte.TYPE))
      loadcode = Opcodes.ILOAD;
    else if (cls.equals(Character.TYPE))
      loadcode = Opcodes.ILOAD;
    else if (cls.equals(Short.TYPE))
      loadcode = Opcodes.ILOAD;
    else if (cls.equals(Integer.TYPE))
      loadcode = Opcodes.ILOAD;
    else if (cls.equals(Long.TYPE))
      loadcode = Opcodes.LLOAD;
    else if (cls.equals(Float.TYPE))
      loadcode = Opcodes.FLOAD;
    else if (cls.equals(Double.TYPE))
      loadcode = Opcodes.DLOAD;
    else
      loadcode = Opcodes.ALOAD;

    return loadcode;
  }

  private static int storeOpcode(Class cls)
  {
    if (cls.equals(Void.TYPE))
      throw new IllegalArgumentException("can not load void");

    int storecode;
    if (cls.equals(Boolean.TYPE))
      storecode = Opcodes.ISTORE;
    else if (cls.equals(Byte.TYPE))
      storecode = Opcodes.ISTORE;
    else if (cls.equals(Character.TYPE))
      storecode = Opcodes.ISTORE;
    else if (cls.equals(Short.TYPE))
      storecode = Opcodes.ISTORE;
    else if (cls.equals(Integer.TYPE))
      storecode = Opcodes.ISTORE;
    else if (cls.equals(Long.TYPE))
      storecode = Opcodes.LSTORE;
    else if (cls.equals(Float.TYPE))
      storecode = Opcodes.FSTORE;
    else if (cls.equals(Double.TYPE))
      storecode = Opcodes.DSTORE;
    else
      storecode = Opcodes.ASTORE;

    return storecode;
  }

  private static String unboxMethod(Class primitive)
  {
    if (! primitive.isPrimitive())
      throw new IllegalArgumentException("can not unbox nonprimitive");

    String method;
    if (primitive.equals(Boolean.TYPE))
      method = "booleanValue";
    else if (primitive.equals(Byte.TYPE))
      method = "byteValue";
    else if (primitive.equals(Character.TYPE))
      method = "charValue";
    else if (primitive.equals(Short.TYPE))
      method = "shortValue";
    else if (primitive.equals(Integer.TYPE))
      method = "intValue";
    else if (primitive.equals(Long.TYPE))
      method = "longValue";
    else if (primitive.equals(Float.TYPE))
      method = "floatValue";
    else if (primitive.equals(Double.TYPE))
      method = "doubleValue";
    else
      throw new IllegalStateException("unknown primitive class " + primitive);

    return method;
  }

  public static Class box(Class cls)
  {
    if (! cls.isPrimitive())
      throw new IllegalArgumentException("can only box primitive");

    Class box;
    if (cls.equals(Boolean.TYPE))
      box = Boolean.class;
    else if (cls.equals(Byte.TYPE))
      box = Byte.class;
    else if (cls.equals(Character.TYPE))
      box = Character.class;
    else if (cls.equals(Short.TYPE))
      box = Short.class;
    else if (cls.equals(Integer.TYPE))
      box = Integer.class;
    else if (cls.equals(Long.TYPE))
      box = Long.class;
    else if (cls.equals(Float.TYPE))
      box = Float.class;
    else if (cls.equals(Double.TYPE))
      box = Double.class;
    else
      throw new IllegalStateException("unknown primitive type " + cls);

    return box;
  }

  private static int size(Class cls) {
    if (cls.equals(Long.TYPE) || cls.equals(Double.TYPE))
      return 2;
    else
      return 1;
  }

  /**
   * Sort exceptions so the most general go last.
   */
  private Class[] sortExceptions(Class[] except)
  {
    for (int i = 0; i < except.length; i++)
      {
	for (int j = i + 1; j < except.length; j++)
	  {
	    if (except[i].isAssignableFrom(except[j]))
	      {
		Class tmp = except[i];
		except[i] = except[j];
		except[j] = tmp;
	      }
	  }
      }
    return (except);
  }

  public void setup(boolean keep, boolean need11Stubs, boolean need12Stubs,
                    boolean iiop, boolean poa, boolean debug, boolean warnings,
                    boolean noWrite, boolean verbose, boolean force, String classpath,
                    String bootclasspath, String extdirs, String outputDirectory)
  {
    this.keep = keep;
    this.need11Stubs = need11Stubs;
    this.need12Stubs = need12Stubs;
    this.verbose = verbose;
    this.noWrite = noWrite;

    // Set up classpath.
    this.classpath = classpath;
    StringTokenizer st =
      new StringTokenizer(classpath, File.pathSeparator);
    URL[] u = new URL[st.countTokens()];
    for (int i = 0; i < u.length; i++)
      {
        String path = st.nextToken();
        File f = new File(path);
        try
          {
            u[i] = f.toURL();
          }
        catch (java.net.MalformedURLException mue)
          {
            logError("malformed classpath component " + path);
            return;
          }
      }
    loader = new URLClassLoader(u);

    destination = outputDirectory;
  }

  private void findRemoteMethods()
    throws RMICException
  {
    List rmeths = new ArrayList();
    for (Class cur = clazz; cur != null; cur = cur.getSuperclass())
      {
        Class[] interfaces = cur.getInterfaces();
        for (int i = 0; i < interfaces.length; i++)
          {
            if (java.rmi.Remote.class.isAssignableFrom(interfaces[i]))
              {
                Class remoteInterface = interfaces[i];
                if (verbose)
                  System.out.println
                    ("[implements " + remoteInterface.getName() + "]");

                // check if the methods declare RemoteExceptions
                Method[] meths = remoteInterface.getMethods();
                for (int j = 0; j < meths.length; j++)
                  {
                    Method m = meths[j];
                    Class[] exs = m.getExceptionTypes();

                    boolean throwsRemote = false;
                    for (int k = 0; k < exs.length; k++)
                      {
                        if (exs[k].isAssignableFrom(RemoteException.class))
                          throwsRemote = true;
                      }

                    if (! throwsRemote)
                      {
                        throw new RMICException
                          ("Method " + m + " in interface " + remoteInterface
                           + " does not throw a RemoteException");
                      }

                    rmeths.add(m);
                  }

                mRemoteInterfaces.add(remoteInterface);
              }
          }
      }

    // intersect exceptions for doubly inherited methods
    boolean[] skip = new boolean[rmeths.size()];
    for (int i = 0; i < skip.length; i++)
      skip[i] = false;
    List methrefs = new ArrayList();
    for (int i = 0; i < rmeths.size(); i++)
      {
        if (skip[i]) continue;
        Method current = (Method) rmeths.get(i);
        MethodRef ref = new MethodRef(current);
        for (int j = i+1; j < rmeths.size(); j++)
          {
            Method other = (Method) rmeths.get(j);
            if (ref.isMatch(other))
              {
                ref.intersectExceptions(other);
                skip[j] = true;
              }
          }
        methrefs.add(ref);
      }

    // Convert into a MethodRef array and sort them
    remotemethods = (MethodRef[])
      methrefs.toArray(new MethodRef[methrefs.size()]);
    Arrays.sort(remotemethods);
  }

  /**
   * Prints an error to System.err and increases the error count.
   */
  private void logError(Exception theError)
  {
    logError(theError.getMessage());
    if (verbose)
      theError.printStackTrace(System.err);
  }

  /**
   * Prints an error to System.err and increases the error count.
   */
  private void logError(String theError)
  {
    errorCount++;
    System.err.println("error: " + theError);
  }

  private static String getPrettyName(Class cls)
  {
    StringBuilder str = new StringBuilder();
    for (int count = 0;; count++)
      {
	if (! cls.isArray())
	  {
	    str.append(cls.getName());
	    for (; count > 0; count--)
	      str.append("[]");
	    return (str.toString());
	  }
	cls = cls.getComponentType();
      }
  }

  private static class MethodRef
    implements Comparable
  {
    Method meth;
    long hash;
    List exceptions;
    private String sig;

    MethodRef(Method m) {
      meth = m;
      sig = Type.getMethodDescriptor(meth);
      hash = RMIHashes.getMethodHash(m);
      // add exceptions removing subclasses
      exceptions = removeSubclasses(m.getExceptionTypes());
    }

    public int compareTo(Object obj) {
      MethodRef that = (MethodRef) obj;
      int name = this.meth.getName().compareTo(that.meth.getName());
      if (name == 0) {
        return this.sig.compareTo(that.sig);
      }
      return name;
    }

    public boolean isMatch(Method m)
    {
      if (!meth.getName().equals(m.getName()))
        return false;

      Class[] params1 = meth.getParameterTypes();
      Class[] params2 = m.getParameterTypes();
      if (params1.length != params2.length)
        return false;

      for (int i = 0; i < params1.length; i++)
        if (!params1[i].equals(params2[i])) return false;

      return true;
    }

    private static List removeSubclasses(Class[] classes)
    {
      List list = new ArrayList();
      for (int i = 0; i < classes.length; i++)
        {
          Class candidate = classes[i];
          boolean add = true;
          for (int j = 0; j < classes.length; j++)
            {
              if (classes[j].equals(candidate))
                continue;
              else if (classes[j].isAssignableFrom(candidate))
                add = false;
            }
          if (add) list.add(candidate);
        }

      return list;
    }

    public void intersectExceptions(Method m)
    {
      List incoming = removeSubclasses(m.getExceptionTypes());

      List updated = new ArrayList();

      for (int i = 0; i < exceptions.size(); i++)
        {
          Class outer = (Class) exceptions.get(i);
          boolean addOuter = false;
          for (int j = 0; j < incoming.size(); j++)
            {
              Class inner = (Class) incoming.get(j);

              if (inner.equals(outer) || inner.isAssignableFrom(outer))
                addOuter = true;
              else if (outer.isAssignableFrom(inner))
                updated.add(inner);
            }

          if (addOuter)
            updated.add(outer);
        }

      exceptions = updated;
    }
  }
}
