tree CHANGE lys_node_dup/free new parameter for shallow copies
diff --git a/src/tree_schema.c b/src/tree_schema.c
index df5e059..79627b0 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -1229,8 +1229,7 @@
             new->info.ident.ref = old->info.ident.ref;
         } else {
             i = unres_schema_find(unres, old, UNRES_TYPE_IDENTREF);
-            assert(i != -1);
-            if (unres_schema_add_str(mod, unres, new, UNRES_TYPE_IDENTREF, unres->str_snode[i], 0)) {
+            if (i > -1 && unres_schema_add_str(mod, unres, new, UNRES_TYPE_IDENTREF, unres->str_snode[i], 0)) {
                 return -1;
             }
         }
@@ -1254,9 +1253,11 @@
         break;
 
     case LY_TYPE_LEAFREF:
-        new->info.lref.path = lydict_insert(mod->ctx, old->info.lref.path, 0);
-        if (unres_schema_add_node(mod, unres, new, UNRES_TYPE_LEAFREF, parent, 0)) {
-            return -1;
+        if (old->info.lref.path) {
+            new->info.lref.path = lydict_insert(mod->ctx, old->info.lref.path, 0);
+            if (unres_schema_add_node(mod, unres, new, UNRES_TYPE_LEAFREF, parent, 0)) {
+                return -1;
+            }
         }
         break;
 
@@ -1467,7 +1468,7 @@
     /* children from a resolved augment are freed under the target node */
     if (!aug.target) {
         LY_TREE_FOR_SAFE(aug.child, next, sub) {
-            lys_node_free(sub, private_destructor);
+            lys_node_free(sub, private_destructor, 0);
         }
     }
 
@@ -1507,6 +1508,7 @@
         new[i].flags = old[i].flags;
         new[i].module = old[i].module;
         new[i].nodetype = old[i].nodetype;
+
         /* this must succeed, it was already resolved once */
         if (resolve_augment_schema_nodeid(new[i].target_name, parent->child, NULL,
                                           (const struct lys_node **)&new[i].target)) {
@@ -1818,7 +1820,7 @@
 }
 
 void
-lys_node_free(struct lys_node *node, void (*private_destructor)(const struct lys_node *node, void *priv))
+lys_node_free(struct lys_node *node, void (*private_destructor)(const struct lys_node *node, void *priv), int shallow)
 {
     struct ly_ctx *ctx;
     struct lys_node *sub, *next;
@@ -1845,9 +1847,9 @@
         lydict_remove(ctx, node->ref);
     }
 
-    if (!(node->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+    if (!shallow && !(node->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
         LY_TREE_FOR_SAFE(node->child, next, sub) {
-            lys_node_free(sub, private_destructor);
+            lys_node_free(sub, private_destructor, 0);
         }
     }
 
@@ -1952,7 +1954,7 @@
      * are placed in the main module altogether */
     if (!module->type) {
         LY_TREE_FOR_SAFE(module->data, next, iter) {
-            lys_node_free(iter, private_destructor);
+            lys_node_free(iter, private_destructor, 0);
         }
     }
 
@@ -2029,7 +2031,7 @@
 
 struct lys_node *
 lys_node_dup(struct lys_module *module, struct lys_node *parent, const struct lys_node *node, uint8_t flags,
-             uint8_t nacm, struct unres_schema *unres)
+             uint8_t nacm, struct unres_schema *unres, int shallow)
 {
     struct lys_node *retval = NULL, *child;
     struct ly_ctx *ctx = module->ctx;
@@ -2167,16 +2169,18 @@
         }
     }
 
-    /* connect it to the parent */
-    if (lys_node_addchild(parent, retval->module, retval)) {
-        goto error;
-    }
+    if (!shallow) {
+        /* connect it to the parent */
+        if (lys_node_addchild(parent, retval->module, retval)) {
+            goto error;
+        }
 
-    /* go recursively */
-    if (!(node->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
-        LY_TREE_FOR(node->child, child) {
-            if (!lys_node_dup(module, retval, child, retval->flags, retval->nacm, unres)) {
-                goto error;
+        /* go recursively */
+        if (!(node->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LY_TREE_FOR(node->child, child) {
+                if (!lys_node_dup(module, retval, child, retval->flags, retval->nacm, unres, 0)) {
+                    goto error;
+                }
             }
         }
     }
@@ -2203,22 +2207,26 @@
             choice->when = lys_when_dup(ctx, choice_orig->when);
         }
 
-        if (choice_orig->dflt) {
-            rc = lys_get_sibling(choice->child, lys_node_module(retval)->name, 0, choice_orig->dflt->name, 0, LYS_ANYXML
-                                         | LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST
-                                         | LYS_LIST, (const struct lys_node **)&choice->dflt);
-            if (rc) {
-                if (rc == EXIT_FAILURE) {
-                    LOGINT;
+        if (!shallow) {
+            if (choice_orig->dflt) {
+                rc = lys_get_sibling(choice->child, lys_node_module(retval)->name, 0, choice_orig->dflt->name, 0, LYS_ANYXML
+                                            | LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST
+                                            | LYS_LIST, (const struct lys_node **)&choice->dflt);
+                if (rc) {
+                    if (rc == EXIT_FAILURE) {
+                        LOGINT;
+                    }
+                    goto error;
                 }
-                goto error;
+            } else {
+                /* useless to check return value, we don't know whether
+                * there really wasn't any default defined or it just hasn't
+                * been resolved, we just hope for the best :)
+                */
+                unres_schema_dup(module, unres, choice_orig, UNRES_CHOICE_DFLT, choice);
             }
         } else {
-            /* useless to check return value, we don't know whether
-             * there really wasn't any default defined or it just hasn't
-             * been resolved, we just hope for the best :)
-             */
-            unres_schema_dup(module, unres, choice_orig, UNRES_CHOICE_DFLT, choice);
+            choice->dflt = choice_orig->dflt;
         }
         break;
 
@@ -2278,24 +2286,28 @@
                 goto error;
             }
 
-            /* we managed to resolve it before, resolve it again manually */
-            if (list_orig->keys[0]) {
-                for (i = 0; i < list->keys_size; ++i) {
-                    rc = lys_get_sibling(list->child, lys_node_module(retval)->name, 0, list_orig->keys[i]->name, 0, LYS_LEAF,
-                                         (const struct lys_node **)&list->keys[i]);
-                    if (rc) {
-                        if (rc == EXIT_FAILURE) {
-                            LOGINT;
+            if (!shallow) {
+                /* we managed to resolve it before, resolve it again manually */
+                if (list_orig->keys[0]) {
+                    for (i = 0; i < list->keys_size; ++i) {
+                        rc = lys_get_sibling(list->child, lys_node_module(retval)->name, 0, list_orig->keys[i]->name, 0, LYS_LEAF,
+                                            (const struct lys_node **)&list->keys[i]);
+                        if (rc) {
+                            if (rc == EXIT_FAILURE) {
+                                LOGINT;
+                            }
+                            goto error;
                         }
+                    }
+                /* it was not resolved yet, add unres copy */
+                } else {
+                    if (unres_schema_dup(module, unres, list_orig, UNRES_LIST_KEYS, list)) {
+                        LOGINT;
                         goto error;
                     }
                 }
-            /* it was not resolved yet, add unres copy */
             } else {
-                if (unres_schema_dup(module, unres, list_orig, UNRES_LIST_KEYS, list)) {
-                    LOGINT;
-                    goto error;
-                }
+                memcpy(list->keys, list_orig->keys, list->keys_size * sizeof *list->keys);
             }
         }
 
@@ -2344,11 +2356,15 @@
         uses->refine_size = uses_orig->refine_size;
         uses->refine = lys_refine_dup(module, uses_orig->refine, uses_orig->refine_size);
         uses->augment_size = uses_orig->augment_size;
-        uses->augment = lys_augment_dup(module, (struct lys_node *)uses, uses_orig->augment, uses_orig->augment_size);
-        if (!uses->child) {
-            if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL, 0) == -1) {
-                goto error;
+        if (!shallow) {
+            uses->augment = lys_augment_dup(module, (struct lys_node *)uses, uses_orig->augment, uses_orig->augment_size);
+            if (!uses->child) {
+                if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL, 0) == -1) {
+                    goto error;
+                }
             }
+        } else {
+            memcpy(uses->augment, uses_orig->augment, uses->augment_size * sizeof *uses->augment);
         }
         break;
 
@@ -2389,7 +2405,7 @@
 
 error:
 
-    lys_node_free(retval, NULL);
+    lys_node_free(retval, NULL, 0);
     return NULL;
 }