data tree BUGFIX keep first sibling pointer correct

In case it is supposed to point to the first data sibling
of a module, do not break this.
diff --git a/src/tree_data.c b/src/tree_data.c
index f57c274..7cb0e45 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -354,8 +354,13 @@
                     (validate_options & LYD_VALIDATE_NO_STATE) ? LYD_IMPLICIT_NO_STATE : 0, NULL);
             LY_CHECK_GOTO(ret, cleanup);
 
+            /* our first module node pointer may no longer be the first */
+            while (*first2 && (*first2)->prev->next && (lyd_owner_module(*first2) == lyd_owner_module((*first2)->prev))) {
+                *first2 = (*first2)->prev;
+            }
+
             /* finish incompletely validated terminal values/attributes and when conditions */
-            ret = lyd_validate_unres(tree, &lydctx->node_when, &lydctx->node_types, &lydctx->meta_types, NULL);
+            ret = lyd_validate_unres(first2, mod, &lydctx->node_when, &lydctx->node_types, &lydctx->meta_types, NULL);
             LY_CHECK_GOTO(ret, cleanup);
 
             /* perform final validation that assumes the data tree is final */
@@ -1568,7 +1573,7 @@
     }
 
     /* resolve when and remove any invalid defaults */
-    LY_CHECK_GOTO(ret = lyd_validate_unres(&tree, &node_when, NULL, NULL, diff), cleanup);
+    LY_CHECK_GOTO(ret = lyd_validate_unres(&tree, NULL, &node_when, NULL, NULL, diff), cleanup);
 
 cleanup:
     ly_set_erase(&node_when, NULL);
@@ -1634,7 +1639,7 @@
     LY_CHECK_GOTO(ret = lyd_new_implicit_r(NULL, tree, NULL, module, NULL, &node_when, implicit_options, diff), cleanup);
 
     /* resolve when and remove any invalid defaults */
-    LY_CHECK_GOTO(ret = lyd_validate_unres(tree, &node_when, NULL, NULL, diff), cleanup);
+    LY_CHECK_GOTO(ret = lyd_validate_unres(tree, module, &node_when, NULL, NULL, diff), cleanup);
 
     /* process nested nodes */
     LY_LIST_FOR(*tree, root) {
diff --git a/src/tree_data.h b/src/tree_data.h
index ee28c41..883929e 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -1074,7 +1074,9 @@
 /**
  * @brief Add any missing implicit nodes. Default nodes with a false "when" are not added.
  *
- * @param[in,out] tree Tree to add implicit nodes into.
+ * @param[in,out] tree Tree to add implicit nodes into. Note that in case a first top-level sibling is used,
+ * it may no longer be first if an implicit node was inserted before @p tree. Use ::lyd_first_sibling() to
+ * adjust @p tree in these cases.
  * @param[in] ctx libyang context, must be set only if @p tree is an empty tree.
  * @param[in] implicit_options Options for implicit node creation, see @ref implicitoptions.
  * @param[out] diff Optional diff with any created nodes.
@@ -1085,7 +1087,9 @@
 /**
  * @brief Add any missing implicit nodes of one module. Default nodes with a false "when" are not added.
  *
- * @param[in,out] tree Tree to add implicit nodes into.
+ * @param[in,out] tree Tree to add implicit nodes into. Note that in case a first top-level sibling is used,
+ * it may no longer be first if an implicit node was inserted before @p tree. Use ::lyd_first_sibling() to
+ * adjust @p tree in these cases.
  * @param[in] module Module whose implicit nodes to create.
  * @param[in] implicit_options Options for implicit node creation, see @ref implicitoptions.
  * @param[out] diff Optional diff with any created nodes.
diff --git a/src/tree_data_helpers.c b/src/tree_data_helpers.c
index a379400..79d789c 100644
--- a/src/tree_data_helpers.c
+++ b/src/tree_data_helpers.c
@@ -397,6 +397,25 @@
 }
 
 void
+lyd_del_move_root(struct lyd_node **root, const struct lyd_node *to_del, const struct lys_module *mod)
+{
+    if (*root && (lyd_owner_module(*root) != mod)) {
+        /* there are no data of mod so this is simply the first top-level sibling */
+        mod = NULL;
+    }
+
+    if ((*root != to_del) || (*root)->parent) {
+        return;
+    }
+
+    *root = (*root)->next;
+    if (mod && *root && (lyd_owner_module(to_del) != lyd_owner_module(*root))) {
+        /* there are no more nodes from mod */
+        *root = lyd_first_sibling(*root);
+    }
+}
+
+void
 ly_free_prefix_data(LY_PREFIX_FORMAT format, void *prefix_data)
 {
     struct ly_set *ns_list;
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index cae048e..71681c3 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -60,12 +60,14 @@
 ly_bool lyb_has_schema_model(const struct lysc_node *sibling, const struct lys_module **models);
 
 /**
- * @brief Check whether a node to be deleted is the first top-level sibling.
+ * @brief Check whether a node to be deleted is the root node, move it if it is.
  *
- * @param[in] first First sibling.
+ * @param[in] root Root sibling.
  * @param[in] to_del Node to be deleted.
+ * @param[in] mod If set, it is expected @p tree should point to the first node of @p mod. Otherwise it will simply be
+ * the first top-level sibling.
  */
-#define LYD_DEL_IS_ROOT(first, to_del) (((first) == (to_del)) && !(first)->parent && !(first)->prev->next)
+void lyd_del_move_root(struct lyd_node **root, const struct lyd_node *to_del, const struct lys_module *mod);
 
 /**
  * @brief Get address of a node's child pointer if any.
diff --git a/src/validation.c b/src/validation.c
index f0320f6..bdfa571 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -152,13 +152,17 @@
  * @brief Evaluate when conditions of collected unres nodes.
  *
  * @param[in,out] tree Data tree, is updated if some nodes are autodeleted.
+ * @param[in] mod Module of the @p tree to take into consideration when deleting @p tree and moving it.
+ * If set, it is expected @p tree should point to the first node of @p mod. Otherwise it will simply be
+ * the first top-level sibling.
  * @param[in] node_when Set with nodes with "when" conditions.
  * @param[in,out] diff Validation diff.
  * @return LY_SUCCESS on success.
  * @return LY_ERR value on error.
  */
 static LY_ERR
-lyd_validate_unres_when(struct lyd_node **tree, struct ly_set *node_when, struct lyd_node **diff)
+lyd_validate_unres_when(struct lyd_node **tree, const struct lys_module *mod, struct ly_set *node_when,
+        struct lyd_node **diff)
 {
     LY_ERR ret;
     uint32_t i;
@@ -181,9 +185,7 @@
                 /* when false */
                 if (node->flags & LYD_WHEN_TRUE) {
                     /* autodelete */
-                    if (LYD_DEL_IS_ROOT(*tree, node)) {
-                        *tree = (*tree)->next;
-                    }
+                    lyd_del_move_root(tree, node, mod);
                     if (diff) {
                         /* add into diff */
                         LY_CHECK_RET(lyd_val_diff_add(node, LYD_DIFF_OP_DELETE, diff));
@@ -211,8 +213,8 @@
 }
 
 LY_ERR
-lyd_validate_unres(struct lyd_node **tree, struct ly_set *node_when, struct ly_set *node_types, struct ly_set *meta_types,
-        struct lyd_node **diff)
+lyd_validate_unres(struct lyd_node **tree, const struct lys_module *mod, struct ly_set *node_when,
+        struct ly_set *node_types, struct ly_set *meta_types, struct lyd_node **diff)
 {
     LY_ERR ret = LY_SUCCESS;
     uint32_t i;
@@ -222,7 +224,7 @@
         uint32_t prev_count;
         do {
             prev_count = node_when->count;
-            LY_CHECK_RET(lyd_validate_unres_when(tree, node_when, diff));
+            LY_CHECK_RET(lyd_validate_unres_when(tree, mod, node_when, diff));
             /* there must have been some when conditions resolved */
         } while (prev_count > node_when->count);
 
@@ -325,12 +327,14 @@
  * @brief Validate multiple case data existence with possible autodelete.
  *
  * @param[in,out] first First sibling to search in, is updated if needed.
+ * @param[in] mod Module of the siblings, NULL for nested siblings.
  * @param[in] choic Choice node whose cases to check.
  * @param[in,out] diff Validation diff.
  * @return LY_ERR value.
  */
 static LY_ERR
-lyd_validate_cases(struct lyd_node **first, const struct lysc_node_choice *choic, struct lyd_node **diff)
+lyd_validate_cases(struct lyd_node **first, const struct lys_module *mod, const struct lysc_node_choice *choic,
+        struct lyd_node **diff)
 {
     const struct lysc_node *scase, *iter, *old_case = NULL, *new_case = NULL;
     struct lyd_node *match, *to_del;
@@ -381,9 +385,8 @@
         match = NULL;
         to_del = NULL;
         while ((match = lys_getnext_data(match, *first, &iter, old_case, NULL))) {
-            if (LYD_DEL_IS_ROOT(*first, to_del)) {
-                *first = (*first)->next;
-            }
+            lyd_del_move_root(first, to_del, mod);
+
             /* free previous node */
             lyd_free_tree(to_del);
             if (diff) {
@@ -392,9 +395,7 @@
             }
             to_del = match;
         }
-        if (LYD_DEL_IS_ROOT(*first, to_del)) {
-            *first = (*first)->next;
-        }
+        lyd_del_move_root(first, to_del, mod);
         lyd_free_tree(to_del);
     }
 
@@ -439,18 +440,17 @@
  *
  * @param[in,out] first First sibling, is updated if needed.
  * @param[in] node Node instance to delete.
+ * @param[in] mod Module of the siblings, NULL for nested siblings.
  * @param[in,out] next_p Temporary LY_LIST_FOR_SAFE next pointer, is updated if needed.
  * @param[in,out] diff Validation diff.
  */
 static void
-lyd_validate_autodel_node_del(struct lyd_node **first, struct lyd_node *node, struct lyd_node **next_p,
-        struct lyd_node **diff)
+lyd_validate_autodel_node_del(struct lyd_node **first, struct lyd_node *node, const struct lys_module *mod,
+        struct lyd_node **next_p, struct lyd_node **diff)
 {
     struct lyd_node *iter;
 
-    if (LYD_DEL_IS_ROOT(*first, node)) {
-        *first = (*first)->next;
-    }
+    lyd_del_move_root(first, node, mod);
     if (node == *next_p) {
         *next_p = (*next_p)->next;
     }
@@ -473,11 +473,13 @@
  *
  * @param[in,out] first First sibling to search in, is updated if needed.
  * @param[in] node New data node instance to check.
+ * @param[in] mod Module of the siblings, NULL for nested siblings.
  * @param[in,out] next_p Temporary LY_LIST_FOR_SAFE next pointer, is updated if needed.
  * @param[in,out] diff Validation diff.
  */
 static void
-lyd_validate_autodel_dup(struct lyd_node **first, struct lyd_node *node, struct lyd_node **next_p, struct lyd_node **diff)
+lyd_validate_autodel_dup(struct lyd_node **first, struct lyd_node *node, const struct lys_module *mod,
+        struct lyd_node **next_p, struct lyd_node **diff)
 {
     struct lyd_node *match, *next;
 
@@ -488,7 +490,7 @@
         LYD_LIST_FOR_INST_SAFE(*first, node->schema, next, match) {
             if ((match->flags & LYD_DEFAULT) && !(match->flags & LYD_NEW)) {
                 /* default instance found, remove it */
-                lyd_validate_autodel_node_del(first, match, next_p, diff);
+                lyd_validate_autodel_node_del(first, match, mod, next_p, diff);
 
                 /* remove only a single container/leaf default instance, if there are more, it is an error */
                 if (node->schema->nodetype & (LYS_LEAF | LYS_CONTAINER)) {
@@ -504,12 +506,13 @@
  *
  * @param[in,out] first First sibling to search in, is updated if needed.
  * @param[in] node Default data node instance to check.
+ * @param[in] mod Module of the siblings, NULL for nested siblings.
  * @param[in,out] next_p Temporary LY_LIST_FOR_SAFE next pointer, is updated if needed.
  * @param[in,out] diff Validation diff.
  */
 static void
-lyd_validate_autodel_case_dflt(struct lyd_node **first, struct lyd_node *node, struct lyd_node **next_p,
-        struct lyd_node **diff)
+lyd_validate_autodel_case_dflt(struct lyd_node **first, struct lyd_node *node, const struct lys_module *mod,
+        struct lyd_node **next_p, struct lyd_node **diff)
 {
     struct lysc_node_choice *choic;
     struct lyd_node *iter = NULL;
@@ -540,7 +543,7 @@
     if (!iter) {
         /* there are only default nodes of the case meaning it does not exist and neither should any default nodes
          * of the case, remove this one default node */
-        lyd_validate_autodel_node_del(first, node, next_p, diff);
+        lyd_validate_autodel_node_del(first, node, mod, next_p, diff);
     }
 }
 
@@ -556,7 +559,7 @@
     while (*first && (snode = lys_getnext(snode, sparent, mod ? mod->compiled : NULL, LYS_GETNEXT_WITHCHOICE))) {
         /* check case duplicites */
         if (snode->nodetype == LYS_CHOICE) {
-            LY_CHECK_RET(lyd_validate_cases(first, (struct lysc_node_choice *)snode, diff));
+            LY_CHECK_RET(lyd_validate_cases(first, mod, (struct lysc_node_choice *)snode, diff));
         }
     }
 
@@ -573,7 +576,7 @@
 
         if (node->flags & LYD_NEW) {
             /* remove old default(s) of the new node if it exists */
-            lyd_validate_autodel_dup(first, node, &next, diff);
+            lyd_validate_autodel_dup(first, node, mod, &next, diff);
 
             /* then check new node instance duplicities */
             LY_CHECK_RET(lyd_validate_duplicates(*first, node));
@@ -584,7 +587,7 @@
 
         if (node->flags & LYD_DEFAULT) {
             /* remove leftover default nodes from a no-longer existing case */
-            lyd_validate_autodel_case_dflt(first, node, &next, diff);
+            lyd_validate_autodel_case_dflt(first, node, mod, &next, diff);
         }
     }
 
@@ -1342,6 +1345,11 @@
                 LYD_IMPLICIT_NO_STATE : 0, diff);
         LY_CHECK_GOTO(ret, cleanup);
 
+        /* our first module node pointer may no longer be the first */
+        while (*first2 && (*first2)->prev->next && (lyd_owner_module(*first2) == lyd_owner_module((*first2)->prev))) {
+            *first2 = (*first2)->prev;
+        }
+
         /* process nested nodes */
         LY_LIST_FOR(*first2, iter) {
             ret = lyd_validate_subtree(iter, &node_types, &meta_types, &node_when, val_opts, diff);
@@ -1349,7 +1357,7 @@
         }
 
         /* finish incompletely validated terminal values/attributes and when conditions */
-        ret = lyd_validate_unres(tree, &node_when, &node_types, &meta_types, diff);
+        ret = lyd_validate_unres(first2, mod, &node_when, &node_types, &meta_types, diff);
         LY_CHECK_GOTO(ret, cleanup);
 
         /* perform final validation that assumes the data tree is final */
@@ -1479,7 +1487,7 @@
     LY_CHECK_GOTO(ret = lyd_validate_subtree(op_node, &type_check, &type_meta_check, &when_check, 0, diff), cleanup);
 
     /* finish incompletely validated terminal values/attributes and when conditions on the full tree */
-    LY_CHECK_GOTO(ret = lyd_validate_unres((struct lyd_node **)&tree, &when_check, &type_check, &type_meta_check,
+    LY_CHECK_GOTO(ret = lyd_validate_unres((struct lyd_node **)&tree, NULL, &when_check, &type_check, &type_meta_check,
             diff), cleanup);
 
     /* perform final validation of the operation/notification */
diff --git a/src/validation.h b/src/validation.h
index 9a7a6b0..ae286be 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -43,14 +43,17 @@
  * !! It is assumed autodeleted nodes cannot be in the unresolved node type set !!
  *
  * @param[in,out] tree Data tree, is updated if some nodes are autodeleted.
+ * @param[in] mod Module of the @p tree to take into consideration when deleting @p tree and moving it.
+ * If set, it is expected @p tree should point to the first node of @p mod. Otherwise it will simply be
+ * the first top-level sibling.
  * @param[in] node_when Set with nodes with "when" conditions, can be NULL.
  * @param[in] node_types Set with nodes with unresolved types, can be NULL
  * @param[in] meta_types Set with metdata with unresolved types, can be NULL.
  * @param[in,out] diff Validation diff.
  * @return LY_ERR value.
  */
-LY_ERR lyd_validate_unres(struct lyd_node **tree, struct ly_set *node_when, struct ly_set *node_types,
-        struct ly_set *meta_types, struct lyd_node **diff);
+LY_ERR lyd_validate_unres(struct lyd_node **tree, const struct lys_module *mod, struct ly_set *node_when,
+        struct ly_set *node_types, struct ly_set *meta_types, struct lyd_node **diff);
 
 /**
  * @brief Validate new siblings. Specifically, check duplicated instances, autodelete default values and cases.
diff --git a/src/xpath.c b/src/xpath.c
index 1fd0e9d..35c29f4 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -8470,6 +8470,14 @@
         return LY_EINVAL;
     }
 
+    if (tree) {
+        /* adjust the pointer to be the first top-level sibling */
+        while (tree->parent) {
+            tree = lyd_parent(tree);
+        }
+        tree = lyd_first_sibling(tree);
+    }
+
     /* prepare set for evaluation */
     memset(set, 0, sizeof *set);
     set->type = LYXP_SET_NODE_SET;
diff --git a/src/xpath.h b/src/xpath.h
index d53bceb..4c5db91 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -284,7 +284,7 @@
  * @param[in] prefix_data Format-specific prefix data (see ::ly_resolve_prefix).
  * @param[in] ctx_node Current (context) data node, NULL in case of the root node.
  * @param[in] tree Data tree on which to perform the evaluation, it must include all the available data (including
- * the tree of @p ctx_node).
+ * the tree of @p ctx_node). Can be any node of the tree, it is adjusted.
  * @param[out] set Result set.
  * @param[in] options Whether to apply some evaluation restrictions.
  * @return LY_EVALID for invalid argument types/count,