@staticmethod
def _build_tree(nodes):
    """Builds the tree (forest) data structure based on the list of nodes.

       Tree building works in O(n*log(n)).

       :param nodes: dict of nodes, where each node is a dictionary with fields
                     "parent_id", "trace_id", "info"
       :returns: list of top level ("root") nodes in form of dictionaries,
                 each containing the "info" and "children" fields, where
                 "children" is the list of child nodes ("children" will be
                 empty for leafs)
       """
    tree = []
    for trace_id in nodes:
        node = nodes[trace_id]
        node.setdefault('children', [])
        parent_id = node['parent_id']
        if parent_id in nodes:
            nodes[parent_id].setdefault('children', [])
            nodes[parent_id]['children'].append(node)
        else:
            tree.append(node)
    for trace_id in nodes:
        nodes[trace_id]['children'].sort(key=lambda x: x['info']['started'])
    return sorted(tree, key=lambda x: x['info']['started'])
