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 editChannelPermission(Operation op, Permission permission, IChannel channel) {
   if (channel.isPrivate()) {
     throw new IllegalArgumentException("No private channels allowed!");
   }
   DiscordGuild g =
       cacheService
           .findGuildById(channel.getGuild().getID())
           .orElseGet(() -> new DiscordGuild(channel.getGuild()));
   g = cacheService.saveGuild(g);
   DiscordChannel ch =
       cacheService.findChannelById(channel.getID()).orElseGet(() -> new DiscordChannel(channel));
   ch.setGuild(g);
   g.getChannels().add(ch);
   changePermission(op, permission, ch);
   ch = cacheService.saveChannel(ch);
   cacheService.saveGuild(g);
   log.info("Saving new permission data: {}", g);
   permissionService.evict();
   return String.format(
       "Modified channel %s: %s permission %s",
       ch.getName(), op.name().toLowerCase(), permission.getName());
 }