'Build a process tree using using parent/child relationships.
Return the tree root node.'

@staticmethod
def build_tree(process_dict, sort_key, sort_reverse, hide_kernel_threads, excluded_processes):

    tree_root = ProcessTreeNode(root=True)
    nodes_to_add_last = collections.deque()
    for (process, stats) in iteritems(process_dict):
        new_node = ProcessTreeNode(process, stats, sort_key, sort_reverse)
        try:
            parent_process = process.parent()
        except psutil.NoSuchProcess:
            parent_process = None
        if ((parent_process is None) or (parent_process in excluded_processes)):
            tree_root.children.append(new_node)
        else:
            parent_node = tree_root.find_process(parent_process)
            if (parent_node is not None):
                parent_node.children.append(new_node)
            else:
                nodes_to_add_last.append(new_node)
    while nodes_to_add_last:
        node_to_add = nodes_to_add_last.popleft()
        try:
            parent_process = node_to_add.process.parent()
        except psutil.NoSuchProcess:
            tree_root.children.append(node_to_add)
        else:
            if ((parent_process is None) or (parent_process in excluded_processes)):
                tree_root.children.append(node_to_add)
            else:
                parent_node = tree_root.find_process(parent_process)
                if (parent_node is not None):
                    parent_node.children.append(node_to_add)
                else:
                    nodes_to_add_last.append(node_to_add)
    return tree_root
