/**
   * Calls all public methods declared in the class corresponding to the given object. Does not
   * include methods from superclasses.
   *
   * @param object object to call the public methods on
   * @param comparator method comparator, allows running the methods in a specific order
   * @return list of methods invoked, including the parameters used for calling them
   */
  private static List<MethodInvocation> callPublicMethodsInOrder(
      Object object, Comparator<Method> comparator) {
    try {
      List<MethodInvocation> invocations = new ArrayList<>();
      Method[] methods = object.getClass().getDeclaredMethods();
      if (comparator != null) Arrays.sort(methods, comparator);

      for (Method method : methods) {
        if (Modifier.isStatic(method.getModifiers()) || !Modifier.isPublic(method.getModifiers()))
          continue;

        Object[] params = new Object[method.getParameterTypes().length];
        for (int i = 0; i < method.getParameterTypes().length; i++) {
          params[i] = instantiateType(method.getParameterTypes()[i]);
        }
        method.invoke(object, params);
        invocations.add(new MethodInvocation(method.getName(), params));
      }
      return invocations;
    } catch (Exception ex) {
      ex.printStackTrace();
      assertTrue(
          "Error calling public methods on object "
              + object
              + " ("
              + object.getClass().getSimpleName()
              + ")",
          false);
      return new ArrayList<>();
    }
  }
 public MethodCallTester<MonitoredClass> assertMethodNotCalled(
     String name, Class<?>... paramTypes) {
   assertFalse(
       "Method "
           + mockClass.getSimpleName()
           + "."
           + name
           + "("
           + Arrays.toString(paramTypes)
           + ") was called but no call was expected",
       wasMethodCalled(name, paramTypes));
   return this;
 }
 public MethodCallTester<MonitoredClass> assertMethodCalled(
     String name, Object... expectedParamValues) {
   assertTrue(
       "Method "
           + mockClass.getSimpleName()
           + "."
           + name
           + "("
           + Arrays.toString(expectedParamValues)
           + ") was not called",
       wasMethodCalled(name, expectedParamValues));
   return this;
 }
 @SuppressWarnings("unused")
 public MethodCallTester<MonitoredClass> assertMethodNotCalled(
     String name, Object... expectedParamValues) {
   assertFalse(
       "Method "
           + mockClass.getSimpleName()
           + "."
           + name
           + "("
           + Arrays.toString(expectedParamValues)
           + ") was called but no call was expected",
       wasMethodCalled(name, expectedParamValues));
   return this;
 }
 @Override
 public int hashCode() {
   int result = method.hashCode();
   result = 31 * result + Arrays.hashCode(params);
   return result;
 }
 /**
  * Check that the two parameter sets are equal
  *
  * @param params1 first parameter set
  * @param params2 second parameter set
  * @return true if the two parameter sets are equal - all the objects' equals() returns true
  */
 private boolean parametersEqual(Object[] params1, Object[] params2) {
   if (params1 == null) params1 = new Object[0];
   if (params2 == null) params2 = new Object[0];
   return Arrays.equals(params1, params2);
 }