@Override
  @CheckForNull
  public EmailMessage format(Notification notif) {
    if (!(notif instanceof ChangesOnMyIssuesNotification)) {
      return null;
    }

    ChangesOnMyIssuesNotification notification = (ChangesOnMyIssuesNotification) notif;

    if (notification.getChange() instanceof AnalysisChange) {
      checkState(!notification.getChangedIssues().isEmpty(), "changedIssues can't be empty");
      return formatAnalysisNotification(notification.getChangedIssues().keySet().iterator().next(), notification);
    }
    return formatMultiProject(notification);
  }
@Test
  public void formats_returns_html_message_with_rules_ordered_by_name_user_change() {
    Project project = newProject("1");
    Rule rule1 = newRandomNotAHotspotRule("1");
    Rule rule2 = newRandomNotAHotspotRule("a");
    Rule rule3 = newRandomNotAHotspotRule("b");
    Rule rule4 = newRandomNotAHotspotRule("X");

    Rule hotspot1 = newSecurityHotspotRule("S");
    Rule hotspot2 = newSecurityHotspotRule("Z");
    Rule hotspot3 = newSecurityHotspotRule("N");
    Rule hotspot4 = newSecurityHotspotRule("M");

    String host = randomAlphabetic(15);
    List<ChangedIssue> changedIssues = Stream.of(rule1, rule2, rule3, rule4, hotspot1, hotspot2, hotspot3, hotspot4)
      .map(rule -> newChangedIssue("issue_" + rule.getName(), randomValidStatus(), project, rule))
      .collect(toList());
    Collections.shuffle(changedIssues);
    UserChange userChange = newUserChange();
    when(emailSettings.getServerBaseURL()).thenReturn(host);

    EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.copyOf(changedIssues)));

    HtmlFragmentAssert.assertThat(emailMessage.getMessage())
      .hasParagraph()
      .hasParagraph()
      .hasParagraph() // skip project name
      .hasList(
        "Rule " + rule1.getName() + " - See the single issue",
        "Rule " + rule2.getName() + " - See the single issue",
        "Rule " + rule3.getName() + " - See the single issue",
        "Rule " + rule4.getName() + " - See the single issue")
      .hasEmptyParagraph()
      .hasList(
        "Rule " + hotspot1.getName() + " - See the single hotspot",
        "Rule " + hotspot2.getName() + " - See the single hotspot",
        "Rule " + hotspot3.getName() + " - See the single hotspot",
        "Rule " + hotspot4.getName() + " - See the single hotspot")
      .hasParagraph().hasParagraph() // skip footer
      .noMoreBlock();
  }