diff --git a/src/common.c b/src/common.c
index 69245d4..5139826 100644
--- a/src/common.c
+++ b/src/common.c
@@ -160,6 +160,17 @@
     return new_mem;
 }
 
+char *
+ly_strnchr(const char *s, int c, unsigned int len)
+{
+    for (; *s != (char)c; ++s, --len) {
+        if ((*s == '\0') || (!len)) {
+            return NULL;
+        }
+    }
+    return (char *)s;
+}
+
 LY_ERR
 ly_getutf8(const char **input, unsigned int *utf8_char, size_t *bytes_read)
 {
diff --git a/src/common.h b/src/common.h
index 642ec15..9a41a5d 100644
--- a/src/common.h
+++ b/src/common.h
@@ -214,6 +214,17 @@
 
 #define LY_VCODE_XP_EOE      LYVE_XPATH, "Unterminated string delimited with %c (%.15s)."
 #define LY_VCODE_XP_INEXPR   LYVE_XPATH, "Invalid character number %u of expression \'%s\'."
+#define LY_VCODE_XP_DUMMY    LYVE_XPATH, "Accessing the value of the dummy node \"%s\"."
+#define LY_VCODE_XP_EOF      LYVE_XPATH, "Unexpected XPath expression end."
+#define LY_VCODE_XP_INTOK    LYVE_XPATH, "Unexpected XPath token %s (%.15s)."
+#define LY_VCODE_XP_INFUNC   LYVE_XPATH, "Unknown XPath function \"%.*s\"."
+#define LY_VCODE_XP_INARGCOUNT LYVE_XPATH, "Invalid number of arguments (%d) for the XPath function %.*s."
+#define LY_VCODE_XP_INARGTYPE LYVE_XPATH, "Wrong type of argument #%d (%s) for the XPath function %s."
+#define LY_VCODE_XP_INCTX    LYVE_XPATH, "Invalid context type %s in %s."
+#define LY_VCODE_XP_DUMMY    LYVE_XPATH, "Accessing the value of the dummy node \"%s\"."
+#define LY_VCODE_XP_INOP_1   LYVE_XPATH, "Cannot apply XPath operation %s on %s."
+#define LY_VCODE_XP_INOP_2   LYVE_XPATH, "Cannot apply XPath operation %s on %s and %s."
+#define LY_VCODE_XP_INMOD    LYVE_XPATH, "Unknown module \"%.*s\"."
 
 #define LY_VCODE_DEV_NODETYPE LYVE_REFERENCE, "Invalid deviation of %s node - it is not possible to %s \"%s\" property."
 #define LY_VCODE_DEV_NOT_PRESENT LYVE_REFERENCE, "Invalid deviation %s \"%s\" property \"%s\" which is not present."
@@ -298,6 +309,16 @@
 void *ly_realloc(void *ptr, size_t size);
 
 /**
+ * @brief Just like strchr() function except limit the number of examined characters.
+ *
+ * @param[in] s String to search in.
+ * @param[in] c Character to search for.
+ * @param[in] len Limit the search to this number of characters in @p s.
+ * @return Pointer to first @p c occurence in @p s, NULL if not found in first @p len characters.
+ */
+char *ly_strnchr(const char *s, int c, unsigned int len);
+
+/**
  * @brief Get UTF8 code point of the next character in the input string.
  *
  * @param[in,out] input Input string to process, updated according to the processed/read data.
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 9d6a339..bae918b 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -324,7 +324,7 @@
 
         rc = pcre2_match(patterns[u]->code, (PCRE2_SPTR)str, str_len, 0, PCRE2_ANCHORED | PCRE2_ENDANCHORED, match_data, NULL);
         if (rc == PCRE2_ERROR_NOMATCH) {
-            asprintf(&errmsg, "String \"%.*s\" does not conforms to the %u. pattern restriction of its type.",
+            asprintf(&errmsg, "String \"%.*s\" does not conform to the %u. pattern restriction of its type.",
                      (int)str_len, str, u + 1);
             *err = ly_err_new(LY_LLERR, LY_ESYS, 0, errmsg, NULL, NULL);
             ret = LY_EVALID;
@@ -1595,7 +1595,7 @@
     /* parse the value and try to resolve it in:
      * a) schema tree - instance is not required, just check that the path is instantiable
      * b) data tree - instance is required, so find it */
-    for(token = value; (size_t)(token - value) < value_len;) {
+    for (token = value; (size_t)(token - value) < value_len;) {
         if (token[0] == '/') {
             /* node identifier */
             node_start = &token[1];
@@ -1607,7 +1607,7 @@
 
             token++;
             if (ly_type_store_instanceid_checknodeid(value, value_len, options, type_inst->require_instance,
-                                                        &token, prefixes, format, &node_s, &node_d, trees, &errmsg)) {
+                                                     &token, prefixes, format, &node_s, &node_d, trees, &errmsg)) {
                 goto error;
             }
 
@@ -1642,7 +1642,8 @@
             }
 
 check_predicates:
-            if (ly_parse_instance_predicate(&token, value_len - (token - value), format, &prefix, &prefix_len, &id, &id_len, &val, &val_len, &pred_errmsg)) {
+            if (ly_parse_instance_predicate(&token, value_len - (token - value), format, &prefix, &prefix_len, &id,
+                    &id_len, &val, &val_len, &pred_errmsg)) {
                 asprintf(&errmsg, "Invalid instance-identifier \"%.*s\" value's predicate \"%.*s\" (%s).", (int)value_len, value,
                          (int)(token - pred_start), pred_start, pred_errmsg);
                 goto error;
@@ -2053,7 +2054,8 @@
     return result;
 }
 
-/* @brief Duplication callback of the instance-identifier values.
+/**
+ * @brief Duplication callback of the instance-identifier values.
  *
  * Implementation of the ly_type_dup_clb.
  */
@@ -2111,6 +2113,205 @@
 }
 
 /**
+ * @brief Find leafref target in instance data.
+ */
+const struct lyd_node *
+ly_type_find_leafref(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len,
+                     const struct lyd_node *context_node, const struct lyd_node **trees, struct lyd_value *storage, char **errmsg)
+{
+    struct lysc_type_leafref *type_lr = (struct lysc_type_leafref*)type;
+    const char *first_pred = NULL;
+    const struct lyd_node *start_search;
+    unsigned int u = 0;
+    const char *prefix, *id;
+    size_t prefix_len, id_len;
+    const struct lys_module *mod_node = NULL;
+    const char *token = type_lr->path;
+    const struct lyd_node *node;
+    struct lys_module *mod_context = context_node->schema->module;
+
+    if (token[0] == '/') {
+        /* absolute-path */
+        node = NULL;
+    } else {
+        /*relative-path */
+        node = context_node;
+    }
+
+    /* resolve leafref path */
+    while (*token) {
+        if (!strncmp(token, "../", 3)) {
+            /* level up */
+            token += 2;
+            node = (struct lyd_node*)node->parent;
+        } else if (!strncmp(token, "/../", 4)) {
+            /* level up */
+            token += 3;
+            node = (struct lyd_node*)node->parent;
+        } else if (*token == '/') {
+            /* level down */
+
+            /* reset predicates */
+            first_pred = NULL;
+
+            token++;
+            ly_parse_nodeid(&token, &prefix, &prefix_len, &id, &id_len);
+            mod_node = lys_module_find_prefix(mod_context, prefix, prefix_len);
+
+            if (node) {
+                /* inner node */
+                start_search = lyd_node_children(node);
+next_instance_inner:
+                if (start_search) {
+                    node = lyd_search(start_search, mod_node, id, id_len, 0, NULL, 0);
+                } else {
+                    node = NULL;
+                }
+            } else {
+                /* top-level node */
+                LY_ARRAY_FOR(trees, u) {
+                    start_search = trees[u];
+next_instance_toplevel:
+                    node = lyd_search(start_search, mod_node, id, id_len, 0, NULL, 0);
+                    if (node) {
+                        break;
+                    }
+                }
+            }
+            if (!node) {
+                /* node not found */
+                const char *pathstr_end = token;
+                if (first_pred) {
+                    /* some node instances actually exist, but they do not fit the predicate restrictions,
+                     * here we want to find the end of the list's predicate(s) */
+                    for (pathstr_end = ly_type_path_predicate_end(token);
+                            pathstr_end[1] == '[';
+                            pathstr_end = ly_type_path_predicate_end(pathstr_end + 1));
+                    /* move after last ']' (after each predicate follows "/something" since path must points to
+                     * a leaf/leaflist and predicates are allowed only for lists) */
+                    pathstr_end++;
+                }
+                asprintf(errmsg, "Invalid leafref - required instance \"%.*s\" does not exists in the data tree(s).",
+                         (int)(pathstr_end - type_lr->path), type_lr->path);
+                return NULL;
+            }
+        } else if (*token == '[') {
+            /* predicate */
+            const char *pred_start = token;
+            const struct lyd_node_term *key;
+            const struct lyd_node *value;
+            const struct lys_module *mod_pred;
+            const char *pred_end = ly_type_path_predicate_end(token);
+            const char *src_prefix, *src;
+            size_t src_prefix_len, src_len;
+
+            /* remember start of the first predicate to be able to return back when comparison fails
+             * on a subsequent predicate in case of multiple predicates - on the next node instance
+             * we have to start again with the first predicate */
+            if (!first_pred) {
+                first_pred = pred_start;
+            }
+
+            /* move after "[ *WSP" */
+            token++;
+            for (; isspace(*token); token++);
+
+            /* parse node-identifier */
+            ly_parse_nodeid(&token, &src_prefix, &src_prefix_len, &src, &src_len);
+            mod_pred = lys_module_find_prefix(mod_context, src_prefix, src_prefix_len);
+
+            key = (const struct lyd_node_term*)lyd_search(lyd_node_children(node), mod_pred, src, src_len, LYS_LEAF, NULL, 0);
+            if (!key) {
+                asprintf(errmsg, "Internal error - missing expected list's key \"%.*s\" in module \"%s\" (%s:%d).",
+                         (int)src_len, src, mod_pred->name, __FILE__, __LINE__);
+                LOGINT(ctx);
+                return NULL;
+            }
+
+            /* move after "*WSP = *WSP" */
+            for (; *token != '='; token++);
+            for (token++; isspace(*token); token++);
+            /* move after "current() *WSP / *WSP 1*(.. *WSP / *WSP)" */
+            token = strchr(token, ')') + 1;
+            for (; *token != '/'; token++);
+            for (; *token != '.'; token++);
+            for (value = (const struct lyd_node*)context_node; *token == '.'; ) {
+                value = (struct lyd_node*)value->parent; /* level up by .. */
+                for (token += 2; *token != '/'; token++);
+                for (token++; isspace(*token); token++);
+            }
+
+            /* parse "*(node-identifier *WSP / *WSP) node-identifier */
+            do {
+                /* parse node-identifier */
+                ly_parse_nodeid(&token, &src_prefix, &src_prefix_len, &src, &src_len);
+                mod_pred = lys_module_find_prefix(mod_context, src_prefix, src_prefix_len);
+
+                if (!value) {
+                    /* top-level search */
+                    LY_ARRAY_FOR(trees, u) {
+                        value = lyd_search(trees[u], mod_pred, src, src_len, 0, NULL, 0);
+                        if (value) {
+                            break;
+                        }
+                    }
+                } else {
+                    /* inner node */
+                    value = lyd_search(lyd_node_children(value), mod_pred, src, src_len, 0, NULL, 0);
+                }
+                if (!value) {
+                    /* node not found - try another instance */
+                    goto next_instance;
+                }
+
+                for (; isspace(*token); token++);
+                if (*token == '/') {
+                    /* - move after it and consume whitespaces */
+                    for (token++; isspace(*token); token++);
+                }
+            } while (*token != ']');
+
+            /* compare key and the value */
+            if (key->value.realtype->plugin->compare(&key->value, &((struct lyd_node_term*)value)->value)) {
+                /* nodes does not match, try another instance */
+next_instance:
+                token = first_pred;
+                start_search = node->next;
+                if (node->parent) {
+                    goto next_instance_inner;
+                } else {
+                    goto next_instance_toplevel;
+                }
+            }
+            /* match */
+
+            /* move after predicate */
+            assert(token == pred_end);
+            token = pred_end + 1;
+        }
+    }
+
+    /* check value */
+    while (node && type_lr->realtype->plugin->compare(&((struct lyd_node_term*)node)->value, storage)) {
+        /* values do not match, try another instance of the node */
+        const struct lysc_node *schema = node->schema;
+        LY_LIST_FOR(node->next, node) {
+            if (node->schema == schema) {
+                break;
+            }
+        }
+    }
+    if (!node) {
+        /* node not found */
+        asprintf(errmsg, "Invalid leafref value \"%.*s\" - required instance \"%.*s\" with this value does not exists"
+                 " in the data tree(s).", (int)value_len, value, (int)(token - type_lr->path), type_lr->path);
+        return NULL;
+    }
+
+    return node;
+}
+
+/**
  * @brief Validate, canonize and store value of the YANG built-in leafref type.
  *
  * Implementation of the ly_type_store_clb.
@@ -2122,15 +2323,9 @@
                       struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
     LY_ERR ret;
-    unsigned int u = 0;
     char *errmsg = NULL;
     struct lysc_type_leafref *type_lr = (struct lysc_type_leafref*)type;
     int storage_dummy = 0;
-    const char *first_pred = NULL;
-    const struct lyd_node *start_search;
-    const char *prefix, *id;
-    size_t prefix_len, id_len;
-    const struct lys_module *mod_node = NULL;
 
     if (!(options & (LY_TYPE_OPTS_STORE | LY_TYPE_OPTS_INCOMPLETE_DATA)) && type_lr->require_instance) {
         /* if there is no storage, but we will check the instance presence in data tree(s),
@@ -2155,185 +2350,7 @@
         }
 
         /* find corresponding data instance */
-        const char *token = type_lr->path;
-        const struct lyd_node *node;
-        struct lys_module *mod_context = ((const struct lyd_node*)context_node)->schema->module;
-
-        if (token[0] == '/') {
-            /* absolute-path */
-            node = NULL;
-        } else {
-            /*relative-path */
-            node = (const struct lyd_node*)context_node;
-        }
-
-        /* resolve leafref path */
-        while (*token) {
-            if (!strncmp(token, "../", 3)) {
-                /* level up */
-                token += 2;
-                node = (struct lyd_node*)node->parent;
-            } else if (!strncmp(token, "/../", 4)) {
-                /* level up */
-                token += 3;
-                node = (struct lyd_node*)node->parent;
-            } else if (*token == '/') {
-                /* level down */
-
-                /* reset predicates */
-                first_pred = NULL;
-
-                token++;
-                ly_parse_nodeid(&token, &prefix, &prefix_len, &id, &id_len);
-                mod_node = lys_module_find_prefix(mod_context, prefix, prefix_len);
-
-                if (node) {
-                    /* inner node */
-                    start_search = lyd_node_children(node);
-next_instance_inner:
-                    if (start_search) {
-                        node = lyd_search(start_search, mod_node, id, id_len, 0, NULL, 0);
-                    } else {
-                        node = NULL;
-                    }
-                } else {
-                    /* top-level node */
-                    LY_ARRAY_FOR(trees, u) {
-                        start_search = trees[u];
-next_instance_toplevel:
-                        node = lyd_search(start_search, mod_node, id, id_len, 0, NULL, 0);
-                        if (node) {
-                            break;
-                        }
-                    }
-                }
-                if (!node) {
-                    /* node not found */
-                    const char *pathstr_end = token;
-                    if (first_pred) {
-                        /* some node instances actually exist, but they do not fit the predicate restrictions,
-                         * here we want to find the end of the list's predicate(s) */
-                        for (pathstr_end = ly_type_path_predicate_end(token);
-                                pathstr_end[1] == '[';
-                                pathstr_end = ly_type_path_predicate_end(pathstr_end + 1));
-                        /* move after last ']' (after each predicate follows "/something" since path must points to
-                         * a leaf/leaflist and predicates are allowed only for lists) */
-                        pathstr_end++;
-                    }
-                    asprintf(&errmsg, "Invalid leafref - required instance \"%.*s\" does not exists in the data tree(s).",
-                             (int)(pathstr_end - type_lr->path), type_lr->path);
-                    goto error;
-                }
-            } else if (*token == '[') {
-                /* predicate */
-                const char *pred_start = token;
-                const struct lyd_node_term *key;
-                const struct lyd_node *value;
-                const struct lys_module *mod_pred;
-                const char *pred_end = ly_type_path_predicate_end(token);
-                const char *src_prefix, *src;
-                size_t src_prefix_len, src_len;
-
-                /* remember start of the first predicate to be able to return back when comparison fails
-                 * on a subsequent predicate in case of multiple predicates - on the next node instance
-                 * we have to start again with the first predicate */
-                if (!first_pred) {
-                    first_pred = pred_start;
-                }
-
-                /* move after "[ *WSP" */
-                token++;
-                for (; isspace(*token); token++);
-
-                /* parse node-identifier */
-                ly_parse_nodeid(&token, &src_prefix, &src_prefix_len, &src, &src_len);
-                mod_pred = lys_module_find_prefix(mod_context, src_prefix, src_prefix_len);
-
-                key = (const struct lyd_node_term*)lyd_search(lyd_node_children(node), mod_pred, src, src_len, LYS_LEAF, NULL, 0);
-                if (!key) {
-                    asprintf(&errmsg, "Internal error - missing expected list's key \"%.*s\" in module \"%s\" (%s:%d).",
-                             (int)src_len, src, mod_pred->name, __FILE__, __LINE__);
-                    LOGINT(ctx);
-                    goto error;
-                }
-
-                /* move after "*WSP = *WSP" */
-                for (; *token != '='; token++);
-                for (token++; isspace(*token); token++);
-                /* move after "current() *WSP / *WSP 1*(.. *WSP / *WSP)" */
-                token = strchr(token, ')') + 1;
-                for (; *token != '/'; token++);
-                for (; *token != '.'; token++);
-                for (value = (const struct lyd_node*)context_node; *token == '.'; ) {
-                    value = (struct lyd_node*)value->parent; /* level up by .. */
-                    for (token += 2; *token != '/'; token++);
-                    for (token++; isspace(*token); token++);
-                }
-
-                /* parse "*(node-identifier *WSP / *WSP) node-identifier */
-                do {
-                    /* parse node-identifier */
-                    ly_parse_nodeid(&token, &src_prefix, &src_prefix_len, &src, &src_len);
-                    mod_pred = lys_module_find_prefix(mod_context, src_prefix, src_prefix_len);
-
-                    if (!value) {
-                        /* top-level search */
-                        LY_ARRAY_FOR(trees, u) {
-                            value = lyd_search(trees[u], mod_pred, src, src_len, 0, NULL, 0);
-                            if (value) {
-                                break;
-                            }
-                        }
-                    } else {
-                        /* inner node */
-                        value = lyd_search(lyd_node_children(value), mod_pred, src, src_len, 0, NULL, 0);
-                    }
-                    if (!value) {
-                        /* node not found - try another instance */
-                        goto next_instance;
-                    }
-
-                    for (; isspace(*token); token++);
-                    if (*token == '/') {
-                        /* - move after it and consume whitespaces */
-                        for (token++; isspace(*token); token++);
-                    }
-                } while (*token != ']');
-
-                /* compare key and the value */
-                if (key->value.realtype->plugin->compare(&key->value, &((struct lyd_node_term*)value)->value)) {
-                    /* nodes does not match, try another instance */
-next_instance:
-                    token = first_pred;
-                    start_search = node->next;
-                    if (node->parent) {
-                        goto next_instance_inner;
-                    } else {
-                        goto next_instance_toplevel;
-                    }
-                }
-                /* match */
-
-                /* move after predicate */
-                assert(token == pred_end);
-                token = pred_end + 1;
-            }
-        }
-
-        /* check value */
-        while (node && type_lr->realtype->plugin->compare(&((struct lyd_node_term*)node)->value, storage)) {
-            /* values do not match, try another instance of the node */
-            const struct lysc_node *schema = node->schema;
-            LY_LIST_FOR(node->next, node) {
-                if (node->schema == schema) {
-                    break;
-                }
-            }
-        }
-        if (!node) {
-            /* node not found */
-            asprintf(&errmsg, "Invalid leafref value \"%.*s\" - required instance \"%.*s\" with this value does not exists in the data tree(s).",
-                     (int)value_len, value, (int)(token - type_lr->path), type_lr->path);
+        if (!ly_type_find_leafref(ctx, type, value, value_len, (const struct lyd_node *)context_node, trees, storage, &errmsg)) {
             goto error;
         }
     }
diff --git a/src/plugins_types.h b/src/plugins_types.h
index a071d38..0a984c3 100644
--- a/src/plugins_types.h
+++ b/src/plugins_types.h
@@ -276,6 +276,26 @@
 LY_ERR ly_type_validate_patterns(struct lysc_pattern **patterns, const char *str, size_t str_len, struct ly_err_item **err);
 
 /**
+ * @brief Find leafref target in instance data.
+ *
+ * @param[in] ctx libyang Context
+ * @param[in] type Type of the value being canonized.
+ * @param[in] value Lexical representation of the value to be validated (and canonized).
+ *            It is never NULL, empty string is represented as "" with zero @p value_len.
+ * @param[in] value_len Length (number of bytes) of the given \p value.
+ * @param[in] context_node The @p value's node for the case that the require-instance restriction is supposed to be resolved.
+ * @param[in] trees ([Sized array](@ref sizedarrays)) of external data trees (e.g. when validating RPC/Notification) where the required data
+ *            instance can be placed.
+ *
+ * @param[in] storage Parsed @p value.
+ * @param[out] errmsg Error message in case of error.
+ * @return Leafref target node or NULL on error when @p errmsg is always set.
+ */
+const struct lyd_node *ly_type_find_leafref(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len,
+                                            const struct lyd_node *context_node, const struct lyd_node **trees,
+                                            struct lyd_value *storage, char **errmsg);
+
+/**
  * @brief Helper function for type validation callbacks to prepare list of all possible prefixes used in the value string.
  *
  * @param[in] ctx libyang context.
diff --git a/src/tree.h b/src/tree.h
index d0a9ced..0f02120 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -20,13 +20,6 @@
 #endif
 
 /**
- * @brief Types of the different schema and data paths.
- */
-typedef enum {
-    LY_PATH_LOG /**< Descriptive path format used in log messages */
-} LY_PATH_TYPE;
-
-/**
  * @brief Macro selector for other LY_ARRAY_* macros, do not use directly!
  */
 #define LY_ARRAY_SELECT(_1, _2, NAME, ...) NAME
diff --git a/src/tree_data.h b/src/tree_data.h
index 41f8d01..d6babc2 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -105,6 +105,11 @@
     }
 
 /**
+ * @brief Macro to get context from a data tree node.
+ */
+#define LYD_NODE_CTX(node) ((node)->schema->module->ctx)
+
+/**
  * @brief Data input/output formats supported by libyang [parser](@ref howtodataparsers) and
  * [printer](@ref howtodataprinters) functions.
  */
@@ -247,6 +252,7 @@
  */
 
 #define LYD_DEFAULT      0x01        /**< default (implicit) node; */
+#define LYD_DUMMY        0x80000000  /**< dummy node (in XPath context, internal flag) */
 /** @} */
 
 /**
diff --git a/src/tree_schema.c b/src/tree_schema.c
index daf0a56..c034581 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -216,12 +216,10 @@
     return NULL;
 }
 
-
-
 API char *
-lysc_path(struct lysc_node *node, LY_PATH_TYPE pathtype, char *buffer, size_t buflen)
+lysc_path(const struct lysc_node *node, LYSC_PATH_TYPE pathtype, char *buffer, size_t buflen)
 {
-    struct lysc_node *iter;
+    const struct lysc_node *iter;
     char *path = NULL;
     int len = 0;
 
@@ -231,26 +229,12 @@
     }
 
     switch (pathtype) {
-    case LY_PATH_LOG:
+    case LYSC_PATH_LOG:
         for (iter = node; iter && len >= 0; iter = iter->parent) {
             char *s = buffer ? strdup(buffer) : path;
             char *id;
 
-            switch (iter->nodetype) {
-            case LYS_USES:
-                asprintf(&id, "{uses='%s'}", iter->name);
-                break;
-            case LYS_GROUPING:
-                asprintf(&id, "{grouping='%s'}", iter->name);
-                break;
-            case LYS_AUGMENT:
-                asprintf(&id, "{augment='%s'}", iter->name);
-                break;
-            default:
-                id = strdup(iter->name);
-                break;
-            }
-
+            id = strdup(iter->name);
             if (!iter->parent || iter->parent->module != iter->module) {
                 /* print prefix */
                 if (buffer) {
diff --git a/src/tree_schema.h b/src/tree_schema.h
index da73da2..b7a8c5d 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -699,42 +699,46 @@
  *     1 - container    6 - anydata/anyxml    11 - identity
  *     2 - choice       7 - case              12 - extension
  *     3 - leaf         8 - notification      13 - bitenum
- *     4 - leaflist     9 - rpc
- *     5 - list        10 - feature
+ *     4 - leaflist     9 - rpc/action        14 - when
+ *     5 - list        10 - feature           15 - must
  *
- *                                             1 1 1 1
- *     bit name              1 2 3 4 5 6 7 8 9 0 1 2 3
- *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       1 LYS_CONFIG_W     |x|x|x|x|x|x|x| | | | | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       2 LYS_CONFIG_R     |x|x|x|x|x|x|x| | | | | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       3 LYS_STATUS_CURR  |x|x|x|x|x|x|x|x|x|x|x|x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       4 LYS_STATUS_DEPRC |x|x|x|x|x|x|x|x|x|x|x|x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       5 LYS_STATUS_OBSLT |x|x|x|x|x|x|x|x|x|x|x|x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       6 LYS_MAND_TRUE    |x|x|x|x|x|x| | | | | | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       7 LYS_ORDBY_USER   | | | |x|x| | | | | | | | |
- *         LYS_MAND_FALSE   | |x|x| | |x| | | | | | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       8 LYS_ORDBY_SYSTEM | | | |x|x| | | | | | | | |
- *         LYS_PRESENCE     |x| | | | | | | | | | | | |
- *         LYS_UNIQUE       | | |x| | | | | | | | | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       9 LYS_KEY          | | |x| | | | | | | | | | |
- *         LYS_FENABLED     | | | | | | | | | |x| | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      10 LYS_SET_DFLT     | | |x|x| | |x| | | | | | |
- *         LYS_ISENUM       | | | | | | | | | | | | |x|
- *         LYS_KEYLESS      | | | | |x| | | | | | | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      11 LYS_SET_UNITS    | | |x|x| | | | | | | | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      12 LYS_SET_CONFIG   |x|x|x|x|x|x| | | | | | | |
- *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *                                             1 1 1 1 1 1
+ *     bit name              1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       1 LYS_CONFIG_W     |x|x|x|x|x|x|x| | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       2 LYS_CONFIG_R     |x|x|x|x|x|x|x| | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       3 LYS_STATUS_CURR  |x|x|x|x|x|x|x|x|x|x|x|x| | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       4 LYS_STATUS_DEPRC |x|x|x|x|x|x|x|x|x|x|x|x| | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       5 LYS_STATUS_OBSLT |x|x|x|x|x|x|x|x|x|x|x|x| | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       6 LYS_MAND_TRUE    |x|x|x|x|x|x| | | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       7 LYS_ORDBY_USER   | | | |x|x| | | | | | | | | | |
+ *         LYS_MAND_FALSE   | |x|x| | |x| | | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       8 LYS_ORDBY_SYSTEM | | | |x|x| | | | | | | | | | |
+ *         LYS_PRESENCE     |x| | | | | | | | | | | | | | |
+ *         LYS_UNIQUE       | | |x| | | | | | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       9 LYS_KEY          | | |x| | | | | | | | | | | | |
+ *         LYS_FENABLED     | | | | | | | | | |x| | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      10 LYS_SET_DFLT     | | |x|x| | |x| | | | | | | | |
+ *         LYS_ISENUM       | | | | | | | | | | | | |x| | |
+ *         LYS_KEYLESS      | | | | |x| | | | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      11 LYS_SET_UNITS    | | |x|x| | | | | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      12 LYS_SET_CONFIG   |x|x|x|x|x|x| | | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      13 LYS_XPATH_DEP    |x|x|x|x|x|x|x|x| | | | | |x|x|
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      14 LYS_LEAFREF_DEP  | | |x|x| | | | | | | | | | | |
+ *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
  */
 
@@ -796,6 +800,9 @@
 #define LYS_SET_UNITS    0x0400      /**< flag to know if the leaf's/leaflist's units are their own (flag set) or it is taken from the type. */
 #define LYS_SET_CONFIG   0x0800      /**< flag to know if the config property was set explicitly (flag set) or it is inherited. */
 
+#define LYS_XPATH_DEP    0x1000      /**< flag for nodes with when/must with external data dependency. */
+#define LYS_LEAFREF_DEP  0x2000      /**< flag for leaves(-lists) with leafref with external dependency. */
+
 #define LYS_SINGLEQUOTED 0x100       /**< flag for single-quoted argument of an extension instance's substatement, only when the source is YANG */
 #define LYS_DOUBLEQUOTED 0x200       /**< flag for double-quoted argument of an extension instance's substatement, only when the source is YANG */
 
@@ -1163,6 +1170,7 @@
     const char *ref;                 /**< reference */
     struct lysc_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
     uint32_t refcount;               /**< reference counter since some of the when statements are shared among several nodes */
+    uint16_t flags;                  /**< [schema node flags](@ref snodeflags) - only LYS_XPATH_DEP is allowed */
 };
 
 /**
@@ -1254,6 +1262,7 @@
     const char *emsg;                /**< error-message */
     const char *eapptag;             /**< error-app-tag value */
     struct lysc_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+    uint16_t flags;                  /**< [schema node flags](@ref snodeflags) - only LYS_XPATH_DEP is allowed */
 };
 
 struct lysc_type {
@@ -1339,7 +1348,7 @@
     struct lysc_type_plugin *plugin; /**< type's plugin with built-in as well as user functions to canonize or validate the value of the type */
     LY_DATA_TYPE basetype;           /**< Base type of the type */
     uint32_t refcount;               /**< reference counter for type sharing */
-    const char* path;                /**< target path */
+    const char *path;                /**< target path */
     struct lys_module *path_context; /**< module where the path is defined, so it provides context to resolve prefixes */
     struct lysc_type *realtype;      /**< pointer to the real (first non-leafref in possible leafrefs chain) type. */
     uint8_t require_instance;        /**< require-instance flag */
@@ -1732,6 +1741,13 @@
 int lysc_feature_value(const struct lysc_feature *feature);
 
 /**
+ * @brief Types of the different schema paths.
+ */
+typedef enum {
+    LYSC_PATH_LOG /**< Descriptive path format used in log messages */
+} LYSC_PATH_TYPE;
+
+/**
  * @brief Generate path of the given node in the requested format.
  *
  * @param[in] node Schema path of this node will be generated.
@@ -1742,7 +1758,7 @@
  * @return NULL in case of memory allocation error, path of the node otherwise.
  * In case the @p buffer is NULL, the returned string is dynamically allocated and caller is responsible to free it.
  */
-char *lysc_path(struct lysc_node *node, LY_PATH_TYPE pathtype, char *buffer, size_t buflen);
+char *lysc_path(const struct lysc_node *node, LYSC_PATH_TYPE pathtype, char *buffer, size_t buflen);
 
 /**
  * @brief Available YANG schema tree structures representing YANG module.
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index f3fba16..d97328c 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -1788,13 +1788,14 @@
 /**
  * @brief Checks pattern syntax.
  *
- * @param[in] ctx Compile context.
+ * @param[in] ctx Context.
+ * @param[in] log_path Path for logging errors.
  * @param[in] pattern Pattern to check.
  * @param[in,out] pcre2_code Compiled PCRE2 pattern. If NULL, the compiled information used to validate pattern are freed.
  * @return LY_ERR value - LY_SUCCESS, LY_EMEM, LY_EVALID.
  */
-static LY_ERR
-lys_compile_type_pattern_check(struct lysc_ctx *ctx, const char *pattern, pcre2_code **code)
+LY_ERR
+lys_compile_type_pattern_check(struct ly_ctx *ctx, const char *log_path, const char *pattern, pcre2_code **code)
 {
     int idx, idx2, start, end, count;
     char *perl_regex, *ptr;
@@ -1893,11 +1894,11 @@
     /* adjust the expression to a Perl equivalent
      * http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#regexs */
 
-    /* we need to replace all "$" with "\$", count them now */
+    /* we need to replace all "$" and "^" with "\$" and "\^", count them now */
     for (count = 0, ptr = strpbrk(pattern, "^$"); ptr; ++count, ptr = strpbrk(ptr + 1, "^$"));
 
     perl_regex = malloc((strlen(pattern) + 4 + count) * sizeof(char));
-    LY_CHECK_ERR_RET(!perl_regex, LOGMEM(ctx->ctx), LY_EMEM);
+    LY_CHECK_ERR_RET(!perl_regex, LOGMEM(ctx), LY_EMEM);
     perl_regex[0] = '\0';
 
     ptr = perl_regex;
@@ -1921,7 +1922,7 @@
 
         ptr = strchr(ptr, '}');
         if (!ptr) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_INREGEXP,
+            LOGVAL(ctx, LY_VLOG_STR, log_path, LY_VCODE_INREGEXP,
                    pattern, perl_regex + start + 2, "unterminated character property");
             free(perl_regex);
             return LY_EVALID;
@@ -1931,7 +1932,7 @@
         /* need more space */
         if (end - start < URANGE_LEN) {
             perl_regex = ly_realloc(perl_regex, strlen(perl_regex) + (URANGE_LEN - (end - start)) + 1);
-            LY_CHECK_ERR_RET(!perl_regex, LOGMEM(ctx->ctx); free(perl_regex), LY_EMEM);
+            LY_CHECK_ERR_RET(!perl_regex, LOGMEM(ctx); free(perl_regex), LY_EMEM);
         }
 
         /* find our range */
@@ -1941,7 +1942,7 @@
             }
         }
         if (!ublock2urange[idx][0]) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_INREGEXP,
+            LOGVAL(ctx, LY_VLOG_STR, log_path, LY_VCODE_INREGEXP,
                    pattern, perl_regex + start + 5, "unknown block name");
             free(perl_regex);
             return LY_EVALID;
@@ -1973,7 +1974,7 @@
     if (!code_local) {
         PCRE2_UCHAR err_msg[256] = {0};
         pcre2_get_error_message(err_code, err_msg, 256);
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_INREGEXP, pattern, perl_regex + err_offset, err_msg);
+        LOGVAL(ctx, LY_VLOG_STR, log_path, LY_VCODE_INREGEXP, pattern, perl_regex + err_offset, err_msg);
         free(perl_regex);
         return LY_EVALID;
     }
@@ -2018,7 +2019,7 @@
         *pattern = calloc(1, sizeof **pattern);
         ++(*pattern)->refcount;
 
-        ret = lys_compile_type_pattern_check(ctx, &patterns_p[u].arg[1], &(*pattern)->code);
+        ret = lys_compile_type_pattern_check(ctx->ctx, ctx->path, &patterns_p[u].arg[1], &(*pattern)->code);
         LY_CHECK_RET(ret);
 
         if (patterns_p[u].arg[0] == 0x15) {
@@ -2219,7 +2220,7 @@
 
 #define MOVE_PATH_PARENT(NODE, LIMIT_COND, TERM, ERR_MSG, ...) \
     for ((NODE) = (NODE)->parent; \
-         (NODE) && !((NODE)->nodetype & (LYS_CONTAINER | LYS_LIST | LYS_ACTION | LYS_NOTIF | LYS_ACTION)); \
+         (NODE) && !((NODE)->nodetype & (LYS_CONTAINER | LYS_LIST | LYS_NOTIF | LYS_ACTION)); \
          (NODE) = (NODE)->parent); \
     if (!(NODE) && (LIMIT_COND)) { /* we are going higher than top-level */ \
         LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, ERR_MSG, ##__VA_ARGS__); \
@@ -2580,6 +2581,54 @@
 }
 
 /**
+ * @brief Check whether a leafref has an external dependency or not.
+ *
+ * @param[in] startnode Node with the leafref.
+ * @param[in] local_mod Local module for the leafref path.
+ * @param[in] first_node First found node when resolving the leafref.
+ * @param[in] abs_path Whether the leafref path is absolute or relative.
+ * @return 0 is the leafref does not require an external dependency, non-zero is it requires.
+ */
+static int
+lys_compile_leafref_has_dep_flag(const struct lysc_node *startnode, const struct lys_module *local_mod,
+                                 const struct lysc_node *first_node, int abs_path)
+{
+    int dep1, dep2;
+    const struct lysc_node *op_node, *node;
+
+    /* find operation schema we are in */
+    for (op_node = startnode->parent;
+        op_node && !(op_node->nodetype & (LYS_ACTION | LYS_NOTIF));
+        op_node = op_node->parent);
+
+    if (!op_node) {
+        /* leafref pointing to a different module */
+        if (local_mod != first_node->module) {
+            return 1;
+        }
+    } else if (op_node->parent) {
+        /* inner operation (notif/action) */
+        if (abs_path) {
+            return 1;
+        } else {
+            /* compare depth of both nodes */
+            for (dep1 = 0, node = op_node; node->parent; node = node->parent);
+            for (dep2 = 0, node = first_node; node->parent; node = node->parent);
+            if ((dep2 > dep1) || ((dep2 == dep1) && (op_node != first_node))) {
+                return 1;
+            }
+        }
+    } else {
+        /* top-level operation (notif/rpc) */
+        if (op_node != first_node) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+/**
  * @brief Validate the leafref path.
  * @param[in] ctx Compile context
  * @param[in] startnode Path context node (where the leafref path begins/is placed).
@@ -2589,7 +2638,7 @@
 static LY_ERR
 lys_compile_leafref_validate(struct lysc_ctx *ctx, struct lysc_node *startnode, struct lysc_type_leafref *leafref)
 {
-    const struct lysc_node *node = NULL, *parent = NULL;
+    const struct lysc_node *node = NULL, *parent = NULL, *tmp_parent;
     const struct lys_module *mod;
     struct lysc_type *type;
     const char *id, *prefix, *name;
@@ -2603,7 +2652,7 @@
     assert(leafref);
 
     ctx->path[0] = '\0';
-    lysc_path(startnode, LY_PATH_LOG, ctx->path, LYSC_CTX_BUFSIZE);
+    lysc_path(startnode, LYSC_PATH_LOG, ctx->path, LYSC_CTX_BUFSIZE);
     ctx->path_len = strlen(ctx->path);
 
     iter = 0;
@@ -2646,6 +2695,16 @@
         }
         parent = node;
 
+        if (!iter) {
+            /* find module whose data will actually contain this leafref */
+            for (tmp_parent = parent; tmp_parent->parent; tmp_parent = tmp_parent->parent);
+
+            /* set external dependency flag, we can decide based on the first found node */
+            if (lys_compile_leafref_has_dep_flag(startnode, tmp_parent->module, node, (parent_times == -1 ? 1 : 0))) {
+                startnode->flags |= LYS_LEAFREF_DEP;
+            }
+        }
+
         if (has_predicate) {
             /* we have predicate, so the current result must be list */
             if (node->nodetype != LYS_LIST) {
@@ -6995,7 +7054,7 @@
         if (err) {
             ly_err_print(err);
             ctx.path[0] = '\0';
-            lysc_path(r->context_node, LY_PATH_LOG, ctx.path, LYSC_CTX_BUFSIZE);
+            lysc_path(r->context_node, LYSC_PATH_LOG, ctx.path, LYSC_CTX_BUFSIZE);
             LOGVAL(ctx.ctx, LY_VLOG_STR, ctx.path, LYVE_SEMANTICS,
                    "Invalid default - value does not fit the type (%s).", err->msg);
             ly_err_free(err);
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 1fac1fe..75e55fd 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -647,6 +647,17 @@
 uint8_t lysc_iff_getop(uint8_t *list, int pos);
 
 /**
+ * @brief Checks pattern syntax.
+ *
+ * @param[in] ctx Context.
+ * @param[in] log_path Path for logging errors.
+ * @param[in] pattern Pattern to check.
+ * @param[in,out] pcre2_code Compiled PCRE2 pattern. If NULL, the compiled information used to validate pattern are freed.
+ * @return LY_ERR value - LY_SUCCESS, LY_EMEM, LY_EVALID.
+ */
+LY_ERR lys_compile_type_pattern_check(struct ly_ctx *ctx, const char *log_path, const char *pattern, pcre2_code **code);
+
+/**
  * @brief Internal wrapper around lys_compile_extension() to be able to prepare list of compiled extension definitions
  * even for the parsed (not-implemented) module - see lys_module::off_extensions.
  *
diff --git a/src/xpath.c b/src/xpath.c
index 69d656c..7ec8c0b 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -3,7 +3,7 @@
  * @author Michal Vasko <mvasko@cesnet.cz>
  * @brief YANG XPath evaluation functions
  *
- * Copyright (c) 2015 - 2017 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2019 CESNET, z.s.p.o.
  *
  * This source code is licensed under BSD 3-Clause License (the "License").
  * You may not use this file except in compliance with the License.
@@ -11,25 +11,2432 @@
  *
  *     https://opensource.org/licenses/BSD-3-Clause
  */
+#define _GNU_SOURCE
+
+/* needed by libmath functions isfinite(), isinf(), isnan(), signbit(), ... */
+#define _ISOC99_SOURCE
 
 #include "common.h"
 
+#include <math.h>
 #include <ctype.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
+#include <assert.h>
 
 #include "xpath.h"
 #include "dict.h"
 #include "xml.h"
+#include "printer_data.h"
+#include "tree_schema_internal.h"
+#include "plugins_types.h"
+
+static const struct lyd_node *moveto_get_root(const struct lyd_node *ctx_node, int options,
+                                              enum lyxp_node_type *root_type);
+static LY_ERR reparse_or_expr(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx);
+static int set_scnode_insert_node(struct lyxp_set *set, const struct lysc_node *node, enum lyxp_node_type node_type);
+static LY_ERR eval_expr_select(struct lyxp_expr *exp, uint16_t *exp_idx, enum lyxp_expr_type etype, struct lyxp_set *set, int options);
+
+/**
+ * @brief Print the type of an XPath \p set.
+ *
+ * @param[in] set Set to use.
+ * @return Set type string.
+ */
+static const char *
+print_set_type(struct lyxp_set *set)
+{
+    switch (set->type) {
+    case LYXP_SET_EMPTY:
+        return "empty";
+    case LYXP_SET_NODE_SET:
+        return "node set";
+    case LYXP_SET_SCNODE_SET:
+        return "schema node set";
+    case LYXP_SET_BOOLEAN:
+        return "boolean";
+    case LYXP_SET_NUMBER:
+        return "number";
+    case LYXP_SET_STRING:
+        return "string";
+    }
+
+    return NULL;
+}
+
+/**
+ * @brief Print an XPath token \p tok type.
+ *
+ * @param[in] tok Token to use.
+ * @return Token type string.
+ */
+static const char *
+print_token(enum lyxp_token tok)
+{
+    switch (tok) {
+    case LYXP_TOKEN_PAR1:
+        return "(";
+    case LYXP_TOKEN_PAR2:
+        return ")";
+    case LYXP_TOKEN_BRACK1:
+        return "[";
+    case LYXP_TOKEN_BRACK2:
+        return "]";
+    case LYXP_TOKEN_DOT:
+        return ".";
+    case LYXP_TOKEN_DDOT:
+        return "..";
+    case LYXP_TOKEN_AT:
+        return "@";
+    case LYXP_TOKEN_COMMA:
+        return ",";
+    case LYXP_TOKEN_NAMETEST:
+        return "NameTest";
+    case LYXP_TOKEN_NODETYPE:
+        return "NodeType";
+    case LYXP_TOKEN_FUNCNAME:
+        return "FunctionName";
+    case LYXP_TOKEN_OPERATOR_LOG:
+        return "Operator(Logic)";
+    case LYXP_TOKEN_OPERATOR_COMP:
+        return "Operator(Comparison)";
+    case LYXP_TOKEN_OPERATOR_MATH:
+        return "Operator(Math)";
+    case LYXP_TOKEN_OPERATOR_UNI:
+        return "Operator(Union)";
+    case LYXP_TOKEN_OPERATOR_PATH:
+        return "Operator(Path)";
+    case LYXP_TOKEN_LITERAL:
+        return "Literal";
+    case LYXP_TOKEN_NUMBER:
+        return "Number";
+    default:
+        LOGINT(NULL);
+        return "";
+    }
+}
+
+/**
+ * @brief Print the whole expression \p exp to debug output.
+ *
+ * @param[in] exp Expression to use.
+ */
+static void
+print_expr_struct_debug(struct lyxp_expr *exp)
+{
+    uint16_t i, j;
+    char tmp[128];
+
+    if (!exp || (ly_log_level < LY_LLDBG)) {
+        return;
+    }
+
+    LOGDBG(LY_LDGXPATH, "expression \"%s\":", exp->expr);
+    for (i = 0; i < exp->used; ++i) {
+        sprintf(tmp, "\ttoken %s, in expression \"%.*s\"", print_token(exp->tokens[i]), exp->tok_len[i],
+               &exp->expr[exp->tok_pos[i]]);
+        if (exp->repeat[i]) {
+            sprintf(tmp + strlen(tmp), " (repeat %d", exp->repeat[i][0]);
+            for (j = 1; exp->repeat[i][j]; ++j) {
+                sprintf(tmp + strlen(tmp), ", %d", exp->repeat[i][j]);
+            }
+            strcat(tmp, ")");
+        }
+        LOGDBG(LY_LDGXPATH, tmp);
+    }
+}
+
+#ifndef NDEBUG
+
+/**
+ * @brief Print XPath set content to debug output.
+ *
+ * @param[in] set Set to print.
+ */
+static void
+print_set_debug(struct lyxp_set *set)
+{
+    uint32_t i;
+    char *str;
+    int dynamic;
+    struct lyxp_set_node *item;
+    struct lyxp_set_scnode *sitem;
+
+    if (ly_log_level < LY_LLDBG) {
+        return;
+    }
+
+    switch (set->type) {
+    case LYXP_SET_NODE_SET:
+        LOGDBG(LY_LDGXPATH, "set NODE SET:");
+        for (i = 0; i < set->used; ++i) {
+            item = &set->val.nodes[i];
+
+            switch (item->type) {
+            case LYXP_NODE_ROOT:
+                LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ROOT", i + 1, item->pos);
+                break;
+            case LYXP_NODE_ROOT_CONFIG:
+                LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ROOT CONFIG", i + 1, item->pos);
+                break;
+            case LYXP_NODE_ELEM:
+                if ((item->node->schema->nodetype == LYS_LIST)
+                        && (((struct lyd_node_inner *)item->node)->child->schema->nodetype == LYS_LEAF)) {
+                    LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ELEM %s (1st child val: %s)", i + 1, item->pos,
+                           item->node->schema->name,
+                           (str = (char *)lyd_value2str((struct lyd_node_term *)lyd_node_children(item->node), &dynamic)));
+                    if (dynamic) {
+                        free(str);
+                    }
+                } else if (((struct lyd_node_inner *)item->node)->schema->nodetype == LYS_LEAFLIST) {
+                    LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ELEM %s (val: %s)", i + 1, item->pos,
+                           item->node->schema->name,
+                           (str = (char *)lyd_value2str((struct lyd_node_term *)item->node, &dynamic)));
+                    if (dynamic) {
+                        free(str);
+                    }
+                } else {
+                    LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ELEM %s", i + 1, item->pos, item->node->schema->name);
+                }
+                break;
+            case LYXP_NODE_TEXT:
+                if (item->node->schema->nodetype & LYS_ANYDATA) {
+                    LOGDBG(LY_LDGXPATH, "\t%d (pos %u): TEXT <%s>", i + 1, item->pos,
+                           item->node->schema->nodetype == LYS_ANYXML ? "anyxml" : "anydata");
+                } else {
+                    LOGDBG(LY_LDGXPATH, "\t%d (pos %u): TEXT %s", i + 1, item->pos,
+                           (str = (char *)lyd_value2str((struct lyd_node_term *)item->node, &dynamic)));
+                    if (dynamic) {
+                        free(str);
+                    }
+                }
+                break;
+            case LYXP_NODE_ATTR:
+                LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ATTR %s = %s", i + 1, item->pos, set->val.attrs[i].attr->name,
+                       set->val.attrs[i].attr->value);
+                break;
+            }
+        }
+        break;
+
+    case LYXP_SET_SCNODE_SET:
+        LOGDBG(LY_LDGXPATH, "set SCNODE SET:");
+        for (i = 0; i < set->used; ++i) {
+            sitem = &set->val.scnodes[i];
+
+            switch (sitem->type) {
+            case LYXP_NODE_ROOT:
+                LOGDBG(LY_LDGXPATH, "\t%d (%u): ROOT", i + 1, sitem->in_ctx);
+                break;
+            case LYXP_NODE_ROOT_CONFIG:
+                LOGDBG(LY_LDGXPATH, "\t%d (%u): ROOT CONFIG", i + 1, sitem->in_ctx);
+                break;
+            case LYXP_NODE_ELEM:
+                LOGDBG(LY_LDGXPATH, "\t%d (%u): ELEM %s", i + 1, sitem->in_ctx, sitem->scnode->name);
+                break;
+            default:
+                LOGINT(NULL);
+                break;
+            }
+        }
+        break;
+
+    case LYXP_SET_EMPTY:
+        LOGDBG(LY_LDGXPATH, "set EMPTY");
+        break;
+
+    case LYXP_SET_BOOLEAN:
+        LOGDBG(LY_LDGXPATH, "set BOOLEAN");
+        LOGDBG(LY_LDGXPATH, "\t%s", (set->val.bool ? "true" : "false"));
+        break;
+
+    case LYXP_SET_STRING:
+        LOGDBG(LY_LDGXPATH, "set STRING");
+        LOGDBG(LY_LDGXPATH, "\t%s", set->val.str);
+        break;
+
+    case LYXP_SET_NUMBER:
+        LOGDBG(LY_LDGXPATH, "set NUMBER");
+
+        if (isnan(set->val.num)) {
+            str = strdup("NaN");
+        } else if ((set->val.num == 0) || (set->val.num == -0.0f)) {
+            str = strdup("0");
+        } else if (isinf(set->val.num) && !signbit(set->val.num)) {
+            str = strdup("Infinity");
+        } else if (isinf(set->val.num) && signbit(set->val.num)) {
+            str = strdup("-Infinity");
+        } else if ((long long)set->val.num == set->val.num) {
+            if (asprintf(&str, "%lld", (long long)set->val.num) == -1) {
+                str = NULL;
+            }
+        } else {
+            if (asprintf(&str, "%03.1Lf", set->val.num) == -1) {
+                str = NULL;
+            }
+        }
+        LY_CHECK_ERR_RET(!str, LOGMEM(NULL), );
+
+        LOGDBG(LY_LDGXPATH, "\t%s", str);
+        free(str);
+    }
+}
+
+#endif
+
+/**
+ * @brief Realloc the string \p str.
+ *
+ * @param[in] ctx libyang context for logging.
+ * @param[in] needed How much free space is required.
+ * @param[in,out] str Pointer to the string to use.
+ * @param[in,out] used Used bytes in \p str.
+ * @param[in,out] size Allocated bytes in \p str.
+ * @return LY_ERR
+ */
+static LY_ERR
+cast_string_realloc(struct ly_ctx *ctx, uint16_t needed, char **str, uint16_t *used, uint16_t *size)
+{
+    if (*size - *used < needed) {
+        do {
+            if ((UINT16_MAX - *size) < LYXP_STRING_CAST_SIZE_STEP) {
+                LOGERR(ctx, LY_EINVAL, "XPath string length limit (%u) reached.", UINT16_MAX);
+                return LY_EINVAL;
+            }
+            *size += LYXP_STRING_CAST_SIZE_STEP;
+        } while (*size - *used < needed);
+        *str = ly_realloc(*str, *size * sizeof(char));
+        LY_CHECK_ERR_RET(!(*str), LOGMEM(ctx), LY_EMEM);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Cast nodes recursively to one string @p str.
+ *
+ * @param[in] node Node to cast.
+ * @param[in] fake_cont Whether to put the data into a "fake" container.
+ * @param[in] root_type Type of the XPath root.
+ * @param[in] indent Current indent.
+ * @param[in,out] str Resulting string.
+ * @param[in,out] used Used bytes in @p str.
+ * @param[in,out] size Allocated bytes in @p str.
+ * @return LY_ERR
+ */
+static LY_ERR
+cast_string_recursive(const struct lyd_node *node, int fake_cont, enum lyxp_node_type root_type, uint16_t indent, char **str,
+                      uint16_t *used, uint16_t *size)
+{
+    char *buf, *line, *ptr;
+    const char *value_str;
+    int dynamic;
+    const struct lyd_node *child;
+    struct lyd_node_any *any;
+    LY_ERR rc;
+
+    if ((root_type == LYXP_NODE_ROOT_CONFIG) && (node->schema->flags & LYS_CONFIG_R)) {
+        return LY_SUCCESS;
+    }
+
+    if (fake_cont) {
+        rc = cast_string_realloc(LYD_NODE_CTX(node), 1, str, used, size);
+        LY_CHECK_RET(rc);
+        strcpy(*str + (*used - 1), "\n");
+        ++(*used);
+
+        ++indent;
+    }
+
+    switch (node->schema->nodetype) {
+    case LYS_CONTAINER:
+    case LYS_LIST:
+    case LYS_RPC:
+    case LYS_NOTIF:
+        rc = cast_string_realloc(LYD_NODE_CTX(node), 1, str, used, size);
+        LY_CHECK_RET(rc);
+        strcpy(*str + (*used - 1), "\n");
+        ++(*used);
+
+        for (child = lyd_node_children(node); child; child = child->next) {
+            rc = cast_string_recursive(child, 0, root_type, indent + 1, str, used, size);
+            LY_CHECK_RET(rc);
+        }
+
+        break;
+
+    case LYS_LEAF:
+    case LYS_LEAFLIST:
+        value_str = lyd_value2str(((struct lyd_node_term *)node), &dynamic);
+
+        /* print indent */
+        rc = cast_string_realloc(LYD_NODE_CTX(node), indent * 2 + strlen(value_str) + 1, str, used, size);
+        if (rc != LY_SUCCESS) {
+            if (dynamic) {
+                free((char *)value_str);
+            }
+            return rc;
+        }
+        memset(*str + (*used - 1), ' ', indent * 2);
+        *used += indent * 2;
+
+        /* print value */
+        if (*used == 1) {
+            sprintf(*str + (*used - 1), "%s", value_str);
+            *used += strlen(value_str);
+        } else {
+            sprintf(*str + (*used - 1), "%s\n", value_str);
+            *used += strlen(value_str) + 1;
+        }
+        if (dynamic) {
+            free((char *)value_str);
+        }
+
+        break;
+
+    case LYS_ANYXML:
+    case LYS_ANYDATA:
+        any = (struct lyd_node_any *)node;
+        if (!(void *)any->value.tree) {
+            /* no content */
+            buf = strdup("");
+            LY_CHECK_ERR_RET(!buf, LOGMEM(LYD_NODE_CTX(node)), LY_EMEM);
+        } else {
+            switch (any->value_type) {
+            case LYD_ANYDATA_STRING:
+            case LYD_ANYDATA_XML:
+            case LYD_ANYDATA_JSON:
+                buf = strdup(any->value.json);
+                LY_CHECK_ERR_RET(!buf, LOGMEM(LYD_NODE_CTX(node)), LY_EMEM);
+                break;
+            case LYD_ANYDATA_DATATREE:
+                rc = lyd_print_mem(&buf, any->value.tree, LYD_XML, LYDP_WITHSIBLINGS);
+                LY_CHECK_RET(rc);
+                break;
+            /* TODO case LYD_ANYDATA_LYB:
+                LOGERR(LYD_NODE_CTX(node), LY_EINVAL, "Cannot convert LYB anydata into string.");
+                return -1;*/
+            }
+        }
+
+        line = strtok_r(buf, "\n", &ptr);
+        do {
+            rc = cast_string_realloc(LYD_NODE_CTX(node), indent * 2 + strlen(line) + 1, str, used, size);
+            if (rc != LY_SUCCESS) {
+                free(buf);
+                return rc;
+            }
+            memset(*str + (*used - 1), ' ', indent * 2);
+            *used += indent * 2;
+
+            strcpy(*str + (*used - 1), line);
+            *used += strlen(line);
+
+            strcpy(*str + (*used - 1), "\n");
+            *used += 1;
+        } while ((line = strtok_r(NULL, "\n", &ptr)));
+
+        free(buf);
+        break;
+
+    default:
+        LOGINT_RET(LYD_NODE_CTX(node));
+    }
+
+    if (fake_cont) {
+        rc = cast_string_realloc(LYD_NODE_CTX(node), 1, str, used, size);
+        LY_CHECK_RET(rc);
+        strcpy(*str + (*used - 1), "\n");
+        ++(*used);
+
+        --indent;
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Cast an element into a string.
+ *
+ * @param[in] node Node to cast.
+ * @param[in] fake_cont Whether to put the data into a "fake" container.
+ * @param[in] root_type Type of the XPath root.
+ * @param[out] str Element cast to dynamically-allocated string.
+ * @return LY_ERR
+ */
+static LY_ERR
+cast_string_elem(struct lyd_node *node, int fake_cont, enum lyxp_node_type root_type, char **str)
+{
+    uint16_t used, size;
+    LY_ERR rc;
+
+    *str = malloc(LYXP_STRING_CAST_SIZE_START * sizeof(char));
+    LY_CHECK_ERR_RET(!*str, LOGMEM(LYD_NODE_CTX(node)), LY_EMEM);
+    (*str)[0] = '\0';
+    used = 1;
+    size = LYXP_STRING_CAST_SIZE_START;
+
+    rc = cast_string_recursive(node, fake_cont, root_type, 0, str, &used, &size);
+    if (rc != LY_SUCCESS) {
+        free(*str);
+        return rc;
+    }
+
+    if (size > used) {
+        *str = ly_realloc(*str, used * sizeof(char));
+        LY_CHECK_ERR_RET(!*str, LOGMEM(LYD_NODE_CTX(node)), LY_EMEM);
+    }
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Cast a LYXP_SET_NODE_SET set into a string.
+ *        Context position aware.
+ *
+ * @param[in] set Set to cast.
+ * @param[in] options XPath options.
+ * @param[out] str Cast dynamically-allocated string.
+ * @return LY_ERR
+ */
+static LY_ERR
+cast_node_set_to_string(struct lyxp_set *set, int options, char **str)
+{
+    enum lyxp_node_type root_type;
+    int dynamic;
+
+    if ((set->val.nodes[0].type != LYXP_NODE_ATTR) && (set->val.nodes[0].node->flags & LYD_DUMMY)) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->val.nodes[0].node, LY_VCODE_XP_DUMMY, set->val.nodes[0].node->schema->name);
+        return LY_EVALID;
+    }
+
+    moveto_get_root(set->ctx_node, options, &root_type);
+
+    switch (set->val.nodes[0].type) {
+    case LYXP_NODE_ROOT:
+    case LYXP_NODE_ROOT_CONFIG:
+        return cast_string_elem(set->val.nodes[0].node, 1, root_type, str);
+    case LYXP_NODE_ELEM:
+    case LYXP_NODE_TEXT:
+        return cast_string_elem(set->val.nodes[0].node, 0, root_type, str);
+    case LYXP_NODE_ATTR:
+        *str = (char *)lyd_attr2str(set->val.attrs[0].attr, &dynamic);
+        if (!dynamic) {
+            *str = strdup(*str);
+            if (!*str) {
+                LOGMEM_RET(set->ctx);
+            }
+        }
+        return LY_SUCCESS;
+    }
+
+    LOGINT_RET(set->ctx);
+}
+
+/**
+ * @brief Cast a string into an XPath number.
+ *
+ * @param[in] str String to use.
+ * @return Cast number.
+ */
+static long double
+cast_string_to_number(const char *str)
+{
+    long double num;
+    char *ptr;
+
+    errno = 0;
+    num = strtold(str, &ptr);
+    if (errno || *ptr) {
+        num = NAN;
+    }
+    return num;
+}
+
+/**
+ * @brief Callback for checking value equality.
+ *
+ * @param[in] val1_p First value.
+ * @param[in] val2_p Second value.
+ * @param[in] mod Whether hash table is being modified.
+ * @param[in] cb_data Callback data.
+ * @return 0 if not equal, non-zero if equal.
+ */
+static int
+set_values_equal_cb(void *val1_p, void *val2_p, int UNUSED(mod), void *UNUSED(cb_data))
+{
+    struct lyxp_set_hash_node *val1, *val2;
+
+    val1 = (struct lyxp_set_hash_node *)val1_p;
+    val2 = (struct lyxp_set_hash_node *)val2_p;
+
+    if ((val1->node == val2->node) && (val1->type == val2->type)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+/**
+ * @brief Insert node and its hash into set.
+ *
+ * @param[in] set et to insert to.
+ * @param[in] node Node with hash.
+ * @param[in] type Node type.
+ */
+static void
+set_insert_node_hash(struct lyxp_set *set, struct lyd_node *node, enum lyxp_node_type type)
+{
+    int r;
+    uint32_t i, hash;
+    struct lyxp_set_hash_node hnode;
+
+    if (!set->ht && (set->used >= LYD_HT_MIN_ITEMS)) {
+        /* create hash table and add all the nodes */
+        set->ht = lyht_new(1, sizeof(struct lyxp_set_hash_node), set_values_equal_cb, NULL, 1);
+        for (i = 0; i < set->used; ++i) {
+            hnode.node = set->val.nodes[i].node;
+            hnode.type = set->val.nodes[i].type;
+
+            hash = dict_hash_multi(0, (const char *)&hnode.node, sizeof hnode.node);
+            hash = dict_hash_multi(hash, (const char *)&hnode.type, sizeof hnode.type);
+            hash = dict_hash_multi(hash, NULL, 0);
+
+            r = lyht_insert(set->ht, &hnode, hash, NULL);
+            assert(!r);
+            (void)r;
+        }
+    } else if (set->ht) {
+        assert(node);
+
+        /* add the new node into hash table */
+        hnode.node = node;
+        hnode.type = type;
+
+        hash = dict_hash_multi(0, (const char *)&hnode.node, sizeof hnode.node);
+        hash = dict_hash_multi(hash, (const char *)&hnode.type, sizeof hnode.type);
+        hash = dict_hash_multi(hash, NULL, 0);
+
+        r = lyht_insert(set->ht, &hnode, hash, NULL);
+        assert(!r);
+        (void)r;
+    }
+}
+
+/**
+ * @brief Remove node and its hash from set.
+ *
+ * @param[in] set Set to remove from.
+ * @param[in] node Node to remove.
+ * @param[in] type Node type.
+ */
+static void
+set_remove_node_hash(struct lyxp_set *set, struct lyd_node *node, enum lyxp_node_type type)
+{
+    int r;
+    struct lyxp_set_hash_node hnode;
+    uint32_t hash;
+
+    if (set->ht) {
+        hnode.node = node;
+        hnode.type = type;
+
+        hash = dict_hash_multi(0, (const char *)&hnode.node, sizeof hnode.node);
+        hash = dict_hash_multi(hash, (const char *)&hnode.type, sizeof hnode.type);
+        hash = dict_hash_multi(hash, NULL, 0);
+
+        r = lyht_remove(set->ht, &hnode, hash);
+        assert(!r);
+        (void)r;
+
+        if (!set->ht->used) {
+            lyht_free(set->ht);
+            set->ht = NULL;
+        }
+    }
+}
+
+/**
+ * @brief Check whether node is in set based on its hash.
+ *
+ * @param[in] set Set to search in.
+ * @param[in] node Node to search for.
+ * @param[in] type Node type.
+ * @param[in] skip_idx Index in @p set to skip.
+ * @return LY_ERR
+ */
+static LY_ERR
+set_dup_node_hash_check(const struct lyxp_set *set, struct lyd_node *node, enum lyxp_node_type type, int skip_idx)
+{
+    struct lyxp_set_hash_node hnode, *match_p;
+    uint32_t hash;
+
+    hnode.node = node;
+    hnode.type = type;
+
+    hash = dict_hash_multi(0, (const char *)&hnode.node, sizeof hnode.node);
+    hash = dict_hash_multi(hash, (const char *)&hnode.type, sizeof hnode.type);
+    hash = dict_hash_multi(hash, NULL, 0);
+
+    if (!lyht_find(set->ht, &hnode, hash, (void **)&match_p)) {
+        if ((skip_idx > -1) && (set->val.nodes[skip_idx].node == match_p->node) && (set->val.nodes[skip_idx].type == match_p->type)) {
+            /* we found it on the index that should be skipped, find another */
+            hnode = *match_p;
+            if (lyht_find_next(set->ht, &hnode, hash, (void **)&match_p)) {
+                /* none other found */
+                return LY_SUCCESS;
+            }
+        }
+
+        return LY_EEXIST;
+    }
+
+    /* not found */
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Free dynamic content of a set.
+ *
+ * @param[in] set Set to modify.
+ */
+static void
+set_free_content(struct lyxp_set *set)
+{
+    if (!set) {
+        return;
+    }
+
+    if (set->type == LYXP_SET_NODE_SET) {
+        free(set->val.nodes);
+        lyht_free(set->ht);
+        set->ht = NULL;
+    } else if (set->type == LYXP_SET_SCNODE_SET) {
+        free(set->val.scnodes);
+    } else if (set->type == LYXP_SET_STRING) {
+        free(set->val.str);
+    }
+    set->type = LYXP_SET_EMPTY;
+}
+
+void
+lyxp_set_free(struct lyxp_set *set)
+{
+    if (!set) {
+        return;
+    }
+
+    set_free_content(set);
+    free(set);
+}
+
+/**
+ * @brief Initialize set context.
+ *
+ * @param[in] new Set to initialize.
+ * @param[in] set Arbitrary initialized set.
+ */
+static void
+set_init(struct lyxp_set *new, struct lyxp_set *set)
+{
+    memset(new, 0, sizeof *new);
+    new->ctx = set->ctx;
+    new->ctx_node = set->ctx_node;
+    new->local_mod = set->local_mod;
+    new->trees = set->trees;
+    new->format = set->format;
+}
+
+/**
+ * @brief Create a deep copy of a set.
+ *
+ * @param[in] set Set to copy.
+ * @return Copy of @p set.
+ */
+static struct lyxp_set *
+set_copy(struct lyxp_set *set)
+{
+    struct lyxp_set *ret;
+    uint16_t i;
+
+    if (!set) {
+        return NULL;
+    }
+
+    ret = malloc(sizeof *ret);
+    LY_CHECK_ERR_RET(!ret, LOGMEM(set->ctx), NULL);
+    set_init(ret, set);
+
+    if (set->type == LYXP_SET_SCNODE_SET) {
+        ret->type = set->type;
+
+        for (i = 0; i < set->used; ++i) {
+            if (set->val.scnodes[i].in_ctx == 1) {
+                if (set_scnode_insert_node(ret, set->val.scnodes[i].scnode, set->val.scnodes[i].type)) {
+                    lyxp_set_free(ret);
+                    return NULL;
+                }
+            }
+        }
+    } else if (set->type == LYXP_SET_NODE_SET) {
+        ret->type = set->type;
+        ret->val.nodes = malloc(set->used * sizeof *ret->val.nodes);
+        LY_CHECK_ERR_RET(!ret->val.nodes, LOGMEM(set->ctx); free(ret), NULL);
+        memcpy(ret->val.nodes, set->val.nodes, set->used * sizeof *ret->val.nodes);
+
+        ret->used = ret->size = set->used;
+        ret->ctx_pos = set->ctx_pos;
+        ret->ctx_size = set->ctx_size;
+        ret->ht = lyht_dup(set->ht);
+    } else {
+       memcpy(ret, set, sizeof *ret);
+       if (set->type == LYXP_SET_STRING) {
+           ret->val.str = strdup(set->val.str);
+           LY_CHECK_ERR_RET(!ret->val.str, LOGMEM(set->ctx); free(ret), NULL);
+       }
+    }
+
+    return ret;
+}
+
+/**
+ * @brief Fill XPath set with a string. Any current data are disposed of.
+ *
+ * @param[in] set Set to fill.
+ * @param[in] string String to fill into \p set.
+ * @param[in] str_len Length of \p string. 0 is a valid value!
+ */
+static void
+set_fill_string(struct lyxp_set *set, const char *string, uint16_t str_len)
+{
+    set_free_content(set);
+
+    set->type = LYXP_SET_STRING;
+    if ((str_len == 0) && (string[0] != '\0')) {
+        string = "";
+    }
+    set->val.str = strndup(string, str_len);
+}
+
+/**
+ * @brief Fill XPath set with a number. Any current data are disposed of.
+ *
+ * @param[in] set Set to fill.
+ * @param[in] number Number to fill into \p set.
+ */
+static void
+set_fill_number(struct lyxp_set *set, long double number)
+{
+    set_free_content(set);
+
+    set->type = LYXP_SET_NUMBER;
+    set->val.num = number;
+}
+
+/**
+ * @brief Fill XPath set with a boolean. Any current data are disposed of.
+ *
+ * @param[in] set Set to fill.
+ * @param[in] boolean Boolean to fill into \p set.
+ */
+static void
+set_fill_boolean(struct lyxp_set *set, int boolean)
+{
+    set_free_content(set);
+
+    set->type = LYXP_SET_BOOLEAN;
+    set->val.bool = boolean;
+}
+
+/**
+ * @brief Fill XPath set with the value from another set (deep assign).
+ *        Any current data are disposed of.
+ *
+ * @param[in] trg Set to fill.
+ * @param[in] src Source set to copy into \p trg.
+ */
+static void
+set_fill_set(struct lyxp_set *trg, struct lyxp_set *src)
+{
+    if (!trg || !src) {
+        return;
+    }
+
+    if (trg->type == LYXP_SET_NODE_SET) {
+        free(trg->val.nodes);
+    } else if (trg->type == LYXP_SET_STRING) {
+        free(trg->val.str);
+    }
+    set_init(trg, src);
+
+    if (src->type == LYXP_SET_SCNODE_SET) {
+        trg->type = LYXP_SET_SCNODE_SET;
+        trg->used = src->used;
+        trg->size = src->used;
+
+        trg->val.scnodes = ly_realloc(trg->val.scnodes, trg->size * sizeof *trg->val.scnodes);
+        LY_CHECK_ERR_RET(!trg->val.scnodes, LOGMEM(src->ctx); memset(trg, 0, sizeof *trg), );
+        memcpy(trg->val.scnodes, src->val.scnodes, src->used * sizeof *src->val.scnodes);
+    } else if (src->type == LYXP_SET_BOOLEAN) {
+        set_fill_boolean(trg, src->val.bool);
+    } else if (src->type ==  LYXP_SET_NUMBER) {
+        set_fill_number(trg, src->val.num);
+    } else if (src->type == LYXP_SET_STRING) {
+        set_fill_string(trg, src->val.str, strlen(src->val.str));
+    } else {
+        if (trg->type == LYXP_SET_NODE_SET) {
+            free(trg->val.nodes);
+        } else if (trg->type == LYXP_SET_STRING) {
+            free(trg->val.str);
+        }
+
+        if (src->type == LYXP_SET_EMPTY) {
+            trg->type = LYXP_SET_EMPTY;
+        } else {
+            assert(src->type == LYXP_SET_NODE_SET);
+
+            trg->type = LYXP_SET_NODE_SET;
+            trg->used = src->used;
+            trg->size = src->used;
+            trg->ctx_pos = src->ctx_pos;
+            trg->ctx_size = src->ctx_size;
+
+            trg->val.nodes = malloc(trg->used * sizeof *trg->val.nodes);
+            LY_CHECK_ERR_RET(!trg->val.nodes, LOGMEM(src->ctx); memset(trg, 0, sizeof *trg), );
+            memcpy(trg->val.nodes, src->val.nodes, src->used * sizeof *src->val.nodes);
+            trg->ht = lyht_dup(src->ht);
+        }
+    }
+}
+
+/**
+ * @brief Clear context of all schema nodes.
+ *
+ * @param[in] set Set to clear.
+ */
+static void
+set_scnode_clear_ctx(struct lyxp_set *set)
+{
+    uint32_t i;
+
+    for (i = 0; i < set->used; ++i) {
+        if (set->val.scnodes[i].in_ctx == 1) {
+            set->val.scnodes[i].in_ctx = 0;
+        }
+    }
+}
+
+/**
+ * @brief Remove a node from a set. Removing last node changes
+ *        set into LYXP_SET_EMPTY. Context position aware.
+ *
+ * @param[in] set Set to use.
+ * @param[in] idx Index from @p set of the node to be removed.
+ */
+static void
+set_remove_node(struct lyxp_set *set, uint32_t idx)
+{
+    assert(set && (set->type == LYXP_SET_NODE_SET));
+    assert(idx < set->used);
+
+    set_remove_node_hash(set, set->val.nodes[idx].node, set->val.nodes[idx].type);
+
+    --set->used;
+    if (set->used) {
+        memmove(&set->val.nodes[idx], &set->val.nodes[idx + 1],
+                (set->used - idx) * sizeof *set->val.nodes);
+    } else {
+        set_free_content(set);
+        set->type = LYXP_SET_EMPTY;
+    }
+}
+
+/**
+ * @brief Check for duplicates in a node set.
+ *
+ * @param[in] set Set to check.
+ * @param[in] node Node to look for in @p set.
+ * @param[in] node_type Type of @p node.
+ * @param[in] skip_idx Index from @p set to skip.
+ * @return LY_ERR
+ */
+static LY_ERR
+set_dup_node_check(const struct lyxp_set *set, const struct lyd_node *node, enum lyxp_node_type node_type, int skip_idx)
+{
+    uint32_t i;
+
+    if (set->ht) {
+        return set_dup_node_hash_check(set, (struct lyd_node *)node, node_type, skip_idx);
+    }
+
+    for (i = 0; i < set->used; ++i) {
+        if ((skip_idx > -1) && (i == (unsigned)skip_idx)) {
+            continue;
+        }
+
+        if ((set->val.nodes[i].node == node) && (set->val.nodes[i].type == node_type)) {
+            return LY_EEXIST;
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Check for duplicates in a schema node set.
+ *
+ * @param[in] set Set to check.
+ * @param[in] node Node to look for in @p set.
+ * @param[in] node_type Type of @p node.
+ * @param[in] skip_idx Index from @p set to skip.
+ * @return Index of the found node, -1 if not found.
+ */
+static int
+set_scnode_dup_node_check(struct lyxp_set *set, const struct lysc_node *node, enum lyxp_node_type node_type, int skip_idx)
+{
+    uint32_t i;
+
+    for (i = 0; i < set->used; ++i) {
+        if ((skip_idx > -1) && (i == (unsigned)skip_idx)) {
+            continue;
+        }
+
+        if ((set->val.scnodes[i].scnode == node) && (set->val.scnodes[i].type == node_type)) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+/**
+ * @brief Merge 2 schema node sets.
+ *
+ * @param[in] set1 Set to merge into.
+ * @param[in] set2 Set to merge. Its content is freed.
+ */
+static void
+set_scnode_merge(struct lyxp_set *set1, struct lyxp_set *set2)
+{
+    uint32_t orig_used, i, j;
+
+    assert(((set1->type == LYXP_SET_SCNODE_SET) || (set1->type == LYXP_SET_EMPTY))
+        && ((set2->type == LYXP_SET_SCNODE_SET) || (set2->type == LYXP_SET_EMPTY)));
+
+    if (set2->type == LYXP_SET_EMPTY) {
+        return;
+    }
+
+    if (set1->type == LYXP_SET_EMPTY) {
+        memcpy(set1, set2, sizeof *set1);
+        return;
+    }
+
+    if (set1->used + set2->used > set1->size) {
+        set1->size = set1->used + set2->used;
+        set1->val.scnodes = ly_realloc(set1->val.scnodes, set1->size * sizeof *set1->val.scnodes);
+        LY_CHECK_ERR_RET(!set1->val.scnodes, LOGMEM(set1->ctx), );
+    }
+
+    orig_used = set1->used;
+
+    for (i = 0; i < set2->used; ++i) {
+        for (j = 0; j < orig_used; ++j) {
+            /* detect duplicities */
+            if (set1->val.scnodes[j].scnode == set2->val.scnodes[i].scnode) {
+                break;
+            }
+        }
+
+        if (j == orig_used) {
+            memcpy(&set1->val.scnodes[set1->used], &set2->val.scnodes[i], sizeof *set2->val.scnodes);
+            ++set1->used;
+        }
+    }
+
+    set_free_content(set2);
+    set2->type = LYXP_SET_EMPTY;
+}
+
+/**
+ * @brief Insert a node into a set. Context position aware.
+ *
+ * @param[in] set Set to use.
+ * @param[in] node Node to insert to @p set.
+ * @param[in] pos Sort position of @p node. If left 0, it is filled just before sorting.
+ * @param[in] node_type Node type of @p node.
+ * @param[in] idx Index in @p set to insert into.
+ */
+static void
+set_insert_node(struct lyxp_set *set, const struct lyd_node *node, uint32_t pos, enum lyxp_node_type node_type, uint32_t idx)
+{
+    assert(set && ((set->type == LYXP_SET_NODE_SET) || (set->type == LYXP_SET_EMPTY)));
+
+    if (set->type == LYXP_SET_EMPTY) {
+        /* first item */
+        if (idx) {
+            /* no real harm done, but it is a bug */
+            LOGINT(set->ctx);
+            idx = 0;
+        }
+        set->val.nodes = malloc(LYXP_SET_SIZE_START * sizeof *set->val.nodes);
+        LY_CHECK_ERR_RET(!set->val.nodes, LOGMEM(set->ctx), );
+        set->type = LYXP_SET_NODE_SET;
+        set->used = 0;
+        set->size = LYXP_SET_SIZE_START;
+        set->ctx_pos = 1;
+        set->ctx_size = 1;
+        set->ht = NULL;
+    } else {
+        /* not an empty set */
+        if (set->used == set->size) {
+
+            /* set is full */
+            set->val.nodes = ly_realloc(set->val.nodes, (set->size + LYXP_SET_SIZE_STEP) * sizeof *set->val.nodes);
+            LY_CHECK_ERR_RET(!set->val.nodes, LOGMEM(set->ctx), );
+            set->size += LYXP_SET_SIZE_STEP;
+        }
+
+        if (idx > set->used) {
+            LOGINT(set->ctx);
+            idx = set->used;
+        }
+
+        /* make space for the new node */
+        if (idx < set->used) {
+            memmove(&set->val.nodes[idx + 1], &set->val.nodes[idx], (set->used - idx) * sizeof *set->val.nodes);
+        }
+    }
+
+    /* finally assign the value */
+    set->val.nodes[idx].node = (struct lyd_node *)node;
+    set->val.nodes[idx].type = node_type;
+    set->val.nodes[idx].pos = pos;
+    ++set->used;
+
+    set_insert_node_hash(set, (struct lyd_node *)node, node_type);
+}
+
+/**
+ * @brief Insert schema node into set.
+ *
+ * @param[in] set Set to insert into.
+ * @param[in] node Node to insert.
+ * @param[in] node_type Node type of @p node.
+ * @return Index of the inserted node in set.
+ */
+static int
+set_scnode_insert_node(struct lyxp_set *set, const struct lysc_node *node, enum lyxp_node_type node_type)
+{
+    int ret;
+
+    assert(set->type == LYXP_SET_SCNODE_SET);
+
+    ret = set_scnode_dup_node_check(set, node, node_type, -1);
+    if (ret > -1) {
+        set->val.scnodes[ret].in_ctx = 1;
+    } else {
+        if (set->used == set->size) {
+            set->val.scnodes = ly_realloc(set->val.scnodes, (set->size + LYXP_SET_SIZE_STEP) * sizeof *set->val.scnodes);
+            LY_CHECK_ERR_RET(!set->val.scnodes, LOGMEM(set->ctx), -1);
+            set->size += LYXP_SET_SIZE_STEP;
+        }
+
+        ret = set->used;
+        set->val.scnodes[ret].scnode = (struct lysc_node *)node;
+        set->val.scnodes[ret].type = node_type;
+        set->val.scnodes[ret].in_ctx = 1;
+        ++set->used;
+    }
+
+    return ret;
+}
+
+/**
+ * @brief Replace a node in a set with another. Context position aware.
+ *
+ * @param[in] set Set to use.
+ * @param[in] node Node to insert to @p set.
+ * @param[in] pos Sort position of @p node. If left 0, it is filled just before sorting.
+ * @param[in] node_type Node type of @p node.
+ * @param[in] idx Index in @p set of the node to replace.
+ */
+static void
+set_replace_node(struct lyxp_set *set, const struct lyd_node *node, uint32_t pos, enum lyxp_node_type node_type, uint32_t idx)
+{
+    assert(set && (idx < set->used));
+
+    set_remove_node_hash(set, set->val.nodes[idx].node, set->val.nodes[idx].type);
+    set->val.nodes[idx].node = (struct lyd_node *)node;
+    set->val.nodes[idx].type = node_type;
+    set->val.nodes[idx].pos = pos;
+    set_insert_node_hash(set, set->val.nodes[idx].node, set->val.nodes[idx].type);
+}
+
+/**
+ * @brief Set all nodes with ctx 1 to a new unique context value.
+ *
+ * @param[in] set Set to modify.
+ * @return New context value.
+ */
+static uint32_t
+set_scnode_new_in_ctx(struct lyxp_set *set)
+{
+    uint32_t ret_ctx, i;
+
+    assert(set->type == LYXP_SET_SCNODE_SET);
+
+    ret_ctx = 3;
+retry:
+    for (i = 0; i < set->used; ++i) {
+        if (set->val.scnodes[i].in_ctx >= ret_ctx) {
+            ret_ctx = set->val.scnodes[i].in_ctx + 1;
+            goto retry;
+        }
+    }
+    for (i = 0; i < set->used; ++i) {
+        if (set->val.scnodes[i].in_ctx == 1) {
+            set->val.scnodes[i].in_ctx = ret_ctx;
+        }
+    }
+
+    return ret_ctx;
+}
+
+/**
+ * @brief Get unique @p node position in the data.
+ *
+ * @param[in] node Node to find.
+ * @param[in] node_type Node type of @p node.
+ * @param[in] root Root node.
+ * @param[in] root_type Type of the XPath @p root node.
+ * @param[in] prev Node that we think is before @p node in DFS from @p root. Can optionally
+ * be used to increase efficiency and start the DFS from this node.
+ * @param[in] prev_pos Node @p prev position. Optional, but must be set if @p prev is set.
+ * @return Node position.
+ */
+static uint32_t
+get_node_pos(const struct lyd_node *node, enum lyxp_node_type node_type, const struct lyd_node *root,
+             enum lyxp_node_type root_type, const struct lyd_node **prev, uint32_t *prev_pos)
+{
+    const struct lyd_node *next, *elem, *top_sibling;
+    uint32_t pos = 1;
+
+    assert(prev && prev_pos && !root->prev->next);
+
+    if ((node_type == LYXP_NODE_ROOT) || (node_type == LYXP_NODE_ROOT_CONFIG)) {
+        return 0;
+    }
+
+    if (*prev) {
+        /* start from the previous element instead from the root */
+        elem = next = *prev;
+        pos = *prev_pos;
+        for (top_sibling = elem; top_sibling->parent; top_sibling = (struct lyd_node *)top_sibling->parent);
+        goto dfs_search;
+    }
+
+    for (top_sibling = root; top_sibling; top_sibling = top_sibling->next) {
+        /* TREE DFS */
+        LYD_TREE_DFS_BEGIN(top_sibling, next, elem) {
+dfs_search:
+            if ((root_type == LYXP_NODE_ROOT_CONFIG) && (elem->schema->flags & LYS_CONFIG_R)) {
+                goto skip_children;
+            }
+
+            if (elem == node) {
+                break;
+            }
+            ++pos;
+
+            /* TREE DFS END */
+            /* select element for the next run - children first,
+             * child exception for lyd_node_leaf and lyd_node_leaflist, but not the root */
+            if (elem->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)) {
+                next = NULL;
+            } else {
+                next = lyd_node_children(elem);
+            }
+            if (!next) {
+skip_children:
+                /* no children */
+                if (elem == top_sibling) {
+                    /* we are done, root has no children */
+                    elem = NULL;
+                    break;
+                }
+                /* try siblings */
+                next = elem->next;
+            }
+            while (!next) {
+                /* no siblings, go back through parents */
+                if (elem->parent == top_sibling->parent) {
+                    /* we are done, no next element to process */
+                    elem = NULL;
+                    break;
+                }
+                /* parent is already processed, go to its sibling */
+                elem = (struct lyd_node *)elem->parent;
+                next = elem->next;
+            }
+        }
+
+        /* node found */
+        if (elem) {
+            break;
+        }
+    }
+
+    if (!elem) {
+        if (!(*prev)) {
+            /* we went from root and failed to find it, cannot be */
+            LOGINT(node->schema->module->ctx);
+            return 0;
+        } else {
+            *prev = NULL;
+            *prev_pos = 0;
+
+            elem = next = top_sibling = root;
+            pos = 1;
+            goto dfs_search;
+        }
+    }
+
+    /* remember the last found node for next time */
+    *prev = node;
+    *prev_pos = pos;
+
+    return pos;
+}
+
+/**
+ * @brief Assign (fill) missing node positions.
+ *
+ * @param[in] set Set to fill positions in.
+ * @param[in] root Context root node.
+ * @param[in] root_type Context root type.
+ * @return LY_ERR
+ */
+static LY_ERR
+set_assign_pos(struct lyxp_set *set, const struct lyd_node *root, enum lyxp_node_type root_type)
+{
+    const struct lyd_node *prev = NULL, *tmp_node;
+    uint32_t i, tmp_pos = 0;
+
+    for (i = 0; i < set->used; ++i) {
+        if (!set->val.nodes[i].pos) {
+            tmp_node = NULL;
+            switch (set->val.nodes[i].type) {
+            case LYXP_NODE_ATTR:
+                tmp_node = set->val.attrs[i].attr->parent;
+                if (!tmp_node) {
+                    LOGINT_RET(root->schema->module->ctx);
+                }
+                /* fallthrough */
+            case LYXP_NODE_ELEM:
+            case LYXP_NODE_TEXT:
+                if (!tmp_node) {
+                    tmp_node = set->val.nodes[i].node;
+                }
+                set->val.nodes[i].pos = get_node_pos(tmp_node, set->val.nodes[i].type, root, root_type, &prev, &tmp_pos);
+                break;
+            default:
+                /* all roots have position 0 */
+                break;
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Get unique @p attr position in the parent attributes.
+ *
+ * @param[in] attr Attr to use.
+ * @return Attribute position.
+ */
+static uint16_t
+get_attr_pos(struct lyd_attr *attr)
+{
+    uint16_t pos = 0;
+    struct lyd_attr *attr2;
+
+    for (attr2 = attr->parent->attr; attr2 && (attr2 != attr); attr2 = attr2->next) {
+        ++pos;
+    }
+
+    assert(attr2);
+    return pos;
+}
+
+/**
+ * @brief Compare 2 nodes in respect to XPath document order.
+ *
+ * @param[in] item1 1st node.
+ * @param[in] item2 2nd node.
+ * @return If 1st > 2nd returns 1, 1st == 2nd returns 0, and 1st < 2nd returns -1.
+ */
+static int
+set_sort_compare(struct lyxp_set_node *item1, struct lyxp_set_node *item2)
+{
+    uint32_t attr_pos1 = 0, attr_pos2 = 0;
+
+    if (item1->pos < item2->pos) {
+        return -1;
+    }
+
+    if (item1->pos > item2->pos) {
+        return 1;
+    }
+
+    /* node positions are equal, the fun case */
+
+    /* 1st ELEM - == - 2nd TEXT, 1st TEXT - == - 2nd ELEM */
+    /* special case since text nodes are actually saved as their parents */
+    if ((item1->node == item2->node) && (item1->type != item2->type)) {
+        if (item1->type == LYXP_NODE_ELEM) {
+            assert(item2->type == LYXP_NODE_TEXT);
+            return -1;
+        } else {
+            assert((item1->type == LYXP_NODE_TEXT) && (item2->type == LYXP_NODE_ELEM));
+            return 1;
+        }
+    }
+
+    /* we need attr positions now */
+    if (item1->type == LYXP_NODE_ATTR) {
+        attr_pos1 = get_attr_pos((struct lyd_attr *)item1->node);
+    }
+    if (item2->type == LYXP_NODE_ATTR) {
+        attr_pos2 = get_attr_pos((struct lyd_attr *)item2->node);
+    }
+
+    /* 1st ROOT - 2nd ROOT, 1st ELEM - 2nd ELEM, 1st TEXT - 2nd TEXT, 1st ATTR - =pos= - 2nd ATTR */
+    /* check for duplicates */
+    if (item1->node == item2->node) {
+        assert((item1->type == item2->type) && ((item1->type != LYXP_NODE_ATTR) || (attr_pos1 == attr_pos2)));
+        return 0;
+    }
+
+    /* 1st ELEM - 2nd TEXT, 1st ELEM - any pos - 2nd ATTR */
+    /* elem is always first, 2nd node is after it */
+    if (item1->type == LYXP_NODE_ELEM) {
+        assert(item2->type != LYXP_NODE_ELEM);
+        return -1;
+    }
+
+    /* 1st TEXT - 2nd ELEM, 1st TEXT - any pos - 2nd ATTR, 1st ATTR - any pos - 2nd ELEM, 1st ATTR - >pos> - 2nd ATTR */
+    /* 2nd is before 1st */
+    if (((item1->type == LYXP_NODE_TEXT)
+            && ((item2->type == LYXP_NODE_ELEM) || (item2->type == LYXP_NODE_ATTR)))
+            || ((item1->type == LYXP_NODE_ATTR) && (item2->type == LYXP_NODE_ELEM))
+            || (((item1->type == LYXP_NODE_ATTR) && (item2->type == LYXP_NODE_ATTR))
+            && (attr_pos1 > attr_pos2))) {
+        return 1;
+    }
+
+    /* 1st ATTR - any pos - 2nd TEXT, 1st ATTR <pos< - 2nd ATTR */
+    /* 2nd is after 1st */
+    return -1;
+}
+
+/**
+ * @brief Set cast for comparisons.
+ *
+ * @param[in] trg Target set to cast source into.
+ * @param[in] src Source set.
+ * @param[in] type Target set type.
+ * @param[in] src_idx Source set node index.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+set_comp_cast(struct lyxp_set *trg, struct lyxp_set *src, enum lyxp_set_type type, uint32_t src_idx, int options)
+{
+    assert(src->type == LYXP_SET_NODE_SET);
+
+    set_init(trg, src);
+
+    /* insert node into target set */
+    set_insert_node(trg, src->val.nodes[src_idx].node, src->val.nodes[src_idx].pos, src->val.nodes[src_idx].type, 0);
+
+    /* cast target set appropriately */
+    return lyxp_set_cast(trg, type, options);
+}
+
+#ifndef NDEBUG
+
+/**
+ * @brief Bubble sort @p set into XPath document order.
+ *        Context position aware. Unused in the 'Release' build target.
+ *
+ * @param[in] set Set to sort.
+ * @param[in] options Xpath options.
+ * @return How many times the whole set was traversed - 1 (if set was sorted, returns 0).
+ */
+static int
+set_sort(struct lyxp_set *set, int options)
+{
+    uint32_t i, j;
+    int ret = 0, cmp, inverted, change;
+    const struct lyd_node *root;
+    enum lyxp_node_type root_type;
+    struct lyxp_set_node item;
+    struct lyxp_set_hash_node hnode;
+    uint64_t hash;
+
+    if ((set->type != LYXP_SET_NODE_SET) || (set->used == 1)) {
+        return 0;
+    }
+
+    /* get root */
+    root = moveto_get_root(set->ctx_node, options, &root_type);
+
+    /* fill positions */
+    if (set_assign_pos(set, root, root_type)) {
+        return -1;
+    }
+
+    LOGDBG(LY_LDGXPATH, "SORT BEGIN");
+    print_set_debug(set);
+
+    for (i = 0; i < set->used; ++i) {
+        inverted = 0;
+        change = 0;
+
+        for (j = 1; j < set->used - i; ++j) {
+            /* compare node positions */
+            if (inverted) {
+                cmp = set_sort_compare(&set->val.nodes[j], &set->val.nodes[j - 1]);
+            } else {
+                cmp = set_sort_compare(&set->val.nodes[j - 1], &set->val.nodes[j]);
+            }
+
+            /* swap if needed */
+            if ((inverted && (cmp < 0)) || (!inverted && (cmp > 0))) {
+                change = 1;
+
+                item = set->val.nodes[j - 1];
+                set->val.nodes[j - 1] = set->val.nodes[j];
+                set->val.nodes[j] = item;
+            } else {
+                /* whether node_pos1 should be smaller than node_pos2 or the other way around */
+                inverted = !inverted;
+            }
+        }
+
+        ++ret;
+
+        if (!change) {
+            break;
+        }
+    }
+
+    LOGDBG(LY_LDGXPATH, "SORT END %d", ret);
+    print_set_debug(set);
+
+    /* check node hashes */
+    if (set->used >= LYD_HT_MIN_ITEMS) {
+        assert(set->ht);
+        for (i = 0; i < set->used; ++i) {
+            hnode.node = set->val.nodes[i].node;
+            hnode.type = set->val.nodes[i].type;
+
+            hash = dict_hash_multi(0, (const char *)&hnode.node, sizeof hnode.node);
+            hash = dict_hash_multi(hash, (const char *)&hnode.type, sizeof hnode.type);
+            hash = dict_hash_multi(hash, NULL, 0);
+
+            assert(!lyht_find(set->ht, &hnode, hash, NULL));
+        }
+    }
+
+    return ret - 1;
+}
+
+/**
+ * @brief Remove duplicate entries in a sorted node set.
+ *
+ * @param[in] set Sorted set to check.
+ * @return LY_ERR (LY_EEXIST if some duplicates are found)
+ */
+static LY_ERR
+set_sorted_dup_node_clean(struct lyxp_set *set)
+{
+    uint32_t i = 0;
+    LY_ERR ret = LY_SUCCESS;
+
+    if (set->used > 1) {
+        while (i < set->used - 1) {
+            if ((set->val.nodes[i].node == set->val.nodes[i + 1].node)
+                    && (set->val.nodes[i].type == set->val.nodes[i + 1].type)) {
+                set_remove_node(set, i + 1);
+            ret = LY_EEXIST;
+            } else {
+                ++i;
+            }
+        }
+    }
+
+    return ret;
+}
+
+#endif
+
+/**
+ * @brief Merge 2 sorted sets into one.
+ *
+ * @param[in,out] trg Set to merge into. Duplicates are removed.
+ * @param[in] src Set to be merged into @p trg. It is cast to #LYXP_SET_EMPTY on success.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+set_sorted_merge(struct lyxp_set *trg, struct lyxp_set *src, int options)
+{
+    uint32_t i, j, k, count, dup_count;
+    int cmp;
+    const struct lyd_node *root;
+    enum lyxp_node_type root_type;
+
+    if (((trg->type != LYXP_SET_NODE_SET) && (trg->type != LYXP_SET_EMPTY))
+            || ((src->type != LYXP_SET_NODE_SET) && (src->type != LYXP_SET_EMPTY))) {
+        return LY_EINVAL;
+    }
+
+    if (src->type == LYXP_SET_EMPTY) {
+        return LY_SUCCESS;
+    } else if (trg->type == LYXP_SET_EMPTY) {
+        set_fill_set(trg, src);
+        lyxp_set_cast(src, LYXP_SET_EMPTY, options);
+        return LY_SUCCESS;
+    }
+
+    /* get root */
+    root = moveto_get_root(trg->ctx_node, options, &root_type);
+
+    /* fill positions */
+    if (set_assign_pos(trg, root, root_type) || set_assign_pos(src, root, root_type)) {
+        return LY_EINT;
+    }
+
+#ifndef NDEBUG
+    LOGDBG(LY_LDGXPATH, "MERGE target");
+    print_set_debug(trg);
+    LOGDBG(LY_LDGXPATH, "MERGE source");
+    print_set_debug(src);
+#endif
+
+    /* make memory for the merge (duplicates are not detected yet, so space
+     * will likely be wasted on them, too bad) */
+    if (trg->size - trg->used < src->used) {
+        trg->size = trg->used + src->used;
+
+        trg->val.nodes = ly_realloc(trg->val.nodes, trg->size * sizeof *trg->val.nodes);
+        LY_CHECK_ERR_RET(!trg->val.nodes, LOGMEM(src->ctx), LY_EMEM);
+    }
+
+    i = 0;
+    j = 0;
+    count = 0;
+    dup_count = 0;
+    do {
+        cmp = set_sort_compare(&src->val.nodes[i], &trg->val.nodes[j]);
+        if (!cmp) {
+            if (!count) {
+                /* duplicate, just skip it */
+                ++i;
+                ++j;
+            } else {
+                /* we are copying something already, so let's copy the duplicate too,
+                 * we are hoping that afterwards there are some more nodes to
+                 * copy and this way we can copy them all together */
+                ++count;
+                ++dup_count;
+                ++i;
+                ++j;
+            }
+        } else if (cmp < 0) {
+            /* inserting src node into trg, just remember it for now */
+            ++count;
+            ++i;
+
+            /* insert the hash now */
+            set_insert_node_hash(trg, src->val.nodes[i - 1].node, src->val.nodes[i - 1].type);
+        } else if (count) {
+copy_nodes:
+            /* time to actually copy the nodes, we have found the largest block of nodes */
+            memmove(&trg->val.nodes[j + (count - dup_count)],
+                    &trg->val.nodes[j],
+                    (trg->used - j) * sizeof *trg->val.nodes);
+            memcpy(&trg->val.nodes[j - dup_count], &src->val.nodes[i - count], count * sizeof *src->val.nodes);
+
+            trg->used += count - dup_count;
+            /* do not change i, except the copying above, we are basically doing exactly what is in the else branch below */
+            j += count - dup_count;
+
+            count = 0;
+            dup_count = 0;
+        } else {
+            ++j;
+        }
+    } while ((i < src->used) && (j < trg->used));
+
+    if ((i < src->used) || count) {
+        /* insert all the hashes first */
+        for (k = i; k < src->used; ++k) {
+            set_insert_node_hash(trg, src->val.nodes[k].node, src->val.nodes[k].type);
+        }
+
+        /* loop ended, but we need to copy something at trg end */
+        count += src->used - i;
+        i = src->used;
+        goto copy_nodes;
+    }
+
+    /* we are inserting hashes before the actual node insert, which causes
+     * situations when there were initially not enough items for a hash table,
+     * but even after some were inserted, hash table was not created (during
+     * insertion the number of items is not updated yet) */
+    if (!trg->ht && (trg->used >= LYD_HT_MIN_ITEMS)) {
+        set_insert_node_hash(trg, NULL, 0);
+    }
+
+#ifndef NDEBUG
+    LOGDBG(LY_LDGXPATH, "MERGE result");
+    print_set_debug(trg);
+#endif
+
+    lyxp_set_cast(src, LYXP_SET_EMPTY, options);
+    return LY_SUCCESS;
+}
+
+/*
+ * (re)parse functions
+ *
+ * Parse functions parse the expression into
+ * tokens (syntactic analysis).
+ *
+ * Reparse functions perform semantic analysis
+ * (do not save the result, just a check) of
+ * the expression and fill repeat indices.
+ */
+
+/**
+ * @brief Look at the next token and check its kind.
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Expression to use.
+ * @param[in] exp_idx Position in the expression \p exp.
+ * @param[in] want_tok Expected token.
+ * @param[in] strict Whether the token is strictly required (print error if
+ * not the next one) or we simply want to check whether it is the next or not.
+ * @return LY_ERR
+ */
+static LY_ERR
+exp_check_token(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t exp_idx, enum lyxp_token want_tok, int strict)
+{
+    if (exp->used == exp_idx) {
+        if (strict) {
+            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_EOF);
+        }
+        return LY_EINVAL;
+    }
+
+    if (want_tok && (exp->tokens[exp_idx] != want_tok)) {
+        if (strict) {
+            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK,
+                   print_token(exp->tokens[exp_idx]), &exp->expr[exp->tok_pos[exp_idx]]);
+        }
+        return LY_EINVAL;
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Stack operation push on the repeat array.
+ *
+ * @param[in] exp Expression to use.
+ * @param[in] exp_idx Position in the expresion \p exp.
+ * @param[in] repeat_op_idx Index from \p exp of the operator token. This value is pushed.
+ */
+static void
+exp_repeat_push(struct lyxp_expr *exp, uint16_t exp_idx, uint16_t repeat_op_idx)
+{
+    uint16_t i;
+
+    if (exp->repeat[exp_idx]) {
+        for (i = 0; exp->repeat[exp_idx][i]; ++i);
+        exp->repeat[exp_idx] = realloc(exp->repeat[exp_idx], (i + 2) * sizeof *exp->repeat[exp_idx]);
+        LY_CHECK_ERR_RET(!exp->repeat[exp_idx], LOGMEM(NULL), );
+        exp->repeat[exp_idx][i] = repeat_op_idx;
+        exp->repeat[exp_idx][i + 1] = 0;
+    } else {
+        exp->repeat[exp_idx] = calloc(2, sizeof *exp->repeat[exp_idx]);
+        LY_CHECK_ERR_RET(!exp->repeat[exp_idx], LOGMEM(NULL), );
+        exp->repeat[exp_idx][0] = repeat_op_idx;
+    }
+}
+
+/**
+ * @brief Reparse Predicate. Logs directly on error.
+ *
+ * [7] Predicate ::= '[' Expr ']'
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @return LY_ERR
+ */
+static LY_ERR
+reparse_predicate(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    LY_ERR rc;
+
+    rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_BRACK1, 1);
+    LY_CHECK_RET(rc);
+    ++(*exp_idx);
+
+    rc = reparse_or_expr(ctx, exp, exp_idx);
+    LY_CHECK_RET(rc);
+
+    rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_BRACK2, 1);
+    LY_CHECK_RET(rc);
+    ++(*exp_idx);
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Reparse RelativeLocationPath. Logs directly on error.
+ *
+ * [4] RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step
+ * [5] Step ::= '@'? NodeTest Predicate* | '.' | '..'
+ * [6] NodeTest ::= NameTest | NodeType '(' ')'
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression \p exp.
+ * @return LY_ERR (LY_EINCOMPLETE on forward reference)
+ */
+static LY_ERR
+reparse_relative_location_path(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    LY_ERR rc;
+
+    rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_NONE, 1);
+    LY_CHECK_RET(rc);
+
+    goto step;
+    do {
+        /* '/' or '//' */
+        ++(*exp_idx);
+
+        rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_NONE, 1);
+        LY_CHECK_RET(rc);
+step:
+        /* Step */
+        switch (exp->tokens[*exp_idx]) {
+        case LYXP_TOKEN_DOT:
+            ++(*exp_idx);
+            break;
+
+        case LYXP_TOKEN_DDOT:
+            ++(*exp_idx);
+            break;
+
+        case LYXP_TOKEN_AT:
+            ++(*exp_idx);
+
+            rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_NONE, 1);
+            LY_CHECK_RET(rc);
+            if ((exp->tokens[*exp_idx] != LYXP_TOKEN_NAMETEST) && (exp->tokens[*exp_idx] != LYXP_TOKEN_NODETYPE)) {
+                LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK,
+                       print_token(exp->tokens[*exp_idx]), &exp->expr[exp->tok_pos[*exp_idx]]);
+                return LY_EVALID;
+            }
+            /* fall through */
+        case LYXP_TOKEN_NAMETEST:
+            ++(*exp_idx);
+            goto reparse_predicate;
+            break;
+
+        case LYXP_TOKEN_NODETYPE:
+            ++(*exp_idx);
+
+            /* '(' */
+            rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_PAR1, 1);
+            LY_CHECK_RET(rc);
+            ++(*exp_idx);
+
+            /* ')' */
+            rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_PAR2, 1);
+            LY_CHECK_RET(rc);
+            ++(*exp_idx);
+
+reparse_predicate:
+            /* Predicate* */
+            while ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_BRACK1)) {
+                rc = reparse_predicate(ctx, exp, exp_idx);
+                LY_CHECK_RET(rc);
+            }
+            break;
+        default:
+            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK,
+                   print_token(exp->tokens[*exp_idx]), &exp->expr[exp->tok_pos[*exp_idx]]);
+            return LY_EVALID;
+        }
+    } while ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_PATH));
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Reparse AbsoluteLocationPath. Logs directly on error.
+ *
+ * [3] AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression \p exp.
+ * @return LY_ERR
+ */
+static LY_ERR
+reparse_absolute_location_path(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    LY_ERR rc;
+
+    rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_PATH, 1);
+    LY_CHECK_RET(rc);
+
+    /* '/' RelativeLocationPath? */
+    if (exp->tok_len[*exp_idx] == 1) {
+        /* '/' */
+        ++(*exp_idx);
+
+        if (exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_NONE, 0)) {
+            return LY_SUCCESS;
+        }
+        switch (exp->tokens[*exp_idx]) {
+        case LYXP_TOKEN_DOT:
+        case LYXP_TOKEN_DDOT:
+        case LYXP_TOKEN_AT:
+        case LYXP_TOKEN_NAMETEST:
+        case LYXP_TOKEN_NODETYPE:
+            rc = reparse_relative_location_path(ctx, exp, exp_idx);
+            LY_CHECK_RET(rc);
+            /* fall through */
+        default:
+            break;
+        }
+
+    /* '//' RelativeLocationPath */
+    } else {
+        /* '//' */
+        ++(*exp_idx);
+
+        rc = reparse_relative_location_path(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Reparse FunctionCall. Logs directly on error.
+ *
+ * [9] FunctionCall ::= FunctionName '(' ( Expr ( ',' Expr )* )? ')'
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @return LY_ERR
+ */
+static LY_ERR
+reparse_function_call(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    int min_arg_count = -1, max_arg_count, arg_count;
+    uint16_t func_exp_idx;
+    LY_ERR rc;
+
+    rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_FUNCNAME, 1);
+    LY_CHECK_RET(rc);
+    func_exp_idx = *exp_idx;
+    switch (exp->tok_len[*exp_idx]) {
+    case 3:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "not", 3)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "sum", 3)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        }
+        break;
+    case 4:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "lang", 4)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "last", 4)) {
+            min_arg_count = 0;
+            max_arg_count = 0;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "name", 4)) {
+            min_arg_count = 0;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "true", 4)) {
+            min_arg_count = 0;
+            max_arg_count = 0;
+        }
+        break;
+    case 5:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "count", 5)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "false", 5)) {
+            min_arg_count = 0;
+            max_arg_count = 0;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "floor", 5)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "round", 5)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "deref", 5)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        }
+        break;
+    case 6:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "concat", 6)) {
+            min_arg_count = 2;
+            max_arg_count = 3;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "number", 6)) {
+            min_arg_count = 0;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "string", 6)) {
+            min_arg_count = 0;
+            max_arg_count = 1;
+        }
+        break;
+    case 7:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "boolean", 7)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "ceiling", 7)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "current", 7)) {
+            min_arg_count = 0;
+            max_arg_count = 0;
+        }
+        break;
+    case 8:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "contains", 8)) {
+            min_arg_count = 2;
+            max_arg_count = 2;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "position", 8)) {
+            min_arg_count = 0;
+            max_arg_count = 0;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "re-match", 8)) {
+            min_arg_count = 2;
+            max_arg_count = 2;
+        }
+        break;
+    case 9:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "substring", 9)) {
+            min_arg_count = 2;
+            max_arg_count = 3;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "translate", 9)) {
+            min_arg_count = 3;
+            max_arg_count = 3;
+        }
+        break;
+    case 10:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "local-name", 10)) {
+            min_arg_count = 0;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "enum-value", 10)) {
+            min_arg_count = 1;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "bit-is-set", 10)) {
+            min_arg_count = 2;
+            max_arg_count = 2;
+        }
+        break;
+    case 11:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "starts-with", 11)) {
+            min_arg_count = 2;
+            max_arg_count = 2;
+        }
+        break;
+    case 12:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "derived-from", 12)) {
+            min_arg_count = 2;
+            max_arg_count = 2;
+        }
+        break;
+    case 13:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "namespace-uri", 13)) {
+            min_arg_count = 0;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "string-length", 13)) {
+            min_arg_count = 0;
+            max_arg_count = 1;
+        }
+        break;
+    case 15:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "normalize-space", 15)) {
+            min_arg_count = 0;
+            max_arg_count = 1;
+        } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "substring-after", 15)) {
+            min_arg_count = 2;
+            max_arg_count = 2;
+        }
+        break;
+    case 16:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "substring-before", 16)) {
+            min_arg_count = 2;
+            max_arg_count = 2;
+        }
+        break;
+    case 20:
+        if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "derived-from-or-self", 20)) {
+            min_arg_count = 2;
+            max_arg_count = 2;
+        }
+        break;
+    }
+    if (min_arg_count == -1) {
+        LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INFUNC, exp->tok_len[*exp_idx], &exp->expr[exp->tok_pos[*exp_idx]]);
+        return LY_EINVAL;
+    }
+    ++(*exp_idx);
+
+    /* '(' */
+    rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_PAR1, 1);
+    LY_CHECK_RET(rc);
+    ++(*exp_idx);
+
+    /* ( Expr ( ',' Expr )* )? */
+    arg_count = 0;
+    rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_NONE, 1);
+    LY_CHECK_RET(rc);
+    if (exp->tokens[*exp_idx] != LYXP_TOKEN_PAR2) {
+        ++arg_count;
+        rc = reparse_or_expr(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+    }
+    while ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_COMMA)) {
+        ++(*exp_idx);
+
+        ++arg_count;
+        rc = reparse_or_expr(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+    }
+
+    /* ')' */
+    rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_PAR2, 1);
+    LY_CHECK_RET(rc);
+    ++(*exp_idx);
+
+    if ((arg_count < min_arg_count) || (arg_count > max_arg_count)) {
+        LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INARGCOUNT, arg_count, exp->tok_len[func_exp_idx],
+               &exp->expr[exp->tok_pos[func_exp_idx]]);
+        return LY_EVALID;
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Reparse PathExpr. Logs directly on error.
+ *
+ * [10] PathExpr ::= LocationPath | PrimaryExpr Predicate*
+ *                 | PrimaryExpr Predicate* '/' RelativeLocationPath
+ *                 | PrimaryExpr Predicate* '//' RelativeLocationPath
+ * [2] LocationPath ::= RelativeLocationPath | AbsoluteLocationPath
+ * [8] PrimaryExpr ::= '(' Expr ')' | Literal | Number | FunctionCall
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @return LY_ERR
+ */
+static LY_ERR
+reparse_path_expr(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    LY_ERR rc;
+
+    if (exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_NONE, 1)) {
+        return -1;
+    }
+
+    switch (exp->tokens[*exp_idx]) {
+    case LYXP_TOKEN_PAR1:
+        /* '(' Expr ')' Predicate* */
+        ++(*exp_idx);
+
+        rc = reparse_or_expr(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+
+        rc = exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_PAR2, 1);
+        LY_CHECK_RET(rc);
+        ++(*exp_idx);
+        goto predicate;
+        break;
+    case LYXP_TOKEN_DOT:
+    case LYXP_TOKEN_DDOT:
+    case LYXP_TOKEN_AT:
+    case LYXP_TOKEN_NAMETEST:
+    case LYXP_TOKEN_NODETYPE:
+        /* RelativeLocationPath */
+        rc = reparse_relative_location_path(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+        break;
+    case LYXP_TOKEN_FUNCNAME:
+        /* FunctionCall */
+        rc = reparse_function_call(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+        goto predicate;
+        break;
+    case LYXP_TOKEN_OPERATOR_PATH:
+        /* AbsoluteLocationPath */
+        rc = reparse_absolute_location_path(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+        break;
+    case LYXP_TOKEN_LITERAL:
+        /* Literal */
+        ++(*exp_idx);
+        goto predicate;
+        break;
+    case LYXP_TOKEN_NUMBER:
+        /* Number */
+        ++(*exp_idx);
+        goto predicate;
+        break;
+    default:
+        LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK,
+               print_token(exp->tokens[*exp_idx]), &exp->expr[exp->tok_pos[*exp_idx]]);
+        return LY_EVALID;
+    }
+
+    return LY_SUCCESS;
+
+predicate:
+    /* Predicate* */
+    while ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_BRACK1)) {
+        rc = reparse_predicate(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+    }
+
+    /* ('/' or '//') RelativeLocationPath */
+    if ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_PATH)) {
+
+        /* '/' or '//' */
+        ++(*exp_idx);
+
+        rc = reparse_relative_location_path(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Reparse UnaryExpr. Logs directly on error.
+ *
+ * [17] UnaryExpr ::= UnionExpr | '-' UnaryExpr
+ * [18] UnionExpr ::= PathExpr | UnionExpr '|' PathExpr
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @return LY_ERR
+ */
+static LY_ERR
+reparse_unary_expr(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    uint16_t prev_exp;
+    LY_ERR rc;
+
+    /* ('-')* */
+    prev_exp = *exp_idx;
+    while (!exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_MATH, 0)
+            && (exp->expr[exp->tok_pos[*exp_idx]] == '-')) {
+        exp_repeat_push(exp, prev_exp, LYXP_EXPR_UNARY);
+        ++(*exp_idx);
+    }
+
+    /* PathExpr */
+    prev_exp = *exp_idx;
+    rc = reparse_path_expr(ctx, exp, exp_idx);
+    LY_CHECK_RET(rc);
+
+    /* ('|' PathExpr)* */
+    while (!exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_UNI, 0)) {
+        exp_repeat_push(exp, prev_exp, LYXP_EXPR_UNION);
+        ++(*exp_idx);
+
+        rc = reparse_path_expr(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Reparse AdditiveExpr. Logs directly on error.
+ *
+ * [15] AdditiveExpr ::= MultiplicativeExpr
+ *                     | AdditiveExpr '+' MultiplicativeExpr
+ *                     | AdditiveExpr '-' MultiplicativeExpr
+ * [16] MultiplicativeExpr ::= UnaryExpr
+ *                     | MultiplicativeExpr '*' UnaryExpr
+ *                     | MultiplicativeExpr 'div' UnaryExpr
+ *                     | MultiplicativeExpr 'mod' UnaryExpr
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @return LY_ERR
+ */
+static LY_ERR
+reparse_additive_expr(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    uint16_t prev_add_exp, prev_mul_exp;
+    LY_ERR rc;
+
+    prev_add_exp = *exp_idx;
+    goto reparse_multiplicative_expr;
+
+    /* ('+' / '-' MultiplicativeExpr)* */
+    while (!exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_MATH, 0)
+            && ((exp->expr[exp->tok_pos[*exp_idx]] == '+') || (exp->expr[exp->tok_pos[*exp_idx]] == '-'))) {
+        exp_repeat_push(exp, prev_add_exp, LYXP_EXPR_ADDITIVE);
+        ++(*exp_idx);
+
+reparse_multiplicative_expr:
+        /* UnaryExpr */
+        prev_mul_exp = *exp_idx;
+        rc = reparse_unary_expr(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+
+        /* ('*' / 'div' / 'mod' UnaryExpr)* */
+        while (!exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_MATH, 0)
+                && ((exp->expr[exp->tok_pos[*exp_idx]] == '*') || (exp->tok_len[*exp_idx] == 3))) {
+            exp_repeat_push(exp, prev_mul_exp, LYXP_EXPR_MULTIPLICATIVE);
+            ++(*exp_idx);
+
+            rc = reparse_unary_expr(ctx, exp, exp_idx);
+            LY_CHECK_RET(rc);
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Reparse EqualityExpr. Logs directly on error.
+ *
+ * [13] EqualityExpr ::= RelationalExpr | EqualityExpr '=' RelationalExpr
+ *                     | EqualityExpr '!=' RelationalExpr
+ * [14] RelationalExpr ::= AdditiveExpr
+ *                       | RelationalExpr '<' AdditiveExpr
+ *                       | RelationalExpr '>' AdditiveExpr
+ *                       | RelationalExpr '<=' AdditiveExpr
+ *                       | RelationalExpr '>=' AdditiveExpr
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @return LY_ERR
+ */
+static LY_ERR
+reparse_equality_expr(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    uint16_t prev_eq_exp, prev_rel_exp;
+    LY_ERR rc;
+
+    prev_eq_exp = *exp_idx;
+    goto reparse_additive_expr;
+
+    /* ('=' / '!=' RelationalExpr)* */
+    while (!exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_COMP, 0)
+            && ((exp->expr[exp->tok_pos[*exp_idx]] == '=') || (exp->expr[exp->tok_pos[*exp_idx]] == '!'))) {
+        exp_repeat_push(exp, prev_eq_exp, LYXP_EXPR_EQUALITY);
+        ++(*exp_idx);
+
+reparse_additive_expr:
+        /* AdditiveExpr */
+        prev_rel_exp = *exp_idx;
+        rc = reparse_additive_expr(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+
+        /* ('<' / '>' / '<=' / '>=' AdditiveExpr)* */
+        while (!exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_COMP, 0)
+                && ((exp->expr[exp->tok_pos[*exp_idx]] == '<') || (exp->expr[exp->tok_pos[*exp_idx]] == '>'))) {
+            exp_repeat_push(exp, prev_rel_exp, LYXP_EXPR_RELATIONAL);
+            ++(*exp_idx);
+
+            rc = reparse_additive_expr(ctx, exp, exp_idx);
+            LY_CHECK_RET(rc);
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Reparse OrExpr. Logs directly on error.
+ *
+ * [11] OrExpr ::= AndExpr | OrExpr 'or' AndExpr
+ * [12] AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr
+ *
+ * @param[in] ctx Context for logging.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @return LY_ERR
+ */
+static LY_ERR
+reparse_or_expr(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx)
+{
+    uint16_t prev_or_exp, prev_and_exp;
+    LY_ERR rc;
+
+    prev_or_exp = *exp_idx;
+    goto reparse_equality_expr;
+
+    /* ('or' AndExpr)* */
+    while (!exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_LOG, 0) && (exp->tok_len[*exp_idx] == 2)) {
+        exp_repeat_push(exp, prev_or_exp, LYXP_EXPR_OR);
+        ++(*exp_idx);
+
+reparse_equality_expr:
+        /* EqualityExpr */
+        prev_and_exp = *exp_idx;
+        rc = reparse_equality_expr(ctx, exp, exp_idx);
+        LY_CHECK_RET(rc);
+
+        /* ('and' EqualityExpr)* */
+        while (!exp_check_token(ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_LOG, 0) && (exp->tok_len[*exp_idx] == 3)) {
+            exp_repeat_push(exp, prev_and_exp, LYXP_EXPR_AND);
+            ++(*exp_idx);
+
+            rc = reparse_equality_expr(ctx, exp, exp_idx);
+            LY_CHECK_RET(rc);
+        }
+    }
+
+    return LY_SUCCESS;
+}
 
 /**
  * @brief Parse NCName.
  *
  * @param[in] ncname Name to parse.
- *
- * @return Length of \p ncname valid bytes.
+ * @return Length of @p ncname valid bytes.
  */
 static long int
 parse_ncname(const char *ncname)
@@ -55,17 +2462,17 @@
 }
 
 /**
- * @brief Add \p token into the expression \p exp.
+ * @brief Add @p token into the expression @p exp.
  *
- * @param[in] ctx libyang context to log in.
+ * @param[in] ctx Context for logging.
  * @param[in] exp Expression to use.
  * @param[in] token Token to add.
- * @param[in] expr_pos Token position in the XPath expression.
+ * @param[in] tok_pos Token position in the XPath expression.
  * @param[in] tok_len Token length in the XPath expression.
- * @return LY_ERR value
+ * @return LY_ERR
  */
 static LY_ERR
-exp_add_token(struct ly_ctx *ctx, struct lyxp_expr *exp, enum lyxp_token token, uint16_t expr_pos, uint16_t tok_len)
+exp_add_token(struct ly_ctx *ctx, struct lyxp_expr *exp, enum lyxp_token token, uint16_t tok_pos, uint16_t tok_len)
 {
     uint32_t prev;
 
@@ -86,7 +2493,7 @@
     }
 
     exp->tokens[exp->used] = token;
-    exp->tok_pos[exp->used] = expr_pos;
+    exp->tok_pos[exp->used] = tok_pos;
     exp->tok_len[exp->used] = tok_len;
     ++exp->used;
     return LY_SUCCESS;
@@ -122,6 +2529,7 @@
     long int ncname_len;
     enum lyxp_token tok_type;
     int prev_function_check = 0;
+    uint16_t exp_idx = 0;
 
     if (strlen(expr) > UINT16_MAX) {
         LOGERR(ctx, LY_EINVAL, "XPath expression cannot be longer than %ud characters.", UINT16_MAX);
@@ -354,6 +2762,17 @@
     ret->repeat = calloc(ret->size, sizeof *ret->repeat);
     LY_CHECK_ERR_GOTO(!ret->repeat, LOGMEM(ctx), error);
 
+    /* fill repeat */
+    LY_CHECK_GOTO(reparse_or_expr(ctx, ret, &exp_idx), error);
+    if (ret->used > exp_idx) {
+        LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK, "Unknown", &ret->expr[ret->tok_pos[exp_idx]]);
+        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of an XPath expression.",
+               &ret->expr[ret->tok_pos[exp_idx]]);
+        goto error;
+    }
+
+    print_expr_struct_debug(ret);
+
     return ret;
 
 error:
@@ -361,3 +2780,5915 @@
     return NULL;
 }
 
+/*
+ * warn functions
+ *
+ * Warn functions check specific reasonable conditions for schema XPath
+ * and print a warning if they are not satisfied.
+ */
+
+/**
+ * @brief Get the last-added schema node that is currently in the context.
+ *
+ * @param[in] set Set to search in.
+ * @return Last-added schema context node, NULL if no node is in context.
+ */
+static struct lysc_node *
+warn_get_scnode_in_ctx(struct lyxp_set *set)
+{
+    uint32_t i;
+
+    if (!set || (set->type != LYXP_SET_SCNODE_SET)) {
+        return NULL;
+    }
+
+    i = set->used;
+    do {
+        --i;
+        if (set->val.scnodes[i].in_ctx == 1) {
+            /* if there are more, simply return the first found (last added) */
+            return set->val.scnodes[i].scnode;
+        }
+    } while (i);
+
+    return NULL;
+}
+
+/**
+ * @brief Test whether a type is numeric - integer type or decimal64.
+ *
+ * @param[in] type Type to test.
+ * @return 1 if numeric, 0 otherwise.
+ */
+static int
+warn_is_numeric_type(struct lysc_type *type)
+{
+    struct lysc_type_union *uni;
+    int ret;
+    uint32_t i;
+
+    switch (type->basetype) {
+    case LY_TYPE_DEC64:
+    case LY_TYPE_INT8:
+    case LY_TYPE_UINT8:
+    case LY_TYPE_INT16:
+    case LY_TYPE_UINT16:
+    case LY_TYPE_INT32:
+    case LY_TYPE_UINT32:
+    case LY_TYPE_INT64:
+    case LY_TYPE_UINT64:
+        return 1;
+    case LY_TYPE_UNION:
+        uni = (struct lysc_type_union *)type;
+        LY_ARRAY_FOR(uni->types, i) {
+            ret = warn_is_numeric_type(uni->types[i]);
+            if (ret) {
+                /* found a suitable type */
+                return 1;
+            }
+        }
+        /* did not find any suitable type */
+        return 0;
+    case LY_TYPE_LEAFREF:
+        return warn_is_numeric_type(((struct lysc_type_leafref *)type)->realtype);
+    default:
+        return 0;
+    }
+}
+
+/**
+ * @brief Test whether a type is string-like - no integers, decimal64 or binary.
+ *
+ * @param[in] type Type to test.
+ * @return 1 if string, 0 otherwise.
+ */
+static int
+warn_is_string_type(struct lysc_type *type)
+{
+    struct lysc_type_union *uni;
+    int ret;
+    uint32_t i;
+
+    switch (type->basetype) {
+    case LY_TYPE_BITS:
+    case LY_TYPE_ENUM:
+    case LY_TYPE_IDENT:
+    case LY_TYPE_INST:
+    case LY_TYPE_STRING:
+        return 1;
+    case LY_TYPE_UNION:
+        uni = (struct lysc_type_union *)type;
+        LY_ARRAY_FOR(uni->types, i) {
+            ret = warn_is_string_type(uni->types[i]);
+            if (ret) {
+                /* found a suitable type */
+                return 1;
+            }
+        }
+        /* did not find any suitable type */
+        return 0;
+    case LY_TYPE_LEAFREF:
+        return warn_is_string_type(((struct lysc_type_leafref *)type)->realtype);
+    default:
+        return 0;
+    }
+}
+
+/**
+ * @brief Test whether a type is one specific type.
+ *
+ * @param[in] type Type to test.
+ * @param[in] base Expected type.
+ * @return 1 if it is, 0 otherwise.
+ */
+static int
+warn_is_specific_type(struct lysc_type *type, LY_DATA_TYPE base)
+{
+    struct lysc_type_union *uni;
+    int ret;
+    uint32_t i;
+
+    if (type->basetype == base) {
+        return 1;
+    } else if (type->basetype == LY_TYPE_UNION) {
+        uni = (struct lysc_type_union *)type;
+        LY_ARRAY_FOR(uni->types, i) {
+            ret = warn_is_specific_type(uni->types[i], base);
+            if (ret) {
+                /* found a suitable type */
+                return 1;
+            }
+        }
+        /* did not find any suitable type */
+        return 0;
+    } else if (type->basetype == LY_TYPE_LEAFREF) {
+        return warn_is_specific_type(((struct lysc_type_leafref *)type)->realtype, base);
+    }
+
+    return 0;
+}
+
+/**
+ * @brief Get next type of a (union) type.
+ *
+ * @param[in] type Base type.
+ * @param[in] prev_type Previously returned type.
+ * @return Next type or NULL.
+ */
+static struct lysc_type *
+warn_is_equal_type_next_type(struct lysc_type *type, struct lysc_type *prev_type)
+{
+    struct lysc_type_union *uni;
+    int found = 0;
+    uint32_t i;
+
+    switch (type->basetype) {
+    case LY_TYPE_UNION:
+        uni = (struct lysc_type_union *)type;
+        if (!prev_type) {
+            return uni->types[0];
+        }
+        LY_ARRAY_FOR(uni->types, i) {
+            if (found) {
+                return uni->types[i];
+            }
+            if (prev_type == uni->types[i]) {
+                found = 1;
+            }
+        }
+        return NULL;
+    default:
+        if (prev_type) {
+            assert(type == prev_type);
+            return NULL;
+        } else {
+            return type;
+        }
+    }
+}
+
+/**
+ * @brief Test whether 2 types have a common type.
+ *
+ * @param[in] type1 First type.
+ * @param[in] type2 Second type.
+ * @return 1 if they do, 0 otherwise.
+ */
+static int
+warn_is_equal_type(struct lysc_type *type1, struct lysc_type *type2)
+{
+    struct lysc_type *t1, *rt1, *t2, *rt2;
+
+    t1 = NULL;
+    while ((t1 = warn_is_equal_type_next_type(type1, t1))) {
+        if (t1->basetype == LY_TYPE_LEAFREF) {
+            rt1 = ((struct lysc_type_leafref *)t1)->realtype;
+        } else {
+            rt1 = t1;
+        }
+
+        t2 = NULL;
+        while ((t2 = warn_is_equal_type_next_type(type2, t2))) {
+            if (t2->basetype == LY_TYPE_LEAFREF) {
+                rt2 = ((struct lysc_type_leafref *)t2)->realtype;
+            } else {
+                rt2 = t2;
+            }
+
+            if (rt2->basetype == rt1->basetype) {
+                /* match found */
+                return 1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * @brief Check both operands of comparison operators.
+ *
+ * @param[in] ctx Context for errors.
+ * @param[in] set1 First operand set.
+ * @param[in] set2 Second operand set.
+ * @param[in] numbers_only Whether accept only numbers or other types are fine too (for '=' and '!=').
+ * @param[in] expr Start of the expression to print with the warning.
+ * @param[in] tok_pos Token position.
+ */
+static void
+warn_operands(struct ly_ctx *ctx, struct lyxp_set *set1, struct lyxp_set *set2, int numbers_only, const char *expr, uint16_t tok_pos)
+{
+    struct lysc_node_leaf *node1, *node2;
+    int leaves = 1, warning = 0;
+
+    node1 = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(set1);
+    node2 = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(set2);
+
+    if (!node1 && !node2) {
+        /* no node-sets involved, nothing to do */
+        return;
+    }
+
+    if (node1) {
+        if (!(node1->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(ctx, "Node type %s \"%s\" used as operand.", lys_nodetype2str(node1->nodetype), node1->name);
+            warning = 1;
+            leaves = 0;
+        } else if (numbers_only && !warn_is_numeric_type(node1->type)) {
+            LOGWRN(ctx, "Node \"%s\" is not of a numeric type, but used where it was expected.", node1->name);
+            warning = 1;
+        }
+    }
+
+    if (node2) {
+        if (!(node2->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(ctx, "Node type %s \"%s\" used as operand.", lys_nodetype2str(node2->nodetype), node2->name);
+            warning = 1;
+            leaves = 0;
+        } else if (numbers_only && !warn_is_numeric_type(node2->type)) {
+            LOGWRN(ctx, "Node \"%s\" is not of a numeric type, but used where it was expected.", node2->name);
+            warning = 1;
+        }
+    }
+
+    if (node1 && node2 && leaves && !numbers_only) {
+        if ((warn_is_numeric_type(node1->type) && !warn_is_numeric_type(node2->type))
+                || (!warn_is_numeric_type(node1->type) && warn_is_numeric_type(node2->type))
+                || (!warn_is_numeric_type(node1->type) && !warn_is_numeric_type(node2->type)
+                && !warn_is_equal_type(node1->type, node2->type))) {
+            LOGWRN(ctx, "Incompatible types of operands \"%s\" and \"%s\" for comparison.", node1->name, node2->name);
+            warning = 1;
+        }
+    }
+
+    if (warning) {
+        LOGWRN(ctx, "Previous warning generated by XPath subexpression[%u] \"%.20s\".", tok_pos, expr + tok_pos);
+    }
+}
+
+/**
+ * @brief Check that a value is valid for a leaf. If not applicable, does nothing.
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] set Set with the leaf/leaf-list.
+ * @param[in] val_exp Index of the value (literal/number) in @p exp.
+ * @param[in] equal_exp Index of the start of the equality expression in @p exp.
+ * @param[in] last_equal_exp Index of the end of the equality expression in @p exp.
+ */
+static void
+warn_equality_value(struct lyxp_expr *exp, struct lyxp_set *set, uint16_t val_exp, uint16_t equal_exp, uint16_t last_equal_exp)
+{
+    struct lysc_node *scnode;
+    struct lysc_type *type;
+    char *value;
+    LY_ERR rc;
+    struct ly_err_item *err = NULL;
+
+    if ((scnode = warn_get_scnode_in_ctx(set)) && (scnode->nodetype & (LYS_LEAF | LYS_LEAFLIST))
+            && ((exp->tokens[val_exp] == LYXP_TOKEN_LITERAL) || (exp->tokens[val_exp] == LYXP_TOKEN_NUMBER))) {
+        /* check that the node can have the specified value */
+        if (exp->tokens[val_exp] == LYXP_TOKEN_LITERAL) {
+            value = strndup(exp->expr + exp->tok_pos[val_exp] + 1, exp->tok_len[val_exp] - 2);
+        } else {
+            value = strndup(exp->expr + exp->tok_pos[val_exp], exp->tok_len[val_exp]);
+        }
+        if (!value) {
+            LOGMEM(set->ctx);
+            return;
+        }
+
+        if ((((struct lysc_node_leaf *)scnode)->type->basetype == LY_TYPE_IDENT) && !strchr(value, ':')) {
+            LOGWRN(set->ctx, "Identityref \"%s\" comparison with identity \"%s\" without prefix, consider adding"
+                   " a prefix or best using \"derived-from(-or-self)()\" functions.", scnode->name, value);
+            LOGWRN(set->ctx, "Previous warning generated by XPath subexpression[%u] \"%.*s\".", exp->tok_pos[equal_exp],
+                   (exp->tok_pos[last_equal_exp] - exp->tok_pos[equal_exp]) + exp->tok_len[last_equal_exp],
+                   exp->expr + exp->tok_pos[equal_exp]);
+        }
+
+        type = ((struct lysc_node_leaf *)scnode)->type;
+        if (type->basetype != LY_TYPE_IDENT) {
+            rc = type->plugin->store(set->ctx, type, value, strlen(value), LY_TYPE_OPTS_SCHEMA,
+                                      lys_resolve_prefix, (void *)type->dflt_mod, LYD_XML, NULL, NULL, NULL, NULL, &err);
+
+            if (err) {
+                LOGWRN(set->ctx, "Invalid value \"%s\" which does not fit the type (%s).", value, err->msg);
+                ly_err_free(err);
+            } else if (rc != LY_SUCCESS) {
+                LOGWRN(set->ctx, "Invalid value \"%s\" which does not fit the type.", value);
+            }
+            if (rc != LY_SUCCESS) {
+                LOGWRN(set->ctx, "Previous warning generated by XPath subexpression[%u] \"%.*s\".", exp->tok_pos[equal_exp],
+                    (exp->tok_pos[last_equal_exp] - exp->tok_pos[equal_exp]) + exp->tok_len[last_equal_exp],
+                    exp->expr + exp->tok_pos[equal_exp]);
+            }
+        }
+        free(value);
+    }
+}
+
+/*
+ * XPath functions
+ */
+
+/**
+ * @brief Execute the YANG 1.1 bit-is-set(node-set, string) function. Returns LYXP_SET_BOOLEAN
+ *        depending on whether the first node bit value from the second argument is set.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_bit_is_set(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lyd_node_term *leaf;
+    struct lysc_node_leaf *sleaf;
+    struct lysc_type_bits *bits;
+    LY_ERR rc = LY_SUCCESS;
+    uint32_t i;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type != LYXP_SET_SCNODE_SET) || !(sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            LOGWRN(set->ctx, "Argument #1 of %s not a node-set as expected.", __func__);
+            rc = LY_EINVAL;
+        } else if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+            rc = LY_EINVAL;
+        } else if (!warn_is_specific_type(sleaf->type, LY_TYPE_BITS)) {
+            LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of type \"bits\".", __func__, sleaf->name);
+            rc = LY_EINVAL;
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    if ((args[0]->type != LYXP_SET_NODE_SET) && (args[0]->type != LYXP_SET_EMPTY)) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "bit-is-set(node-set, string)");
+        return LY_EVALID;
+    }
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    set_fill_boolean(set, 0);
+    if (args[0]->type == LYXP_SET_NODE_SET) {
+        leaf = (struct lyd_node_term *)args[0]->val.nodes[0].node;
+        if ((leaf->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST))
+                && (((struct lysc_node_leaf *)leaf->schema)->type->basetype == LY_TYPE_BITS)) {
+            bits = (struct lysc_type_bits *)((struct lysc_node_leaf *)leaf->schema)->type;
+            LY_ARRAY_FOR(bits->bits, i) {
+                if (!strcmp(bits->bits[i].name, args[1]->val.str)) {
+                    set_fill_boolean(set, 1);
+                    break;
+                }
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath boolean(object) function. Returns LYXP_SET_BOOLEAN
+ *        with the argument converted to boolean.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_boolean(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_BOOLEAN, options);
+    LY_CHECK_RET(rc);
+    set_fill_set(set, args[0]);
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath ceiling(number) function. Returns LYXP_SET_NUMBER
+ *        with the first argument rounded up to the nearest integer.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_ceiling(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type != LYXP_SET_SCNODE_SET) || !(sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            LOGWRN(set->ctx, "Argument #1 of %s not a node-set as expected.", __func__);
+            rc = LY_EINVAL;
+        } else if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+            rc = LY_EINVAL;
+        } else if (!warn_is_specific_type(sleaf->type, LY_TYPE_DEC64)) {
+            LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of type \"decimal64\".", __func__, sleaf->name);
+            rc = LY_EINVAL;
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_NUMBER, options);
+    LY_CHECK_RET(rc);
+    if ((long long)args[0]->val.num != args[0]->val.num) {
+        set_fill_number(set, ((long long)args[0]->val.num) + 1);
+    } else {
+        set_fill_number(set, args[0]->val.num);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath concat(string, string, string*) function.
+ *        Returns LYXP_SET_STRING with the concatenation of all the arguments.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_concat(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    uint16_t i;
+    char *str = NULL;
+    size_t used = 1;
+    LY_ERR rc = LY_SUCCESS;
+    struct lysc_node_leaf *sleaf;
+
+    if (options & LYXP_SCNODE_ALL) {
+        for (i = 0; i < arg_count; ++i) {
+            if ((args[i]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[i]))) {
+                if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                    LOGWRN(set->ctx, "Argument #%u of %s is a %s node \"%s\".",
+                           i + 1, __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                    rc = LY_EINVAL;
+                } else if (!warn_is_string_type(sleaf->type)) {
+                    LOGWRN(set->ctx, "Argument #%u of %s is node \"%s\", not of string-type.", __func__, i + 1, sleaf->name);
+                    rc = LY_EINVAL;
+                }
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    for (i = 0; i < arg_count; ++i) {
+        rc = lyxp_set_cast(args[i], LYXP_SET_STRING, options);
+        if (rc != LY_SUCCESS) {
+            free(str);
+            return rc;
+        }
+
+        str = ly_realloc(str, (used + strlen(args[i]->val.str)) * sizeof(char));
+        LY_CHECK_ERR_RET(!str, LOGMEM(set->ctx), LY_EMEM);
+        strcpy(str + used - 1, args[i]->val.str);
+        used += strlen(args[i]->val.str);
+    }
+
+    /* free, kind of */
+    lyxp_set_cast(set, LYXP_SET_EMPTY, options);
+    set->type = LYXP_SET_STRING;
+    set->val.str = str;
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath contains(string, string) function.
+ *        Returns LYXP_SET_BOOLEAN whether the second argument can
+ *        be found in the first or not.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_contains(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    if (strstr(args[0]->val.str, args[1]->val.str)) {
+        set_fill_boolean(set, 1);
+    } else {
+        set_fill_boolean(set, 0);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath count(node-set) function. Returns LYXP_SET_NUMBER
+ *        with the size of the node-set from the argument.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_count(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lysc_node *scnode = NULL;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type != LYXP_SET_SCNODE_SET) || !(scnode = warn_get_scnode_in_ctx(args[0]))) {
+            LOGWRN(set->ctx, "Argument #1 of %s not a node-set as expected.", __func__);
+            rc = LY_EINVAL;
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    if (args[0]->type == LYXP_SET_EMPTY) {
+        set_fill_number(set, 0);
+        return LY_SUCCESS;
+    }
+
+    if (args[0]->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "count(node-set)");
+        return LY_EVALID;
+    }
+
+    set_fill_number(set, args[0]->used);
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath current() function. Returns LYXP_SET_NODE_SET
+ *        with the context with the intial node.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_current(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    if (arg_count || args) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGCOUNT, arg_count, "current()");
+        return LY_EVALID;
+    }
+
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+
+        set_scnode_insert_node(set, set->ctx_scnode, LYXP_NODE_ELEM);
+    } else {
+        lyxp_set_cast(set, LYXP_SET_EMPTY, options);
+
+        /* position is filled later */
+        set_insert_node(set, set->ctx_node, 0, LYXP_NODE_ELEM, 0);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the YANG 1.1 deref(node-set) function. Returns LYXP_SET_NODE_SET with either
+ *        leafref or instance-identifier target node(s).
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_deref(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lyd_node_term *leaf;
+    struct lysc_node_leaf *sleaf;
+    const struct lyd_node *node;
+    char *errmsg = NULL;
+    const char *val;
+    int dynamic;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type != LYXP_SET_SCNODE_SET) || !(sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            LOGWRN(set->ctx, "Argument #1 of %s not a node-set as expected.", __func__);
+            rc = LY_EINVAL;
+        } else if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+            rc = LY_EINVAL;
+        } else if (!warn_is_specific_type(sleaf->type, LY_TYPE_LEAFREF) && !warn_is_specific_type(sleaf->type, LY_TYPE_INST)) {
+            LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of type \"leafref\" nor \"instance-identifier\".",
+                   __func__, sleaf->name);
+            rc = LY_EINVAL;
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    if ((args[0]->type != LYXP_SET_NODE_SET) && (args[0]->type != LYXP_SET_EMPTY)) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "deref(node-set)");
+        return LY_EVALID;
+    }
+
+    lyxp_set_cast(set, LYXP_SET_EMPTY, options);
+    if (args[0]->type != LYXP_SET_EMPTY) {
+        leaf = (struct lyd_node_term *)args[0]->val.nodes[0].node;
+        sleaf = (struct lysc_node_leaf *)leaf->schema;
+        if (sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST)) {
+            if (sleaf->type->basetype == LY_TYPE_LEAFREF) {
+                /* find leafref target */
+                val = lyd_value2str(leaf, &dynamic);
+                node = ly_type_find_leafref(set->ctx, sleaf->type, val, strlen(val), (struct lyd_node *)leaf,
+                                            set->trees, &leaf->value, &errmsg);
+                if (dynamic) {
+                    free((char *)val);
+                }
+                if (!node) {
+                    LOGERR(set->ctx, LY_EINVAL, errmsg);
+                    free(errmsg);
+                    return LY_EINVAL;
+                }
+
+                /* insert it */
+                set_insert_node(set, node, 0, LYXP_NODE_ELEM, 0);
+            } else {
+                assert(sleaf->type->basetype == LY_TYPE_INST);
+                node = (struct lyd_node *)lyd_target(leaf->value.target, set->trees);
+                if (!node) {
+                    val = lyd_value2str(leaf, &dynamic);
+                    LOGERR(set->ctx, LY_EVALID, "Invalid instance-identifier \"%s\" value - required instance not found.", val);
+                    if (dynamic) {
+                        free((char *)val);
+                    }
+                    return LY_EVALID;
+                }
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the YANG 1.1 derived-from(node-set, string) function. Returns LYXP_SET_BOOLEAN depending
+ *        on whether the first argument nodes contain a node of an identity derived from the second
+ *        argument identity.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_derived_from(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    uint16_t i;
+    struct lyd_node_term *leaf;
+    struct lysc_node_leaf *sleaf;
+    struct lyd_value data = {0};
+    struct ly_err_item *err = NULL;
+    LY_ERR rc = LY_SUCCESS;
+    int found;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type != LYXP_SET_SCNODE_SET) || !(sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            LOGWRN(set->ctx, "Argument #1 of %s not a node-set as expected.", __func__);
+            rc = LY_EINVAL;
+        } else if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+            rc = LY_EINVAL;
+        } else if (!warn_is_specific_type(sleaf->type, LY_TYPE_IDENT)) {
+            LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of type \"identityref\".", __func__, sleaf->name);
+            rc = LY_EINVAL;
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    if ((args[0]->type != LYXP_SET_NODE_SET) && (args[0]->type != LYXP_SET_EMPTY)) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "derived-from(node-set, string)");
+        return LY_EVALID;
+    }
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    set_fill_boolean(set, 0);
+    if (args[0]->type != LYXP_SET_EMPTY) {
+        found = 0;
+        for (i = 0; i < args[0]->used; ++i) {
+            leaf = (struct lyd_node_term *)args[0]->val.nodes[i].node;
+            sleaf = (struct lysc_node_leaf *)leaf->schema;
+            if ((sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && (sleaf->type->basetype == LY_TYPE_IDENT)) {
+                /* store args[1] into ident */
+                rc = sleaf->type->plugin->store(set->ctx, sleaf->type, args[1]->val.str, strlen(args[1]->val.str),
+                                                LY_TYPE_OPTS_STORE, lys_resolve_prefix, (void *)sleaf->dflt_mod, set->format,
+                                                (struct lyd_node *)leaf, set->trees, &data, NULL, &err);
+                if (err) {
+                    ly_err_print(err);
+                    ly_err_free(err);
+                }
+                LY_CHECK_RET(rc);
+
+                LY_ARRAY_FOR(data.ident->derived, i) {
+                    if (data.ident->derived[i] == leaf->value.ident) {
+                        set_fill_boolean(set, 1);
+                        found = 1;
+                        break;
+                    }
+                }
+                if (found) {
+                    break;
+                }
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the YANG 1.1 derived-from-or-self(node-set, string) function. Returns LYXP_SET_BOOLEAN depending
+ *        on whether the first argument nodes contain a node of an identity that either is or is derived from
+ *        the second argument identity.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_derived_from_or_self(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    uint16_t i;
+    struct lyd_node_term *leaf;
+    struct lysc_node_leaf *sleaf;
+    struct lyd_value data = {0};
+    struct ly_err_item *err = NULL;
+    LY_ERR rc = LY_SUCCESS;
+    int found;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type != LYXP_SET_SCNODE_SET) || !(sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            LOGWRN(set->ctx, "Argument #1 of %s not a node-set as expected.", __func__);
+            rc = LY_EINVAL;
+        } else if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+            rc = LY_EINVAL;
+        } else if (!warn_is_specific_type(sleaf->type, LY_TYPE_IDENT)) {
+            LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of type \"identityref\".", __func__, sleaf->name);
+            rc = LY_EINVAL;
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    if ((args[0]->type != LYXP_SET_NODE_SET) && (args[0]->type != LYXP_SET_EMPTY)) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "derived-from-or-self(node-set, string)");
+        return LY_EVALID;
+    }
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    set_fill_boolean(set, 0);
+    if (args[0]->type != LYXP_SET_EMPTY) {
+        found = 0;
+        for (i = 0; i < args[0]->used; ++i) {
+            leaf = (struct lyd_node_term *)args[0]->val.nodes[i].node;
+            sleaf = (struct lysc_node_leaf *)leaf->schema;
+            if ((sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && (sleaf->type->basetype == LY_TYPE_IDENT)) {
+                /* store args[1] into ident */
+                rc = sleaf->type->plugin->store(set->ctx, sleaf->type, args[1]->val.str, strlen(args[1]->val.str),
+                                                LY_TYPE_OPTS_STORE, lys_resolve_prefix, (void *)sleaf->dflt_mod, set->format,
+                                                (struct lyd_node *)leaf, set->trees, &data, NULL, &err);
+                if (err) {
+                    ly_err_print(err);
+                    ly_err_free(err);
+                }
+                LY_CHECK_RET(rc);
+
+                if (data.ident == leaf->value.ident) {
+                    set_fill_boolean(set, 1);
+                    break;
+                }
+                LY_ARRAY_FOR(data.ident->derived, i) {
+                    if (data.ident->derived[i] == leaf->value.ident) {
+                        set_fill_boolean(set, 1);
+                        found = 1;
+                        break;
+                    }
+                }
+                if (found) {
+                    break;
+                }
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the YANG 1.1 enum-value(node-set) function. Returns LYXP_SET_NUMBER
+ *        with the integer value of the first node's enum value, otherwise NaN.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_enum_value(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lyd_node_term *leaf;
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type != LYXP_SET_SCNODE_SET) || !(sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            LOGWRN(set->ctx, "Argument #1 of %s not a node-set as expected.", __func__);
+            rc = LY_EINVAL;
+        } else if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+            rc = LY_EINVAL;
+        } else if (!warn_is_specific_type(sleaf->type, LY_TYPE_ENUM)) {
+            LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of type \"enumeration\".", __func__, sleaf->name);
+            rc = LY_EINVAL;
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    if ((args[0]->type != LYXP_SET_NODE_SET) && (args[0]->type != LYXP_SET_EMPTY)) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "enum-value(node-set)");
+        return LY_EVALID;
+    }
+
+    set_fill_number(set, NAN);
+    if (args[0]->type == LYXP_SET_NODE_SET) {
+        leaf = (struct lyd_node_term *)args[0]->val.nodes[0].node;
+        sleaf = (struct lysc_node_leaf *)leaf->schema;
+        if ((sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && (sleaf->type->basetype == LY_TYPE_ENUM)) {
+            set_fill_number(set, leaf->value.enum_item->value);
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath false() function. Returns LYXP_SET_BOOLEAN
+ *        with false value.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_false(struct lyxp_set **UNUSED(args), uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    set_fill_boolean(set, 0);
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath floor(number) function. Returns LYXP_SET_NUMBER
+ *        with the first argument floored (truncated).
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_floor(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_NUMBER, options);
+    LY_CHECK_RET(rc);
+    if (isfinite(args[0]->val.num)) {
+        set_fill_number(set, (long long)args[0]->val.num);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath lang(string) function. Returns LYXP_SET_BOOLEAN
+ *        whether the language of the text matches the one from the argument.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_lang(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    const struct lyd_node *node;
+    struct lysc_node_leaf *sleaf;
+    struct lyd_attr *attr = NULL;
+    const char *val;
+    int i, dynamic;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    if (set->type == LYXP_SET_EMPTY) {
+        set_fill_boolean(set, 0);
+        return LY_SUCCESS;
+    }
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INCTX, print_set_type(set), "lang(string)");
+        return LY_EVALID;
+    }
+
+    switch (set->val.nodes[0].type) {
+    case LYXP_NODE_ELEM:
+    case LYXP_NODE_TEXT:
+        node = set->val.nodes[0].node;
+        break;
+    case LYXP_NODE_ATTR:
+        node = set->val.attrs[0].attr->parent;
+        break;
+    default:
+        /* nothing to do with roots */
+        set_fill_boolean(set, 0);
+        return LY_SUCCESS;
+    }
+
+    /* find lang attribute */
+    for (; node; node = (struct lyd_node *)node->parent) {
+        for (attr = node->attr; attr; attr = attr->next) {
+            /* annotations */
+            if (attr->name && !strcmp(attr->name, "lang") && !strcmp(attr->annotation->module->name, "xml")) {
+                break;
+            }
+        }
+
+        if (attr) {
+            break;
+        }
+    }
+
+    /* compare languages */
+    if (!attr) {
+        set_fill_boolean(set, 0);
+    } else {
+        val = lyd_attr2str(attr, &dynamic);
+        for (i = 0; args[0]->val.str[i]; ++i) {
+            if (tolower(args[0]->val.str[i]) != tolower(val[i])) {
+                set_fill_boolean(set, 0);
+                break;
+            }
+        }
+        if (!args[0]->val.str[i]) {
+            if (!val[i] || (val[i] == '-')) {
+                set_fill_boolean(set, 1);
+            } else {
+                set_fill_boolean(set, 0);
+            }
+        }
+        if (dynamic) {
+            free((char *)val);
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath last() function. Returns LYXP_SET_NUMBER
+ *        with the context size.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_last(struct lyxp_set **UNUSED(args), uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (set->type == LYXP_SET_EMPTY) {
+        set_fill_number(set, 0);
+        return LY_SUCCESS;
+    }
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INCTX, print_set_type(set), "last()");
+        return LY_EVALID;
+    }
+
+    set_fill_number(set, set->ctx_size);
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath local-name(node-set?) function. Returns LYXP_SET_STRING
+ *        with the node name without namespace from the argument or the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_local_name(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    struct lyxp_set_node *item;
+    /* suppress unused variable warning */
+    (void)options;
+
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (arg_count) {
+        if (args[0]->type == LYXP_SET_EMPTY) {
+            set_fill_string(set, "", 0);
+            return LY_SUCCESS;
+        }
+        if (args[0]->type != LYXP_SET_NODE_SET) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "local-name(node-set?)");
+            return LY_EVALID;
+        }
+
+        /* we need the set sorted, it affects the result */
+        assert(!set_sort(args[0], options));
+
+        item = &args[0]->val.nodes[0];
+    } else {
+        if (set->type == LYXP_SET_EMPTY) {
+            set_fill_string(set, "", 0);
+            return LY_SUCCESS;
+        }
+        if (set->type != LYXP_SET_NODE_SET) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INCTX, print_set_type(set), "local-name(node-set?)");
+            return LY_EVALID;
+        }
+
+        /* we need the set sorted, it affects the result */
+        assert(!set_sort(set, options));
+
+        item = &set->val.nodes[0];
+    }
+
+    switch (item->type) {
+    case LYXP_NODE_ROOT:
+    case LYXP_NODE_ROOT_CONFIG:
+    case LYXP_NODE_TEXT:
+        set_fill_string(set, "", 0);
+        break;
+    case LYXP_NODE_ELEM:
+        set_fill_string(set, item->node->schema->name, strlen(item->node->schema->name));
+        break;
+    case LYXP_NODE_ATTR:
+        set_fill_string(set, ((struct lyd_attr *)item->node)->name, strlen(((struct lyd_attr *)item->node)->name));
+        break;
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath name(node-set?) function. Returns LYXP_SET_STRING
+ *        with the node name fully qualified (with namespace) from the argument or the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_name(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    struct lyxp_set_node *item;
+    struct lys_module *mod;
+    char *str;
+    const char *name;
+    int rc;
+
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (arg_count) {
+        if (args[0]->type == LYXP_SET_EMPTY) {
+            set_fill_string(set, "", 0);
+            return LY_SUCCESS;
+        }
+        if (args[0]->type != LYXP_SET_NODE_SET) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "name(node-set?)");
+            return LY_EVALID;
+        }
+
+        /* we need the set sorted, it affects the result */
+        assert(!set_sort(args[0], options));
+
+        item = &args[0]->val.nodes[0];
+    } else {
+        if (set->type == LYXP_SET_EMPTY) {
+            set_fill_string(set, "", 0);
+            return LY_SUCCESS;
+        }
+        if (set->type != LYXP_SET_NODE_SET) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INCTX, print_set_type(set), "name(node-set?)");
+            return LY_EVALID;
+        }
+
+        /* we need the set sorted, it affects the result */
+        assert(!set_sort(set, options));
+
+        item = &set->val.nodes[0];
+    }
+
+    switch (item->type) {
+    case LYXP_NODE_ROOT:
+    case LYXP_NODE_ROOT_CONFIG:
+    case LYXP_NODE_TEXT:
+        mod = NULL;
+        name = NULL;
+        break;
+    case LYXP_NODE_ELEM:
+        mod = item->node->schema->module;
+        name = item->node->schema->name;
+        break;
+    case LYXP_NODE_ATTR:
+        mod = ((struct lyd_attr *)item->node)->annotation->module;
+        name = ((struct lyd_attr *)item->node)->name;
+        break;
+    }
+
+    if (mod && name) {
+        switch (set->format) {
+        case LYD_UNKNOWN:
+            rc = asprintf(&str, "%s:%s", lys_prefix_find_module(set->local_mod, mod), name);
+            break;
+        case LYD_JSON:
+            rc = asprintf(&str, "%s:%s", mod->name, name);
+            break;
+        }
+        LY_CHECK_ERR_RET(rc == -1, LOGMEM(set->ctx), LY_EMEM);
+        set_fill_string(set, str, strlen(str));
+        free(str);
+    } else {
+        set_fill_string(set, "", 0);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath namespace-uri(node-set?) function. Returns LYXP_SET_STRING
+ *        with the namespace of the node from the argument or the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_namespace_uri(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    struct lyxp_set_node *item;
+    struct lys_module *mod;
+    /* suppress unused variable warning */
+    (void)options;
+
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (arg_count) {
+        if (args[0]->type == LYXP_SET_EMPTY) {
+            set_fill_string(set, "", 0);
+            return LY_SUCCESS;
+        }
+        if (args[0]->type != LYXP_SET_NODE_SET) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "namespace-uri(node-set?)");
+            return LY_EVALID;
+        }
+
+        /* we need the set sorted, it affects the result */
+        assert(!set_sort(args[0], options));
+
+        item = &args[0]->val.nodes[0];
+    } else {
+        if (set->type == LYXP_SET_EMPTY) {
+            set_fill_string(set, "", 0);
+            return LY_SUCCESS;
+        }
+        if (set->type != LYXP_SET_NODE_SET) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INCTX, print_set_type(set), "namespace-uri(node-set?)");
+            return LY_EVALID;
+        }
+
+        /* we need the set sorted, it affects the result */
+        assert(!set_sort(set, options));
+
+        item = &set->val.nodes[0];
+    }
+
+    switch (item->type) {
+    case LYXP_NODE_ROOT:
+    case LYXP_NODE_ROOT_CONFIG:
+    case LYXP_NODE_TEXT:
+        set_fill_string(set, "", 0);
+        break;
+    case LYXP_NODE_ELEM:
+    case LYXP_NODE_ATTR:
+        if (item->type == LYXP_NODE_ELEM) {
+            mod = item->node->schema->module;
+        } else { /* LYXP_NODE_ATTR */
+            /* annotations */
+            mod = ((struct lyd_attr *)item->node)->annotation->module;
+        }
+
+        set_fill_string(set, mod->ns, strlen(mod->ns));
+        break;
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath node() function (node type). Returns LYXP_SET_NODE_SET
+ *        with only nodes from the context. In practice it either leaves the context
+ *        as it is or returns an empty node set.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_node(struct lyxp_set **UNUSED(args), uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_NODE_SET) {
+        lyxp_set_cast(set, LYXP_SET_EMPTY, options);
+    }
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath normalize-space(string?) function. Returns LYXP_SET_STRING
+ *        with normalized value (no leading, trailing, double white spaces) of the node
+ *        from the argument or the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_normalize_space(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    uint16_t i, new_used;
+    char *new;
+    int have_spaces = 0, space_before = 0;
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if (arg_count && (args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    if (arg_count) {
+        set_fill_set(set, args[0]);
+    }
+    rc = lyxp_set_cast(set, LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    /* is there any normalization necessary? */
+    for (i = 0; set->val.str[i]; ++i) {
+        if (is_xmlws(set->val.str[i])) {
+            if ((i == 0) || space_before || (!set->val.str[i + 1])) {
+                have_spaces = 1;
+                break;
+            }
+            space_before = 1;
+        } else {
+            space_before = 0;
+        }
+    }
+
+    /* yep, there is */
+    if (have_spaces) {
+        /* it's enough, at least one character will go, makes space for ending '\0' */
+        new = malloc(strlen(set->val.str) * sizeof(char));
+        LY_CHECK_ERR_RET(!new, LOGMEM(set->ctx), LY_EMEM);
+        new_used = 0;
+
+        space_before = 0;
+        for (i = 0; set->val.str[i]; ++i) {
+            if (is_xmlws(set->val.str[i])) {
+                if ((i == 0) || space_before) {
+                    space_before = 1;
+                    continue;
+                } else {
+                    space_before = 1;
+                }
+            } else {
+                space_before = 0;
+            }
+
+            new[new_used] = (space_before ? ' ' : set->val.str[i]);
+            ++new_used;
+        }
+
+        /* at worst there is one trailing space now */
+        if (new_used && is_xmlws(new[new_used - 1])) {
+            --new_used;
+        }
+
+        new = ly_realloc(new, (new_used + 1) * sizeof(char));
+        LY_CHECK_ERR_RET(!new, LOGMEM(set->ctx), LY_EMEM);
+        new[new_used] = '\0';
+
+        free(set->val.str);
+        set->val.str = new;
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath not(boolean) function. Returns LYXP_SET_BOOLEAN
+ *        with the argument converted to boolean and logically inverted.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_not(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    lyxp_set_cast(args[0], LYXP_SET_BOOLEAN, options);
+    if (args[0]->val.bool) {
+        set_fill_boolean(set, 0);
+    } else {
+        set_fill_boolean(set, 1);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath number(object?) function. Returns LYXP_SET_NUMBER
+ *        with the number representation of either the argument or the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_number(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (arg_count) {
+        rc = lyxp_set_cast(args[0], LYXP_SET_NUMBER, options);
+        LY_CHECK_RET(rc);
+        set_fill_set(set, args[0]);
+    } else {
+        rc = lyxp_set_cast(set, LYXP_SET_NUMBER, options);
+        LY_CHECK_RET(rc);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath position() function. Returns LYXP_SET_NUMBER
+ *        with the context position.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_position(struct lyxp_set **UNUSED(args), uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (set->type == LYXP_SET_EMPTY) {
+        set_fill_number(set, 0);
+        return LY_SUCCESS;
+    }
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INCTX, print_set_type(set), "position()");
+        return LY_EVALID;
+    }
+
+    set_fill_number(set, set->ctx_pos);
+
+    /* UNUSED in 'Release' build type */
+    (void)options;
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the YANG 1.1 re-match(string, string) function. Returns LYXP_SET_BOOLEAN
+ *        depending on whether the second argument regex matches the first argument string. For details refer to
+ *        YANG 1.1 RFC section 10.2.1.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_re_match(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lysc_pattern **patterns = NULL, **pattern;
+    struct lysc_node_leaf *sleaf;
+    char *path;
+    LY_ERR rc = LY_SUCCESS;
+    struct ly_err_item *err;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    LY_ARRAY_NEW_RET(set->ctx, patterns, pattern, LY_EMEM);
+    *pattern = malloc(sizeof **pattern);
+    path = lyd_path(set->ctx_node, LYD_PATH_LOG, NULL, 0);
+    rc = lys_compile_type_pattern_check(set->ctx, path, args[1]->val.str, &(*pattern)->code);
+    free(path);
+    if (rc != LY_SUCCESS) {
+        LY_ARRAY_FREE(patterns);
+        return rc;
+    }
+
+    rc = ly_type_validate_patterns(patterns, args[0]->val.str, strlen(args[0]->val.str), &err);
+    pcre2_code_free((*pattern)->code);
+    free(*pattern);
+    LY_ARRAY_FREE(patterns);
+    if (rc && (rc != LY_EVALID)) {
+        ly_err_print(err);
+        ly_err_free(err);
+        return rc;
+    }
+
+    if (rc == LY_EVALID) {
+        ly_err_free(err);
+        set_fill_boolean(set, 0);
+    } else {
+        set_fill_boolean(set, 1);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath round(number) function. Returns LYXP_SET_NUMBER
+ *        with the rounded first argument. For details refer to
+ *        http://www.w3.org/TR/1999/REC-xpath-19991116/#function-round.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_round(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type != LYXP_SET_SCNODE_SET) || !(sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            LOGWRN(set->ctx, "Argument #1 of %s not a node-set as expected.", __func__);
+            rc = LY_EINVAL;
+        } else if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+            LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+            rc = LY_EINVAL;
+        } else if (!warn_is_specific_type(sleaf->type, LY_TYPE_DEC64)) {
+            LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of type \"decimal64\".", __func__, sleaf->name);
+            rc = LY_EINVAL;
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_NUMBER, options);
+    LY_CHECK_RET(rc);
+
+    /* cover only the cases where floor can't be used */
+    if ((args[0]->val.num == -0.0f) || ((args[0]->val.num < 0) && (args[0]->val.num >= -0.5))) {
+        set_fill_number(set, -0.0f);
+    } else {
+        args[0]->val.num += 0.5;
+        rc = xpath_floor(args, 1, args[0], options);
+        LY_CHECK_RET(rc);
+        set_fill_number(set, args[0]->val.num);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath starts-with(string, string) function.
+ *        Returns LYXP_SET_BOOLEAN whether the second argument is
+ *        the prefix of the first or not.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_starts_with(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    if (strncmp(args[0]->val.str, args[1]->val.str, strlen(args[1]->val.str))) {
+        set_fill_boolean(set, 0);
+    } else {
+        set_fill_boolean(set, 1);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath string(object?) function. Returns LYXP_SET_STRING
+ *        with the string representation of either the argument or the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_string(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (arg_count) {
+        rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+        LY_CHECK_RET(rc);
+        set_fill_set(set, args[0]);
+    } else {
+        rc = lyxp_set_cast(set, LYXP_SET_STRING, options);
+        LY_CHECK_RET(rc);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath string-length(string?) function. Returns LYXP_SET_NUMBER
+ *        with the length of the string in either the argument or the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_string_length(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if (arg_count && (args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        if (!arg_count && (set->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(set))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #0 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #0 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    if (arg_count) {
+        rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+        LY_CHECK_RET(rc);
+        set_fill_number(set, strlen(args[0]->val.str));
+    } else {
+        rc = lyxp_set_cast(set, LYXP_SET_STRING, options);
+        LY_CHECK_RET(rc);
+        set_fill_number(set, strlen(set->val.str));
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath substring(string, number, number?) function.
+ *        Returns LYXP_SET_STRING substring of the first argument starting
+ *        on the second argument index ending on the third argument index,
+ *        indexed from 1. For exact definition refer to
+ *        http://www.w3.org/TR/1999/REC-xpath-19991116/#function-substring.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_substring(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, int options)
+{
+    int start, len;
+    uint16_t str_start, str_len, pos;
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_numeric_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of numeric type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((arg_count == 3) && (args[2]->type == LYXP_SET_SCNODE_SET)
+                    && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[2]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #3 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_numeric_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #3 of %s is node \"%s\", not of numeric type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    /* start */
+    if (xpath_round(&args[1], 1, args[1], options)) {
+        return -1;
+    }
+    if (isfinite(args[1]->val.num)) {
+        start = args[1]->val.num - 1;
+    } else if (isinf(args[1]->val.num) && signbit(args[1]->val.num)) {
+        start = INT_MIN;
+    } else {
+        start = INT_MAX;
+    }
+
+    /* len */
+    if (arg_count == 3) {
+        rc = xpath_round(&args[2], 1, args[2], options);
+        LY_CHECK_RET(rc);
+        if (isfinite(args[2]->val.num)) {
+            len = args[2]->val.num;
+        } else if (isnan(args[2]->val.num) || signbit(args[2]->val.num)) {
+            len = 0;
+        } else {
+            len = INT_MAX;
+        }
+    } else {
+        len = INT_MAX;
+    }
+
+    /* find matching character positions */
+    str_start = 0;
+    str_len = 0;
+    for (pos = 0; args[0]->val.str[pos]; ++pos) {
+        if (pos < start) {
+            ++str_start;
+        } else if (pos < start + len) {
+            ++str_len;
+        } else {
+            break;
+        }
+    }
+
+    set_fill_string(set, args[0]->val.str + str_start, str_len);
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath substring-after(string, string) function.
+ *        Returns LYXP_SET_STRING with the string succeeding the occurance
+ *        of the second argument in the first or an empty string.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_substring_after(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    char *ptr;
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    ptr = strstr(args[0]->val.str, args[1]->val.str);
+    if (ptr) {
+        set_fill_string(set, ptr + strlen(args[1]->val.str), strlen(ptr + strlen(args[1]->val.str)));
+    } else {
+        set_fill_string(set, "", 0);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath substring-before(string, string) function.
+ *        Returns LYXP_SET_STRING with the string preceding the occurance
+ *        of the second argument in the first or an empty string.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_substring_before(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    char *ptr;
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    ptr = strstr(args[0]->val.str, args[1]->val.str);
+    if (ptr) {
+        set_fill_string(set, args[0]->val.str, ptr - args[0]->val.str);
+    } else {
+        set_fill_string(set, "", 0);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath sum(node-set) function. Returns LYXP_SET_NUMBER
+ *        with the sum of all the nodes in the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_sum(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    long double num;
+    char *str;
+    uint16_t i;
+    struct lyxp_set set_item;
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if (args[0]->type == LYXP_SET_SCNODE_SET) {
+            for (i = 0; i < args[0]->used; ++i) {
+                if (args[0]->val.scnodes[i].in_ctx == 1) {
+                    sleaf = (struct lysc_node_leaf *)args[0]->val.scnodes[i].scnode;
+                    if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                        LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__,
+                               lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                        rc = LY_EINVAL;
+                    } else if (!warn_is_numeric_type(sleaf->type)) {
+                        LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of numeric type.", __func__, sleaf->name);
+                        rc = LY_EINVAL;
+                    }
+                }
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    set_fill_number(set, 0);
+    if (args[0]->type == LYXP_SET_EMPTY) {
+        return LY_SUCCESS;
+    }
+
+    if (args[0]->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "sum(node-set)");
+        return LY_EVALID;
+    }
+
+    set_item.type = LYXP_SET_NODE_SET;
+    set_item.val.nodes = malloc(sizeof *set_item.val.nodes);
+    LY_CHECK_ERR_RET(!set_item.val.nodes, LOGMEM(set->ctx), LY_EMEM);
+
+    set_item.used = 1;
+    set_item.size = 1;
+
+    for (i = 0; i < args[0]->used; ++i) {
+        set_item.val.nodes[0] = args[0]->val.nodes[i];
+
+        rc = cast_node_set_to_string(&set_item, options, &str);
+        LY_CHECK_RET(rc);
+        num = cast_string_to_number(str);
+        free(str);
+        set->val.num += num;
+    }
+
+    free(set_item.val.nodes);
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath text() function (node type). Returns LYXP_SET_NODE_SET
+ *        with the text content of the nodes in the context.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_text(struct lyxp_set **UNUSED(args), uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    uint32_t i;
+
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    if (set->type == LYXP_SET_EMPTY) {
+        return LY_SUCCESS;
+    }
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INCTX, print_set_type(set), "text()");
+        return LY_EVALID;
+    }
+
+    for (i = 0; i < set->used;) {
+        switch (set->val.nodes[i].type) {
+        case LYXP_NODE_ELEM:
+            if (set->val.nodes[i].node->flags & LYD_DUMMY) {
+                LOGVAL(set->ctx, LY_VLOG_LYD, set->val.nodes[i].node, LY_VCODE_XP_DUMMY, set->val.nodes[i].node->schema->name);
+                return LY_EVALID;
+            }
+            if (set->val.nodes[i].node->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST)) {
+                set->val.nodes[i].type = LYXP_NODE_TEXT;
+                ++i;
+                break;
+            }
+            /* fall through */
+        case LYXP_NODE_ROOT:
+        case LYXP_NODE_ROOT_CONFIG:
+        case LYXP_NODE_TEXT:
+        case LYXP_NODE_ATTR:
+            set_remove_node(set, i);
+            break;
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath translate(string, string, string) function.
+ *        Returns LYXP_SET_STRING with the first argument with the characters
+ *        from the second argument replaced by those on the corresponding
+ *        positions in the third argument.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_translate(struct lyxp_set **args, uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    uint16_t i, j, new_used;
+    char *new;
+    int found, have_removed;
+    struct lysc_node_leaf *sleaf;
+    LY_ERR rc = LY_SUCCESS;
+
+    if (options & LYXP_SCNODE_ALL) {
+        if ((args[0]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[0]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #1 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #1 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((args[1]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[1]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #2 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #2 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+
+        if ((args[2]->type == LYXP_SET_SCNODE_SET) && (sleaf = (struct lysc_node_leaf *)warn_get_scnode_in_ctx(args[2]))) {
+            if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
+                LOGWRN(set->ctx, "Argument #3 of %s is a %s node \"%s\".", __func__, lys_nodetype2str(sleaf->nodetype), sleaf->name);
+                rc = LY_EINVAL;
+            } else if (!warn_is_string_type(sleaf->type)) {
+                LOGWRN(set->ctx, "Argument #3 of %s is node \"%s\", not of string-type.", __func__, sleaf->name);
+                rc = LY_EINVAL;
+            }
+        }
+        set_scnode_clear_ctx(set);
+        return rc;
+    }
+
+    rc = lyxp_set_cast(args[0], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+    rc = lyxp_set_cast(args[1], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+    rc = lyxp_set_cast(args[2], LYXP_SET_STRING, options);
+    LY_CHECK_RET(rc);
+
+    new = malloc((strlen(args[0]->val.str) + 1) * sizeof(char));
+    LY_CHECK_ERR_RET(!new, LOGMEM(set->ctx), LY_EMEM);
+    new_used = 0;
+
+    have_removed = 0;
+    for (i = 0; args[0]->val.str[i]; ++i) {
+        found = 0;
+
+        for (j = 0; args[1]->val.str[j]; ++j) {
+            if (args[0]->val.str[i] == args[1]->val.str[j]) {
+                /* removing this char */
+                if (j >= strlen(args[2]->val.str)) {
+                    have_removed = 1;
+                    found = 1;
+                    break;
+                }
+                /* replacing this char */
+                new[new_used] = args[2]->val.str[j];
+                ++new_used;
+                found = 1;
+                break;
+            }
+        }
+
+        /* copying this char */
+        if (!found) {
+            new[new_used] = args[0]->val.str[i];
+            ++new_used;
+        }
+    }
+
+    if (have_removed) {
+        new = ly_realloc(new, (new_used + 1) * sizeof(char));
+        LY_CHECK_ERR_RET(!new, LOGMEM(set->ctx), LY_EMEM);
+    }
+    new[new_used] = '\0';
+
+    lyxp_set_cast(set, LYXP_SET_EMPTY, options);
+    set->type = LYXP_SET_STRING;
+    set->val.str = new;
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Execute the XPath true() function. Returns LYXP_SET_BOOLEAN
+ *        with true value.
+ *
+ * @param[in] args Array of arguments.
+ * @param[in] arg_count Count of elements in @p args.
+ * @param[in,out] set Context and result set at the same time.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINVAL for wrong arguments on schema)
+ */
+static LY_ERR
+xpath_true(struct lyxp_set **UNUSED(args), uint16_t UNUSED(arg_count), struct lyxp_set *set, int options)
+{
+    if (options & LYXP_SCNODE_ALL) {
+        set_scnode_clear_ctx(set);
+        return LY_SUCCESS;
+    }
+
+    set_fill_boolean(set, 1);
+    return LY_SUCCESS;
+}
+
+/*
+ * moveto functions
+ *
+ * They and only they actually change the context (set).
+ */
+
+/**
+ * @brief Resolve and find a specific model. Does not log.
+ *
+ * @param[in] prefix Prefix with various meaning dependning on @p format.
+ * @param[in] len Prefix length.
+ * @param[in] format Format determining the meaning of @p prefix (LYD_UNKNOWN refers to schema).
+ * @param[in] ctx libyang context.
+ * @param[in] local_mod Local module of the XPath expression.
+ * @return Corresponding module or NULL on error.
+ */
+static struct lys_module *
+moveto_resolve_model(const char *prefix, uint16_t len, LYD_FORMAT format, struct ly_ctx *ctx, const struct lys_module *local_mod)
+{
+    struct lys_module *mod = NULL;
+    char *str;
+
+    switch (format) {
+    case LYD_UNKNOWN:
+        /* schema, search all local module imports */
+        mod = lys_module_find_prefix(local_mod, prefix, len);
+        break;
+    case LYD_JSON:
+        /* JSON data, search in context */
+        str = strndup(prefix, len);
+        mod = ly_ctx_get_module(ctx, str, NULL);
+        free(str);
+        break;
+    }
+
+    if (!mod->implemented) {
+        /* non-implemented module is not valid */
+        mod = NULL;
+    }
+
+    return mod;
+}
+
+/**
+ * @brief Get the context root.
+ *
+ * @param[in] ctx_node Original context node.
+ * @param[in] options XPath options.
+ * @param[out] root_type Root type, differs only for when/must evaluation.
+ * @return Context root.
+ */
+static const struct lyd_node *
+moveto_get_root(const struct lyd_node *ctx_node, int options, enum lyxp_node_type *root_type)
+{
+    const struct lyd_node *root;
+
+    if (!ctx_node) {
+        return NULL;
+    }
+
+    if (!(options & LYXP_SCHEMA)) {
+        /* special kind of root that can access everything */
+        for (root = ctx_node; root->parent; root = (struct lyd_node *)root->parent);
+        for (; root->prev->next; root = root->prev);
+        *root_type = LYXP_NODE_ROOT;
+        return root;
+    }
+
+    if (ctx_node->schema->flags & LYS_CONFIG_W) {
+        *root_type = LYXP_NODE_ROOT_CONFIG;
+    } else {
+        *root_type = LYXP_NODE_ROOT;
+    }
+
+    for (root = ctx_node; root->parent; root = (struct lyd_node *)root->parent);
+    for (; root->prev->next; root = root->prev);
+
+    return root;
+}
+
+/**
+ * @brief Get the schema context root.
+ *
+ * @param[in] ctx_scnode Original schema context node.
+ * @param[in] options XPath options.
+ * @param[out] root_type Root type, doffers only for when/must evaluation.
+ * @return Context schema root.
+ */
+static const struct lysc_node *
+moveto_scnode_get_root(const struct lysc_node *ctx_scnode, int options, enum lyxp_node_type *root_type)
+{
+    const struct lysc_node *root;
+
+    assert(ctx_scnode && root_type);
+
+    if (options & LYXP_SCNODE) {
+        /* general root that can access everything */
+        *root_type = LYXP_NODE_ROOT;
+    } else if (ctx_scnode->flags & LYS_CONFIG_W) {
+        *root_type = LYXP_NODE_ROOT_CONFIG;
+    } else {
+        *root_type = LYXP_NODE_ROOT;
+    }
+
+    root = lys_getnext(NULL, NULL, ctx_scnode->module->compiled, LYS_GETNEXT_NOSTATECHECK);
+
+    return root;
+}
+
+/**
+ * @brief Move context @p set to the root. Handles absolute path.
+ *        Result is LYXP_SET_NODE_SET.
+ *
+ * @param[in,out] set Set to use.
+ * @param[in] options Xpath options.
+ */
+static void
+moveto_root(struct lyxp_set *set, int options)
+{
+    const struct lysc_node *scroot;
+    const struct lyd_node *root;
+    enum lyxp_node_type root_type;
+
+    if (!set) {
+        return;
+    }
+
+    if (options & LYXP_SCNODE_ALL) {
+        scroot = moveto_scnode_get_root(set->ctx_scnode, options, &root_type);
+        set_scnode_clear_ctx(set);
+        set_scnode_insert_node(set, scroot, root_type);
+    } else {
+        root = moveto_get_root(set->ctx_node, options, &root_type);
+        lyxp_set_cast(set, LYXP_SET_EMPTY, options);
+        if (root) {
+            set_insert_node(set, root, 0, root_type, 0);
+        }
+    }
+}
+
+/**
+ * @brief Check @p node as a part of NameTest processing.
+ *
+ * @param[in] node Node to check.
+ * @param[in] root_type XPath root node type.
+ * @param[in] node_name Node name to move to. Must be in the dictionary!
+ * @param[in] moveto_mod Expected module of the node.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+moveto_node_check(const struct lyd_node *node, enum lyxp_node_type root_type, const char *node_name,
+                  const struct lys_module *moveto_mod)
+{
+    /* module check */
+    if (moveto_mod && (node->schema->module != moveto_mod)) {
+        return LY_EINVAL;
+    }
+
+    /* context check */
+    if ((root_type == LYXP_NODE_ROOT_CONFIG) && (node->schema->flags & LYS_CONFIG_R)) {
+        return LY_EINVAL;
+    }
+
+    /* name check */
+    if (strcmp(node_name, "*") && !strcmp(node->schema->name, node_name)) {
+        return LY_EINVAL;
+    }
+
+    /* TODO when check */
+    /*if (!LYD_WHEN_DONE(node->when_status)) {
+        return LY_EINCOMPLETE;
+    }*/
+
+    /* match */
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Check @p node as a part of schema NameTest processing.
+ *
+ * @param[in] node Schema node to check.
+ * @param[in] root_type XPath root node type.
+ * @param[in] node_name Node name to move to. Must be in the dictionary!
+ * @param[in] moveto_mod Expected module of the node.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_scnode_check(const struct lysc_node *node, enum lyxp_node_type root_type, const char *node_name,
+                    const struct lys_module *moveto_mod, int options)
+{
+    struct lysc_node *parent;
+
+    /* RPC input/output check */
+    for (parent = node->parent; parent && (parent->nodetype != LYS_ACTION); parent = parent->parent);
+    if (options & LYXP_SCNODE_OUTPUT) {
+        if (parent && (node->flags & LYS_CONFIG_W)) {
+            return LY_EINVAL;
+        }
+    } else {
+        if (parent && (node->flags & LYS_CONFIG_R)) {
+            return LY_EINVAL;
+        }
+    }
+
+    /* module check */
+    if (strcmp(node_name, "*") && (node->module != moveto_mod)) {
+        return LY_EINVAL;
+    }
+
+    /* context check */
+    if ((root_type == LYXP_NODE_ROOT_CONFIG) && (node->flags & LYS_CONFIG_R)) {
+        return LY_EINVAL;
+    }
+
+    /* name check */
+    if (strcmp(node_name, "*") && !strcmp(node->name, node_name)) {
+        return LY_EINVAL;
+    }
+
+    /* match */
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to a node. Handles '/' and '*', 'NAME', 'PREFIX:*', or 'PREFIX:NAME'.
+ *        Result is LYXP_SET_NODE_SET (or LYXP_SET_EMPTY). Context position aware.
+ *
+ * @param[in,out] set Set to use.
+ * @param[in] qname Qualified node name to move to.
+ * @param[in] qname_len Length of @p qname.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+moveto_node(struct lyxp_set *set, const char *qname, uint16_t qname_len, int options)
+{
+    uint32_t i;
+    int replaced, pref_len;
+    const char *ptr, *name_dict = NULL; /* optimization - so we can do (==) instead (!strncmp(...)) in moveto_node_check() */
+    const struct lys_module *moveto_mod;
+    const struct lyd_node *sub;
+    enum lyxp_node_type root_type;
+    LY_ERR rc;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    moveto_get_root(set->ctx_node, options, &root_type);
+
+    /* prefix */
+    if ((ptr = ly_strnchr(qname, ':', qname_len))) {
+        /* specific module */
+        pref_len = ptr - qname;
+        moveto_mod = moveto_resolve_model(qname, pref_len, set->format, set->ctx, set->local_mod);
+        if (!moveto_mod) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INMOD, pref_len, qname);
+            return LY_EVALID;
+        }
+        qname += pref_len + 1;
+        qname_len -= pref_len + 1;
+    } else if ((qname[0] == '*') && (qname_len == 1)) {
+        /* all modules - special case */
+        moveto_mod = NULL;
+    } else {
+        /* local module */
+        moveto_mod = set->local_mod;
+    }
+
+    /* name */
+    name_dict = lydict_insert(set->ctx, qname, qname_len);
+
+    for (i = 0; i < set->used; ) {
+        replaced = 0;
+
+        if ((set->val.nodes[i].type == LYXP_NODE_ROOT_CONFIG) || (set->val.nodes[i].type == LYXP_NODE_ROOT)) {
+            if (set->trees) {
+                /* search in all the trees */
+                LY_ARRAY_FOR(set->trees, i) {
+                    for (sub = set->trees[i]; sub; sub = sub->next) {
+                        rc = moveto_node_check(sub, root_type, name_dict, moveto_mod);
+                        if (rc == LY_SUCCESS) {
+                            /* pos filled later */
+                            if (!replaced) {
+                                set_replace_node(set, sub, 0, LYXP_NODE_ELEM, i);
+                                replaced = 1;
+                            } else {
+                                set_insert_node(set, sub, 0, LYXP_NODE_ELEM, i);
+                            }
+                            ++i;
+                        } else if (rc == LY_EINCOMPLETE) {
+                            lydict_remove(set->ctx, name_dict);
+                            return rc;
+                        }
+                    }
+                }
+            } else {
+                /* use just the context node */
+                for (sub = set->val.nodes[i].node; sub; sub = sub->next) {
+                    rc = moveto_node_check(sub, root_type, name_dict, moveto_mod);
+                    if (rc == LY_SUCCESS) {
+                        /* pos filled later */
+                        if (!replaced) {
+                            set_replace_node(set, sub, 0, LYXP_NODE_ELEM, i);
+                            replaced = 1;
+                        } else {
+                            set_insert_node(set, sub, 0, LYXP_NODE_ELEM, i);
+                        }
+                        ++i;
+                    } else if (rc == LY_EINCOMPLETE) {
+                        lydict_remove(set->ctx, name_dict);
+                        return rc;
+                    }
+                }
+            }
+
+        /* skip nodes without children - leaves, leaflists, anyxmls, and dummy nodes (ouput root will eval to true) */
+        } else if (!(set->val.nodes[i].node->flags & LYD_DUMMY)
+                && !(set->val.nodes[i].node->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA))) {
+
+            for (sub = lyd_node_children(set->val.nodes[i].node); sub; sub = sub->next) {
+                rc = moveto_node_check(sub, root_type, name_dict, moveto_mod);
+                if (rc == LY_SUCCESS) {
+                    if (!replaced) {
+                        set_replace_node(set, sub, 0, LYXP_NODE_ELEM, i);
+                        replaced = 1;
+                    } else {
+                        set_insert_node(set, sub, 0, LYXP_NODE_ELEM, i);
+                    }
+                    ++i;
+                } else if (rc == LY_EINCOMPLETE) {
+                    lydict_remove(set->ctx, name_dict);
+                    return rc;
+                }
+            }
+        }
+
+        if (!replaced) {
+            /* no match */
+            set_remove_node(set, i);
+        }
+    }
+    lydict_remove(set->ctx, name_dict);
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to a schema node. Handles '/' and '*', 'NAME', 'PREFIX:*', or 'PREFIX:NAME'.
+ *        Result is LYXP_SET_SCNODE_SET (or LYXP_SET_EMPTY).
+ *
+ * @param[in,out] set Set to use.
+ * @param[in] qname Qualified node name to move to.
+ * @param[in] qname_len Length of @p qname.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_scnode(struct lyxp_set *set, const char *qname, uint16_t qname_len, int options)
+{
+    int i, orig_used, pref_len, idx, temp_ctx = 0;
+    uint32_t mod_idx;
+    const char *ptr, *name_dict = NULL; /* optimization - so we can do (==) instead (!strncmp(...)) in moveto_node_check() */
+    const struct lys_module *moveto_mod;
+    const struct lysc_node *sub, *start_parent;
+    enum lyxp_node_type root_type;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_SCNODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYS, set->ctx_scnode, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    moveto_scnode_get_root(set->ctx_scnode, options, &root_type);
+
+    /* prefix */
+    if ((ptr = ly_strnchr(qname, ':', qname_len))) {
+        pref_len = ptr - qname;
+        moveto_mod = moveto_resolve_model(qname, pref_len, set->format, set->ctx, set->local_mod);
+        if (!moveto_mod) {
+            LOGVAL(set->ctx, LY_VLOG_LYS, set->ctx_scnode, LY_VCODE_XP_INMOD, pref_len, qname);
+            return LY_EVALID;
+        }
+        qname += pref_len + 1;
+        qname_len -= pref_len + 1;
+    } else if ((qname[0] == '*') && (qname_len == 1)) {
+        /* all modules - special case */
+        moveto_mod = NULL;
+    } else {
+        /* local module */
+        moveto_mod = set->local_mod;
+    }
+
+    /* name */
+    name_dict = lydict_insert(set->ctx, qname, qname_len);
+
+    orig_used = set->used;
+    for (i = 0; i < orig_used; ++i) {
+        if (set->val.scnodes[i].in_ctx != 1) {
+            continue;
+        }
+        set->val.scnodes[i].in_ctx = 0;
+
+        start_parent = set->val.scnodes[i].scnode;
+
+        if ((set->val.scnodes[i].type == LYXP_NODE_ROOT_CONFIG) || (set->val.scnodes[i].type == LYXP_NODE_ROOT)) {
+            /* it can actually be in any module, it's all <running>, but we know it's moveto_mod (if set),
+             * so use it directly (root node itself is useless in this case) */
+            mod_idx = 0;
+            while (moveto_mod || (moveto_mod = (struct lys_module *)ly_ctx_get_module_iter(set->ctx, &mod_idx))) {
+                sub = NULL;
+                while ((sub = lys_getnext(sub, NULL, moveto_mod->compiled, LYS_GETNEXT_NOSTATECHECK))) {
+                    if (!moveto_scnode_check(sub, root_type, name_dict, moveto_mod, options)) {
+                        idx = set_scnode_insert_node(set, sub, LYXP_NODE_ELEM);
+                        /* we need to prevent these nodes from being considered in this moveto */
+                        if ((idx < orig_used) && (idx > i)) {
+                            set->val.scnodes[idx].in_ctx = 2;
+                            temp_ctx = 1;
+                        }
+                    }
+                }
+
+                if (!mod_idx) {
+                    /* moveto_mod was specified, we are not going through the whole context */
+                    break;
+                }
+                /* next iteration */
+                moveto_mod = NULL;
+            }
+
+        /* skip nodes without children - leaves, leaflists, and anyxmls (ouput root will eval to true) */
+        } else if (!(start_parent->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA))) {
+            sub = NULL;
+            while ((sub = lys_getnext(sub, start_parent, NULL, LYS_GETNEXT_NOSTATECHECK))) {
+                if (!moveto_scnode_check(sub, root_type, name_dict, (moveto_mod ? moveto_mod : set->local_mod), options)) {
+                    idx = set_scnode_insert_node(set, sub, LYXP_NODE_ELEM);
+                    if ((idx < orig_used) && (idx > i)) {
+                        set->val.scnodes[idx].in_ctx = 2;
+                        temp_ctx = 1;
+                    }
+                }
+            }
+        }
+    }
+    lydict_remove(set->ctx, name_dict);
+
+    /* correct temporary in_ctx values */
+    if (temp_ctx) {
+        for (i = 0; i < orig_used; ++i) {
+            if (set->val.scnodes[i].in_ctx == 2) {
+                set->val.scnodes[i].in_ctx = 1;
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to a node and all its descendants. Handles '//' and '*', 'NAME',
+ *        'PREFIX:*', or 'PREFIX:NAME'. Result is LYXP_SET_NODE_SET (or LYXP_SET_EMPTY).
+ *        Context position aware.
+ *
+ * @param[in] set Set to use.
+ * @param[in] qname Qualified node name to move to.
+ * @param[in] qname_len Length of @p qname.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+moveto_node_alldesc(struct lyxp_set *set, const char *qname, uint16_t qname_len, int options)
+{
+    uint32_t i;
+    int pref_len, all = 0, match;
+    const struct lyd_node *next, *elem, *start;
+    const struct lys_module *moveto_mod;
+    enum lyxp_node_type root_type;
+    struct lyxp_set ret_set;
+    LY_ERR rc;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    moveto_get_root(set->ctx_node, options, &root_type);
+
+    /* prefix */
+    if (ly_strnchr(qname, ':', qname_len)) {
+        pref_len = ly_strnchr(qname, ':', qname_len) - qname;
+        moveto_mod = moveto_resolve_model(qname, pref_len, set->format, set->ctx, set->local_mod);
+        if (!moveto_mod) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INMOD, pref_len, qname);
+            return LY_EVALID;
+        }
+        qname += pref_len + 1;
+        qname_len -= pref_len + 1;
+    } else {
+        moveto_mod = NULL;
+    }
+
+    /* replace the original nodes (and throws away all text and attr nodes, root is replaced by a child) */
+    rc = moveto_node(set, "*", 1, options);
+    LY_CHECK_RET(rc);
+
+    if ((qname_len == 1) && (qname[0] == '*')) {
+        all = 1;
+    }
+
+    /* this loop traverses all the nodes in the set and addds/keeps only
+     * those that match qname */
+    set_init(&ret_set, set);
+    for (i = 0; i < set->used; ++i) {
+
+        /* TREE DFS */
+        start = set->val.nodes[i].node;
+        for (elem = next = start; elem; elem = next) {
+
+            /* TODO when check */
+            /*if (!LYD_WHEN_DONE(elem->when_status)) {
+                return LY_EINCOMPLETE;
+            }*/
+
+            /* dummy and context check */
+            if ((elem->flags & LYD_DUMMY) || ((root_type == LYXP_NODE_ROOT_CONFIG) && (elem->schema->flags & LYS_CONFIG_R))) {
+                goto skip_children;
+            }
+
+            match = 1;
+
+            /* module check */
+            if (!all) {
+                if (moveto_mod && (elem->schema->module != moveto_mod)) {
+                    match = 0;
+                } else if (!moveto_mod && (elem->schema->module != set->ctx_node->schema->module)) {
+                    match = 0;
+                }
+            }
+
+            /* name check */
+            if (match && !all && (strncmp(elem->schema->name, qname, qname_len) || elem->schema->name[qname_len])) {
+                match = 0;
+            }
+
+            if (match) {
+                /* add matching node into result set */
+                set_insert_node(&ret_set, elem, 0, LYXP_NODE_ELEM, ret_set.used);
+                if (set_dup_node_check(set, elem, LYXP_NODE_ELEM, i)) {
+                    /* the node is a duplicate, we'll process it later in the set */
+                    goto skip_children;
+                }
+            }
+
+            /* TREE DFS NEXT ELEM */
+            /* select element for the next run - children first */
+            if (elem->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)) {
+                next = NULL;
+            } else {
+                next = lyd_node_children(elem);
+            }
+            if (!next) {
+skip_children:
+                /* no children, so try siblings, but only if it's not the start,
+                 * that is considered to be the root and it's siblings are not traversed */
+                if (elem != start) {
+                    next = elem->next;
+                } else {
+                    break;
+                }
+            }
+            while (!next) {
+                /* no siblings, go back through the parents */
+                if ((struct lyd_node *)elem->parent == start) {
+                    /* we are done, no next element to process */
+                    break;
+                }
+                /* parent is already processed, go to its sibling */
+                elem = (struct lyd_node *)elem->parent;
+                next = elem->next;
+            }
+        }
+    }
+
+    /* make the temporary set the current one */
+    ret_set.ctx_pos = set->ctx_pos;
+    ret_set.ctx_size = set->ctx_size;
+    set_free_content(set);
+    memcpy(set, &ret_set, sizeof *set);
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to a schema node and all its descendants. Handles '//' and '*', 'NAME',
+ *        'PREFIX:*', or 'PREFIX:NAME'. Result is LYXP_SET_NODE_SET (or LYXP_SET_EMPTY).
+ *
+ * @param[in] set Set to use.
+ * @param[in] qname Qualified node name to move to.
+ * @param[in] qname_len Length of @p qname.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_scnode_alldesc(struct lyxp_set *set, const char *qname, uint16_t qname_len, int options)
+{
+    int i, orig_used, pref_len, all = 0, match, idx;
+    const struct lysc_node *next, *elem, *start;
+    const struct lys_module *moveto_mod;
+    enum lyxp_node_type root_type;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_SCNODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYS, set->ctx_scnode, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    moveto_scnode_get_root(set->ctx_scnode, options, &root_type);
+
+    /* prefix */
+    if (ly_strnchr(qname, ':', qname_len)) {
+        pref_len = ly_strnchr(qname, ':', qname_len) - qname;
+        moveto_mod = moveto_resolve_model(qname, pref_len, set->format, set->ctx, set->local_mod);
+        if (!moveto_mod) {
+            LOGVAL(set->ctx, LY_VLOG_LYS, set->ctx_scnode, LY_VCODE_XP_INMOD, pref_len, qname);
+            return LY_EVALID;
+        }
+        qname += pref_len + 1;
+        qname_len -= pref_len + 1;
+    } else {
+        moveto_mod = NULL;
+    }
+
+    if ((qname_len == 1) && (qname[0] == '*')) {
+        all = 1;
+    }
+
+    orig_used = set->used;
+    for (i = 0; i < orig_used; ++i) {
+        if (set->val.scnodes[i].in_ctx != 1) {
+            continue;
+        }
+        set->val.scnodes[i].in_ctx = 0;
+
+        /* TREE DFS */
+        start = set->val.scnodes[i].scnode;
+        for (elem = next = start; elem; elem = next) {
+
+            /* context/nodetype check */
+            if ((root_type == LYXP_NODE_ROOT_CONFIG) && (elem->flags & LYS_CONFIG_R)) {
+                /* valid node, but it is hidden in this context */
+                goto skip_children;
+            }
+            switch (elem->nodetype) {
+            case LYS_USES:
+            case LYS_CHOICE:
+            case LYS_CASE:
+                /* schema-only nodes */
+                goto next_iter;
+            default:
+                break;
+            }
+
+            match = 1;
+
+            /* skip root */
+            if (elem == start) {
+                match = 0;
+            }
+
+            /* module check */
+            if (match && !all) {
+                if (moveto_mod && (elem->module != moveto_mod)) {
+                    match = 0;
+                } else if (!moveto_mod && (elem->module != set->ctx_scnode->module)) {
+                    match = 0;
+                }
+            }
+
+            /* name check */
+            if (match && !all && (strncmp(elem->name, qname, qname_len) || elem->name[qname_len])) {
+                match = 0;
+            }
+
+            if (match) {
+                if ((idx = set_scnode_dup_node_check(set, elem, LYXP_NODE_ELEM, i)) > -1) {
+                    set->val.scnodes[idx].in_ctx = 1;
+                    if (idx > i) {
+                        /* we will process it later in the set */
+                        goto skip_children;
+                    }
+                } else {
+                    set_scnode_insert_node(set, elem, LYXP_NODE_ELEM);
+                }
+            }
+
+next_iter:
+            /* TREE DFS NEXT ELEM */
+            /* select element for the next run - children first */
+            next = lysc_node_children(elem, options & LYXP_SCNODE_OUTPUT ? LYS_CONFIG_R : LYS_CONFIG_W);
+            if (elem->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)) {
+                next = NULL;
+            }
+            if (!next) {
+skip_children:
+                /* no children, so try siblings, but only if it's not the start,
+                 * that is considered to be the root and it's siblings are not traversed */
+                if (elem != start) {
+                    next = elem->next;
+                } else {
+                    break;
+                }
+            }
+            while (!next) {
+                /* no siblings, go back through the parents */
+                if (elem->parent == start) {
+                    /* we are done, no next element to process */
+                    break;
+                }
+                /* parent is already processed, go to its sibling */
+                elem = elem->parent;
+                next = elem->next;
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to an attribute. Handles '/' and '@*', '@NAME', '@PREFIX:*',
+ *        or '@PREFIX:NAME'. Result is LYXP_SET_NODE_SET (or LYXP_SET_EMPTY).
+ *        Indirectly context position aware.
+ *
+ * @param[in,out] set Set to use.
+ * @param[in] qname Qualified node name to move to.
+ * @param[in] qname_len Length of @p qname.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_attr(struct lyxp_set *set, const char *qname, uint16_t qname_len, int UNUSED(options))
+{
+    uint32_t i;
+    int replaced, all = 0, pref_len;
+    struct lys_module *moveto_mod;
+    struct lyd_attr *sub;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    /* prefix */
+    if (ly_strnchr(qname, ':', qname_len)) {
+        pref_len = ly_strnchr(qname, ':', qname_len) - qname;
+        moveto_mod = moveto_resolve_model(qname, pref_len, set->format, set->ctx, set->local_mod);
+        if (!moveto_mod) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INMOD, pref_len, qname);
+            return LY_EVALID;
+        }
+        qname += pref_len + 1;
+        qname_len -= pref_len + 1;
+    } else {
+        moveto_mod = NULL;
+    }
+
+    if ((qname_len == 1) && (qname[0] == '*')) {
+        all = 1;
+    }
+
+    for (i = 0; i < set->used; ) {
+        replaced = 0;
+
+        /* only attributes of an elem (not dummy) can be in the result, skip all the rest;
+         * our attributes are always qualified */
+        if ((set->val.nodes[i].type == LYXP_NODE_ELEM) && !(set->val.nodes[i].node->flags & LYD_DUMMY)) {
+            for (sub = set->val.nodes[i].node->attr; sub; sub = sub->next) {
+
+                /* check "namespace" */
+                if (moveto_mod && (sub->annotation->module != moveto_mod)) {
+                    continue;
+                }
+
+                if (all || (!strncmp(sub->name, qname, qname_len) && !sub->name[qname_len])) {
+                    /* match */
+                    if (!replaced) {
+                        set->val.attrs[i].attr = sub;
+                        set->val.attrs[i].type = LYXP_NODE_ATTR;
+                        /* pos does not change */
+                        replaced = 1;
+                    } else {
+                        set_insert_node(set, (struct lyd_node *)sub, set->val.nodes[i].pos, LYXP_NODE_ATTR, i + 1);
+                    }
+                    ++i;
+                }
+            }
+        }
+
+        if (!replaced) {
+            /* no match */
+            set_remove_node(set, i);
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set1 to union with @p set2. @p set2 is emptied afterwards.
+ *        Result is LYXP_SET_NODE_SET (or LYXP_SET_EMPTY). Context position aware.
+ *
+ * @param[in,out] set1 Set to use for the result.
+ * @param[in] set2 Set that is copied to @p set1.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_union(struct lyxp_set *set1, struct lyxp_set *set2, int options)
+{
+    LY_ERR rc;
+
+    if (((set1->type != LYXP_SET_NODE_SET) && (set1->type != LYXP_SET_EMPTY))
+            || ((set2->type != LYXP_SET_NODE_SET) && (set2->type != LYXP_SET_EMPTY))) {
+        LOGVAL(set1->ctx, LY_VLOG_LYD, set1->ctx_node, LY_VCODE_XP_INOP_2, "union", print_set_type(set1), print_set_type(set2));
+        return LY_EVALID;
+    }
+
+    /* set2 is empty or both set1 and set2 */
+    if (set2->type == LYXP_SET_EMPTY) {
+        return LY_SUCCESS;
+    }
+
+    if (set1->type == LYXP_SET_EMPTY) {
+        memcpy(set1, set2, sizeof *set1);
+        /* dynamic memory belongs to set1 now, do not free */
+        set2->type = LYXP_SET_EMPTY;
+        return LY_SUCCESS;
+    }
+
+    /* we assume sets are sorted */
+    assert(!set_sort(set1, options) && !set_sort(set2, options));
+
+    /* sort, remove duplicates */
+    rc = set_sorted_merge(set1, set2, options);
+    LY_CHECK_RET(rc);
+
+    /* final set must be sorted */
+    assert(!set_sort(set1, options));
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to an attribute in any of the descendants. Handles '//' and '@*',
+ *        '@NAME', '@PREFIX:*', or '@PREFIX:NAME'. Result is LYXP_SET_NODE_SET (or LYXP_SET_EMPTY).
+ *        Context position aware.
+ *
+ * @param[in,out] set Set to use.
+ * @param[in] qname Qualified node name to move to.
+ * @param[in] qname_len Length of @p qname.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static int
+moveto_attr_alldesc(struct lyxp_set *set, const char *qname, uint16_t qname_len, int options)
+{
+    uint32_t i;
+    int pref_len, replaced, all = 0;
+    struct lyd_attr *sub;
+    struct lys_module *moveto_mod;
+    struct lyxp_set *set_all_desc = NULL;
+    LY_ERR rc;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    /* prefix */
+    if (ly_strnchr(qname, ':', qname_len)) {
+        pref_len = ly_strnchr(qname, ':', qname_len) - qname;
+        moveto_mod = moveto_resolve_model(qname, pref_len, set->format, set->ctx, set->local_mod);
+        if (!moveto_mod) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INMOD, pref_len, qname);
+            return LY_EVALID;
+        }
+        qname += pref_len + 1;
+        qname_len -= pref_len + 1;
+    } else {
+        moveto_mod = NULL;
+    }
+
+    /* can be optimized similarly to moveto_node_alldesc() and save considerable amount of memory,
+     * but it likely won't be used much, so it's a waste of time */
+    /* copy the context */
+    set_all_desc = set_copy(set);
+    /* get all descendant nodes (the original context nodes are removed) */
+    rc = moveto_node_alldesc(set_all_desc, "*", 1, options);
+    if (rc != LY_SUCCESS) {
+        lyxp_set_free(set_all_desc);
+        return rc;
+    }
+    /* prepend the original context nodes */
+    rc =  moveto_union(set, set_all_desc, options);
+    if (rc != LY_SUCCESS) {
+        lyxp_set_free(set_all_desc);
+        return rc;
+    }
+    lyxp_set_free(set_all_desc);
+
+    if ((qname_len == 1) && (qname[0] == '*')) {
+        all = 1;
+    }
+
+    for (i = 0; i < set->used; ) {
+        replaced = 0;
+
+        /* only attributes of an elem can be in the result, skip all the rest,
+         * we have all attributes qualified in lyd tree */
+        if (set->val.nodes[i].type == LYXP_NODE_ELEM) {
+            for (sub = set->val.nodes[i].node->attr; sub; sub = sub->next) {
+                /* check "namespace" */
+                if (moveto_mod && (sub->annotation->module != moveto_mod)) {
+                    continue;
+                }
+
+                if (all || (!strncmp(sub->name, qname, qname_len) && !sub->name[qname_len])) {
+                    /* match */
+                    if (!replaced) {
+                        set->val.attrs[i].attr = sub;
+                        set->val.attrs[i].type = LYXP_NODE_ATTR;
+                        /* pos does not change */
+                        replaced = 1;
+                    } else {
+                        set_insert_node(set, (struct lyd_node *)sub, set->val.attrs[i].pos, LYXP_NODE_ATTR, i + 1);
+                    }
+                    ++i;
+                }
+            }
+        }
+
+        if (!replaced) {
+            /* no match */
+            set_remove_node(set, i);
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to self and al chilren, recursively. Handles '/' or '//' and '.'. Result is LYXP_SET_NODE_SET
+ *        (or LYXP_SET_EMPTY). Context position aware.
+ *
+ * @param[in] parent Current parent.
+ * @param[in] parent_pos Position of @p parent.
+ * @param[in] parent_type Node type of @p parent.
+ * @param[in,out] to_set Set to use.
+ * @param[in] dup_check_set Set for checking duplicities.
+ * @param[in] root_type Node type of root.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+moveto_self_add_children_r(const struct lyd_node *parent, uint32_t parent_pos, enum lyxp_node_type parent_type,
+                           struct lyxp_set *to_set, const struct lyxp_set *dup_check_set, enum lyxp_node_type root_type,
+                           int options)
+{
+    const struct lyd_node *sub;
+    LY_ERR rc;
+
+    switch (parent_type) {
+    case LYXP_NODE_ROOT:
+    case LYXP_NODE_ROOT_CONFIG:
+        /* add the same node but as an element */
+        if (!set_dup_node_check(dup_check_set, parent, LYXP_NODE_ELEM, -1)) {
+            set_insert_node(to_set, parent, 0, LYXP_NODE_ELEM, to_set->used);
+
+            /* skip anydata/anyxml and dummy nodes */
+            if (!(parent->schema->nodetype & LYS_ANYDATA) && !(parent->flags & LYD_DUMMY)) {
+                /* also add all the children of this node, recursively */
+                rc = moveto_self_add_children_r(parent, 0, LYXP_NODE_ELEM, to_set, dup_check_set, root_type, options);
+                LY_CHECK_RET(rc);
+            }
+        }
+        break;
+    case LYXP_NODE_ELEM:
+        /* add all the children ... */
+        if (!(parent->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA))) {
+            for (sub = lyd_node_children(parent); sub; sub = sub->next) {
+                /* context check */
+                if ((root_type == LYXP_NODE_ROOT_CONFIG) && (sub->schema->flags & LYS_CONFIG_R)) {
+                    continue;
+                }
+
+                /* TODO when check */
+                /*if (!LYD_WHEN_DONE(sub->when_status)) {
+                    return LY_EINCOMPLETE;
+                }*/
+
+                if (!set_dup_node_check(dup_check_set, sub, LYXP_NODE_ELEM, -1)) {
+                    set_insert_node(to_set, sub, 0, LYXP_NODE_ELEM, to_set->used);
+
+                    /* skip anydata/anyxml and dummy nodes */
+                    if ((sub->schema->nodetype & LYS_ANYDATA) || (sub->flags & LYD_DUMMY)) {
+                        continue;
+                    }
+
+                    /* also add all the children of this node, recursively */
+                    rc = moveto_self_add_children_r(sub, 0, LYXP_NODE_ELEM, to_set, dup_check_set, root_type, options);
+                    LY_CHECK_RET(rc);
+                }
+            }
+
+        /* ... or add their text node, ... */
+        } else {
+            if (!set_dup_node_check(dup_check_set, parent, LYXP_NODE_TEXT, -1)) {
+                set_insert_node(to_set, parent, parent_pos, LYXP_NODE_TEXT, to_set->used);
+            }
+        }
+        break;
+    default:
+        LOGINT_RET(parent->schema->module->ctx);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to self. Handles '/' or '//' and '.'. Result is LYXP_SET_NODE_SET
+ *        (or LYXP_SET_EMPTY). Context position aware.
+ *
+ * @param[in,out] set Set to use.
+ * @param[in] all_desc Whether to go to all descendants ('//') or not ('/').
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+moveto_self(struct lyxp_set *set, int all_desc, int options)
+{
+    uint32_t i;
+    enum lyxp_node_type root_type;
+    struct lyxp_set ret_set;
+    LY_ERR rc;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    /* nothing to do */
+    if (!all_desc) {
+        return LY_SUCCESS;
+    }
+
+    moveto_get_root(set->ctx_node, options, &root_type);
+
+    /* add all the children, they get added recursively */
+    set_init(&ret_set, set);
+    for (i = 0; i < set->used; ++i) {
+        /* copy the current node to tmp */
+        set_insert_node(&ret_set, set->val.nodes[i].node, set->val.nodes[i].pos, set->val.nodes[i].type, ret_set.used);
+
+        /* do not touch attributes and text nodes */
+        if ((set->val.nodes[i].type == LYXP_NODE_TEXT) || (set->val.nodes[i].type == LYXP_NODE_ATTR)) {
+            continue;
+        }
+
+        /* skip anydata/anyxml and dummy nodes */
+        if ((set->val.nodes[i].node->schema->nodetype & LYS_ANYDATA) || (set->val.nodes[i].node->flags & LYD_DUMMY)) {
+            continue;
+        }
+
+        /* add all the children */
+        rc = moveto_self_add_children_r(set->val.nodes[i].node, set->val.nodes[i].pos, set->val.nodes[i].type, &ret_set,
+                                        set, root_type, options);
+        if (rc != LY_SUCCESS) {
+            set_free_content(&ret_set);
+            return rc;
+        }
+    }
+
+    /* use the temporary set as the current one */
+    ret_set.ctx_pos = set->ctx_pos;
+    ret_set.ctx_size = set->ctx_size;
+    set_free_content(set);
+    memcpy(set, &ret_set, sizeof *set);
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context schema @p set to self. Handles '/' or '//' and '.'. Result is LYXP_SET_SCNODE_SET
+ *        (or LYXP_SET_EMPTY).
+ *
+ * @param[in,out] set Set to use.
+ * @param[in] all_desc Whether to go to all descendants ('//') or not ('/').
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_scnode_self(struct lyxp_set *set, int all_desc, int options)
+{
+    const struct lysc_node *sub;
+    uint32_t i;
+    enum lyxp_node_type root_type;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_SCNODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYS, set->ctx_scnode, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    /* nothing to do */
+    if (!all_desc) {
+        return LY_SUCCESS;
+    }
+
+    moveto_scnode_get_root(set->ctx_scnode, options, &root_type);
+
+    /* add all the children, they get added recursively */
+    for (i = 0; i < set->used; ++i) {
+        if (set->val.scnodes[i].in_ctx != 1) {
+            continue;
+        }
+
+        /* add all the children */
+        if (set->val.scnodes[i].scnode->nodetype & (LYS_LIST | LYS_CONTAINER)) {
+            sub = NULL;
+            while ((sub = lys_getnext(sub, set->val.scnodes[i].scnode, NULL, LYS_GETNEXT_NOSTATECHECK))) {
+                /* RPC input/output check */
+                if (options & LYXP_SCNODE_OUTPUT) {
+                    if (sub->parent->nodetype == LYS_INPUT) {
+                        continue;
+                    }
+                } else {
+                    if (sub->parent->nodetype == LYS_OUTPUT) {
+                        continue;
+                    }
+                }
+
+                /* context check */
+                if ((root_type == LYXP_NODE_ROOT_CONFIG) && (sub->flags & LYS_CONFIG_R)) {
+                    continue;
+                }
+
+                set_scnode_insert_node(set, sub, LYXP_NODE_ELEM);
+                /* throw away the insert index, we want to consider that node again, recursively */
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to parent. Handles '/' or '//' and '..'. Result is LYXP_SET_NODE_SET
+ *        (or LYXP_SET_EMPTY). Context position aware.
+ *
+ * @param[in] set Set to use.
+ * @param[in] all_desc Whether to go to all descendants ('//') or not ('/').
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+moveto_parent(struct lyxp_set *set, int all_desc, int options)
+{
+    LY_ERR rc;
+    uint32_t i;
+    struct lyd_node *node, *new_node;
+    const struct lyd_node *root;
+    enum lyxp_node_type root_type, new_type;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_NODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    if (all_desc) {
+        /* <path>//.. == <path>//./.. */
+        rc = moveto_self(set, 1, options);
+        LY_CHECK_RET(rc);
+    }
+
+    root = moveto_get_root(set->ctx_node, options, &root_type);
+
+    for (i = 0; i < set->used; ) {
+        node = set->val.nodes[i].node;
+
+        if (set->val.nodes[i].type == LYXP_NODE_ELEM) {
+            new_node = (struct lyd_node *)node->parent;
+        } else if (set->val.nodes[i].type == LYXP_NODE_TEXT) {
+            new_node = node;
+        } else if (set->val.nodes[i].type == LYXP_NODE_ATTR) {
+            new_node = set->val.attrs[i].attr->parent;
+            if (!new_node) {
+                LOGINT_RET(set->ctx);
+            }
+        } else {
+            /* root does not have a parent */
+            set_remove_node(set, i);
+            continue;
+        }
+
+        /* TODO when check */
+        /*if (new_node && !LYD_WHEN_DONE(new_node->when_status)) {
+            return LY_EINCOMPLETE;
+        }*/
+
+        /* node already there can also be the root */
+        if (root == node) {
+            if (options && (set->ctx_node->schema->flags & LYS_CONFIG_W)) {
+                new_type = LYXP_NODE_ROOT_CONFIG;
+            } else {
+                new_type = LYXP_NODE_ROOT;
+            }
+            new_node = node;
+
+        /* node has no parent */
+        } else if (!new_node) {
+            if (options && (set->ctx_node->schema->flags & LYS_CONFIG_W)) {
+                new_type = LYXP_NODE_ROOT_CONFIG;
+            } else {
+                new_type = LYXP_NODE_ROOT;
+            }
+#ifndef NDEBUG
+            for (; node->prev->next; node = node->prev);
+            if (node != root) {
+                LOGINT(set->ctx);
+            }
+#endif
+            new_node = (struct lyd_node *)root;
+
+        /* node has a standard parent (it can equal the root, it's not the root yet since they are fake) */
+        } else {
+            new_type = LYXP_NODE_ELEM;
+        }
+
+        assert((new_type == LYXP_NODE_ELEM) || ((new_type == root_type) && (new_node == root)));
+
+        if (set_dup_node_check(set, new_node, new_type, -1)) {
+            set_remove_node(set, i);
+        } else {
+            set_replace_node(set, new_node, 0, new_type, i);
+            ++i;
+        }
+    }
+
+    assert(!set_sort(set, options) && !set_sorted_dup_node_clean(set));
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context schema @p set to parent. Handles '/' or '//' and '..'. Result is LYXP_SET_SCNODE_SET
+ *        (or LYXP_SET_EMPTY).
+ *
+ * @param[in] set Set to use.
+ * @param[in] all_desc Whether to go to all descendants ('//') or not ('/').
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_scnode_parent(struct lyxp_set *set, int all_desc, int options)
+{
+    int idx, i, orig_used, temp_ctx = 0;
+    const struct lysc_node *root, *node, *new_node;
+    enum lyxp_node_type root_type, new_type;
+    LY_ERR rc;
+
+    if (!set || (set->type == LYXP_SET_EMPTY)) {
+        return LY_SUCCESS;
+    }
+
+    if (set->type != LYXP_SET_SCNODE_SET) {
+        LOGVAL(set->ctx, LY_VLOG_LYS, set->ctx_scnode, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        return LY_EVALID;
+    }
+
+    if (all_desc) {
+        /* <path>//.. == <path>//./.. */
+        rc = moveto_scnode_self(set, 1, options);
+        LY_CHECK_RET(rc);
+    }
+
+    root = moveto_scnode_get_root(set->ctx_scnode, options, &root_type);
+
+    orig_used = set->used;
+    for (i = 0; i < orig_used; ++i) {
+        if (set->val.scnodes[i].in_ctx != 1) {
+            continue;
+        }
+        set->val.scnodes[i].in_ctx = 0;
+
+        node = set->val.scnodes[i].scnode;
+
+        if (set->val.scnodes[i].type == LYXP_NODE_ELEM) {
+            for (new_node = node->parent;
+                 new_node && (new_node->nodetype & (LYS_CHOICE | LYS_CASE));
+                 new_node = new_node->parent);
+        } else {
+            /* root does not have a parent */
+            continue;
+        }
+
+        /* node already there can also be the root */
+        if (root == node) {
+            if ((options & LYXP_SCNODE_SCHEMA) && (set->ctx_scnode->flags & LYS_CONFIG_W)) {
+                new_type = LYXP_NODE_ROOT_CONFIG;
+            } else {
+                new_type = LYXP_NODE_ROOT;
+            }
+            new_node = node;
+
+        /* node has no parent */
+        } else if (!new_node) {
+            if ((options & LYXP_SCNODE_SCHEMA) && (set->ctx_scnode->flags & LYS_CONFIG_W)) {
+                new_type = LYXP_NODE_ROOT_CONFIG;
+            } else {
+                new_type = LYXP_NODE_ROOT;
+            }
+#ifndef NDEBUG
+            node = lys_getnext(NULL, NULL, node->module->compiled, LYS_GETNEXT_NOSTATECHECK);
+            if (node != root) {
+                LOGINT(set->ctx);
+            }
+#endif
+            new_node = root;
+
+        /* node has a standard parent (it can equal the root, it's not the root yet since they are fake) */
+        } else {
+            new_type = LYXP_NODE_ELEM;
+        }
+
+        assert((new_type == LYXP_NODE_ELEM) || ((new_type == root_type) && (new_node == root)));
+
+        idx = set_scnode_insert_node(set, new_node, new_type);
+        if ((idx < orig_used) && (idx > i)) {
+            set->val.scnodes[idx].in_ctx = 2;
+            temp_ctx = 1;
+        }
+    }
+
+    if (temp_ctx) {
+        for (i = 0; i < orig_used; ++i) {
+            if (set->val.scnodes[i].in_ctx == 2) {
+                set->val.scnodes[i].in_ctx = 1;
+            }
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to the result of a comparison. Handles '=', '!=', '<=', '<', '>=', or '>'.
+ *        Result is LYXP_SET_BOOLEAN. Indirectly context position aware.
+ *
+ * @param[in,out] set1 Set to use for the result.
+ * @param[in] set2 Set acting as the second operand for @p op.
+ * @param[in] op Comparison operator to process.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_op_comp(struct lyxp_set *set1, struct lyxp_set *set2, const char *op, int options)
+{
+    /*
+     * NODE SET + NODE SET = NODE SET + STRING /(1 NODE SET) 2 STRING
+     * NODE SET + STRING = STRING + STRING     /1 STRING (2 STRING)
+     * NODE SET + NUMBER = NUMBER + NUMBER     /1 NUMBER (2 NUMBER)
+     * NODE SET + BOOLEAN = BOOLEAN + BOOLEAN  /1 BOOLEAN (2 BOOLEAN)
+     * STRING + NODE SET = STRING + STRING     /(1 STRING) 2 STRING
+     * NUMBER + NODE SET = NUMBER + NUMBER     /(1 NUMBER) 2 NUMBER
+     * BOOLEAN + NODE SET = BOOLEAN + BOOLEAN  /(1 BOOLEAN) 2 BOOLEAN
+     *
+     * '=' or '!='
+     * BOOLEAN + BOOLEAN
+     * BOOLEAN + STRING = BOOLEAN + BOOLEAN    /(1 BOOLEAN) 2 BOOLEAN
+     * BOOLEAN + NUMBER = BOOLEAN + BOOLEAN    /(1 BOOLEAN) 2 BOOLEAN
+     * STRING + BOOLEAN = BOOLEAN + BOOLEAN    /1 BOOLEAN (2 BOOLEAN)
+     * NUMBER + BOOLEAN = BOOLEAN + BOOLEAN    /1 BOOLEAN (2 BOOLEAN)
+     * NUMBER + NUMBER
+     * NUMBER + STRING = NUMBER + NUMBER       /(1 NUMBER) 2 NUMBER
+     * STRING + NUMBER = NUMBER + NUMBER       /1 NUMBER (2 NUMBER)
+     * STRING + STRING
+     *
+     * '<=', '<', '>=', '>'
+     * NUMBER + NUMBER
+     * BOOLEAN + BOOLEAN = NUMBER + NUMBER     /1 NUMBER, 2 NUMBER
+     * BOOLEAN + NUMBER = NUMBER + NUMBER      /1 NUMBER (2 NUMBER)
+     * BOOLEAN + STRING = NUMBER + NUMBER      /1 NUMBER, 2 NUMBER
+     * NUMBER + STRING = NUMBER + NUMBER       /(1 NUMBER) 2 NUMBER
+     * STRING + STRING = NUMBER + NUMBER       /1 NUMBER, 2 NUMBER
+     * STRING + NUMBER = NUMBER + NUMBER       /1 NUMBER (2 NUMBER)
+     * NUMBER + BOOLEAN = NUMBER + NUMBER      /(1 NUMBER) 2 NUMBER
+     * STRING + BOOLEAN = NUMBER + NUMBER      /(1 NUMBER) 2 NUMBER
+     */
+    struct lyxp_set iter1, iter2;
+    int result;
+    int64_t i;
+    LY_ERR rc;
+
+    iter1.type = LYXP_SET_EMPTY;
+
+    /* empty node-sets are always false */
+    if ((set1->type == LYXP_SET_EMPTY) || (set2->type == LYXP_SET_EMPTY)) {
+        set_fill_boolean(set1, 0);
+        return LY_SUCCESS;
+    }
+
+    /* iterative evaluation with node-sets */
+    if ((set1->type == LYXP_SET_NODE_SET) || (set2->type == LYXP_SET_NODE_SET)) {
+        if (set1->type == LYXP_SET_NODE_SET) {
+            for (i = 0; i < set1->used; ++i) {
+                switch (set2->type) {
+                case LYXP_SET_NUMBER:
+                    rc = set_comp_cast(&iter1, set1, LYXP_SET_NUMBER, i, options);
+                    break;
+                case LYXP_SET_BOOLEAN:
+                    rc = set_comp_cast(&iter1, set1, LYXP_SET_BOOLEAN, i, options);
+                    break;
+                default:
+                    rc = set_comp_cast(&iter1, set1, LYXP_SET_STRING, i, options);
+                    break;
+                }
+                LY_CHECK_RET(rc);
+
+                rc = moveto_op_comp(&iter1, set2, op, options);
+                if (rc != LY_SUCCESS) {
+                    set_free_content(&iter1);
+                    return rc;
+                }
+
+                /* lazy evaluation until true */
+                if (iter1.val.bool) {
+                    set_fill_boolean(set1, 1);
+                    return LY_SUCCESS;
+                }
+            }
+        } else {
+            for (i = 0; i < set2->used; ++i) {
+                switch (set1->type) {
+                    case LYXP_SET_NUMBER:
+                        rc = set_comp_cast(&iter2, set2, LYXP_SET_NUMBER, i, options);
+                        break;
+                    case LYXP_SET_BOOLEAN:
+                        rc = set_comp_cast(&iter2, set2, LYXP_SET_BOOLEAN, i, options);
+                        break;
+                    default:
+                        rc = set_comp_cast(&iter2, set2, LYXP_SET_STRING, i, options);
+                        break;
+                }
+                LY_CHECK_RET(rc);
+
+                set_fill_set(&iter1, set1);
+
+                rc = moveto_op_comp(&iter1, &iter2, op, options);
+                if (rc != LY_SUCCESS) {
+                    set_free_content(&iter1);
+                    set_free_content(&iter2);
+                    return rc;
+                }
+                set_free_content(&iter2);
+
+                /* lazy evaluation until true */
+                if (iter1.val.bool) {
+                    set_fill_boolean(set1, 1);
+                    return LY_SUCCESS;
+                }
+            }
+        }
+
+        /* false for all nodes */
+        set_fill_boolean(set1, 0);
+        return LY_SUCCESS;
+    }
+
+    /* first convert properly */
+    if ((op[0] == '=') || (op[0] == '!')) {
+        if ((set1->type == LYXP_SET_BOOLEAN) || (set2->type == LYXP_SET_BOOLEAN)) {
+            lyxp_set_cast(set1, LYXP_SET_BOOLEAN, options);
+            lyxp_set_cast(set2, LYXP_SET_BOOLEAN, options);
+        } else if ((set1->type == LYXP_SET_NUMBER) || (set2->type == LYXP_SET_NUMBER)) {
+            rc = lyxp_set_cast(set1, LYXP_SET_NUMBER, options);
+            LY_CHECK_RET(rc);
+            rc = lyxp_set_cast(set2, LYXP_SET_NUMBER, options);
+            LY_CHECK_RET(rc);
+        } /* else we have 2 strings */
+    } else {
+        rc = lyxp_set_cast(set1, LYXP_SET_NUMBER, options);
+        LY_CHECK_RET(rc);
+        rc = lyxp_set_cast(set2, LYXP_SET_NUMBER, options);
+        LY_CHECK_RET(rc);
+    }
+
+    assert(set1->type == set2->type);
+
+    /* compute result */
+    if (op[0] == '=') {
+        if (set1->type == LYXP_SET_BOOLEAN) {
+            result = (set1->val.bool == set2->val.bool);
+        } else if (set1->type == LYXP_SET_NUMBER) {
+            result = (set1->val.num == set2->val.num);
+        } else {
+            assert(set1->type == LYXP_SET_STRING);
+            result = strcmp(set1->val.str, set2->val.str);
+        }
+    } else if (op[0] == '!') {
+        if (set1->type == LYXP_SET_BOOLEAN) {
+            result = (set1->val.bool != set2->val.bool);
+        } else if (set1->type == LYXP_SET_NUMBER) {
+            result = (set1->val.num != set2->val.num);
+        } else {
+            assert(set1->type == LYXP_SET_STRING);
+            result = strcmp(set1->val.str, set2->val.str);
+        }
+    } else {
+        assert(set1->type == LYXP_SET_NUMBER);
+        if (op[0] == '<') {
+            if (op[1] == '=') {
+                result = (set1->val.num <= set2->val.num);
+            } else {
+                result = (set1->val.num < set2->val.num);
+            }
+        } else {
+            if (op[1] == '=') {
+                result = (set1->val.num >= set2->val.num);
+            } else {
+                result = (set1->val.num > set2->val.num);
+            }
+        }
+    }
+
+    /* assign result */
+    if (result) {
+        set_fill_boolean(set1, 1);
+    } else {
+        set_fill_boolean(set1, 0);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Move context @p set to the result of a basic operation. Handles '+', '-', unary '-', '*', 'div',
+ *        or 'mod'. Result is LYXP_SET_NUMBER. Indirectly context position aware.
+ *
+ * @param[in,out] set1 Set to use for the result.
+ * @param[in] set2 Set acting as the second operand for @p op.
+ * @param[in] op Operator to process.
+ * @param[in] options XPath options.
+ * @return LY_ERR
+ */
+static LY_ERR
+moveto_op_math(struct lyxp_set *set1, struct lyxp_set *set2, const char *op, int options)
+{
+    LY_ERR rc;
+
+    /* unary '-' */
+    if (!set2 && (op[0] == '-')) {
+        rc = lyxp_set_cast(set1, LYXP_SET_NUMBER, options);
+        LY_CHECK_RET(rc);
+        set1->val.num *= -1;
+        lyxp_set_free(set2);
+        return LY_SUCCESS;
+    }
+
+    assert(set1 && set2);
+
+    rc = lyxp_set_cast(set1, LYXP_SET_NUMBER, options);
+    LY_CHECK_RET(rc);
+    rc = lyxp_set_cast(set2, LYXP_SET_NUMBER, options);
+    LY_CHECK_RET(rc);
+
+    switch (op[0]) {
+    /* '+' */
+    case '+':
+        set1->val.num += set2->val.num;
+        break;
+
+    /* '-' */
+    case '-':
+        set1->val.num -= set2->val.num;
+        break;
+
+    /* '*' */
+    case '*':
+        set1->val.num *= set2->val.num;
+        break;
+
+    /* 'div' */
+    case 'd':
+        set1->val.num /= set2->val.num;
+        break;
+
+    /* 'mod' */
+    case 'm':
+        set1->val.num = ((long long)set1->val.num) % ((long long)set2->val.num);
+        break;
+
+    default:
+        LOGINT_RET(set1->ctx);
+    }
+
+    return LY_SUCCESS;
+}
+
+/*
+ * eval functions
+ *
+ * They execute a parsed XPath expression on some data subtree.
+ */
+
+/**
+ * @brief Evaluate Literal. Logs directly on error.
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ */
+static void
+eval_literal(struct lyxp_expr *exp, uint16_t *exp_idx, struct lyxp_set *set)
+{
+    if (set) {
+        if (exp->tok_len[*exp_idx] == 2) {
+            set_fill_string(set, "", 0);
+        } else {
+            set_fill_string(set, &exp->expr[exp->tok_pos[*exp_idx] + 1], exp->tok_len[*exp_idx] - 2);
+        }
+    }
+    LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+    ++(*exp_idx);
+}
+
+/**
+ * @brief Evaluate NodeTest. Logs directly on error.
+ *
+ * [6] NodeTest ::= NameTest | NodeType '(' ')'
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] attr_axis Whether to search attributes or standard nodes.
+ * @param[in] all_desc Whether to search all the descendants or children only.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static int
+eval_node_test(struct lyxp_expr *exp, uint16_t *exp_idx, int attr_axis, int all_desc,
+               struct lyxp_set *set, int options)
+{
+    int i;
+    char *path;
+    LY_ERR rc;
+
+    switch (exp->tokens[*exp_idx]) {
+    case LYXP_TOKEN_NAMETEST:
+        if (attr_axis) {
+            if (set && (options & LYXP_SCNODE_ALL)) {
+                set_scnode_clear_ctx(set);
+                rc = LY_SUCCESS;
+            } else {
+                if (all_desc) {
+                    rc = moveto_attr_alldesc(set, &exp->expr[exp->tok_pos[*exp_idx]], exp->tok_len[*exp_idx], options);
+                } else {
+                    rc = moveto_attr(set, &exp->expr[exp->tok_pos[*exp_idx]], exp->tok_len[*exp_idx], options);
+                }
+            }
+        } else {
+            if (all_desc) {
+                if (set && (options & LYXP_SCNODE_ALL)) {
+                    rc = moveto_scnode_alldesc(set, &exp->expr[exp->tok_pos[*exp_idx]], exp->tok_len[*exp_idx], options);
+                } else {
+                    rc = moveto_node_alldesc(set, &exp->expr[exp->tok_pos[*exp_idx]], exp->tok_len[*exp_idx], options);
+                }
+            } else {
+                if (set && (options & LYXP_SCNODE_ALL)) {
+                    rc = moveto_scnode(set, &exp->expr[exp->tok_pos[*exp_idx]], exp->tok_len[*exp_idx], options);
+                } else {
+                    rc = moveto_node(set, &exp->expr[exp->tok_pos[*exp_idx]], exp->tok_len[*exp_idx], options);
+                }
+            }
+
+            if ((rc == LY_SUCCESS) && set && (options & LYXP_SCNODE_ALL)) {
+                for (i = set->used - 1; i > -1; --i) {
+                    if (set->val.scnodes[i].in_ctx) {
+                        break;
+                    }
+                }
+                if (i == -1) {
+                    path = lysc_path(set->ctx_scnode, LYSC_PATH_LOG, NULL, 0);
+                    LOGWRN(set->ctx, "Schema node \"%.*s\" not found (%.*s) with context node \"%s\".",
+                           exp->tok_len[*exp_idx], &exp->expr[exp->tok_pos[*exp_idx]],
+                           exp->tok_pos[*exp_idx] + exp->tok_len[*exp_idx], exp->expr, path);
+                    free(path);
+                }
+            }
+        }
+        LY_CHECK_RET(rc);
+
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+        break;
+
+    case LYXP_TOKEN_NODETYPE:
+        if (set) {
+            assert(exp->tok_len[*exp_idx] == 4);
+            if (set->type == LYXP_SET_SCNODE_SET) {
+                set_scnode_clear_ctx(set);
+                /* just for the debug message underneath */
+                set = NULL;
+            } else {
+                if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "node", 4)) {
+                    rc = xpath_node(NULL, 0, set, options);
+                    LY_CHECK_RET(rc);
+                } else {
+                    assert(!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "text", 4));
+                    rc = xpath_text(NULL, 0, set, options);
+                    LY_CHECK_RET(rc);
+                }
+            }
+        }
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        /* '(' */
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_PAR1);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        /* ')' */
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_PAR2);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+        break;
+
+    default:
+        LOGINT_RET(set->ctx);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Evaluate Predicate. Logs directly on error.
+ *
+ * [7] Predicate ::= '[' Expr ']'
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @param[in] parent_pos_pred Whether parent predicate was a positional one.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_predicate(struct lyxp_expr *exp, uint16_t *exp_idx, struct lyxp_set *set, int options, int parent_pos_pred)
+{
+    LY_ERR rc;
+    uint16_t i, orig_exp, brack2_exp, open_brack;
+    uint32_t orig_pos, orig_size, pred_in_ctx;
+    struct lyxp_set set2;
+    struct lyd_node *orig_parent;
+
+    /* '[' */
+    LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+           print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+    ++(*exp_idx);
+
+    if (!set) {
+only_parse:
+        rc = eval_expr_select(exp, exp_idx, 0, NULL, options);
+        LY_CHECK_RET(rc);
+    } else if (set->type == LYXP_SET_NODE_SET) {
+        /* we (possibly) need the set sorted, it can affect the result (if the predicate result is a number) */
+        assert(!set_sort(set, options));
+
+        /* empty set, nothing to evaluate */
+        if (!set->used) {
+            goto only_parse;
+        }
+
+        orig_exp = *exp_idx;
+
+        /* find the predicate end */
+        open_brack = 0;
+        for (brack2_exp = orig_exp; open_brack || (exp->tokens[brack2_exp] != LYXP_TOKEN_BRACK2); ++brack2_exp) {
+            if (exp->tokens[brack2_exp] == LYXP_TOKEN_BRACK1) {
+                ++open_brack;
+            } else if (exp->tokens[brack2_exp] == LYXP_TOKEN_BRACK2) {
+                --open_brack;
+            }
+        }
+
+        orig_pos = 0;
+        orig_size = set->used;
+        orig_parent = NULL;
+        for (i = 0; i < set->used; ) {
+            set_init(&set2, set);
+            set_insert_node(&set2, set->val.nodes[i].node, set->val.nodes[i].pos, set->val.nodes[i].type, 0);
+            /* remember the node context position for position() and context size for last(),
+             * predicates should always be evaluated with respect to the child axis (since we do
+             * not support explicit axes) so we assign positions based on their parents */
+            if (parent_pos_pred && ((struct lyd_node *)set->val.nodes[i].node->parent != orig_parent)) {
+                orig_parent = (struct lyd_node *)set->val.nodes[i].node->parent;
+                orig_pos = 1;
+            } else {
+                ++orig_pos;
+            }
+
+            set2.ctx_pos = orig_pos;
+            set2.ctx_size = orig_size;
+            *exp_idx = orig_exp;
+
+            rc = eval_expr_select(exp, exp_idx, 0, &set2, options);
+            if (rc != LY_SUCCESS) {
+                lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+                return rc;
+            }
+
+            /* number is a position */
+            if (set2.type == LYXP_SET_NUMBER) {
+                if ((long long)set2.val.num == orig_pos) {
+                    set2.val.num = 1;
+                } else {
+                    set2.val.num = 0;
+                }
+            }
+            lyxp_set_cast(&set2, LYXP_SET_BOOLEAN, options);
+
+            /* predicate satisfied or not? */
+            if (set2.val.bool) {
+                ++i;
+            } else {
+                set_remove_node(set, i);
+            }
+        }
+
+    } else if (set->type == LYXP_SET_SCNODE_SET) {
+        for (i = 0; i < set->used; ++i) {
+            if (set->val.scnodes[i].in_ctx == 1) {
+                /* there is a currently-valid node */
+                break;
+            }
+        }
+        /* empty set, nothing to evaluate */
+        if (i == set->used) {
+            goto only_parse;
+        }
+
+        orig_exp = *exp_idx;
+
+        /* find the predicate end */
+        open_brack = 0;
+        for (brack2_exp = orig_exp; open_brack || (exp->tokens[brack2_exp] != LYXP_TOKEN_BRACK2); ++brack2_exp) {
+            if (exp->tokens[brack2_exp] == LYXP_TOKEN_BRACK1) {
+                ++open_brack;
+            } else if (exp->tokens[brack2_exp] == LYXP_TOKEN_BRACK2) {
+                --open_brack;
+            }
+        }
+
+        /* set special in_ctx to all the valid snodes */
+        pred_in_ctx = set_scnode_new_in_ctx(set);
+
+        /* use the valid snodes one-by-one */
+        for (i = 0; i < set->used; ++i) {
+            if (set->val.scnodes[i].in_ctx != pred_in_ctx) {
+                continue;
+            }
+            set->val.scnodes[i].in_ctx = 1;
+
+            *exp_idx = orig_exp;
+
+            rc = eval_expr_select(exp, exp_idx, 0, set, options);
+            LY_CHECK_RET(rc);
+
+            set->val.scnodes[i].in_ctx = pred_in_ctx;
+        }
+
+        /* restore the state as it was before the predicate */
+        for (i = 0; i < set->used; ++i) {
+            if (set->val.scnodes[i].in_ctx == 1) {
+                set->val.scnodes[i].in_ctx = 0;
+            } else if (set->val.scnodes[i].in_ctx == pred_in_ctx) {
+                set->val.scnodes[i].in_ctx = 1;
+            }
+        }
+
+    } else {
+        set2.type = LYXP_SET_EMPTY;
+        set_fill_set(&set2, set);
+
+        rc = eval_expr_select(exp, exp_idx, 0, &set2, options);
+        if (rc != LY_SUCCESS) {
+            lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+            return rc;
+        }
+
+        lyxp_set_cast(&set2, LYXP_SET_BOOLEAN, options);
+        if (!set2.val.bool) {
+            lyxp_set_cast(set, LYXP_SET_EMPTY, options);
+        }
+        lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+    }
+
+    /* ']' */
+    assert(exp->tokens[*exp_idx] == LYXP_TOKEN_BRACK2);
+    LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+           print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+    ++(*exp_idx);
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Evaluate RelativeLocationPath. Logs directly on error.
+ *
+ * [4] RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step
+ * [5] Step ::= '@'? NodeTest Predicate* | '.' | '..'
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] all_desc Whether to search all the descendants or children only.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (YL_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_relative_location_path(struct lyxp_expr *exp, uint16_t *exp_idx, int all_desc, struct lyxp_set *set, int options)
+{
+    int attr_axis;
+    LY_ERR rc;
+
+    goto step;
+    do {
+        /* evaluate '/' or '//' */
+        if (exp->tok_len[*exp_idx] == 1) {
+            all_desc = 0;
+        } else {
+            assert(exp->tok_len[*exp_idx] == 2);
+            all_desc = 1;
+        }
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+step:
+        /* Step */
+        attr_axis = 0;
+        switch (exp->tokens[*exp_idx]) {
+        case LYXP_TOKEN_DOT:
+            /* evaluate '.' */
+            if (set && (options & LYXP_SCNODE_ALL)) {
+                rc = moveto_scnode_self(set, all_desc, options);
+            } else {
+                rc = moveto_self(set, all_desc, options);
+            }
+            LY_CHECK_RET(rc);
+            LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+            ++(*exp_idx);
+            break;
+
+        case LYXP_TOKEN_DDOT:
+            /* evaluate '..' */
+            if (set && (options & LYXP_SCNODE_ALL)) {
+                rc = moveto_scnode_parent(set, all_desc, options);
+            } else {
+                rc = moveto_parent(set, all_desc, options);
+            }
+            LY_CHECK_RET(rc);
+            LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+            ++(*exp_idx);
+            break;
+
+        case LYXP_TOKEN_AT:
+            /* evaluate '@' */
+            attr_axis = 1;
+            LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+            ++(*exp_idx);
+
+            /* fall through */
+        case LYXP_TOKEN_NAMETEST:
+        case LYXP_TOKEN_NODETYPE:
+            rc = eval_node_test(exp, exp_idx, attr_axis, all_desc, set, options);
+            LY_CHECK_RET(rc);
+
+            while ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_BRACK1)) {
+                rc = eval_predicate(exp, exp_idx, set, options, 1);
+                LY_CHECK_RET(rc);
+            }
+            break;
+
+        default:
+            LOGINT_RET(set->ctx);
+        }
+    } while ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_PATH));
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Evaluate AbsoluteLocationPath. Logs directly on error.
+ *
+ * [3] AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_absolute_location_path(struct lyxp_expr *exp, uint16_t *exp_idx, struct lyxp_set *set, int options)
+{
+    int all_desc;
+    LY_ERR rc;
+
+    if (set) {
+        /* no matter what tokens follow, we need to be at the root */
+        moveto_root(set, options);
+    }
+
+    /* '/' RelativeLocationPath? */
+    if (exp->tok_len[*exp_idx] == 1) {
+        /* evaluate '/' - deferred */
+        all_desc = 0;
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        if (exp_check_token(set->ctx, exp, *exp_idx, LYXP_TOKEN_NONE, 0)) {
+            return LY_SUCCESS;
+        }
+        switch (exp->tokens[*exp_idx]) {
+        case LYXP_TOKEN_DOT:
+        case LYXP_TOKEN_DDOT:
+        case LYXP_TOKEN_AT:
+        case LYXP_TOKEN_NAMETEST:
+        case LYXP_TOKEN_NODETYPE:
+            rc = eval_relative_location_path(exp, exp_idx, all_desc, set, options);
+            LY_CHECK_RET(rc);
+            break;
+        default:
+            break;
+        }
+
+    /* '//' RelativeLocationPath */
+    } else {
+        /* evaluate '//' - deferred so as not to waste memory by remembering all the nodes */
+        all_desc = 1;
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        rc = eval_relative_location_path(exp, exp_idx, all_desc, set, options);
+        LY_CHECK_RET(rc);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Evaluate FunctionCall. Logs directly on error.
+ *
+ * [9] FunctionCall ::= FunctionName '(' ( Expr ( ',' Expr )* )? ')'
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_function_call(struct lyxp_expr *exp, uint16_t *exp_idx, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+    LY_ERR (*xpath_func)(struct lyxp_set **, uint16_t, struct lyxp_set *, int) = NULL;
+    uint16_t arg_count = 0, i, func_exp = *exp_idx;
+    struct lyxp_set **args = NULL, **args_aux;
+
+    if (set) {
+        /* FunctionName */
+        switch (exp->tok_len[*exp_idx]) {
+        case 3:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "not", 3)) {
+                xpath_func = &xpath_not;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "sum", 3)) {
+                xpath_func = &xpath_sum;
+            }
+            break;
+        case 4:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "lang", 4)) {
+                xpath_func = &xpath_lang;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "last", 4)) {
+                xpath_func = &xpath_last;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "name", 4)) {
+                xpath_func = &xpath_name;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "true", 4)) {
+                xpath_func = &xpath_true;
+            }
+            break;
+        case 5:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "count", 5)) {
+                xpath_func = &xpath_count;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "false", 5)) {
+                xpath_func = &xpath_false;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "floor", 5)) {
+                xpath_func = &xpath_floor;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "round", 5)) {
+                xpath_func = &xpath_round;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "deref", 5)) {
+                xpath_func = &xpath_deref;
+            }
+            break;
+        case 6:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "concat", 6)) {
+                xpath_func = &xpath_concat;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "number", 6)) {
+                xpath_func = &xpath_number;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "string", 6)) {
+                xpath_func = &xpath_string;
+            }
+            break;
+        case 7:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "boolean", 7)) {
+                xpath_func = &xpath_boolean;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "ceiling", 7)) {
+                xpath_func = &xpath_ceiling;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "current", 7)) {
+                xpath_func = &xpath_current;
+            }
+            break;
+        case 8:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "contains", 8)) {
+                xpath_func = &xpath_contains;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "position", 8)) {
+                xpath_func = &xpath_position;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "re-match", 8)) {
+                xpath_func = &xpath_re_match;
+            }
+            break;
+        case 9:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "substring", 9)) {
+                xpath_func = &xpath_substring;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "translate", 9)) {
+                xpath_func = &xpath_translate;
+            }
+            break;
+        case 10:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "local-name", 10)) {
+                xpath_func = &xpath_local_name;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "enum-value", 10)) {
+                xpath_func = &xpath_enum_value;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "bit-is-set", 10)) {
+                xpath_func = &xpath_bit_is_set;
+            }
+            break;
+        case 11:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "starts-with", 11)) {
+                xpath_func = &xpath_starts_with;
+            }
+            break;
+        case 12:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "derived-from", 12)) {
+                xpath_func = &xpath_derived_from;
+            }
+            break;
+        case 13:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "namespace-uri", 13)) {
+                xpath_func = &xpath_namespace_uri;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "string-length", 13)) {
+                xpath_func = &xpath_string_length;
+            }
+            break;
+        case 15:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "normalize-space", 15)) {
+                xpath_func = &xpath_normalize_space;
+            } else if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "substring-after", 15)) {
+                xpath_func = &xpath_substring_after;
+            }
+            break;
+        case 16:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "substring-before", 16)) {
+                xpath_func = &xpath_substring_before;
+            }
+            break;
+        case 20:
+            if (!strncmp(&exp->expr[exp->tok_pos[*exp_idx]], "derived-from-or-self", 20)) {
+                xpath_func = &xpath_derived_from_or_self;
+            }
+            break;
+        }
+
+        if (!xpath_func) {
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INTOK, "Unknown", &exp->expr[exp->tok_pos[*exp_idx]]);
+            LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INFUNC, exp->tok_len[*exp_idx], &exp->expr[exp->tok_pos[*exp_idx]]);
+            return LY_EVALID;
+        }
+    }
+
+    LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+    ++(*exp_idx);
+
+    /* '(' */
+    assert(exp->tokens[*exp_idx] == LYXP_TOKEN_PAR1);
+    LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+    ++(*exp_idx);
+
+    /* ( Expr ( ',' Expr )* )? */
+    if (exp->tokens[*exp_idx] != LYXP_TOKEN_PAR2) {
+        if (set) {
+            args = malloc(sizeof *args);
+            LY_CHECK_ERR_GOTO(!args, LOGMEM(set->ctx); rc = LY_EMEM, cleanup);
+            arg_count = 1;
+            args[0] = set_copy(set);
+            if (!args[0]) {
+                rc = LY_EMEM;
+                goto cleanup;
+            }
+
+            rc = eval_expr_select(exp, exp_idx, 0, args[0], options);
+            LY_CHECK_GOTO(rc, cleanup);
+        } else {
+            rc = eval_expr_select(exp, exp_idx, 0, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+        }
+    }
+    while ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_COMMA)) {
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        if (set) {
+            ++arg_count;
+            args_aux = realloc(args, arg_count * sizeof *args);
+            LY_CHECK_ERR_GOTO(!args_aux, arg_count--; LOGMEM(set->ctx); rc = LY_EMEM, cleanup);
+            args = args_aux;
+            args[arg_count - 1] = set_copy(set);
+            if (!args[arg_count - 1]) {
+                rc = LY_EMEM;
+                goto cleanup;
+            }
+
+            rc = eval_expr_select(exp, exp_idx, 0, args[arg_count - 1], options);
+            LY_CHECK_GOTO(rc, cleanup);
+        } else {
+            rc = eval_expr_select(exp, exp_idx, 0, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+        }
+    }
+
+    /* ')' */
+    assert(exp->tokens[*exp_idx] == LYXP_TOKEN_PAR2);
+    LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+    ++(*exp_idx);
+
+    if (set) {
+        /* evaluate function */
+        rc = xpath_func(args, arg_count, set, options);
+
+        if (options & LYXP_SCNODE_ALL) {
+            if (rc == LY_EINVAL) {
+                /* some validation warning TODO log everything immediately? */
+                LOGWRN(set->ctx, "Previous warning generated by XPath function \"%.*s\".",
+                       (exp->tok_pos[*exp_idx - 1] - exp->tok_pos[func_exp]) + 1, &exp->expr[exp->tok_pos[func_exp]]);
+                rc = LY_SUCCESS;
+            }
+
+            /* merge all nodes from arg evaluations */
+            for (i = 0; i < arg_count; ++i) {
+                set_scnode_clear_ctx(args[i]);
+                set_scnode_merge(set, args[i]);
+            }
+        }
+    } else {
+        rc = LY_SUCCESS;
+    }
+
+cleanup:
+    for (i = 0; i < arg_count; ++i) {
+        lyxp_set_free(args[i]);
+    }
+    free(args);
+
+    return rc;
+}
+
+/**
+ * @brief Evaluate Number. Logs directly on error.
+ *
+ * @param[in] ctx Context for errors.
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @return LY_ERR
+ */
+static LY_ERR
+eval_number(struct ly_ctx *ctx, struct lyxp_expr *exp, uint16_t *exp_idx, struct lyxp_set *set)
+{
+    long double num;
+    char *endptr;
+
+    if (set) {
+        errno = 0;
+        num = strtold(&exp->expr[exp->tok_pos[*exp_idx]], &endptr);
+        if (errno) {
+            LOGVAL(ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INTOK, "Unknown", &exp->expr[exp->tok_pos[*exp_idx]]);
+            LOGVAL(ctx, LY_VLOG_LYD, set->ctx_node, LYVE_XPATH, "Failed to convert \"%.*s\" into a long double (%s).",
+                   exp->tok_len[*exp_idx], &exp->expr[exp->tok_pos[*exp_idx]], strerror(errno));
+            return LY_EVALID;
+        } else if (endptr - &exp->expr[exp->tok_pos[*exp_idx]] != exp->tok_len[*exp_idx]) {
+            LOGVAL(ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INTOK, "Unknown", &exp->expr[exp->tok_pos[*exp_idx]]);
+            LOGVAL(ctx, LY_VLOG_LYD, set->ctx_node, LYVE_XPATH, "Failed to convert \"%.*s\" into a long double.",
+                   exp->tok_len[*exp_idx], &exp->expr[exp->tok_pos[*exp_idx]]);
+            return LY_EVALID;
+        }
+
+        set_fill_number(set, num);
+    }
+
+    LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+    ++(*exp_idx);
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Evaluate PathExpr. Logs directly on error.
+ *
+ * [10] PathExpr ::= LocationPath | PrimaryExpr Predicate*
+ *                 | PrimaryExpr Predicate* '/' RelativeLocationPath
+ *                 | PrimaryExpr Predicate* '//' RelativeLocationPath
+ * [2] LocationPath ::= RelativeLocationPath | AbsoluteLocationPath
+ * [8] PrimaryExpr ::= '(' Expr ')' | Literal | Number | FunctionCall
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_path_expr(struct lyxp_expr *exp, uint16_t *exp_idx, struct lyxp_set *set, int options)
+{
+    int all_desc, parent_pos_pred;
+    LY_ERR rc;
+
+    switch (exp->tokens[*exp_idx]) {
+    case LYXP_TOKEN_PAR1:
+        /* '(' Expr ')' */
+
+        /* '(' */
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        /* Expr */
+        rc = eval_expr_select(exp, exp_idx, 0, set, options);
+        LY_CHECK_RET(rc);
+
+        /* ')' */
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_PAR2);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        parent_pos_pred = 0;
+        goto predicate;
+
+    case LYXP_TOKEN_DOT:
+    case LYXP_TOKEN_DDOT:
+    case LYXP_TOKEN_AT:
+    case LYXP_TOKEN_NAMETEST:
+    case LYXP_TOKEN_NODETYPE:
+        /* RelativeLocationPath */
+        rc = eval_relative_location_path(exp, exp_idx, 0, set, options);
+        LY_CHECK_RET(rc);
+        break;
+
+    case LYXP_TOKEN_FUNCNAME:
+        /* FunctionCall */
+        if (!set) {
+            rc = eval_function_call(exp, exp_idx, NULL, options);
+        } else {
+            rc = eval_function_call(exp, exp_idx, set, options);
+        }
+        LY_CHECK_RET(rc);
+
+        parent_pos_pred = 1;
+        goto predicate;
+
+    case LYXP_TOKEN_OPERATOR_PATH:
+        /* AbsoluteLocationPath */
+        rc = eval_absolute_location_path(exp, exp_idx, set, options);
+        LY_CHECK_RET(rc);
+        break;
+
+    case LYXP_TOKEN_LITERAL:
+        /* Literal */
+        if (!set || (options & LYXP_SCNODE_ALL)) {
+            if (set) {
+                set_scnode_clear_ctx(set);
+            }
+            eval_literal(exp, exp_idx, NULL);
+        } else {
+            eval_literal(exp, exp_idx, set);
+        }
+
+        parent_pos_pred = 1;
+        goto predicate;
+
+    case LYXP_TOKEN_NUMBER:
+        /* Number */
+        if (!set || (options & LYXP_SCNODE_ALL)) {
+            if (set) {
+                set_scnode_clear_ctx(set);
+            }
+            rc = eval_number(set->ctx, exp, exp_idx, NULL);
+        } else {
+            rc = eval_number(set->ctx, exp, exp_idx, set);
+        }
+        LY_CHECK_RET(rc);
+
+        parent_pos_pred = 1;
+        goto predicate;
+
+    default:
+        LOGVAL(set->ctx, LY_VLOG_LYD, set->ctx_node, LY_VCODE_XP_INTOK, print_token(exp->tokens[*exp_idx]),
+               &exp->expr[exp->tok_pos[*exp_idx]]);
+        return LY_EVALID;
+    }
+
+    return LY_SUCCESS;
+
+predicate:
+    /* Predicate* */
+    while ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_BRACK1)) {
+        rc = eval_predicate(exp, exp_idx, set, options, parent_pos_pred);
+        LY_CHECK_RET(rc);
+    }
+
+    /* ('/' or '//') RelativeLocationPath */
+    if ((exp->used > *exp_idx) && (exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_PATH)) {
+
+        /* evaluate '/' or '//' */
+        if (exp->tok_len[*exp_idx] == 1) {
+            all_desc = 0;
+        } else {
+            assert(exp->tok_len[*exp_idx] == 2);
+            all_desc = 1;
+        }
+
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        rc = eval_relative_location_path(exp, exp_idx, all_desc, set, options);
+        LY_CHECK_RET(rc);
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Evaluate UnionExpr. Logs directly on error.
+ *
+ * [18] UnionExpr ::= PathExpr | UnionExpr '|' PathExpr
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] repeat How many times this expression is repeated.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_union_expr(struct lyxp_expr *exp, uint16_t *exp_idx, uint16_t repeat, struct lyxp_set *set, int options)
+{
+    LY_ERR rc = LY_SUCCESS;
+    struct lyxp_set orig_set, set2;
+    uint16_t i;
+
+    assert(repeat);
+
+    set_init(&orig_set, set);
+    set_init(&set2, set);
+
+    set_fill_set(&orig_set, set);
+
+    rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_UNION, set, options);
+    LY_CHECK_GOTO(rc, cleanup);
+
+    /* ('|' PathExpr)* */
+    for (i = 0; i < repeat; ++i) {
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_UNI);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        if (!set) {
+            rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_UNION, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+            continue;
+        }
+
+        set_fill_set(&set2, &orig_set);
+        rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_UNION, &set2, options);
+        LY_CHECK_GOTO(rc, cleanup);
+
+        /* eval */
+        if (options & LYXP_SCNODE_ALL) {
+            set_scnode_merge(set, &set2);
+        } else {
+            rc = moveto_union(set, &set2, options);
+            LY_CHECK_GOTO(rc, cleanup);
+        }
+    }
+
+cleanup:
+    lyxp_set_cast(&orig_set, LYXP_SET_EMPTY, options);
+    lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+    return rc;
+}
+
+/**
+ * @brief Evaluate UnaryExpr. Logs directly on error.
+ *
+ * [17] UnaryExpr ::= UnionExpr | '-' UnaryExpr
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] repeat How many times this expression is repeated.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_unary_expr(struct lyxp_expr *exp, uint16_t *exp_idx, uint16_t repeat, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+    uint16_t this_op, i;
+
+    assert(repeat);
+
+    /* ('-')+ */
+    this_op = *exp_idx;
+    for (i = 0; i < repeat; ++i) {
+        assert(!exp_check_token(set->ctx, exp, *exp_idx, LYXP_TOKEN_OPERATOR_MATH, 0) && (exp->expr[exp->tok_pos[*exp_idx]] == '-'));
+
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+    }
+
+    rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_UNARY, set, options);
+    LY_CHECK_RET(rc);
+
+    if (set && (repeat % 2)) {
+        if (options & LYXP_SCNODE_ALL) {
+            warn_operands(set->ctx, set, NULL, 1, exp->expr, exp->tok_pos[this_op]);
+        } else {
+            rc = moveto_op_math(set, NULL, &exp->expr[exp->tok_pos[this_op]], options);
+            LY_CHECK_RET(rc);
+        }
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Evaluate MultiplicativeExpr. Logs directly on error.
+ *
+ * [16] MultiplicativeExpr ::= UnaryExpr
+ *                     | MultiplicativeExpr '*' UnaryExpr
+ *                     | MultiplicativeExpr 'div' UnaryExpr
+ *                     | MultiplicativeExpr 'mod' UnaryExpr
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] repeat How many times this expression is repeated.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_multiplicative_expr(struct lyxp_expr *exp, uint16_t *exp_idx, uint16_t repeat, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+    uint16_t this_op;
+    struct lyxp_set orig_set, set2;
+    uint16_t i;
+
+    assert(repeat);
+
+    set_init(&orig_set, set);
+    set_init(&set2, set);
+
+    set_fill_set(&orig_set, set);
+
+    rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_MULTIPLICATIVE, set, options);
+    LY_CHECK_GOTO(rc, cleanup);
+
+    /* ('*' / 'div' / 'mod' UnaryExpr)* */
+    for (i = 0; i < repeat; ++i) {
+        this_op = *exp_idx;
+
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_MATH);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        if (!set) {
+            rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_MULTIPLICATIVE, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+            continue;
+        }
+
+        set_fill_set(&set2, &orig_set);
+        rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_MULTIPLICATIVE, &set2, options);
+        LY_CHECK_GOTO(rc, cleanup);
+
+        /* eval */
+        if (options & LYXP_SCNODE_ALL) {
+            warn_operands(set->ctx, set, &set2, 1, exp->expr, exp->tok_pos[this_op - 1]);
+            set_scnode_merge(set, &set2);
+            set_scnode_clear_ctx(set);
+        } else {
+            rc = moveto_op_math(set, &set2, &exp->expr[exp->tok_pos[this_op]], options);
+            LY_CHECK_GOTO(rc, cleanup);
+        }
+    }
+
+cleanup:
+    lyxp_set_cast(&orig_set, LYXP_SET_EMPTY, options);
+    lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+    return rc;
+}
+
+/**
+ * @brief Evaluate AdditiveExpr. Logs directly on error.
+ *
+ * [15] AdditiveExpr ::= MultiplicativeExpr
+ *                     | AdditiveExpr '+' MultiplicativeExpr
+ *                     | AdditiveExpr '-' MultiplicativeExpr
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] repeat How many times this expression is repeated.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_additive_expr(struct lyxp_expr *exp, uint16_t *exp_idx, uint16_t repeat, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+    uint16_t this_op;
+    struct lyxp_set orig_set, set2;
+    uint16_t i;
+
+    assert(repeat);
+
+    set_init(&orig_set, set);
+    set_init(&set2, set);
+
+    set_fill_set(&orig_set, set);
+
+    rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_ADDITIVE, set, options);
+    LY_CHECK_GOTO(rc, cleanup);
+
+    /* ('+' / '-' MultiplicativeExpr)* */
+    for (i = 0; i < repeat; ++i) {
+        this_op = *exp_idx;
+
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_MATH);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        if (!set) {
+            rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_ADDITIVE, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+            continue;
+        }
+
+        set_fill_set(&set2, &orig_set);
+        rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_ADDITIVE, &set2, options);
+        LY_CHECK_GOTO(rc, cleanup);
+
+        /* eval */
+        if (options & LYXP_SCNODE_ALL) {
+            warn_operands(set->ctx, set, &set2, 1, exp->expr, exp->tok_pos[this_op - 1]);
+            set_scnode_merge(set, &set2);
+            set_scnode_clear_ctx(set);
+        } else {
+            rc = moveto_op_math(set, &set2, &exp->expr[exp->tok_pos[this_op]], options);
+            LY_CHECK_GOTO(rc, cleanup);
+        }
+    }
+
+cleanup:
+    lyxp_set_cast(&orig_set, LYXP_SET_EMPTY, options);
+    lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+    return rc;
+}
+
+/**
+ * @brief Evaluate RelationalExpr. Logs directly on error.
+ *
+ * [14] RelationalExpr ::= AdditiveExpr
+ *                       | RelationalExpr '<' AdditiveExpr
+ *                       | RelationalExpr '>' AdditiveExpr
+ *                       | RelationalExpr '<=' AdditiveExpr
+ *                       | RelationalExpr '>=' AdditiveExpr
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] repeat How many times this expression is repeated.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_relational_expr(struct lyxp_expr *exp, uint16_t *exp_idx, uint16_t repeat, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+    uint16_t this_op;
+    struct lyxp_set orig_set, set2;
+    uint16_t i;
+
+    assert(repeat);
+
+    set_init(&orig_set, set);
+    set_init(&set2, set);
+
+    set_fill_set(&orig_set, set);
+
+    rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_RELATIONAL, set, options);
+    LY_CHECK_GOTO(rc, cleanup);
+
+    /* ('<' / '>' / '<=' / '>=' AdditiveExpr)* */
+    for (i = 0; i < repeat; ++i) {
+        this_op = *exp_idx;
+
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_COMP);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        if (!set) {
+            rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_RELATIONAL, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+            continue;
+        }
+
+        set_fill_set(&set2, &orig_set);
+        rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_RELATIONAL, &set2, options);
+        LY_CHECK_GOTO(rc, cleanup);
+
+        /* eval */
+        if (options & LYXP_SCNODE_ALL) {
+            warn_operands(set->ctx, set, &set2, 1, exp->expr, exp->tok_pos[this_op - 1]);
+            set_scnode_merge(set, &set2);
+            set_scnode_clear_ctx(set);
+        } else {
+            rc = moveto_op_comp(set, &set2, &exp->expr[exp->tok_pos[this_op]], options);
+            LY_CHECK_GOTO(rc, cleanup);
+        }
+    }
+
+cleanup:
+    lyxp_set_cast(&orig_set, LYXP_SET_EMPTY, options);
+    lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+    return rc;
+}
+
+/**
+ * @brief Evaluate EqualityExpr. Logs directly on error.
+ *
+ * [13] EqualityExpr ::= RelationalExpr | EqualityExpr '=' RelationalExpr
+ *                     | EqualityExpr '!=' RelationalExpr
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] repeat How many times this expression is repeated.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_equality_expr(struct lyxp_expr *exp, uint16_t *exp_idx, uint16_t repeat, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+    uint16_t this_op;
+    struct lyxp_set orig_set, set2;
+    uint16_t i;
+
+    assert(repeat);
+
+    set_init(&orig_set, set);
+    set_init(&set2, set);
+
+    set_fill_set(&orig_set, set);
+
+    rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_EQUALITY, set, options);
+    LY_CHECK_GOTO(rc, cleanup);
+
+    /* ('=' / '!=' RelationalExpr)* */
+    for (i = 0; i < repeat; ++i) {
+        this_op = *exp_idx;
+
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_COMP);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (set ? "parsed" : "skipped"),
+               print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        if (!set) {
+            rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_EQUALITY, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+            continue;
+        }
+
+        set_fill_set(&set2, &orig_set);
+        rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_EQUALITY, &set2, options);
+        LY_CHECK_GOTO(rc, cleanup);
+
+        /* eval */
+        if (options & LYXP_SCNODE_ALL) {
+            warn_operands(set->ctx, set, &set2, 0, exp->expr, exp->tok_pos[this_op - 1]);
+            warn_equality_value(exp, set, *exp_idx - 1, this_op - 1, *exp_idx - 1);
+            warn_equality_value(exp, &set2, this_op - 1, this_op - 1, *exp_idx - 1);
+            set_scnode_merge(set, &set2);
+            set_scnode_clear_ctx(set);
+        } else {
+            /* special handling of evaluations of identityref comparisons, always compare prefixed identites */
+            if ((set->type == LYXP_SET_NODE_SET) && (set->val.nodes[0].node->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST))
+                    && (((struct lysc_node_leaf *)set->val.nodes[0].node->schema)->type->basetype == LY_TYPE_IDENT)) {
+                /* left operand is identityref */
+                if ((set2.type == LYXP_SET_STRING) && !strchr(set2.val.str, ':')) {
+                    /* missing prefix in the right operand */
+                    set2.val.str = ly_realloc(set2.val.str, strlen(set->local_mod->name) + 1 + strlen(set2.val.str) + 1);
+                    if (!set2.val.str) {
+                        goto cleanup;
+                    }
+
+                    memmove(set2.val.str + strlen(set->local_mod->name) + 1, set2.val.str, strlen(set2.val.str) + 1);
+                    memcpy(set2.val.str, set->local_mod->name, strlen(set->local_mod->name));
+                    set2.val.str[strlen(set->local_mod->name)] = ':';
+                }
+            }
+
+            rc = moveto_op_comp(set, &set2, &exp->expr[exp->tok_pos[this_op]], options);
+            LY_CHECK_GOTO(rc, cleanup);
+        }
+    }
+
+cleanup:
+    lyxp_set_cast(&orig_set, LYXP_SET_EMPTY, options);
+    lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+    return rc;
+}
+
+/**
+ * @brief Evaluate AndExpr. Logs directly on error.
+ *
+ * [12] AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] repeat How many times this expression is repeated.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_and_expr(struct lyxp_expr *exp, uint16_t *exp_idx, uint16_t repeat, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+    struct lyxp_set orig_set, set2;
+    uint16_t i;
+
+    assert(repeat);
+
+    set_init(&orig_set, set);
+    set_init(&set2, set);
+
+    set_fill_set(&orig_set, set);
+
+    rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_AND, set, options);
+    LY_CHECK_GOTO(rc, cleanup);
+
+    /* cast to boolean, we know that will be the final result */
+    if (set && (options & LYXP_SCNODE_ALL)) {
+        set_scnode_clear_ctx(set);
+    } else {
+        lyxp_set_cast(set, LYXP_SET_BOOLEAN, options);
+    }
+
+    /* ('and' EqualityExpr)* */
+    for (i = 0; i < repeat; ++i) {
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_LOG);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (!set || !set->val.bool ? "skipped" : "parsed"),
+            print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        /* lazy evaluation */
+        if (!set || ((set->type == LYXP_SET_BOOLEAN) && !set->val.bool)) {
+            rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_AND, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+            continue;
+        }
+
+        set_fill_set(&set2, &orig_set);
+        rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_AND, &set2, options);
+        LY_CHECK_GOTO(rc, cleanup);
+
+        /* eval - just get boolean value actually */
+        if (set->type == LYXP_SET_SCNODE_SET) {
+            set_scnode_clear_ctx(&set2);
+            set_scnode_merge(set, &set2);
+        } else {
+            lyxp_set_cast(&set2, LYXP_SET_BOOLEAN, options);
+            set_fill_set(set, &set2);
+        }
+    }
+
+cleanup:
+    lyxp_set_cast(&orig_set, LYXP_SET_EMPTY, options);
+    lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+    return rc;
+}
+
+/**
+ * @brief Evaluate OrExpr. Logs directly on error.
+ *
+ * [11] OrExpr ::= AndExpr | OrExpr 'or' AndExpr
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] repeat How many times this expression is repeated.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_or_expr(struct lyxp_expr *exp, uint16_t *exp_idx, uint16_t repeat, struct lyxp_set *set, int options)
+{
+    LY_ERR rc;
+    struct lyxp_set orig_set, set2;
+    uint16_t i;
+
+    assert(repeat);
+
+    set_init(&orig_set, set);
+    set_init(&set2, set);
+
+    set_fill_set(&orig_set, set);
+
+    rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_OR, set, options);
+    LY_CHECK_GOTO(rc, cleanup);
+
+    /* cast to boolean, we know that will be the final result */
+    if (set && (options & LYXP_SCNODE_ALL)) {
+        set_scnode_clear_ctx(set);
+    } else {
+        lyxp_set_cast(set, LYXP_SET_BOOLEAN, options);
+    }
+
+    /* ('or' AndExpr)* */
+    for (i = 0; i < repeat; ++i) {
+        assert(exp->tokens[*exp_idx] == LYXP_TOKEN_OPERATOR_LOG);
+        LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (!set || set->val.bool ? "skipped" : "parsed"),
+            print_token(exp->tokens[*exp_idx]), exp->tok_pos[*exp_idx]);
+        ++(*exp_idx);
+
+        /* lazy evaluation */
+        if (!set || ((set->type == LYXP_SET_BOOLEAN) && set->val.bool)) {
+            rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_OR, NULL, options);
+            LY_CHECK_GOTO(rc, cleanup);
+            continue;
+        }
+
+        set_fill_set(&set2, &orig_set);
+        /* expr_type cound have been LYXP_EXPR_NONE in all these later calls (except for the first one),
+         * but it does not matter */
+        rc = eval_expr_select(exp, exp_idx, LYXP_EXPR_OR, &set2, options);
+        LY_CHECK_GOTO(rc, cleanup);
+
+        /* eval - just get boolean value actually */
+        if (set->type == LYXP_SET_SCNODE_SET) {
+            set_scnode_clear_ctx(&set2);
+            set_scnode_merge(set, &set2);
+        } else {
+            lyxp_set_cast(&set2, LYXP_SET_BOOLEAN, options);
+            set_fill_set(set, &set2);
+        }
+    }
+
+cleanup:
+    lyxp_set_cast(&orig_set, LYXP_SET_EMPTY, options);
+    lyxp_set_cast(&set2, LYXP_SET_EMPTY, options);
+    return rc;
+}
+
+/**
+ * @brief Decide what expression is at the pointer @p exp_idx and evaluate it accordingly.
+ *
+ * @param[in] exp Parsed XPath expression.
+ * @param[in] exp_idx Position in the expression @p exp.
+ * @param[in] etype Expression type to evaluate.
+ * @param[in,out] set Context and result set. On NULL the rule is only parsed.
+ * @param[in] options XPath options.
+ * @return LY_ERR (LY_EINCOMPLETE on unresolved when)
+ */
+static LY_ERR
+eval_expr_select(struct lyxp_expr *exp, uint16_t *exp_idx, enum lyxp_expr_type etype, struct lyxp_set *set, int options)
+{
+    uint16_t i, count;
+    enum lyxp_expr_type next_etype;
+    LY_ERR rc;
+
+    /* process operator repeats */
+    if (!exp->repeat[*exp_idx]) {
+        next_etype = LYXP_EXPR_NONE;
+    } else {
+        /* find etype repeat */
+        for (i = 0; exp->repeat[*exp_idx][i] > etype; ++i);
+
+        /* select one-priority lower because etype expression called us */
+        if (i) {
+            next_etype = exp->repeat[*exp_idx][i - 1];
+            /* count repeats for that expression */
+            for (count = 0; i && exp->repeat[*exp_idx][i - 1] == next_etype; ++count, --i);
+        } else {
+            next_etype = LYXP_EXPR_NONE;
+        }
+    }
+
+    /* decide what expression are we parsing based on the repeat */
+    switch (next_etype) {
+    case LYXP_EXPR_OR:
+        rc = eval_or_expr(exp, exp_idx, count, set, options);
+        break;
+    case LYXP_EXPR_AND:
+        rc = eval_and_expr(exp, exp_idx, count, set, options);
+        break;
+    case LYXP_EXPR_EQUALITY:
+        rc = eval_equality_expr(exp, exp_idx, count, set, options);
+        break;
+    case LYXP_EXPR_RELATIONAL:
+        rc = eval_relational_expr(exp, exp_idx, count, set, options);
+        break;
+    case LYXP_EXPR_ADDITIVE:
+        rc = eval_additive_expr(exp, exp_idx, count, set, options);
+        break;
+    case LYXP_EXPR_MULTIPLICATIVE:
+        rc = eval_multiplicative_expr(exp, exp_idx, count, set, options);
+        break;
+    case LYXP_EXPR_UNARY:
+        rc = eval_unary_expr(exp, exp_idx, count, set, options);
+        break;
+    case LYXP_EXPR_UNION:
+        rc = eval_union_expr(exp, exp_idx, count, set, options);
+        break;
+    case LYXP_EXPR_NONE:
+        rc = eval_path_expr(exp, exp_idx, set, options);
+        break;
+    default:
+        LOGINT_RET(set->ctx);
+    }
+
+    return rc;
+}
+
+LY_ERR
+lyxp_eval(const char *expr, LYD_FORMAT format, const struct lys_module *local_mod, const struct lyd_node *ctx_node,
+          enum lyxp_node_type ctx_node_type, const struct lyd_node **trees, struct lyxp_set *set, int options)
+{
+    struct ly_ctx *ctx;
+    struct lyxp_expr *exp;
+    uint16_t exp_idx = 0;
+    LY_ERR rc;
+
+    LY_CHECK_ARG_RET(NULL, !expr || !local_mod || !ctx_node || !set, LY_EINVAL);
+
+    ctx = local_mod->ctx;
+
+    exp = lyxp_expr_parse(ctx, expr);
+    if (!exp) {
+        return LY_EINVAL;
+    }
+
+    /* prepare set for evaluation */
+    exp_idx = 0;
+    memset(set, 0, sizeof *set);
+    set->type = LYXP_SET_EMPTY;
+    set_insert_node(set, (struct lyd_node *)ctx_node, 0, ctx_node_type, options);
+    set->ctx = ctx;
+    set->ctx_node = ctx_node;
+    set->local_mod = local_mod;
+    set->trees = trees;
+    set->format = format;
+
+    /* evaluate */
+    rc = eval_expr_select(exp, &exp_idx, 0, set, options);
+    if (rc != LY_SUCCESS) {
+        lyxp_set_cast(set, LYXP_SET_EMPTY, options);
+    }
+
+    lyxp_expr_free(ctx, exp);
+    return rc;
+}
+
+#if 0
+
+/* full xml printing of set elements, not used currently */
+
+void
+lyxp_set_print_xml(FILE *f, struct lyxp_set *set)
+{
+    uint32_t i;
+    char *str_num;
+    struct lyout out;
+
+    memset(&out, 0, sizeof out);
+
+    out.type = LYOUT_STREAM;
+    out.method.f = f;
+
+    switch (set->type) {
+    case LYXP_SET_EMPTY:
+        ly_print(&out, "Empty XPath set\n\n");
+        break;
+    case LYXP_SET_BOOLEAN:
+        ly_print(&out, "Boolean XPath set:\n");
+        ly_print(&out, "%s\n\n", set->value.bool ? "true" : "false");
+        break;
+    case LYXP_SET_STRING:
+        ly_print(&out, "String XPath set:\n");
+        ly_print(&out, "\"%s\"\n\n", set->value.str);
+        break;
+    case LYXP_SET_NUMBER:
+        ly_print(&out, "Number XPath set:\n");
+
+        if (isnan(set->value.num)) {
+            str_num = strdup("NaN");
+        } else if ((set->value.num == 0) || (set->value.num == -0.0f)) {
+            str_num = strdup("0");
+        } else if (isinf(set->value.num) && !signbit(set->value.num)) {
+            str_num = strdup("Infinity");
+        } else if (isinf(set->value.num) && signbit(set->value.num)) {
+            str_num = strdup("-Infinity");
+        } else if ((long long)set->value.num == set->value.num) {
+            if (asprintf(&str_num, "%lld", (long long)set->value.num) == -1) {
+                str_num = NULL;
+            }
+        } else {
+            if (asprintf(&str_num, "%03.1Lf", set->value.num) == -1) {
+                str_num = NULL;
+            }
+        }
+        if (!str_num) {
+            LOGMEM;
+            return;
+        }
+        ly_print(&out, "%s\n\n", str_num);
+        free(str_num);
+        break;
+    case LYXP_SET_NODE_SET:
+        ly_print(&out, "Node XPath set:\n");
+
+        for (i = 0; i < set->used; ++i) {
+            ly_print(&out, "%d. ", i + 1);
+            switch (set->node_type[i]) {
+            case LYXP_NODE_ROOT_ALL:
+                ly_print(&out, "ROOT all\n\n");
+                break;
+            case LYXP_NODE_ROOT_CONFIG:
+                ly_print(&out, "ROOT config\n\n");
+                break;
+            case LYXP_NODE_ROOT_STATE:
+                ly_print(&out, "ROOT state\n\n");
+                break;
+            case LYXP_NODE_ROOT_NOTIF:
+                ly_print(&out, "ROOT notification \"%s\"\n\n", set->value.nodes[i]->schema->name);
+                break;
+            case LYXP_NODE_ROOT_RPC:
+                ly_print(&out, "ROOT rpc \"%s\"\n\n", set->value.nodes[i]->schema->name);
+                break;
+            case LYXP_NODE_ROOT_OUTPUT:
+                ly_print(&out, "ROOT output \"%s\"\n\n", set->value.nodes[i]->schema->name);
+                break;
+            case LYXP_NODE_ELEM:
+                ly_print(&out, "ELEM \"%s\"\n", set->value.nodes[i]->schema->name);
+                xml_print_node(&out, 1, set->value.nodes[i], 1, LYP_FORMAT);
+                ly_print(&out, "\n");
+                break;
+            case LYXP_NODE_TEXT:
+                ly_print(&out, "TEXT \"%s\"\n\n", ((struct lyd_node_leaf_list *)set->value.nodes[i])->value_str);
+                break;
+            case LYXP_NODE_ATTR:
+                ly_print(&out, "ATTR \"%s\" = \"%s\"\n\n", set->value.attrs[i]->name, set->value.attrs[i]->value);
+                break;
+            }
+        }
+        break;
+    }
+}
+
+#endif
+
+LY_ERR
+lyxp_set_cast(struct lyxp_set *set, enum lyxp_set_type target, int options)
+{
+    long double num;
+    char *str;
+    LY_ERR rc;
+
+    if (!set || (set->type == target)) {
+        return LY_SUCCESS;
+    }
+
+    /* it's not possible to convert anything into a node set */
+    assert((target != LYXP_SET_NODE_SET) && ((set->type != LYXP_SET_SCNODE_SET) || (target == LYXP_SET_EMPTY)));
+
+    if (set->type == LYXP_SET_SCNODE_SET) {
+        set_free_content(set);
+        return LY_EINVAL;
+    }
+
+    /* to STRING */
+    if ((target == LYXP_SET_STRING) || ((target == LYXP_SET_NUMBER)
+            && ((set->type == LYXP_SET_NODE_SET) || (set->type == LYXP_SET_EMPTY)))) {
+        switch (set->type) {
+        case LYXP_SET_NUMBER:
+            if (isnan(set->val.num)) {
+                set->val.str = strdup("NaN");
+                LY_CHECK_ERR_RET(!set->val.str, LOGMEM(set->ctx), -1);
+            } else if ((set->val.num == 0) || (set->val.num == -0.0f)) {
+                set->val.str = strdup("0");
+                LY_CHECK_ERR_RET(!set->val.str, LOGMEM(set->ctx), -1);
+            } else if (isinf(set->val.num) && !signbit(set->val.num)) {
+                set->val.str = strdup("Infinity");
+                LY_CHECK_ERR_RET(!set->val.str, LOGMEM(set->ctx), -1);
+            } else if (isinf(set->val.num) && signbit(set->val.num)) {
+                set->val.str = strdup("-Infinity");
+                LY_CHECK_ERR_RET(!set->val.str, LOGMEM(set->ctx), -1);
+            } else if ((long long)set->val.num == set->val.num) {
+                if (asprintf(&str, "%lld", (long long)set->val.num) == -1) {
+                    LOGMEM_RET(set->ctx);
+                }
+                set->val.str = str;
+            } else {
+                if (asprintf(&str, "%03.1Lf", set->val.num) == -1) {
+                    LOGMEM_RET(set->ctx);
+                }
+                set->val.str = str;
+            }
+            break;
+        case LYXP_SET_BOOLEAN:
+            if (set->val.bool) {
+                set->val.str = strdup("true");
+            } else {
+                set->val.str = strdup("false");
+            }
+            LY_CHECK_ERR_RET(!set->val.str, LOGMEM(set->ctx), LY_EMEM);
+            break;
+        case LYXP_SET_NODE_SET:
+            assert(set->used);
+
+            /* we need the set sorted, it affects the result */
+            assert(!set_sort(set, options));
+
+            rc = cast_node_set_to_string(set, options, &str);
+            LY_CHECK_RET(rc);
+            set_free_content(set);
+            set->val.str = str;
+            break;
+        case LYXP_SET_EMPTY:
+            set->val.str = strdup("");
+            LY_CHECK_ERR_RET(!set->val.str, LOGMEM(set->ctx), LY_EMEM);
+            break;
+        default:
+            LOGINT_RET(set->ctx);
+        }
+        set->type = LYXP_SET_STRING;
+    }
+
+    /* to NUMBER */
+    if (target == LYXP_SET_NUMBER) {
+        switch (set->type) {
+        case LYXP_SET_STRING:
+            num = cast_string_to_number(set->val.str);
+            set_free_content(set);
+            set->val.num = num;
+            break;
+        case LYXP_SET_BOOLEAN:
+            if (set->val.bool) {
+                set->val.num = 1;
+            } else {
+                set->val.num = 0;
+            }
+            break;
+        default:
+            LOGINT_RET(set->ctx);
+        }
+        set->type = LYXP_SET_NUMBER;
+    }
+
+    /* to BOOLEAN */
+    if (target == LYXP_SET_BOOLEAN) {
+        switch (set->type) {
+        case LYXP_SET_NUMBER:
+            if ((set->val.num == 0) || (set->val.num == -0.0f) || isnan(set->val.num)) {
+                set->val.bool = 0;
+            } else {
+                set->val.bool = 1;
+            }
+            break;
+        case LYXP_SET_STRING:
+            if (set->val.str[0]) {
+                set_free_content(set);
+                set->val.bool = 1;
+            } else {
+                set_free_content(set);
+                set->val.bool = 0;
+            }
+            break;
+        case LYXP_SET_NODE_SET:
+            set_free_content(set);
+
+            assert(set->used);
+            set->val.bool = 1;
+            break;
+        case LYXP_SET_EMPTY:
+            set->val.bool = 0;
+            break;
+        default:
+            LOGINT_RET(set->ctx);
+        }
+        set->type = LYXP_SET_BOOLEAN;
+    }
+
+    /* to EMPTY */
+    if (target == LYXP_SET_EMPTY) {
+        set_free_content(set);
+        set->type = LYXP_SET_EMPTY;
+    }
+
+    return LY_SUCCESS;
+}
+
+LY_ERR
+lyxp_atomize(struct lyxp_expr *exp, LYD_FORMAT format, const struct lys_module *local_mod, const struct lysc_node *ctx_scnode,
+             enum lyxp_node_type ctx_scnode_type, struct lyxp_set *set, int options)
+{
+    struct ly_ctx *ctx;
+    uint16_t exp_idx = 0;
+
+    LY_CHECK_ARG_RET(NULL, !exp || !local_mod || !ctx_scnode || !set, LY_EINVAL);
+
+    ctx = local_mod->ctx;
+
+    /* prepare set for evaluation */
+    exp_idx = 0;
+    memset(set, 0, sizeof *set);
+    set->type = LYXP_SET_SCNODE_SET;
+    set_scnode_insert_node(set, ctx_scnode, ctx_scnode_type);
+    set->ctx = ctx;
+    set->ctx_scnode = ctx_scnode;
+    set->local_mod = local_mod;
+    set->format = format;
+
+    /* evaluate */
+    return eval_expr_select(exp, &exp_idx, 0, set, options);
+}
+
+LY_ERR
+lyxp_node_atomize(const struct lysc_node *node, struct lyxp_set *set, int set_ext_dep_flags)
+{
+    struct ly_ctx *ctx;
+    struct lysc_ctx cctx;
+    struct lysc_node *parent, *elem;
+    struct lyxp_set tmp_set;
+    uint32_t i, j;
+    int opts;
+    struct lysc_when **when = NULL;
+    struct lysc_must *musts = NULL;
+    LY_ERR rc;
+
+    ctx = node->module->ctx;
+
+    memset(&tmp_set, 0, sizeof tmp_set);
+    memset(set, 0, sizeof *set);
+    set->ctx = ctx;
+
+    /* check if we will be traversing RPC output */
+    for (parent = (struct lysc_node *)node; parent && (parent->nodetype != LYS_ACTION); parent = parent->parent);
+    if (parent && (node->flags & LYS_CONFIG_R)) {
+        opts = LYXP_SCNODE_OUTPUT;
+    } else {
+        opts = LYXP_SCNODE_SCHEMA;
+    }
+
+    switch (node->nodetype) {
+    case LYS_CONTAINER:
+        when = ((struct lysc_node_container *)node)->when;
+        musts = ((struct lysc_node_container *)node)->musts;
+        break;
+    case LYS_CHOICE:
+        when = ((struct lysc_node_choice *)node)->when;
+        break;
+    case LYS_LEAF:
+        when = ((struct lysc_node_leaf *)node)->when;
+        musts = ((struct lysc_node_leaf *)node)->musts;
+        break;
+    case LYS_LEAFLIST:
+        when = ((struct lysc_node_leaflist *)node)->when;
+        musts = ((struct lysc_node_leaflist *)node)->musts;
+        break;
+    case LYS_LIST:
+        when = ((struct lysc_node_list *)node)->when;
+        musts = ((struct lysc_node_list *)node)->musts;
+        break;
+    case LYS_ANYXML:
+    case LYS_ANYDATA:
+        when = ((struct lysc_node_anydata *)node)->when;
+        musts = ((struct lysc_node_anydata *)node)->musts;
+        break;
+    case LYS_CASE:
+        when = ((struct lysc_node_case *)node)->when;
+        break;
+    case LYS_NOTIF:
+        musts = ((struct lysc_notif *)node)->musts;
+        break;
+    default:
+        /* nothing to check */
+        break;
+    }
+
+    if (set_ext_dep_flags) {
+        /* find operation if in one, used later */
+        for (parent = (struct lysc_node *)node;
+             parent && !(parent->nodetype & (LYS_ACTION | LYS_NOTIF));
+             parent = parent->parent);
+    }
+
+    /* check "when" */
+    LY_ARRAY_FOR(when, i) {
+        rc = lyxp_atomize(when[i]->cond, LYD_UNKNOWN, when[i]->module, when[i]->context, LYXP_NODE_ELEM, &tmp_set, opts);
+        if (rc != LY_SUCCESS) {
+            free(tmp_set.val.scnodes);
+            LOGVAL(ctx, LY_VLOG_LYS, when[i]->context, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when[i]->cond->expr);
+            goto error;
+        } else {
+            if (set_ext_dep_flags) {
+                for (j = 0; j < tmp_set.used; ++j) {
+                    /* skip roots'n'stuff */
+                    if (tmp_set.val.scnodes[j].type == LYXP_NODE_ELEM) {
+                        /* XPath expression cannot reference "lower" status than the node that has the definition */
+                        cctx.ctx = ctx;
+                        lysc_path((struct lysc_node *)node, LYSC_PATH_LOG, cctx.path, LYSC_CTX_BUFSIZE);
+                        rc = lysc_check_status(&cctx, node->flags, node->module, node->name, tmp_set.val.scnodes[j].scnode->flags,
+                                tmp_set.val.scnodes[j].scnode->module, tmp_set.val.scnodes[j].scnode->name);
+                        LY_CHECK_GOTO(rc, error);
+
+                        if (parent) {
+                            for (elem = tmp_set.val.scnodes[j].scnode; elem && (elem != parent); elem = elem->parent);
+                            if (!elem) {
+                                /* not in node's RPC or notification subtree, set the correct dep flag */
+                                when[i]->flags |= LYS_XPATH_DEP;
+                                ((struct lysc_node *)node)->flags |= LYS_XPATH_DEP;
+                            }
+                        }
+                    }
+                }
+            }
+            set_scnode_merge(set, &tmp_set);
+            memset(&tmp_set, 0, sizeof tmp_set);
+        }
+    }
+
+    /* check "must" */
+    LY_ARRAY_FOR(musts, i) {
+        rc = lyxp_atomize(musts[i].cond, LYD_UNKNOWN, musts[i].module, node, LYXP_NODE_ELEM, &tmp_set, opts);
+        if (rc != LY_SUCCESS) {
+            free(tmp_set.val.scnodes);
+            LOGVAL(ctx, LY_VLOG_LYS, node, LYVE_SEMANTICS, "Invalid must restriction \"%s\".", musts[i].cond->expr);
+            goto error;
+        } else {
+            if (set_ext_dep_flags) {
+                for (j = 0; j < tmp_set.used; ++j) {
+                    /* skip roots'n'stuff */
+                    if (tmp_set.val.scnodes[j].type == LYXP_NODE_ELEM) {
+                        /* XPath expression cannot reference "lower" status than the node that has the definition */
+                        cctx.ctx = ctx;
+                        lysc_path((struct lysc_node *)node, LYSC_PATH_LOG, cctx.path, LYSC_CTX_BUFSIZE);
+                        rc = lysc_check_status(&cctx, node->flags, node->module, node->name, tmp_set.val.scnodes[j].scnode->flags,
+                                tmp_set.val.scnodes[j].scnode->module, tmp_set.val.scnodes[j].scnode->name);
+                        LY_CHECK_GOTO(rc, error);
+
+                        if (parent) {
+                            for (elem = tmp_set.val.scnodes[j].scnode; elem && (elem != parent); elem = elem->parent);
+                            if (!elem) {
+                                /* not in node's RPC or notification subtree, set the correct dep flag */
+                                musts[i].flags |= LYS_XPATH_DEP;
+                                ((struct lysc_node *)node)->flags |= LYS_XPATH_DEP;
+                            }
+                        }
+                    }
+                }
+            }
+            set_scnode_merge(set, &tmp_set);
+            memset(&tmp_set, 0, sizeof tmp_set);
+        }
+    }
+
+    return LY_SUCCESS;
+
+error:
+    free(set->val.scnodes);
+    memset(set, 0, sizeof *set);
+    return rc;
+}
diff --git a/src/xpath.h b/src/xpath.h
index 5abd427..c0d12bb 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -3,7 +3,7 @@
  * @author Michal Vasko <mvasko@cesnet.cz>
  * @brief YANG XPath evaluation functions header
  *
- * Copyright (c) 2015 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2019 CESNET, z.s.p.o.
  *
  * This source code is licensed under BSD 3-Clause License (the "License").
  * You may not use this file except in compliance with the License.
@@ -124,6 +124,20 @@
 };
 
 /**
+ * @brief Types of context nodes, #LYXP_NODE_ROOT_CONFIG used only in when or must conditions.
+ */
+enum lyxp_node_type {
+    /* XML document roots */
+    LYXP_NODE_ROOT,             /* access to all the data (node value first top-level node) */
+    LYXP_NODE_ROOT_CONFIG,      /* <running> data context, no state data (node value first top-level node) */
+
+    /* XML elements */
+    LYXP_NODE_ELEM,             /* XML element (most common) */
+    LYXP_NODE_TEXT,             /* XML text element (extremely specific use, unlikely to be ever needed) */
+    LYXP_NODE_ATTR              /* XML attribute (in YANG cannot happen, do not use for the context node) */
+};
+
+/**
  * @brief Structure holding a parsed XPath expression.
  */
 struct lyxp_expr {
@@ -172,13 +186,11 @@
 enum lyxp_set_type {
     LYXP_SET_EMPTY = 0,
     LYXP_SET_NODE_SET,
-    LYXP_SET_SNODE_SET,
+    LYXP_SET_SCNODE_SET,
     LYXP_SET_BOOLEAN,
     LYXP_SET_NUMBER,
     LYXP_SET_STRING
 };
-#if 0
-#ifdef LY_ENABLED_CACHE
 
 /**
  * @brief Item stored in an XPath set hash table.
@@ -188,8 +200,6 @@
     enum lyxp_node_type type;
 } _PACKED;
 
-#endif
-
 /**
  * @brief XPath set - (partial) result.
  */
@@ -201,15 +211,15 @@
             enum lyxp_node_type type;
             uint32_t pos;
         } *nodes;
-        struct lyxp_set_snode {
-            struct lys_node *snode;
+        struct lyxp_set_scnode {
+            struct lysc_node *scnode;
             enum lyxp_node_type type;
-            /* 0 - snode was traversed, but not currently in the context,
-             * 1 - snode currently in context,
-             * 2 - snode in context and just added, so skip it for the current operation,
-             * >=3 - snode is not in context because we are in a predicate and this snode was used/will be used later */
+            /* 0 - scnode was traversed, but not currently in the context,
+             * 1 - scnode currently in context,
+             * 2 - scnode in context and just added, so skip it for the current operation,
+             * >=3 - scnode is not in context because we are in a predicate and this scnode was used/will be used later */
             uint32_t in_ctx;
-        } *snodes;
+        } *scnodes;
         struct lyxp_set_attr {
             struct lyd_attr *attr;
             enum lyxp_node_type type;
@@ -220,75 +230,79 @@
         int bool;
     } val;
 
-    /* this is valid only for type LYXP_SET_NODE_SET and LYXP_SET_SNODE_SET */
+    /* this is valid only for type LYXP_SET_NODE_SET and LYXP_SET_SCNODE_SET */
     uint32_t used;
     uint32_t size;
-#ifdef LY_ENABLED_CACHE
     struct hash_table *ht;
-#endif
-    /* this is valid only for type LYXP_SET_NODE_SET */
+
+    /* XPath context information, this is valid only for type LYXP_SET_NODE_SET */
     uint32_t ctx_pos;
     uint32_t ctx_size;
+
+    /* general context */
+    struct ly_ctx *ctx;
+    union {
+        const struct lyd_node *ctx_node;
+        const struct lysc_node *ctx_scnode;
+    };
+    const struct lys_module *local_mod;
+    const struct lyd_node **trees;
+    LYD_FORMAT format;
 };
 
 /**
- * @brief Evaluate the XPath expression \p expr on data. Be careful when using this function, the result can often
- * be confusing without thorough understanding of XPath evaluation rules defined in RFC 6020.
+ * @brief Evaluate an XPath expression on data. Be careful when using this function, the result can often
+ * be confusing without thorough understanding of XPath evaluation rules defined in RFC 7950.
  *
- * @param[in] expr XPath expression to evaluate. Must be in JSON format (prefixes are model names).
- * @param[in] cur_node Current (context) data node. If the node has #LYD_VAL_INUSE flag, it is considered dummy (intended
- * for but not restricted to evaluation with the LYXP_WHEN flag).
- * @param[in] cur_node_type Current (context) data node type. For every standard case use #LYXP_NODE_ELEM. But there are
- * cases when the context node \p cur_node is actually supposed to be the XML root, there is no such data node. So, in
- * this case just pass the first top-level node into \p cur_node and use an enum value for this kind of root
- * (#LYXP_NODE_ROOT_CONFIG if \p cur_node has config true, otherwise #LYXP_NODE_ROOT). #LYXP_NODE_TEXT and #LYXP_NODE_ATTR can also be used,
+ * @param[in] expr XPath expression to evaluate.
+ * @param[in] format Format of the XPath expression (more specifcally, of any used prefixes).
+ * @param[in] local_mod Local module relative to the @p expr.
+ * @param[in] ctx_node Current (context) data node.
+ * @param[in] ctx_node_type Current (context) data node type. For every standard case use #LYXP_NODE_ELEM. But there are
+ * cases when the context node @p ctx_node is actually supposed to be the XML root, there is no such data node. So, in
+ * this case just pass the first top-level node into @p ctx_node and use an enum value for this kind of root
+ * (#LYXP_NODE_ROOT_CONFIG if @p ctx_node has config true, otherwise #LYXP_NODE_ROOT). #LYXP_NODE_TEXT and #LYXP_NODE_ATTR can also be used,
  * but there are no use-cases in YANG.
- * @param[in] local_mod Local module relative to the \p expr. Used only to determine the internal canonical value for identities.
- * @param[out] set Result set. Must be valid and in the same libyang context as \p cur_node.
- * To be safe, always either zero or cast the \p set to empty. After done using, either cast
- * the \p set to empty (if allocated statically) or free it (if allocated dynamically) to
+ * @param[in] trees Data trees on which to perform the evaluation.
+ * @param[out] set Result set. Must be valid and in the same libyang context as @p ctx_node.
+ * To be safe, always either zero or cast the @p set to empty. After done using, either cast
+ * the @p set to empty (if allocated statically) or free it (if allocated dynamically) to
  * prevent memory leaks.
  * @param[in] options Whether to apply some evaluation restrictions.
- * LYXP_MUST - apply must data tree access restrictions.
- * LYXP_WHEN - apply when data tree access restrictions and consider LYD_WHEN flags in data nodes.
- *
- * @return EXIT_SUCCESS on success, EXIT_FAILURE on unresolved when dependency, -1 on error.
+ * @return LY_ERR
  */
-int lyxp_eval(const char *expr, const struct lyd_node *cur_node, enum lyxp_node_type cur_node_type,
-              const struct lys_module *local_mod, struct lyxp_set *set, int options);
+LY_ERR lyxp_eval(const char *expr, LYD_FORMAT format, const struct lys_module *local_mod, const struct lyd_node *ctx_node,
+                 enum lyxp_node_type ctx_node_type, const struct lyd_node **trees, struct lyxp_set *set, int options);
+
+#define LYXP_SCHEMA 0x01 /**< Apply data node access restrictions defined for 'when' and 'must' evaluation. */
 
 /**
- * @brief Get all the partial XPath nodes (atoms) that are required for \p expr to be evaluated.
+ * @brief Get all the partial XPath nodes (atoms) that are required for @p exp to be evaluated.
  *
- * If any LYXP_SNODE* options is set, only fatal errors are printed, otherwise they are downgraded
+ * If any LYXP_SCNODE* options is set, only fatal errors are printed, otherwise they are downgraded
  * to warnings.
  *
- * @param[in] expr XPath expression to be evaluated. Must be in JSON format (prefixes are model names).
- * @param[in] cur_snode Current (context) schema node.
- * @param[in] cur_snode_type Current (context) schema node type.
- * @param[out] set Result set. Must be valid and in the same libyang context as \p cur_snode.
- * To be safe, always either zero or cast the \p set to empty. After done using, either cast
- * the \p set to empty (if allocated statically) or free it (if allocated dynamically) to
+ * @param[in] exp Parsed XPath expression to be evaluated.
+ * @param[in] format Format of the XPath expression (more specifcally, of any used prefixes).
+ * @param[in] local_mod Local module relative to the @p exp.
+ * @param[in] ctx_scnode Current (context) schema node.
+ * @param[in] ctx_scnode_type Current (context) schema node type.
+ * @param[out] set Result set. Must be valid and in the same libyang context as @p ctx_scnode.
+ * To be safe, always either zero or cast the @p set to empty. After done using, either cast
+ * the @p set to empty (if allocated statically) or free it (if allocated dynamically) to
  * prevent memory leaks.
  * @param[in] options Whether to apply some evaluation restrictions, one flag must always be used.
- * LYXP_SNODE - no special data tree access modifiers.
- * LYXP_SNODE_MUST - apply must data tree access restrictions.
- * LYXP_SNODE_WHEN - apply when data tree access restrictions.
- * LYXP_SNODE_OUTPUT - search RPC/action output instead input
- * @param[out] ctx_snode Actual context node for the expression (it often changes for "when" expressions).
- *
- * @return EXIT_SUCCESS on success, -1 on error.
+ * @return LY_ERR
  */
-int lyxp_atomize(const char *expr, const struct lys_node *cur_snode, enum lyxp_node_type cur_snode_type,
-                 struct lyxp_set *set, int options, const struct lys_node **ctx_snode);
+LY_ERR lyxp_atomize(struct lyxp_expr *exp, LYD_FORMAT format, const struct lys_module *local_mod, const struct lysc_node *ctx_scnode,
+                    enum lyxp_node_type ctx_scnode_type, struct lyxp_set *set, int options);
 
 /* these are used only internally */
-#define LYXP_SNODE 0x04
-#define LYXP_SNODE_MUST 0x08
-#define LYXP_SNODE_WHEN 0x10
-#define LYXP_SNODE_OUTPUT 0x20
+#define LYXP_SCNODE 0x02        /**< No special data tree access modifiers. */
+#define LYXP_SCNODE_SCHEMA 0x04 /**< Apply schema node access restrictions defined for 'when' and 'must' evaluation. */
+#define LYXP_SCNODE_OUTPUT 0x08 /**< Search RPC/action output instead of input. */
 
-#define LYXP_SNODE_ALL 0x1C
+#define LYXP_SCNODE_ALL 0x0E
 
 /**
  * @brief Works like lyxp_atomize(), but it is executed on all the when and must expressions
@@ -297,59 +311,44 @@
  * @param[in] node Node to examine.
  * @param[in,out] set Resulting set of atoms merged from all the expressions.
  * Will be cleared before use.
- * @param[in] set_ext_dep_flags Whether to set #LYS_XPCONF_DEP or #LYS_XPSTATE_DEP for conditions that
- * require foreign configuration or state subtree and also for the node itself, if it has any such condition.
- *
- * @return EXIT_SUCCESS on success, -1 on error.
+ * @param[in] set_ext_dep_flags Whether to set #LYS_XPATH_DEP for conditions that require data subtree
+ * and also for the node itself, if it has any such condition.
+ * @return LY_ERR
  */
-int lyxp_node_atomize(const struct lys_node *node, struct lyxp_set *set, int set_ext_dep_flags);
-#endif
-/**
- * @brief Check syntax of all the XPath expressions of the node.
- *
- * @param[in] node Node to examine.
- *
- * @return LY_ERR value.
- */
-LY_ERR lyxp_node_check_syntax(const struct lysc_node *node);
-#if 0
+LY_ERR lyxp_node_atomize(const struct lysc_node *node, struct lyxp_set *set, int set_ext_dep_flags);
+
 /**
  * @brief Cast XPath set to another type.
  *        Indirectly context position aware.
  *
  * @param[in] set Set to cast.
  * @param[in] target Target type to cast \p set into.
- * @param[in] cur_node Current (context) data node. Cannot be NULL.
- * @param[in] local_mod Local expression module.
  * @param[in] options Whether to apply some evaluation restrictions.
- *
- * @return EXIT_SUCCESS on success, -1 on error.
+ * @return LY_ERR
  */
-int lyxp_set_cast(struct lyxp_set *set, enum lyxp_set_type target, const struct lyd_node *cur_node,
-                  const struct lys_module *local_mod, int options);
+LY_ERR lyxp_set_cast(struct lyxp_set *set, enum lyxp_set_type target, int options);
 
 /**
- * @brief Free contents of an XPath \p set.
+ * @brief Free contents of an XPath @p set.
  *
  * @param[in] set Set to free.
  */
 void lyxp_set_free(struct lyxp_set *set);
-#endif
+
 /**
  * @brief Parse an XPath expression into a structure of tokens.
  *        Logs directly.
  *
- * http://www.w3.org/TR/1999/REC-xpath-19991116/ section 3.7
+ * https://www.w3.org/TR/1999/REC-xpath-19991116/#exprlex
  *
  * @param[in] ctx Context for errors.
  * @param[in] expr XPath expression to parse. It is duplicated.
- *
  * @return Filled expression structure or NULL on error.
  */
 struct lyxp_expr *lyxp_expr_parse(struct ly_ctx *ctx, const char *expr);
 
 /**
- * @brief Frees a parsed XPath expression. \p expr should not be used afterwards.
+ * @brief Frees a parsed XPath expression. @p expr should not be used afterwards.
  *
  * @param[in] ctx libyang context of the expression.
  * @param[in] expr Expression to free.
