@Override
  @CheckForNull
  public EmailMessage format(Notification notification) {
    if (!BuiltInQPChangeNotification.TYPE.equals(notification.getType())) {
      return null;
    }

    BuiltInQPChangeNotificationBuilder profilesNotification = parse(notification);
    StringBuilder message = new StringBuilder("The following built-in profiles have been updated:\n\n");
    profilesNotification.getProfiles().stream()
      .sorted(Comparator.comparing(Profile::getLanguageName).thenComparing(Profile::getProfileName))
      .forEach(profile -> {
        message.append("\"")
          .append(profile.getProfileName())
          .append("\" - ")
          .append(profile.getLanguageName())
          .append(": ")
          .append(server.getPublicRootUrl()).append("/profiles/changelog?language=")
          .append(profile.getLanguageKey())
          .append("&name=")
          .append(encode(profile.getProfileName()))
          .append("&since=")
          .append(formatDate(new Date(profile.getStartDate())))
          .append("&to=")
          .append(formatDate(new Date(profile.getEndDate())))
          .append("\n");
        int newRules = profile.getNewRules();
        if (newRules > 0) {
          message.append(" ").append(newRules).append(" new rule")
            .append(plural(newRules))
            .append('\n');
        }
        int updatedRules = profile.getUpdatedRules();
        if (updatedRules > 0) {
          message.append(" ").append(updatedRules).append(" rule")
            .append(updatedRules > 1 ? "s have been updated" : " has been updated")
            .append("\n");
        }
        int removedRules = profile.getRemovedRules();
        if (removedRules > 0) {
          message.append(" ").append(removedRules).append(" rule")
            .append(plural(removedRules))
            .append(" removed\n");
        }
        message.append("\n");
      });

    message.append("This is a good time to review your quality profiles and update them to benefit from the latest evolutions: ");
    message.append(server.getPublicRootUrl()).append("/profiles");

    // And finally return the email that will be sent
    return new EmailMessage()
      .setMessageId(BuiltInQPChangeNotification.TYPE)
      .setSubject("Built-in quality profiles have been updated")
      .setPlainTextMessage(message.toString());
  }
@Test
  public void notification_contains_profiles_sorted_by_language_then_by_profile_name() {
    String languageKey1 = "langkey1_" + randomAlphanumeric(20);
    String languageName1 = "langName1_" + randomAlphanumeric(20);
    String languageKey2 = "langKey2_" + randomAlphanumeric(20);
    String languageName2 = "langName2_" + randomAlphanumeric(20);
    String profileName1 = "profile1_" + randomAlphanumeric(20);
    String profileName2 = "profile2_" + randomAlphanumeric(20);
    String profileName3 = "profile3_" + randomAlphanumeric(20);
    BuiltInQPChangeNotificationBuilder notification = new BuiltInQPChangeNotificationBuilder()
      .addProfile(Profile.newBuilder().setProfileName(profileName3).setLanguageKey(languageKey2).setLanguageName(languageName2).build())
      .addProfile(Profile.newBuilder().setProfileName(profileName2).setLanguageKey(languageKey1).setLanguageName(languageName1).build())
      .addProfile(Profile.newBuilder().setProfileName(profileName1).setLanguageKey(languageKey2).setLanguageName(languageName2).build());

    EmailMessage emailMessage = underTest.format(notification.build());

    assertThat(emailMessage.getMessage()).containsSubsequence(
      "\"" + profileName2 + "\" - " + languageName1,
      "\"" + profileName1 + "\" - " + languageName2,
      "\"" + profileName3 + "\" - " + languageName2);
  }