schema CHANGE move when statement from common schema node structure

The when statement is not present in many of the lysc_node* and
lysp_node* structures. It is actually similar to the must statement
which is placed in the specific schema node structures, so it make sense
to move the when statement to the same place.

Some helpers functions to access the musts and whens were added.
diff --git a/src/printer_yang.c b/src/printer_yang.c
index 57d9f12..925b1f3 100644
--- a/src/printer_yang.c
+++ b/src/printer_yang.c
@@ -1236,7 +1236,7 @@
     LEVEL++;
 
     yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, node->exts, flag, 0);
-    yprp_when(ctx, node->when, flag);
+    yprp_when(ctx, lysp_node_when(node), flag);
     yprp_iffeatures(ctx, node->iffeatures, node->exts, flag);
 }
 
@@ -1244,13 +1244,16 @@
 yprc_node_common1(struct ypr_ctx *ctx, const struct lysc_node *node, ly_bool *flag)
 {
     LY_ARRAY_COUNT_TYPE u;
+    struct lysc_when **when;
 
     ly_print_(ctx->out, "%*s%s %s%s", INDENT, lys_nodetype2str(node->nodetype), node->name, flag ? "" : " {\n");
     LEVEL++;
 
     yprc_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, node->exts, flag, 0);
-    LY_ARRAY_FOR(node->when, u) {
-        yprc_when(ctx, node->when[u], flag);
+
+    when = lysc_node_when(node);
+    LY_ARRAY_FOR(when, u) {
+        yprc_when(ctx, when[u], flag);
     }
 }
 
diff --git a/src/printer_yin.c b/src/printer_yin.c
index a316bce..6107c42 100644
--- a/src/printer_yin.c
+++ b/src/printer_yin.c
@@ -670,7 +670,7 @@
     LEVEL++;
 
     yprp_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, node->exts, flag, 0);
-    yprp_when(ctx, node->when, flag);
+    yprp_when(ctx, lysp_node_when(node), flag);
     yprp_iffeatures(ctx, node->iffeatures, node->exts, flag);
 }
 
diff --git a/src/schema_compile.c b/src/schema_compile.c
index a692b7b..bf8fc29 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -764,7 +764,6 @@
     struct lyxp_set_scnode *xp_scnode;
     uint32_t i, j;
     LY_ARRAY_COUNT_TYPE u;
-    struct lysc_when *when;
     LY_ERR ret = LY_SUCCESS;
 
     memset(&tmp_set, 0, sizeof tmp_set);
@@ -787,7 +786,7 @@
         }
 
         if ((xp_scnode->type != LYXP_NODE_ELEM) || (xp_scnode->scnode->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) ||
-                !xp_scnode->scnode->when) {
+                !lysc_node_when(xp_scnode->scnode)) {
             /* no when to check */
             xp_scnode->in_ctx = LYXP_SET_SCNODE_ATOM;
             continue;
@@ -795,9 +794,12 @@
 
         node = xp_scnode->scnode;
         do {
+            struct lysc_when **when_list, *when;
+
             LOG_LOCSET(node, NULL, NULL, NULL);
-            LY_ARRAY_FOR(node->when, u) {
-                when = node->when[u];
+            when_list = lysc_node_when(node);
+            LY_ARRAY_FOR(when_list, u) {
+                when = when_list[u];
                 ret = lyxp_atomize(set->ctx, when->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when->prefixes,
                         when->context, &tmp_set, LYXP_SCNODE_SCHEMA);
                 if (ret != LY_SUCCESS) {
@@ -922,7 +924,7 @@
     uint32_t i, opts;
     LY_ARRAY_COUNT_TYPE u;
     ly_bool input_done = 0;
-    struct lysc_when **when = NULL;
+    struct lysc_when **whens = NULL;
     struct lysc_must *musts = NULL;
     LY_ERR ret = LY_SUCCESS;
     const struct lysc_node *op;
@@ -940,67 +942,27 @@
         }
     }
 
-    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:
-        when = ((struct lysc_node_notif *)node)->when;
-        musts = ((struct lysc_node_notif *)node)->musts;
-        break;
-    case LYS_RPC:
-    case LYS_ACTION:
-        /* first process when and input musts */
-        when = ((struct lysc_node_action *)node)->when;
-        musts = ((struct lysc_node_action *)node)->input.musts;
-        break;
-    default:
-        /* nothing to check */
-        break;
-    }
+    whens = lysc_node_when(node);
+    musts = lysc_node_musts(node);
 
-    LY_ARRAY_FOR(when, u) {
+    LY_ARRAY_FOR(whens, u) {
         /* first check whether all the referenced modules are implemented */
         mod = NULL;
-        ret = lys_compile_expr_implement(ctx->ctx, when[u]->cond, LY_PREF_SCHEMA_RESOLVED, when[u]->prefixes,
+        ret = lys_compile_expr_implement(ctx->ctx, whens[u]->cond, LY_PREF_SCHEMA_RESOLVED, whens[u]->prefixes,
                 ctx->ctx->flags & LY_CTX_REF_IMPLEMENTED, unres, &mod);
         if (ret) {
             goto cleanup;
         } else if (mod) {
             LOGWRN(ctx->ctx, "When condition \"%s\" check skipped because referenced module \"%s\" is not implemented.",
-                    when[u]->cond->expr, mod->name);
+                    whens[u]->cond->expr, mod->name);
             continue;
         }
 
         /* check "when" */
-        ret = lyxp_atomize(ctx->ctx, when[u]->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when[u]->prefixes,
-                when[u]->context, &tmp_set, opts);
+        ret = lyxp_atomize(ctx->ctx, whens[u]->cond, node->module, LY_PREF_SCHEMA_RESOLVED, whens[u]->prefixes,
+                whens[u]->context, &tmp_set, opts);
         if (ret) {
-            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when[u]->cond->expr);
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid when condition \"%s\".", whens[u]->cond->expr);
             goto cleanup;
         }
 
@@ -1012,7 +974,7 @@
                 struct lysc_node *schema = tmp_set.val.scnodes[i].scnode;
 
                 /* XPath expression cannot reference "lower" status than the node that has the definition */
-                ret = lysc_check_status(ctx, when[u]->flags, node->module, node->name, schema->flags, schema->module,
+                ret = lysc_check_status(ctx, whens[u]->flags, node->module, node->name, schema->flags, schema->module,
                         schema->name);
                 LY_CHECK_GOTO(ret, cleanup);
 
@@ -1072,7 +1034,7 @@
     if ((node->nodetype & (LYS_RPC | LYS_ACTION)) && !input_done) {
         /* now check output musts */
         input_done = 1;
-        when = NULL;
+        whens = NULL;
         musts = ((struct lysc_node_action *)node)->output.musts;
         opts = LYXP_SCNODE_OUTPUT;
         goto check_musts;
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index c491f32..240804c 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -386,19 +386,19 @@
     DUP_STRING(ctx, orig->name, node->name, ret);
     DUP_STRING(ctx, orig->dsc, node->dsc, ret);
     DUP_STRING(ctx, orig->ref, node->ref, ret);
-
-    if (orig->when) {
-        node->when = calloc(1, sizeof *node->when);
-        LY_CHECK_ERR_RET(!node->when, LOGMEM(ctx), LY_EMEM);
-        LY_CHECK_RET(lysp_when_dup(ctx, node->when, orig->when));
-    }
-
     DUP_ARRAY(ctx, orig->iffeatures, node->iffeatures, lysp_qname_dup);
     DUP_ARRAY(ctx, orig->exts, node->exts, lysp_ext_dup);
 
     return ret;
 }
 
+#define DUP_PWHEN(CTX, ORIG, NEW) \
+    if (ORIG) { \
+        NEW = calloc(1, sizeof *NEW); \
+        LY_CHECK_ERR_RET(!NEW, LOGMEM(CTX), LY_EMEM); \
+        LY_CHECK_RET(lysp_when_dup(CTX, NEW, ORIG)); \
+    }
+
 static LY_ERR
 lysp_node_dup(const struct ly_ctx *ctx, struct lysp_node *node, const struct lysp_node *orig)
 {
@@ -436,6 +436,7 @@
         cont = (struct lysp_node_container *)node;
         orig_cont = (const struct lysp_node_container *)orig;
 
+        DUP_PWHEN(ctx, orig_cont->when, cont->when);
         DUP_ARRAY(ctx, orig_cont->musts, cont->musts, lysp_restr_dup);
         DUP_STRING(ctx, orig_cont->presence, cont->presence, ret);
         /* we do not need the rest */
@@ -444,6 +445,7 @@
         leaf = (struct lysp_node_leaf *)node;
         orig_leaf = (const struct lysp_node_leaf *)orig;
 
+        DUP_PWHEN(ctx, orig_leaf->when, leaf->when);
         DUP_ARRAY(ctx, orig_leaf->musts, leaf->musts, lysp_restr_dup);
         LY_CHECK_RET(lysp_type_dup(ctx, &leaf->type, &orig_leaf->type));
         DUP_STRING(ctx, orig_leaf->units, leaf->units, ret);
@@ -453,6 +455,7 @@
         llist = (struct lysp_node_leaflist *)node;
         orig_llist = (const struct lysp_node_leaflist *)orig;
 
+        DUP_PWHEN(ctx, orig_llist->when, llist->when);
         DUP_ARRAY(ctx, orig_llist->musts, llist->musts, lysp_restr_dup);
         LY_CHECK_RET(lysp_type_dup(ctx, &llist->type, &orig_llist->type));
         DUP_STRING(ctx, orig_llist->units, llist->units, ret);
@@ -464,6 +467,7 @@
         list = (struct lysp_node_list *)node;
         orig_list = (const struct lysp_node_list *)orig;
 
+        DUP_PWHEN(ctx, orig_list->when, list->when);
         DUP_ARRAY(ctx, orig_list->musts, list->musts, lysp_restr_dup);
         DUP_STRING(ctx, orig_list->key, list->key, ret);
         /* we do not need these arrays */
@@ -475,6 +479,7 @@
         choice = (struct lysp_node_choice *)node;
         orig_choice = (const struct lysp_node_choice *)orig;
 
+        DUP_PWHEN(ctx, orig_choice->when, choice->when);
         /* we do not need children */
         LY_CHECK_RET(lysp_qname_dup(ctx, &choice->dflt, &orig_choice->dflt));
         break;
@@ -482,15 +487,15 @@
         cas = (struct lysp_node_case *)node;
         orig_cas = (const struct lysp_node_case *)orig;
 
+        DUP_PWHEN(ctx, orig_cas->when, cas->when);
         /* we do not need children */
-        (void)cas;
-        (void)orig_cas;
         break;
     case LYS_ANYDATA:
     case LYS_ANYXML:
         any = (struct lysp_node_anydata *)node;
         orig_any = (const struct lysp_node_anydata *)orig;
 
+        DUP_PWHEN(ctx, orig_any->when, any->when);
         DUP_ARRAY(ctx, orig_any->musts, any->musts, lysp_restr_dup);
         break;
     case LYS_RPC:
@@ -855,23 +860,8 @@
 
     /* *must-stmt */
     if (d->musts) {
-        switch (target->nodetype) {
-        case LYS_CONTAINER:
-        case LYS_LIST:
-        case LYS_LEAF:
-        case LYS_LEAFLIST:
-        case LYS_ANYDATA:
-        case LYS_ANYXML:
-            musts = &((struct lysp_node_container *)target)->musts;
-            break;
-        case LYS_NOTIF:
-            musts = &((struct lysp_node_notif *)target)->musts;
-            break;
-        case LYS_INPUT:
-        case LYS_OUTPUT:
-            musts = &((struct lysp_node_action_inout *)target)->musts;
-            break;
-        default:
+        musts = lysp_node_musts_p(target);
+        if (!musts) {
             AMEND_WRONG_NODETYPE("deviation", "add", "must");
         }
 
@@ -1098,23 +1088,8 @@
 
     /* *must-stmt */
     if (d->musts) {
-        switch (target->nodetype) {
-        case LYS_CONTAINER:
-        case LYS_LIST:
-        case LYS_LEAF:
-        case LYS_LEAFLIST:
-        case LYS_ANYDATA:
-        case LYS_ANYXML:
-            musts = &((struct lysp_node_container *)target)->musts;
-            break;
-        case LYS_NOTIF:
-            musts = &((struct lysp_node_notif *)target)->musts;
-            break;
-        case LYS_INPUT:
-        case LYS_OUTPUT:
-            musts = &((struct lysp_node_action_inout *)target)->musts;
-            break;
-        default:
+        musts = lysp_node_musts_p(target);
+        if (!musts) {
             AMEND_WRONG_NODETYPE("deviation", "delete", "must");
         }
 
@@ -1375,42 +1350,6 @@
 }
 
 /**
- * @brief Check whether a parsed node matches a single schema nodeid name test.
- *
- * @param[in] pnode Parsed node to consider.
- * @param[in] pnode_mod Compiled @p pnode to-be module.
- * @param[in] mod Expected module.
- * @param[in] name Expected name.
- * @param[in] name_len Length of @p name.
- * @return Whether it is a match or not.
- */
-static ly_bool
-lysp_schema_nodeid_match_pnode(const struct lysp_node *pnode, const struct lys_module *pnode_mod,
-        const struct lys_module *mod, const char *name, size_t name_len)
-{
-    const char *pname;
-
-    /* compare with the module of the node */
-    if (pnode_mod != mod) {
-        return 0;
-    }
-
-    /* compare names */
-    if (pnode->nodetype & (LYS_ACTION | LYS_RPC)) {
-        pname = ((struct lysp_node_action *)pnode)->name;
-    } else if (pnode->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
-        pname = (pnode->nodetype & LYS_INPUT) ? "input" : "output";
-    } else {
-        pname = pnode->name;
-    }
-    if (ly_strncmp(pname, name, name_len)) {
-        return 0;
-    }
-
-    return 1;
-}
-
-/**
  * @brief Check whether a compiled node matches a single schema nodeid name test.
  *
  * @param[in,out] node Compiled node to consider. On a match it is moved to its parent.
@@ -1477,7 +1416,7 @@
 
     if (pnode) {
         /* compare on the last parsed-only node */
-        if (!lysp_schema_nodeid_match_pnode(pnode, pnode_mod, mod, name, name_len)) {
+        if (pnode_mod != mod || ly_strncmp(pnode->name, name, name_len)) {
             return 0;
         }
     } else {
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 960abaa..e64b54d 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -257,13 +257,7 @@
     assert(when_p);
 
     /* get the when array */
-    if (node->nodetype & LYS_ACTION) {
-        node_when = &((struct lysc_node_action *)node)->when;
-    } else if (node->nodetype == LYS_NOTIF) {
-        node_when = &((struct lysc_node_notif *)node)->when;
-    } else {
-        node_when = &node->when;
-    }
+    node_when = lysc_node_when_p(node);
 
     /* create new when pointer */
     LY_ARRAY_NEW_RET(ctx->ctx, *node_when, new_when, LY_EMEM);
@@ -2271,6 +2265,7 @@
     LY_ERR ret = LY_SUCCESS;
     ly_bool not_supported, enabled;
     struct lysp_node *dev_pnode = NULL;
+    struct lysp_when *pwhen = NULL;
 
     node->nodetype = pnode->nodetype;
     node->module = ctx->cur_mod;
@@ -2322,9 +2317,9 @@
     /* insert into parent's children/compiled module (we can no longer free the node separately on error) */
     LY_CHECK_GOTO(ret = lys_compile_node_connect(ctx, parent, node), cleanup);
 
-    if (pnode->when) {
+    if ((pwhen = lysp_node_when(pnode))) {
         /* compile when */
-        ret = lys_compile_when(ctx, pnode->when, pnode->flags, lysc_data_node(node), node, NULL);
+        ret = lys_compile_when(ctx, pwhen, pnode->flags, lysc_data_node(node), node, NULL);
         LY_CHECK_GOTO(ret, cleanup);
     }
 
diff --git a/src/tree_data.c b/src/tree_data.c
index 95af572..93e3d99 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1534,11 +1534,11 @@
             if (!(iter->flags & LYS_PRESENCE) && lyd_find_sibling_val(*first, iter, NULL, 0, NULL)) {
                 /* create default NP container */
                 LY_CHECK_RET(lyd_create_inner(iter, &node));
-                node->flags = LYD_DEFAULT | (node->schema->when ? LYD_WHEN_TRUE : 0);
+                node->flags = LYD_DEFAULT | (lysc_node_when(node->schema) ? LYD_WHEN_TRUE : 0);
                 lyd_insert_node(parent, first, node);
 
                 /* cannot be a NP container with when */
-                assert(!iter->when);
+                assert(!lysc_node_when(iter));
 
                 if (diff) {
                     /* add into diff */
@@ -1563,10 +1563,10 @@
                 } else if (ret) {
                     return ret;
                 }
-                node->flags = LYD_DEFAULT | (node->schema->when ? LYD_WHEN_TRUE : 0);
+                node->flags = LYD_DEFAULT | (lysc_node_when(node->schema) ? LYD_WHEN_TRUE : 0);
                 lyd_insert_node(parent, first, node);
 
-                if (iter->when && node_when) {
+                if (lysc_node_when(iter) && node_when) {
                     /* remember to resolve when */
                     LY_CHECK_RET(ly_set_add(node_when, node, 1, NULL));
                 }
@@ -1591,10 +1591,10 @@
                     } else if (ret) {
                         return ret;
                     }
-                    node->flags = LYD_DEFAULT | (node->schema->when ? LYD_WHEN_TRUE : 0);
+                    node->flags = LYD_DEFAULT | (lysc_node_when(node->schema) ? LYD_WHEN_TRUE : 0);
                     lyd_insert_node(parent, first, node);
 
-                    if (iter->when && node_when) {
+                    if (lysc_node_when(iter) && node_when) {
                         /* remember to resolve when */
                         LY_CHECK_RET(ly_set_add(node_when, node, 1, NULL));
                     }
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 027e964..b5e62ce 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -925,7 +925,6 @@
     const char *name;                /**< node name (mandatory) */
     const char *dsc;                 /**< description statement */
     const char *ref;                 /**< reference statement */
-    struct lysp_when *when;          /**< when statement */
     struct lysp_qname *iffeatures;   /**< list of if-feature expressions ([sized array](@ref sizedarrays)),
                                           must be qname because of refines */
     struct lysp_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
@@ -945,7 +944,6 @@
             const char *name;        /**< node name (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -953,6 +951,7 @@
 
     /* container */
     struct lysp_restr *musts;        /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysp_when *when;          /**< when statement */
     const char *presence;            /**< presence description */
     struct lysp_tpdf *typedefs;      /**< list of typedefs ([sized array](@ref sizedarrays)) */
     struct lysp_node_grp *groupings; /**< list of groupings (linked list) */
@@ -972,7 +971,6 @@
             const char *name;        /**< node name (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -980,6 +978,7 @@
 
     /* leaf */
     struct lysp_restr *musts;        /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysp_when *when;          /**< when statement */
     struct lysp_type type;           /**< type of the leaf node (mandatory) */
     const char *units;               /**< units of the leaf's type */
     struct lysp_qname dflt;          /**< default value, it may or may not be a qualified name */
@@ -996,7 +995,6 @@
             const char *name;        /**< node name (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1004,6 +1002,7 @@
 
     /* leaf-list */
     struct lysp_restr *musts;        /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysp_when *when;          /**< when statement */
     struct lysp_type type;           /**< type of the leaf node (mandatory) */
     const char *units;               /**< units of the leaf's type */
     struct lysp_qname *dflts;        /**< list of default values ([sized array](@ref sizedarrays)), they may or
@@ -1023,7 +1022,6 @@
             const char *name;        /**< node name (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1031,6 +1029,7 @@
 
     /* list */
     struct lysp_restr *musts;        /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysp_when *when;          /**< when statement */
     const char *key;                 /**< keys specification */
     struct lysp_tpdf *typedefs;      /**< list of typedefs ([sized array](@ref sizedarrays)) */
     struct lysp_node_grp *groupings; /**< list of groupings (linked list) */
@@ -1053,7 +1052,6 @@
             const char *name;        /**< node name (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1061,6 +1059,7 @@
 
     /* choice */
     struct lysp_node *child;         /**< list of data nodes (linked list) */
+    struct lysp_when *when;          /**< when statement */
     struct lysp_qname dflt;          /**< default case */
 };
 
@@ -1075,7 +1074,6 @@
             const char *name;        /**< node name (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1083,6 +1081,7 @@
 
     /* case */
     struct lysp_node *child;         /**< list of data nodes (linked list) */
+    struct lysp_when *when;          /**< when statement */
 };
 
 struct lysp_node_anydata {
@@ -1096,7 +1095,6 @@
             const char *name;        /**< node name (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1104,6 +1102,7 @@
 
     /* anyxml/anydata */
     struct lysp_restr *musts;        /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysp_when *when;          /**< when statement */
 };
 
 struct lysp_node_uses {
@@ -1117,7 +1116,6 @@
             const char *name;        /**< grouping name reference (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1126,6 +1124,7 @@
     /* uses */
     struct lysp_refine *refines;     /**< list of uses's refines ([sized array](@ref sizedarrays)) */
     struct lysp_node_augment *augments; /**< list of augments (linked list) */
+    struct lysp_when *when;          /**< when statement */
 };
 
 /**
@@ -1142,7 +1141,6 @@
             const char *name;        /**< empty string */
             const char *dsc;         /**< ALWAYS NULL, compatibility member with ::lysp_node */
             const char *ref;         /**< ALWAYS NULL, compatibility member with ::lysp_node */
-            struct lysp_when *when;  /**< ALWAYS NULL, compatibility member with ::lysp_node */
             struct lysp_qname *iffeatures; /**< ALWAYS NULL, compatibility member with ::lysp_node */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1169,7 +1167,6 @@
             const char *name;        /**< grouping name reference (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< ALWAYS NULL, compatibility member with ::lysp_node */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1197,7 +1194,6 @@
             const char *name;        /**< grouping name reference (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< ALWAYS NULL, compatibility member with ::lysp_node */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1224,7 +1220,6 @@
             const char *name;        /**< grouping name (mandatory) */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< ALWAYS NULL, compatibility member with ::lysp_node */
             struct lysp_qname *iffeatures; /**< ALWAYS NULL, compatibility member with ::lysp_node */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
@@ -1252,13 +1247,13 @@
             const char *nodeid;      /**< target schema nodeid (mandatory) - absolute for global augments, descendant for uses's augments */
             const char *dsc;         /**< description statement */
             const char *ref;         /**< reference statement */
-            struct lysp_when *when;  /**< when statement */
             struct lysp_qname *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
             struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
         };
     };                                /**< common part corresponding to ::lysp_node */
 
     struct lysp_node *child;         /**< list of data nodes (linked list) */
+    struct lysp_when *when;          /**< when statement */
     struct lysp_node_action *actions;/**< list of actions (linked list) */
     struct lysp_node_notif *notifs;  /**< list of notifications (linked list) */
 };
@@ -1602,7 +1597,6 @@
     const char *dsc;                 /**< description */
     const char *ref;                 /**< reference */
     struct lysc_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-    struct lysc_when **when;         /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
     void *priv;                      /**< private arbitrary user data, not used by libyang */
 };
 
@@ -1622,12 +1616,11 @@
             const char *dsc;         /**< ALWAYS NULL, compatibility member with ::lysc_node */
             const char *ref;         /**< ALWAYS NULL, compatibility member with ::lysc_node */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /** private arbitrary user data, not used by libyang */
         };
     };
 
-    struct lysc_node *child;          /**< first child node (linked list) */
+    struct lysc_node *child;         /**< first child node (linked list) */
     struct lysc_must *musts;         /**< list of must restrictions ([sized array](@ref sizedarrays)) */
 };
 
@@ -1649,11 +1642,13 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< ALWAYS NULL, compatibility member with ::lysc_node */
             void *priv;              /** private arbitrary user data, not used by libyang */
         };
     };
 
+    struct lysc_when **when;         /**< list of pointers to when statements ([sized array](@ref sizedarrays)),
+                                          the action/RPC nodes do not contain the when statement on their own, but they can
+                                          inherit it from the parent's uses. */
     struct lysc_node_action_inout input;  /**< RPC's/action's input */
     struct lysc_node_action_inout output; /**< RPC's/action's output */
 
@@ -1677,13 +1672,15 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /** private arbitrary user data, not used by libyang */
         };
     };
 
-    struct lysc_node *child;          /**< first child node (linked list) */
+    struct lysc_node *child;         /**< first child node (linked list) */
     struct lysc_must *musts;         /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysc_when **when;         /**< list of pointers to when statements ([sized array](@ref sizedarrays)),
+                                          the notification nodes do not contain the when statement on their own, but they can
+                                          inherit it from the parent's uses. */
 };
 
 struct lysc_node_container {
@@ -1704,13 +1701,13 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /**< private arbitrary user data, not used by libyang */
         };
     };
 
     struct lysc_node *child;         /**< first child node (linked list) */
     struct lysc_must *musts;         /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysc_when **when;         /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
     struct lysc_node_action *actions;/**< first of actions nodes (linked list) */
     struct lysc_node_notif *notifs;  /**< first of notifications nodes (linked list) */
 };
@@ -1733,13 +1730,13 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /**< private arbitrary user data, not used by libyang */
         };
     };
 
     struct lysc_node *child;         /**< first child node of the case (linked list). Note that all the children of all the sibling cases are linked
                                           each other as siblings with the parent pointer pointing to appropriate case node. */
+    struct lysc_when **when;         /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
 };
 
 struct lysc_node_choice {
@@ -1760,7 +1757,6 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /**< private arbitrary user data, not used by libyang */
         };
     };
@@ -1768,6 +1764,7 @@
     struct lysc_node_case *cases;    /**< list of the cases (linked list). Note that all the children of all the cases are linked each other
                                           as siblings. Their parent pointers points to the specific case they belongs to, so distinguish the
                                           case is simple. */
+    struct lysc_when **when;         /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
     struct lysc_node_case *dflt;     /**< default case of the choice, only a pointer into the cases array. */
 };
 
@@ -1789,12 +1786,12 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /**< private arbitrary user data, not used by libyang */
         };
     };
 
     struct lysc_must *musts;         /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysc_when **when;         /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
     struct lysc_type *type;          /**< type of the leaf node (mandatory) */
 
     const char *units;               /**< units of the leaf's type */
@@ -1819,12 +1816,12 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /**< private arbitrary user data, not used by libyang */
         };
     };
 
     struct lysc_must *musts;         /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysc_when **when;         /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
     struct lysc_type *type;          /**< type of the leaf node (mandatory) */
 
     const char *units;               /**< units of the leaf's type */
@@ -1853,13 +1850,13 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /**< private arbitrary user data, not used by libyang */
         };
     };
 
     struct lysc_node *child;         /**< first child node (linked list) */
     struct lysc_must *musts;         /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
     struct lysc_node_action *actions;/**< first of actions nodes (linked list) */
     struct lysc_node_notif *notifs;  /**< first of notifications nodes (linked list) */
 
@@ -1886,12 +1883,12 @@
             const char *dsc;         /**< description */
             const char *ref;         /**< reference */
             struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-            struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
             void *priv;              /**< private arbitrary user data, not used by libyang */
         };
     };
 
     struct lysc_must *musts;         /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+    struct lysc_when **when; /**< list of pointers to when statements ([sized array](@ref sizedarrays)) */
 };
 
 /**
@@ -2015,6 +2012,24 @@
 const struct lysc_node *lysc_node_children(const struct lysc_node *node, uint16_t flags);
 
 /**
+ * @brief Get the must statements list if present in the @p node
+ *
+ * @param[in] node Node to examine.
+ * @return Pointer to the list of must restrictions ([sized array](@ref sizedarrays))
+ * @return NULL if there is no must statement in the node, no matter if it is not even allowed or just present
+ */
+struct lysc_must *lysc_node_musts(const struct lysc_node *node);
+
+/**
+ * @brief Get the when statements list if present in the @p node
+ *
+ * @param[in] node Node to examine.
+ * @return Pointer to the list of pointers to when statements ([sized array](@ref sizedarrays))
+ * @return NULL if there is no when statement in the node, no matter if it is not even allowed or just present
+ */
+struct lysc_when **lysc_node_when(const struct lysc_node *node);
+
+/**
  * @brief Callback to be called for every schema node in a DFS traversal.
  *
  * @param[in] node Current node.
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 44b3e58..47e1a99 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -318,58 +318,58 @@
 lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node)
 {
     struct lysp_node *child, *next;
+    struct lysp_restr *musts = lysp_node_musts(node);
+    struct lysp_when *when = lysp_node_when(node);
 
     FREE_STRING(ctx, node->name);
     FREE_STRING(ctx, node->dsc);
     FREE_STRING(ctx, node->ref);
-    FREE_MEMBER(ctx, node->when, lysp_when_free);
     FREE_ARRAY(ctx, node->iffeatures, lysp_qname_free);
     FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
 
+    FREE_MEMBER(ctx, when, lysp_when_free);
+    FREE_ARRAY(ctx, musts, lysp_restr_free);
+
     switch (node->nodetype) {
     case LYS_CONTAINER:
-        FREE_ARRAY(ctx, ((struct lysp_node_container *)node)->musts, lysp_restr_free);
         FREE_STRING(ctx, ((struct lysp_node_container *)node)->presence);
         FREE_ARRAY(ctx, ((struct lysp_node_container *)node)->typedefs, lysp_tpdf_free);
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_container *)node)->groupings, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_container *)node)->groupings->node, next, child) {
             lysp_node_free(ctx, child);
         }
         LY_LIST_FOR_SAFE(((struct lysp_node_container *)node)->child, next, child) {
             lysp_node_free(ctx, child);
         }
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_container *)node)->actions, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_container *)node)->actions->node, next, child) {
             lysp_node_free(ctx, child);
         }
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_container *)node)->notifs, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_container *)node)->notifs->node, next, child) {
             lysp_node_free(ctx, child);
         }
         break;
     case LYS_LEAF:
-        FREE_ARRAY(ctx, ((struct lysp_node_leaf *)node)->musts, lysp_restr_free);
         lysp_type_free(ctx, &((struct lysp_node_leaf *)node)->type);
         FREE_STRING(ctx, ((struct lysp_node_leaf *)node)->units);
         FREE_STRING(ctx, ((struct lysp_node_leaf *)node)->dflt.str);
         break;
     case LYS_LEAFLIST:
-        FREE_ARRAY(ctx, ((struct lysp_node_leaflist *)node)->musts, lysp_restr_free);
         lysp_type_free(ctx, &((struct lysp_node_leaflist *)node)->type);
         FREE_STRING(ctx, ((struct lysp_node_leaflist *)node)->units);
         FREE_ARRAY(ctx, ((struct lysp_node_leaflist *)node)->dflts, lysp_qname_free);
         break;
     case LYS_LIST:
-        FREE_ARRAY(ctx, ((struct lysp_node_list *)node)->musts, lysp_restr_free);
         FREE_STRING(ctx, ((struct lysp_node_list *)node)->key);
         FREE_ARRAY(ctx, ((struct lysp_node_list *)node)->typedefs, lysp_tpdf_free);
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_list *)node)->groupings, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_list *)node)->groupings->node, next, child) {
             lysp_node_free(ctx, child);
         }
         LY_LIST_FOR_SAFE(((struct lysp_node_list *)node)->child, next, child) {
             lysp_node_free(ctx, child);
         }
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_list *)node)->actions, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_list *)node)->actions->node, next, child) {
             lysp_node_free(ctx, child);
         }
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_list *)node)->notifs, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_list *)node)->notifs->node, next, child) {
             lysp_node_free(ctx, child);
         }
         FREE_ARRAY(ctx, ((struct lysp_node_list *)node)->uniques, lysp_qname_free);
@@ -387,32 +387,31 @@
         break;
     case LYS_ANYDATA:
     case LYS_ANYXML:
-        FREE_ARRAY(ctx, ((struct lysp_node_anydata *)node)->musts, lysp_restr_free);
+        /* nothing special to do */
         break;
     case LYS_USES:
         FREE_ARRAY(ctx, ((struct lysp_node_uses *)node)->refines, lysp_refine_free);
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_uses *)node)->augments, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_uses *)node)->augments->node, next, child) {
             lysp_node_free(ctx, child);
         }
         break;
     case LYS_RPC:
     case LYS_ACTION:
         FREE_ARRAY(ctx, ((struct lysp_node_action *)node)->typedefs, lysp_tpdf_free);
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_action *)node)->groupings, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_action *)node)->groupings->node, next, child) {
             lysp_node_free(ctx, child);
         }
         if (((struct lysp_node_action *)node)->input.nodetype) {
-            lysp_node_free(ctx, (struct lysp_node *)&((struct lysp_node_action *)node)->input);
+            lysp_node_free(ctx, &((struct lysp_node_action *)node)->input.node);
         }
         if (((struct lysp_node_action *)node)->output.nodetype) {
-            lysp_node_free(ctx, (struct lysp_node *)&((struct lysp_node_action *)node)->output);
+            lysp_node_free(ctx, &((struct lysp_node_action *)node)->output.node);
         }
         break;
     case LYS_INPUT:
     case LYS_OUTPUT:
-        FREE_ARRAY(ctx, ((struct lysp_node_action_inout *)node)->musts, lysp_restr_free);
         FREE_ARRAY(ctx, ((struct lysp_node_action_inout *)node)->typedefs, lysp_tpdf_free);
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_action_inout *)node)->groupings, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_action_inout *)node)->groupings->node, next, child) {
             lysp_node_free(ctx, child);
         }
         LY_LIST_FOR_SAFE(((struct lysp_node_action_inout *)node)->child, next, child) {
@@ -421,9 +420,8 @@
         /* do not free the node, it is never standalone but part of the action node */
         return;
     case LYS_NOTIF:
-        FREE_ARRAY(ctx, ((struct lysp_node_notif *)node)->musts, lysp_restr_free);
         FREE_ARRAY(ctx, ((struct lysp_node_notif *)node)->typedefs, lysp_tpdf_free);
-        LY_LIST_FOR_SAFE((struct lysp_node *)((struct lysp_node_notif *)node)->groupings, next, child) {
+        LY_LIST_FOR_SAFE(&((struct lysp_node_notif *)node)->groupings->node, next, child) {
             lysp_node_free(ctx, child);
         }
         LY_LIST_FOR_SAFE(((struct lysp_node_notif *)node)->child, next, child) {
@@ -434,7 +432,7 @@
         lysp_grp_free(ctx, (struct lysp_node_grp *)node);
         break;
     case LYS_AUGMENT:
-        lysp_augment_free(ctx, (struct lysp_node_augment *)node);
+        lysp_augment_free(ctx, ((struct lysp_node_augment *)node));
         break;
     default:
         LOGINT(ctx);
@@ -708,12 +706,14 @@
     LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
         lysc_node_free_(ctx, child);
     }
+    FREE_ARRAY(ctx, node->when, lysc_when_free);
     FREE_ARRAY(ctx, node->musts, lysc_must_free);
 }
 
 static void
 lysc_node_leaf_free(struct ly_ctx *ctx, struct lysc_node_leaf *node)
 {
+    FREE_ARRAY(ctx, node->when, lysc_when_free);
     FREE_ARRAY(ctx, node->musts, lysc_must_free);
     if (node->type) {
         lysc_type_free(ctx, node->type);
@@ -731,6 +731,7 @@
 {
     LY_ARRAY_COUNT_TYPE u;
 
+    FREE_ARRAY(ctx, node->when, lysc_when_free);
     FREE_ARRAY(ctx, node->musts, lysc_must_free);
     if (node->type) {
         lysc_type_free(ctx, node->type);
@@ -753,6 +754,7 @@
     LY_LIST_FOR_SAFE(node->child, child_next, child) {
         lysc_node_free_(ctx, child);
     }
+    FREE_ARRAY(ctx, node->when, lysc_when_free);
     FREE_ARRAY(ctx, node->musts, lysc_must_free);
 
     LY_ARRAY_FOR(node->uniques, u) {
@@ -773,6 +775,7 @@
 {
     struct lysc_node *child, *child_next;
 
+    FREE_ARRAY(ctx, node->when, lysc_when_free);
     LY_LIST_FOR_SAFE((struct lysc_node *)node->cases, child_next, child) {
         lysc_node_free_(ctx, child);
     }
@@ -783,6 +786,7 @@
 {
     struct lysc_node *child, *child_next;
 
+    FREE_ARRAY(ctx, node->when, lysc_when_free);
     LY_LIST_FOR_SAFE(node->child, child_next, child) {
         lysc_node_free_(ctx, child);
     }
@@ -791,6 +795,7 @@
 static void
 lysc_node_anydata_free(struct ly_ctx *ctx, struct lysc_node_anydata *node)
 {
+    FREE_ARRAY(ctx, node->when, lysc_when_free);
     FREE_ARRAY(ctx, node->musts, lysc_must_free);
 }
 
@@ -844,7 +849,6 @@
         LOGINT(ctx);
     }
 
-    FREE_ARRAY(ctx, node->when, lysc_when_free);
     FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
 
     if (!inout) {
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 01878c3..61b7c89 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -1023,30 +1023,17 @@
 API const struct lysc_when *
 lysc_has_when(const struct lysc_node *node)
 {
+    struct lysc_when **when;
+
     if (!node) {
         return NULL;
     }
 
     do {
-        switch (node->nodetype) {
-        case LYS_RPC:
-        case LYS_ACTION:
-            if (((struct lysc_node_action *)node)->when) {
-                return *((struct lysc_node_action *)node)->when;
-            }
-            break;
-        case LYS_NOTIF:
-            if (((struct lysc_node_notif *)node)->when) {
-                return *((struct lysc_node_notif *)node)->when;
-            }
-            break;
-        default:
-            if (node->when) {
-                return *node->when;
-            }
-            break;
+        when = lysc_node_when(node);
+        if (when) {
+            return when[0];
         }
-
         node = node->parent;
     } while (node && (node->nodetype & (LYS_CASE | LYS_CHOICE)));
 
@@ -1286,6 +1273,93 @@
     }
 }
 
+struct lysp_restr **
+lysp_node_musts_p(const struct lysp_node *node)
+{
+    if (!node) {
+        return NULL;
+    }
+
+    switch(node->nodetype) {
+    case LYS_CONTAINER:
+        return &((struct lysp_node_container *)node)->musts;
+    case LYS_LEAF:
+        return &((struct lysp_node_leaf *)node)->musts;
+    case LYS_LEAFLIST:
+        return &((struct lysp_node_leaflist *)node)->musts;
+    case LYS_LIST:
+        return &((struct lysp_node_list *)node)->musts;
+    case LYS_ANYXML:
+    case LYS_ANYDATA:
+        return &((struct lysp_node_anydata *)node)->musts;
+    case LYS_NOTIF:
+        return &((struct lysp_node_notif *)node)->musts;
+    case LYS_INPUT:
+    case LYS_OUTPUT:
+        return &((struct lysp_node_action_inout *)node)->musts;
+    default:
+        return NULL;
+    }
+}
+
+struct lysp_restr *
+lysp_node_musts(const struct lysp_node *node)
+{
+    struct lysp_restr **musts;
+
+    musts = lysp_node_musts_p(node);
+    if (musts) {
+        return *musts;
+    } else {
+        return NULL;
+    }
+}
+
+struct lysp_when **
+lysp_node_when_p(const struct lysp_node *node)
+{
+    if (!node) {
+        return NULL;
+    }
+
+    switch(node->nodetype) {
+    case LYS_CONTAINER:
+        return &((struct lysp_node_container *)node)->when;
+    case LYS_CHOICE:
+        return &((struct lysp_node_choice *)node)->when;
+    case LYS_LEAF:
+        return &((struct lysp_node_leaf *)node)->when;
+    case LYS_LEAFLIST:
+        return &((struct lysp_node_leaflist *)node)->when;
+    case LYS_LIST:
+        return &((struct lysp_node_list *)node)->when;
+    case LYS_ANYXML:
+    case LYS_ANYDATA:
+        return &((struct lysp_node_anydata *)node)->when;
+    case LYS_CASE:
+        return &((struct lysp_node_case *)node)->when;
+    case LYS_USES:
+        return &((struct lysp_node_uses *)node)->when;
+    case LYS_AUGMENT:
+        return &((struct lysp_node_augment *)node)->when;
+    default:
+        return NULL;
+    }
+}
+
+struct lysp_when *
+lysp_node_when(const struct lysp_node *node)
+{
+    struct lysp_when **when;
+
+    when = lysp_node_when_p(node);
+    if (when) {
+        return *when;
+    } else {
+        return NULL;
+    }
+}
+
 struct lysc_node_action **
 lysc_node_actions_p(struct lysc_node *node)
 {
@@ -1397,6 +1471,94 @@
     }
 }
 
+struct lysc_must **
+lysc_node_musts_p(const struct lysc_node *node)
+{
+    if (!node) {
+        return NULL;
+    }
+
+    switch(node->nodetype) {
+    case LYS_CONTAINER:
+        return &((struct lysc_node_container *)node)->musts;
+    case LYS_LEAF:
+        return &((struct lysc_node_leaf *)node)->musts;
+    case LYS_LEAFLIST:
+        return &((struct lysc_node_leaflist *)node)->musts;
+    case LYS_LIST:
+        return &((struct lysc_node_list *)node)->musts;
+    case LYS_ANYXML:
+    case LYS_ANYDATA:
+        return &((struct lysc_node_anydata *)node)->musts;
+    case LYS_NOTIF:
+        return &((struct lysc_node_notif *)node)->musts;
+    case LYS_INPUT:
+    case LYS_OUTPUT:
+        return &((struct lysc_node_action_inout *)node)->musts;
+    default:
+        return NULL;
+    }
+}
+
+API struct lysc_must *
+lysc_node_musts(const struct lysc_node *node)
+{
+    struct lysc_must **must_p;
+
+    must_p = lysc_node_musts_p(node);
+    if (must_p) {
+        return *must_p;
+    } else {
+        return NULL;
+    }
+}
+
+struct lysc_when ***
+lysc_node_when_p(const struct lysc_node *node)
+{
+    if (!node) {
+        return NULL;
+    }
+
+    switch(node->nodetype) {
+    case LYS_CONTAINER:
+        return &((struct lysc_node_container *)node)->when;
+    case LYS_CHOICE:
+        return &((struct lysc_node_choice *)node)->when;
+    case LYS_LEAF:
+        return &((struct lysc_node_leaf *)node)->when;
+    case LYS_LEAFLIST:
+        return &((struct lysc_node_leaflist *)node)->when;
+    case LYS_LIST:
+        return &((struct lysc_node_list *)node)->when;
+    case LYS_ANYXML:
+    case LYS_ANYDATA:
+        return &((struct lysc_node_anydata *)node)->when;
+    case LYS_CASE:
+        return &((struct lysc_node_case *)node)->when;
+    case LYS_NOTIF:
+        return &((struct lysc_node_notif *)node)->when;
+    case LYS_RPC:
+    case LYS_ACTION:
+        return &((struct lysc_node_action *)node)->when;
+    default:
+        return NULL;
+    }
+}
+
+API struct lysc_when **
+lysc_node_when(const struct lysc_node *node)
+{
+    struct lysc_when ***when_p;
+
+    when_p = lysc_node_when_p(node);
+    if (when_p) {
+        return *when_p;
+    } else {
+        return NULL;
+    }
+}
+
 struct lys_module *
 lysp_find_module(struct ly_ctx *ctx, const struct lysp_module *mod)
 {
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index afeefac..c92269b 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -347,6 +347,38 @@
 struct lysp_node **lysp_node_children_p(struct lysp_node *node);
 
 /**
+ * @brief Get the address of the node's musts member, if any.
+ * Decides the node's type and in case it has a musts member, returns its address.
+ * @param[in] node Node to examine.
+ * @return The address of the node's musts member if any, NULL otherwise.
+ */
+struct lysp_restr **lysp_node_musts_p(const struct lysp_node *node);
+
+/**
+ * @brief Get the node's musts member, if any.
+ * Decides the node's type and in case it has a musts member, returns its address.
+ * @param[in] node Node to examine.
+ * @return The node's musts member if any, NULL otherwise.
+ */
+struct lysp_restr *lysp_node_musts(const struct lysp_node *node);
+
+/**
+ * @brief Get the address of the node's when member, if any.
+ * Decides the node's type and in case it has a when, returns it.
+ * @param[in] node Node to examine.
+ * @return The address of the node's when member if any, NULL otherwise.
+ */
+struct lysp_when **lysp_node_when_p(const struct lysp_node *node);
+
+/**
+ * @brief Get the node's when member, if any.
+ * Decides the node's type and in case it has a when, returns it.
+ * @param[in] node Node to examine.
+ * @return The node's when member if any, NULL otherwise.
+ */
+struct lysp_when *lysp_node_when(const struct lysp_node *node);
+
+/**
  * @brief Get address of a node's child pointer if any.
  *
  * Decides the node's type and in case it has a children list, returns its address.
@@ -375,6 +407,24 @@
 struct lysc_node_action **lysc_node_actions_p(struct lysc_node *node);
 
 /**
+ * @brief Get address of a node's when member if any.
+ *
+ * Decides the node's type and in case it has a when member, returns its address.
+ * @param[in] node Node to check.
+ * @return Address of the node's when member if any, NULL otherwise.
+ */
+struct lysc_when ***lysc_node_when_p(const struct lysc_node *node);
+
+/**
+ * @brief Get address of a node's musts member if any.
+ *
+ * Decides the node's type and in case it has a musts member, returns its address.
+ * @param[in] node Node to check.
+ * @return Address of the node's musts member if any, NULL otherwise.
+ */
+struct lysc_must **lysc_node_musts_p(const struct lysc_node *node);
+
+/**
  * @brief Iterate over the specified type of the extension instances
  *
  * @param[in] ext ([Sized array](@ref sizedarrays)) of extensions to explore
diff --git a/src/validation.c b/src/validation.c
index 5c8ebf9..5f26751 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -106,7 +106,6 @@
 {
     LY_ERR ret;
     const struct lyd_node *ctx_node;
-    const struct lysc_when *when;
     struct lyxp_set xp_set;
     LY_ARRAY_COUNT_TYPE u;
 
@@ -115,8 +114,10 @@
     *disabled = NULL;
 
     do {
-        LY_ARRAY_FOR(schema->when, u) {
-            when = schema->when[u];
+        const struct lysc_when *when;
+        struct lysc_when **when_list = lysc_node_when(schema);
+        LY_ARRAY_FOR(when_list, u) {
+            when = when_list[u];
 
             /* get context node */
             if (when->context == schema) {
@@ -1158,44 +1159,22 @@
     struct lyxp_set xp_set;
     struct lysc_must *musts;
     const struct lyd_node *tree;
+    const struct lysc_node *schema;
     LY_ARRAY_COUNT_TYPE u;
 
-    switch (node->schema->nodetype) {
-    case LYS_CONTAINER:
-        musts = ((struct lysc_node_container *)node->schema)->musts;
-        break;
-    case LYS_LEAF:
-        musts = ((struct lysc_node_leaf *)node->schema)->musts;
-        break;
-    case LYS_LEAFLIST:
-        musts = ((struct lysc_node_leaflist *)node->schema)->musts;
-        break;
-    case LYS_LIST:
-        musts = ((struct lysc_node_list *)node->schema)->musts;
-        break;
-    case LYS_ANYXML:
-    case LYS_ANYDATA:
-        musts = ((struct lysc_node_anydata *)node->schema)->musts;
-        break;
-    case LYS_NOTIF:
-        musts = ((struct lysc_node_notif *)node->schema)->musts;
-        break;
-    case LYS_RPC:
-    case LYS_ACTION:
+    if (node->schema->nodetype & (LYS_ACTION | LYS_RPC)) {
         if (op == LYD_VALIDATE_OP_RPC) {
-            musts = ((struct lysc_node_action *)node->schema)->input.musts;
+            schema = &((struct lysc_node_action *)node->schema)->input.node;
         } else if (op == LYD_VALIDATE_OP_REPLY) {
-            musts = ((struct lysc_node_action *)node->schema)->output.musts;
+            schema = &((struct lysc_node_action *)node->schema)->output.node;
         } else {
             LOGINT(LYD_CTX(node));
             return LY_EINT;
         }
-        break;
-    default:
-        LOGINT(LYD_CTX(node));
-        return LY_EINT;
+    } else {
+        schema = node->schema;
     }
-
+    musts = lysc_node_musts(schema);
     if (!musts) {
         /* no must to evaluate */
         return LY_SUCCESS;
@@ -1337,7 +1316,7 @@
                     NULL, impl_opts, diff));
         }
 
-        if (!(node->schema->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && node->schema->when) {
+        if (!(node->schema->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && lysc_node_when(node->schema)) {
             /* when evaluation */
             LY_CHECK_RET(ly_set_add(node_when, (void *)node, 1, NULL));
         }