gt:         Class<?>[] parameterTypes = new Class[arguments];
context: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.commons.lang3.reflect;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  
  import org.apache.commons.lang3.ArrayUtils;
  import org.apache.commons.lang3.ClassUtils;
  
  /**
   * <p>Utility reflection methods focused on methods, originally from Commons BeanUtils.
   * Differences from the BeanUtils version may be noted, especially where similar functionality
   * already existed within Lang.
   * </p>
   *
   * <h3>Known Limitations</h3>
   * <h4>Accessing Public Methods In A Default Access Superclass</h4>
   * <p>There is an issue when invoking public methods contained in a default access superclass on JREs prior to 1.4.
   * Reflection locates these methods fine and correctly assigns them as public.
   * However, an <code>IllegalAccessException</code> is thrown if the method is invoked.</p>
   *
   * <p><code>MethodUtils</code> contains a workaround for this situation. 
   * It will attempt to call <code>setAccessible</code> on this method.
   * If this call succeeds, then the method can be invoked as normal.
   * This call will only succeed when the application has sufficient security privileges. 
   * If this call fails then the method may fail.</p>
   *
   * @since 2.5
   * @version $Id: MethodUtils.java 1166253 2011-09-07 16:27:42Z ggregory $
   */
  public class MethodUtils {
  
      /**
       * <p>MethodUtils instances should NOT be constructed in standard programming.
       * Instead, the class should be used as
       * <code>MethodUtils.getAccessibleMethod(method)</code>.</p>
       *
       * <p>This constructor is public to permit tools that require a JavaBean
       * instance to operate.</p>
       */
      public MethodUtils() {
          super();
      }
  
      /**
       * <p>Invokes a named method whose parameter type matches the object type.</p>
       *
       * <p>This method delegates the method search to {@link #getMatchingAccessibleMethod(Class, String, Class[])}.</p>
       *
       * <p>This method supports calls to methods taking primitive parameters 
       * via passing in wrapping classes. So, for example, a <code>Boolean</code> object
       * would match a <code>boolean</code> primitive.</p>
       *
       * <p>This is a convenient wrapper for
       * {@link #invokeMethod(Object object,String methodName, Object[] args, Class[] parameterTypes)}.
       * </p>
       *
       * @param object invoke method on this object
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @return The value returned by the invoked method
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the method invoked
       * @throws IllegalAccessException if the requested method is not accessible via reflection
       */
      public static Object invokeMethod(Object object, String methodName,
              Object... args) throws NoSuchMethodException,
              IllegalAccessException, InvocationTargetException {
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }
          int arguments = args.length;
          Class<?>[] parameterTypes = new Class[arguments];
          for (int i = 0; i < arguments; i++) {
              parameterTypes[i] = args[i].getClass();
          }
          return invokeMethod(object, methodName, args, parameterTypes);
      }
  
      /**
       * <p>Invokes a named method whose parameter type matches the object type.</p>
       *
       * <p>This method delegates the method search to {@link #getMatchingAccessibleMethod(Class, String, Class[])}.</p>
       *
       * <p>This method supports calls to methods taking primitive parameters 
       * via passing in wrapping classes. So, for example, a <code>Boolean</code> object
       * would match a <code>boolean</code> primitive.</p>
       *
       * @param object invoke method on this object
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @param parameterTypes match these parameters - treat null as empty array
       * @return The value returned by the invoked method
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the method invoked
       * @throws IllegalAccessException if the requested method is not accessible via reflection
       */
      public static Object invokeMethod(Object object, String methodName,
              Object[] args, Class<?>[] parameterTypes)
              throws NoSuchMethodException, IllegalAccessException,
              InvocationTargetException {
          if (parameterTypes == null) {
              parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
          }
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }
          Method method = getMatchingAccessibleMethod(object.getClass(),
                  methodName, parameterTypes);
          if (method == null) {
              throw new NoSuchMethodException("No such accessible method: "
                      + methodName + "() on object: "
                      + object.getClass().getName());
          }
          return method.invoke(object, args);
      }
  
      /**
       * <p>Invokes a method whose parameter types match exactly the object
       * types.</p>
       *
       * <p>This uses reflection to invoke the method obtained from a call to
       * <code>getAccessibleMethod()</code>.</p>
       *
       * @param object invoke method on this object
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @return The value returned by the invoked method
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeExactMethod(Object object, String methodName,
              Object... args) throws NoSuchMethodException,
              IllegalAccessException, InvocationTargetException {
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }
          int arguments = args.length;
          Class<?>[] parameterTypes = new Class[arguments];
          for (int i = 0; i < arguments; i++) {
              parameterTypes[i] = args[i].getClass();
          }
          return invokeExactMethod(object, methodName, args, parameterTypes);
      }
  
      /**
       * <p>Invokes a method whose parameter types match exactly the parameter
       * types given.</p>
       *
       * <p>This uses reflection to invoke the method obtained from a call to
       * <code>getAccessibleMethod()</code>.</p>
       *
       * @param object invoke method on this object
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @param parameterTypes match these parameters - treat null as empty array
       * @return The value returned by the invoked method
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeExactMethod(Object object, String methodName,
              Object[] args, Class<?>[] parameterTypes)
              throws NoSuchMethodException, IllegalAccessException,
              InvocationTargetException {
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }
          if (parameterTypes == null) {
              parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
          }
          Method method = getAccessibleMethod(object.getClass(), methodName,
                  parameterTypes);
          if (method == null) {
              throw new NoSuchMethodException("No such accessible method: "
                      + methodName + "() on object: "
                      + object.getClass().getName());
          }
          return method.invoke(object, args);
      }
  
      /**
       * <p>Invokes a static method whose parameter types match exactly the parameter
       * types given.</p>
       *
       * <p>This uses reflection to invoke the method obtained from a call to
       * {@link #getAccessibleMethod(Class, String, Class[])}.</p>
       *
       * @param cls invoke static method on this class
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @param parameterTypes match these parameters - treat null as empty array
       * @return The value returned by the invoked method
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeExactStaticMethod(Class<?> cls, String methodName,
              Object[] args, Class<?>[] parameterTypes)
              throws NoSuchMethodException, IllegalAccessException,
              InvocationTargetException {
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }
          if (parameterTypes == null) {
              parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
          }
          Method method = getAccessibleMethod(cls, methodName, parameterTypes);
          if (method == null) {
              throw new NoSuchMethodException("No such accessible method: "
                      + methodName + "() on class: " + cls.getName());
          }
          return method.invoke(null, args);
      }
  
      /**
       * <p>Invokes a named static method whose parameter type matches the object type.</p>
       *
       * <p>This method delegates the method search to {@link #getMatchingAccessibleMethod(Class, String, Class[])}.</p>
       *
       * <p>This method supports calls to methods taking primitive parameters 
       * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
       * would match a <code>boolean</code> primitive.</p>
       *
       * <p>This is a convenient wrapper for
       * {@link #invokeStaticMethod(Class objectClass,String methodName,Object [] args,Class[] parameterTypes)}.
       * </p>
       *
       * @param cls invoke static method on this class
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @return The value returned by the invoked method
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeStaticMethod(Class<?> cls, String methodName,
              Object... args) throws NoSuchMethodException,
              IllegalAccessException, InvocationTargetException {
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }
          int arguments = args.length;
          Class<?>[] parameterTypes = new Class[arguments];
          for (int i = 0; i < arguments; i++) {
              parameterTypes[i] = args[i].getClass();
          }
          return invokeStaticMethod(cls, methodName, args, parameterTypes);
      }
  
      /**
       * <p>Invokes a named static method whose parameter type matches the object type.</p>
       *
       * <p>This method delegates the method search to {@link #getMatchingAccessibleMethod(Class, String, Class[])}.</p>
       *
       * <p>This method supports calls to methods taking primitive parameters 
       * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
       * would match a <code>boolean</code> primitive.</p>
       *
       *
       * @param cls invoke static method on this class
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @param parameterTypes match these parameters - treat null as empty array
       * @return The value returned by the invoked method
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeStaticMethod(Class<?> cls, String methodName,
              Object[] args, Class<?>[] parameterTypes)
              throws NoSuchMethodException, IllegalAccessException,
              InvocationTargetException {
          if (parameterTypes == null) {
              parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
          }
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }
          Method method = getMatchingAccessibleMethod(cls, methodName,
                  parameterTypes);
          if (method == null) {
              throw new NoSuchMethodException("No such accessible method: "
                      + methodName + "() on class: " + cls.getName());
          }
          return method.invoke(null, args);
      }
  
      /**
       * <p>Invokes a static method whose parameter types match exactly the object
       * types.</p>
       *
       * <p>This uses reflection to invoke the method obtained from a call to
       * {@link #getAccessibleMethod(Class, String, Class[])}.</p>
       *
       * @param cls invoke static method on this class
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @return The value returned by the invoked method
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeExactStaticMethod(Class<?> cls, String methodName,
              Object... args) throws NoSuchMethodException,
              IllegalAccessException, InvocationTargetException {
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }
          int arguments = args.length;
  