private void assertEQ(T t, Object returned) {
   if (rtype.isArray()) {
     Asserts.assertEQ(t.getClass(), returned.getClass());
     int n = Array.getLength(t);
     Asserts.assertEQ(n, Array.getLength(returned));
     for (int i = 0; i < n; ++i) {
       Asserts.assertEQ(Array.get(t, i), Array.get(returned, i));
     }
   } else {
     Asserts.assertEQ(t, returned);
   }
 }
 public void assertCatch(Throwable ex) {
   try {
     Asserts.assertSame(thrown, ex, "must get the out-of-band exception");
   } catch (Throwable t) {
     ex.printStackTrace();
   }
 }
  private void runTest() {
    Helper.clear();

    Object[] args = Helper.randomArgs(argsCount, thrower.type().parameterArray());
    Object arg0 = Helper.MISSING_ARG;
    Object arg1 = testCase.thrown;
    if (argsCount > 0) {
      arg0 = args[0];
    }
    if (argsCount > 1) {
      args[1] = arg1;
    }
    Asserts.assertEQ(nargs, thrower.type().parameterCount());
    if (argsCount < nargs) {
      Object[] appendArgs = {arg0, arg1};
      appendArgs = Arrays.copyOfRange(appendArgs, argsCount, nargs);
      thrower = MethodHandles.insertArguments(thrower, argsCount, appendArgs);
    }
    Asserts.assertEQ(argsCount, thrower.type().parameterCount());

    MethodHandle target =
        MethodHandles.catchException(
            testCase.filter(thrower), testCase.throwableClass, testCase.filter(catcher));

    Asserts.assertEQ(thrower.type(), target.type());
    Asserts.assertEQ(argsCount, target.type().parameterCount());

    Object returned;
    try {
      returned = target.invokeWithArguments(args);
    } catch (Throwable ex) {
      testCase.assertCatch(ex);
      returned = ex;
    }

    testCase.assertReturn(returned, arg0, arg1, dropped, args);
  }
  public void assertReturn(
      Object returned, Object arg0, Object arg1, int catchDrops, Object... args) {
    int lag = 0;
    if (throwMode == ThrowMode.CAUGHT) {
      lag = 1;
    }
    Helper.assertCalled(lag, callName(), arg0, arg1);

    if (throwMode == ThrowMode.NOTHING) {
      assertEQ(cast.apply(arg0), returned);
    } else if (throwMode == ThrowMode.CAUGHT) {
      List<Object> catchArgs = new ArrayList<>(Arrays.asList(args));
      // catcher receives an initial subsequence of target arguments:
      catchArgs.subList(args.length - catchDrops, args.length).clear();
      // catcher also receives the exception, prepended:
      catchArgs.add(0, thrown);
      Helper.assertCalled("catcher", catchArgs);
      assertEQ(cast.apply(catchArgs), returned);
    }
    Asserts.assertEQ(0, fakeIdentityCount);
  }