/* Proxy.java -- build a proxy class that implements reflected interfaces
   Copyright (C) 2001, 2002, 2003 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.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.lang.reflect;

import java.io.Serializable;
import java.security.ProtectionDomain;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import gnu.classpath.Configuration;
import gnu.java.lang.reflect.TypeSignature;

/**
 * This class allows you to dynamically create an instance of any (or
 * even multiple) interfaces by reflection, and decide at runtime
 * how that instance will behave by giving it an appropriate
 * {@link InvocationHandler}.  Proxy classes serialize specially, so
 * that the proxy object can be reused between VMs, without requiring
 * a persistent copy of the generated class code.
 *
 * <h3>Creation</h3>
 * To create a proxy for some interface Foo:
 *
 * <pre>
 *   InvocationHandler handler = new MyInvocationHandler(...);
 *   Class proxyClass = Proxy.getProxyClass(
 *       Foo.class.getClassLoader(), new Class[] { Foo.class });
 *   Foo f = (Foo) proxyClass
 *       .getConstructor(new Class[] { InvocationHandler.class })
 *       .newInstance(new Object[] { handler });
 * </pre>
 * or more simply:
 * <pre>
 *   Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
 *                                        new Class[] { Foo.class },
 *                                        handler);
 * </pre>
 *
 * <h3>Dynamic Proxy Classes</h3>
 * A dynamic proxy class is created at runtime, and has the following
 * properties:
 * <ul>
 *  <li>The class is <code>public</code> and <code>final</code>,
 *      and is neither <code>abstract</code> nor an inner class.</li>
 *  <li>The class has no canonical name (there is no formula you can use
 *      to determine or generate its name), but begins with the
 *      sequence "$Proxy".  Abuse this knowledge at your own peril.
 *      (For now, '$' in user identifiers is legal, but it may not
 *      be that way forever. You weren't using '$' in your
 *      identifiers, were you?)</li>
 *  <li>The class extends Proxy, and explicitly implements all the
 *      interfaces specified at creation, in order (this is important
 *      for determining how method invocation is resolved).  Note that
 *      a proxy class implements {@link Serializable}, at least
 *      implicitly, since Proxy does, but true serial behavior
 *      depends on using a serializable invocation handler as well.</li>
 *  <li>If at least one interface is non-public, the proxy class
 *      will be in the same package.  Otherwise, the package is
 *      unspecified.  This will work even if the package is sealed
 *      from user-generated classes, because Proxy classes are
 *      generated by a trusted source.  Meanwhile, the proxy class
 *      belongs to the classloader you designated.</li>
 *  <li>Reflection works as expected: {@link Class#getInterfaces()} and
 *      {@link Class#getMethods()} work as they do on normal classes.</li>
 *  <li>The method {@link #isProxyClass()} will distinguish between
 *      true proxy classes and user extensions of this class.  It only
 *      returns true for classes created by {@link #getProxyClass}.</li>
 *  <li>The {@link ProtectionDomain} of a proxy class is the same as for
 *      bootstrap classes, such as Object or Proxy, since it is created by
 *      a trusted source.  This protection domain will typically be granted
 *      {@link java.security.AllPermission}. But this is not a security
 *      risk, since there are adequate permissions on reflection, which is
 *      the only way to create an instance of the proxy class.</li>
 *  <li>The proxy class contains a single constructor, which takes as
 *      its only argument an {@link InvocationHandler}.  The method
 *      {@link #newInstance} is shorthand to do the necessary
 *      reflection.</li>
 * </ul>
 *
 * <h3>Proxy Instances</h3>
 * A proxy instance is an instance of a proxy class.  It has the
 * following properties, many of which follow from the properties of a
 * proxy class listed above:
 * <ul>
 *  <li>For a proxy class with Foo listed as one of its interfaces, the
 *      expression <code>proxy instanceof Foo</code> will return true,
 *      and the expression <code>(Foo) proxy</code> will succeed without
 *      a {@link ClassCastException}.</li>
 *  <li>Each proxy instance has an invocation handler, which can be
 *      accessed by {@link #getInvocationHandler(Object)}.  Any call
 *      to an interface method, including {@link Object#hashcode()},
 *      {@link Object#equals(Object)}, or {@link Object#toString()},
 *      but excluding the public final methods of Object, will be
 *      encoded and passed to the {@link InvocationHandler#invoke}
 *      method of this handler.</li>
 * </ul>
 *
 * <h3>Inheritance Issues</h3>
 * A proxy class may inherit a method from more than one interface.
 * The order in which interfaces are listed matters, because it determines
 * which reflected {@link Method} object will be passed to the invocation
 * handler.  This means that the dynamically generated class cannot
 * determine through which interface a method is being invoked.<p>
 *
 * In short, if a method is declared in Object (namely, hashCode,
 * equals, or toString), then Object will be used; otherwise, the
 * leftmost interface that inherits or declares a method will be used,
 * even if it has a more permissive throws clause than what the proxy
 * class is allowed. Thus, in the invocation handler, it is not always
 * safe to assume that every class listed in the throws clause of the
 * passed Method object can safely be thrown; fortunately, the Proxy
 * instance is robust enough to wrap all illegal checked exceptions in
 * {@link UndeclaredThrowableException}.
 *
 * @see InvocationHandler
 * @see UndeclaredThrowableException
 * @see Class
 * @author Eric Blake <ebb9@email.byu.edu>
 * @since 1.3
 * @status updated to 1.4, except for the use of ProtectionDomain
 */
public class Proxy implements Serializable
{
  /**
   * Compatible with JDK 1.3+.
   */
  private static final long serialVersionUID = -2222568056686623797L;

  /**
   * Map of ProxyType to proxy class.
   *
   * @XXX This prevents proxy classes from being garbage collected.
   * java.util.WeakHashSet is not appropriate, because that collects the
   * keys, but we are interested in collecting the elements.
   */
  private static final Map proxyClasses = new HashMap();

  /**
   * The invocation handler for this proxy instance.  For Proxy, this
   * field is unused, but it appears here in order to be serialized in all
   * proxy classes.
   *
   * <em>NOTE</em>: This implementation is more secure for proxy classes
   * than what Sun specifies. Sun does not require h to be immutable, but
   * this means you could change h after the fact by reflection.  However,
   * by making h immutable, we may break non-proxy classes which extend
   * Proxy.
   * @serial invocation handler associated with this proxy instance
   */
  protected InvocationHandler h;

  /**
   * Constructs a new Proxy from a subclass (usually a proxy class),
   * with the specified invocation handler.
   *
   * <em>NOTE</em>: This throws a NullPointerException if you attempt
   * to create a proxy instance with a null handler using reflection.
   * This behavior is not yet specified by Sun; see Sun Bug 4487672.
   *
   * @param handler the invocation handler, may be null if the subclass
   *        is not a proxy class
   * @throws NullPointerException if handler is null and this is a proxy
   *         instance
   */
  protected Proxy(InvocationHandler handler)
  {
    if (handler == null && isProxyClass(getClass()))
      throw new NullPointerException("invalid handler");
    h = handler;
  }

  /**
   * Returns the proxy {@link Class} for the given ClassLoader and array
   * of interfaces, dynamically generating it if necessary.
   *
   * There are several restrictions on this method, the violation of
   * which will result in an IllegalArgumentException or
   * NullPointerException:
   * <ul>
   *  <li>All objects in `interfaces' must represent distinct interfaces.
   *      Classes, primitive types, null, and duplicates are forbidden.</li>
   *  <li>The interfaces must be visible in the specified ClassLoader.
   *      In other words, for each interface i:
   *      <code>Class.forName(i.getName(), false, loader) == i</code>
   *      must be true.</li>
   *  <li>All non-public interfaces (if any) must reside in the same
   *      package, or the proxy class would be non-instantiable.  If
   *      there are no non-public interfaces, the package of the proxy
   *      class is unspecified.</li>
   *  <li>All interfaces must be compatible - if two declare a method
   *      with the same name and parameters, the return type must be
   *      the same and the throws clause of the proxy class will be
   *      the maximal subset of subclasses of the throws clauses for
   *      each method that is overridden.</li>
   *  <li>VM constraints limit the number of interfaces a proxy class
   *      may directly implement (however, the indirect inheritance
   *      of {@link Serializable} does not count against this limit).
   *      Even though most VMs can theoretically have 65535
   *      superinterfaces for a class, the actual limit is smaller
   *      because a class's constant pool is limited to 65535 entries,
   *      and not all entries can be interfaces.</li>
   * </ul><p>
   *
   * Note that different orders of interfaces produce distinct classes.
   *
   * @param loader the class loader to define the proxy class in; null
   *        implies the bootstrap class loader
   * @param interfaces the array of interfaces the proxy class implements,
   *        may be empty, but not null
   * @return the Class object of the proxy class
   * @throws IllegalArgumentException if the constraints above were
   *         violated, except for problems with null
   * @throws NullPointerException if `interfaces' is null or contains
   *         a null entry
   */
  // synchronized so that we aren't trying to build the same class
  // simultaneously in two threads
  public static synchronized Class getProxyClass(ClassLoader loader,
                                                 Class[] interfaces)
  {
    interfaces = (Class[]) interfaces.clone();
    ProxyType pt = new ProxyType(loader, interfaces);
    Class clazz = (Class) proxyClasses.get(pt);
    if (clazz == null)
      {
        if (Configuration.HAVE_NATIVE_GET_PROXY_CLASS)
          clazz = getProxyClass0(loader, interfaces);
        else
          {
            ProxyData data = (Configuration.HAVE_NATIVE_GET_PROXY_DATA
                              ? getProxyData0(loader, interfaces)
                              : ProxyData.getProxyData(pt));

            clazz = (Configuration.HAVE_NATIVE_GENERATE_PROXY_CLASS
		     ? generateProxyClass0(loader, data)
                     : new ClassFactory(data).generate(loader));
          }

        Object check = proxyClasses.put(pt, clazz);
        // assert check == null && clazz != null;
        if (check != null || clazz == null)
          throw new InternalError(/*"Fatal flaw in getProxyClass"*/);
      }
    return clazz;
  }

  /**
   * Combines several methods into one.  This is equivalent to:
   * <pre>
   *   Proxy.getProxyClass(loader, interfaces)
   *       .getConstructor(new Class[] {InvocationHandler.class})
   *       .newInstance(new Object[] {handler});
   * </pre>
   * except that it will not fail with the normal problems caused
   * by reflection.  It can still fail for the same reasons documented
   * in getProxyClass, or if handler is null.
   *
   * @param loader the class loader to define the proxy class in; null
   *        implies the bootstrap class loader
   * @param interfaces the array of interfaces the proxy class implements,
   *        may be empty, but not null
   * @param handler the invocation handler, may not be null
   * @return a proxy instance implementing the specified interfaces
   * @throws IllegalArgumentException if the constraints for getProxyClass
   *         were violated, except for problems with null
   * @throws NullPointerException if `interfaces' is null or contains
   *         a null entry, or if handler is null
   * @see #getProxyClass(ClassLoader, Class[])
   * @see Class#getConstructor(Class[])
   * @see Constructor#newInstance(Object[])
   */
  public static Object newProxyInstance(ClassLoader loader,
                                        Class[] interfaces,
                                        InvocationHandler handler)
  {
    try
      {
        // getProxyClass() and Proxy() throw the necessary exceptions
        return getProxyClass(loader, interfaces)
          .getConstructor(new Class[] {InvocationHandler.class})
          .newInstance(new Object[] {handler});
      }
    catch (RuntimeException e)
      {
        // Let IllegalArgumentException, NullPointerException escape.
        // assert e instanceof IllegalArgumentException
        //   || e instanceof NullPointerException;
        throw e;
      }
    catch (InvocationTargetException e)
      {
        // Let wrapped NullPointerException escape.
        // assert e.getTargetException() instanceof NullPointerException
        throw (NullPointerException) e.getCause();
      }
    catch (Exception e)
      {
        // Covers InstantiationException, IllegalAccessException,
        // NoSuchMethodException, none of which should be generated
        // if the proxy class was generated correctly.
        // assert false;
        throw (Error) new InternalError("Unexpected: " + e).initCause(e);
      }
  }

  /**
   * Returns true if and only if the Class object is a dynamically created
   * proxy class (created by <code>getProxyClass</code> or by the
   * syntactic sugar of <code>newProxyInstance</code>).
   *
   * <p>This check is secure (in other words, it is not simply
   * <code>clazz.getSuperclass() == Proxy.class</code>), it will not
   * be spoofed by non-proxy classes that extend Proxy.
   *
   * @param clazz the class to check, must not be null
   * @return true if the class represents a proxy class
   * @throws NullPointerException if clazz is null
   */
  // This is synchronized on the off chance that another thread is
  // trying to add a class to the map at the same time we read it.
  public static synchronized boolean isProxyClass(Class clazz)
  {
    if (! Proxy.class.isAssignableFrom(clazz))
      return false;
    // This is a linear search, even though we could do an O(1) search
    // using new ProxyType(clazz.getClassLoader(), clazz.getInterfaces()).
    return proxyClasses.containsValue(clazz);
  }

  /**
   * Returns the invocation handler for the given proxy instance.<p>
   *
   * <em>NOTE</em>: We guarantee a non-null result if successful,
   * but Sun allows the creation of a proxy instance with a null
   * handler.  See the comments for {@link #Proxy(InvocationHandler)}.
   *
   * @param proxy the proxy instance, must not be null
   * @return the invocation handler, guaranteed non-null.
   * @throws IllegalArgumentException if
   *         <code>Proxy.isProxyClass(proxy.getClass())</code> returns false.
   * @throws NullPointerException if proxy is null
   */
  public static InvocationHandler getInvocationHandler(Object proxy)
  {
    if (! isProxyClass(proxy.getClass()))
      throw new IllegalArgumentException("not a proxy instance");
    return ((Proxy) proxy).h;
  }

  /**
   * Optional native method to replace (and speed up) the pure Java
   * implementation of getProxyClass.  Only needed if
   * Configuration.HAVE_NATIVE_GET_PROXY_CLASS is true, this does the
   * work of both getProxyData0 and generateProxyClass0 with no
   * intermediate form in Java. The native code may safely assume that
   * this class must be created, and does not already exist.
   *
   * @param loader the class loader to define the proxy class in; null
   *        implies the bootstrap class loader
   * @param interfaces the interfaces the class will extend
   * @return the generated proxy class
   * @throws IllegalArgumentException if the constraints for getProxyClass
   *         were violated, except for problems with null
   * @throws NullPointerException if `interfaces' is null or contains
   *         a null entry, or if handler is null
   * @see Configuration#HAVE_NATIVE_GET_PROXY_CLASS
   * @see #getProxyClass(ClassLoader, Class[])
   * @see #getProxyData0(ClassLoader, Class[])
   * @see #generateProxyClass0(ProxyData)
   */
  private static native Class getProxyClass0(ClassLoader loader,
                                             Class[] interfaces);

  /**
   * Optional native method to replace (and speed up) the pure Java
   * implementation of getProxyData.  Only needed if
   * Configuration.HAVE_NATIVE_GET_PROXY_DATA is true. The native code
   * may safely assume that a new ProxyData object must be created which
   * does not duplicate any existing ones.
   *
   * @param loader the class loader to define the proxy class in; null
   *        implies the bootstrap class loader
   * @param interfaces the interfaces the class will extend
   * @return all data that is required to make this proxy class
   * @throws IllegalArgumentException if the constraints for getProxyClass
   *         were violated, except for problems with null
   * @throws NullPointerException if `interfaces' is null or contains
   *         a null entry, or if handler is null
   * @see Configuration.HAVE_NATIVE_GET_PROXY_DATA
   * @see #getProxyClass(ClassLoader, Class[])
   * @see #getProxyClass0(ClassLoader, Class[])
   * @see ProxyType#getProxyData()
   */
  private static native ProxyData getProxyData0(ClassLoader loader,
                                                Class[] interfaces);

  /**
   * Optional native method to replace (and speed up) the pure Java
   * implementation of generateProxyClass.  Only needed if
   * Configuration.HAVE_NATIVE_GENERATE_PROXY_CLASS is true. The native
   * code may safely assume that a new Class must be created, and that
   * the ProxyData object does not describe any existing class.
   *
   * @param loader the class loader to define the proxy class in; null
   *        implies the bootstrap class loader
   * @param data the struct of information to convert to a Class. This
   *        has already been verified for all problems except exceeding
   *        VM limitations
   * @return the newly generated class
   * @throws IllegalArgumentException if VM limitations are exceeded
   * @see #getProxyClass(ClassLoader, Class[])
   * @see #getProxyClass0(ClassLoader, Class[])
   * @see ProxyData#generateProxyClass(ClassLoader)
   */
  private static native Class generateProxyClass0(ClassLoader loader,
                                                  ProxyData data);

  /**
   * Helper class for mapping unique ClassLoader and interface combinations
   * to proxy classes.
   *
   * @author Eric Blake <ebb9@email.byu.edu>
   */
  private static final class ProxyType
  {
    /**
     * Store the class loader (may be null)
     */
    final ClassLoader loader;

    /**
     * Store the interfaces (never null, all elements are interfaces)
     */
    final Class[] interfaces;

    /**
     * Construct the helper object.
     *
     * @param loader the class loader to define the proxy class in; null
     *        implies the bootstrap class loader
     * @param interfaces an array of interfaces
     */
    ProxyType(ClassLoader loader, Class[] interfaces)
    {
      if (loader == null)
         loader = ClassLoader.getSystemClassLoader();
      this.loader = loader;
      this.interfaces = interfaces;
    }

    /**
     * Calculates the hash code.
     *
     * @return a combination of the classloader and interfaces hashcodes.
     */
    public int hashCode()
    {
      //loader is always not null
      int hash = loader.hashCode();
      for (int i = 0; i < interfaces.length; i++)
        hash = hash * 31 + interfaces[i].hashCode();
      return hash;
    }

    // A more comprehensive comparison of two arrays,
    //   ignore array element order, and
    //   ignore redundant elements
    private static boolean sameTypes(Class arr1[], Class arr2[]) {
      if (arr1.length == 1 && arr2.length == 1) {
        return arr1[0] == arr2[0];
      }
        
      // total occurrance of elements of arr1 in arr2
      int total_occ_of_arr1_in_arr2 = 0;
    each_type:
      for (int i = arr1.length; --i >= 0; ) 
      {
        Class t = arr1[i];
        for (int j = i; --j >= 0; ) 
        {
          if (t == arr1[j]) 
          { //found duplicate type
            continue each_type;  
          }
        }
            
        // count c(a unique element of arr1)'s 
        //   occurrences in arr2
        int occ_in_arr2 = 0;
        for (int j = arr2.length; --j >= 0; ) 
        {
          if (t == arr2[j]) 
          {
            ++occ_in_arr2;
          }
        }
        if (occ_in_arr2 == 0) 
        { // t does not occur in arr2
          return false;
        }
        
        total_occ_of_arr1_in_arr2 += occ_in_arr2;
      }
      // now, each element of arr2 must have been visited
      return total_occ_of_arr1_in_arr2 == arr2.length;
    }

    /**
     * Calculates equality.
     *
     * @param the object to compare to
     * @return true if it is a ProxyType with same data
     */
    public boolean equals(Object other)
    {
      ProxyType pt = (ProxyType) other;
      if (loader != pt.loader || interfaces.length != pt.interfaces.length)
        return false;
	  return sameTypes(interfaces, pt.interfaces);
    }
  } // class ProxyType

  /**
   * Helper class which allows hashing of a method name and signature
   * without worrying about return type, declaring class, or throws clause,
   * and which reduces the maximally common throws clause between two methods
   *
   * @author Eric Blake <ebb9@email.byu.edu>
   */
  private static final class ProxySignature
  {
    /**
     * The core signatures which all Proxy instances handle.
     */
    static final HashMap coreMethods = new HashMap();
    static
    {
      try
        {
          ProxySignature sig
            = new ProxySignature(Object.class
                                 .getMethod("equals",
                                            new Class[] {Object.class}));
          coreMethods.put(sig, sig);
          sig = new ProxySignature(Object.class.getMethod("hashCode", null));
          coreMethods.put(sig, sig);
          sig = new ProxySignature(Object.class.getMethod("toString", null));
          coreMethods.put(sig, sig);
        }
      catch (Exception e)
        {
          // assert false;
          throw (Error) new InternalError("Unexpected: " + e).initCause(e);
        }
    }

    /**
     * The underlying Method object, never null
     */
    final Method method;

    /**
     * The set of compatible thrown exceptions, may be empty
     */
    final Set exceptions = new HashSet();

    /**
     * Construct a signature
     *
     * @param method the Method this signature is based on, never null
     */
    ProxySignature(Method method)
    {
      this.method = method;
      Class[] exc = method.getExceptionTypes();
      int i = exc.length;
      while (--i >= 0)
        {
          // discard unchecked exceptions
          if (Error.class.isAssignableFrom(exc[i])
              || RuntimeException.class.isAssignableFrom(exc[i]))
            continue;
          exceptions.add(exc[i]);
        }
    }

    /**
     * Given a method, make sure it's return type is identical
     * to this, and adjust this signature's throws clause appropriately
     *
     * @param other the signature to merge in
     * @throws IllegalArgumentException if the return types conflict
     */
    void checkCompatibility(ProxySignature other)
    {
      if (method.getReturnType() != other.method.getReturnType())
        throw new IllegalArgumentException("incompatible return types: "
                                           + method + ", " + other.method);

      // if you can think of a more efficient way than this O(n^2) search,
      // implement it!
      int size1 = exceptions.size();
      int size2 = other.exceptions.size();
      boolean[] valid1 = new boolean[size1];
      boolean[] valid2 = new boolean[size2];
      Iterator itr = exceptions.iterator();
      int pos = size1;
      while (--pos >= 0)
        {
          Class c1 = (Class) itr.next();
          Iterator itr2 = other.exceptions.iterator();
          int pos2 = size2;
          while (--pos2 >= 0)
            {
              Class c2 = (Class) itr2.next();
              if (c2.isAssignableFrom(c1))
                valid1[pos] = true;
              if (c1.isAssignableFrom(c2))
                valid2[pos2] = true;
            }
        }
      pos = size1;
      itr = exceptions.iterator();
      while (--pos >= 0)
        {
          itr.next();
          if (! valid1[pos])
            itr.remove();
        }
      pos = size2;
      itr = other.exceptions.iterator();
      while (--pos >= 0)
        {
          itr.next();
          if (! valid2[pos])
            itr.remove();
        }
      exceptions.addAll(other.exceptions);
    }

    /**
     * Calculates the hash code.
     *
     * @return a combination of name and parameter types
     */
    public int hashCode()
    {
      int hash = method.getName().hashCode();
      Class[] types = method.getParameterTypes();
      for (int i = 0; i < types.length; i++)
        hash = hash * 31 + types[i].hashCode();
      return hash;
    }

    /**
     * Calculates equality.
     *
     * @param the object to compare to
     * @return true if it is a ProxySignature with same data
     */
    public boolean equals(Object other)
    {
      ProxySignature ps = (ProxySignature) other;
      Class[] types1 = method.getParameterTypes();
      Class[] types2 = ps.method.getParameterTypes();
      if (! method.getName().equals(ps.method.getName())
          || types1.length != types2.length)
        return false;
      int i = types1.length;
      while (--i >= 0)
        if (types1[i] != types2[i])
          return false;
      return true;
    }
  } // class ProxySignature

  /**
   * A flat representation of all data needed to generate bytecode/instantiate
   * a proxy class.  This is basically a struct.
   *
   * @author Eric Blake <ebb9@email.byu.edu>
   */
  private static final class ProxyData
  {
    /**
     * The package this class is in.  Possibly null, meaning the unnamed
     * package.
     */
    String pack;

    /**
     * The interfaces this class implements.  Non-null, but possibly empty.
     */
    Class[] interfaces;

    /**
     * The Method objects this class must pass as the second argument to
     * invoke (also useful for determining what methods this class has).
     * Non-null, non-empty (includes at least Object.hashCode, Object.equals,
     * and Object.toString).
     */
    Method[] methods;

    /**
     * The exceptions that do not need to be wrapped in
     * UndeclaredThrowableException. exceptions[i] is the same as, or a
     * subset of subclasses, of methods[i].getExceptionTypes(), depending on
     * compatible throws clauses with multiple inheritance. It is unspecified
     * if these lists include or exclude subclasses of Error and
     * RuntimeException, but excluding them is harmless and generates a
     * smaller class.
     */
    Class[][] exceptions;

    /**
     * For unique id's
     */
    private static int count = 0;

    /**
     * The id of this proxy class
     */
    final int id = count++;

    /**
     * Construct a ProxyData with uninitialized data members.
     */
    ProxyData()
    {
    }

    /**
     * Return the name of a package given the name of a class.
     * Returns null if no package.  We use this in preference to
     * using Class.getPackage() to avoid problems with ClassLoaders
     * that don't set the package.
     */
    static String getPackage(Class k)
    {
      String name = k.getName();
      int idx = name.lastIndexOf('.');
      if (idx >= 0)
	return name.substring(0, idx);
      return null;
    }

    /**
     * Verifies that the arguments are legal, and sets up remaining data
     * This should only be called when a class must be generated, as
     * it is expensive.
     *
     * @param pt the ProxyType to convert to ProxyData
     * @return the flattened, verified ProxyData structure for use in
     *         class generation
     * @throws IllegalArgumentException if `interfaces' contains
     *         non-interfaces or incompatible combinations, and verify is true
     * @throws NullPointerException if interfaces is null or contains null
     */
    static ProxyData getProxyData(ProxyType pt)
    {
      Map method_set = (Map) ProxySignature.coreMethods.clone();
      boolean in_package = false; // true if we encounter non-public interface

      ProxyData data = new ProxyData();
      data.interfaces = pt.interfaces;

      // if interfaces is too large, we croak later on when the constant
      // pool overflows
      int i = data.interfaces.length;
      while (--i >= 0)
        {
          Class inter = data.interfaces[i];
          if (! inter.isInterface())
            throw new IllegalArgumentException("not an interface: " + inter);
          try
            {
              if (Class.forName(inter.getName(), false, pt.loader) != inter)
                throw new IllegalArgumentException("not accessible in "
                                                   + "classloader: " + inter);
            }
          catch (ClassNotFoundException e)
            {
              throw new IllegalArgumentException("not accessible in "
                                                 + "classloader: " + inter);
            }
          if (! Modifier.isPublic(inter.getModifiers()))
            if (in_package)
              {
		String p = getPackage(inter);
                if (! data.pack.equals(p))
                  throw new IllegalArgumentException("non-public interfaces "
                                                     + "from different "
                                                     + "packages");
              }
            else
              {
                in_package = true;
                data.pack = getPackage(inter);
              }
          for (int j = i-1; j >= 0; j--)
            if (data.interfaces[j] == inter)
              throw new IllegalArgumentException("duplicate interface: "
                                                 + inter);
          Method[] methods = inter.getMethods();
          int j = methods.length;
          while (--j >= 0)
            {
              ProxySignature sig = new ProxySignature(methods[j]);
              ProxySignature old = (ProxySignature) method_set.put(sig, sig);
              if (old != null)
                sig.checkCompatibility(old);
            }
        }

      i = method_set.size();
      data.methods = new Method[i];
      data.exceptions = new Class[i][];
      Iterator itr = method_set.values().iterator();
      while (--i >= 0)
        {
          ProxySignature sig = (ProxySignature) itr.next();
          data.methods[i] = sig.method;
          data.exceptions[i] = (Class[]) sig.exceptions
            .toArray(new Class[sig.exceptions.size()]);
        }
      return data;
    }
  } // class ProxyData

  /**
   * Does all the work of building a class. By making this a nested class,
   * this code is not loaded in memory if the VM has a native
   * implementation instead.
   *
   * @author Eric Blake <ebb9@email.byu.edu>
   */
  private static final class ClassFactory
  {
    /** Constants for assisting the compilation */
    private static final byte POOL = 0;
    private static final byte FIELD = 1;
    private static final byte METHOD = 2;
    private static final byte INTERFACE = 3;
    private static final String CTOR_SIG
      = "(Ljava/lang/reflect/InvocationHandler;)V";
    private static final String INVOKE_SIG = "(Ljava/lang/Object;"
      + "Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;";

    /** Bytecodes for insertion in the class definition byte[] */
    private static final char ACONST_NULL = 1;
    private static final char ICONST_0 = 3;
    private static final char BIPUSH = 16;
    private static final char SIPUSH = 17;
    private static final char ILOAD = 21;
    private static final char ILOAD_0 = 26;
    private static final char ALOAD_0 = 42;
    private static final char ALOAD_1 = 43;
    private static final char AALOAD = 50;
    private static final char AASTORE = 83;
    private static final char DUP = 89;
    private static final char DUP_X1 = 90;
    private static final char SWAP = 95;
    private static final char IRETURN = 172;
    private static final char LRETURN = 173;
    private static final char FRETURN = 174;
    private static final char DRETURN = 175;
    private static final char ARETURN = 176;
    private static final char RETURN = 177;
    private static final char GETSTATIC = 178;
    private static final char GETFIELD = 180;
    private static final char INVOKEVIRTUAL = 182;
    private static final char INVOKESPECIAL = 183;
    private static final char INVOKESTATIC = 184;
    private static final char INVOKEINTERFACE = 185;
    private static final char NEW = 187;
    private static final char ANEWARRAY = 189;
    private static final char ATHROW = 191;
    private static final char CHECKCAST = 192;

    // Implementation note: we use StringBuffers to hold the byte data, since
    // they automatically grow.  However, we only use the low 8 bits of
    // every char in the array, so we are using twice the necessary memory
    // for the ease StringBuffer provides.

    /** The constant pool. */
    private final StringBuffer pool = new StringBuffer();
    /** The rest of the class data. */
    private final StringBuffer stream = new StringBuffer();

    /** Map of strings to byte sequences, to minimize size of pool. */
    private final Map poolEntries = new HashMap();

    /** The VM name of this proxy class. */
    private final String qualName;

    /**
     * The Method objects the proxy class refers to when calling the
     * invocation handler.
     */
    private final Method[] methods;

    /**
     * Initializes the buffers with the bytecode contents for a proxy class.
     *
     * @param data the remainder of the class data
     * @throws IllegalArgumentException if anything else goes wrong this
     *         late in the game; as far as I can tell, this will only happen
     *         if the constant pool overflows, which is possible even when
     *         the user doesn't exceed the 65535 interface limit
     */
    ClassFactory(ProxyData data)
    {
      methods = data.methods;

      // magic = 0xcafebabe
      // minor_version = 0
      // major_version = 46
      // constant_pool_count: place-holder for now
      pool.append("\u00ca\u00fe\u00ba\u00be\0\0\0\56\0\0");
      // constant_pool[], filled in as we go

      // access_flags
      putU2(Modifier.SUPER | Modifier.FINAL | Modifier.PUBLIC);
      // this_class
      qualName = ((data.pack == null ? "" : data.pack + '.')
                  + "$Proxy" + data.id);
      putU2(classInfo(TypeSignature.getEncodingOfClass(qualName, false)));
      // super_class
      putU2(classInfo("java/lang/reflect/Proxy"));

      // interfaces_count
      putU2(data.interfaces.length);
      // interfaces[]
      for (int i = 0; i < data.interfaces.length; i++)
        putU2(classInfo(data.interfaces[i]));

      // Recall that Proxy classes serialize specially, so we do not need
      // to worry about a <clinit> method for this field.  Instead, we
      // just assign it by reflection after the class is successfully loaded.
      // fields_count - private static Method[] m;
      putU2(1);
      // fields[]
      // m.access_flags
      putU2(Modifier.PRIVATE | Modifier.STATIC);
      // m.name_index
      putU2(utf8Info("m"));
      // m.descriptor_index
      putU2(utf8Info("[Ljava/lang/reflect/Method;"));
      // m.attributes_count
      putU2(0);
      // m.attributes[]

      // methods_count - # handler methods, plus <init>
      putU2(methods.length + 1);
      // methods[]
      // <init>.access_flags
      putU2(Modifier.PUBLIC);
      // <init>.name_index
      putU2(utf8Info("<init>"));
      // <init>.descriptor_index
      putU2(utf8Info(CTOR_SIG));
      // <init>.attributes_count - only Code is needed
      putU2(1);
      // <init>.Code.attribute_name_index
      putU2(utf8Info("Code"));
      // <init>.Code.attribute_length = 18
      // <init>.Code.info:
      //   $Proxynn(InvocationHandler h) { super(h); }
      // <init>.Code.max_stack = 2
      // <init>.Code.max_locals = 2
      // <init>.Code.code_length = 6
      // <init>.Code.code[]
      stream.append("\0\0\0\22\0\2\0\2\0\0\0\6" + ALOAD_0 + ALOAD_1
                    + INVOKESPECIAL);
      putU2(refInfo(METHOD, "java/lang/reflect/Proxy", "<init>", CTOR_SIG));
      // <init>.Code.exception_table_length = 0
      // <init>.Code.exception_table[]
      // <init>.Code.attributes_count = 0
      // <init>.Code.attributes[]
      stream.append(RETURN + "\0\0\0\0");

      for (int i = methods.length - 1; i >= 0; i--)
        emitMethod(i, data.exceptions[i]);

      // attributes_count
      putU2(0);
      // attributes[] - empty; omit SourceFile attribute
      // XXX should we mark this with a Synthetic attribute?
    }

    /**
     * Produce the bytecode for a single method.
     *
     * @param i the index of the method we are building
     * @param e the exceptions possible for the method
     */
    private void emitMethod(int i, Class[] e)
    {
      // First, we precalculate the method length and other information.

      Method m = methods[i];
      Class[] paramtypes = m.getParameterTypes();
      int wrap_overhead = 0; // max words taken by wrapped primitive
      int param_count = 1; // 1 for this
      int code_length = 16; // aload_0, getfield, aload_0, getstatic, const,
      // aaload, const/aconst_null, invokeinterface
      if (i > 5)
        {
          if (i > Byte.MAX_VALUE)
            code_length += 2; // sipush
          else
            code_length++; // bipush
        }
      if (paramtypes.length > 0)
        {
          code_length += 3; // anewarray
          if (paramtypes.length > Byte.MAX_VALUE)
            code_length += 2; // sipush
          else if (paramtypes.length > 5)
            code_length++; // bipush
          for (int j = 0; j < paramtypes.length; j++)
            {
              code_length += 4; // dup, const, load, store
              Class type = paramtypes[j];
              if (j > 5)
                {
                  if (j > Byte.MAX_VALUE)
                    code_length += 2; // sipush
                  else
                    code_length++; // bipush
                }
              if (param_count >= 4)
                code_length++; // 2-byte load
              param_count++;
              if (type.isPrimitive())
                {
                  code_length += 7; // new, dup, invokespecial
                  if (type == long.class || type == double.class)
                    {
                      wrap_overhead = 3;
                      param_count++;
                    }
                  else if (wrap_overhead < 2)
                    wrap_overhead = 2;
                }
            }
        }
      int end_pc = code_length;
      Class ret_type = m.getReturnType();
      if (ret_type == void.class)
        code_length++; // return
      else if (ret_type.isPrimitive())
        code_length += 7; // cast, invokevirtual, return
      else
        code_length += 4; // cast, return
      int exception_count = 0;
      boolean throws_throwable = false;
      for (int j = 0; j < e.length; j++)
        if (e[j] == Throwable.class)
          {
            throws_throwable = true;
            break;
          }
      if (! throws_throwable)
        {
          exception_count = e.length + 3; // Throwable, Error, RuntimeException
          code_length += 9; // new, dup_x1, swap, invokespecial, athrow
        }
      int handler_pc = code_length - 1;
      StringBuffer signature = new StringBuffer("(");
      for (int j = 0; j < paramtypes.length; j++)
        signature.append(TypeSignature.getEncodingOfClass(paramtypes[j]));
      signature.append(")").append(TypeSignature.getEncodingOfClass(ret_type));

      // Now we have enough information to emit the method.

      // handler.access_flags
      putU2(Modifier.PUBLIC | Modifier.FINAL);
      // handler.name_index
      putU2(utf8Info(m.getName()));
      // handler.descriptor_index
      putU2(utf8Info(signature.toString()));
      // handler.attributes_count - Code is necessary, Exceptions possible
      putU2(e.length > 0 ? 2 : 1);

      // handler.Code.info:
      //   type name(args) {
      //     try {
      //       return (type) h.invoke(this, methods[i], new Object[] {args});
      //     } catch (<declared Exceptions> e) {
      //       throw e;
      //     } catch (Throwable t) {
      //       throw new UndeclaredThrowableException(t);
      //     }
      //   }
      // Special cases:
      //  if arg_n is primitive, wrap it
      //  if method throws Throwable, try-catch is not needed
      //  if method returns void, return statement not needed
      //  if method returns primitive, unwrap it
      //  save space by sharing code for all the declared handlers

      // handler.Code.attribute_name_index
      putU2(utf8Info("Code"));
      // handler.Code.attribute_length
      putU4(12 + code_length + 8 * exception_count);
      // handler.Code.max_stack
      putU2(param_count == 1 ? 4 : 7 + wrap_overhead);
      // handler.Code.max_locals
      putU2(param_count);
      // handler.Code.code_length
      putU4(code_length);
      // handler.Code.code[]
      putU1(ALOAD_0);
      putU1(GETFIELD);
      putU2(refInfo(FIELD, "java/lang/reflect/Proxy", "h",
                    "Ljava/lang/reflect/InvocationHandler;"));
      putU1(ALOAD_0);
      putU1(GETSTATIC);
      putU2(refInfo(FIELD, TypeSignature.getEncodingOfClass(qualName, false),
                    "m", "[Ljava/lang/reflect/Method;"));
      putConst(i);
      putU1(AALOAD);
      if (paramtypes.length > 0)
        {
          putConst(paramtypes.length);
          putU1(ANEWARRAY);
          putU2(classInfo("java/lang/Object"));
          param_count = 1;
          for (int j = 0; j < paramtypes.length; j++, param_count++)
            {
              putU1(DUP);
              putConst(j);
              if (paramtypes[j].isPrimitive())
                {
                  putU1(NEW);
                  putU2(classInfo(wrapper(paramtypes[j])));
                  putU1(DUP);
                }
              putLoad(param_count, paramtypes[j]);
              if (paramtypes[j].isPrimitive())
                {
                  putU1(INVOKESPECIAL);
                  putU2(refInfo(METHOD, wrapper(paramtypes[j]), "<init>",
                                '(' + (TypeSignature
                                       .getEncodingOfClass(paramtypes[j])
                                       + ")V")));
                  if (paramtypes[j] == long.class
                      || paramtypes[j] == double.class)
                    param_count++;
                }
              putU1(AASTORE);
            }
        }
      else
        putU1(ACONST_NULL);
      putU1(INVOKEINTERFACE);
      putU2(refInfo(INTERFACE, "java/lang/reflect/InvocationHandler",
                    "invoke", INVOKE_SIG));
      putU1(4); // InvocationHandler, this, Method, Object[]
      putU1(0);
      if (ret_type == void.class)
        putU1(RETURN);
      else if (ret_type.isPrimitive())
        {
          putU1(CHECKCAST);
          putU2(classInfo(wrapper(ret_type)));
          putU1(INVOKEVIRTUAL);
          putU2(refInfo(METHOD, wrapper(ret_type),
                        ret_type.getName() + "Value",
                        "()" + TypeSignature.getEncodingOfClass(ret_type)));
          if (ret_type == long.class)
            putU1(LRETURN);
          else if (ret_type == float.class)
            putU1(FRETURN);
          else if (ret_type == double.class)
            putU1(DRETURN);
          else
            putU1(IRETURN);
        }
      else
        {
          putU1(CHECKCAST);
          putU2(classInfo(ret_type));
          putU1(ARETURN);
        }
      if (! throws_throwable)
        {
          putU1(NEW);
          putU2(classInfo("java/lang/reflect/UndeclaredThrowableException"));
          putU1(DUP_X1);
          putU1(SWAP);
          putU1(INVOKESPECIAL);
          putU2(refInfo(METHOD,
                        "java/lang/reflect/UndeclaredThrowableException",
                        "<init>", "(Ljava/lang/Throwable;)V"));
          putU1(ATHROW);
        }

      // handler.Code.exception_table_length
      putU2(exception_count);
      // handler.Code.exception_table[]
      if (! throws_throwable)
        {
          // handler.Code.exception_table.start_pc
          putU2(0);
          // handler.Code.exception_table.end_pc
          putU2(end_pc);
          // handler.Code.exception_table.handler_pc
          putU2(handler_pc);
          // handler.Code.exception_table.catch_type
          putU2(classInfo("java/lang/Error"));
          // handler.Code.exception_table.start_pc
          putU2(0);
          // handler.Code.exception_table.end_pc
          putU2(end_pc);
          // handler.Code.exception_table.handler_pc
          putU2(handler_pc);
          // handler.Code.exception_table.catch_type
          putU2(classInfo("java/lang/RuntimeException"));
          for (int j = 0; j < e.length; j++)
            {
              // handler.Code.exception_table.start_pc
              putU2(0);
              // handler.Code.exception_table.end_pc
              putU2(end_pc);
              // handler.Code.exception_table.handler_pc
              putU2(handler_pc);
              // handler.Code.exception_table.catch_type
              putU2(classInfo(e[j]));
            }
          // handler.Code.exception_table.start_pc
          putU2(0);
          // handler.Code.exception_table.end_pc
          putU2(end_pc);
          // handler.Code.exception_table.handler_pc -
          //   -8 for undeclared handler, which falls thru to normal one
          putU2(handler_pc - 8);
          // handler.Code.exception_table.catch_type
          putU2(0);
        }
      // handler.Code.attributes_count
      putU2(0);
      // handler.Code.attributes[]

      if (e.length > 0)
        {
          // handler.Exceptions.attribute_name_index
          putU2(utf8Info("Exceptions"));
          // handler.Exceptions.attribute_length
          putU4(2 * e.length + 2);
          // handler.Exceptions.number_of_exceptions
          putU2(e.length);
          // handler.Exceptions.exception_index_table[]
          for (int j = 0; j < e.length; j++)
            putU2(classInfo(e[j]));
        }
    }

    /**
     * Creates the Class object that corresponds to the bytecode buffers
     * built when this object was constructed.
     *
     * @param loader the class loader to define the proxy class in; null
     *        implies the bootstrap class loader
     * @return the proxy class Class object
     */
    final Class generate(ClassLoader loader)
    {
      byte[] bytecode = new byte[pool.length() + stream.length()];
      // More efficient to bypass calling charAt() repetitively.
      char[] c = pool.toString().toCharArray();
      int i = c.length;
      while (--i >= 0)
        bytecode[i] = (byte) c[i];
      c = stream.toString().toCharArray();
      i = c.length;
      int j = bytecode.length;
      while (i > 0)
        bytecode[--j] = (byte) c[--i];

      // Patch the constant pool size, which we left at 0 earlier.
      int count = poolEntries.size() + 1;
      bytecode[8] = (byte) (count >> 8);
      bytecode[9] = (byte) count;

      try
        {
          // XXX Do we require more native support here?

          Class vmClassLoader = Class.forName("java.lang.VMClassLoader");
          Class[] types = {ClassLoader.class, String.class,
                           byte[].class, int.class, int.class,
                           ProtectionDomain.class };
          Method m = vmClassLoader.getDeclaredMethod("defineClass", types);

          // Bypass the security check of setAccessible(true), since this
          // is trusted code. But note the comment above about the security
          // risk of doing this outside a synchronized block.
          m.flag = true;
          Object[] args = {loader, qualName, bytecode, new Integer(0),
                           new Integer(bytecode.length),
                           Object.class.getProtectionDomain() };
          Class clazz = (Class) m.invoke(null, args);
          m.flag = false;

          // Finally, initialize the m field of the proxy class, before
          // returning it.

          // No security risk here, since clazz has not been exposed yet,
          // so user code cannot grab the same reflection object.
          Field f = clazz.getDeclaredField("m");
          f.flag = true;
          // we can share the array, because it is not publicized
          f.set(null, methods);
          f.flag = false;

          return clazz;
        }
      catch (Throwable e)
        {
          // assert false;
          throw (Error) new InternalError("Unexpected: " + e).initCause(e);
        }
    }

    /**
     * Put a single byte on the stream.
     *
     * @param i the information to add (only lowest 8 bits are used)
     */
    private void putU1(int i)
    {
      stream.append((char) i);
    }

    /**
     * Put two bytes on the stream.
     *
     * @param i the information to add (only lowest 16 bits are used)
     */
    private void putU2(int i)
    {
      stream.append((char) (i >> 8)).append((char) i);
    }

    /**
     * Put four bytes on the stream.
     *
     * @param i the information to add (treated as unsigned)
     */
    private void putU4(int i)
    {
      stream.append((char) (i >> 24)).append((char) (i >> 16));
      stream.append((char) (i >> 8)).append((char) i);
    }

    /**
     * Put bytecode to load a constant integer on the stream. This only
     * needs to work for values less than Short.MAX_VALUE.
     *
     * @param i the int to add
     */
    private void putConst(int i)
    {
      if (i >= -1 && i <= 5)
        putU1(ICONST_0 + i);
      else if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE)
        {
          putU1(BIPUSH);
          putU1(i);
        }
      else
        {
          putU1(SIPUSH);
          putU2(i);
        }
    }

    /**
     * Put bytecode to load a given local variable on the stream.
     *
     * @param i the slot to load
     * @param type the base type of the load
     */
    private void putLoad(int i, Class type)
    {
      int offset = 0;
      if (type == long.class)
        offset = 1;
      else if (type == float.class)
        offset = 2;
      else if (type == double.class)
        offset = 3;
      else if (! type.isPrimitive())
        offset = 4;
      if (i < 4)
        putU1(ILOAD_0 + 4 * offset + i);
      else
        {
          putU1(ILOAD + offset);
          putU1(i);
        }
    }

    /**
     * Given a primitive type, return its wrapper class name.
     *
     * @param clazz the primitive type (but not void.class)
     * @return the internal form of the wrapper class name
     */
    private String wrapper(Class clazz)
    {
      if (clazz == boolean.class)
        return "java/lang/Boolean";
      if (clazz == byte.class)
        return "java/lang/Byte";
      if (clazz == short.class)
        return "java/lang/Short";
      if (clazz == char.class)
        return "java/lang/Character";
      if (clazz == int.class)
        return "java/lang/Integer";
      if (clazz == long.class)
        return "java/lang/Long";
      if (clazz == float.class)
        return "java/lang/Float";
      if (clazz == double.class)
        return "java/lang/Double";
      // assert false;
      return null;
    }

    /**
     * Returns the entry of this String in the Constant pool, adding it
     * if necessary.
     *
     * @param str the String to resolve
     * @return the index of the String in the constant pool
     */
    private char utf8Info(String str)
    {
      String utf8 = toUtf8(str);
      int len = utf8.length();
      return poolIndex("\1" + (char) (len >> 8) + (char) (len & 0xff) + utf8);
    }

    /**
     * Returns the entry of the appropriate class info structure in the
     * Constant pool, adding it if necessary.
     *
     * @param name the class name, in internal form
     * @return the index of the ClassInfo in the constant pool
     */
    private char classInfo(String name)
    {
      char index = utf8Info(name);
      char[] c = {7, (char) (index >> 8), (char) (index & 0xff)};
      return poolIndex(new String(c));
    }

    /**
     * Returns the entry of the appropriate class info structure in the
     * Constant pool, adding it if necessary.
     *
     * @param clazz the class type
     * @return the index of the ClassInfo in the constant pool
     */
    private char classInfo(Class clazz)
    {
      return classInfo(TypeSignature.getEncodingOfClass(clazz.getName(),
                                                        false));
    }

    /**
     * Returns the entry of the appropriate fieldref, methodref, or
     * interfacemethodref info structure in the Constant pool, adding it
     * if necessary.
     *
     * @param structure FIELD, METHOD, or INTERFACE
     * @param clazz the class name, in internal form
     * @param name the simple reference name
     * @param type the type of the reference
     * @return the index of the appropriate Info structure in the constant pool
     */
    private char refInfo(byte structure, String clazz, String name,
                         String type)
    {
      char cindex = classInfo(clazz);
      char ntindex = nameAndTypeInfo(name, type);
      // relies on FIELD == 1, METHOD == 2, INTERFACE == 3
      char[] c = {(char) (structure + 8),
                  (char) (cindex >> 8), (char) (cindex & 0xff),
                  (char) (ntindex >> 8), (char) (ntindex & 0xff)};
      return poolIndex(new String(c));
    }

    /**
     * Returns the entry of the appropriate nameAndTyperef info structure
     * in the Constant pool, adding it if necessary.
     *
     * @param name the simple name
     * @param type the reference type
     * @return the index of the NameAndTypeInfo structure in the constant pool
     */
    private char nameAndTypeInfo(String name, String type)
    {
      char nindex = utf8Info(name);
      char tindex = utf8Info(type);
      char[] c = {12, (char) (nindex >> 8), (char) (nindex & 0xff),
                  (char) (tindex >> 8), (char) (tindex & 0xff)};
      return poolIndex(new String(c));
    }

    /**
     * Converts a regular string to a UTF8 string, where the upper byte
     * of every char is 0, and '\\u0000' is not in the string.  This is
     * basically to use a String as a fancy byte[], and while it is less
     * efficient in memory use, it is easier for hashing.
     *
     * @param str the original, in straight unicode
     * @return a modified string, in UTF8 format in the low bytes
     */
    private String toUtf8(String str)
    {
      final char[] ca = str.toCharArray();
      final int len = ca.length;

      // Avoid object creation, if str is already fits UTF8.
      int i;
      for (i = 0; i < len; i++)
        if (ca[i] == 0 || ca[i] > '\u007f')
          break;
      if (i == len)
        return str;

      final StringBuffer sb = new StringBuffer(str);
      sb.setLength(i);
      for ( ; i < len; i++)
        {
          final char c = ca[i];
          if (c > 0 && c <= '\u007f')
            sb.append(c);
          else if (c <= '\u07ff') // includes '\0'
            {
              sb.append((char) (0xc0 | (c >> 6)));
              sb.append((char) (0x80 | (c & 0x6f)));
            }
          else
            {
              sb.append((char) (0xe0 | (c >> 12)));
              sb.append((char) (0x80 | ((c >> 6) & 0x6f)));
              sb.append((char) (0x80 | (c & 0x6f)));
            }
        }
      return sb.toString();
    }

    /**
     * Returns the location of a byte sequence (conveniently wrapped in
     * a String with all characters between \u0001 and \u00ff inclusive)
     * in the constant pool, adding it if necessary.
     *
     * @param sequence the byte sequence to look for
     * @return the index of the sequence
     * @throws IllegalArgumentException if this would make the constant
     *         pool overflow
     */
    private char poolIndex(String sequence)
    {
      Integer i = (Integer) poolEntries.get(sequence);
      if (i == null)
        {
          // pool starts at index 1
          int size = poolEntries.size() + 1;
          if (size >= 65535)
            throw new IllegalArgumentException("exceeds VM limitations");
          i = new Integer(size);
          poolEntries.put(sequence, i);
          pool.append(sequence);
        }
      return (char) i.intValue();
    }
  } // class ClassFactory
}
