/**
   * Gets a message using the provided filters
   *
   * <p>You can use this method instead of the sendMessage methods if you want to manipulate the
   * string outside of the provided filters before sending the message.
   *
   * <p>If the key is not in the language configuration, null will be returned
   *
   * @param key key for the language message
   * @param player whether or not it is for a player
   * @param filterType type of built-in filter to use
   * @param filters custom filters to use
   * @return filtered message or null if an invalid key
   */
  public List<String> getMessage(
      String key, boolean player, FilterType filterType, CustomFilter... filters) {

    List<String> lines;
    if (!getConfig().has(key)) return null;
    else if (getConfig().isList(key)) {
      lines = getConfig().getList(key);
    } else {
      lines = new ArrayList<String>();
      lines.add(getConfig().getString(key));
    }
    List<String> result = new ArrayList<String>();

    // Filter each line
    for (String line : lines) {
      StringBuilder sb = new StringBuilder(line);

      // Apply custom filters
      for (CustomFilter filter : filters) {
        filter.apply(sb);
      }

      // Filter colors
      if (filterType == FilterType.COLOR || filterType == FilterType.ALL) {
        TextFormatter.colorString(sb);
      }

      // Filter specials
      if (filterType == FilterType.SPECIAL || filterType == FilterType.ALL) {
        filterSizer(sb, true, player);
        filterSizer(sb, false, player);
        filterBreak(sb);
      }

      sb.append(ChatColor.RESET);

      result.add(sb.toString());
    }

    return result;
  }