def parse(raw_line)
      line = decompose(raw_line)

      if line.command =~ /^(PRIVMSG|NOTICE)$/ && line.args[1] =~ /\x01/
        return handle_ctcp_message(line)
      end

      msg_class = case
      when line.command =~ /^\d{3}$/
        begin
          constantize("IRCSupport::Message::Numeric#{line.command}")
        rescue
          constantize("IRCSupport::Message::Numeric")
        end
      when line.command == "MODE"
        if @isupport['CHANTYPES'].include?(line.args[0][0])
          constantize("IRCSupport::Message::ChannelModeChange")
        else
          constantize("IRCSupport::Message::UserModeChange")
        end
      when line.command == "NOTICE" && (!line.prefix || line.prefix !~ /!/)
        constantize("IRCSupport::Message::ServerNotice")
      when line.command == "CAP" && %w{LS LIST ACK}.include?(line.args[0])
        constantize("IRCSupport::Message::CAP::#{line.args[0]}")
      else
        begin
          constantize("IRCSupport::Message::#{line.command.capitalize}")
        rescue
          constantize("IRCSupport::Message")
        end
      end

      message = msg_class.new(line, @isupport, @capabilities)

      case message.type
      when :'005'
        @isupport.merge! message.isupport
      when :cap_ack
        message.capabilities.each do |capability, options|
          if options.include?(:disable)
            @capabilities = @capabilities - [capability]
          elsif options.include?(:enable)
            @capabilities = @capabilities + [capability]
          end
        end
      end

      return message
    end
def parse(raw_line)
      line = decompose(raw_line)

      if line.command =~ /^(PRIVMSG|NOTICE)$/ && line.args[1] =~ /\x01/
        return handle_ctcp_message(line)
      end

      msg_class = case
      when line.command =~ /^\d{3}$/
        begin
          constantize("IRCSupport::Message::Numeric#{line.command}")
        rescue
          constantize("IRCSupport::Message::Numeric")
        end
      when line.command == "MODE"
        if @isupport['CHANTYPES'].include?(line.args[0][0])
          constantize("IRCSupport::Message::ChannelModeChange")
        else
          constantize("IRCSupport::Message::UserModeChange")
        end
      when line.command == "NOTICE" && (!line.prefix || line.prefix !~ /!/)
        constantize("IRCSupport::Message::ServerNotice")
      when line.command == "CAP" && %w{LS LIST ACK}.include?(line.args[0])
        constantize("IRCSupport::Message::CAP::#{line.args[0]}")
      else
        begin
          constantize("IRCSupport::Message::#{line.command.capitalize}")
        rescue
          constantize("IRCSupport::Message")
        end
      end

      message = msg_class.new(line, @isupport, @capabilities)

      case message.type
      when :'005'
        @isupport.merge! message.isupport
      when :cap_ack
        message.capabilities.each do |capability, options|
          if options.include?(:disable)
            @capabilities = @capabilities - [capability]
          elsif options.include?(:enable)
            @capabilities = @capabilities + [capability]
          end
        end
      end

      return message
    end
Parse an IRC protocol line into a complete message object.
 @param [String] raw_line An IRC protocol line.
 @return [IRCSupport::Message] A parsed message object.