/* Proxy.java -- build a proxy class that implements reflected interfaces
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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 gnu.java.lang.CPStringBuilder;

import gnu.java.lang.reflect.TypeSignature;

import java.io.Serializable;
import java.security.ProtectionDomain;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 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(Class)} 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 #newProxyInstance(ClassLoader, Class[], InvocationHandler)}
 *      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.5, 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.
   *
   * <p>There are several restrictions on this method, the violation of
   * which will result in an IllegalArgumentException or
   * NullPointerException:</p>
   * 
   * <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.</p>
   *
   * @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 (VMProxy.HAVE_NATIVE_GET_PROXY_CLASS)
          clazz = VMProxy.getProxyClass(loader, interfaces);
        else
          {
            ProxyData data = (VMProxy.HAVE_NATIVE_GET_PROXY_DATA
                              ? VMProxy.getProxyData(loader, interfaces)
                              : ProxyData.getProxyData(pt));

            clazz = (VMProxy.HAVE_NATIVE_GENERATE_PROXY_CLASS
		     ? VMProxy.generateProxyClass(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;
  }

  /**
   * 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)
    {
      this.loader = loader;
      this.interfaces = interfaces;
    }

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

    /**
     * Calculates equality.
     *
     * @param other 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;
      for (int i = 0; i < interfaces.length; i++)
        if (interfaces[i] != pt.interfaces[i])
          return false;
      return true;
    }
  } // 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"));
          coreMethods.put(sig, sig);
          sig = new ProxySignature(Object.class.getMethod("toString"));
          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 other 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)
   */
  static final class ProxyData
  {
    /**
     * The package this class is in <b>including the trailing dot</b>
     * or an empty string for the unnamed (aka default) 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;

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

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

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

    /**
     * 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)
            {
              if (isCoreObjectMethod(methods[j]))
                {
                  // In the case of an attempt to redefine a public non-final
                  // method of Object, we must skip it
                  continue;
                }
              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;
    }

    /**
     * Checks whether the method is similar to a public non-final method of
     * Object or not (i.e. with the same name and parameter types). Note that we
     * can't rely, directly or indirectly (via Collection.contains) on
     * Method.equals as it would also check the declaring class, what we do not
     * want. We only want to check that the given method have the same signature
     * as a core method (same name and parameter types)
     * 
     * @param method the method to check
     * @return whether the method has the same name and parameter types as
     *         Object.equals, Object.hashCode or Object.toString
     * @see java.lang.Object#equals(Object)
     * @see java.lang.Object#hashCode()
     * @see java.lang.Object#toString()
     */
    private static boolean isCoreObjectMethod(Method method)
    {
      String methodName = method.getName();
      if (methodName.equals("equals"))
        {
          return Arrays.equals(method.getParameterTypes(),
                               new Class[] { Object.class });
        }
      if (methodName.equals("hashCode"))
        {
          return method.getParameterTypes().length == 0;
        }
      if (methodName.equals("toString"))
        {
          return method.getParameterTypes().length == 0;
        }
      return false;
    }
    
  } // 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 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 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 + "$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;
      CPStringBuilder signature = new CPStringBuilder("(");
      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
     */
    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
        {
          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);
          // We can bypass the security check of setAccessible(true), since
	  // we're in the same package.
          m.flag = true;

          Object[] args = {loader, qualName, bytecode, Integer.valueOf(0),
                           Integer.valueOf(bytecode.length),
                           Object.class.getProtectionDomain() };
          Class clazz = (Class) m.invoke(null, args);

          // Finally, initialize the m field of the proxy class, before
          // returning it.
          Field f = clazz.getDeclaredField("m");
          f.flag = true;
          // we can share the array, because it is not publicized
          f.set(null, methods);

          return clazz;
        }
      catch (Exception 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 CPStringBuilder sb = new CPStringBuilder(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 = Integer.valueOf(size);
          poolEntries.put(sequence, i);
          pool.append(sequence);
        }
      return (char) i.intValue();
    }
  } // class ClassFactory
}
