@Override
  public void broadcastOnIssueChange(List<DefaultIssue> issues, Collection<QGChangeEvent> changeEvents, boolean fromAlm) {
    if (listeners.isEmpty() || issues.isEmpty() || changeEvents.isEmpty()) {
      return;
    }

    try {
      broadcastChangeEventsToBranches(issues, changeEvents, fromAlm);
    } catch (Error e) {
      LOG.warn(format("Broadcasting to listeners failed for %s events", changeEvents.size()), e);
    }
  }
@Test
  public void broadcastOnIssueChange_calls_listener_for_each_component_uuid_with_at_least_one_QGChangeEvent() {
    // branch has multiple issues
    BranchDto component2 = newBranchDto(project1Uuid + "2");
    DefaultIssue[] component2Issues = {newDefaultIssue(component2.getUuid()), newDefaultIssue(component2.getUuid())};
    QGChangeEvent component2QGChangeEvent = newQGChangeEvent(component2);

    // branch 3 has multiple QGChangeEvent and only one issue
    BranchDto component3 = newBranchDto(project1Uuid + "3");
    DefaultIssue component3Issue = newDefaultIssue(component3.getUuid());
    QGChangeEvent[] component3QGChangeEvents = {newQGChangeEvent(component3), newQGChangeEvent(component3)};

    // branch 4 has multiple QGChangeEvent and multiples issues
    BranchDto component4 = newBranchDto(project1Uuid + "4");
    DefaultIssue[] component4Issues = {newDefaultIssue(component4.getUuid()), newDefaultIssue(component4.getUuid())};
    QGChangeEvent[] component4QGChangeEvents = {newQGChangeEvent(component4), newQGChangeEvent(component4)};

    // branch 5 has no QGChangeEvent but one issue
    BranchDto component5 = newBranchDto(project1Uuid + "5");
    DefaultIssue component5Issue = newDefaultIssue(component5.getUuid());

    List<DefaultIssue> issues = Stream.of(
      Stream.of(component1Issue),
      Arrays.stream(component2Issues),
      Stream.of(component3Issue),
      Arrays.stream(component4Issues),
      Stream.of(component5Issue))
      .flatMap(s -> s)
      .toList();

    List<DefaultIssue> changedIssues = randomizedList(issues);
    List<QGChangeEvent> qgChangeEvents = Stream.of(
      Stream.of(component1QGChangeEvent),
      Stream.of(component2QGChangeEvent),
      Arrays.stream(component3QGChangeEvents),
      Arrays.stream(component4QGChangeEvents))
      .flatMap(s -> s)
      .toList();

    underTest.broadcastOnIssueChange(changedIssues, randomizedList(qgChangeEvents), false);

    listeners.forEach(listener -> {
      verifyListenerCalled(listener, component1QGChangeEvent, component1Issue);
      verifyListenerCalled(listener, component2QGChangeEvent, component2Issues);
      Arrays.stream(component3QGChangeEvents)
        .forEach(component3QGChangeEvent -> verifyListenerCalled(listener, component3QGChangeEvent, component3Issue));
      Arrays.stream(component4QGChangeEvents)
        .forEach(component4QGChangeEvent -> verifyListenerCalled(listener, component4QGChangeEvent, component4Issues));
    });
    verifyNoMoreInteractions(listener1, listener2, listener3);
  }