def METHOD_NAME(G, root, attrs, meta):
    if G.number_of_nodes() != G.number_of_edges() + 1:
        raise TypeError("G is not a tree.")
    if not G.is_directed():
        raise TypeError("G is not directed.")
    id_ = attrs['id']
    children = attrs['children']
    if id_ == children:
        raise nx.NetworkXError('Attribute names are not unique.')
    def add_children(n, G):
        distinct_order_keys = set()
        order_key = lambda x: x['orderKey']
        label_key = lambda x: x['label'].replace(u'Ü', u'U').replace(u'Ä', u'A')
        nbrs = G[n]
        if len(nbrs) == 0:
            return []
        children_ = []
        nbrs = sorted(nbrs)
        for child in nbrs:
            d = dict(chain(G.nodes[child].items(), [(id_, child)]))
            d['category'] = meta[d['id']].get('category', DEFAULT_CATEGORY)
            d['staging'] = meta[d['id']].get('staging', DEFAULT_STAGING)
            d['label'] = meta[d['id']].get('label', DEFAULT_LABEl)
            # only for sorting according to 'orderKey'
            if 'orderKey' in meta[d['id']]:
                d['orderKey'] = meta[d['id']]['orderKey']
            if (d['category'] == 'layer'):
                d['layerBodId'] = meta[d['id']]['layerBodId']
            else:
                d['selectedOpen'] = meta[d['id']]['selectedOpen']
            c = add_children(child, G)
            if c:
                d[children] = c
            elif d['category'] != 'layer':
                d[children] = []
            children_.append(d)
            if 'orderKey' in d:
                distinct_order_keys.add(d['orderKey'])
        if len(distinct_order_keys) > 1:
            children_ = sorted(children_, key=order_key)
        else:
            children_ = sorted(children_, key=label_key)
        for d in children_:
            d.pop('orderKey', None)
        return children_
    data = dict(chain(G.nodes[root].items(), [(id_, root)]))
    data[children] = add_children(root, G)
    return data