@SuppressWarnings({"rawtypes", "unchecked"})
  public void testExceptions() {
    // LuceneTestCase is not a subclass and can never override publicTest(String)
    expectThrows(
        IllegalArgumentException.class,
        () -> {
          // cast to Class to remove generics:
          publicTestMethod.getImplementationDistance((Class) LuceneTestCase.class);
        });

    // Method bogus() does not exist, so IAE should be thrown
    expectThrows(
        IllegalArgumentException.class,
        () -> {
          new VirtualMethod<>(TestVirtualMethod.class, "bogus");
        });

    // Method publicTest(String) is not declared in TestClass2, so IAE should be thrown
    expectThrows(
        IllegalArgumentException.class,
        () -> {
          new VirtualMethod<>(TestClass2.class, "publicTest", String.class);
        });

    // try to create a second instance of the same baseClass / method combination
    expectThrows(
        UnsupportedOperationException.class,
        () -> {
          new VirtualMethod<>(TestVirtualMethod.class, "publicTest", String.class);
        });
  }
  public void testGeneral() {
    assertEquals(0, publicTestMethod.getImplementationDistance(this.getClass()));
    assertEquals(1, publicTestMethod.getImplementationDistance(TestClass1.class));
    assertEquals(1, publicTestMethod.getImplementationDistance(TestClass2.class));
    assertEquals(3, publicTestMethod.getImplementationDistance(TestClass3.class));
    assertFalse(publicTestMethod.isOverriddenAsOf(TestClass4.class));
    assertFalse(publicTestMethod.isOverriddenAsOf(TestClass5.class));

    assertEquals(0, protectedTestMethod.getImplementationDistance(this.getClass()));
    assertEquals(1, protectedTestMethod.getImplementationDistance(TestClass1.class));
    assertEquals(2, protectedTestMethod.getImplementationDistance(TestClass2.class));
    assertEquals(2, protectedTestMethod.getImplementationDistance(TestClass3.class));
    assertFalse(protectedTestMethod.isOverriddenAsOf(TestClass4.class));
    assertFalse(protectedTestMethod.isOverriddenAsOf(TestClass5.class));

    assertTrue(
        VirtualMethod.compareImplementationDistance(
                TestClass3.class, publicTestMethod, protectedTestMethod)
            > 0);
    assertEquals(
        0,
        VirtualMethod.compareImplementationDistance(
            TestClass5.class, publicTestMethod, protectedTestMethod));
  }