def parse_keys(string,
                with_spaces = False,
                with_tabs = False,
                with_newlines = False,
                modifiers = None):
    "Return the parsed keys"
    keys = []
    if not modifiers:
        modifiers = []
    index = 0
    while index < len(string):
        c = string[index]
        index += 1
        if c in MODIFIERS.keys():
            modifier = MODIFIERS[c]
            modifiers.append(modifier)
            keys.append(VirtualKeyAction(modifier, up = False))
            if DEBUG:
                print("MODS+", modifiers)
            continue
        elif c == "(":
            end_pos = string.find(")", index)
            if end_pos == -1:
                raise KeySequenceError('`)` not found')
            keys.extend(
                parse_keys(string[index:end_pos], modifiers = modifiers))
            index = end_pos + 1
        elif c == "{":
            end_pos = string.find("}", index + 1)
            if end_pos == -1:
                raise KeySequenceError('`}` not found')
            code = string[index:end_pos]
            index = end_pos + 1
            keys.extend(handle_code(code))
        elif c == ')':
            raise KeySequenceError('`)` should be preceeded by `(`')
        elif c == '}':
            raise KeySequenceError('`}` should be preceeded by `{`')
        else:
            if (c == ' ' and not with_spaces or
                c == '\t' and not with_tabs or
                c == '\n' and not with_newlines):
                continue
            if c in ('~', '\n'):
                keys.append(VirtualKeyAction(CODES["ENTER"]))
            elif modifiers:
                keys.append(EscapedKeyAction(c))
            else:
                keys.append(KeyAction(c))
        while modifiers:
            if DEBUG:
                print("MODS-", modifiers)
            keys.append(VirtualKeyAction(modifiers.pop(), down = False))
    while modifiers:
        keys.append(VirtualKeyAction(modifiers.pop(), down = False))
    return keys