@Test
  public void findingAnnotationsRecursively() {
    Method method = findMethod(this.getClass(), "withMarker", String.class);

    List<Annotation> annotations = allAnnotations(method.getParameters()[0]);

    assertEquals(4, annotations.size());
    assertEquals(X.class, annotations.get(0).annotationType());
    assertEquals(Y.class, annotations.get(1).annotationType());
    assertEquals(Z.class, annotations.get(2).annotationType());
    assertEquals(W.class, annotations.get(3).annotationType());
  }
  @Test
  public void findingAllDeclaredFieldsOnAClassExcludesSynthetics() throws Exception {
    List<Field> fields = allDeclaredFieldsOf(Outer.Inner.class);

    assertEquals(1, fields.size());
    assertThat(fields, hasItem(Outer.Inner.class.getDeclaredField("s")));
  }
  @Test
  public void findingAllDeclaredFieldsOnAClass() throws Exception {
    List<Field> fields = allDeclaredFieldsOf(Child.class);

    assertEquals(2, fields.size());
    assertThat(fields, hasItem(Child.class.getDeclaredField("s")));
    assertThat(fields, hasItem(Parent.class.getDeclaredField("i")));
  }
  @Test
  public void settingFieldWithoutBypassingProtection() throws Exception {
    WithAccessibleField target = new WithAccessibleField();

    setField(target.getClass().getField("i"), target, 2, false);

    assertEquals(2, target.i);
  }
  @Test
  public void settingInaccessibleFieldBypassingProtection() throws Exception {
    WithInaccessibleField target = new WithInaccessibleField();

    setField(target.getClass().getDeclaredField("i"), target, 3, true);

    assertEquals(3, target.i);
  }
  @Test
  public void anInterfaceThatOverloadsEqualsWithMoreThanOneParameterCanBeASingleAbstractMethodType()
      throws Exception {

    assertEquals(
        OverloadingEqualsWithMoreParameters.class.getMethod("equals", Object.class, Object.class),
        singleAbstractMethodOf(OverloadingEqualsWithMoreParameters.class));
  }
  @Test
  public void anInterfaceThatOverloadsEqualsWithMixedParameterTypesIsNotASingleAbstractMethodType()
      throws Exception {

    assertEquals(
        OverloadingEqualsWithMixedParameterTypes.class.getMethod(
            "equals", Object.class, String.class, int.class),
        singleAbstractMethodOf(OverloadingEqualsWithMixedParameterTypes.class));
  }
  @Test
  public void findingSingleAccessibleConstructorSuccessfully() {
    Constructor<Object> ctor = singleAccessibleConstructor(Object.class);

    assertEquals(0, ctor.getParameterTypes().length);
  }
  @Test
  public void findingConstructorQuietly() {
    Constructor<Integer> ctor = findConstructor(Integer.class, int.class);

    assertEquals(int.class, ctor.getParameterTypes()[0]);
  }
 @Test
 public void anInterfaceThatOverloadsToStringCanBeASingleAbstractMethodType() throws Exception {
   assertEquals(
       OverloadingToString.class.getMethod("toString", Object.class),
       singleAbstractMethodOf(OverloadingToString.class));
 }
 @Test
 public void anInterfaceThatOverloadsHashCodeCanBeASingleAbstractMethodType() throws Exception {
   assertEquals(
       OverloadingHashCode.class.getMethod("hashCode", Object.class),
       singleAbstractMethodOf(OverloadingHashCode.class));
 }
 @Test
 public void anInterfaceThatOverloadsEqualsCanBeASingleAbstractMethodType() throws Exception {
   assertEquals(
       OverloadingEquals.class.getMethod("equals", String.class),
       singleAbstractMethodOf(OverloadingEquals.class));
 }
 @Test
 public void anInterfaceWithASingleAbstractMethodIsASingleAbstractMethodType() throws Exception {
   assertEquals(
       Comparator.class.getMethod("compare", Object.class, Object.class),
       singleAbstractMethodOf(Comparator.class));
 }
 @Test
 public void findingDefaultValueOfAnnotationAttribute() throws Exception {
   assertEquals("baz", defaultValueOf(Foo.class, "bar"));
 }