/**
   * Make sure that when the listener graph changes during an event, it gets processed only at the
   * conclusion of that event.
   */
  public void testRemovesAndAddsDuringEvent() {
    SequenceDependenciesEventPublisher publisher = new SequenceDependenciesEventPublisher();
    SimpleSubjectListener a = new SimpleSubjectListener("A", publisher);
    SimpleSubjectListener b = new SimpleSubjectListener("B", publisher);
    SimpleSubjectListener c = new SimpleSubjectListener("C", publisher);
    SimpleSubjectListener d = new SimpleSubjectListener("D", publisher);
    a.addListener(b);

    // add c as a listener to b, it shouldn't receive the first event
    b.setRunOnceRunnable(new AddListenerRunnable(b, c));
    a.setValue("Saskatchwan");
    assertEquals(1, b.getReceivedEvents().size());
    assertEquals(0, c.getReceivedEvents().size());

    a.setValue("Tiger-Cats");
    assertEquals(2, b.getReceivedEvents().size());
    assertEquals(1, c.getReceivedEvents().size());

    // remove c as a listener to b, it should still receive the event
    b.setRunOnceRunnable(new RemoveListenerRunnable(b, c));
    a.setValue("Blue Bombers");
    assertEquals(3, b.getReceivedEvents().size());
    assertEquals(2, c.getReceivedEvents().size());
    a.setValue("Stampeders");
    assertEquals(4, b.getReceivedEvents().size());
    assertEquals(2, c.getReceivedEvents().size());

    // add a completely unrelated listener b to do events for c and d
    a.addListener(c);
    b.setRunOnceRunnable(new AddListenerRunnable(c, d));
    a.setValue("Argonauts");
    assertEquals(3, c.getReceivedEvents().size());
    assertEquals(0, d.getReceivedEvents().size());

    a.setValue("Lions");
    assertEquals(4, c.getReceivedEvents().size());
    assertEquals(1, d.getReceivedEvents().size());

    // remove the unrelated listener b to do events for c and d
    b.setRunOnceRunnable(new RemoveListenerRunnable(c, d));
    a.setValue("Eskimos");
    assertEquals(5, c.getReceivedEvents().size());
    assertEquals(2, d.getReceivedEvents().size());

    a.setValue("Alouettes");
    assertEquals(6, c.getReceivedEvents().size());
    assertEquals(2, d.getReceivedEvents().size());
  }