/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.springframework.util.ClassUtils;

import com.opengamma.OpenGammaRuntimeException;

/**
 * Utility to provide reflection helpers.
 * <p>
 * This is a thread-safe static utility class.
 */
public final class ReflectionUtils {

  /**
   * Restricted constructor.
   */
  private ReflectionUtils() {
  }

  //-------------------------------------------------------------------------
  /**
   * Loads a Class from a full class name.
   * <p>
   * This uses Spring's {@link ClassUtils#forName(String, ClassLoader)} passing null
   * for the class loader.
   * 
   * @param <T> the auto-cast class
   * @param className  the class name, not null
   * @return the class, not null
   * @throws RuntimeException if the class cannot be loaded
   */
  @SuppressWarnings("unchecked")
  public static <T> Class<T> loadClass(final String className) {
    try {
      return (Class<T>) ClassUtils.forName(className, null);
    } catch (ClassNotFoundException ex) {
      throw new OpenGammaRuntimeException(ex.getMessage(), ex);
    }
  }

  /**
   * Loads a Class from a full class name with a fallback class loader.
   * <p>
   * This uses Spring's {@link ClassUtils#forName(String, ClassLoader)} passing null
   * for the class loader. If that fails, it calls the same method with the class loader
   * 
   * @param <T> the auto-cast class
   * @param className  the class name, not null
   * @param fallbackClassLoader  a suitable class loader, may be null
   * @return the class, not null
   * @throws RuntimeException if the class cannot be loaded
   */
  @SuppressWarnings("unchecked")
  public static <T> Class<T> loadClassWithFallbackLoader(final String className, final ClassLoader fallbackClassLoader) {
    try {
      return (Class<T>) ClassUtils.forName(className, null);
    } catch (ClassNotFoundException ex) {
      try {
        return (Class<T>) ClassUtils.forName(className, fallbackClassLoader);
      } catch (ClassNotFoundException ex2) {
        throw new OpenGammaRuntimeException(ex.getMessage(), ex2);
      }
    }
  }

  //-------------------------------------------------------------------------
  /**
   * Finds a constructor from a Class.
   * 
   * @param <T> the type
   * @param type  the type to create, not null
   * @param paramTypes  the parameter types, not null
   * @return the constructor, not null
   * @throws RuntimeException if the class cannot be loaded
   */
  public static <T> Constructor<T> findConstructor(final Class<T> type, final Class<?>... paramTypes) {
    try {
      return type.getConstructor(paramTypes);
    } catch (NoSuchMethodException ex) {
      throw new OpenGammaRuntimeException(ex.getMessage(), ex);
    }
  }

  //-------------------------------------------------------------------------
  /**
   * Creates an instance of a class from a constructor..
   * 
   * @param <T> the type
   * @param constructor  the constructor to call, not null
   * @param args  the arguments, not null
   * @return the constructor, not null
   * @throws RuntimeException if the class cannot be loaded
   */
  public static <T> T newInstance(final Constructor<T> constructor, final Object... args) {
    try {
      return constructor.newInstance(args);
    } catch (InstantiationException ex) {
      throw new OpenGammaRuntimeException(ex.getMessage(), ex);
    } catch (IllegalAccessException ex) {
      throw new OpenGammaRuntimeException(ex.getMessage(), ex);
    } catch (InvocationTargetException ex) {
      if (ex.getCause() instanceof RuntimeException) {
        throw (RuntimeException) ex.getCause();
      }
      throw new OpenGammaRuntimeException(ex.getMessage(), ex);
    }
  }

}

@@ -249,16 +249,91 @@
 ception;
+%0Aimport java.util.Arrays;%0Aimport java.util.Iterator;%0Aimport java.util.List;
 %0A%0Aimport
@@ -2362,32 +2362,1284 @@
    %7D%0A    %7D%0A  %7D%0A%0A
+  //-------------------------------------------------------------------------%0A  /**%0A   * Finds a constructor from a Class.%0A   * %0A   * @param %3CT%3E the type%0A   * @param type  the type to create, not null%0A   * @param arguments  the arguments, not null%0A   * @return the constructor, not null%0A   * @throws RuntimeException if the class cannot be loaded%0A   */%0A  @SuppressWarnings(%22unchecked%22)%0A  public static %3CT%3E Constructor%3CT%3E findConstructorByArguments(final Class%3CT%3E type, final Object... arguments) %7B%0A    Class%3C?%3E%5B%5D paramTypes = new Class%3C?%3E%5Barguments.length%5D;%0A    for (int i = 0; i %3C arguments.length; i++) %7B%0A      paramTypes%5Bi%5D = (arguments%5Bi%5D != null ? arguments%5Bi%5D.getClass() : null);%0A    %7D%0A    List%3CConstructor%3C?%3E%3E constructors = Arrays.asList(type.getConstructors());%0A    for (Iterator%3CConstructor%3C?%3E%3E it = constructors.iterator(); it.hasNext(); ) %7B%0A      Constructor%3C?%3E constructor = (Constructor%3C?%3E) it.next();%0A      if (org.apache.commons.lang.ClassUtils.isAssignable(paramTypes, constructor.getParameterTypes()) == false) %7B%0A        it.remove();%0A      %7D%0A    %7D%0A    if (constructors.size() != 1) %7B%0A      throw new OpenGammaRuntimeException(%22Unable to match single constructor: %22 + type);%0A    %7D%0A    return (Constructor%3CT%3E) constructors.get(0);%0A  %7D%0A%0A
   //------------

Add reflection helper to match best constructor