Index: trunk/ippTools/src/magictool.c
===================================================================
--- trunk/ippTools/src/magictool.c	(revision 20691)
+++ trunk/ippTools/src/magictool.c	(revision 20692)
@@ -801,6 +801,4 @@
     if (!psArrayLength(output)) {
         psTrace("magictool", PS_LOG_INFO, "no rows found");
-        // psFree(output);
-        // return true;
     }
 
@@ -843,33 +841,59 @@
     }
 
-    psHash *forest = psHashAlloc(psArrayLength(magicTree));
-
-    // convert the array of metadata into a pxTree structure
-    for (long i = 0; i < psArrayLength(magicTree); i++) {
+    // entries are ordered by magic_id
+    long index = 0;
+    while (index <  psArrayLength(magicTree)) {
         bool status;
-        psString node = psMetadataLookupStr(&status, magicTree->data[i], "node");
+        psS64 current_magic_id = psMetadataLookupS64(&status, magicTree->data[index], "magic_id");
         if (!status) {
-            psAbort("failed to lookup value for node column");
-        }
-
-        psString dep = psMetadataLookupStr(&status, magicTree->data[i], "dep");
-        if (!status) {
-            psAbort("failed to lookup value for dep column");
-        }
-
-        pxTreeBuilder(forest, node, dep, magicTree->data[i]);
-
-    }
-    psFree(magicTree);
-
-    // find the root of the tree
-    pxNode *root = psMemIncrRefCounter(psHashLookup(forest, "root"));
-    psFree(forest);
-    //    pxTreePrint(stdout, root);
-
-    // crawl through the tree and looking for nodes with children that are all
-    // "done"
-    pxTreeCrawl(root, findReadyNodes, output);
-    psFree(root);
+            psAbort("failed to lookup value for magic_id column");
+        }
+
+        // find the end of this block
+        long first = index;
+        long last = index;
+        for (long i = index + 1; i < psArrayLength(magicTree); i++) {
+            psS64 magic_id = psMetadataLookupS64(&status, magicTree->data[i], "magic_id");
+            if (!status) {
+                psAbort("failed to lookup value for magic_id column");
+            }
+            if (magic_id != current_magic_id) {
+                break;
+            }
+            last = i;
+        }
+
+        index = last + 1;
+
+        psHash *forest = psHashAlloc(last - first + 1);
+
+        // convert the array of metadata into a pxTree structure
+        for (long i = first; i <= last; i++) {
+            bool status;
+            psString node = psMetadataLookupStr(&status, magicTree->data[i], "node");
+            if (!status) {
+                psAbort("failed to lookup value for node column");
+            }
+
+            psString dep = psMetadataLookupStr(&status, magicTree->data[i], "dep");
+            if (!status) {
+                psAbort("failed to lookup value for dep column");
+            }
+
+            pxTreeBuilder(forest, node, dep, magicTree->data[i]);
+
+        }
+
+        // find the root of the tree
+        pxNode *root = psMemIncrRefCounter(psHashLookup(forest, "root"));
+        psFree(forest);
+        //    pxTreePrint(stdout, root);
+
+        // crawl through the tree and looking for nodes with children that are all
+        // "done"
+        pxTreeCrawl(root, findReadyNodes, output);
+        psFree(root);
+
+    }
 
     if (psArrayLength(output)) {
@@ -882,4 +906,5 @@
     }
 
+    psFree(magicTree);
     psFree(output);
     psFree(whereClause);
