def parse_channel_modes(modes, opts = {})
      chanmodes = opts[:chanmodes] || {
        'A' => %w{b e I}.to_set,
        'B' => %w{k}.to_set,
        'C' => %w{l}.to_set,
        'D' => %w{i m n p s t a q r}.to_set,
      }
      statmodes = opts[:statmodes] || %w{o h v}.to_set

      mode_changes = []
      modelist, *args = modes
      parse_modes(modelist).each do |mode_change|
        set, mode = mode_change[:set], mode_change[:mode]
        case
        when chanmodes["A"].include?(mode) || chanmodes["B"].include?(mode)
          mode_changes << {
            mode: mode,
            set: set,
            argument: args.shift
          }
        when chanmodes["C"].include?(mode)
          mode_changes << {
            mode: mode,
            set: set,
            argument: args.shift.to_i
          }
        when chanmodes["D"].include?(mode)
          mode_changes << {
            mode: mode,
            set: set,
          }
        else
          raise ArgumentError, "Unknown mode: #{mode}"
        end
      end

      return mode_changes
    end
def parse_channel_modes(modes, opts = {})
      chanmodes = opts[:chanmodes] || {
        'A' => %w{b e I}.to_set,
        'B' => %w{k}.to_set,
        'C' => %w{l}.to_set,
        'D' => %w{i m n p s t a q r}.to_set,
      }
      statmodes = opts[:statmodes] || %w{o h v}.to_set

      mode_changes = []
      modelist, *args = modes
      parse_modes(modelist).each do |mode_change|
        set, mode = mode_change[:set], mode_change[:mode]
        case
        when chanmodes["A"].include?(mode) || chanmodes["B"].include?(mode)
          mode_changes << {
            mode: mode,
            set: set,
            argument: args.shift
          }
        when chanmodes["C"].include?(mode)
          mode_changes << {
            mode: mode,
            set: set,
            argument: args.shift.to_i
          }
        when chanmodes["D"].include?(mode)
          mode_changes << {
            mode: mode,
            set: set,
          }
        else
          raise ArgumentError, "Unknown mode: #{mode}"
        end
      end

      return mode_changes
    end
Parse channel mode changes.
 @param [Array] modes The modes you want to parse.
 @option opts [Hash] :chanmodes The channel modes which are allowed. This is
   the same as the "CHANMODES" isupport option.
 @option opts [Hash] :statmodes The channel modes which are allowed. This is
   the same as the keys of the "PREFIX" isupport option.
 @return [Array] Each element will be a hash with three keys: `:set`,
   a boolean indicating whether the mode is being set (instead of unset);
   `:mode`, the mode character; and `:argument`, the argument to the mode,
   if any.