// updateMetrics recursively updates all fields in a treeNode's TestSuite
func updateMetrics(root *treeNode) {
	for _, child := range root.children {
		updateMetrics(child)
		// we should be building a tree, so updates on children are independent and we can bring
		// in the updated data for this child right away
		root.suite.NumTests += child.suite.NumTests
		root.suite.NumSkipped += child.suite.NumSkipped
		root.suite.NumFailed += child.suite.NumFailed
		root.suite.Duration += child.suite.Duration
		root.suite.Children = append(root.suite.Children, child.suite)
	}

	// we need to sort our children so that we can ensure reproducible output for testing
	sort.Sort(api.ByName(root.suite.Children))
}
// Build builds an api.TestSuites from the list of nodes that is contained in the builder.
func (b *nestedTestSuitesBuilder) Build() *api.TestSuites {
	// build a tree from our list of nodes
	nodesToAdd := []*treeNode{}
	for _, node := range b.nodes {
		// make a copy of which nodes we're interested in, otherwise we'll be concurrently modifying b.nodes
		nodesToAdd = append(nodesToAdd, node)
	}

	for _, node := range nodesToAdd {
		parentNode, exists := b.nodes[getParentName(node.suite.Name)]
		if !exists {
			makeParentsFor(node, b.nodes, b.restrictedRoots)
			continue
		}

		parentNode.children = append(parentNode.children, node)
		node.parent = parentNode
	}

	// find the tree's roots
	roots := []*treeNode{}
	for _, node := range b.nodes {
		if node.parent == nil {
			roots = append(roots, node)
		}
	}

	// update all metrics inside of test suites so they encompass those of their children
	rootSuites := []*api.TestSuite{}
	for _, root := range roots {
		updateMetrics(root)
		rootSuites = append(rootSuites, root.suite)
	}

	// we need to sort our children so that we can ensure reproducible output for testing
	sort.Sort(api.ByName(rootSuites))

	return &api.TestSuites{Suites: rootSuites}
}