def topological_sort(data):
    def check_self_dependencies(input_data):
        for k, v in input_data.items():
            if k in v:
                raise ValueError('Self-dependency, {} depends on itself.'.format(k))
    def prepare_input_data(input_data):
        return {k: set(v) for k, v in input_data.items()}
    def find_items_without_dependencies(input_data):
        return list(reduce(set.union, input_data.values()) - set(input_data.keys()))
    def add_empty_dependencies(data):
        items_without_dependencies = find_items_without_dependencies(data)
        data.update({item: set() for item in items_without_dependencies})
    def get_sorted(input_data):
        data = input_data
        while True:
            ordered = set(item for item, dep in data.items() if len(dep) == 0)
            if not ordered:
                break
            yield ordered
            data = {item: (dep - ordered) for item, dep in data.items() if item not in ordered}
        if len(data) != 0:
            raise ValueError('Cyclic dependencies exist '
                             'among these items: {}'.format(', '.join(repr(x) for x in data.items())))
    check_self_dependencies(data)
    if not len(data):
        return []
    data_copy = prepare_input_data(data)
    add_empty_dependencies(data_copy)
    result = []
    for d in get_sorted(data_copy):
        try:
            d = sorted(d)
        except TypeError:
            d = list(d)
        result.extend(d)
    return result