private String listPermissions(IMessage message, Permission permission, List<String> args) {
   List<String> matches = new ArrayList<>();
   // TODO narrow search by following args
   for (DiscordGuild guild : cacheService.findAllGuilds()) {
     if (guild.getDenied().contains(permission)) {
       matches.add(
           String.format(
               "deny everyone in guild %s (%s)", nullAsEmpty(guild.getName()), guild.getId()));
     } else if (guild.getAllowed().contains(permission)) {
       matches.add(
           String.format(
               "allow anyone in guild %s (%s)", nullAsEmpty(guild.getName()), guild.getId()));
     }
     for (DiscordRole role : guild.getRoles()) {
       if (role.getDenied().contains(permission)) {
         matches.add(
             String.format(
                 "deny everyone with role %s (%s) in guild %s (%s)",
                 nullAsEmpty(role.getName()),
                 role.getId(),
                 nullAsEmpty(guild.getName()),
                 guild.getId()));
       } else if (role.getAllowed().contains(permission)) {
         matches.add(
             String.format(
                 "allow anyone with role %s (%s) in guild %s (%s)",
                 nullAsEmpty(role.getName()),
                 role.getId(),
                 nullAsEmpty(guild.getName()),
                 guild.getId()));
       }
     }
   }
   for (DiscordChannel channel : cacheService.findAllChannels()) {
     if (channel.getDenied().contains(permission)) {
       matches.add(
           String.format(
               "deny everyone in channel %s (%s)",
               nullAsEmpty(channel.getName()), channel.getId()));
     } else if (channel.getAllowed().contains(permission)) {
       matches.add(
           String.format(
               "allow anyone in channel %s (%s)",
               nullAsEmpty(channel.getName()), channel.getId()));
     }
   }
   for (DiscordUser user : cacheService.findAllUsers()) {
     if (user.getDenied().contains(permission)) {
       matches.add(String.format("deny user %s (%s)", nullAsEmpty(user.getName()), user.getId()));
     } else if (user.getAllowed().contains(permission)) {
       matches.add(String.format("allow user %s (%s)", nullAsEmpty(user.getName()), user.getId()));
     }
   }
   if (permission.isDefaultAllow()) {
     matches.add("allow if not previously denied");
   }
   return matches.stream().collect(Collectors.joining(", "));
 }
 private String editRolePermission(Operation op, Permission permission, IRole role) {
   IGuild parent = role.getGuild();
   DiscordGuild g =
       cacheService.findGuildById(parent.getID()).orElseGet(() -> new DiscordGuild(parent));
   DiscordRole edit = null;
   for (DiscordRole r : g.getRoles()) {
     if (r.getId().equals(role.getID())) {
       edit = r;
       break;
     }
   }
   if (edit == null) {
     edit = new DiscordRole(role);
     g.getRoles().add(edit);
   }
   if (edit.getName() == null) {
     edit.setName(role.getName());
   }
   changePermission(op, permission, edit);
   g = cacheService.saveGuild(g);
   log.info("Saving new guild/role permission settings: {}", g);
   permissionService.evict();
   return String.format(
       "Modified role %s: %s permission %s",
       edit.getName(), op.name().toLowerCase(), permission.getName());
 }