def get_members(cls, member_class=None, is_member=None, sort_key=None, _parameter=None):
    if member_class is None and is_member is None:
        raise TypeError("get_members either needs a member_class parameter or an is_member check function (or both)")
    members = OrderedDict()
    for base in cls.__bases__:
        if _parameter is None:
            inherited_members = get_members(base, member_class=member_class, is_member=is_member, sort_key=sort_key)
        else:
            inherited_members = get_declared(base, _parameter)
        members.update(inherited_members)
    def generate_member_bindings():
        for name in cls.__dict__:
            if name.startswith('__'):
                continue
            obj = getattr(cls, name)
            if member_class is not None and isinstance(obj, member_class):
                yield name, obj
            elif is_member is not None and is_member(obj):
                yield name, obj
            elif type(obj) is tuple and len(obj) == 1 and isinstance(obj[0], member_class):
                raise TypeError("'%s' is a one-tuple containing what we are looking for.  Trailing comma much?  Don't... just don't." % name)
    bindings = generate_member_bindings()
    if sort_key is not None:
        try:
            sorted_bindings = sorted(bindings, key=lambda x: sort_key(x[1]))
        except AttributeError:
            if sort_key is default_sort_key:
                raise TypeError('Missing member ordering definition. Use @creation_ordered or specify sort_key')
            else:
                raise
        members.update(sorted_bindings)
    else:
        members.update(bindings)
    return members