public void fire(
     DependentSubjectListener subject, Integer event, DependentSubjectListener listener) {
   // update the listener
   boolean incremented = listener.latestRevision < event.intValue();
   listener.latestRevision = event.intValue();
   // make sure the listener's dependencies were notified first
   listener.assertDependenciesSatisfiedRecursively(listener);
   // send the event forward
   if (incremented) {
     listener.increment(0);
   }
 }
  /**
   * Prepare the original diamond-dependency problem, where B depends on A and C depends on both A
   * and B. We need to guarantee that C can read all of its dependencies only when they're in a
   * 'consistent' state, which is when they've received all events from their dependencies, and
   * their dependencies are in a consistent state.
   *
   * <p>A --> B --. This diagram shows A --> B, B --> C and A --> C. | | The only safe notification
   * order of events is | V for B to receive events from A before C receives '-------> C those same
   * events.
   */
  public void testDiamondDependency() {

    SequenceDependenciesEventPublisher publisher = new SequenceDependenciesEventPublisher();
    DependentSubjectListener a = new DependentSubjectListener("A", publisher);
    DependentSubjectListener b = new DependentSubjectListener("B", publisher);
    DependentSubjectListener c = new DependentSubjectListener("C", publisher);

    a.addListener(c);
    a.increment(10);
    assertEquals(10, a.latestRevision);
    assertEquals(0, b.latestRevision);
    assertEquals(10, c.latestRevision);

    c.increment(5);
    assertEquals(10, a.latestRevision);
    assertEquals(0, b.latestRevision);
    assertEquals(15, c.latestRevision);

    b.increment(20);
    assertEquals(10, a.latestRevision);
    assertEquals(20, b.latestRevision);
    assertEquals(15, c.latestRevision);

    b.addListener(c);
    assertEquals(10, a.latestRevision);
    assertEquals(20, b.latestRevision);
    assertEquals(20, c.latestRevision);

    b.increment(2);
    assertEquals(10, a.latestRevision);
    assertEquals(22, b.latestRevision);
    assertEquals(22, c.latestRevision);

    a.increment(15);
    assertEquals(25, a.latestRevision);
    assertEquals(22, b.latestRevision);
    assertEquals(25, c.latestRevision);

    a.addListener(b);
    assertEquals(25, a.latestRevision);
    assertEquals(25, b.latestRevision);
    assertEquals(25, c.latestRevision);

    a.increment(4);
    assertEquals(29, a.latestRevision);
    assertEquals(29, b.latestRevision);
    assertEquals(29, c.latestRevision);
  }