Index: /trunk/ippTools/src/pxtree.c
===================================================================
--- /trunk/ippTools/src/pxtree.c	(revision 15220)
+++ /trunk/ippTools/src/pxtree.c	(revision 15221)
@@ -32,4 +32,5 @@
     psFree(node->parent);
     psFree(node->children);
+    psFree(node->data);
 }
 
@@ -43,4 +44,5 @@
     node->parent = NULL;
     node->children = psListAlloc(NULL);
+    node->data = NULL;
 
     psMemSetDeallocator(node, (psFreeFunc) pxNodeFree);
@@ -69,4 +71,11 @@
     // [re]parent the child
     child->parent = psMemIncrRefCounter(node);
+
+    return node;
+}
+
+pxNode *pxNodeAddData(pxNode *node, psPtr data)
+{
+    node->data = psMemIncrRefCounter(data);
 
     return node;
@@ -151,5 +160,5 @@
 pxNode *pxTreeFromMetadata(psMetadata *md)
 {
-    psHash *nodeNames = psHashAlloc(10);
+    psHash *forest = psHashAlloc(10);
 
     psMetadataIterator *iter = psMetadataIteratorAlloc(md, 0, NULL);
@@ -160,39 +169,54 @@
         }
 
+        // add this node to the forest and hopefully it'll get attached to the
+        // root tree
+        pxTreeBuilder(forest, item->name, item->data.str, NULL);
+    }
+    psFree(iter);
+
+    pxNode *root = psHashLookup(forest, "root");
+    psFree(forest);
+
+    return psMemIncrRefCounter(root);
+}
+
+psHash *pxTreeBuilder(psHash *forest,
+                      const char *nodeName,
+                      const char *childName,
+                      psPtr data)
+{
+    // try to find a node with this name
+    pxNode *node = psHashLookup(forest, nodeName);
+    if (!node) {
+        // create a new node with this name
+        node = pxNodeAlloc(nodeName);
+        if (data) {
+            pxNodeAddData(node, data);
+        }
+        // add it to the hash of nodes
+        psHashAdd(forest, nodeName, node);
+        // node may be used below because it will still have a ref count of
+        // 1 from being on the hash, this is equivalent to the "view" we
+        // get from a hashlookup
+        psFree(node);
+    }
+
+    // does this node declare a child?
+    if (childName) {
         // try to find a node with this name
-        pxNode *node = psHashLookup(nodeNames, item->name);
-        if (!node) {
+        pxNode *child = psHashLookup(forest, childName);
+        if (!child ) {
             // create a new node with this name
-            node = pxNodeAlloc(item->name);
+            child = pxNodeAlloc(childName);
             // add it to the hash of nodes
-            psHashAdd(nodeNames, item->name, node);
-            // node may be used below because it will still have a ref count of
-            // 1 from being on the hash, this is equivalent to the "view" we
-            // get from a hashlookup
-            psFree(node);
+            psHashAdd(forest, childName, child);
+            // child may be used below because it will still have a ref
+            // count of 1 from being on the hash, this is equivalent to the
+            // "view" we get from a hashlookup
+            psFree(child);
         }
-
-        // does this node declare a child?
-        if (item->data.str) {
-            // try to find a node with this name
-            pxNode *child = psHashLookup(nodeNames, item->data.str);
-            if (!child ) {
-                // create a new node with this name
-                child = pxNodeAlloc(item->data.str);
-                // add it to the hash of nodes
-                psHashAdd(nodeNames, item->data.str, child);
-                // child may be used below because it will still have a ref
-                // count of 1 from being on the hash, this is equivalent to the
-                // "view" we get from a hashlookup
-                psFree(child);
-            }
-            pxNodeAddChild(node, child);
-        }
-    }
-    psFree(iter);
-
-    pxNode *root = psHashLookup(nodeNames, "root");
-    psFree(nodeNames);
-
-    return psMemIncrRefCounter(root);
-}
+        pxNodeAddChild(node, child);
+    }
+
+    return forest;
+}
Index: /trunk/ippTools/src/pxtree.h
===================================================================
--- /trunk/ippTools/src/pxtree.h	(revision 15220)
+++ /trunk/ippTools/src/pxtree.h	(revision 15221)
@@ -31,4 +31,5 @@
   struct pxNode *parent;
   psList  *children;
+  void *data;
 } pxNode;
 
@@ -41,4 +42,5 @@
 pxNode *pxNodeAddParent(pxNode *node, pxNode *parent);
 pxNode *pxNodeAddChild(pxNode *node, pxNode *child);
+pxNode *pxNodeAddData(pxNode *node, psPtr data);
 
 void pxNodePrint(
@@ -61,3 +63,8 @@
 pxNode *pxTreeFromMetadata(psMetadata *md);
 
+psHash *pxTreeBuilder(psHash *forest,
+                      const char *nodeName,
+                      const char *childName,
+                      psPtr data);
+
 #endif // PXTREE_H
