validation NEW default values creation

Also a lot of other refactoring and
improvements. No tests yet.
diff --git a/src/tree_data.c b/src/tree_data.c
index 0b9b59f..b441363 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -458,17 +458,50 @@
     LY_ERR ret;
     struct lyd_node_term *term;
 
+    assert(schema->nodetype & LYD_NODE_TERM);
+
     term = calloc(1, sizeof *term);
     LY_CHECK_ERR_RET(!term, LOGMEM(schema->module->ctx), LY_EMEM);
 
     term->schema = schema;
     term->prev = (struct lyd_node *)term;
+    term->flags = LYD_NEW;
 
     ret = lyd_value_parse(term, value, value_len, dynamic, 0, get_prefix, prefix_data, format, NULL);
     if (ret && (ret != LY_EINCOMPLETE)) {
         free(term);
         return ret;
     }
+    lyd_hash((struct lyd_node *)term);
+
+    *node = (struct lyd_node *)term;
+    return ret;
+}
+
+LY_ERR
+lyd_create_term2(const struct lysc_node *schema, const struct lyd_value *val, struct lyd_node **node)
+{
+    LY_ERR ret;
+    struct lyd_node_term *term;
+    struct lysc_type *type;
+
+    assert(schema->nodetype & LYD_NODE_TERM);
+
+    term = calloc(1, sizeof *term);
+    LY_CHECK_ERR_RET(!term, LOGMEM(schema->module->ctx), LY_EMEM);
+
+    term->schema = schema;
+    term->prev = (struct lyd_node *)term;
+    term->flags = LYD_NEW;
+
+    type = ((struct lysc_node_leaf *)schema)->type;
+    ret = type->plugin->duplicate(schema->module->ctx, val, &term->value);
+    if (ret) {
+        LOGERR(schema->module->ctx, ret, "Value duplication failed.");
+        free(term);
+        return ret;
+    }
+    lyd_hash((struct lyd_node *)term);
 
     *node = (struct lyd_node *)term;
     return ret;
@@ -479,15 +512,22 @@
 {
     struct lyd_node_inner *in;
 
+    assert(schema->nodetype & LYD_NODE_INNER);
+
     in = calloc(1, sizeof *in);
     LY_CHECK_ERR_RET(!in, LOGMEM(schema->module->ctx), LY_EMEM);
 
     in->schema = schema;
     in->prev = (struct lyd_node *)in;
+    in->flags = LYD_NEW;
 
-    if ((schema->nodetype == LYS_CONTAINER) && !(((struct lysc_node_container *)schema)->flags & LYS_PRESENCE)) {
-        /* non-presence cotnainer, default */
-        in->flags = LYD_DEFAULT;
+    /* do not hash list with keys, we need them for the hash */
+    if ((schema->nodetype != LYS_LIST) || (schema->flags & LYS_KEYLESS)) {
+        lyd_hash((struct lyd_node *)in);
+    }
+    if ((schema->nodetype == LYS_CONTAINER) && !(schema->flags & LYS_PRESENCE)) {
+        /* NP cotnainer always a default */
+        in->flags |= LYD_DEFAULT;
     }
 
     *node = (struct lyd_node *)in;
@@ -652,6 +692,9 @@
         lyd_insert_node(list, NULL, key);
     }
 
+    /* hash having all the keys */
+    lyd_hash(list);
+
     /* success */
     *node = list;
     list = NULL;
@@ -667,14 +710,18 @@
 {
     struct lyd_node_any *any;
 
+    assert(schema->nodetype & LYD_NODE_ANY);
+
     any = calloc(1, sizeof *any);
     LY_CHECK_ERR_RET(!any, LOGMEM(schema->module->ctx), LY_EMEM);
 
     any->schema = schema;
     any->prev = (struct lyd_node *)any;
+    any->flags = LYD_NEW;
 
     any->value.xml = value;
     any->value_type = value_type;
+    lyd_hash((struct lyd_node *)any);
 
     *node = (struct lyd_node *)any;
     return LY_SUCCESS;
@@ -778,19 +825,22 @@
 }
 
 void
-lyd_insert_node(struct lyd_node *parent, struct lyd_node *first_sibling, struct lyd_node *node)
+lyd_insert_node(struct lyd_node *parent, struct lyd_node **first_sibling, struct lyd_node *node)
 {
-    struct lyd_node *key_anchor;
+    struct lyd_node *anchor;
 
-    assert((!parent && first_sibling) || (!first_sibling && parent));
-    assert(node && node->hash);
+    assert((parent || first_sibling) && node && node->hash);
+
+    if (!parent && first_sibling && (*first_sibling) && (*first_sibling)->parent) {
+        parent = (struct lyd_node *)(*first_sibling)->parent;
+    }
 
     if (parent) {
         if (node->schema->flags & LYS_KEY) {
             /* it is key and we need to insert it at the correct place */
-            key_anchor = lyd_get_prev_key_anchor(lyd_node_children(parent), node->schema);
-            if (key_anchor) {
-                lyd_insert_after(key_anchor, node);
+            anchor = lyd_get_prev_key_anchor(lyd_node_children(parent), node->schema);
+            if (anchor) {
+                lyd_insert_after(anchor, node);
             } else if (lyd_node_children(parent)) {
                 lyd_insert_before((struct lyd_node *)lyd_node_children(parent), node);
             } else {
@@ -800,15 +850,26 @@
             /* last child */
             lyd_insert_last(parent, node);
         }
+    } else if (*first_sibling) {
+        /* top-level siblings, find the last one from this module, or simply the last */
+        anchor = (*first_sibling)->prev;
+        while (anchor->prev->next && (lyd_top_node_module(anchor) != lyd_top_node_module(node))) {
+            anchor = anchor->prev;
+        }
+
+        /* insert */
+        lyd_insert_after(anchor, node);
     } else {
-        /* last sibling */
-        lyd_insert_after(first_sibling->prev, node);
+        /* the only sibling */
+        *first_sibling = node;
     }
 
-    /* remove default flags from NP containers */
-    while (parent && (parent->flags & LYD_DEFAULT)) {
-        parent->flags &= ~LYD_DEFAULT;
-        parent = (struct lyd_node *)parent->parent;
+    if (!(node->flags & LYD_DEFAULT)) {
+        /* remove default flags from NP containers */
+        while (parent && (parent->flags & LYD_DEFAULT)) {
+            parent->flags &= ~LYD_DEFAULT;
+            parent = (struct lyd_node *)parent->parent;
+        }
     }
 
     /* insert into hash table */
@@ -1553,105 +1614,34 @@
     return buffer;
 }
 
-API struct ly_set *
-lyd_find_instance(const struct lyd_node *sibling, const struct lysc_node *schema)
-{
-    struct ly_set *ret, *ret_aux, *spath;
-    const struct lysc_node *siter, *sparent;
-    const struct lyd_node *iter;
-    unsigned int i, j;
-
-    LY_CHECK_ARG_RET(NULL, sibling, schema, NULL);
-    if (schema->nodetype & (LYS_CHOICE | LYS_CASE)) {
-        LOGARG(schema->module->ctx, schema);
-        return NULL;
-    }
-
-    ret = ly_set_new();
-    spath = ly_set_new();
-    LY_CHECK_ERR_GOTO(!ret || !spath, LOGMEM(schema->module->ctx), error);
-
-    /* build schema path until sibling parent */
-    sparent = sibling->parent ? sibling->parent->schema : NULL;
-    for (siter = schema; siter && (siter != sparent); siter = siter->parent) {
-        if (siter->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_ANYDATA | LYS_NOTIF | LYS_RPC | LYS_ACTION)) {
-            /* standard data node */
-            ly_set_add(spath, (void *)siter, LY_SET_OPT_USEASLIST);
-
-        } /* else skip the rest node types */
-    }
-    /* no valid path */
-    LY_CHECK_GOTO(!spath->count, error);
-
-    /* start searching */
-    LY_LIST_FOR(sibling, iter) {
-        if (iter->schema == spath->objs[spath->count - 1]) {
-            ly_set_add(ret, (void *)iter, LY_SET_OPT_USEASLIST);
-        }
-    }
-    for (i = spath->count - 1; i; i--) {
-        if (!ret->count) {
-            /* nothing found */
-            break;
-        }
-
-        ret_aux = ly_set_new();
-        LY_CHECK_ERR_GOTO(!ret_aux, LOGMEM(schema->module->ctx), error);
-        for (j = 0; j < ret->count; j++) {
-            LY_LIST_FOR(lyd_node_children(ret->objs[j]), iter) {
-                if (iter->schema == spath->objs[i - 1]) {
-                    ly_set_add(ret_aux, (void *)iter, LY_SET_OPT_USEASLIST);
-                }
-            }
-        }
-        ly_set_free(ret, NULL);
-        ret = ret_aux;
-    }
-
-    ly_set_free(spath, NULL);
-    return ret;
-
-error:
-    ly_set_free(ret, NULL);
-    ly_set_free(spath, NULL);
-
-    return NULL;
-}
-
-API LY_ERR
-lyd_find_sibling_next(const struct lyd_node *first, const struct lys_module *module, const char *name, size_t name_len,
-                      const char *key_or_value, size_t val_len, struct lyd_node **match)
+LY_ERR
+lyd_find_sibling_next2(const struct lyd_node *first, const struct lysc_node *schema, const char *key_or_value,
+                       size_t val_len, struct lyd_node **match)
 {
     LY_ERR rc;
     const struct lyd_node *node = NULL;
     struct lyd_node_term *term;
-    const struct lysc_node *schema;
     struct ly_keys keys = {0};
     struct lyd_value val = {0};
     size_t i;
 
-    LY_CHECK_ARG_RET(NULL, module, name, LY_EINVAL);
+    LY_CHECK_ARG_RET(NULL, schema, LY_EINVAL);
 
     if (!first) {
         /* no data */
-        *match = NULL;
+        if (match) {
+            *match = NULL;
+        }
         return LY_ENOTFOUND;
     }
 
-    /* find schema */
-    schema = lys_find_child(first->parent ? first->parent->schema : NULL, module, name, name_len, 0, 0);
-    if (!schema) {
-        LOGERR(module->ctx, LY_EINVAL, "Schema node not found.");
-        return LY_EINVAL;
-    }
-
     if (key_or_value && !val_len) {
         val_len = strlen(key_or_value);
     }
 
     if (key_or_value && (schema->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
         /* store the value */
-        LY_CHECK_GOTO(lyd_value_store(&val, schema, key_or_value, val_len, 0, lydjson_resolve_prefix, NULL, LYD_JSON), cleanup);
+        LY_CHECK_GOTO(rc = lyd_value_store(&val, schema, key_or_value, val_len, 0, lydjson_resolve_prefix, NULL, LYD_JSON), cleanup);
     } else if (key_or_value && (schema->nodetype == LYS_LIST)) {
         /* parse keys into canonical values */
         LY_CHECK_GOTO(rc = ly_keys_parse(schema, key_or_value, val_len, 1, &keys), cleanup);
@@ -1671,7 +1661,7 @@
                                           (struct lyd_node **)&term);
                 if (rc == LY_ENOTFOUND) {
                     /* all keys must always exist */
-                    LOGINT_RET(module->ctx);
+                    LOGINT_RET(schema->module->ctx);
                 }
                 LY_CHECK_GOTO(rc, cleanup);
 
@@ -1701,23 +1691,51 @@
 
     if (!node) {
         rc = LY_ENOTFOUND;
-        *match = NULL;
+        if (match) {
+            *match = NULL;
+        }
         goto cleanup;
     }
 
     /* success */
-    *match = (struct lyd_node *)node;
+    if (match) {
+        *match = (struct lyd_node *)node;
+    }
     rc = LY_SUCCESS;
 
 cleanup:
     ly_keys_clean(&keys);
     if (val.realtype) {
-        val.realtype->plugin->free(module->ctx, &val);
+        val.realtype->plugin->free(schema->module->ctx, &val);
     }
     return rc;
 }
 
 API LY_ERR
+lyd_find_sibling_next(const struct lyd_node *first, const struct lys_module *module, const char *name, size_t name_len,
+                      const char *key_or_value, size_t val_len, struct lyd_node **match)
+{
+    const struct lysc_node *schema;
+
+    LY_CHECK_ARG_RET(NULL, module, name, match, LY_EINVAL);
+
+    if (!first) {
+        /* no data */
+        *match = NULL;
+        return LY_ENOTFOUND;
+    }
+
+    /* find schema */
+    schema = lys_find_child(first->parent ? first->parent->schema : NULL, module, name, name_len, 0, 0);
+    if (!schema) {
+        LOGERR(module->ctx, LY_EINVAL, "Schema node not found.");
+        return LY_EINVAL;
+    }
+
+    return lyd_find_sibling_next2(first, schema, key_or_value, val_len, match);
+}
+
+API LY_ERR
 lyd_find_sibling_first(const struct lyd_node *siblings, const struct lyd_node *target, struct lyd_node **match)
 {
     struct lyd_node **match_p;
@@ -1727,7 +1745,9 @@
 
     if (!siblings) {
         /* no data */
-        *match = NULL;
+        if (match) {
+            *match = NULL;
+        }
         return LY_ENOTFOUND;
     }
 
@@ -1761,11 +1781,15 @@
     }
 
     if (!siblings) {
-        *match = NULL;
+        if (match) {
+            *match = NULL;
+        }
         return LY_ENOTFOUND;
     }
 
-    *match = (struct lyd_node *)siblings;
+    if (match) {
+        *match = (struct lyd_node *)siblings;
+    }
     return LY_SUCCESS;
 }
 
@@ -1914,11 +1938,15 @@
     }
 
     if (!siblings) {
-        *match = NULL;
+        if (match) {
+            *match = NULL;
+        }
         return LY_ENOTFOUND;
     }
 
-    *match = (struct lyd_node *)siblings;
+    if (match) {
+        *match = (struct lyd_node *)siblings;
+    }
     return LY_SUCCESS;
 }
 
@@ -1944,7 +1972,9 @@
 
     if (!siblings) {
         /* no data */
-        *match = NULL;
+        if (match) {
+            *match = NULL;
+        }
         return LY_ENOTFOUND;
     }
 
@@ -1954,7 +1984,7 @@
     case LYS_ANYXML:
     case LYS_ANYDATA:
     case LYS_NOTIF:
-    case LYS_RPC:
+    case LYS_ACTION:
     case LYS_LEAF:
         /* find it based on schema only */
         rc = lyd_find_sibling_schema(siblings, schema, match);
@@ -1962,13 +1992,11 @@
     case LYS_LEAFLIST:
         /* target used attributes: schema, hash, value */
         LY_CHECK_RET(lyd_create_term(schema, key_or_value, val_len, NULL, lydjson_resolve_prefix, NULL, LYD_JSON, &target));
-        lyd_hash(target);
         /* fallthrough */
     case LYS_LIST:
         if (schema->nodetype == LYS_LIST) {
             /* target used attributes: schema, hash, child (all keys) */
             LY_CHECK_RET(lyd_create_list(schema, key_or_value, val_len, &target));
-            lyd_hash(target);
         }
 
         /* find it */