### Question:
ReflectionUtils { public static void invokeMethodsWithAnnotation( final Class<? extends Annotation> annotation, final Object instance, final Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { invokeMethodsWithAnnotations(annotation, null, instance, args); }  static void invokeMethodsWithAnnotation(
            final Class<? extends Annotation> annotation, final Object instance, final Object... args); @SuppressWarnings("unchecked") static void invokeMethodsWithAnnotations(final Class<? extends Annotation> preferredAnnotation,
            final Class<? extends Annotation> alternateAnnotation, final Object instance, final Object... args); static boolean quietlyInvokeMethodsWithAnnotation(final Class<? extends Annotation> annotation, final Object instance, final Object... args); static boolean quietlyInvokeMethodsWithAnnotation(final Class<? extends Annotation> annotation,
            final Object instance, final ComponentLog logger, final Object... args); static boolean quietlyInvokeMethodsWithAnnotations(final Class<? extends Annotation> preferredAnnotation,
            final Class<? extends Annotation> alternateAnnotation, final Object instance, final Object... args); @SuppressWarnings("unchecked") static boolean quietlyInvokeMethodsWithAnnotations(final Class<? extends Annotation> preferredAnnotation,
            final Class<? extends Annotation> alternateAnnotation, final Object instance, final ComponentLog logger,
            final Object... args);  }### Answer:
@Test public void invokeWithBridgePresent() throws Exception { ReflectionUtils.invokeMethodsWithAnnotation(OnStopped.class, new B(), 2); assertEquals(2, this.invocations.size()); assertEquals("B", this.invocations.get(0)); assertEquals("B", this.invocations.get(1)); }
@Test public void ensureParentMethodIsCalled() throws Exception { ReflectionUtils.invokeMethodsWithAnnotation(OnStopped.class, new C(), 4); assertEquals(1, this.invocations.size()); assertEquals("A", this.invocations.get(0)); }
@Test public void ensureOnlyOverridenMethodIsCalled() throws Exception { ReflectionUtils.invokeMethodsWithAnnotation(OnStopped.class, new D(), "String"); assertEquals(1, this.invocations.size()); assertEquals("D", this.invocations.get(0)); }
@Test(expected = IllegalArgumentException.class) public void validateFailureWithWrongArgumentType() throws Exception { ReflectionUtils.invokeMethodsWithAnnotation(OnStopped.class, new B(), "foo"); }
@Test public void ensureSuccessWhenArgumentCountDoesntMatch() throws Exception { ReflectionUtils.invokeMethodsWithAnnotation(OnStopped.class, new B(), 3, "hjk"); assertEquals(2, this.invocations.size()); assertEquals("B", this.invocations.get(0)); assertEquals("B", this.invocations.get(1)); }
@Test public void ensureSuccessWithMultipleArgumentsOfPropperType() throws Exception { ReflectionUtils.invokeMethodsWithAnnotation(OnStopped.class, new E(), 3, "hjk", "hjk".getBytes()); assertEquals(1, this.invocations.size()); assertEquals("E", this.invocations.get(0)); }
@Test(expected = IllegalArgumentException.class) public void validateFailureIfOneOfArgumentsWrongType() throws Exception { ReflectionUtils.invokeMethodsWithAnnotation(OnStopped.class, new E(), 3, "hjk", "hjk"); }
@Test(expected = InvocationTargetException.class) public void validateInvocationFailure() throws Exception { ReflectionUtils.invokeMethodsWithAnnotation(OnStopped.class, new F(), 3); }