/*******************************************************************************
 * Copyright (c) 2005, 2010 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.ArrayList;

import org.eclipse.jpt.utility.internal.iterables.ArrayIterable;

/**
 * Convenience methods related to the <code>java.lang.reflect</code> 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.
 * <p>
 * In most cases, all exceptions are handled and wrapped in
 * {@link java.lang.RuntimeException}s; so these methods should
 * be used when there should be no problems using reflection (i.e.
 * the referenced members are presumably present etc.).
 * <p>
 * There are also a number of methods whose names
 * end with an underscore. These methods declare the expected checked
 * exceptions (e.g. {@link NoSuchMethodException}, {@link NoSuchFieldException}).
 * These methods can be used to probe
 * for methods, fields, etc. that should be present but might not be.
 */
public final class ReflectionTools {

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

	public static final Class<?> VOID_CLASS = void.class;
	public static final Class<java.lang.Void> VOID_WRAPPER_CLASS = java.lang.Void.class;


	// ********** fields **********

	/**
	 * Get a field value, given the containing object and field name.
	 * Return its result.
	 * Useful for accessing private, package, or protected fields.
	 * <p>
	 * <code>Object.getFieldValue(String fieldName)</code>
	 */
	public static Object getFieldValue(Object object, String fieldName) {
		try {
			return getFieldValue_(object, fieldName);
		} catch (NoSuchFieldException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
		} catch (IllegalAccessException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
		}
	}

	/**
	 * Get a field value, given the containing object and field name.
	 * Return its result.
	 * Useful for accessing private, package, or protected fields.
	 * <p>
	 * <code>Object.getFieldValue(String fieldName)</code>
	 */
	public static Object getFieldValue_(Object object, String fieldName)
		throws NoSuchFieldException, IllegalAccessException
	{
		return getField_(object, fieldName).get(object);
	}

	/**
	 * Get a static field value, given the containing class and field name.
	 * Return its result.
	 * Useful for accessing private, package, or protected fields.
	 * <p>
	 * <code>Class.getStaticFieldValue(String fieldName)</code>
	 */
	public static Object getStaticFieldValue(Class<?> javaClass, String fieldName) {
		try {
			return getStaticFieldValue_(javaClass, fieldName);
		} catch (NoSuchFieldException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
		} catch (IllegalAccessException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
		}
	}

	/**
	 * Get a static field value, given the containing class and field name.
	 * Return its result.
	 * Useful for accessing private, package, or protected fields.
	 * <p>
	 * <code>Class.getStaticFieldValue(String fieldName)</code>
	 */
	public static Object getStaticFieldValue_(Class<?> javaClass, String fieldName)
		throws NoSuchFieldException, IllegalAccessException
	{
		return getField_(javaClass, fieldName).get(null);
	}

	/**
	 * Set a field value, given the containing object, field name, and new value.
	 * Useful for accessing private, package, or protected fields.
	 * <p>
	 * <code>Object.setFieldValue(String fieldName, Object value)</code>
	 */
	public static void setFieldValue(Object object, String fieldName, Object value) {
		try {
			setFieldValue_(object, fieldName, value);
		} catch (NoSuchFieldException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
		} catch (IllegalAccessException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
		}
	}

	/**
	 * Set a field value, given the containing object, field name, and new value.
	 * Useful for accessing private, package, or protected fields.
	 * <p>
	 * <code>Object.setFieldValue(String fieldName, Object value)</code>
	 */
	public static void setFieldValue_(Object object, String fieldName, Object value)
		throws NoSuchFieldException, IllegalAccessException
	{
		getField_(object, fieldName).set(object, value);
	}

	/**
	 * Set a static field value, given the containing class, field name, and new value.
	 * Useful for accessing private, package, or protected fields.
	 * <p>
	 * <code>Class.setStaticFieldValue(String fieldName, Object value)</code>
	 */
	public static void setStaticFieldValue(Class<?> javaClass, String fieldName, Object value) {
		try {
			setStaticFieldValue_(javaClass, fieldName, value);
		} catch (NoSuchFieldException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
		} catch (IllegalAccessException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
		}
	}

	/**
	 * Set a static field value, given the containing class, field name, and new value.
	 * Useful for accessing private, package, or protected fields.
	 * <p>
	 * <code>Class.setStaticFieldValue(String fieldName, Object value)</code>
	 */
	public static void setStaticFieldValue_(Class<?> javaClass, String fieldName, Object value)
		throws NoSuchFieldException, IllegalAccessException
	{
		getField_(javaClass, fieldName).set(null, value);
	}

	/**
	 * 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.
	 * Make any private/package/protected field accessible.
	 * <p>
	 * <code>Object.getField(String fieldName)</code>
	 */
	public static Field getField(Object object, String fieldName) {
		try {
			return getField_(object, fieldName);
		} catch (NoSuchFieldException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
		}
	}

	/**
	 * 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.
	 * Make any private/package/protected field accessible.
	 * <p>
	 * <code>Object.getField(String fieldName)</code>
	 */
	public static Field getField_(Object object, String fieldName)
		throws NoSuchFieldException
	{
		return getField_(object.getClass(), fieldName);
	}

	/**
	 * 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.
	 * Make any private/package/protected field accessible.
	 */
	public static Field getField(Class<?> javaClass, String fieldName) {
		try {
			return getField_(javaClass, fieldName);
		} catch (NoSuchFieldException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
		}
	}

	/**
	 * 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.
	 * Make any private/package/protected field accessible.
	 */
	public static Field getField_(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;
			}
			return getField_(superclass, fieldName);  // recurse
		}
		field.setAccessible(true);
		return field;
	}

	/**
	 * Return all the fields for the
	 * specified class, including inherited fields.
	 * Make any private/package/protected fields accessible.
	 * <p>
	 * <code>Class.getAllFields()</code>
	 */
	public static Iterable<Field> getAllFields(Class<?> javaClass) {
		ArrayList<Field> fields = new ArrayList<Field>();
		for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
			addDeclaredFieldsTo(tempClass, fields);
		}
		return fields;
	}

	/*
	 * Add the declared fields for the specified class
	 * to the specified list.
	 */
	private static void addDeclaredFieldsTo(Class<?> javaClass, ArrayList<Field> fields) {
		for (Field field : getDeclaredFields(javaClass)) {
			fields.add(field);
		}
	}

	/**
	 * Return the declared fields for the specified class.
	 * Make any private/package/protected fields accessible.
	 * <p>
	 * <code>Class.getAccessibleDeclaredFields()</code>
	 */
	public static Iterable<Field> getDeclaredFields(Class<?> javaClass) {
		Field[] fields = javaClass.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
		}
		return new ArrayIterable<Field>(fields);
	}


	// ********** methods **********

	/**
	 * Convenience method.
	 * Execute a zero-argument method, given the receiver and method name.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Object.execute(String methodName)</code>
	 */
	public static Object executeMethod(Object receiver, String methodName) {
		return executeMethod(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
	}

	/**
	 * Convenience method.
	 * Execute a one-argument method, given the receiver,
	 * method name, parameter type, and argument.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Object.execute(String methodName, Class<?> parameterType, Object argument)</code>
	 */
	public static Object executeMethod(Object receiver, String methodName, Class<?> parameterType, Object argument) {
		return executeMethod(receiver, methodName, new Class[] {parameterType}, new Object[] {argument});
	}

	/**
	 * Execute a method, given the receiver,
	 * method name, parameter types, and arguments.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Object.execute(String methodName, Class<?>[] parameterTypes, Object[] arguments)</code>
	 */
	public static Object executeMethod(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] arguments) {
		return executeMethod(getMethod(receiver, methodName, parameterTypes), receiver, arguments);
	}

	/**
	 * Execute the specified method, given the receiver and arguments.
	 * Return its result.
	 * Useful for invoking cached methods.
	 */
	public static Object executeMethod(Method method, Object receiver, Object[] arguments) {
		try {
			return method.invoke(receiver, arguments);
		} catch (IllegalAccessException ex) {
			throw new RuntimeException(ex + CR + method, ex);
		} catch (InvocationTargetException ex) {
			throw new RuntimeException(method + CR + ex.getTargetException(), ex);
		}
	}

	/**
	 * Convenience method.
	 * Execute a zero-argument method,
	 * given the receiver and method name.
	 * Return its result.
	 * Throw an exception if the method is not defined.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Object.execute(String methodName)</code>
	 */
	public static Object executeMethod_(Object receiver, String methodName)
		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
	{
		return executeMethod_(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
	}

	/**
	 * Convenience method.
	 * Execute a method, given the receiver,
	 * method name, parameter type, and argument.
	 * Return its result.
	 * Throw an exception if the method is not defined.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Object.execute(String methodName, Class<?> parameterType, Object argument)</code>
	 */
	public static Object executeMethod_(Object receiver, String methodName, Class<?> parameterType, Object argument)
		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
	{
		return executeMethod_(receiver, methodName, new Class[] {parameterType}, new Object[] {argument});
	}

	/**
	 * Execute a method, given the receiver,
	 * method name, parameter types, and arguments.
	 * Return its result.
	 * Throw an exception if the method is not defined.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Object.execute(String methodName, Class<?>[] parameterTypes, Object[] arguments)</code>
	 */
	public static Object executeMethod_(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] arguments)
		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
	{
		return getMethod_(receiver, methodName, parameterTypes).invoke(receiver, arguments);
	}

	/**
	 * 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.
	 * <p>
	 * <code>Class.executeStaticMethod(String methodName)</code>
	 */
	public static Object executeStaticMethod(Class<?> javaClass, String methodName) {
		return executeStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
	}

	/**
	 * Convenience method.
	 * Execute a static method, given the class,
	 * method name, parameter type, and argument.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Class.executeStaticMethod(String methodName, Class<?> parameterType, Object argument)</code>
	 */
	public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterType, Object argument) {
		return executeStaticMethod(javaClass, methodName, new Class[] {parameterType}, new Object[] {argument});
	}

	/**
	 * Execute a static method, given the class,
	 * method name, parameter types, and arguments.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Class.executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] arguments)</code>
	 */
	public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] arguments) {
		try {
			return executeStaticMethod_(javaClass, methodName, parameterTypes, arguments);
		} catch (NoSuchMethodException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
		} catch (IllegalAccessException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
		} catch (InvocationTargetException ex) {
			throw new RuntimeException(buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes) + CR + ex.getTargetException(), ex);
		}
	}

	/**
	 * 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.
	 * <p>
	 * <code>Class.executeStaticMethod(String methodName)</code>
	 */
	public static Object executeStaticMethod_(Class<?> javaClass, String methodName)
		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
	{
		return executeStaticMethod_(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
	}

	/**
	 * Convenience method.
	 * Execute a static method, given the class,
	 * method name, parameter type, and argument.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Class.executeStaticMethod(String methodName, Class<?> parameterType, Object argument)</code>
	 */
	public static Object executeStaticMethod_(Class<?> javaClass, String methodName, Class<?> parameterType, Object argument)
		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
	{
		return executeStaticMethod_(javaClass, methodName, new Class[] {parameterType}, new Object[] {argument});
	}

	/**
	 * Execute a static method, given the class,
	 * method name, parameter types, and arguments.
	 * Return its result.
	 * Useful for invoking private, package, or protected methods.
	 * <p>
	 * <code>Class.executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] arguments)</code>
	 */
	public static Object executeStaticMethod_(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] arguments)
		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
	{
		return getStaticMethod_(javaClass, methodName, parameterTypes).invoke(null, arguments);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod(Class<?> javaClass, String methodName) {
		return getMethod(javaClass, methodName, ZERO_PARAMETER_TYPES);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod_(Class<?> javaClass, String methodName)
		throws NoSuchMethodException
	{
		return getMethod_(javaClass, methodName, ZERO_PARAMETER_TYPES);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod(Class<?> javaClass, String methodName, Class<?> parameterType) {
		return getMethod(javaClass, methodName, new Class[] {parameterType});
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod_(Class<?> javaClass, String methodName, Class<?> parameterType)
		throws NoSuchMethodException
	{
		return getMethod_(javaClass, methodName, new Class[] {parameterType});
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
		try {
			return getMethod_(javaClass, methodName, parameterTypes);
		} catch (NoSuchMethodException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
		}
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod_(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 getMethod_(superclass, methodName, parameterTypes);
		}
		method.setAccessible(true);
		return method;
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod(Object object, String methodName) {
		return getMethod(object.getClass(), methodName);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod_(Object object, String methodName)
		throws NoSuchMethodException
	{
		return getMethod_(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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod(Object object, String methodName, Class<?>[] parameterTypes) {
		return getMethod(object.getClass(), methodName, parameterTypes);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod_(Object object, String methodName, Class<?>[] parameterTypes)
		throws NoSuchMethodException
	{
		return getMethod_(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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod(Object object, String methodName, Class<?> parameterType) {
		return getMethod(object.getClass(), methodName, parameterType);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getMethod_(Object object, String methodName, Class<?> parameterType)
		throws NoSuchMethodException
	{
		return getMethod_(object.getClass(), methodName, parameterType);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getStaticMethod(Class<?> javaClass, String methodName) {
		return getStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterTypes) {
		return getStaticMethod(javaClass, methodName, new Class[] {parameterTypes});
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
		try {
			return getStaticMethod_(javaClass, methodName, parameterTypes);
		} catch (NoSuchMethodException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
		}
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getStaticMethod_(Class<?> javaClass, String methodName)
		throws NoSuchMethodException
	{
		return getStaticMethod_(javaClass, methodName, ZERO_PARAMETER_TYPES);
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getStaticMethod_(Class<?> javaClass, String methodName, Class<?> parameterTypes)
		throws NoSuchMethodException
	{
		return getStaticMethod_(javaClass, methodName, new Class[] {parameterTypes});
	}

	/**
	 * 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.
	 * Make any private/package/protected method accessible.
	 */
	public static Method getStaticMethod_(Class<?> javaClass, String methodName, Class<?>[] parameterTypes)
		throws NoSuchMethodException
	{
		Method method = getMethod_(javaClass, methodName, parameterTypes);
		if (Modifier.isStatic(method.getModifiers())) {
			return method;
		}
		throw new NoSuchMethodException(buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes));
	}

	/**
	 * Return all the methods for the
	 * specified class, including inherited methods.
	 * Make any private/package/protected methods accessible.
	 * <p>
	 * <code>Class.getAllMethods()</code>
	 */
	public static Iterable<Method> getAllMethods(Class<?> javaClass) {
		ArrayList<Method> methods = new ArrayList<Method>();
		for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
			addDeclaredMethodsTo(tempClass, methods);
		}
		return methods;
	}

	/*
	 * Add the declared methods for the specified class
	 * to the specified list.
	 */
	private static void addDeclaredMethodsTo(Class<?> javaClass, ArrayList<Method> methods) {
		for (Method method : getDeclaredMethods(javaClass)) {
			methods.add(method);
		}
	}

	/**
	 * Return the declared methods for the specified class.
	 * Make any private/package/protected methods accessible.
	 * <p>
	 * <code>Class.getAccessibleDeclaredMethods()</code>
	 */
	public static Iterable<Method> getDeclaredMethods(Class<?> javaClass) {
		Method[] methods = javaClass.getDeclaredMethods();
		for (Method method : methods) {
			method.setAccessible(true);
		}
		return new ArrayIterable<Method>(methods);
	}


	// ********** constructors **********

	/**
	 * Return the default (zero-argument) constructor
	 * for the specified class.
	 * Make any private/package/protected constructor accessible.
	 * <p>
	 * <code>Class.getDefaultConstructor()</code>
	 */
	public static <T> Constructor<T> getDefaultConstructor(Class<T> javaClass) {
		return getConstructor(javaClass);
	}

	/**
	 * Convenience method.
	 * Return the default (zero-argument) constructor
	 * for the specified class.
	 * Make any private/package/protected constructor accessible.
	 * <p>
	 * <code>Class.getConstructor()</code>
	 */
	public static <T> Constructor<T> getConstructor(Class<T> javaClass) {
		return getConstructor(javaClass, ZERO_PARAMETER_TYPES);
	}

	/**
	 * Convenience method.
	 * Return the constructor for the specified class
	 * and formal parameter type.
	 * Make any private/package/protected constructor accessible.
	 * <p>
	 * <code>Class.getConstructor(Class<?> parameterType)</code>
	 */
	public static <T> Constructor<T> getConstructor(Class<T> javaClass, Class<?> parameterType) {
		return getConstructor(javaClass, new Class[] {parameterType});
	}

	/**
	 * Return the constructor for the specified class
	 * and formal parameter types.
	 * Make any private/package/protected constructor accessible.
	 * <p>
	 * <code>Class.getConstructor(Class<?>[] parameterTypes)</code>
	 */
	public static <T> Constructor<T> getConstructor(Class<T> javaClass, Class<?>[] parameterTypes) {
		try {
			return getConstructor_(javaClass, parameterTypes);
		} catch (NoSuchMethodException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
		}
	}

	/**
	 * Return the default (zero-argument) constructor
	 * for the specified class.
	 * Make any private/package/protected constructor accessible.
	 * <p>
	 * <code>Class.getDefaultConstructor()</code>
	 */
	public static <T> Constructor<T> getDefaultConstructor_(Class<T> javaClass)
		throws NoSuchMethodException
	{
		return getConstructor_(javaClass);
	}

	/**
	 * Convenience method.
	 * Return the default (zero-argument) constructor
	 * for the specified class.
	 * Make any private/package/protected constructor accessible.
	 * <p>
	 * <code>Class.getConstructor()</code>
	 */
	public static <T> Constructor<T> getConstructor_(Class<T> javaClass)
		throws NoSuchMethodException
	{
		return getConstructor_(javaClass, ZERO_PARAMETER_TYPES);
	}

	/**
	 * Convenience method.
	 * Return the constructor for the specified class
	 * and formal parameter type.
	 * Make any private/package/protected constructor accessible.
	 * <p>
	 * <code>Class.getConstructor(Class<?> parameterType)</code>
	 */
	public static <T> Constructor<T> getConstructor_(Class<T> javaClass, Class<?> parameterType)
		throws NoSuchMethodException
	{
		return getConstructor_(javaClass, new Class[] {parameterType});
	}

	/**
	 * Return the constructor for the specified class
	 * and formal parameter types.
	 * Make any private/package/protected constructor accessible.
	 * <p>
	 * <code>Class.getConstructor(Class<?>[] parameterTypes)</code>
	 */
	public static <T> Constructor<T> getConstructor_(Class<T> javaClass, Class<?>[] parameterTypes)
		throws NoSuchMethodException
	{
		Constructor<T> constructor = javaClass.getDeclaredConstructor(parameterTypes);
		constructor.setAccessible(true);
		return constructor;
	}

	/**
	 * Return the declared constructors for the specified class.
	 * Make any private/package/protected constructors accessible.
	 * <p>
	 * <code>Class.getAccessibleDeclaredConstructors()</code>
	 */
	public static <T> Iterable<Constructor<T>> getDeclaredConstructors(Class<T> javaClass) {
		@SuppressWarnings("unchecked")
		Constructor<T>[] constructors = (Constructor<T>[]) javaClass.getDeclaredConstructors();
		for (Constructor<T> constructor : constructors) {
			constructor.setAccessible(true);
		}
		return new ArrayIterable<Constructor<T>>(constructors);
	}


	// ********** classes **********

	/**
	 * 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 the specified class (without the checked exception).
	 */
	public static Class<?> classForName(String className, boolean initialize, ClassLoader classLoader) {
		try {
			return Class.forName(className, initialize, classLoader);
		} catch (ClassNotFoundException ex) {
			throw new RuntimeException(className, ex);
		}
	}

	/**
	 * 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.
	 * <p>
	 * <code>Class.getArrayDepth()</code>
	 */
	public static int getArrayDepth(Class<?> javaClass) {
		int depth = 0;
		while (javaClass.isArray()) {
			depth++;
			javaClass = javaClass.getComponentType();
		}
		return depth;
	}

	/**
	 * 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.
	 * <p>
	 * <code>Class.getElementType()</code>
	 */
	public static Class<?> getElementType(Class<?> javaClass) {
		while (javaClass.isArray()) {
			javaClass = javaClass.getComponentType();
		}
		return javaClass;
	}

	/**
	 * Return the wrapper class corresponding to the specified
	 * primitive class. Return <code>null</code> if the specified class
	 * is not a primitive class.
	 * <p>
	 * <code>Class.getWrapperClass()</code>
	 */
	public static Class<?> getWrapperClass(Class<?> primitiveClass) {
		for (Primitive primitive : PRIMITIVES) {
			if (primitive.javaClass == primitiveClass) {
				return primitive.wrapperClass;
			}
		}
		return null;
	}

	/**
	 * Return whether the specified class is a primitive wrapper
	 * class (i.e. <code>java.lang.Void</code> or one of the primitive
	 * variable wrapper classes, <code>java.lang.Boolean</code>,
	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.).
	 * <p>
	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
	 * <p>
	 * <code>Class.isPrimitiveWrapper()</code>
	 */
	public static boolean classIsPrimitiveWrapper(Class<?> javaClass) {
		if (javaClass.isArray() || (javaClass.getName().length() > MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH)) {
			return false;  // performance tweak
		}
		for (Primitive primitive : PRIMITIVES) {
			if (javaClass == primitive.wrapperClass) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Return whether the specified class is a "variable" primitive wrapper
	 * class (i.e. <code>java.lang.Boolean</code>,
	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.,
	 * but not <code>java.lang.Void</code>).
	 * <p>
	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
	 * <p>
	 * <code>Class.isVariablePrimitiveWrapper()</code>
	 */
	public static boolean classIsVariablePrimitiveWrapper(Class<?> javaClass) {
		return classIsPrimitiveWrapper(javaClass)
			&& (javaClass != VOID_WRAPPER_CLASS);
	}

	/**
	 * Return whether the specified class is a "variable" primitive
	 * class (i.e. <code>boolean</code>, <code>int</code>,
	 * <code>float</code>, etc., but not <code>void</code>).
	 * <p>
	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
	 * <p>
	 * <code>Class.isVariablePrimitive()</code>
	 */
	public static boolean classIsVariablePrimitive(Class<?> javaClass) {
		return javaClass.isPrimitive() && (javaClass != VOID_CLASS);
	}

	/**
	 * Return the primitive class for the specified primitive class code.
	 * Return <code>null</code> if the specified code
	 * is not a primitive class code.
	 * @see java.lang.Class#getName()
	 */
	public static Class<?> getClassForCode(int classCode) {
		return getClassForCode((char) classCode);
	}

	/**
	 * Return the primitive class for the specified primitive class code.
	 * Return <code>null</code> if the specified code
	 * is not a primitive class code.
	 * @see java.lang.Class#getName()
	 */
	public static Class<?> getClassForCode(char classCode) {
		for (Primitive primitive : PRIMITIVES) {
			if (primitive.code == classCode) {
				return primitive.javaClass;
			}
		}
		return null;
	}

	/**
	 * Return the class code for the specified primitive class.
	 * Return <code>0</code> if the specified class
	 * is not a primitive class.
	 * @see java.lang.Class#getName()
	 */
	public static char getCodeForClass(Class<?> primitiveClass) {
		if (( ! primitiveClass.isArray()) && (primitiveClass.getName().length() <= MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
			for (Primitive primitive : PRIMITIVES) {
				if (primitive.javaClass == primitiveClass) {
					return primitive.code;
				}
			}
		}
		return 0;
	}


	// ********** instantiation **********

	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * using the class's default (zero-argument) constructor.
	 * <p>
	 * <code>Class.newInstance()</code>
	 */
	public static Object newInstance(String className) {
		return newInstance(className, null);
	}

	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter type and argument.
	 * <p>
	 * <code>Class.newInstance(Class<?> parameterType, Object argument)</code>
	 */
	public static Object newInstance(String className, Class<?> parameterType, Object argument) {
		return newInstance(className, parameterType, argument, null);
	}

	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter types and arguments.
	 * <p>
	 * <code>Class.newInstance(Class<?>[] parameterTypes, Object[] arguments)</code>
	 */
	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] arguments) {
		return newInstance(className, parameterTypes, arguments, null);
	}

	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * using the class's default (zero-argument) constructor.
	 * Use the specified class loader to load the class.
	 * <p>
	 * <code>Class.newInstance()</code>
	 */
	public static Object newInstance(String className, ClassLoader classLoader) {
		return newInstance(classForName(className, false, classLoader));
	}

	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter type and argument.
	 * <p>
	 * <code>Class.newInstance(Class<?> parameterType, Object argument)</code>
	 */
	public static Object newInstance(String className, Class<?> parameterType, Object argument, ClassLoader classLoader) {
		return newInstance(classForName(className, false, classLoader), parameterType, argument);
	}

	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter types and arguments.
	 * <p>
	 * <code>Class.newInstance(Class<?>[] parameterTypes, Object[] arguments)</code>
	 */
	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] arguments, ClassLoader classLoader) {
		return newInstance(classForName(className, false, classLoader), parameterTypes, arguments);
	}

	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * using the class's default (zero-argument) constructor.
	 * <p>
	 * <code>Class.newInstance()</code>
	 */
	public static <T> T newInstance(Class<T> javaClass) {
		return newInstance(javaClass, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
	}

	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * given the constructor parameter type and argument.
	 * <p>
	 * <code>Class.newInstance(Class<?> parameterType, Object argument)</code>
	 */
	public static <T> T newInstance(Class<T> javaClass, Class<?> parameterType, Object argument) {
		return newInstance(javaClass, new Class[] {parameterType}, new Object[] {argument});
	}

	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter types and arguments.
	 * <p>
	 * <code>Class.newInstance(Class<?>[] parameterTypes, Object[] arguments)</code>
	 */
	public static <T> T newInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object[] arguments) {
		try {
			return newInstance_(javaClass, parameterTypes, arguments);
		} catch (InstantiationException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
		} catch (IllegalAccessException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
		} catch (InvocationTargetException ex) {
			throw new RuntimeException(buildFullyQualifiedConstructorSignature(javaClass, parameterTypes) + CR + ex.getTargetException(), ex);
		} catch (NoSuchMethodException ex) {
			throw new RuntimeException(ex + CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
		}
	}

	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * using the class's default (zero-argument) constructor.
	 * <p>
	 * <code>Class.newInstance()</code>
	 */
	public static <T> T newInstance_(Class<T> javaClass)
		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
	{
		return newInstance_(javaClass, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
	}

	/**
	 * Convenience method.
	 * Return a new instance of the specified class,
	 * given the constructor parameter type and argument.
	 * <p>
	 * <code>Class.newInstance(Class<?> parameterType, Object argument)</code>
	 */
	public static <T> T newInstance_(Class<T> javaClass, Class<?> parameterType, Object argument)
		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
	{
		return newInstance_(javaClass, new Class[] {parameterType}, new Object[] {argument});
	}

	/**
	 * Return a new instance of the specified class,
	 * given the constructor parameter types and arguments.
	 * <p>
	 * <code>Class.newInstance(Class<?>[] parameterTypes, Object[] arguments)</code>
	 */
	public static <T> T newInstance_(Class<T> javaClass, Class<?>[] parameterTypes, Object[] arguments)
		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
	{
		return getConstructor_(javaClass, parameterTypes).newInstance(arguments);
	}


	// ********** type declarations **********

	/**
	 * Return the class for the specified "type declaration".
	 */
	public static Class<?> getClassForTypeDeclaration(String typeDeclaration) {
		return getClassForTypeDeclaration(typeDeclaration, null);
	}

	/**
	 * Return the class for the specified "type declaration".
	 */
	public static Class<?> getClassForTypeDeclaration_(String typeDeclaration)
		throws ClassNotFoundException
	{
		return getClassForTypeDeclaration_(typeDeclaration, null);
	}

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

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

	private static TypeDeclaration buildTypeDeclaration(String typeDeclaration) {
		typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
		int arrayDepth = getArrayDepthForTypeDeclaration_(typeDeclaration);
		String elementTypeName = getElementTypeNameForTypeDeclaration_(typeDeclaration, arrayDepth);
		return new TypeDeclaration(elementTypeName, arrayDepth);
	}

	/**
	 * Return the array depth for the specified "type declaration"; e.g.<ul>
	 * <li><code>"int[]"</code> returns <code>1</code>
	 * <li><code>"java.lang.String[][][]"</code> returns <code>3</code>
	 * </ul>
	 */
	public static int getArrayDepthForTypeDeclaration(String typeDeclaration) {
		return getArrayDepthForTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration));
	}

	/**
	 * pre-condition: no whitespace in the type declaration.
	 */
	private static int getArrayDepthForTypeDeclaration_(String typeDeclaration) {
		int last = typeDeclaration.length() - 1;
		int depth = 0;
		int close = last;
		while (typeDeclaration.charAt(close) == ']') {
			if (typeDeclaration.charAt(close - 1) == '[') {
				depth++;
			} else {
				throw new IllegalArgumentException("invalid type declaration: " + typeDeclaration); //$NON-NLS-1$
			}
			close = last - (depth * 2);
		}
		return depth;
	}

	/**
	 * Return the element type name for the specified "type declaration"; e.g.<ul>
	 * <li><code>"int[]"</code> returns <code>"int"</code>
	 * <li><code>"java.lang.String[][][]"</code> returns <code>"java.lang.String"</code>
	 * </ul>
	 */
	public static String getElementTypeNameForTypeDeclaration(String typeDeclaration) {
		typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
		return getElementTypeNameForTypeDeclaration_(typeDeclaration, getArrayDepthForTypeDeclaration_(typeDeclaration));
	}

	/**
	 * Return the element type name for the specified "type declaration"; e.g.<ul>
	 * <li><code>"int[]"</code> returns <code>"int"</code>
	 * <li><code>"java.lang.String[][][]"</code> returns <code>"java.lang.String"</code>
	 * </ul>
	 * Useful for clients that have already queried the type declaration's array depth.
	 */
	public static String getElementTypeNameForTypeDeclaration(String typeDeclaration, int arrayDepth) {
		return getElementTypeNameForTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration), arrayDepth);
	}

	/**
	 * pre-condition: no whitespace in the type declaration.
	 */
	private static String getElementTypeNameForTypeDeclaration_(String typeDeclaration, int arrayDepth) {
		return typeDeclaration.substring(0, typeDeclaration.length() - (arrayDepth * 2));
	}

	/**
	 * Return the class for the specified "type declaration".
	 */
	public static Class<?> getClassForTypeDeclaration(String elementTypeName, int arrayDepth) {
		return getClassForTypeDeclaration(elementTypeName, arrayDepth, null);
	}

	/**
	 * Return the class for the specified "type declaration".
	 */
	public static Class<?> getClassForTypeDeclaration_(String elementTypeName, int arrayDepth)
		throws ClassNotFoundException
	{
		return getClassForTypeDeclaration_(elementTypeName, arrayDepth, null);
	}

	/**
	 * Return the class for the specified "type declaration",
	 * using the specified class loader.
	 */
	public static Class<?> getClassForTypeDeclaration(String elementTypeName, int arrayDepth, ClassLoader classLoader) {
		try {
			return getClassForTypeDeclaration_(elementTypeName, arrayDepth, classLoader);
		} catch (ClassNotFoundException ex) {
			throw new RuntimeException(ex);
		}
	}

	/**
	 * 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<?> getClassForTypeDeclaration_(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() <= MAX_PRIMITIVE_CLASS_NAME_LENGTH) {  // performance tweak
			for (Primitive primitive : PRIMITIVES) {
				if (primitive.javaClass.getName().equals(elementTypeName)) {
					pcc = primitive;
					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('[');
		}
		if (pcc == null) {
			ClassName.append(elementTypeName, sb);
		} else {
			sb.append(pcc.code);
		}
		return Class.forName(sb.toString(), false, classLoader);
	}

	/**
	 * Return the class name for the specified "type declaration"; e.g.<ul>
	 * <li><code>"int"</code> returns <code>"int"</code>
	 * <li><code>"int[]"</code> returns <code>"[I"</code>
	 * <li><code>"java.lang.String"</code> returns <code>"java.lang.String"</code>
	 * <li><code>"java.lang.String[][][]"</code> returns <code>"[[[Ljava.lang.String;"</code>
	 * </ul>
	 * @see java.lang.Class#getName()
	 */
	public static String getClassNameForTypeDeclaration(String typeDeclaration) {
		TypeDeclaration td = buildTypeDeclaration(typeDeclaration);
		return getClassNameForTypeDeclaration(td.elementTypeName, td.arrayDepth);
	}

	/**
	 * Return the class name for the specified "type declaration".
	 * @see java.lang.Class#getName()
	 */
	public static String getClassNameForTypeDeclaration(String elementTypeName, int arrayDepth) {
		// non-array
		if (arrayDepth == 0) {
			return elementTypeName;
		}

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

		// look for a primitive first
		Primitive pcc = null;
		if (elementTypeName.length() <= MAX_PRIMITIVE_CLASS_NAME_LENGTH) {  // performance tweak
			for (Primitive primitive : PRIMITIVES) {
				if (primitive.javaClass.getName().equals(elementTypeName)) {
					pcc = primitive;
					break;
				}
			}
		}

		if (pcc == null) {
			ClassName.append(elementTypeName, sb);
		} else {
			sb.append(pcc.code);
		}

		return sb.toString();
	}


	// ********** exception messages **********

	/**
	 * Return a string representation of the specified constructor.
	 */
	private static String buildFullyQualifiedConstructorSignature(Class<?> javaClass, Class<?>[] parameterTypes) {
		return buildFullyQualifiedMethodSignature(javaClass, null, parameterTypes);
	}

	/**
	 * Return a string representation of the specified field.
	 */
	private static String buildFullyQualifiedFieldName(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 buildFullyQualifiedFieldName(Object object, String fieldName) {
		return buildFullyQualifiedFieldName(object.getClass(), fieldName);
	}

	/**
	 * Return a string representation of the specified method.
	 */
	private static String buildFullyQualifiedMethodSignature(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(", "); //$NON-NLS-1$
			}
			sb.append(parameterTypes[max].getName());
		}
		sb.append(')');
		return sb.toString();
	}


	// ********** primitive constants **********

	static final Iterable<Primitive> PRIMITIVES = buildPrimitives();

	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';

	static final int MAX_PRIMITIVE_CLASS_NAME_LENGTH = calculateMaxPrimitiveClassNameLength();
	static final int MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = calculateMaxPrimitiveWrapperClassNameLength();

	private static int calculateMaxPrimitiveClassNameLength() {
		int max = -1;
		for (Primitive primitive : PRIMITIVES) {
			int len = primitive.javaClass.getName().length();
			if (len > max) {
				max = len;
			}
		}
		return max;
	}

	private static int calculateMaxPrimitiveWrapperClassNameLength() {
		int max = -1;
		for (Primitive primitive : PRIMITIVES) {
			int len = primitive.wrapperClass.getName().length();
			if (len > max) {
				max = len;
			}
		}
		return max;
	}

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


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

	static class Primitive {
		final char code;
		final Class<?> javaClass;
		final Class<?> wrapperClass;
		private static final String WRAPPER_CLASS_TYPE_FIELD_NAME = "TYPE"; //$NON-NLS-1$
		// e.g. java.lang.Boolean.TYPE => boolean.class
		Primitive(char code, Class<?> wrapperClass) {
			this.code = code;
			this.wrapperClass = wrapperClass;
			this.javaClass = (Class<?>) getStaticFieldValue(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;
		}
	}


	// ********** suppressed constructor **********

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

}
