def parse_iptables_rule(line):
    '''
    Parse one iptables rule. Returns a dict where each iptables code argument
    is mapped to a name using IPTABLES_ARGS.
    '''
    bits = line.split()
    definition = {}
    key = None
    args = []
    not_arg = False
    def add_args():
        arg_string = ' '.join(args)
        if key in IPTABLES_ARGS:
            definition_key = (
                'not_{0}'.format(IPTABLES_ARGS[key])
                if not_arg
                else IPTABLES_ARGS[key]
            )
            definition[definition_key] = arg_string
        else:
            definition.setdefault('extras', []).extend((key, arg_string))
    for bit in bits:
        if bit == '!':
            if key:
                add_args()
                args = []
                key = None
            not_arg = True
        elif bit.startswith('-'):
            if key:
                add_args()
                args = []
                not_arg = False
            key = bit
        else:
            args.append(bit)
    if key:
        add_args()
    if 'extras' in definition:
        definition['extras'] = set(definition['extras'])
    return definition