def parse(cls, line, encoding=pydle.protocol.DEFAULT_ENCODING):
        valid = True
        try:
            message = line.decode(encoding)
        except UnicodeDecodeError:
            message = line.decode(pydle.protocol.FALLBACK_ENCODING)
        if len(message) > protocol.MESSAGE_LENGTH_LIMIT:
            valid = False
        if message.endswith(protocol.LINE_SEPARATOR):
            message = message[:-len(protocol.LINE_SEPARATOR)]
        elif message.endswith(protocol.MINIMAL_LINE_SEPARATOR):
            message = message[:-len(protocol.MINIMAL_LINE_SEPARATOR)]
        if any(ch in message for ch in protocol.FORBIDDEN_CHARACTERS):
            valid = False
        if message.startswith(':'):
            parts = protocol.ARGUMENT_SEPARATOR.split(message[1:], 2)
        else:
            parts = [ None ] + protocol.ARGUMENT_SEPARATOR.split(message, 1)
        if len(parts) == 3:
            source, command, raw_params = parts
        elif len(parts) == 2:
            source, command = parts
            raw_params = ''
        else:
            raise pydle.protocol.ProtocolViolation('Improper IRC message format: not enough elements.', message=message)
        if not protocol.COMMAND_PATTERN.match(command):
            valid = False
        if raw_params.startswith(protocol.TRAILING_PREFIX):
            params = [ raw_params[len(protocol.TRAILING_PREFIX):] ]
        elif ' ' + protocol.TRAILING_PREFIX in raw_params:
            index = raw_params.find(' ' + protocol.TRAILING_PREFIX)
            params = protocol.ARGUMENT_SEPARATOR.split(raw_params[:index].rstrip(' '))
            params.append(raw_params[index + len(protocol.TRAILING_PREFIX) + 1:])
        elif raw_params:
            params = protocol.ARGUMENT_SEPARATOR.split(raw_params)
        else:
            params = []
        try:
            command = int(command)
        except ValueError:
            command = command.upper()
        return RFC1459Message(command, params, source=source, _valid=valid, _raw=message)