Given a an input message (privmsg/pubmsg/notice), return events.

def ctcp_unpack_message(info):
    """Given a an input message (privmsg/pubmsg/notice), return events."""
    verb = info['verb']
    message = info['params'][1]

    # NOTE: full CTCP dequoting and unpacking is not done here, only a subset
    #   this is because doing the full thing breaks legitimate messages

    # basics
    infos = []

    X_QUOTE = '\\'
    X_DELIM = '\x01'

    # tagged data
    messages = str(message).split(X_DELIM)

    for i in range(len(messages)):
        msg = messages[i]
        new_info = dict(info)

        if i % 2 == 0:  # is normal message)
            if not msg:
                continue
            new_info['params'] = new_info['params'][:1]
            new_info['params'].append(msg)
        else:
            if verb in ['privnotice', 'pubnotice']:
                new_info['verb'] = 'ctcp_reply'
            else:
                new_info['verb'] = 'ctcp'
            if ' ' in msg.lstrip():
                new_info['ctcp_verb'], new_info['ctcp_text'] = msg.lstrip().split(' ', 1)
            else:
                new_info['ctcp_verb'] = msg.lstrip()
                new_info['ctcp_text'] = ''

            new_info['ctcp_verb'] = new_info['ctcp_verb'].lower()

        infos.append([new_info['verb'], new_info])

    # ctcp-level dequoting
    for i in range(len(infos)):
        if infos[i][NAME_ATTR] == 'ctcp':
            attrs = ['ctcp_verb', 'ctcp_text']
        else:
            attrs = ['params']

        for attr in attrs:
            if isinstance(infos[i][INFO_ATTR][attr], (list, tuple)):
                raw_messages = infos[i][INFO_ATTR][attr]
            else:
                raw_messages = [infos[i][INFO_ATTR][attr]]

            messages = []
            for raw in raw_messages:
                unquoted = ''
                while len(raw):
                    char = raw[0]
                    raw = raw[1:]

                    if char == X_QUOTE:
                        if not len(raw):
                            continue
                        key = raw[0]
                        raw = raw[1:]

                        if key == 'a':
                            unquoted += X_DELIM
                        elif key == X_QUOTE:
                            unquoted += X_QUOTE
                        else:
                            unquoted += key
                    else:
                        unquoted += char
                messages.append(unquoted)

            if isinstance(infos[i][INFO_ATTR][attr], (list, tuple)):
                infos[i][INFO_ATTR][attr] = messages
            else:
                infos[i][INFO_ATTR][attr] = messages[0]

    return infos