compiled schema NEW when dummy node check

Also, no need to check it in data now.
diff --git a/src/common.h b/src/common.h
index a3403b5..9392b5c 100644
--- a/src/common.h
+++ b/src/common.h
@@ -183,6 +183,7 @@
 
 #define LY_VCODE_INVAL_MINMAX   LYVE_SEMANTICS, "Invalid combination of min-elements and max-elements: min value %u is bigger than the max value %u."
 #define LY_VCODE_CIRC_WHEN      LYVE_SEMANTICS, "When condition of \"%s\" includes a self-reference (referenced by when of \"%s\")."
+#define LY_VCODE_DUMMY_WHEN     LYVE_SEMANTICS, "When condition of \"%s\" is accessing its own conditional node."
 
 #define LY_VCODE_INSTMT         LYVE_SYNTAX_YANG, "Invalid keyword \"%s\"."
 #define LY_VCODE_INCHILDSTMT    LYVE_SYNTAX_YANG, "Invalid keyword \"%s\" as a child of \"%s\"."
@@ -220,7 +221,6 @@
 #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\"."
diff --git a/src/tree_data.h b/src/tree_data.h
index 6820144..6e63d38 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -244,13 +244,13 @@
  *     ---------------------+-+-+-+-+-+-+-+
  *       1 LYD_DEFAULT      |x| |x|x| | | |
  *                          +-+-+-+-+-+-+-+
- *       2                  | | | | | | | |
+ *       2 LYD_WHEN_TRUE    |x|x|x|x|x| | |
  *     ---------------------+-+-+-+-+-+-+-+
  *
  */
 
-#define LYD_DEFAULT      0x01        /**< default (implicit) node; */
-#define LYD_DUMMY        0x80000000  /**< dummy node (in XPath context, internal flag) */
+#define LYD_DEFAULT      0x01        /**< default (implicit) node */
+#define LYD_WHEN_TRUE    0x02        /**< all when conditions of this node were evaluated to true */
 /** @} */
 
 /**
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 574a49e..47e759f 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -4758,13 +4758,18 @@
 
                 if (!(ctx->options & LYSC_OPT_GROUPING)) {
                     /* do not check "when" semantics in a grouping */
-                    ly_set_add(&ctx->unres, target, 0);
+                    ly_set_add(&ctx->unres, node, 0);
                 }
 
                 when_shared = *when;
             } else {
                 ++when_shared->refcount;
                 (*when) = when_shared;
+
+                if (!(ctx->options & LYSC_OPT_GROUPING)) {
+                    /* in this case check "when" again for all children because of dummy node check */
+                    ly_set_add(&ctx->unres, node, 0);
+                }
             }
         }
     }
@@ -5040,6 +5045,11 @@
             } else {
                 ++when_shared->refcount;
                 (*when) = when_shared;
+
+                if (!(ctx->options & LYSC_OPT_GROUPING)) {
+                    /* in this case check "when" again for all children because of dummy node check */
+                    ly_set_add(&ctx->unres, child, 0);
+                }
             }
         }
     }
@@ -6940,7 +6950,7 @@
  * @return LY_ERR value
  */
 static LY_ERR
-lys_compile_check_cyclic_when(struct lyxp_set *set, const struct lysc_node *node)
+lys_compile_check_when_cyclic(struct lyxp_set *set, const struct lysc_node *node)
 {
     struct lyxp_set tmp_set;
     struct lyxp_set_scnode *xp_scnode;
@@ -6955,11 +6965,8 @@
     for (i = 0; i < set->used; ++i) {
         xp_scnode = &set->val.scnodes[i];
 
-        if ((xp_scnode->type == LYXP_NODE_ELEM) && (xp_scnode->scnode == node)) {
-            /* node when was already checked */
-            xp_scnode->in_ctx = 2;
-        } else {
-            /* check node when */
+        if (xp_scnode->in_ctx != -1) {
+            /* check node when, skip the context node (it was just checked) */
             xp_scnode->in_ctx = 1;
         }
     }
@@ -6993,7 +7000,7 @@
                     if (tmp_set.val.scnodes[j].type == LYXP_NODE_ELEM) {
                         /* try to find this node in our set */
                         idx = lyxp_set_scnode_dup_node_check(set, tmp_set.val.scnodes[j].scnode, LYXP_NODE_ELEM, -1);
-                        if ((idx > -1) && (set->val.scnodes[idx].in_ctx == 2)) {
+                        if ((idx > -1) && (set->val.scnodes[idx].in_ctx == -1)) {
                             LOGVAL(set->ctx, LY_VLOG_LYS, node, LY_VCODE_CIRC_WHEN, node->name, set->val.scnodes[idx].scnode->name);
                             ret = LY_EVALID;
                             goto cleanup;
@@ -7016,7 +7023,7 @@
         } while (node && (node->nodetype & (LYS_CASE | LYS_CHOICE)));
 
         /* this node when was checked */
-        xp_scnode->in_ctx = 2;
+        xp_scnode->in_ctx = -1;
     }
 
 cleanup:
@@ -7095,22 +7102,26 @@
         ctx->path[0] = '\0';
         lysc_path((struct lysc_node *)node, LYSC_PATH_LOG, ctx->path, LYSC_CTX_BUFSIZE);
         for (j = 0; j < tmp_set.used; ++j) {
-            /* skip roots'n'stuff, set in_ctx for when checking */
-            if (tmp_set.val.scnodes[j].type == LYXP_NODE_ELEM) {
+            /* skip roots'n'stuff */
+            if ((tmp_set.val.scnodes[j].type == LYXP_NODE_ELEM) && (tmp_set.val.scnodes[j].in_ctx != -1)) {
                 struct lysc_node *schema = tmp_set.val.scnodes[j].scnode;
 
                 /* XPath expression cannot reference "lower" status than the node that has the definition */
                 ret = lysc_check_status(ctx, when[i]->flags, when[i]->module, node->name, schema->flags, schema->module,
                                         schema->name);
                 LY_CHECK_GOTO(ret, cleanup);
+
+                /* check dummy node accessing */
+                if (schema == node) {
+                    LOGVAL(ctx->ctx, LY_VLOG_LYS, node, LY_VCODE_DUMMY_WHEN, node->name);
+                    ret = LY_EVALID;
+                    goto cleanup;
+                }
             }
         }
 
-        /* check dummy node accessing */
-        /* TODO */
-
         /* check cyclic dependencies */
-        ret = lys_compile_check_cyclic_when(&tmp_set, node);
+        ret = lys_compile_check_when_cyclic(&tmp_set, node);
         LY_CHECK_GOTO(ret, cleanup);
 
         lyxp_set_cast(&tmp_set, LYXP_SET_EMPTY);
diff --git a/src/xpath.c b/src/xpath.c
index 995941c..93dd7f6 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -502,11 +502,6 @@
 {
     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;
-    }
-
     switch (set->val.nodes[0].type) {
     case LYXP_NODE_ROOT:
     case LYXP_NODE_ROOT_CONFIG:
@@ -924,6 +919,8 @@
     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 == -2) {
+            set->val.scnodes[i].in_ctx = -1;
         }
     }
 }
@@ -1223,10 +1220,11 @@
  * @param[in] set Set to modify.
  * @return New context value.
  */
-static uint32_t
+static int32_t
 set_scnode_new_in_ctx(struct lyxp_set *set)
 {
-    uint32_t ret_ctx, i;
+    uint32_t i;
+    int32_t ret_ctx;
 
     assert(set->type == LYXP_SET_SCNODE_SET);
 
@@ -4969,6 +4967,8 @@
         return LY_EVALID;
     }
 
+    set_init(&set_item, set);
+
     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);
@@ -5022,10 +5022,6 @@
     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;
@@ -5278,8 +5274,8 @@
         return LY_ENOT;
     }
 
-    /* dummy and context check */
-    if ((node->flags & LYD_DUMMY) || ((root_type == LYXP_NODE_ROOT_CONFIG) && (node->schema->flags & LYS_CONFIG_R))) {
+    /* context check */
+    if ((root_type == LYXP_NODE_ROOT_CONFIG) && (node->schema->flags & LYS_CONFIG_R)) {
         return LY_EINVAL;
     }
 
@@ -5389,9 +5385,8 @@
                 }
             }
 
-        /* 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))) {
+        /* skip nodes without children - leaves, leaflists, anyxmls (ouput root will eval to true) */
+        } else if (!(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, set->root_type, name_dict, moveto_mod);
@@ -5464,9 +5459,13 @@
     orig_used = set->used;
     for (i = 0; i < orig_used; ++i) {
         if (set->val.scnodes[i].in_ctx != 1) {
-            continue;
+            if (set->val.scnodes[i].in_ctx != -2) {
+                continue;
+            }
+
+            /* remember context node */
+            set->val.scnodes[i].in_ctx = -1;
         }
-        set->val.scnodes[i].in_ctx = 0;
 
         start_parent = set->val.scnodes[i].scnode;
 
@@ -5657,9 +5656,13 @@
     orig_used = set->used;
     for (i = 0; i < orig_used; ++i) {
         if (set->val.scnodes[i].in_ctx != 1) {
-            continue;
+            if (set->val.scnodes[i].in_ctx != -2) {
+                continue;
+            }
+
+            /* remember context node */
+            set->val.scnodes[i].in_ctx = -1;
         }
-        set->val.scnodes[i].in_ctx = 0;
 
         /* TREE DFS */
         start = set->val.scnodes[i].scnode;
@@ -5757,7 +5760,7 @@
 
         /* 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)) {
+        if (set->val.nodes[i].type == LYXP_NODE_ELEM) {
             for (sub = set->val.nodes[i].node->attr; sub; sub = sub->next) {
 
                 /* check "namespace" */
@@ -5950,7 +5953,7 @@
             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)) {
+            if (!(parent->schema->nodetype & LYS_ANYDATA)) {
                 /* 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, options);
                 LY_CHECK_RET(rc);
@@ -5974,8 +5977,8 @@
                 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)) {
+                    /* skip anydata/anyxml nodes */
+                    if (sub->schema->nodetype & LYS_ANYDATA) {
                         continue;
                     }
 
@@ -6040,8 +6043,8 @@
             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)) {
+        /* skip anydata/anyxml nodes */
+        if (set->val.nodes[i].node->schema->nodetype & LYS_ANYDATA) {
             continue;
         }
 
@@ -6095,7 +6098,12 @@
     /* add all the children, they get added recursively */
     for (i = 0; i < set->used; ++i) {
         if (set->val.scnodes[i].in_ctx != 1) {
-            continue;
+            if (set->val.scnodes[i].in_ctx != -2) {
+                continue;
+            }
+
+            /* remember context node (it was traversed again so it changes to a normal node) */
+            set->val.scnodes[i].in_ctx = 1;
         }
 
         /* add all the children */
@@ -6239,9 +6247,13 @@
     orig_used = set->used;
     for (i = 0; i < orig_used; ++i) {
         if (set->val.scnodes[i].in_ctx != 1) {
-            continue;
+            if (set->val.scnodes[i].in_ctx != -2) {
+                continue;
+            }
+
+            /* remember context node */
+            set->val.scnodes[i].in_ctx = -1;
         }
-        set->val.scnodes[i].in_ctx = 0;
 
         node = set->val.scnodes[i].scnode;
 
@@ -6613,7 +6625,7 @@
 
             if ((rc == LY_SUCCESS) && set && (options & LYXP_SCNODE_ALL)) {
                 for (i = set->used - 1; i > -1; --i) {
-                    if (set->val.scnodes[i].in_ctx) {
+                    if (set->val.scnodes[i].in_ctx > 0) {
                         break;
                     }
                 }
@@ -6692,7 +6704,8 @@
 {
     LY_ERR rc;
     uint16_t i, orig_exp;
-    uint32_t orig_pos, orig_size, pred_in_ctx;
+    uint32_t orig_pos, orig_size;
+    int32_t pred_in_ctx;
     struct lyxp_set set2;
     struct lyd_node *orig_parent;
 
@@ -8307,6 +8320,7 @@
     memset(set, 0, sizeof *set);
     set->type = LYXP_SET_SCNODE_SET;
     lyxp_set_scnode_insert_node(set, ctx_scnode, ctx_scnode_type);
+    set->val.scnodes[0].in_ctx = -2;
     set->ctx = ctx;
     set->ctx_scnode = ctx_scnode;
     set->root_type = lyxp_get_root_type(NULL, ctx_scnode, options);
diff --git a/src/xpath.h b/src/xpath.h
index 1e27ab1..a0e45a1 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -214,11 +214,13 @@
         struct lyxp_set_scnode {
             struct lysc_node *scnode;
             enum lyxp_node_type type;
-            /* 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,
+            /* -2 - scnode not traversed, currently (the only node) in context;
+             * -1 - scnode not traversed except for the eval start, not currently in the context;
+             * 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;
+            int32_t in_ctx;
         } *scnodes;
         struct lyxp_set_attr {
             struct lyd_attr *attr;
diff --git a/tests/src/test_tree_schema_compile.c b/tests/src/test_tree_schema_compile.c
index de53e76..260e4dc 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/src/test_tree_schema_compile.c
@@ -758,7 +758,7 @@
     assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
 
     assert_non_null(mod = lys_parse_mem(ctx, "module a {namespace urn:a;prefix a;feature f;"
-                                        "choice ch {default a:b; when a2; case a {leaf a1 {type string;}leaf a2 {type string;}}"
+                                        "choice ch {default a:b; when \"true()\"; case a {leaf a1 {type string;}leaf a2 {type string;}}"
                                         "leaf b {type string;}}}", LYS_IN_YANG));
     ch = (struct lysc_node_choice*)mod->compiled->data;
     assert_non_null(ch);
@@ -3491,6 +3491,49 @@
     , LYS_IN_YANG));
     logbuf_assert("When condition of \"cont2\" includes a self-reference (referenced by when of \"val\").");
 
+    assert_null(lys_parse_mem(ctx,
+        "module a {"
+            "namespace urn:a;"
+            "prefix a;"
+            "leaf val {"
+                "type int64;"
+                "when \"../val='25'\";"
+            "}"
+        "}"
+    , LYS_IN_YANG));
+    logbuf_assert("When condition of \"val\" is accessing its own conditional node.");
+
+    assert_null(lys_parse_mem(ctx,
+        "module a {"
+            "namespace urn:a;"
+            "prefix a;"
+            "grouping grp {"
+                "leaf val {"
+                    "type int64;"
+                "}"
+            "}"
+            "uses grp {"
+                "when \"val='25'\";"
+            "}"
+        "}"
+    , LYS_IN_YANG));
+    logbuf_assert("When condition of \"val\" is accessing its own conditional node.");
+
+    assert_null(lys_parse_mem(ctx,
+        "module a {"
+            "namespace urn:a;"
+            "prefix a;"
+            "augment /cont {"
+                "when \"val='25'\";"
+                "leaf val {"
+                    "type int64;"
+                "}"
+            "}"
+            "container cont;"
+        "}"
+    , LYS_IN_YANG));
+    logbuf_assert("When condition of \"val\" is accessing its own conditional node.");
+
     *state = NULL;
     ly_ctx_destroy(ctx, NULL);
 }