Parse a filter name to get information about how to interpret and display 
    that filter.  For example, consider the following filter name:

        "Foldability Filter [+|guide 0.1]"

    Everything outside the brackets is the name of the filter.  This is 
    converted into a simpler name which can be referred to later on by making 
    everything lower case, dropping anything inside of parentheses, replacing 
    non-ASCII characters with ASCII ones (on a best-effort basis, some letters 
    may be dropped), and replacing spaces and dashes with underscores (expect 
    trailing spaces, which are removed).

    Everything in the brackets provides metadata about the filter.  All 
    metadata is optional.  Different pieces of metadata are separated by 
    vertical bars, and do not have to be labeled.  If unlabeled, the metadata 
    are interpreted in the following order:

    1. Direction (i.e. '+' or '-', are higher or lower values better?)
    2. Unit (i.e. how to label the metric?)
    3. Order (i.e. how to sort a list of filters?)
    4. Guide (i.e. where should a dashed line be drawn in the GUI?)
    5. Lower limit (i.e. the default lower limit in the GUI)
    6. Upper limit (i.e. the default upper limit in the GUI)

    If labeled, the data can appear in any order.  The labels corresponding to 
    the above arguments are abbreviated as follows: 'dir', 'unit', 'order', 
    'guide', 'lower', 'upper'.  No unlabeled metadata can appear after any 
    labeled metadata.

def parse_extra_metric(desc, default_order=None):
    """
    Parse a filter name to get information about how to interpret and display 
    that filter.  For example, consider the following filter name:

        "Foldability Filter [+|guide 0.1]"

    Everything outside the brackets is the name of the filter.  This is 
    converted into a simpler name which can be referred to later on by making 
    everything lower case, dropping anything inside of parentheses, replacing 
    non-ASCII characters with ASCII ones (on a best-effort basis, some letters 
    may be dropped), and replacing spaces and dashes with underscores (expect 
    trailing spaces, which are removed).

    Everything in the brackets provides metadata about the filter.  All 
    metadata is optional.  Different pieces of metadata are separated by 
    vertical bars, and do not have to be labeled.  If unlabeled, the metadata 
    are interpreted in the following order:

    1. Direction (i.e. '+' or '-', are higher or lower values better?)
    2. Unit (i.e. how to label the metric?)
    3. Order (i.e. how to sort a list of filters?)
    4. Guide (i.e. where should a dashed line be drawn in the GUI?)
    5. Lower limit (i.e. the default lower limit in the GUI)
    6. Upper limit (i.e. the default upper limit in the GUI)

    If labeled, the data can appear in any order.  The labels corresponding to 
    the above arguments are abbreviated as follows: 'dir', 'unit', 'order', 
    'guide', 'lower', 'upper'.  No unlabeled metadata can appear after any 
    labeled metadata.
    """
    meta = re.search(r'\[\[?(.*?)\]\]?', desc)

    if not meta:
        return ScoreMetadata(desc, order=default_order)

    args = {}
    if default_order is not None:
        args['order'] = default_order

    title = desc[:meta.start()] + desc[meta.end():]
    tokens = meta.group(1).split('|')
    default_keys = 'dir', 'unit', 'order', 'guide', 'min', 'max'
    default_ok = True

    for i, token in enumerate(tokens):
        try:
            key, value = token.strip().split(None, 1)
            # Stop using the defaults once we've been given an explicit key.
            default_ok = False
        except ValueError:
            if default_ok and i < len(default_keys):
                key, value = default_keys[i], token
            else:
                raise IOError("Unknown key for '{0}' in filter '{1}'".format(token, desc))

        args[key] = value

    return ScoreMetadata(title, **args)