tests/test_tree.c

changeset 1681
56e76fbac167
parent 1675
36c0fb2b60b2
--- a/tests/test_tree.c	Tue Dec 30 13:50:55 2025 +0100
+++ b/tests/test_tree.c	Tue Dec 30 21:44:23 2025 +0100
@@ -41,7 +41,7 @@
 } tree_node;
 
 typedef struct tree_node2 {
-    CX_TREE_NODE_BASE(struct tree_node2);
+    CX_TREE_NODE(struct tree_node2);
     int data;
 } tree_node2;
 
@@ -54,37 +54,13 @@
     const char *path;
 } tree_node_file;
 
-static void *tree_node_file_create(
-        const void *dptr,
-        void *allocator) {
-    if (allocator == NULL) allocator = (void*) cxDefaultAllocator;
-
-    tree_node_file *node = cxMalloc(allocator, sizeof(tree_node_file));
-    node->path = dptr;
-
-    // intentionally write garbage into the pointers, it's part of the test
-    node->parent = (void *) 0xf00ba1;
-    node->next = (void *) 0xf00ba2;
-    node->prev = (void *) 0xf00ba3;
-    node->children = (void *) 0xf00ba4;
-    node->last_child = (void *) 0xf00ba5;
-
-    return node;
-}
-
-static void *tree_node_file_create_hl(
-        const void *dptr,
-        void *tree) {
-    return tree_node_file_create(dptr, (void*)((CxTree*)tree)->collection.allocator);
-}
-
-static int tree_node_file_search(const void *l, const void *r) {
+static int tree_node_file_search_func(const void *l, const void *d) {
     const tree_node_file *left = l;
-    const tree_node_file *right = r;
+    const char *right = d;
     size_t len1 = strlen(left->path);
-    size_t len2 = strlen(right->path);
+    size_t len2 = strlen(right);
     if (len1 <= len2) {
-        if (memcmp(left->path, right->path, len1) == 0) {
+        if (memcmp(left->path, right, len1) == 0) {
             return (int) (len2 - len1);
         } else {
             return -1;
@@ -94,54 +70,33 @@
     }
 }
 
-static int tree_node_file_search_data(const void *l, const void *d) {
-    tree_node_file r;
-    r.path = d;
-    return tree_node_file_search(l, &r);
-}
-
 #define tree_node_layout \
     offsetof(tree_node, parent), offsetof(tree_node, children), -1, \
     offsetof(tree_node, prev), offsetof(tree_node, next)
 #define tree_node_layout_no_prev \
     offsetof(tree_node, parent), offsetof(tree_node, children), -1, -1, \
     offsetof(tree_node, next)
-#define tree_node_full_layout(structname) \
-    offsetof(structname, parent), offsetof(structname, children),\
-    offsetof(structname, last_child), \
-    offsetof(structname, prev), offsetof(structname, next)
-#define tree_node2_layout cx_tree_node_base_layout
-#define tree_node_file_layout tree_node_full_layout(tree_node_file)
-
 #define tree_children(type) offsetof(type, children), offsetof(type, next)
 
-CX_TEST(test_tree_link_new_child) {
-    tree_node parent = {0};
-    tree_node child = {0};
-
-    CX_TEST_DO {
-        cx_tree_link(&parent, &child, tree_node_layout);
-        CX_TEST_ASSERT(parent.next == NULL);
-        CX_TEST_ASSERT(parent.prev == NULL);
-        CX_TEST_ASSERT(parent.parent == NULL);
-        CX_TEST_ASSERT(parent.children == &child);
-        CX_TEST_ASSERT(child.parent == &parent);
-        CX_TEST_ASSERT(child.next == NULL);
-        CX_TEST_ASSERT(child.prev == NULL);
-        CX_TEST_ASSERT(child.children == NULL);
-    }
-}
-
-CX_TEST(test_tree_link_add_child) {
+CX_TEST(test_tree_add) {
     tree_node parent = {0};
     tree_node child1 = {0};
     tree_node child2 = {0};
     tree_node child3 = {0};
 
     CX_TEST_DO {
-        cx_tree_link(&parent, &child1, tree_node_layout);
-        cx_tree_link(&parent, &child2, tree_node_layout);
-        cx_tree_link(&parent, &child3, tree_node_layout);
+        cx_tree_add(&parent, &child1, tree_node_layout);
+        CX_TEST_ASSERT(parent.next == NULL);
+        CX_TEST_ASSERT(parent.prev == NULL);
+        CX_TEST_ASSERT(parent.parent == NULL);
+        CX_TEST_ASSERT(parent.children == &child1);
+        CX_TEST_ASSERT(child1.parent == &parent);
+        CX_TEST_ASSERT(child1.next == NULL);
+        CX_TEST_ASSERT(child1.prev == NULL);
+        CX_TEST_ASSERT(child1.children == NULL);
+
+        cx_tree_add(&parent, &child2, tree_node_layout);
+        cx_tree_add(&parent, &child3, tree_node_layout);
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
         CX_TEST_ASSERT(parent.parent == NULL);
@@ -163,17 +118,17 @@
     }
 }
 
-CX_TEST(test_tree_link_move_to_other_parent) {
+CX_TEST(test_tree_add_move_to_other_parent) {
     tree_node parent = {0};
     tree_node child1 = {0};
     tree_node child2 = {0};
     tree_node child3 = {0};
-    cx_tree_link(&parent, &child1, tree_node_layout);
-    cx_tree_link(&parent, &child2, tree_node_layout);
-    cx_tree_link(&parent, &child3, tree_node_layout);
+    cx_tree_add(&parent, &child1, tree_node_layout);
+    cx_tree_add(&parent, &child2, tree_node_layout);
+    cx_tree_add(&parent, &child3, tree_node_layout);
 
     CX_TEST_DO {
-        cx_tree_link(&child3, &child2, tree_node_layout);
+        cx_tree_add(&child3, &child2, tree_node_layout);
 
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
@@ -197,19 +152,19 @@
     }
 }
 
-CX_TEST(test_tree_unlink) {
+CX_TEST(test_tree_remove) {
     tree_node parent = {0};
     tree_node child1 = {0};
     tree_node child2 = {0};
     tree_node child3 = {0};
     tree_node child4 = {0};
-    cx_tree_link(&parent, &child1, tree_node_layout);
-    cx_tree_link(&parent, &child3, tree_node_layout);
-    cx_tree_link(&parent, &child4, tree_node_layout);
-    cx_tree_link(&child3, &child2, tree_node_layout);
+    cx_tree_add(&parent, &child1, tree_node_layout);
+    cx_tree_add(&parent, &child3, tree_node_layout);
+    cx_tree_add(&parent, &child4, tree_node_layout);
+    cx_tree_add(&child3, &child2, tree_node_layout);
 
     CX_TEST_DO {
-        cx_tree_unlink(&child3, tree_node_layout);
+        cx_tree_remove(&child3, tree_node_layout);
 
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
@@ -239,7 +194,7 @@
         CX_TEST_ASSERT(child2.next == NULL);
 
         // unlink first child from parent
-        cx_tree_unlink(&child1, tree_node_layout);
+        cx_tree_remove(&child1, tree_node_layout);
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
         CX_TEST_ASSERT(parent.parent == NULL);
@@ -252,22 +207,22 @@
     }
 }
 
-CX_TEST(test_tree_unlink_no_prev) {
+CX_TEST(test_tree_remove_no_prev) {
     tree_node parent = {0};
     tree_node child1 = {0};
     tree_node child2 = {0};
     tree_node child3 = {0};
     tree_node child4 = {0};
-    cx_tree_link(&parent, &child1, tree_node_layout_no_prev);
-    cx_tree_link(&parent, &child3, tree_node_layout_no_prev);
-    cx_tree_link(&parent, &child4, tree_node_layout_no_prev);
-    cx_tree_link(&child3, &child2, tree_node_layout_no_prev);
+    cx_tree_add(&parent, &child1, tree_node_layout_no_prev);
+    cx_tree_add(&parent, &child3, tree_node_layout_no_prev);
+    cx_tree_add(&parent, &child4, tree_node_layout_no_prev);
+    cx_tree_add(&child3, &child2, tree_node_layout_no_prev);
     void * const marker = (void*) 0xc0ffee;
     child1.prev = child2.prev = child3.prev = child4.prev = marker;
 
     CX_TEST_DO {
         // in contrast to the other test we here remove child 4 instead of 3!
-        cx_tree_unlink(&child4, tree_node_layout_no_prev);
+        cx_tree_remove(&child4, tree_node_layout_no_prev);
 
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
@@ -286,7 +241,7 @@
         CX_TEST_ASSERT(child4.next == NULL);
 
         // unlink first child from parent
-        cx_tree_unlink(&child1, tree_node_layout_no_prev);
+        cx_tree_remove(&child1, tree_node_layout_no_prev);
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
         CX_TEST_ASSERT(parent.parent == NULL);
@@ -304,7 +259,7 @@
     tree_node2 child = {0};
 
     CX_TEST_DO {
-        cx_tree_link(&parent, &child, tree_node2_layout);
+        cx_tree_add(&parent, &child, cx_tree_node_layout(tree_node2));
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
         CX_TEST_ASSERT(parent.parent == NULL);
@@ -325,9 +280,9 @@
     tree_node2 child3 = {0};
 
     CX_TEST_DO {
-        cx_tree_link(&parent, &child1, tree_node2_layout);
-        cx_tree_link(&parent, &child2, tree_node2_layout);
-        cx_tree_link(&parent, &child3, tree_node2_layout);
+        cx_tree_add(&parent, &child1, cx_tree_node_layout(tree_node2));
+        cx_tree_add(&parent, &child2, cx_tree_node_layout(tree_node2));
+        cx_tree_add(&parent, &child3, cx_tree_node_layout(tree_node2));
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
         CX_TEST_ASSERT(parent.parent == NULL);
@@ -358,12 +313,12 @@
     tree_node2 child1 = {0};
     tree_node2 child2 = {0};
     tree_node2 child3 = {0};
-    cx_tree_link(&parent, &child1, tree_node2_layout);
-    cx_tree_link(&parent, &child2, tree_node2_layout);
-    cx_tree_link(&parent, &child3, tree_node2_layout);
+    cx_tree_add(&parent, &child1, cx_tree_node_layout(tree_node2));
+    cx_tree_add(&parent, &child2, cx_tree_node_layout(tree_node2));
+    cx_tree_add(&parent, &child3, cx_tree_node_layout(tree_node2));
 
     CX_TEST_DO {
-        cx_tree_link(&child3, &child2, tree_node2_layout);
+        cx_tree_add(&child3, &child2, cx_tree_node_layout(tree_node2));
 
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
@@ -396,12 +351,12 @@
     tree_node2 child1 = {0};
     tree_node2 child2 = {0};
     tree_node2 child3 = {0};
-    cx_tree_link(&parent, &child1, tree_node2_layout);
-    cx_tree_link(&parent, &child3, tree_node2_layout);
-    cx_tree_link(&child3, &child2, tree_node2_layout);
+    cx_tree_add(&parent, &child1, cx_tree_node_layout(tree_node2));
+    cx_tree_add(&parent, &child3, cx_tree_node_layout(tree_node2));
+    cx_tree_add(&child3, &child2, cx_tree_node_layout(tree_node2));
 
     CX_TEST_DO {
-        cx_tree_unlink(&child3, tree_node2_layout);
+        cx_tree_remove(&child3, cx_tree_node_layout(tree_node2));
 
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
@@ -430,7 +385,7 @@
         CX_TEST_ASSERT(child2.next == NULL);
 
         // unlink last child from parent
-        cx_tree_unlink(&child1, tree_node2_layout);
+        cx_tree_remove(&child1, cx_tree_node_layout(tree_node2));
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
         CX_TEST_ASSERT(parent.parent == NULL);
@@ -469,20 +424,20 @@
         testnodes[i]->data = testdata[i];
     }
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
 
-    cx_tree_link(&a, &aa, tree_node_layout);
-    cx_tree_link(&a, &ab, tree_node_layout);
+    cx_tree_add(&a, &aa, tree_node_layout);
+    cx_tree_add(&a, &ab, tree_node_layout);
 
-    cx_tree_link(&b, &ba, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
 
-    cx_tree_link(&c, &ca, tree_node_layout);
-    cx_tree_link(&c, &cb, tree_node_layout);
-    cx_tree_link(&c, &cc, tree_node_layout);
+    cx_tree_add(&c, &ca, tree_node_layout);
+    cx_tree_add(&c, &cb, tree_node_layout);
+    cx_tree_add(&c, &cc, tree_node_layout);
 
-    cx_tree_link(&cb, &cba, tree_node_layout);
+    cx_tree_add(&cb, &cba, tree_node_layout);
 
     int s;
     int r;
@@ -490,38 +445,38 @@
     CX_TEST_DO {
         for (unsigned i = 0 ; i <= 10 ; i++) {
             s = testdata[i];
-            r = cx_tree_search_data(&root, 0, &s, test_tree_search_function,
+            r = cx_tree_search(&root, 0, &s, test_tree_search_function,
                                (void **) &n, tree_children(tree_node));
             CX_TEST_ASSERT(r == 0);
             CX_TEST_ASSERT(n == testnodes[i]);
         }
 
         s = -5;
-        r = cx_tree_search_data(&root, 0, &s, test_tree_search_function,
+        r = cx_tree_search(&root, 0, &s, test_tree_search_function,
                            (void **) &n, tree_children(tree_node));
         CX_TEST_ASSERT(r < 0);
         CX_TEST_ASSERT(n == NULL);
 
         s = 26;
-        r = cx_tree_search_data(&root, 0, &s, test_tree_search_function,
+        r = cx_tree_search(&root, 0, &s, test_tree_search_function,
                            (void **) &n, tree_children(tree_node));
         CX_TEST_ASSERT(r > 0);
         CX_TEST_ASSERT(n == &ba);
 
         s = 35;
-        r = cx_tree_search_data(&root, 0, &s, test_tree_search_function,
+        r = cx_tree_search(&root, 0, &s, test_tree_search_function,
                            (void **) &n, tree_children(tree_node));
         CX_TEST_ASSERT(r > 0);
         CX_TEST_ASSERT(n == &cb);
 
         s = 38;
-        r = cx_tree_search_data(&root, 0, &s, test_tree_search_function,
+        r = cx_tree_search(&root, 0, &s, test_tree_search_function,
                            (void **) &n, tree_children(tree_node));
         CX_TEST_ASSERT(r > 0);
         CX_TEST_ASSERT(n == &cba);
 
         s = 42;
-        r = cx_tree_search_data(&root, 0, &s, test_tree_search_function,
+        r = cx_tree_search(&root, 0, &s, test_tree_search_function,
                            (void **) &n, tree_children(tree_node));
         CX_TEST_ASSERT(r > 0);
         CX_TEST_ASSERT(n == &cc);
@@ -533,115 +488,115 @@
     root.path = "/";
     tree_node_file usr = {0};
     usr.path = "/usr/";
-    cx_tree_link(&root, &usr, tree_node_file_layout);
+    cx_tree_add(&root, &usr, cx_tree_node_layout(tree_node_file));
     tree_node_file home = {0};
     home.path = "/home/";
-    cx_tree_link(&root, &home, tree_node_file_layout);
+    cx_tree_add(&root, &home, cx_tree_node_layout(tree_node_file));
     tree_node_file doe = {0};
     doe.path = "/home/doe/";
-    cx_tree_link(&home, &doe, tree_node_file_layout);
+    cx_tree_add(&home, &doe, cx_tree_node_layout(tree_node_file));
     tree_node_file lib = {0};
     lib.path = "/usr/lib/";
-    cx_tree_link(&usr, &lib, tree_node_file_layout);
+    cx_tree_add(&usr, &lib, cx_tree_node_layout(tree_node_file));
     tree_node_file modules = {0};
     modules.path = "/usr/lib/modules/";
-    cx_tree_link(&lib, &modules, tree_node_file_layout);
+    cx_tree_add(&lib, &modules, cx_tree_node_layout(tree_node_file));
 
     CX_TEST_DO {
         int result;
         void *found;
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 1, "/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERTM(result == 0, "root not found");
         CX_TEST_ASSERT(found == &root);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 1, "/usr/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERT(result > 0);
         CX_TEST_ASSERT(found == &root);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 2, "/usr/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERT(result == 0);
         CX_TEST_ASSERT(found == &usr);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 2, "/usr/lib/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERT(result > 0);
         CX_TEST_ASSERT(found == &usr);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 3, "/usr/lib/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERTM(result == 0, "lib not found");
         CX_TEST_ASSERT(found == &lib);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 1, "/home/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERT(result > 0);
         CX_TEST_ASSERT(found == &root);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 2, "/home/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERTM(result == 0, "home not found");
         CX_TEST_ASSERT(found == &home);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 2, "/home/doe/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERT(result > 0);
         CX_TEST_ASSERT(found == &home);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 3, "/home/doe/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERTM(result == 0, "doe not found");
         CX_TEST_ASSERT(found == &doe);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 3, "/usr/lib/modules/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERT(result > 0);
         CX_TEST_ASSERT(found == &lib);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &root, 4, "/usr/lib/modules/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERTM(result == 0, "modules not found (start=root)");
         CX_TEST_ASSERT(found == &modules);
 
-        result = cx_tree_search_data(
+        result = cx_tree_search(
                 &usr, 3, "/usr/lib/modules/",
-                tree_node_file_search_data, &found,
+                tree_node_file_search_func, &found,
                 tree_children(tree_node_file)
         );
         CX_TEST_ASSERTM(result == 0, "modules not found (start=usr)");
@@ -661,7 +616,6 @@
         CX_TEST_ASSERT(!iter.base.remove);
         CX_TEST_ASSERT(iter.stack != NULL);
         CX_TEST_ASSERT(iter.stack_capacity > 0);
-        CX_TEST_ASSERT(iter.stack_size == 1);
         CX_TEST_ASSERT(iter.depth == 1);
         CX_TEST_ASSERT(iter.loc_next == offsetof(tree_node, next));
         CX_TEST_ASSERT(iter.loc_children == offsetof(tree_node, children));
@@ -681,7 +635,6 @@
         CX_TEST_ASSERT(!iter.base.remove);
         CX_TEST_ASSERT(iter.stack == NULL);
         CX_TEST_ASSERT(iter.stack_capacity == 0);
-        CX_TEST_ASSERT(iter.stack_size == 0);
         CX_TEST_ASSERT(iter.depth == 0);
         CX_TEST_ASSERT(iter.loc_next == offsetof(tree_node, next));
         CX_TEST_ASSERT(iter.loc_children == offsetof(tree_node, children));
@@ -712,16 +665,16 @@
     };
     tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
-    cx_tree_link(&a, &aa, tree_node_layout);
-    cx_tree_link(&a, &ab, tree_node_layout);
-    cx_tree_link(&b, &ba, tree_node_layout);
-    cx_tree_link(&c, &ca, tree_node_layout);
-    cx_tree_link(&c, &cb, tree_node_layout);
-    cx_tree_link(&c, &cc, tree_node_layout);
-    cx_tree_link(&cb, &cba, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
+    cx_tree_add(&a, &aa, tree_node_layout);
+    cx_tree_add(&a, &ab, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
+    cx_tree_add(&c, &ca, tree_node_layout);
+    cx_tree_add(&c, &cb, tree_node_layout);
+    cx_tree_add(&c, &cc, tree_node_layout);
+    cx_tree_add(&cb, &cba, tree_node_layout);
     CX_TEST_DO {
         CxTreeIterator iter = cx_tree_iterator(&root, false, tree_children(tree_node));
         unsigned chk = 0;
@@ -765,16 +718,16 @@
     tree_node cc = {0};
     tree_node cba = {0};
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
-    cx_tree_link(&a, &aa, tree_node_layout);
-    cx_tree_link(&a, &ab, tree_node_layout);
-    cx_tree_link(&b, &ba, tree_node_layout);
-    cx_tree_link(&c, &ca, tree_node_layout);
-    cx_tree_link(&c, &cb, tree_node_layout);
-    cx_tree_link(&c, &cc, tree_node_layout);
-    cx_tree_link(&cb, &cba, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
+    cx_tree_add(&a, &aa, tree_node_layout);
+    cx_tree_add(&a, &ab, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
+    cx_tree_add(&c, &ca, tree_node_layout);
+    cx_tree_add(&c, &cb, tree_node_layout);
+    cx_tree_add(&c, &cc, tree_node_layout);
+    cx_tree_add(&cb, &cba, tree_node_layout);
     CX_TEST_DO {
         CxTreeIterator iter = cx_tree_iterator(&root, true, tree_children(tree_node));
         unsigned chk = 0;
@@ -823,16 +776,16 @@
     tree_node cc = { 0 };
     tree_node cba = { 0 };
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
-    cx_tree_link(&a, &aa, tree_node_layout);
-    cx_tree_link(&a, &ab, tree_node_layout);
-    cx_tree_link(&b, &ba, tree_node_layout);
-    cx_tree_link(&c, &ca, tree_node_layout);
-    cx_tree_link(&c, &cb, tree_node_layout);
-    cx_tree_link(&c, &cc, tree_node_layout);
-    cx_tree_link(&cb, &cba, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
+    cx_tree_add(&a, &aa, tree_node_layout);
+    cx_tree_add(&a, &ab, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
+    cx_tree_add(&c, &ca, tree_node_layout);
+    cx_tree_add(&c, &cb, tree_node_layout);
+    cx_tree_add(&c, &cc, tree_node_layout);
+    cx_tree_add(&cb, &cba, tree_node_layout);
     CX_TEST_DO{
         CxTreeIterator iter = cx_tree_iterator(&b, true, tree_children(tree_node));
         unsigned chk = 0;
@@ -931,19 +884,19 @@
     target_dependencies.name = "dependencies";
     target_feature_dependencies.name = "dependencies";
 
-    cx_tree_link(&project, &config, tree_node_layout);
-    cx_tree_link(&project, &dependency1, tree_node_layout);
-    cx_tree_link(&project, &dependency2, tree_node_layout);
-    cx_tree_link(&project, &target, tree_node_layout);
-    cx_tree_link(&config, &var1, tree_node_layout);
-    cx_tree_link(&config, &var2, tree_node_layout);
-    cx_tree_link(&config, &var3, tree_node_layout);
-    cx_tree_link(&dependency1, &dependency1make, tree_node_layout);
-    cx_tree_link(&dependency2, &dependency2lang, tree_node_layout);
-    cx_tree_link(&dependency2, &dependency2make, tree_node_layout);
-    cx_tree_link(&target, &target_feature, tree_node_layout);
-    cx_tree_link(&target, &target_dependencies, tree_node_layout);
-    cx_tree_link(&target_feature, &target_feature_dependencies, tree_node_layout);
+    cx_tree_add(&project, &config, tree_node_layout);
+    cx_tree_add(&project, &dependency1, tree_node_layout);
+    cx_tree_add(&project, &dependency2, tree_node_layout);
+    cx_tree_add(&project, &target, tree_node_layout);
+    cx_tree_add(&config, &var1, tree_node_layout);
+    cx_tree_add(&config, &var2, tree_node_layout);
+    cx_tree_add(&config, &var3, tree_node_layout);
+    cx_tree_add(&dependency1, &dependency1make, tree_node_layout);
+    cx_tree_add(&dependency2, &dependency2lang, tree_node_layout);
+    cx_tree_add(&dependency2, &dependency2make, tree_node_layout);
+    cx_tree_add(&target, &target_feature, tree_node_layout);
+    cx_tree_add(&target, &target_dependencies, tree_node_layout);
+    cx_tree_add(&target_feature, &target_feature_dependencies, tree_node_layout);
 
     const char *expected =
             "<project><config><var></var><var></var><var></var></config>"
@@ -986,16 +939,16 @@
         tree_node *cc = cxCalloc(alloc, 1, sizeof(tree_node));
         tree_node *cba = cxCalloc(alloc, 1, sizeof(tree_node));
 
-        cx_tree_link(root, a, tree_node_layout);
-        cx_tree_link(root, b, tree_node_layout);
-        cx_tree_link(root, c, tree_node_layout);
-        cx_tree_link(a, aa, tree_node_layout);
-        cx_tree_link(a, ab, tree_node_layout);
-        cx_tree_link(b, ba, tree_node_layout);
-        cx_tree_link(c, ca, tree_node_layout);
-        cx_tree_link(c, cb, tree_node_layout);
-        cx_tree_link(c, cc, tree_node_layout);
-        cx_tree_link(cb, cba, tree_node_layout);
+        cx_tree_add(root, a, tree_node_layout);
+        cx_tree_add(root, b, tree_node_layout);
+        cx_tree_add(root, c, tree_node_layout);
+        cx_tree_add(a, aa, tree_node_layout);
+        cx_tree_add(a, ab, tree_node_layout);
+        cx_tree_add(b, ba, tree_node_layout);
+        cx_tree_add(c, ca, tree_node_layout);
+        cx_tree_add(c, cb, tree_node_layout);
+        cx_tree_add(c, cc, tree_node_layout);
+        cx_tree_add(cb, cba, tree_node_layout);
 
         CxTreeIterator iter = cx_tree_iterator(root, true, tree_children(tree_node));
         cx_foreach(tree_node *, node, iter) {
@@ -1013,10 +966,10 @@
     tree_node root = {0};
     tree_node child = {0};
     tree_node child2 = {0};
-    cx_tree_link(&root, &child, tree_node_layout);
-    cx_tree_link(&root, &child2, tree_node_layout);
+    cx_tree_add(&root, &child, tree_node_layout);
+    cx_tree_add(&root, &child2, tree_node_layout);
     CX_TEST_DO {
-        CxTreeVisitor iter = cx_tree_visitor(&root, tree_children(tree_node));
+        CxTreeIterator iter = cx_tree_visitor(&root, tree_children(tree_node));
         CX_TEST_ASSERT(iter.counter == 1);
         CX_TEST_ASSERT(iter.node == &root);
         CX_TEST_ASSERT(!iter.base.allow_remove);
@@ -1029,7 +982,7 @@
         CX_TEST_ASSERT(iter.queue_last != NULL);
         CX_TEST_ASSERT(iter.queue_next->node == &child2);
         CX_TEST_ASSERT(iter.queue_last->node == &child2);
-        cxTreeVisitorDispose(&iter);
+        cxTreeIteratorDispose(&iter);
         CX_TEST_ASSERT(iter.queue_next == NULL);
         CX_TEST_ASSERT(iter.queue_last == NULL);
     }
@@ -1056,18 +1009,18 @@
     };
     tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
-    cx_tree_link(&a, &aa, tree_node_layout);
-    cx_tree_link(&a, &ab, tree_node_layout);
-    cx_tree_link(&b, &ba, tree_node_layout);
-    cx_tree_link(&c, &ca, tree_node_layout);
-    cx_tree_link(&c, &cb, tree_node_layout);
-    cx_tree_link(&c, &cc, tree_node_layout);
-    cx_tree_link(&cb, &cba, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
+    cx_tree_add(&a, &aa, tree_node_layout);
+    cx_tree_add(&a, &ab, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
+    cx_tree_add(&c, &ca, tree_node_layout);
+    cx_tree_add(&c, &cb, tree_node_layout);
+    cx_tree_add(&c, &cc, tree_node_layout);
+    cx_tree_add(&cb, &cba, tree_node_layout);
     CX_TEST_DO {
-        CxTreeVisitor iter = cx_tree_visitor(&root, tree_children(tree_node));
+        CxTreeIterator iter = cx_tree_visitor(&root, tree_children(tree_node));
         unsigned chk = 0;
         cx_foreach(tree_node*, node, iter) {
             CX_TEST_ASSERT(node->data == 0);
@@ -1100,7 +1053,7 @@
     tree_node root = {0};
 
     CX_TEST_DO {
-        CxTreeVisitor iter = cx_tree_visitor(&root, tree_children(tree_node));
+        CxTreeIterator iter = cx_tree_visitor(&root, tree_children(tree_node));
         unsigned chk = 0;
         cx_foreach(tree_node*, node, iter) {
             CX_TEST_ASSERT(node == iter.node);
@@ -1124,12 +1077,12 @@
     };
     tree_node* actual_order[4];
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&a, &b, tree_node_layout);
-    cx_tree_link(&b, &c, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&a, &b, tree_node_layout);
+    cx_tree_add(&b, &c, tree_node_layout);
 
     CX_TEST_DO {
-        CxTreeVisitor iter = cx_tree_visitor(&root, tree_children(tree_node));
+        CxTreeIterator iter = cx_tree_visitor(&root, tree_children(tree_node));
         unsigned chk = 0;
         cx_foreach(tree_node*, node, iter) {
             CX_TEST_ASSERT(node == iter.node);
@@ -1164,16 +1117,16 @@
     };
     tree_node* actual_order[5];
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
-    cx_tree_link(&b, &ba, tree_node_layout);
-    cx_tree_link(&b, &bb, tree_node_layout);
-    cx_tree_link(&b, &bc, tree_node_layout);
-    cx_tree_link(&bb, &bba, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
+    cx_tree_add(&b, &bb, tree_node_layout);
+    cx_tree_add(&b, &bc, tree_node_layout);
+    cx_tree_add(&bb, &bba, tree_node_layout);
 
     CX_TEST_DO {
-        CxTreeVisitor iter = cx_tree_visitor(&b, tree_children(tree_node));
+        CxTreeIterator iter = cx_tree_visitor(&b, tree_children(tree_node));
         unsigned chk = 0;
         cx_foreach(tree_node*, node, iter) {
             CX_TEST_ASSERT(node == iter.node);
@@ -1213,18 +1166,18 @@
     };
     tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
-    cx_tree_link(&a, &aa, tree_node_layout);
-    cx_tree_link(&a, &ab, tree_node_layout);
-    cx_tree_link(&b, &ba, tree_node_layout);
-    cx_tree_link(&c, &ca, tree_node_layout);
-    cx_tree_link(&c, &cb, tree_node_layout);
-    cx_tree_link(&c, &cc, tree_node_layout);
-    cx_tree_link(&cb, &cba, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
+    cx_tree_add(&a, &aa, tree_node_layout);
+    cx_tree_add(&a, &ab, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
+    cx_tree_add(&c, &ca, tree_node_layout);
+    cx_tree_add(&c, &cb, tree_node_layout);
+    cx_tree_add(&c, &cc, tree_node_layout);
+    cx_tree_add(&cb, &cba, tree_node_layout);
     CX_TEST_DO {
-        CxTreeVisitor iter = cx_tree_visitor(&root, tree_children(tree_node));
+        CxTreeIterator iter = cx_tree_visitor(&root, tree_children(tree_node));
         unsigned chk = 0;
         cx_foreach(tree_node*, node, iter) {
             CX_TEST_ASSERT(node->data == 0);
@@ -1240,7 +1193,7 @@
                 CX_TEST_ASSERT(iter.depth == 3);
             }
             if (node == &c) {
-                cxTreeVisitorContinue(iter);
+                cxTreeIteratorContinue(iter);
             }
         }
         CX_TEST_ASSERT(iter.counter == 7);
@@ -1279,16 +1232,16 @@
     };
     tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
-    cx_tree_link(&a, &aa, tree_node_layout);
-    cx_tree_link(&a, &ab, tree_node_layout);
-    cx_tree_link(&b, &ba, tree_node_layout);
-    cx_tree_link(&c, &ca, tree_node_layout);
-    cx_tree_link(&c, &cb, tree_node_layout);
-    cx_tree_link(&c, &cc, tree_node_layout);
-    cx_tree_link(&cb, &cba, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
+    cx_tree_add(&a, &aa, tree_node_layout);
+    cx_tree_add(&a, &ab, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
+    cx_tree_add(&c, &ca, tree_node_layout);
+    cx_tree_add(&c, &cb, tree_node_layout);
+    cx_tree_add(&c, &cc, tree_node_layout);
+    cx_tree_add(&cb, &cba, tree_node_layout);
     CX_TEST_DO {
         CxTreeIterator iter = cx_tree_iterator(&root, false, tree_children(tree_node));
         unsigned chk = 0;
@@ -1337,16 +1290,16 @@
     tree_node cc = {0};
     tree_node cba = {0};
 
-    cx_tree_link(&root, &a, tree_node_layout);
-    cx_tree_link(&root, &b, tree_node_layout);
-    cx_tree_link(&root, &c, tree_node_layout);
-    cx_tree_link(&a, &aa, tree_node_layout);
-    cx_tree_link(&a, &ab, tree_node_layout);
-    cx_tree_link(&b, &ba, tree_node_layout);
-    cx_tree_link(&c, &ca, tree_node_layout);
-    cx_tree_link(&c, &cb, tree_node_layout);
-    cx_tree_link(&c, &cc, tree_node_layout);
-    cx_tree_link(&cb, &cba, tree_node_layout);
+    cx_tree_add(&root, &a, tree_node_layout);
+    cx_tree_add(&root, &b, tree_node_layout);
+    cx_tree_add(&root, &c, tree_node_layout);
+    cx_tree_add(&a, &aa, tree_node_layout);
+    cx_tree_add(&a, &ab, tree_node_layout);
+    cx_tree_add(&b, &ba, tree_node_layout);
+    cx_tree_add(&c, &ca, tree_node_layout);
+    cx_tree_add(&c, &cb, tree_node_layout);
+    cx_tree_add(&c, &cc, tree_node_layout);
+    cx_tree_add(&cb, &cba, tree_node_layout);
     CX_TEST_DO {
         CxTreeIterator iter = cx_tree_iterator(&root, true, tree_children(tree_node));
         unsigned chk = 0;
@@ -1383,520 +1336,25 @@
     }
 }
 
-CX_TEST(test_tree_add_one) {
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    tree_node_file root = {0};
-    root.path = "/";
-    tree_node_file usr = {0};
-    usr.path = "/usr/";
-    cx_tree_link(&root, &usr, tree_node_file_layout);
-    tree_node_file home = {0};
-    home.path = "/home/";
-    cx_tree_link(&root, &home, tree_node_file_layout);
-    tree_node_file lib = {0};
-    lib.path = "/usr/lib/";
-    cx_tree_link(&usr, &lib, tree_node_file_layout);
-
-    CX_TEST_DO {
-        tree_node_file *foo;
-        int result;
-        result = cx_tree_add(
-                "/home/foo/",
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                (void **) &foo, &root,
-                tree_node_file_layout
-        );
-        CX_TEST_ASSERT(result == 0);
-        CX_TEST_ASSERT(foo != NULL);
-        const char *bar_path = "/home/foo/bar/";
-        void *failed;
-        size_t added = cx_tree_add_array(
-                bar_path, 1, sizeof(const char *),
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                &failed, &root,
-                tree_node_file_layout
-        );
-        CX_TEST_ASSERT(added == 1);
-        CX_TEST_ASSERT(failed == NULL);
-        tree_node_file *bar = foo->children;
-        CX_TEST_ASSERT(bar != NULL);
-        CX_TEST_ASSERT(bar->parent == foo);
-        CX_TEST_ASSERT(bar->path == bar_path);
-        CX_TEST_ASSERT(foo->parent == &home);
-
-        tree_node_file *new_node;
-        result = cx_tree_add(
-                "newroot",
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                (void **) &new_node, &root,
-                tree_node_file_layout
-        );
-        CX_TEST_ASSERT(0 != result);
-        CX_TEST_ASSERT(NULL != new_node);
-        CX_TEST_ASSERT(new_node->children == NULL);
-        CX_TEST_ASSERT(new_node->parent == NULL);
-
-        CX_TEST_ASSERT(talloc.alloc_total == 3);
-
-        cxFree(alloc, foo);
-        cxFree(alloc, bar);
-        cxFree(alloc, new_node);
-
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
-CX_TEST(test_tree_add_one_existing) {
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    tree_node_file root = {0};
-    root.path = "/";
-    tree_node_file usr = {0};
-    usr.path = "/usr/";
-    cx_tree_link(&root, &usr, tree_node_file_layout);
-    tree_node_file home = {0};
-    home.path = "/home/";
-    cx_tree_link(&root, &home, tree_node_file_layout);
-    tree_node_file lib = {0};
-    lib.path = "/usr/lib/";
-    cx_tree_link(&usr, &lib, tree_node_file_layout);
-
-    CX_TEST_DO {
-        tree_node_file *node;
-        int result = cx_tree_add(
-                "/usr/lib/",
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                (void **) &node, &root,
-                tree_node_file_layout
-        );
-        CX_TEST_ASSERT(result == 0);
-        CX_TEST_ASSERT(node != &lib);
-        CX_TEST_ASSERT(node->prev == &lib);
-        CX_TEST_ASSERT(lib.next == node);
-        CX_TEST_ASSERT(node->parent == &usr);
-        CX_TEST_ASSERT(talloc.alloc_total == 1);
-        cxFree(alloc, node);
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
-CX_TEST(test_tree_add_one_no_match) {
-    tree_node_file root = {0};
-    root.path = "/mnt/";
-
-    CX_TEST_DO {
-        tree_node_file *node = NULL;
-        int result = cx_tree_add(
-                "/usr/lib/",
-                tree_node_file_search,
-                tree_node_file_create, NULL,
-                (void **) &node, &root,
-                tree_node_file_layout
-        );
-        CX_TEST_ASSERT(result != 0);
-        CX_TEST_ASSERT(node != NULL);
-        CX_TEST_ASSERT(node->parent == NULL);
-        CX_TEST_ASSERT(node->children == NULL);
-        cxFreeDefault(node);
-        node = NULL;
-        size_t added = cx_tree_add_array(
-                "/", 1, sizeof(const char *),
-                tree_node_file_search,
-                tree_node_file_create, NULL,
-                (void **) &node, &root,
-                tree_node_file_layout
-        );
-        CX_TEST_ASSERT(added == 0);
-        CX_TEST_ASSERT(node != NULL);
-        CX_TEST_ASSERT(node->parent == NULL);
-        CX_TEST_ASSERT(node->children == NULL);
-        cxFreeDefault(node);
-    }
-}
-
-CX_TEST(test_tree_add_duplicate_root) {
-    tree_node_file root = {0};
-    root.path = "/";
-    CX_TEST_DO {
-        tree_node_file *node;
-        int result = cx_tree_add(
-                "/",
-                tree_node_file_search,
-                tree_node_file_create, NULL,
-                (void **) &node, &root,
-                tree_node_file_layout
-        );
-        CX_TEST_ASSERT(result == 0);
-        CX_TEST_ASSERT(root.children == node);
-        CX_TEST_ASSERT(node->parent == &root);
-        cxFreeDefault(node);
-    }
-}
-
-CX_TEST(test_tree_add_zero) {
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    tree_node_file root = {0};
-    root.path = "/";
-    CX_TEST_DO {
-        void *failed;
-
-        size_t processed = cx_tree_add_array(
-                (void *) 0xc0ffee, 0, sizeof(void *),
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                &failed, &root, tree_node_file_layout
-        );
-        CX_TEST_ASSERT(failed == NULL);
-        CX_TEST_ASSERT(processed == 0);
-        CX_TEST_ASSERT(talloc.alloc_total == 0);
-
-        CxIterator iter = cxIterator(NULL, sizeof(void *), 0);
-        processed = cx_tree_add_iter(
-                cxIteratorRef(iter),
-                10, // deliberately specify more than the iter has
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                &failed, &root, tree_node_file_layout
-        );
-        CX_TEST_ASSERT(processed == 0);
-        CX_TEST_ASSERT(failed == NULL);
-        CX_TEST_ASSERT(talloc.alloc_total == 0);
-
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
-CX_TEST(test_tree_add_many) {
-    // adds many elements to an existing tree
-
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    tree_node_file root = {0};
-    root.path = "/";
-    tree_node_file usr = {0};
-    usr.path = "/usr/";
-    cx_tree_link(&root, &usr, tree_node_file_layout);
-    tree_node_file home = {0};
-    home.path = "/home/";
-    cx_tree_link(&root, &home, tree_node_file_layout);
-    tree_node_file lib = {0};
-    lib.path = "/usr/lib/";
-    cx_tree_link(&usr, &lib, tree_node_file_layout);
-
-    CX_TEST_DO {
-        void *failed;
-
-        const char *paths[] = {
-                "/home/foo/",
-                "/home/foo/bar",
-                "/usr/lib64/",
-                "/usr/lib/foo.so"
-        };
-
-        size_t processed = cx_tree_add_array(
-                paths, 4, sizeof(const char *),
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                &failed, &root, tree_node_file_layout
-        );
-
-        CX_TEST_ASSERT(failed == NULL);
-        CX_TEST_ASSERT(processed == 4);
-        CX_TEST_ASSERT(talloc.alloc_total == 4);
-
-        CX_TEST_ASSERT(home.children == home.last_child);
-        tree_node_file *foo = home.children;
-        CX_TEST_ASSERT(foo != NULL && foo->path == paths[0]);
-        CX_TEST_ASSERT(foo->children == foo->last_child);
-        tree_node_file *bar = foo->children;
-        CX_TEST_ASSERT(bar != NULL && bar->path == paths[1]);
-        CX_TEST_ASSERT(usr.children != usr.last_child);
-        tree_node_file *lib64 = usr.last_child;
-        CX_TEST_ASSERT(lib64 != NULL);
-        CX_TEST_ASSERT(lib64->path == paths[2]);
-        CX_TEST_ASSERT(lib64->prev == &lib);
-        CX_TEST_ASSERT(lib64->parent == &usr);
-        CX_TEST_ASSERT(lib.children != NULL);
-        tree_node_file *libfoo = lib.children;
-        CX_TEST_ASSERT(libfoo != NULL && libfoo->path == paths[3]);
-
-        cxFree(alloc, foo);
-        cxFree(alloc, bar);
-        cxFree(alloc, lib64);
-        cxFree(alloc, libfoo);
-
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
-CX_TEST(test_tree_add_many_but_not_all) {
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    tree_node_file root = {0};
-    root.path = "/";
-    tree_node_file usr = {0};
-    usr.path = "/usr/";
-    cx_tree_link(&root, &usr, tree_node_file_layout);
-    tree_node_file home = {0};
-    home.path = "/home/";
-    cx_tree_link(&root, &home, tree_node_file_layout);
-    tree_node_file lib = {0};
-    lib.path = "/usr/lib/";
-    cx_tree_link(&usr, &lib, tree_node_file_layout);
-
-    CX_TEST_DO {
-        void *failed;
-
-        const char *paths[] = {
-                "/home/foo/",
-                "/home/foo/bar",
-                "/usr/lib64/",
-                "/usr/lib/foo.so"
-        };
-        // create iterator for 4 elements, but choose to insert only 3 of them
-        CxIterator iter = cxIterator(paths, sizeof(const char*), 4);
-        size_t processed = cx_tree_add_iter(
-                cxIteratorRef(iter), 3,
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                &failed, &root, tree_node_file_layout
-        );
-
-        CX_TEST_ASSERT(cxIteratorValid(iter));
-        CX_TEST_ASSERT(cxIteratorCurrent(iter) == &paths[3]);
-
-        CX_TEST_ASSERT(failed == NULL);
-        CX_TEST_ASSERT(processed == 3);
-        CX_TEST_ASSERT(talloc.alloc_total == 3);
-
-        CX_TEST_ASSERT(home.children == home.last_child);
-        tree_node_file *foo = home.children;
-        CX_TEST_ASSERT(foo != NULL && foo->path == paths[0]);
-        CX_TEST_ASSERT(foo->children == foo->last_child);
-        tree_node_file *bar = foo->children;
-        CX_TEST_ASSERT(bar != NULL && bar->path == paths[1]);
-        CX_TEST_ASSERT(usr.children != usr.last_child);
-        tree_node_file *lib64 = usr.last_child;
-        CX_TEST_ASSERT(lib64 != NULL);
-        CX_TEST_ASSERT(lib64->path == paths[2]);
-        CX_TEST_ASSERT(lib64->prev == &lib);
-        CX_TEST_ASSERT(lib64->parent == &usr);
-        CX_TEST_ASSERT(lib.children == NULL);
-
-        cxFree(alloc, foo);
-        cxFree(alloc, bar);
-        cxFree(alloc, lib64);
-
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
-CX_TEST(test_tree_add_many_with_dupl_and_no_match) {
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    tree_node_file root = {0};
-    root.path = "/mnt/";
-
-    CX_TEST_DO {
-        tree_node_file *failed;
-
-        const char *paths[] = {
-                "/mnt/sdcard/",
-                "/mnt/foo/",
-                "/mnt/sdcard/",
-                "/home/",
-                "/usr/"
-        };
-
-        size_t processed = cx_tree_add_array(
-                paths, 5, sizeof(const char *),
-                tree_node_file_search,
-                tree_node_file_create, alloc,
-                (void **) &failed, &root, tree_node_file_layout
-        );
-
-        CX_TEST_ASSERT(processed == 3);
-        CX_TEST_ASSERT(failed != NULL);
-        CX_TEST_ASSERT(failed->parent == NULL);
-        CX_TEST_ASSERT(failed->children == NULL);
-        CX_TEST_ASSERT(strcmp(failed->path, "/home/") == 0);
-        cxFree(alloc, failed);
-
-        CX_TEST_ASSERT(root.children != root.last_child);
-        CX_TEST_ASSERT(strcmp(root.children->path, "/mnt/sdcard/") == 0);
-        CX_TEST_ASSERT(strcmp(root.last_child->path, "/mnt/sdcard/") == 0);
-        CX_TEST_ASSERT(strcmp(root.children->next->path, "/mnt/foo/") == 0);
-        CX_TEST_ASSERT(strcmp(root.last_child->prev->path, "/mnt/foo/") == 0);
-
-        CxTreeIterator iter = cx_tree_iterator(
-                &root, true,
-                offsetof(tree_node_file, children),
-                offsetof(tree_node_file, next)
-        );
-        cx_foreach(tree_node_file *, node, iter) {
-            if (iter.exiting) {
-                if (node != &root) {
-                    cxFree(alloc, node);
-                }
-            }
-        }
-
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
-static CX_TEST_SUBROUTINE(test_tree_add_create_from_array_impl,
-                          CxAllocator *alloc, const char **paths) {
-    tree_node_file root = {0};
-    root.path = "/";
-
-    void *failed;
-    size_t processed = cx_tree_add_array(
-            paths, 10, sizeof(const char *),
-            tree_node_file_search,
-            tree_node_file_create, alloc,
-            &failed, &root, tree_node_file_layout
-    );
-
-    CX_TEST_ASSERT(failed == NULL);
-    CX_TEST_ASSERT(processed == 10);
-
-    const char *exp_order[] = {
-            "/",
-            "/usr/",
-            "/usr/lib/",
-            "/usr/lib/libbumm.so",
-            "/home/",
-            "/home/foo/",
-            "/var/",
-            "/var/www/",
-            "/var/www/vhosts/",
-            "/var/www/vhosts/live/",
-            "/var/www/vhosts/live/htdocs/"
-    };
-    unsigned exp_depth[] = {
-            1,
-            2,
-            3,
-            4,
-            2,
-            3,
-            2,
-            3,
-            4,
-            5,
-            6
-    };
-
-    CxTreeIterator iter = cx_tree_iterator(
-            &root, true,
-            offsetof(tree_node_file, children),
-            offsetof(tree_node_file, next)
-    );
-    cx_foreach(tree_node_file *, node, iter) {
-        if (iter.exiting) {
-            if (node != &root) {
-                cxFree(alloc, node);
-            }
-        } else {
-            CX_TEST_ASSERT(iter.counter <= 11);
-            CX_TEST_ASSERT(iter.depth == exp_depth[iter.counter - 1]);
-            CX_TEST_ASSERT(strcmp(node->path, exp_order[iter.counter - 1]) == 0);
-        }
-    }
-}
-
-CX_TEST(test_tree_add_create_from_array) {
-    // creates an entirely new tree from an array
-
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    CX_TEST_DO {
-        const char *paths[] = {
-                "/usr/",
-                "/home/",
-                "/usr/lib/",
-                "/usr/lib/libbumm.so",
-                "/var/",
-                "/var/www/",
-                "/var/www/vhosts/",
-                "/var/www/vhosts/live/",
-                "/var/www/vhosts/live/htdocs/",
-                "/home/foo/"
-        };
-
-        const char *scrambled_paths[] = {
-                "/usr/",
-                "/home/",
-                "/var/www/vhosts/live/",
-                "/usr/lib/",
-                "/var/",
-                "/var/www/",
-                "/usr/lib/libbumm.so",
-                "/var/www/vhosts/",
-                "/var/www/vhosts/live/htdocs/",
-                "/home/foo/"
-        };
-
-        // no matter how the original array is sorted,
-        // the resulting tree should be the same
-        CX_TEST_CALL_SUBROUTINE(test_tree_add_create_from_array_impl, alloc,
-                                paths);
-        CX_TEST_CALL_SUBROUTINE(test_tree_add_create_from_array_impl, alloc,
-                                scrambled_paths);
-
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
 CX_TEST(test_tree_high_create) {
     CxTestingAllocator talloc;
     cx_testing_allocator_init(&talloc);
     CX_TEST_DO {
         CxTree *tree = cxTreeCreate(
                 &talloc.base,
-                tree_node_file_create_hl,
-                tree_node_file_search,
-                tree_node_file_search_data,
-                tree_node_file_layout
+                sizeof(tree_node_file),
+                CX_STORE_POINTERS,
+                NULL, offsetof(tree_node_file, path),
+                cx_tree_node_layout(tree_node_file)
         );
-        CX_TEST_ASSERT(tree->cl != NULL);
         CX_TEST_ASSERT(tree->collection.allocator == &talloc.base);
-        CX_TEST_ASSERT(tree->node_create == tree_node_file_create_hl);
-        CX_TEST_ASSERT(tree->search == tree_node_file_search);
-        CX_TEST_ASSERT(tree->search_data == tree_node_file_search_data);
+        CX_TEST_ASSERT(tree->node_size == sizeof(tree_node_file));
+        CX_TEST_ASSERT(tree->collection.elem_size == sizeof(void*));
         CX_TEST_ASSERT(tree->collection.size == 0);
         CX_TEST_ASSERT(tree->collection.simple_destructor == NULL);
         CX_TEST_ASSERT(tree->collection.advanced_destructor == (cx_destructor_func2) cxFree);
         CX_TEST_ASSERT(tree->collection.destructor_data == &talloc.base);
-        CX_TEST_ASSERT(tree->collection.store_pointer == false);
+        CX_TEST_ASSERT(tree->collection.store_pointer == true);
         CX_TEST_ASSERT(tree->collection.sorted == false);
         CX_TEST_ASSERT(tree->root == NULL);
         CX_TEST_ASSERT(tree->loc_parent == offsetof(tree_node_file, parent));
@@ -1904,6 +1362,7 @@
         CX_TEST_ASSERT(tree->loc_last_child == offsetof(tree_node_file, last_child));
         CX_TEST_ASSERT(tree->loc_prev == offsetof(tree_node_file, prev));
         CX_TEST_ASSERT(tree->loc_next == offsetof(tree_node_file, next));
+        CX_TEST_ASSERT(tree->loc_data == offsetof(tree_node_file, path));
 
         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
         CX_TEST_ASSERT(talloc.alloc_total == 1);
@@ -1914,65 +1373,13 @@
     cx_testing_allocator_destroy(&talloc);
 }
 
-CX_TEST(test_tree_high_create_simple) {
-    CX_TEST_DO {
-        CxTree *tree = cxTreeCreateSimple(
-                NULL, // shall fall back to the default allocator
-                tree_node_file_create_hl,
-                tree_node_file_search,
-                tree_node_file_search_data
-        );
-        CX_TEST_ASSERT(tree->cl != NULL);
-        CX_TEST_ASSERT(tree->collection.allocator == cxDefaultAllocator);
-        CX_TEST_ASSERT(tree->node_create == tree_node_file_create_hl);
-        CX_TEST_ASSERT(tree->search == tree_node_file_search);
-        CX_TEST_ASSERT(tree->search_data == tree_node_file_search_data);
-        CX_TEST_ASSERT(tree->collection.size == 0);
-        CX_TEST_ASSERT(tree->collection.simple_destructor == NULL);
-        CX_TEST_ASSERT(tree->collection.advanced_destructor == (cx_destructor_func2) cxFree);
-        CX_TEST_ASSERT(tree->collection.destructor_data == cxDefaultAllocator);
-        CX_TEST_ASSERT(tree->root == NULL);
-        CX_TEST_ASSERT(tree->loc_parent == offsetof(struct cx_tree_node_base_s, parent));
-        CX_TEST_ASSERT(tree->loc_children == offsetof(struct cx_tree_node_base_s, children));
-        CX_TEST_ASSERT(tree->loc_last_child == offsetof(struct cx_tree_node_base_s, last_child));
-        CX_TEST_ASSERT(tree->loc_prev == offsetof(struct cx_tree_node_base_s, prev));
-        CX_TEST_ASSERT(tree->loc_next == offsetof(struct cx_tree_node_base_s, next));
-        cxTreeFree(tree);
-    }
-}
-
-CX_TEST(test_tree_high_create_wrapped) {
-    tree_node root = {0}, child1 = {0}, child2 = {0}, child3 = {0};
-    cx_tree_link(&root, &child1, tree_node_layout);
-    cx_tree_link(&root, &child2, tree_node_layout);
-    cx_tree_link(&child1, &child3, tree_node_layout);
-    CX_TEST_DO {
-        CxTree *tree = cxTreeCreateWrapped(NULL, &root, tree_node_layout);
-        CX_TEST_ASSERT(tree->cl != NULL);
-        CX_TEST_ASSERT(tree->collection.allocator == cxDefaultAllocator);
-        CX_TEST_ASSERT(tree->node_create == NULL);
-        CX_TEST_ASSERT(tree->search == NULL);
-        CX_TEST_ASSERT(tree->search_data == NULL);
-        CX_TEST_ASSERT(tree->root == &root);
-        CX_TEST_ASSERT(tree->collection.size == 4);
-        CX_TEST_ASSERT(tree->collection.simple_destructor == NULL);
-        CX_TEST_ASSERT(tree->collection.advanced_destructor == NULL);
-        CX_TEST_ASSERT(tree->collection.destructor_data == NULL);
-        CX_TEST_ASSERT(tree->loc_parent == offsetof(tree_node, parent));
-        CX_TEST_ASSERT(tree->loc_children == offsetof(tree_node, children));
-        CX_TEST_ASSERT(tree->loc_last_child == -1);
-        CX_TEST_ASSERT(tree->loc_prev == offsetof(tree_node, prev));
-        CX_TEST_ASSERT(tree->loc_next == offsetof(tree_node, next));
-        cxTreeFree(tree);
-    }
-}
-
 CX_TEST(test_tree_high_tree_depth) {
     tree_node root = {0}, child1 = {0}, child2 = {0}, child3 = {0};
-    cx_tree_link(&root, &child1, tree_node_layout);
-    cx_tree_link(&root, &child2, tree_node_layout);
-    cx_tree_link(&child1, &child3, tree_node_layout);
-    CxTree *tree = cxTreeCreateWrapped(cxDefaultAllocator, &root, tree_node_layout);
+    cx_tree_add(&root, &child1, tree_node_layout);
+    cx_tree_add(&root, &child2, tree_node_layout);
+    cx_tree_add(&child1, &child3, tree_node_layout);
+    CxTree *tree = cxTreeCreate(cxDefaultAllocator, sizeof(tree_node),
+        sizeof(int), &root, offsetof(tree_node, data), tree_node_layout);
     CX_TEST_DO {
         CX_TEST_ASSERT(cxTreeDepth(tree) == 3);
         CX_TEST_ASSERT(cxTreeSubtreeDepth(tree, &root) == 3);
@@ -1980,13 +1387,8 @@
         CX_TEST_ASSERT(cxTreeSubtreeDepth(tree, &child2) == 1);
         CX_TEST_ASSERT(cxTreeSubtreeDepth(tree, &child3) == 1);
 
-        CxTree *empty = cxTreeCreate(
-                cxDefaultAllocator,
-                tree_node_file_create_hl,
-                tree_node_file_search,
-                tree_node_file_search_data,
-                tree_node_file_layout
-        );
+        CxTree *empty = cxTreeCreate(cxDefaultAllocator, sizeof(tree_node),
+            sizeof(int), NULL, offsetof(tree_node, data), tree_node_layout);
         CX_TEST_ASSERT(cxTreeDepth(empty) == 0);
         cxTreeFree(empty);
     }
@@ -1995,7 +1397,8 @@
 
 CX_TEST(test_tree_high_set_parent) {
     tree_node root = {0}, child1 = {0}, child2 = {0}, child3 = {0};
-    CxTree *tree = cxTreeCreateWrapped(cxDefaultAllocator, &root, tree_node_layout);
+    CxTree *tree = cxTreeCreate(cxDefaultAllocator, sizeof(tree_node),
+        sizeof(int), &root, offsetof(tree_node, data), tree_node_layout);
     CX_TEST_DO {
         cxTreeSetParent(tree, &root, &child1);
         cxTreeSetParent(tree, &root, &child2);
@@ -2012,85 +1415,14 @@
         CX_TEST_ASSERT(cxTreeSubtreeDepth(tree, &child2) == 2);
         CX_TEST_ASSERT(cxTreeSubtreeDepth(tree, &child3) == 1);
 
-        CxTree *empty = cxTreeCreate(
-                cxDefaultAllocator,
-                tree_node_file_create_hl,
-                tree_node_file_search,
-                tree_node_file_search_data,
-                tree_node_file_layout
-        );
+        CxTree *empty = cxTreeCreate(cxDefaultAllocator, sizeof(tree_node),
+            sizeof(int), NULL, offsetof(tree_node, data), tree_node_layout);
         CX_TEST_ASSERT(cxTreeDepth(empty) == 0);
         cxTreeFree(empty);
     }
     cxTreeFree(tree);
 }
 
-CX_TEST(test_tree_high_insert_one) {
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    CX_TEST_DO {
-        CxTree *tree = cxTreeCreate(
-                alloc, tree_node_file_create_hl,
-                tree_node_file_search, tree_node_file_search_data,
-                tree_node_file_layout
-        );
-
-        int result = 0;
-        result |= cxTreeInsert(tree, "/");
-        result |= cxTreeInsert(tree, "/usr/");
-        result |= cxTreeInsert(tree, "/home/");
-        result |= cxTreeInsert(tree, "/usr/lib/");
-        result |= cxTreeInsert(tree, "/home/foo/");
-        CX_TEST_ASSERT(result == 0);
-        CX_TEST_ASSERT(1 == cxTreeInsertArray(tree, "/home/foo/bar/", sizeof(const char*), 1));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 6);
-        CX_TEST_ASSERT(0 != cxTreeInsert(tree, "newroot"));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 6);
-
-        CX_TEST_ASSERT(talloc.alloc_total == 8);
-        CX_TEST_ASSERT(talloc.free_total == 1); // the one that could not be added
-
-        cxTreeFree(tree);
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
-CX_TEST(test_tree_high_insert_many) {
-    CxTestingAllocator talloc;
-    cx_testing_allocator_init(&talloc);
-    CxAllocator *alloc = &talloc.base;
-
-    CX_TEST_DO {
-        CxTree *tree = cxTreeCreate(
-                alloc, tree_node_file_create_hl,
-                tree_node_file_search, tree_node_file_search_data,
-                tree_node_file_layout
-        );
-
-        const char *paths[] = {
-                "/",
-                "/usr/",
-                "/home/",
-                "/usr/lib/",
-                "/home/foo/",
-                "/home/foo/bar/",
-                "newroot"
-        };
-        CX_TEST_ASSERT(6 == cxTreeInsertArray(tree, paths, sizeof(const char*), 7));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 6);
-
-        CX_TEST_ASSERT(talloc.alloc_total == 8);
-        CX_TEST_ASSERT(talloc.free_total == 1); // the one that could not be added
-
-        cxTreeFree(tree);
-        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
-    }
-    cx_testing_allocator_destroy(&talloc);
-}
-
 static void test_tree_remove_node_relink_mock(
         void *node,
         CX_UNUSED const void *oldp,
@@ -2105,167 +1437,182 @@
     }
 }
 
+static CX_TEST_SUBROUTINE(validate_tree_high_add_find_remove_nodes,
+            CxAllocator *alloc, bool use_dfs) {
+    CxTree *tree = cxTreeCreate(alloc,
+        sizeof(tree_node_file),
+        CX_STORE_POINTERS,
+        NULL, offsetof(tree_node_file, path),
+        cx_tree_node_layout(tree_node_file)
+    );
+    cxSetCompareFunc(tree, strcmp);
+
+    {
+        tree_node_file *root = cxTreeCreateRootData(tree, "/");
+        tree_node_file *home = cxTreeAddData(tree, root, "/home/");
+        tree_node_file *foo = cxTreeAddData(tree, home, "/home/foo/");
+        cxTreeAddData(tree, foo, "/home/foo/bar/");
+        tree_node_file *usr = cxTreeAddData(tree, root, "/usr/");
+        cxTreeAddData(tree, usr, "/usr/lib/");
+    }
+
+    tree_node_file *foo = cxTreeFind(tree, "/home/foo/", use_dfs);
+    CX_TEST_ASSERT(NULL != foo);
+    CX_TEST_ASSERT(0 == strcmp("/home/foo/", foo->path));
+    CX_TEST_ASSERT(NULL != foo->parent);
+    CX_TEST_ASSERT(0 == strcmp("/home/", foo->parent->path));
+    CX_TEST_ASSERT(cxTreeSize(tree) == 6);
+
+    CX_TEST_ASSERT(NULL != cxTreeAddData(tree, foo->parent, "/home/baz/"));
+    tree_node_file *baz = cxTreeFind(tree, "/home/baz/", use_dfs);
+    CX_TEST_ASSERT(NULL != baz);
+    CX_TEST_ASSERT(0 == strcmp("/home/baz/", baz->path));
+    CX_TEST_ASSERT(NULL != baz->parent);
+    CX_TEST_ASSERT(0 == strcmp("/home/", baz->parent->path));
+    CX_TEST_ASSERT(cxTreeSize(tree) == 7);
+
+    tree_node_file *home = cxTreeFind(tree, "/home/", use_dfs);
+    CX_TEST_ASSERT(NULL == cxTreeFindInSubtree(tree, "/usr/", foo, 0, use_dfs));
+    tree_node_file *bar = cxTreeFindInSubtree(tree, "/home/foo/bar/", home, 0, use_dfs);
+    CX_TEST_ASSERT(NULL != bar);
+    CX_TEST_ASSERT(0 == strcmp("/home/foo/bar/", bar->path));
+    CX_TEST_ASSERT(bar->parent == foo);
+
+    tree_node_file *share = cxCalloc(alloc, 1, sizeof(tree_node_file));
+    share->path = "/usr/share/";
+    tree_node_file *usr = cxTreeFind(tree, "/usr/", use_dfs);
+    cxTreeAddNode(tree, usr, share);
+    CX_TEST_ASSERT(cxTreeSize(tree) == 8);
+
+    cxTreeRemoveSubtree(tree, foo);
+    CX_TEST_ASSERT(cxTreeSize(tree) == 6);
+    CX_TEST_ASSERT(foo->children == bar);
+    CX_TEST_ASSERT(foo->last_child == bar);
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/", use_dfs));
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/bar/", use_dfs));
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/bar/", use_dfs));
+
+    CX_TEST_ASSERT(0 == cxTreeRemoveNode(tree, usr, test_tree_remove_node_relink_mock));
+    CX_TEST_ASSERT(cxTreeSize(tree) == 5);
+    CX_TEST_ASSERT(usr->parent == NULL);
+    CX_TEST_ASSERT(usr->children == NULL);
+    CX_TEST_ASSERT(usr->last_child == NULL);
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/", use_dfs));
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/lib/", use_dfs));
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/share/", use_dfs));
+    tree_node_file *relinked_share = cxTreeFind(tree, "/share/", use_dfs);
+    tree_node_file *relinked_lib = cxTreeFind(tree, "/lib/", use_dfs);
+    CX_TEST_ASSERT(relinked_share != NULL);
+    CX_TEST_ASSERT(relinked_share->parent == tree->root);
+    CX_TEST_ASSERT(relinked_lib != NULL);
+    CX_TEST_ASSERT(relinked_lib->parent == tree->root);
+    CX_TEST_ASSERT(NULL != cxTreeFind(tree, "/home/", use_dfs));
+    cxTreeFree(tree);
+
+    // we are not done yet, because we need to free the removed stuff
+    cxFree(alloc, usr);
+    // for the subtree, we use a little trick and wrap it in a new tree
+    CxTree *foo_tree = cxTreeCreate(alloc,
+            sizeof(tree_node_file),
+            CX_STORE_POINTERS,
+            foo, offsetof(tree_node_file, path),
+            cx_tree_node_layout(tree_node_file)
+    );
+    cxSetAdvancedDestructor(foo_tree, cxFree, alloc);
+    cxTreeFree(foo_tree);
+}
+
 CX_TEST(test_tree_high_add_find_remove_nodes) {
     CxTestingAllocator talloc;
     cx_testing_allocator_init(&talloc);
     CxAllocator *alloc = &talloc.base;
 
     CX_TEST_DO {
-        CxTree *tree = cxTreeCreate(
-                alloc, tree_node_file_create_hl,
-                tree_node_file_search, tree_node_file_search_data,
-                tree_node_file_layout
-        );
-
-        const char *paths[] = {
-                "/",
-                "/usr/",
-                "/home/",
-                "/usr/lib/",
-                "/home/foo/",
-                "/home/foo/bar/"
-        };
-        cxTreeInsertArray(tree, paths, sizeof(const char*), 6);
-
-        tree_node_file *foo = cxTreeFind(tree, "/home/foo/");
-        CX_TEST_ASSERT(NULL != foo);
-        CX_TEST_ASSERT(0 == strcmp("/home/foo/", foo->path));
-        CX_TEST_ASSERT(NULL != foo->parent);
-        CX_TEST_ASSERT(0 == strcmp("/home/", foo->parent->path));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 6);
-
-        CX_TEST_ASSERT(0 == cxTreeAddChild(tree, foo->parent, "/home/baz/"));
-        tree_node_file *baz = cxTreeFind(tree, "/home/baz/");
-        CX_TEST_ASSERT(NULL != baz);
-        CX_TEST_ASSERT(0 == strcmp("/home/baz/", baz->path));
-        CX_TEST_ASSERT(NULL != baz->parent);
-        CX_TEST_ASSERT(0 == strcmp("/home/", baz->parent->path));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 7);
-
-        tree_node_file *home = cxTreeFind(tree, "/home/");
-        CX_TEST_ASSERT(NULL == cxTreeFindInSubtree(tree, "/usr/", foo, 0));
-        tree_node_file *bar = cxTreeFindInSubtree(tree, "/home/foo/bar/", home, 0);
-        CX_TEST_ASSERT(NULL != bar);
-        CX_TEST_ASSERT(0 == strcmp("/home/foo/bar/", bar->path));
-        CX_TEST_ASSERT(bar->parent == foo);
-
-        tree_node_file *share = cxCalloc(alloc, 1, sizeof(tree_node_file));
-        share->path = "/usr/share/";
-        tree_node_file *usr = cxTreeFind(tree, "/usr/");
-        cxTreeAddChildNode(tree, usr, share);
-        CX_TEST_ASSERT(cxTreeSize(tree) == 8);
-
-        cxTreeRemoveSubtree(tree, foo);
-        CX_TEST_ASSERT(cxTreeSize(tree) == 6);
-        CX_TEST_ASSERT(foo->children == bar);
-        CX_TEST_ASSERT(foo->last_child == bar);
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/"));
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/bar/"));
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/bar/"));
-
-        CX_TEST_ASSERT(0 == cxTreeRemoveNode(tree, usr, test_tree_remove_node_relink_mock));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 5);
-        CX_TEST_ASSERT(usr->parent == NULL);
-        CX_TEST_ASSERT(usr->children == NULL);
-        CX_TEST_ASSERT(usr->last_child == NULL);
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/"));
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/lib/"));
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/share/"));
-        tree_node_file *relinked_share = cxTreeFind(tree, "/share/");
-        tree_node_file *relinked_lib = cxTreeFind(tree, "/lib/");
-        CX_TEST_ASSERT(relinked_share != NULL);
-        CX_TEST_ASSERT(relinked_share->parent == tree->root);
-        CX_TEST_ASSERT(relinked_lib != NULL);
-        CX_TEST_ASSERT(relinked_lib->parent == tree->root);
-        CX_TEST_ASSERT(NULL != cxTreeFind(tree, "/home/"));
-
-
-        cxTreeFree(tree);
-        // we are not done yet, because we need to free the removed stuff
-        CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
-
-        cxFree(alloc, usr);
-        // for the subtree, we use a little trick and wrap it in a new tree
-        CxTree *foo_tree = cxTreeCreateWrapped(alloc, foo, tree_node_file_layout);
-        foo_tree->collection.allocator = alloc;
-        cxSetAdvancedDestructor(foo_tree, cxFree, alloc);
-        cxTreeFree(foo_tree);
+        CX_TEST_CALL_SUBROUTINE(validate_tree_high_add_find_remove_nodes, alloc, true);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+        CX_TEST_CALL_SUBROUTINE(validate_tree_high_add_find_remove_nodes, alloc, false);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
     }
     cx_testing_allocator_destroy(&talloc);
 }
 
+static CX_TEST_SUBROUTINE(validate_tree_high_add_find_destroy_nodes,
+        CxAllocator *alloc, bool use_dfs) {
+    CxTree *tree = cxTreeCreate(alloc,
+        sizeof(tree_node_file),
+        CX_STORE_POINTERS,
+        NULL, offsetof(tree_node_file, path),
+        cx_tree_node_layout(tree_node_file)
+    );
+    cxSetCompareFunc(tree, strcmp);
+
+    {
+        tree_node_file *root = cxTreeCreateRootData(tree, "/");
+        tree_node_file *home = cxTreeAddData(tree, root, "/home/");
+        tree_node_file *foo = cxTreeAddData(tree, home, "/home/foo/");
+        cxTreeAddData(tree, foo, "/home/foo/bar/");
+        tree_node_file *usr = cxTreeAddData(tree, root, "/usr/");
+        cxTreeAddData(tree, usr, "/usr/lib/");
+    }
+
+    tree_node_file *foo = cxTreeFind(tree, "/home/foo/", use_dfs);
+    CX_TEST_ASSERT(NULL != foo);
+    CX_TEST_ASSERT(0 == strcmp("/home/foo/", foo->path));
+    CX_TEST_ASSERT(NULL != foo->parent);
+    CX_TEST_ASSERT(0 == strcmp("/home/", foo->parent->path));
+    CX_TEST_ASSERT(cxTreeSize(tree) == 6);
+
+    CX_TEST_ASSERT(NULL != cxTreeAddData(tree, foo->parent, "/home/baz/"));
+    tree_node_file *baz = cxTreeFind(tree, "/home/baz/", use_dfs);
+    CX_TEST_ASSERT(NULL != baz);
+    CX_TEST_ASSERT(0 == strcmp("/home/baz/", baz->path));
+    CX_TEST_ASSERT(NULL != baz->parent);
+    CX_TEST_ASSERT(0 == strcmp("/home/", baz->parent->path));
+    CX_TEST_ASSERT(cxTreeSize(tree) == 7);
+
+    tree_node_file *home = cxTreeFind(tree, "/home/", use_dfs);
+    CX_TEST_ASSERT(NULL == cxTreeFindInSubtree(tree, "/usr/", foo, 0, use_dfs));
+    tree_node_file *bar = cxTreeFindInSubtree(tree, "/home/foo/bar/", home, 0, use_dfs);
+    CX_TEST_ASSERT(NULL != bar);
+    CX_TEST_ASSERT(0 == strcmp("/home/foo/bar/", bar->path));
+    CX_TEST_ASSERT(bar->parent == foo);
+
+    tree_node_file *share = cxCalloc(alloc, 1, sizeof(tree_node_file));
+    share->path = "/usr/share/";
+    tree_node_file *usr = cxTreeFind(tree, "/usr/", use_dfs);
+    cxTreeAddNode(tree, usr, share);
+    CX_TEST_ASSERT(cxTreeSize(tree) == 8);
+
+    cxTreeDestroySubtree(tree, foo);
+    CX_TEST_ASSERT(cxTreeSize(tree) == 6);
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/", use_dfs));
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/bar/", use_dfs));
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/bar/", use_dfs));
+
+    CX_TEST_ASSERT(0 == cxTreeDestroyNode(tree, usr, test_tree_remove_node_relink_mock));
+    CX_TEST_ASSERT(cxTreeSize(tree) == 5);
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/", use_dfs));
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/lib/", use_dfs));
+    CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/share/", use_dfs));
+    tree_node_file *relinked_share = cxTreeFind(tree, "/share/", use_dfs);
+    tree_node_file *relinked_lib = cxTreeFind(tree, "/lib/", use_dfs);
+    CX_TEST_ASSERT(relinked_share != NULL);
+    CX_TEST_ASSERT(relinked_share->parent == tree->root);
+    CX_TEST_ASSERT(relinked_lib != NULL);
+    CX_TEST_ASSERT(relinked_lib->parent == tree->root);
+    CX_TEST_ASSERT(NULL != cxTreeFind(tree, "/home/", use_dfs));
+
+    cxTreeFree(tree);
+}
+
 CX_TEST(test_tree_high_add_find_destroy_nodes) {
     CxTestingAllocator talloc;
     cx_testing_allocator_init(&talloc);
     CxAllocator *alloc = &talloc.base;
 
     CX_TEST_DO {
-        CxTree *tree = cxTreeCreate(
-                alloc, tree_node_file_create_hl,
-                tree_node_file_search, tree_node_file_search_data,
-                tree_node_file_layout
-        );
-
-        const char *paths[] = {
-                "/",
-                "/usr/",
-                "/home/",
-                "/usr/lib/",
-                "/home/foo/",
-                "/home/foo/bar/"
-        };
-        cxTreeInsertArray(tree, paths, sizeof(const char*), 6);
-
-        tree_node_file *foo = cxTreeFind(tree, "/home/foo/");
-        CX_TEST_ASSERT(NULL != foo);
-        CX_TEST_ASSERT(0 == strcmp("/home/foo/", foo->path));
-        CX_TEST_ASSERT(NULL != foo->parent);
-        CX_TEST_ASSERT(0 == strcmp("/home/", foo->parent->path));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 6);
-
-        CX_TEST_ASSERT(0 == cxTreeAddChild(tree, foo->parent, "/home/baz/"));
-        tree_node_file *baz = cxTreeFind(tree, "/home/baz/");
-        CX_TEST_ASSERT(NULL != baz);
-        CX_TEST_ASSERT(0 == strcmp("/home/baz/", baz->path));
-        CX_TEST_ASSERT(NULL != baz->parent);
-        CX_TEST_ASSERT(0 == strcmp("/home/", baz->parent->path));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 7);
-
-        tree_node_file *home = cxTreeFind(tree, "/home/");
-        CX_TEST_ASSERT(NULL == cxTreeFindInSubtree(tree, "/usr/", foo, 0));
-        tree_node_file *bar = cxTreeFindInSubtree(tree, "/home/foo/bar/", home, 0);
-        CX_TEST_ASSERT(NULL != bar);
-        CX_TEST_ASSERT(0 == strcmp("/home/foo/bar/", bar->path));
-        CX_TEST_ASSERT(bar->parent == foo);
-
-        tree_node_file *share = cxCalloc(alloc, 1, sizeof(tree_node_file));
-        share->path = "/usr/share/";
-        tree_node_file *usr = cxTreeFind(tree, "/usr/");
-        cxTreeAddChildNode(tree, usr, share);
-        CX_TEST_ASSERT(cxTreeSize(tree) == 8);
-
-        cxTreeDestroySubtree(tree, foo);
-        CX_TEST_ASSERT(cxTreeSize(tree) == 6);
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/"));
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/bar/"));
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/bar/"));
-
-        CX_TEST_ASSERT(0 == cxTreeDestroyNode(tree, usr, test_tree_remove_node_relink_mock));
-        CX_TEST_ASSERT(cxTreeSize(tree) == 5);
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/"));
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/lib/"));
-        CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/share/"));
-        tree_node_file *relinked_share = cxTreeFind(tree, "/share/");
-        tree_node_file *relinked_lib = cxTreeFind(tree, "/lib/");
-        CX_TEST_ASSERT(relinked_share != NULL);
-        CX_TEST_ASSERT(relinked_share->parent == tree->root);
-        CX_TEST_ASSERT(relinked_lib != NULL);
-        CX_TEST_ASSERT(relinked_lib->parent == tree->root);
-        CX_TEST_ASSERT(NULL != cxTreeFind(tree, "/home/"));
-
-        cxTreeFree(tree);
-        // all memory should be free when using destroy instead of remove
+        CX_TEST_CALL_SUBROUTINE(validate_tree_high_add_find_destroy_nodes, alloc, true);
+        CX_TEST_CALL_SUBROUTINE(validate_tree_high_add_find_destroy_nodes, alloc, false);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
     }
     cx_testing_allocator_destroy(&talloc);
@@ -2277,21 +1624,21 @@
     CxAllocator *alloc = &talloc.base;
 
     CX_TEST_DO {
-        CxTree *tree = cxTreeCreate(
-                alloc, tree_node_file_create_hl,
-                tree_node_file_search, tree_node_file_search_data,
-                tree_node_file_layout
+        CxTree *tree = cxTreeCreate(alloc,
+                sizeof(tree_node_file),
+                CX_STORE_POINTERS,
+                NULL, offsetof(tree_node_file, path),
+                cx_tree_node_layout(tree_node_file)
         );
 
-        const char *paths[] = {
-                "/",
-                "/usr/",
-                "/home/",
-                "/usr/lib/",
-                "/home/foo/",
-                "/home/foo/bar/"
-        };
-        cxTreeInsertArray(tree, paths, sizeof(const char*), 6);
+        {
+            tree_node_file *root = cxTreeCreateRootData(tree, "/");
+            tree_node_file *home = cxTreeAddData(tree, root, "/home/");
+            tree_node_file *foo = cxTreeAddData(tree, home, "/home/foo/");
+            cxTreeAddData(tree, foo, "/home/foo/bar/");
+            tree_node_file *usr = cxTreeAddData(tree, root, "/usr/");
+            cxTreeAddData(tree, usr, "/usr/lib/");
+        }
         void *root = tree->root;
         CX_TEST_ASSERT(0 != cxTreeRemoveNode(tree, root, NULL));
         CX_TEST_ASSERT(tree->root == root);
@@ -2305,7 +1652,13 @@
         CX_TEST_ASSERT(cxTreeDepth(tree) == 0);
         cxTreeFree(tree);
         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
-        CxTree *w = cxTreeCreateWrapped(alloc, root, tree_node_file_layout);
+
+        CxTree *w = cxTreeCreate(alloc,
+                sizeof(tree_node_file),
+                CX_STORE_POINTERS,
+                root, offsetof(tree_node_file, path),
+                cx_tree_node_layout(tree_node_file)
+        );
         cxSetAdvancedDestructor(w, cxFree, alloc);
         cxTreeDestroySubtree(w, w->root);
         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
@@ -2321,11 +1674,12 @@
 
 CX_TEST(test_tree_high_simple_destructor) {
     tree_node root = {0}, child1 = {0}, child2 = {0}, child3 = {0};
-    cx_tree_link(&root, &child1, tree_node_layout);
-    cx_tree_link(&root, &child2, tree_node_layout);
-    cx_tree_link(&child1, &child3, tree_node_layout);
+    cx_tree_add(&root, &child1, tree_node_layout);
+    cx_tree_add(&root, &child2, tree_node_layout);
+    cx_tree_add(&child1, &child3, tree_node_layout);
     CX_TEST_DO {
-        CxTree *tree = cxTreeCreateWrapped(cxDefaultAllocator, &root, tree_node_layout);
+        CxTree *tree = cxTreeCreate(cxDefaultAllocator, sizeof(tree_node),
+            sizeof(int), &root, offsetof(tree_node, data), tree_node_layout);
         cxSetDestructor(tree,test_tree_high_simple_destructor_func);
         cxTreeDestroyNode(tree, &child1, NULL);
         cxTreeFree(tree);
@@ -2337,20 +1691,23 @@
 }
 
 CX_TEST(test_tree_high_iterator) {
-    CxTree *tree = cxTreeCreate(
-        NULL, tree_node_file_create_hl,
-        tree_node_file_search, tree_node_file_search_data,
-        tree_node_file_layout
+    CxTree *tree = cxTreeCreate(NULL,
+            sizeof(tree_node_file),
+            CX_STORE_POINTERS,
+            NULL, offsetof(tree_node_file, path),
+            cx_tree_node_layout(tree_node_file)
     );
-    cxTreeInsert(tree, "/");
-    cxTreeInsert(tree, "/etc");
-    cxTreeInsert(tree, "/home");
-    cxTreeInsert(tree, "/home/jane");
-    cxTreeInsert(tree, "/usr");
-    cxTreeInsert(tree, "/usr/local");
-    cxTreeInsert(tree, "/usr/local/lib");
-    cxTreeInsert(tree, "/var");
-    cxTreeInsert(tree, "/var/lib");
+    {
+        tree_node_file *root = cxTreeCreateRootData(tree, "/");
+        cxTreeAddData(tree, root, "/etc");
+        tree_node_file *home = cxTreeAddData(tree, root, "/home");
+        cxTreeAddData(tree, home, "/home/jane");
+        tree_node_file *usr = cxTreeAddData(tree, root, "/usr");
+        cxTreeAddData(tree, usr, "/usr/local");
+        cxTreeAddData(tree, usr, "/usr/local/lib");
+        tree_node_file *var = cxTreeAddData(tree, root, "/var");
+        cxTreeAddData(tree, var, "/var/lib");
+    }
     CX_TEST_DO {
         const char *expected_order[] = {
             "/",
@@ -2377,20 +1734,23 @@
 }
 
 CX_TEST(test_tree_high_visitor) {
-    CxTree *tree = cxTreeCreate(
-        NULL, tree_node_file_create_hl,
-        tree_node_file_search, tree_node_file_search_data,
-        tree_node_file_layout
+    CxTree *tree = cxTreeCreate(NULL,
+            sizeof(tree_node_file),
+            CX_STORE_POINTERS,
+            NULL, offsetof(tree_node_file, path),
+            cx_tree_node_layout(tree_node_file)
     );
-    cxTreeInsert(tree, "/");
-    cxTreeInsert(tree, "/etc");
-    cxTreeInsert(tree, "/home");
-    cxTreeInsert(tree, "/home/jane");
-    cxTreeInsert(tree, "/usr");
-    cxTreeInsert(tree, "/usr/local");
-    cxTreeInsert(tree, "/usr/local/lib");
-    cxTreeInsert(tree, "/var");
-    cxTreeInsert(tree, "/var/lib");
+    {
+        tree_node_file *root = cxTreeCreateRootData(tree, "/");
+        cxTreeAddData(tree, root, "/etc");
+        tree_node_file *home = cxTreeAddData(tree, root, "/home");
+        cxTreeAddData(tree, home, "/home/jane");
+        tree_node_file *usr = cxTreeAddData(tree, root, "/usr");
+        tree_node_file *usr_local = cxTreeAddData(tree, usr, "/usr/local");
+        cxTreeAddData(tree, usr_local, "/usr/local/lib");
+        tree_node_file *var = cxTreeAddData(tree, root, "/var");
+        cxTreeAddData(tree, var, "/var/lib");
+    }
     CX_TEST_DO {
         const char *expected_order[] = {
             "/",
@@ -2404,7 +1764,7 @@
             "/usr/local/lib",
         };
         const char *actual_order[9];
-        CxTreeVisitor iter = cxTreeVisit(tree);
+        CxTreeIterator iter = cxTreeVisit(tree);
         cx_foreach(tree_node_file*, p, iter) {
             actual_order[iter.counter-1] = p->path;
         }
@@ -2419,11 +1779,10 @@
 CxTestSuite *cx_test_suite_tree_low_level(void) {
     CxTestSuite *suite = cx_test_suite_new("tree (low level)");
 
-    cx_test_register(suite, test_tree_link_new_child);
-    cx_test_register(suite, test_tree_link_add_child);
-    cx_test_register(suite, test_tree_link_move_to_other_parent);
-    cx_test_register(suite, test_tree_unlink);
-    cx_test_register(suite, test_tree_unlink_no_prev);
+    cx_test_register(suite, test_tree_add);
+    cx_test_register(suite, test_tree_add_move_to_other_parent);
+    cx_test_register(suite, test_tree_remove);
+    cx_test_register(suite, test_tree_remove_no_prev);
     cx_test_register(suite, test_tree2_link_new_child);
     cx_test_register(suite, test_tree2_link_add_child);
     cx_test_register(suite, test_tree2_link_move_to_other_parent);
@@ -2445,15 +1804,6 @@
     cx_test_register(suite, test_tree_visitor_continue);
     cx_test_register(suite, test_tree_iterator_continue);
     cx_test_register(suite, test_tree_iterator_continue_with_exit);
-    cx_test_register(suite, test_tree_add_one);
-    cx_test_register(suite, test_tree_add_one_existing);
-    cx_test_register(suite, test_tree_add_one_no_match);
-    cx_test_register(suite, test_tree_add_duplicate_root);
-    cx_test_register(suite, test_tree_add_zero);
-    cx_test_register(suite, test_tree_add_many);
-    cx_test_register(suite, test_tree_add_many_but_not_all);
-    cx_test_register(suite, test_tree_add_many_with_dupl_and_no_match);
-    cx_test_register(suite, test_tree_add_create_from_array);
 
     return suite;
 }
@@ -2462,18 +1812,14 @@
     CxTestSuite *suite = cx_test_suite_new("tree (high level)");
 
     cx_test_register(suite, test_tree_high_create);
-    cx_test_register(suite, test_tree_high_create_simple);
-    cx_test_register(suite, test_tree_high_create_wrapped);
     cx_test_register(suite, test_tree_high_tree_depth);
-    cx_test_register(suite, test_tree_high_set_parent);
-    cx_test_register(suite, test_tree_high_insert_one);
-    cx_test_register(suite, test_tree_high_insert_many);
-    cx_test_register(suite, test_tree_high_add_find_remove_nodes);
-    cx_test_register(suite, test_tree_high_add_find_destroy_nodes);
-    cx_test_register(suite, test_tree_high_remove_or_destroy_root);
-    cx_test_register(suite, test_tree_high_simple_destructor);
-    cx_test_register(suite, test_tree_high_iterator);
-    cx_test_register(suite, test_tree_high_visitor);
+    // cx_test_register(suite, test_tree_high_set_parent);
+    // cx_test_register(suite, test_tree_high_add_find_remove_nodes);
+    // cx_test_register(suite, test_tree_high_add_find_destroy_nodes);
+    // cx_test_register(suite, test_tree_high_remove_or_destroy_root);
+    // cx_test_register(suite, test_tree_high_simple_destructor);
+    // cx_test_register(suite, test_tree_high_iterator);
+    // cx_test_register(suite, test_tree_high_visitor);
 
     return suite;
 }

mercurial