@Test
  public void events_are_collected() {

    // given:

    Predicate<Integer> filter = Mockito.mock(UberClasses.cast(Predicate.class));
    EventHandler<Integer> filterEH = Mockito.mock(UberClasses.cast(EventHandler.class));

    Mockito.when(filter.test(Matchers.any())).thenReturn(true);
    Mockito.when(filterEH.test(Matchers.any())).thenReturn(true);

    Mockito.when(filter.test(200)).thenReturn(false);

    EventCollector<Listener, Integer> collector = createCollector(filter, filterEH);
    Listener target = collector.getTarget();

    // when:

    target.event(100);
    target.event(200);
    target.event(300);

    // then:

    Mockito.verify(filter, Mockito.times(3)).test(Matchers.any());
    Mockito.verify(filterEH, Mockito.times(3)).test(Matchers.any());

    // and:

    List<Integer> events = collector.getEvents();
    Assert.assertThat(events, contains(100, 300));
    Assert.assertThat(collector.getLastEvent(), equalTo(300));
  }
  @Test
  @SuppressWarnings("unchecked")
  public void eventCombiner_capture_two_arguments() {

    // given:

    EventCombiner<Listener, Tuple2<Integer, String>> combiner =
        EventCombiner.create(Listener::event2);

    Predicate<Tuple2<Integer, String>> filter = Mockito.mock(UberClasses.cast(Predicate.class));

    Mockito.when(filter.test(tuple2(42, "qwe"))).thenReturn(true);
    Mockito.when(filter.test(tuple2(12, "rty"))).thenReturn(false);

    EventCollector<Listener, Tuple2<Integer, String>> collector =
        EventCollector.create(Listener.class, combiner, filter);
    Listener target = collector.getTarget();

    // when

    target.event2(42, "qwe");
    target.event2(12, "rty");
    target.event(100);

    // then

    InOrder order = Mockito.inOrder(filter);
    order.verify(filter, Mockito.times(1)).test(tuple2(42, "qwe"));
    order.verify(filter, Mockito.times(1)).test(tuple2(12, "rty"));
    order.verifyNoMoreInteractions();

    // and:

    List<Tuple2<Integer, String>> events = collector.getEvents();
    Assert.assertThat(events, contains(tuple2(42, "qwe")));
    Assert.assertThat(collector.getLastEvent(), equalTo(tuple2(42, "qwe")));
  }
  @Test
  public void eventCombiner_capture_selective() {

    // given:

    EventCombiner<Listener, String> combiner =
        EventCombiner.forCaptor((l, c) -> l.event2(Matchers.any(), c.capture()));

    Predicate<String> filter = Mockito.mock(UberClasses.cast(Predicate.class));

    Mockito.when(filter.test("qwe")).thenReturn(true);
    Mockito.when(filter.test("rty")).thenReturn(false);

    EventCollector<Listener, String> collector =
        EventCollector.create(Listener.class, combiner, filter);
    Listener target = collector.getTarget();

    // when

    target.event2(42, "qwe");
    target.event2(12, "rty");
    target.event(100);

    // then

    InOrder order = Mockito.inOrder(filter);
    order.verify(filter, Mockito.times(1)).test("qwe");
    order.verify(filter, Mockito.times(1)).test("rty");
    order.verifyNoMoreInteractions();

    // and:

    List<String> events = collector.getEvents();
    Assert.assertThat(events, contains("qwe"));
    Assert.assertThat(collector.getLastEvent(), equalTo("qwe"));
  }