@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_stops_calling_listeners_when_one_throws_an_ERROR() {
    doThrow(new Error("Faking an error thrown by a listener"))
      .when(listener2)
      .onIssueChanges(any(), any());

    underTest.broadcastOnIssueChange(oneIssueOnComponent1, singletonList(component1QGChangeEvent), false);

    ArgumentCaptor<Set<ChangedIssue>> changedIssuesCaptor = newSetCaptor();
    inOrder.verify(listener1).onIssueChanges(same(component1QGChangeEvent), changedIssuesCaptor.capture());
    Set<ChangedIssue> changedIssues = changedIssuesCaptor.getValue();
    inOrder.verify(listener2).onIssueChanges(same(component1QGChangeEvent), same(changedIssues));
    inOrder.verifyNoMoreInteractions();
    assertThat(logTester.logs(Level.TRACE)).hasSizeGreaterThanOrEqualTo(2).contains(
      format("calling onChange() on listener %s for events %s...", listener1.getClass().getName(), component1QGChangeEvent),
      format("calling onChange() on listener %s for events %s...", listener2.getClass().getName(), component1QGChangeEvent));
    assertThat(logTester.logs(Level.WARN)).hasSizeGreaterThanOrEqualTo(1).contains("Broadcasting to listeners failed for 1 events");
  }