def parse_rank_specification(s):
    """
    Parses info about rank specification, used to filter games by player's ranks.
    Returns None (all ranks allowed),
    or a set of possible values
    (None as a possible value in the set means that we should include games without rank info)


    # returns None, all ranks possible
    parse_rank_specification('')

    # returns set([1, 2, 3, None])), 1, 2, 3 allowed, as well as missing rank info
    parse_rank_specification('1..3,')

    # returns set([None])), only games WITHOUT rank info are allowed
    parse_rank_specification(',')

    See test for more examples.
    """
    if not s:
        return None

    ret = []
    s = s.replace(' ','')
    categories = s.split(',')

    for cat in categories:
        cs = cat.split('..')
        try:
            if len(cs) == 1:
                if not cs[0]:
                    ret.append(None)
                else:
                    ret.append(int(cs[0]))
            elif len(cs) == 2:
                fr, to = map(int,cs)
                if to < fr:
                    raise RuntimeError('Empty range %s'%(cat))

                ret.extend(range(fr, to+1))
            else:
                raise ValueError()

        except ValueError:
            raise RuntimeError('Could not parse rank info on token "%s"'%(cat))

    return set(ret)