/*******************************************************************************
 * Copyright (c) 2005, 2008 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.internal;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.Stack;

/**
 * Convenience methods related to the java.lang.reflect package.
 * These methods provide shortcuts for manipulating objects via
 * reflection; particularly when dealing with fields and/or methods that
 * are not publicly accessible or are inherited.
 * 
 * In most cases, all the exceptions are handled and
 * wrapped in java.lang.RuntimeExceptions; so these methods should
 * be used when you are confident that you will not having any problems
 * using reflection.
 * 
 * There are also a number of methods whose names
 * begin with "attempt". These methods will throw a NoSuchMethodException
 * or NoSuchFieldException when appropriate, allowing you to probe
 * for methods that should be present but might not.
 */
public final class ClassTools {

	public static final Class<?>[] ZERO_PARAMETER_TYPES = new Class[0];
	public static final Object[] ZERO_PARAMETERS = new Object[0];
	private static final String CR = StringTools.CR;

	public static final char NESTED_CLASS_NAME_SEPARATOR = '$';

	public static final char ARRAY_INDICATOR = '[';
	public static final char TYPE_DECLARATION_ARRAY_OPEN = '[';
	public static final char TYPE_DECLARATION_ARRAY_CLOSE = ']';

	public static final char REFERENCE_CLASS_CODE = 'L';
	public static final char REFERENCE_CLASS_NAME_DELIMITER = ';';
	
	private static Primitive[] PRIMITIVES;  // pseudo-'final' - lazy-initialized
	public static final char BYTE_CODE = 'B';
	public static final char CHAR_CODE = 'C';
	public static final char DOUBLE_CODE = 'D';
	public static final char FLOAT_CODE = 'F';
	public static final char INT_CODE = 'I';
	public static final char LONG_CODE = 'J';
	public static final char SHORT_CODE = 'S';
	public static final char BOOLEAN_CODE = 'Z';
	public static final char VOID_CODE = 'V';
	private static int MAX_PRIMITIVE_CLASS_NAME_LENGTH = -1;  // pseudo-'final' - lazy-initialized
	private static int MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = -1;  // pseudo-'final' - lazy-initialized

	public static final String VOID_CLASS_NAME = void.class.getName();
	public static final String VOID_WRAPPER_CLASS_NAME = java.lang.Void.class.getName();


	/**
	 * Return all the fields for the
	 * specified class, including inherited fields.
	 * Class#allFields()
	 */
	public static Field[] allFields(Class<?> javaClass) {
		Stack<Field> stack = new Stack<Field>();
		for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
			pushDeclaredFields(tempClass, stack);
		}
		Collections.reverse(stack);
		return stack.toArray(new Field[stack.size()]);
	}
	
	/**
	 * Return all the methods for the
	 * specified class, including inherited methods.
	 * Class#allMethods()
	 */
	public static Method[] allMethods(Class<?> javaClass) {
		Stack<Method> stack = new Stack<Method>();
		for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
			pushDeclaredMethods(tempClass, stack);
		}
		Collections.reverse(stack);
		return stack.toArray(new Method[stack.size()]);
	}
	
	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * using the class's default (zero-argument) constructor.
	 * Throw an exception if the default constructor is not defined.
	 * Class#newInstance() throws NoSuchMethodException
	 */
	public static <T> T attemptNewInstance(Class<T> javaClass) throws NoSuchMethodException {
		return attemptNewInstance(javaClass, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
	}
	
	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter types and parameters.
	 * Throw an exception if the constructor is not defined.
	 * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException
	 */
	public static <T> T attemptNewInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException {
		try {
			return constructor(javaClass, parameterTypes).newInstance(parameters);
		} catch (InstantiationException ie) {
			throw new RuntimeException(ie + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), ie);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException(iae + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), iae);
		} catch (InvocationTargetException ite) {
			throw new RuntimeException(fullyQualifiedConstructorSignature(javaClass, parameterTypes) + CR + ite.getTargetException(), ite);
		}
	}
	
	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * given the constructor parameter type and parameter.
	 * Throw an exception if the constructor is not defined.
	 * Class#newInstance(Class<?> parameterType, Object parameter) throws NoSuchMethodException
	 */
	public static <T> T attemptNewInstance(Class<T> javaClass, Class<?> parameterType, Object parameter) throws NoSuchMethodException {
		return attemptNewInstance(javaClass, new Class[] {parameterType}, new Object[] {parameter});
	}
	
	/**
	 * Attempt to get a field value, given the containing object and field name.
	 * Return its result.
	 * Useful for accessing private, package, or protected fields.
	 * Throw an exception if the field is not defined.
	 * Object#getFieldValue(String fieldName) throws NoSuchFieldException
	 */
	public static Object attemptToGetFieldValue(Object object, String fieldName) throws NoSuchFieldException {
		try {
			return field(object, fieldName).get(object);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException(iae + CR + fullyQualifiedFieldName(object, fieldName), iae);
		}
	}
	
	/**
	 * Attempt to get a static field value, given the containing object and field name.
	 * Return its result.
	 * Useful for accessing private, package, or protected fields.
	 * Throw an exception if the field is not defined.
	 * Class#getStaticFieldValue(String fieldName) throws NoSuchFieldException
	 */
	public static Object attemptToGetStaticFieldValue(Class<?> javaClass, String fieldName) throws NoSuchFieldException {
		try {
			return field(javaClass, fieldName).get(null);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException(iae + CR + fullyQualifiedFieldName(javaClass, fieldName), iae);
		}
	}
	
	/**
	 * Convenience method.
	 * Attempt to execute a zero-argument method,
	 * given the receiver and method name.
	 * Return its result.
	 * Throw an exception if the method is not found.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName) throws NoSuchMethodException
	 */
	public static Object attemptToExecuteMethod(Object receiver, String methodName) throws NoSuchMethodException {
		return attemptToExecuteMethod(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
	}
	
	/**
	 * Convenience method.
	 * Attempt to execute a method, given the receiver,
	 * method name, parameter type, and parameter.
	 * Return its result.
	 * Throw an exception if the method is not found.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException
	 */
	public static Object attemptToExecuteMethod(Object receiver, String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException {
		return attemptToExecuteMethod(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter});
	}
	
	/**
	 * Attempt to execute a method, given the receiver,
	 * method name, parameter types, and parameters.
	 * Return its result.
	 * Throw an exception if the method is not found.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException
	 */
	public static Object attemptToExecuteMethod(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException {
		return executeMethod(method(receiver, methodName, parameterTypes), receiver, parameters);
	}
	
	/**
	 * Attempt to execute a method, given the receiver,
	 * method name, parameter types, and parameters.
	 * Return its result.
	 * Throw an exception if the method is not found.
	 * If the executed method throws an exception, rethrow that exception.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException
	 */
	public static Object attemptToExecuteMethodWithException(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) 
		throws Throwable, NoSuchMethodException 
	{
		return executeMethodWithException(method(receiver, methodName, parameterTypes), receiver, parameters);
	}
	
	/**
	 * Convenience method.
	 * Attempt to execute a zero-argument static method,
	 * given the class and method name.
	 * Return its result.
	 * Throw an exception if the method is not found.
	 * Useful for invoking private, package, or protected methods.
	 * Class#executeStaticMethod(String methodName) throws NoSuchMethodException
	 */
	public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName) throws NoSuchMethodException {
		return attemptToExecuteStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
	}
	
	/**
	 * Attempt to execute a static method, given the class,
	 * method name, parameter types, and parameters.
	 * Return its result.
	 * Throw an exception if the method is not found.
	 * Useful for invoking private, package, or protected methods.
	 * Class#executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException
	 */
	public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException {
		return executeStaticMethod(staticMethod(javaClass, methodName, parameterTypes), parameters);
	}
	
	/**
	 * Convenience method.
	 * Attempt to execute a static method, given the class,
	 * method name, parameter type, and parameter.
	 * Return its result.
	 * Throw an exception if the method is not found.
	 * Useful for invoking private, package, or protected methods.
	 * Class#executeStaticMethod(String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException
	 */
	public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException {
		return attemptToExecuteStaticMethod(javaClass, methodName, new Class[] {parameterType}, new Object[] {parameter});
	}
	
	/**
	 * Attempt to set a field value, given the
	 * containing object, field name, and new field value.
	 * Useful for accessing private, package, or protected fields.
	 * Throw an exception if the field is not defined.
	 * Object#setFieldValue(String fieldName, Object fieldValue) throws NoSuchFieldException
	 */
	public static void attemptToSetFieldValue(Object object, String fieldName, Object fieldValue) throws NoSuchFieldException {
		try {
			field(object, fieldName).set(object, fieldValue);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException(iae + CR + fullyQualifiedFieldName(object, fieldName), iae);
		}
	}
	
	/**
	 * Attempt to set a static field value, given the
	 * containing class, field name, and new field value.
	 * Useful for accessing private, package, or protected fields.
	 * Throw an exception if the field is not defined.
	 * Class#setStaticFieldValue(String fieldName, Object fieldValue) throws NoSuchFieldException
	 */
	public static void attemptToSetStaticFieldValue(Class<?> javaClass, String fieldName, Object fieldValue) throws NoSuchFieldException {
		try {
			field(javaClass, fieldName).set(null, fieldValue);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException(iae + CR + fullyQualifiedFieldName(javaClass, fieldName), iae);
		}
	}
	
	/**
	 * Convenience method.
	 * Return the default (zero-argument) constructor
	 * for the specified class.
	 * Set accessible to true, so we can access
	 * private/package/protected constructors.
	 * Class#constructor() throws NoSuchMethodException
	 */
	public static <T> Constructor<T> constructor(Class<T> javaClass) throws NoSuchMethodException {
		return constructor(javaClass, ZERO_PARAMETER_TYPES);
	}
	
	/**
	 * Return the constructor for the specified class
	 * and formal parameter types.
	 * Set accessible to true, so we can access
	 * private/package/protected constructors.
	 * Class#constructor(Class<?>[] parameterTypes) throws NoSuchMethodException
	 */
	public static <T> Constructor<T> constructor(Class<T> javaClass, Class<?>[] parameterTypes) throws NoSuchMethodException {
		Constructor<T> constructor = javaClass.getDeclaredConstructor(parameterTypes);
		constructor.setAccessible(true);
		return constructor;
	}
	
	/**
	 * Convenience method.
	 * Return the constructor for the specified class
	 * and formal parameter type.
	 * Set accessible to true, so we can access
	 * private/package/protected constructors.
	 * Class#constructor(Class<?> parameterType) throws NoSuchMethodException
	 */
	public static <T> Constructor<T> constructor(Class<T> javaClass, Class<?> parameterType) throws NoSuchMethodException {
		return constructor(javaClass, new Class[] {parameterType});
	}
	
	/**
	 * Return the declared fields for the specified class.
	 * Set accessible to true, so we can access
	 * private/package/protected fields.
	 * Class#accessibleDeclaredFields()
	 */
	public static Field[] declaredFields(Class<?> javaClass) {
		Field[] fields = javaClass.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
		}
		return fields;
	}
	
	/**
	 * Return the declared methods for the
	 * specified class.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 * Class#accessibleDeclaredMethods()
	 */
	public static Method[] declaredMethods(Class<?> javaClass) {
		Method[] methods = javaClass.getDeclaredMethods();
		for (Method method : methods) {
			method.setAccessible(true);
		}
		return methods;
	}
	
	/**
	 * Return the default (zero-argument) constructor
	 * for the specified class.
	 * Set accessible to true, so we can access
	 * private/package/protected constructors.
	 * Class#defaultConstructor()
	 */
	public static <T> Constructor<T> defaultConstructor(Class<T> javaClass) throws NoSuchMethodException {
		return constructor(javaClass);
	}
	
	/**
	 * Return a field for the specified class and field name.
	 * If the class does not directly
	 * define the field, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected fields.
	 */
	public static Field field(Class<?> javaClass, String fieldName) throws NoSuchFieldException {
		Field field = null;
		try {
			field = javaClass.getDeclaredField(fieldName);
		} catch (NoSuchFieldException ex) {
			Class<?> superclass = javaClass.getSuperclass();
			if (superclass == null) {
				throw ex;
			}
			// recurse
			return field(superclass, fieldName);
		}
		field.setAccessible(true);
		return field;
	}
	
	/**
	 * Convenience method.
	 * Return a field for the specified object and field name.
	 * If the object's class does not directly
	 * define the field, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected fields.
	 */
	public static Field field(Object object, String fieldName) throws NoSuchFieldException {
		return field(object.getClass(), fieldName);
	}
	
	/*
	 * Return a string representation of the specified constructor.
	 */
	private static String fullyQualifiedConstructorSignature(Class<?> javaClass, Class<?>[] parameterTypes) {
		return fullyQualifiedMethodSignature(javaClass, null, parameterTypes);
	}
	
	/*
	 * Return a string representation of the specified field.
	 */
	private static String fullyQualifiedFieldName(Class<?> javaClass, String fieldName) {
		StringBuilder sb = new StringBuilder(200);
		sb.append(javaClass.getName());
		sb.append('.');
		sb.append(fieldName);
		return sb.toString();
	}
	
	/*
	 * Return a string representation of the specified field.
	 */
	private static String fullyQualifiedFieldName(Object object, String fieldName) {
		return fullyQualifiedFieldName(object.getClass(), fieldName);
	}
	
	/*
	 * Return a string representation of the specified method.
	 */
	private static String fullyQualifiedMethodSignature(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
		StringBuilder sb = new StringBuilder(200);
		sb.append(javaClass.getName());
		// this check allows us to use this code for constructors, where the methodName is null
		if (methodName != null) {
			sb.append('.');
			sb.append(methodName);
		}
		sb.append('(');
		int max = parameterTypes.length - 1;
		if (max != -1) {
			// stop one short of the end of the array
			for (int i = 0; i < max; i++) {
				sb.append(parameterTypes[i].getName());
				sb.append(", ");
			}
			sb.append(parameterTypes[max].getName());
		}
		sb.append(')');
		return sb.toString();
	}
	
	/*
	 * Return a string representation of the specified method.
	 */
	private static String fullyQualifiedMethodSignature(Object receiver, String methodName, Class<?>[] parameterTypes) {
		return fullyQualifiedMethodSignature(receiver.getClass(), methodName, parameterTypes);
	}
	
	/**
	 * Get a field value, given the containing object and field name.
	 * Return its result.
	 * Useful for accessing private, package, or protected fields.
	 * Object#getFieldValue(String fieldName)
	 */
	public static Object fieldValue(Object object, String fieldName) {
		try {
			return attemptToGetFieldValue(object, fieldName);
		} catch (NoSuchFieldException nsfe) {
			throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(object, fieldName), nsfe);
		}
	}
	
	/**
	 * Get a static field value, given the containing class and field name.
	 * Return its result.
	 * Useful for accessing private, package, or protected fields.
	 * Class#getStaticFieldValue(String fieldName)
	 */
	public static Object staticFieldValue(Class<?> javaClass, String fieldName) {
		try {
			return attemptToGetStaticFieldValue(javaClass, fieldName);
		} catch (NoSuchFieldException nsfe) {
			throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(javaClass, fieldName), nsfe);
		}
	}
	
	/**
	 * Convenience method.
	 * Execute a zero-argument method, given the receiver and method name.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName)
	 */
	public static Object executeMethod(Object receiver, String methodName) {
		return executeMethod(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
	}
	
	/**
	 * Execute a method, given the receiver,
	 * method name, parameter types, and parameters.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters)
	 */
	public static Object executeMethod(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) {
		try {
			return attemptToExecuteMethod(receiver, methodName, parameterTypes, parameters);
		} catch (NoSuchMethodException nsme) {
			throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(receiver, methodName, parameterTypes), nsme);
		}
	}
	
	/**
	 * Convenience method.
	 * Execute a one-argument method, given the receiver,
	 * method name, parameter type, and parameter.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName, Class<?> parameterType, Object parameter)
	 */
	public static Object executeMethod(Object receiver, String methodName, Class<?> parameterType, Object parameter) {
		return executeMethod(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter});
	}
	
	/**
	 * Convenience method.
	 * Execute a zero-argument method, given the receiver and method name.
	 * Return its result.
	 * If the method throws an exception, rethrow that exception.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName)
	 */
	public static Object executeMethodWithException(Object receiver, String methodName) 
		throws Throwable
	{
		return executeMethodWithException(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
	}
	
	/**
	 * Convenience method.
	 * Execute a one-argument method, given the receiver,
	 * method name, parameter type, and parameter.
	 * Return its result.
	 * If the method throws an exception, rethrow that exception.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName, Class<?> parameterType, Object parameter)
	 */
	public static Object executeMethodWithException(Object receiver, String methodName, Class<?> parameterType, Object parameter) 
		throws Throwable
	{
		return executeMethodWithException(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter});
	}
	
	/**
	 * Execute a method, given the receiver,
	 * method name, parameter types, and parameters.
	 * Return its result.
	 * If the method throws an exception, rethrow that exception.
	 * Useful for invoking private, package, or protected methods.
	 * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters)
	 */
	public static Object executeMethodWithException(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) 
		throws Throwable
	{
		try {
			return attemptToExecuteMethodWithException(receiver, methodName, parameterTypes, parameters);
		} catch (NoSuchMethodException nsme) {
			throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(receiver, methodName, parameterTypes), nsme);
		}
	}
	
	/**
	 * Execute the specified method with the specified parameters.
	 * Return its result.
	 * Convert exceptions to RuntimeExceptions.
	 */
	public static Object executeMethod(Method method, Object receiver, Object[] parameters) {
		try {
			return method.invoke(receiver, parameters);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException(iae + CR + method, iae);
		} catch (InvocationTargetException ite) {
			throw new RuntimeException(method + CR + ite.getTargetException(), ite);
		}
	}
	
	/**
	 * Execute the specified method with the specified parameters.
	 * Return its result.
	 * If the method throws an exception, rethrow that exception.
	 * Convert all other exceptions to RuntimeExceptions.
	 */
	public static Object executeMethodWithException(Method method, Object receiver, Object[] parameters)
		throws Throwable
	{
		try {
			return method.invoke(receiver, parameters);
		} catch (IllegalAccessException iae) {
			throw new RuntimeException(iae + CR + method, iae);
		} catch (InvocationTargetException ite) {
			Throwable cause = ite.getCause();
			if (cause == null) {
				throw new RuntimeException(method.toString(), ite);
			}
			throw cause;
		}
	}
	
	/**
	 * Convenience method.
	 * Execute a zero-argument static method,
	 * given the class and method name.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * Class#executeStaticMethod(String methodName)
	 */
	public static Object executeStaticMethod(Class<?> javaClass, String methodName) {
		return executeStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
	}
	
	/**
	 * Execute a static method, given the class,
	 * method name, parameter types, and parameters.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * Class#executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] parameters)
	 */
	public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] parameters) {
		try {
			return attemptToExecuteStaticMethod(javaClass, methodName, parameterTypes, parameters);
		} catch (NoSuchMethodException nsme) {
			throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), nsme);
		}
	}
	
	/**
	 * Convenience method.
	 * Execute a static method, given the class,
	 * method name, parameter type, and parameter.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * Class#executeStaticMethod(String methodName, Class<?> parameterType, Object parameter)
	 */
	public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterType, Object parameter) {
		return executeStaticMethod(javaClass, methodName, new Class[] {parameterType}, new Object[] {parameter});
	}
	
	/**
	 * Execute the specified static method with the specified parameters.
	 * Return its result.
	 * Convert exceptions to RuntimeExceptions.
	 */
	public static Object executeStaticMethod(Method method, Object[] parameters) {
		return executeMethod(method, null, parameters);
	}
	
	/**
	 * Convenience method.
	 * Return a zero-argument method for the specified class
	 * and method name. If the class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method method(Class<?> javaClass, String methodName) throws NoSuchMethodException {
		return method(javaClass, methodName, ZERO_PARAMETER_TYPES);
	}
	
	/**
	 * Return a method for the specified class, method name,
	 * and formal parameter types. If the class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method method(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException {
		Method method = null;
		try {
			method = javaClass.getDeclaredMethod(methodName, parameterTypes);
		} catch (NoSuchMethodException ex) {
			Class<?> superclass = javaClass.getSuperclass();
			if (superclass == null) {
				throw ex;
			}
			// recurse
			return method(superclass, methodName, parameterTypes);
		}
		method.setAccessible(true);
		return method;
	}
	
	/**
	 * Convenience method.
	 * Return a method for the specified class, method name,
	 * and formal parameter type. If the class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method method(Class<?> javaClass, String methodName, Class<?> parameterType) throws NoSuchMethodException {
		return method(javaClass, methodName, new Class[] {parameterType});
	}
	
	/**
	 * Convenience method.
	 * Return a zero-argument method for the specified object
	 * and method name. If the object's class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method method(Object object, String methodName) throws NoSuchMethodException {
		return method(object.getClass(), methodName);
	}
	
	/**
	 * Convenience method.
	 * Return a method for the specified object, method name,
	 * and formal parameter types. If the object's class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method method(Object object, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException {
		return method(object.getClass(), methodName, parameterTypes);
	}
	
	/**
	 * Convenience method.
	 * Return a method for the specified object, method name,
	 * and formal parameter type. If the object's class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method method(Object object, String methodName, Class<?> parameterType) throws NoSuchMethodException {
		return method(object.getClass(), methodName, parameterType);
	}
	
	/**
	 * Convenience method.
	 * Return the specified class (without the checked exception).
	 */
	public static Class<?> classForName(String className) {
		try {
			return Class.forName(className);
		} catch (ClassNotFoundException ex) {
			throw new RuntimeException(className, ex);
		}
	}
	
	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * using the class's default (zero-argument) constructor.
	 * Class#newInstance()
	 */
	public static <T> T newInstance(Class<T> javaClass) {
		return newInstance(javaClass, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
	}
	
	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * using the class's default (zero-argument) constructor.
	 * Class#newInstance()
	 */
	public static Object newInstance(String className) throws ClassNotFoundException {
		return newInstance(className, null);
	}
	
	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * using the class's default (zero-argument) constructor.
	 * Class#newInstance()
	 */
	public static Object newInstance(String className, ClassLoader classLoader) throws ClassNotFoundException {
		return newInstance(Class.forName(className, true, classLoader));
	}
	
	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter types and parameters.
	 * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters)
	 */
	public static <T> T newInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object[] parameters) {
		try {
			return attemptNewInstance(javaClass, parameterTypes, parameters);
		} catch (NoSuchMethodException nsme) {
			throw new RuntimeException(nsme + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), nsme);
		}
	}
	
	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter types and parameters.
	 * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters)
	 */
	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] parameters) throws ClassNotFoundException {
		return newInstance(className, parameterTypes, parameters, null);
	}
	
	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter types and parameters.
	 * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters)
	 */
	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] parameters, ClassLoader classLoader) throws ClassNotFoundException {
		return newInstance(Class.forName(className, true, classLoader), parameterTypes, parameters);
	}
	
	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * given the constructor parameter type and parameter.
	 * Class#newInstance(Class<?> parameterType, Object parameter)
	 */
	public static <T> T newInstance(Class<T> javaClass, Class<?> parameterType, Object parameter) {
		return newInstance(javaClass, new Class[] {parameterType}, new Object[] {parameter});
	}
	
	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter type and parameter.
	 * Class#newInstance(Class<?> parameterType, Object parameter)
	 */
	public static Object newInstance(String className, Class<?> parameterType, Object parameter) throws ClassNotFoundException {
		return newInstance(className, parameterType, parameter, null);
	}
	
	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter type and parameter.
	 * Class#newInstance(Class<?> parameterType, Object parameter)
	 */
	public static Object newInstance(String className, Class<?> parameterType, Object parameter, ClassLoader classLoader) throws ClassNotFoundException {
		return newInstance(Class.forName(className, false, classLoader), parameterType, parameter);
	}
	
	/*
	 * Push the declared fields for the specified class
	 * onto the top of the stack.
	 */
	private static void pushDeclaredFields(Class<?> javaClass, Stack<Field> stack) {
		Field[] fields = declaredFields(javaClass);
		for (int i = fields.length; i-- > 0; ) {
			stack.push(fields[i]);
		}
	}
	
	/*
	 * Push the declared methods for the specified class
	 * onto the top of the stack.
	 */
	private static void pushDeclaredMethods(Class<?> javaClass, Stack<Method> stack) {
		Method[] methods = declaredMethods(javaClass);
		for (int i = methods.length; i-- > 0; ) {
			stack.push(methods[i]);
		}
	}
	
	/**
	 * Set a field value, given the containing object, field name, and new field value.
	 * Useful for accessing private, package, or protected fields.
	 * Object#setFieldValue(String fieldName, Object fieldValue)
	 */
	public static void setFieldValue(Object object, String fieldName, Object fieldValue) {
		try {
			attemptToSetFieldValue(object, fieldName, fieldValue);
		} catch (NoSuchFieldException nsfe) {
			throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(object, fieldName), nsfe);
		}
	}
	
	/**
	 * Set a static field value, given the containing class, field name, and new field value.
	 * Useful for accessing private, package, or protected fields.
	 * Class#setStaticFieldValue(String fieldName, Object fieldValue)
	 */
	public static void setStaticFieldValue(Class<?> javaClass, String fieldName, Object fieldValue) {
		try {
			attemptToSetStaticFieldValue(javaClass, fieldName, fieldValue);
		} catch (NoSuchFieldException nsfe) {
			throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(javaClass, fieldName), nsfe);
		}
	}
	
	/**
	 * Return the short name of the object's class.
	 * Class#getShortName()
	 */
	public static String shortClassNameForObject(Object object) {
		return shortNameFor(object.getClass());
	}
	
	/**
	 * Return the short name of the class (e.g. "Object").
	 * Class#getShortName()
	 */
	public static String shortNameForClassNamed(String className) {
		return className.substring(className.lastIndexOf('.') + 1);
	}
	
	/**
	 * Return the short name of the class (e.g. "Object").
	 * Class#getShortName()
	 */
	public static String shortNameFor(Class<?> javaClass) {
		return shortNameForClassNamed(javaClass.getName());
	}
	
	/**
	 * Return the nested name of the object's class.
	 * Class#getNestedName()
	 */
	public static String nestedClassNameForObject(Object object) {
		return nestedNameFor(object.getClass());
	}
	
	/**
	 * Return the nested name of the class (e.g. "Entry").
	 * Class#getNestedName()
	 */
	public static String nestedNameForClassNamed(String className) {
		return className.substring(className.lastIndexOf(NESTED_CLASS_NAME_SEPARATOR) + 1);
	}
	
	/**
	 * Return the nested name of the class (e.g. "Entry").
	 * Class#getNestedName()
	 */
	public static String nestedNameFor(Class<?> javaClass) {
		return nestedNameForClassNamed(javaClass.getName());
	}
	
	/**
	 * Return the "toString()" name of the object's class.
	 */
	public static String toStringClassNameForObject(Object object) {
		return toStringNameFor(object.getClass());
	}
	
	/**
	 * Return the "toString()" name of the class.
	 * "Member" classes will return only the final name:
	 *     "com.foo.bar.TopLevelClass$MemberClass$NestedMemberClass"
	 *         => "NestedMemberClass"
	 * "Local" and "anonymous" classes will still return the embedded '$'s:
	 *     "com.foo.bar.TopLevelClass$1LocalClass"
	 *         => "TopLevelClass$1LocalClass"
	 *     "com.foo.bar.TopLevelClass$1"
	 *         => "TopLevelClass$1"
	 */
	public static String toStringNameForClassNamed(String className) {
		return classNamedIsMember(className) ?
			className.substring(className.lastIndexOf(NESTED_CLASS_NAME_SEPARATOR) + 1)
		:
			className.substring(className.lastIndexOf('.') + 1);
	}
	
	/**
	 * Return the "toString()" name of the class.
	 */
	public static String toStringNameFor(Class<?> javaClass) {
		return toStringNameForClassNamed(javaClass.getName());
	}
	
	/**
	 * Return the package name of the class (e.g. "java.lang").
	 * Class#getPackageName()
	 */
	public static String packageNameFor(Class<?> javaClass) {
		return packageNameForClassNamed(javaClass.getName());
	}
	
	/**
	 * Return the package name of the class (e.g. "java.lang").
	 * Class#getPackageName()
	 */
	public static String packageNameForClassNamed(String className) {
		int lastPeriod = className.lastIndexOf('.');
		if (lastPeriod == -1) {
			return "";
		}
		return className.substring(0, lastPeriod);
	}
	
	/**
	 * Return the short name of the class,
	 * followed by its package name (e.g. "Object (java.lang)").
	 * Class#getShortNameWithPackage()
	 */
	public static String shortNameWithPackage(Class<?> javaClass) {
		StringBuilder sb = new StringBuilder(200);
		sb.append(shortNameFor(javaClass));
		if ( ! javaClass.isPrimitive()) {
			sb.append(" (");
			sb.append(packageNameFor(javaClass));
			sb.append(')');
		}
		return sb.toString();
	}
	
	/**
	 * Convenience method.
	 * Return a zero-argument, static method for the specified class
	 * and method name. If the class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method staticMethod(Class<?> javaClass, String methodName) throws NoSuchMethodException {
		return staticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES);
	}
	
	/**
	 * Return a static method for the specified class, method name,
	 * and formal parameter types. If the class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method staticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException {
		Method method = method(javaClass, methodName, parameterTypes);
		if (Modifier.isStatic(method.getModifiers())) {
			return method;
		}
		throw new NoSuchMethodException(fullyQualifiedMethodSignature(javaClass, methodName, parameterTypes));
	}
	
	/**
	 * Convenience method.
	 * Return a static method for the specified class, method name,
	 * and formal parameter type. If the class does not directly
	 * implement the method, look for it in the class's superclasses.
	 * Set accessible to true, so we can access
	 * private/package/protected methods.
	 */
	public static Method staticMethod(Class<?> javaClass, String methodName, Class<?> parameterTypes) throws NoSuchMethodException {
		return staticMethod(javaClass, methodName, new Class[] {parameterTypes});
	}

	/**
	 * Return whether the specified class can be "declared" in code;
	 * i.e. it is either a "top-level" class or a "member" class, but it
	 * is not an "array" class. This method rolls together all the checks
	 * from the other methods for a bit of a performance tweak.
	 * Class#isDeclarable()
	 */
	public static boolean classNamedIsDeclarable(String className) {
		if (className.charAt(0) == ARRAY_INDICATOR) {
			return false;		// it is an "array" class
		}
		int index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR);
		if (index == -1) {
			return true;		// it is a "top-level" class
		}
		do {
			// the character immediately after each dollar sign cannot be a digit
			index++;
			if (Character.isDigit(className.charAt(index))) {
				return false;
			}
			index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR, index);
		} while (index != -1);
		return true;
	}
	
	/**
	 * Return whether the specified class is a "top-level" class,
	 * as opposed to a "member", "local", or "anonymous" class,
	 * using the standard jdk naming conventions (i.e. the class
	 * name does NOT contain a '$': "TopLevelClass").
	 * Class#isTopLevel()
	 */
	public static boolean classNamedIsTopLevel(String className) {
		if (classNamedIsArray(className)) {
			return false;
		}
		return className.indexOf(NESTED_CLASS_NAME_SEPARATOR) == -1;
	}

	/**
	 * Return whether the specified class is a "member" class,
	 * as opposed to a "top-level", "local", or "anonymous" class,
	 * using the standard jdk naming conventions (i.e. the class
	 * name contains at least one '$' and all the names between
	 * each '$' are legal class names:
	 * "TopLevelClass$MemberClass$NestedMemberClass").
	 * Class#isMember()
	 */
	public static boolean classNamedIsMember(String className) {
		if (classNamedIsArray(className)) {
			return false;
		}
		int index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR);
		if (index == -1) {
			return false;	// it is a "top-level" class
		}
		do {
			// the character immediately after each dollar sign cannot be a digit
			index++;
			if (Character.isDigit(className.charAt(index))) {
				return false;
			}
			index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR, index);
		} while (index != -1);
		return true;
	}

	/**
	 * Return whether the specified class is a "local" class,
	 * as opposed to a "top-level", "member", or "anonymous" class,
	 * using the standard jdk (or Eclipse) naming conventions.
	 * In the jdk, the class name ends with '$nnnXXX' where the '$' is
	 * followed by a series of numeric digits which are followed by the
	 * local class name: "TopLevelClass$1LocalClass".
	 * In Eclipse, the class name ends with '$nnn$XXX' where the '$' is
	 * followed by a series of numeric digits which are separated from
	 * the local class name by another '$': "TopLevelClass$1$LocalClass".
	 * Class#isLocal()
	 */
	public static boolean classNamedIsLocal(String className) {
		if (classNamedIsArray(className)) {
			return false;
		}
		int dollar = className.indexOf(NESTED_CLASS_NAME_SEPARATOR);
		if (dollar == -1) {
			return false;
		}
		if ( ! Character.isDigit(className.charAt(dollar + 1))) {
			return false;
		}
		int len = className.length();
		for (int i = dollar + 2; i < len; i++) {
			if (Character.isJavaIdentifierStart(className.charAt(i))) {
				return true;
			}
		}
		// all the characters past the $ are digits (anonymous)
		return false;
	}

	/**
	 * Return whether the specified class is an "anonymous" class,
	 * as opposed to a "top-level", "member", or "local" class,
	 * using the standard jdk naming conventions (i.e. the class
	 * name ends with '$nnn' where all the characters past the
	 * last '$' are numeric digits: "TopLevelClass$1").
	 * Class#isAnonymous()
	 */
	public static boolean classNamedIsAnonymous(String className) {
		if (classNamedIsArray(className)) {
			return false;
		}
		int dollar = className.indexOf(NESTED_CLASS_NAME_SEPARATOR);
		if (dollar == -1) {
			return false;
		}
		int start = dollar + 1;
		for (int i = className.length(); i-- > start; ) {
			if ( ! Character.isDigit(className.charAt(i))) {
				return false;
			}
		}
		// all the characters past the $ are digits
		return true;
	}

	/**
	 * Return the "array depth" of the specified class.
	 * The depth is the number of dimensions for an array type.
	 * Non-array types have a depth of zero.
	 * Class#getArrayDepth()
	 */
	public static int arrayDepthFor(Class<?> javaClass) {
		int depth = 0;
		while (javaClass.isArray()) {
			depth++;
			javaClass = javaClass.getComponentType();
		}
		return depth;
	}
	
	/**
	 * Return the "array depth" of the specified object.
	 * The depth is the number of dimensions for an array.
	 * Non-arrays have a depth of zero.
	 */
	public static int arrayDepthForObject(Object object) {
		return arrayDepthFor(object.getClass());
	}
	
	/**
	 * Return the "array depth" of the specified class.
	 * The depth is the number of dimensions for an array type.
	 * Non-array types have a depth of zero.
	 * @see java.lang.Class#getName()
	 * Class#getArrayDepth()
	 */
	public static int arrayDepthForClassNamed(String className) {
		int depth = 0;
		while (className.charAt(depth) == ARRAY_INDICATOR) {
			depth++;
		}
		return depth;
	}

	/**
	 * Return whether the specified class is an array type.
	 * @see java.lang.Class#getName()
	 */
	public static boolean classNamedIsArray(String className) {
		return className.charAt(0) == ARRAY_INDICATOR;
	}

	/**
	 * Return the "element type" of the specified class.
	 * The element type is the base type held by an array type.
	 * A non-array type simply returns itself.
	 * Class#getElementType()
	 */
	public static Class<?> elementTypeFor(Class<?> javaClass) {
		while (javaClass.isArray()) {
			javaClass = javaClass.getComponentType();
		}
		return javaClass;
	}

	/**
	 * Return the "element type" of the specified object.
	 * The element type is the base type held by an array.
	 * A non-array simply returns its class.
	 */
	public static Class<?> elementTypeForObject(Object object) {
		return elementTypeFor(object.getClass());
	}

	/**
	 * Return the "element type" of the specified class.
	 * The element type is the base type held by an array type.
	 * Non-array types simply return themselves.
	 * Class#getElementType()
	 */
	public static String elementTypeNameFor(Class<?> javaClass) {
		return elementTypeFor(javaClass).getName();
	}

	/**
	 * Return the "element type" of the specified class.
	 * The element type is the base type held by an array type.
	 * Non-array types simply return themselves.
	 * @see java.lang.Class#getName()
	 * Class#getElementType()
	 */
	public static String elementTypeNameForClassNamed(String className) {
		int depth = arrayDepthForClassNamed(className);
		if (depth == 0) {
			// the name is in the form: "java.lang.Object" or "int"
			return className;
		}
		int last = className.length() - 1;
		if (className.charAt(depth) == REFERENCE_CLASS_CODE) {
			// the name is in the form: "[[[Ljava.lang.Object;"
			return className.substring(depth + 1, last);	// drop the trailing ';'
		}
		// the name is in the form: "[[[I"
		return classNameForCode(className.charAt(last));
	}
	
	/**
	 * Return whether the specified class is a "reference"
	 * class (i.e. neither 'void' nor one of the primitive variable classes,
	 * ['boolean', 'int', 'float', etc.]).
	 * NB: void.class.isPrimitive() == true
	 */
	public static boolean classNamedIsReference(String className) {
		return ! classNamedIsPrimitive(className);
	}

	/**
	 * Return whether the specified class is a primitive
	 * class (i.e. 'void' or one of the primitive variable classes,
	 * ['boolean', 'int', 'float', etc.]).
	 * NB: void.class.isPrimitive() == true
	 */
	public static boolean classNamedIsPrimitive(String className) {
		if (classNamedIsArray(className) || (className.length() > maxPrimitiveClassNameLength())) {
			return false;  // performance tweak
		}
		Primitive[] codes = primitives();
		for (int i = codes.length; i-- > 0; ) {
			if (codes[i].javaClass.getName().equals(className)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Return whether the specified class is a "variable" primitive
	 * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
	 * NB: void.class.isPrimitive() == true
	 */
	public static boolean classNamedIsVariablePrimitive(String className) {
		return classNamedIsPrimitive(className)
			&& ( ! className.equals(VOID_CLASS_NAME));
	}

	/**
	 * Return whether the specified class is a primitive wrapper
	 * class (i.e. 'java.lang.Void' or one of the primitive variable wrapper classes,
	 * ['java.lang.Boolean', 'java.lang.Integer', 'java.lang.Float', etc.]).
	 * NB: void.class.isPrimitive() == true
	 */
	public static boolean classNamedIsPrimitiveWrapperClass(String className) {
		if (classNamedIsArray(className) || (className.length() > maxPrimitiveWrapperClassNameLength())) {
			return false;  // performance tweak
		}
		Primitive[] codes = primitives();
		for (int i = codes.length; i-- > 0; ) {
			if (codes[i].wrapperClass.getName().equals(className)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Return whether the specified class is a "variable" primitive
	 * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
	 * NB: void.class.isPrimitive() == true
	 */
	public static boolean classNamedIsVariablePrimitiveWrapperClass(String className) {
		return classNamedIsPrimitiveWrapperClass(className)
			&& ( ! className.equals(VOID_WRAPPER_CLASS_NAME));
	}

	/**
	 * Return whether the specified class is a primitive wrapper
	 * class (i.e. 'java.lang.Void' or one of the primitive variable wrapper classes,
	 * ['java.lang.Boolean', 'java.lang.Integer', 'java.lang.Float', etc.]).
	 * NB: void.class.isPrimitive() == true
	 */
	public static boolean classIsPrimitiveWrapperClass(Class<?> javaClass) {
		if (javaClass.isArray() || (javaClass.getName().length() > maxPrimitiveWrapperClassNameLength())) {
			return false;  // performance tweak
		}
		Primitive[] codes = primitives();
		for (int i = codes.length; i-- > 0; ) {
			if (codes[i].wrapperClass == javaClass) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Return whether the specified class is a "variable" primitive
	 * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
	 * NB: void.class.isPrimitive() == true
	 */
	public static boolean classIsVariablePrimitiveWrapperClass(Class<?> javaClass) {
		return classIsPrimitiveWrapperClass(javaClass)
			&& (javaClass != java.lang.Void.class);
	}

	/**
	 * Return the class name for the specified class code.
	 * @see java.lang.Class#getName()
	 */
	public static String classNameForCode(char classCode) {
		return classForCode(classCode).getName();
	}
	
	/**
	 * Return the class name for the specified class code.
	 * @see java.lang.Class#getName()
	 */
	public static String classNameForCode(int classCode) {
		return classNameForCode((char) classCode);
	}
	
	/**
	 * Return the class for the specified class code.
	 * @see java.lang.Class#getName()
	 */
	public static Class<?> classForCode(char classCode) {
		Primitive[] codes = primitives();
		for (int i = codes.length; i-- > 0; ) {
			if (codes[i].code == classCode) {
				return codes[i].javaClass;
			}
		}
		throw new IllegalArgumentException(String.valueOf(classCode));
	}

	/**
	 * Return the class for the specified class code.
	 * @see java.lang.Class#getName()
	 */
	public static Class<?> classForCode(int classCode) {
		return classForCode((char) classCode);
	}
	
	/**
	 * Return the class code for the specified class.
	 * @see java.lang.Class#getName()
	 */
	public static char codeForClass(Class<?> javaClass) {
		if (( ! javaClass.isArray()) && (javaClass.getName().length() <= maxPrimitiveClassNameLength())) {
			Primitive[] codes = primitives();
			for (int i = codes.length; i-- > 0; ) {
				if (codes[i].javaClass == javaClass) {
					return codes[i].code;
				}
			}
		}
		throw new IllegalArgumentException(javaClass.getName());		
	}
	
	/**
	 * Return the class code for the specified class.
	 * @see java.lang.Class#getName()
	 */
	public static char codeForClassNamed(String className) {
		if (( ! classNamedIsArray(className)) && (className.length() <= maxPrimitiveClassNameLength())) {
			Primitive[] codes = primitives();
			for (int i = codes.length; i-- > 0; ) {
				if (codes[i].javaClass.getName().equals(className)) {
					return codes[i].code;
				}
			}
		}
		throw new IllegalArgumentException(className);		
	}

	/**
	 * Return the class for the specified "type declaration".
	 */
	public static Class<?> classForTypeDeclaration(String typeDeclaration) throws ClassNotFoundException {
		return classForTypeDeclaration(typeDeclaration, ClassTools.class.getClassLoader());
	}
	
	/**
	 * Return the class for the specified "type declaration",
	 * using the specified class loader.
	 */
	public static Class<?> classForTypeDeclaration(String typeDeclaration, ClassLoader classLoader) throws ClassNotFoundException {
		TypeDeclaration td = typeDeclaration(typeDeclaration);
		return classForTypeDeclaration(td.elementTypeName, td.arrayDepth);
	}

	private static TypeDeclaration typeDeclaration(String typeDeclaration) {
		typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
		int arrayDepth = arrayDepthForTypeDeclaration_(typeDeclaration);
		String elementTypeName = typeDeclaration.substring(0, typeDeclaration.length() - (arrayDepth * 2));
		return new TypeDeclaration(elementTypeName, arrayDepth);
	}

	/**
	 * Return the class for the specified "type declaration".
	 */
	public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth) throws ClassNotFoundException {
		return classForTypeDeclaration(elementTypeName, arrayDepth, null);
	}
	
	/**
	 * Return the class for the specified "type declaration",
	 * using the specified class loader.
	 */
	// see the "Evaluation" of jdk bug 6446627 for a discussion of loading classes
	public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth, ClassLoader classLoader) throws ClassNotFoundException {
		// primitives cannot be loaded via Class#forName(),
		// so check for a primitive class name first
		Primitive pcc = null;
		if (elementTypeName.length() <= maxPrimitiveClassNameLength()) {  // performance tweak
			Primitive[] codes = primitives();
			for (int i = codes.length; i-- > 0; ) {
				if (codes[i].javaClass.getName().equals(elementTypeName)) {
					pcc = codes[i];
					break;
				}
			}
		}

		// non-array
		if (arrayDepth == 0) {
			return (pcc == null) ? Class.forName(elementTypeName, false, classLoader) : pcc.javaClass;
		}

		// array
		StringBuilder sb = new StringBuilder(100);
		for (int i = arrayDepth; i-- > 0; ) {
			sb.append(ARRAY_INDICATOR);
		}
		if (pcc == null) {
			sb.append(REFERENCE_CLASS_CODE);
			sb.append(elementTypeName);
			sb.append(REFERENCE_CLASS_NAME_DELIMITER);
		} else {
			sb.append(pcc.code);
		}
		return Class.forName(sb.toString(), false, classLoader);
	}
	
	/**
	 * Return the class name for the specified "type declaration"; e.g.
	 *     "int[]" -> "[I"
	 * @see java.lang.Class#getName()
	 */
	public static String classNameForTypeDeclaration(String typeDeclaration) {
		TypeDeclaration td = typeDeclaration(typeDeclaration);
		return classNameForTypeDeclaration(td.elementTypeName, td.arrayDepth);
	}

	/**
	 * Return the array depth for the specified "type declaration"; e.g.
	 *     "int[]" -> 1
	 */
	public static int arrayDepthForTypeDeclaration(String typeDeclaration) {
		return arrayDepthForTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration));
	}

	/*
	 * Assume no whitespace in the type declaration.
	 */
	private static int arrayDepthForTypeDeclaration_(String typeDeclaration) {
		int last = typeDeclaration.length() - 1;
		int depth = 0;
		int close = last;
		while (typeDeclaration.charAt(close) == TYPE_DECLARATION_ARRAY_CLOSE) {
			if (typeDeclaration.charAt(close - 1) == TYPE_DECLARATION_ARRAY_OPEN) {
				depth++;
			} else {
				throw new IllegalArgumentException("invalid type declaration: " + typeDeclaration);
			}
			close = last - (depth * 2);
		}
		return depth;
	}
	
	/**
	 * Return the class name for the specified "type declaration".
	 * @see java.lang.Class#getName()
	 */
	public static String classNameForTypeDeclaration(String elementTypeName, int arrayDepth) {
		// non-array
		if (arrayDepth == 0) {
			return elementTypeName;
		}

		if (elementTypeName.equals(VOID_CLASS_NAME)) {
			throw new IllegalArgumentException("'" + VOID_CLASS_NAME + "' must have an array depth of zero: " + arrayDepth + '.');
		}
		// array
		StringBuilder sb = new StringBuilder(100);
		for (int i = arrayDepth; i-- > 0; ) {
			sb.append(ARRAY_INDICATOR);
		}

		// look for a primitive first
		Primitive pcc = null;
		if (elementTypeName.length() <= maxPrimitiveClassNameLength()) {  // performance tweak
			Primitive[] codes = primitives();
			for (int i = codes.length; i-- > 0; ) {
				if (codes[i].javaClass.getName().equals(elementTypeName)) {
					pcc = codes[i];
					break;
				}
			}
		}

		if (pcc == null) {
			sb.append(REFERENCE_CLASS_CODE);
			sb.append(elementTypeName);
			sb.append(REFERENCE_CLASS_NAME_DELIMITER);
		} else {
			sb.append(pcc.code);
		}

		return sb.toString();
	}

	private static int maxPrimitiveClassNameLength() {
		if (MAX_PRIMITIVE_CLASS_NAME_LENGTH == -1) {
			MAX_PRIMITIVE_CLASS_NAME_LENGTH = calculateMaxPrimitiveClassNameLength();
		}
		return MAX_PRIMITIVE_CLASS_NAME_LENGTH;
	}

	private static int calculateMaxPrimitiveClassNameLength() {
		int max = -1;
		Primitive[] codes = primitives();
		for (int i = codes.length; i-- > 0; ) {
			int len = codes[i].javaClass.getName().length();
			if (len > max) {
				max = len;
			}
		}
		return max;
	}

	private static int maxPrimitiveWrapperClassNameLength() {
		if (MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH == -1) {
			MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = calculateMaxPrimitiveWrapperClassNameLength();
		}
		return MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH;
	}

	private static int calculateMaxPrimitiveWrapperClassNameLength() {
		int max = -1;
		Primitive[] codes = primitives();
		for (int i = codes.length; i-- > 0; ) {
			int len = codes[i].wrapperClass.getName().length();
			if (len > max) {
				max = len;
			}
		}
		return max;
	}

	private static Primitive[] primitives() {
		if (PRIMITIVES == null) {
			PRIMITIVES = buildPrimitives();
		}
		return PRIMITIVES;
	}
	
	/**
	 * NB: void.class.isPrimitive() == true
	 */
	private static Primitive[] buildPrimitives() {
		Primitive[] result = new Primitive[9];
		result[0] = new Primitive(BYTE_CODE, java.lang.Byte.class);
		result[1] = new Primitive(CHAR_CODE, java.lang.Character.class);
		result[2] = new Primitive(DOUBLE_CODE, java.lang.Double.class);
		result[3] = new Primitive(FLOAT_CODE, java.lang.Float.class);
		result[4] = new Primitive(INT_CODE, java.lang.Integer.class);
		result[5] = new Primitive(LONG_CODE, java.lang.Long.class);
		result[6] = new Primitive(SHORT_CODE, java.lang.Short.class);
		result[7] = new Primitive(BOOLEAN_CODE, java.lang.Boolean.class);
		result[8] = new Primitive(VOID_CODE, java.lang.Void.class);
		return result;
	}

	/**
	 * Suppress default constructor, ensuring non-instantiability.
	 */
	private ClassTools() {
		super();
		throw new UnsupportedOperationException();
	}


	// ********** member classes **********

	private static class Primitive {
		final char code;
		final Class<?> javaClass;
		final Class<?> wrapperClass;
		private static final String WRAPPER_CLASS_TYPE_FIELD_NAME = "TYPE";
		// e.g. java.lang.Boolean.TYPE => boolean.class
		Primitive(char code, Class<?> wrapperClass) {
			this.code = code;
			this.wrapperClass = wrapperClass;
			this.javaClass = (Class<?>) staticFieldValue(wrapperClass, WRAPPER_CLASS_TYPE_FIELD_NAME);
		}
	}

	private static class TypeDeclaration {
		final String elementTypeName;
		final int arrayDepth;
		TypeDeclaration(String elementTypeName, int arrayDepth) {
			this.elementTypeName = elementTypeName;
			this.arrayDepth = arrayDepth;
		}
	}

}
