@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
  @NotNull
  private static String makeDescription(
      @NotNull Collection<VcsRootError> unregisteredRoots,
      @NotNull Collection<VcsRootError> invalidRoots) {
    Function<VcsRootError, String> rootToDisplayableString =
        rootError -> {
          if (rootError.getMapping().equals(VcsDirectoryMapping.PROJECT_CONSTANT)) {
            return StringUtil.escapeXml(rootError.getMapping());
          }
          return FileUtil.toSystemDependentName(rootError.getMapping());
        };

    StringBuilder description = new StringBuilder();
    if (!invalidRoots.isEmpty()) {
      if (invalidRoots.size() == 1) {
        VcsRootError rootError = invalidRoots.iterator().next();
        String vcsName = rootError.getVcsKey().getName();
        description.append(
            String.format(
                "The directory %s is registered as a %s root, but no %s repositories were found there.",
                rootToDisplayableString.fun(rootError), vcsName, vcsName));
      } else {
        description.append(
            "The following directories are registered as VCS roots, but they are not: <br/>"
                + StringUtil.join(invalidRoots, rootToDisplayableString, "<br/>"));
      }
      description.append("<br/>");
    }

    if (!unregisteredRoots.isEmpty()) {
      if (unregisteredRoots.size() == 1) {
        VcsRootError unregisteredRoot = unregisteredRoots.iterator().next();
        description.append(
            String.format(
                "The directory %s is under %s, but is not registered in the Settings.",
                rootToDisplayableString.fun(unregisteredRoot),
                unregisteredRoot.getVcsKey().getName()));
      } else {
        description.append(
            "The following directories are roots of VCS repositories, but they are not registered in the Settings: <br/>"
                + StringUtil.join(unregisteredRoots, rootToDisplayableString, "<br/>"));
      }
      description.append("<br/>");
    }

    String add =
        invalidRoots.isEmpty()
            ? "<a href='add'>Add "
                + pluralize("root", unregisteredRoots.size())
                + "</a>&nbsp;&nbsp;"
            : "";
    String configure = "<a href='configure'>Configure</a>";
    String ignore = invalidRoots.isEmpty() ? "&nbsp;&nbsp;<a href='ignore'>Ignore</a>" : "";
    description.append(add + configure + ignore);

    return description.toString();
  }
 @Override
 protected void hyperlinkActivated(
     @NotNull Notification notification, @NotNull HyperlinkEvent event) {
   if (event.getDescription().equals("configure") && !myProject.isDisposed()) {
     ShowSettingsUtil.getInstance()
         .showSettingsDialog(myProject, ActionsBundle.message("group.VcsGroup.text"));
     Collection<VcsRootError> errorsAfterPossibleFix = getInstance(myProject).scan();
     if (errorsAfterPossibleFix.isEmpty() && !notification.isExpired()) {
       notification.expire();
     }
   } else if (event.getDescription().equals("ignore")) {
     mySettings.addIgnoredUnregisteredRoots(
         ContainerUtil.map(myImportantUnregisteredRoots, PATH_FROM_ROOT_ERROR));
     notification.expire();
   } else if (event.getDescription().equals("add")) {
     List<VcsDirectoryMapping> mappings = myVcsManager.getDirectoryMappings();
     for (VcsRootError root : myImportantUnregisteredRoots) {
       mappings = VcsUtil.addMapping(mappings, root.getMapping(), root.getVcsKey().getName());
     }
     myVcsManager.setDirectoryMappings(mappings);
   }
 }