schema compile WIP partial support for uses's refine
diff --git a/src/common.h b/src/common.h
index dfcc0b3..3a550b8 100644
--- a/src/common.h
+++ b/src/common.h
@@ -283,6 +283,8 @@
  * Generic useful functions.
  *****************************************************************************/
 
+#define FREE_STRING(CTX, STRING) if (STRING) {lydict_remove(CTX, STRING);}
+
 /**
  * @brief Wrapper for realloc() call. The only difference is that if it fails to
  * allocate the requested memory, the original memory is freed as well.
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 6c7253b..9eadc37 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -4507,6 +4507,7 @@
             child->parent = (struct lysp_node*)&mod->groupings[u];
         }
     }
+    /* TODO the same finalization for rpcs and notifications, do also in the relevant nodes */
 
 checks:
     /* mandatory substatements */
diff --git a/src/tree_schema.h b/src/tree_schema.h
index b5f5410..a6ed85e 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -574,6 +574,8 @@
  *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *       9 LYS_KEY          | | |x| | | | | | | | | | | |
  *         LYS_FENABLED     | | | | | | | | | | | |x| | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      10 LYS_SET_DFLT     | | |x| | | |x| | | | | | | |
  *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
  */
@@ -622,6 +624,10 @@
 #define LYS_SET_RANGE    0x0080      /**< type's flag for present range substatement */
 #define LYS_SET_TYPE     0x0100      /**< type's flag for present type substatement */
 #define LYS_SET_REQINST  0x0200      /**< type's flag for present require-instance substatement */
+#define LYS_SET_DFLT     0x0200      /**< flag to mark leaf with own default value, not a default value taken from its type, and default
+                                          cases of choice. This information is important for refines, since it is prohibited to make leafs
+                                          with default statement mandatory. In case the default leaf value is taken from type, it is thrown
+                                          away when it is refined to be mandatory node. */
 
 #define LYS_FLAGS_COMPILED_MASK 0x7f /**< mask for flags that maps to the compiled structures */
 /** @} */
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index bbae473..4761520 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -2707,6 +2707,9 @@
     COMPILE_ARRAY_GOTO(ctx, leaf_p->musts, leaf->musts, options, u, lys_compile_must, ret, done);
     DUP_STRING(ctx->ctx, leaf_p->units, leaf->units);
     DUP_STRING(ctx->ctx, leaf_p->dflt, leaf->dflt);
+    if (leaf->dflt) {
+        leaf->flags |= LYS_SET_DFLT;
+    }
 
     ret = lys_compile_type(ctx, node_p, node_p->flags, ctx->mod_def->parsed, node_p->name, &leaf_p->type, options, &leaf->type,
                            leaf->units ? NULL : &leaf->units, leaf->dflt || (leaf->flags & LYS_MAND_TRUE) ? NULL : &leaf->dflt);
@@ -2906,6 +2909,11 @@
                 return LY_EVALID;
             }
         }
+
+        /* check status */
+        LY_CHECK_RET(lysc_check_status(ctx, list->flags, list->module, list->name,
+                                       (*key)->flags, (*key)->module, (*key)->name));
+
         /* ignore default values of the key */
         if ((*key)->dflt) {
             lydict_remove(ctx->ctx, (*key)->dflt);
@@ -2958,6 +2966,10 @@
                     config = 0;
                 }
 
+                /* check status */
+                LY_CHECK_RET(lysc_check_status(ctx, list->flags, list->module, list->name,
+                                               (*key)->flags, (*key)->module, (*key)->name));
+
                 /* mark leaf as unique */
                 (*key)->flags |= LYS_UNIQUE;
 
@@ -2975,13 +2987,54 @@
     return ret;
 }
 
+static LY_ERR
+lys_compile_node_choice_dflt(struct lysc_ctx *ctx, const char *dflt, struct lysc_node_choice *ch)
+{
+    struct lysc_node *iter, *node = (struct lysc_node*)ch;
+    const char *prefix = NULL, *name;
+    size_t prefix_len = 0;
+
+    /* could use lys_parse_nodeid(), but it checks syntax which is already done in this case by the parsers */
+    name = strchr(dflt, ':');
+    if (name) {
+        prefix = dflt;
+        prefix_len = name - prefix;
+        ++name;
+    } else {
+        name = dflt;
+    }
+    if (prefix && (strncmp(prefix, node->module->compiled->prefix, prefix_len) || node->module->compiled->prefix[prefix_len] != '\0')) {
+        /* prefixed default case make sense only for the prefix of the schema itself */
+        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+               "Invalid default case referencing a case from different YANG module (by prefix \"%.*s\").",
+               prefix_len, prefix);
+        return LY_EVALID;
+    }
+    ch->dflt = (struct lysc_node_case*)lys_child(node, node->module, name, 0, LYS_CASE, LYS_GETNEXT_NOSTATECHECK | LYS_GETNEXT_WITHCASE);
+    if (!ch->dflt) {
+        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+               "Default case \"%s\" not found.", dflt);
+        return LY_EVALID;
+    }
+    /* no mandatory nodes directly under the default case */
+    LY_LIST_FOR(ch->dflt->child, iter) {
+        if (iter->flags & LYS_MAND_TRUE) {
+            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                   "Mandatory node \"%s\" under the default case \"%s\".", iter->name, dflt);
+            return LY_EVALID;
+        }
+    }
+    ch->flags |= LYS_SET_DFLT;
+    return LY_SUCCESS;
+}
+
 /**
  * @brief Compile parsed choice node information.
  * @param[in] ctx Compile context
  * @param[in] node_p Parsed choice node.
  * @param[in] options Various options to modify compiler behavior, see [compile flags](@ref scflags).
  * @param[in,out] node Pre-prepared structure from lys_compile_node() with filled generic node information
- * is enriched with the container-specific information.
+ * is enriched with the choice-specific information.
  * @return LY_ERR value - LY_SUCCESS or LY_EVALID.
  */
 static LY_ERR
@@ -2990,9 +3043,6 @@
     struct lysp_node_choice *ch_p = (struct lysp_node_choice*)node_p;
     struct lysc_node_choice *ch = (struct lysc_node_choice*)node;
     struct lysp_node *child_p, *case_child_p;
-    struct lysc_node *iter;
-    const char *prefix = NULL, *name;
-    size_t prefix_len = 0;
     struct lys_module;
     LY_ERR ret = LY_SUCCESS;
 
@@ -3008,36 +3058,7 @@
 
     /* default branch */
     if (ch_p->dflt) {
-        /* could use lys_parse_nodeid(), but it checks syntax which is already done in this case by the parsers */
-        name = strchr(ch_p->dflt, ':');
-        if (name) {
-            prefix = ch_p->dflt;
-            prefix_len = name - prefix;
-            ++name;
-        } else {
-            name = ch_p->dflt;
-        }
-        if (prefix && (strncmp(prefix, node->module->compiled->prefix, prefix_len) || node->module->compiled->prefix[prefix_len] != '\0')) {
-            /* prefixed default case make sense only for the prefix of the schema itself */
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
-                   "Invalid default case referencing a case from different YANG module (by prefix \"%.*s\").",
-                   prefix_len, prefix);
-            return LY_EVALID;
-        }
-        ch->dflt = (struct lysc_node_case*)lys_child(node, node->module, name, 0, LYS_CASE, LYS_GETNEXT_NOSTATECHECK | LYS_GETNEXT_WITHCASE);
-        if (!ch->dflt) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                   "Default case \"%s\" not found.", ch_p->dflt);
-            return LY_EVALID;
-        }
-        /* no mandatory nodes directly under the default case */
-        LY_LIST_FOR(ch->dflt->child, iter) {
-            if (iter->flags & LYS_MAND_TRUE) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                       "Mandatory node \"%s\" under the default case \"%s\".", iter->name, ch_p->dflt);
-                return LY_EVALID;
-            }
-        }
+        LY_CHECK_RET(lys_compile_node_choice_dflt(ctx, ch_p->dflt, ch));
     }
 
     return ret;
@@ -3071,7 +3092,25 @@
 }
 
 static LY_ERR
-lys_compile_status(struct lysc_ctx *ctx, struct lysc_node *node,  struct lysc_node *parent)
+lys_compile_status_check(struct lysc_ctx *ctx, uint16_t node_flags, uint16_t parent_flags)
+{
+    /* check status compatibility with the parent */
+    if ((parent_flags & LYS_STATUS_MASK) > (node_flags & LYS_STATUS_MASK)) {
+        if (node_flags & LYS_STATUS_CURR) {
+            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                   "A \"current\" status is in conflict with the parent's \"%s\" status.",
+                   (parent_flags & LYS_STATUS_DEPRC) ? "deprecated" : "obsolete");
+        } else { /* LYS_STATUS_DEPRC */
+            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                   "A \"deprecated\" status is in conflict with the parent's \"obsolete\" status.");
+        }
+        return LY_EVALID;
+    }
+    return LY_SUCCESS;
+}
+
+static LY_ERR
+lys_compile_status(struct lysc_ctx *ctx, struct lysc_node *node, struct lysc_node *parent)
 {
 
     /* status - it is not inherited by specification, but it does not make sense to have
@@ -3085,18 +3124,7 @@
             node->flags |= LYS_STATUS_CURR;
         }
     } else if (parent) {
-        /* check status compatibility with the parent */
-        if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
-            if (node->flags & LYS_STATUS_CURR) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                       "A \"current\" status is in conflict with the parent's \"%s\" status.",
-                       (parent->flags & LYS_STATUS_DEPRC) ? "deprecated" : "obsolete");
-            } else { /* LYS_STATUS_DEPRC */
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                       "A \"deprecated\" status is in conflict with the parent's \"obsolete\" status.");
-            }
-            return LY_EVALID;
-        }
+        return lys_compile_status_check(ctx, node->flags, parent->flags);
     }
     return LY_SUCCESS;
 }
@@ -3229,6 +3257,38 @@
 #undef UNIQUE_CHECK
 }
 
+static LY_ERR
+lys_compile_refine_config(struct lysc_ctx *ctx, struct lysc_node *node, struct lysp_refine *rfn, int inheriting)
+{
+    struct lysc_node *child;
+    uint16_t config = rfn->flags & LYS_CONFIG_MASK;
+
+    if (config == (node->flags & LYS_CONFIG_MASK)) {
+        /* nothing to do */
+        return LY_SUCCESS;
+    }
+
+    if (!inheriting) {
+        /* explicit refine */
+        if (config == LYS_CONFIG_W && node->parent && (node->parent->flags & LYS_CONFIG_R)) {
+            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                   "Invalid refine of config in \"%s\" - configuration node cannot be child of any state data node.");
+            return LY_EVALID;
+        }
+    }
+    node->flags &= ~LYS_CONFIG_MASK;
+    node->flags |= config;
+
+    /* inherit the change into the children */
+    LY_LIST_FOR((struct lysc_node*)lysc_node_children(node), child) {
+        LY_CHECK_RET(lys_compile_refine_config(ctx, child, rfn, 1));
+    }
+
+    /* TODO actions and notifications */
+
+    return LY_SUCCESS;
+}
+
 /**
  * @brief Compile parsed uses statement - resolve target grouping and connect its content into parent.
  * If present, also apply uses's modificators.
@@ -3245,13 +3305,14 @@
 lys_compile_uses(struct lysc_ctx *ctx, struct lysp_node_uses *uses_p, int options, struct lysc_node *parent)
 {
     struct lysp_node *node_p;
-    struct lysc_node *last;
+    struct lysc_node *node;
     const struct lysp_grp *grp = NULL;
-    unsigned int u, grp_stack_count;
+    unsigned int u, v, grp_stack_count;
     int found;
     const char *id, *name, *prefix;
     size_t prefix_len, name_len;
     struct lys_module *mod, *mod_old;
+    struct lysp_refine *rfn;
     LY_ERR ret = LY_EVALID;
 
     /* search for the grouping definition */
@@ -3281,13 +3342,28 @@
         }
     }
     if (!found) {
-        /* search in top-level groupings */
+        /* search in top-level groupings of the main module ... */
         grp = mod->parsed->groupings;
-        LY_ARRAY_FOR(grp, u) {
-            if (!strcmp(grp[u].name, name)) {
-                grp = &grp[u];
-                found = 1;
-                break;
+        if (grp) {
+            for (u = 0; !found && u < LY_ARRAY_SIZE(grp); ++u) {
+                if (!strcmp(grp[u].name, name)) {
+                    grp = &grp[u];
+                    found = 1;
+                }
+            }
+        }
+        if (!found && mod->parsed->includes) {
+            /* ... and all the submodules */
+            for (u = 0; !found && u < LY_ARRAY_SIZE(mod->parsed->includes); ++u) {
+                grp = mod->parsed->includes[u].submodule->groupings;
+                if (grp) {
+                    for (v = 0; !found && v < LY_ARRAY_SIZE(grp); ++v) {
+                        if (!strcmp(grp[v].name, name)) {
+                            grp = &grp[v];
+                            found = 1;
+                        }
+                    }
+                }
             }
         }
     }
@@ -3314,20 +3390,99 @@
     /* check status */
     LY_CHECK_GOTO(lysc_check_status(ctx, uses_p->flags, mod_old, uses_p->name, grp->flags, mod, grp->name), error);
 
-    /* remember the last parent's child present before connecting the grouping content, it will be used later
-     * to know where start when applying uses's modificators */
-    if (parent) {
-        last = (struct lysc_node*)lysc_node_children(parent);
-    } else {
-        last = ctx->mod->compiled->data;
-    }
-    if (last) {
-        last = last->prev; /* get the last one */
-    }
-
     /* connect the grouping's content */
     LY_LIST_FOR(grp->data, node_p) {
         LY_CHECK_GOTO(lys_compile_node(ctx, node_p, options, parent), error);
+        /* check status between parent (uses in this case) and child - lys_compile_node() compares parent and the new node */
+        if (lys_compile_status_check(ctx, parent ? lysc_node_children(parent)->prev->flags : ctx->mod->compiled->data->prev->flags, uses_p->flags)) {
+            goto error;
+        }
+    }
+
+    /* apply refine */
+    LY_ARRAY_FOR(uses_p->refines, struct lysp_refine, rfn) {
+        LY_CHECK_GOTO(lys_resolve_descendant_schema_nodeid(ctx, rfn->nodeid, 0, parent, 0, (const struct lysc_node**)&node), error);
+
+        /* default value */
+        if (rfn->dflts) {
+            if ((node->nodetype & (LYS_LEAF | LYS_CHOICE)) && LY_ARRAY_SIZE(rfn->dflts) > 1) {
+                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                       "Invalid refine of default in \"%s\" - %s cannot hold %d default values.",
+                       rfn->nodeid, lys_nodetype2str(node->nodetype), LY_ARRAY_SIZE(rfn->dflts));
+                goto error;
+            }
+            if (!(node->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
+                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                       "Invalid refine of default in \"%s\" - %s cannot hold default value(s).",
+                       rfn->nodeid, lys_nodetype2str(node->nodetype));
+                goto error;
+            }
+            if (node->nodetype == LYS_LEAF) {
+                FREE_STRING(ctx->ctx, ((struct lysc_node_leaf*)node)->dflt);
+                DUP_STRING(ctx->ctx, rfn->dflts[0], ((struct lysc_node_leaf*)node)->dflt);
+                /* TODO check the default value according to type */
+            } else if (node->nodetype == LYS_LEAFLIST) {
+                LY_ARRAY_FOR(((struct lysc_node_leaflist*)node)->dflts, u) {
+                    lydict_remove(ctx->ctx, ((struct lysc_node_leaflist*)node)->dflts[u]);
+                }
+                LY_ARRAY_FREE(((struct lysc_node_leaflist*)node)->dflts);
+                LY_ARRAY_CREATE_GOTO(ctx->ctx, ((struct lysc_node_leaflist*)node)->dflts, LY_ARRAY_SIZE(rfn->dflts), ret, error);
+                LY_ARRAY_FOR(rfn->dflts, u) {
+                    LY_ARRAY_INCREMENT(((struct lysc_node_leaflist*)node)->dflts);
+                    DUP_STRING(ctx->ctx, rfn->dflts[u], ((struct lysc_node_leaflist*)node)->dflts[u]);
+                }
+                /* TODO check the default values according to type */
+            } else if (node->nodetype == LYS_CHOICE) {
+                LY_CHECK_GOTO(lys_compile_node_choice_dflt(ctx, rfn->dflts[0], (struct lysc_node_choice*)node), error);
+            }
+        }
+
+        /* description refine not applicable */
+        /* reference refine not applicable */
+
+        /* config */
+        if (rfn->flags & LYS_CONFIG_MASK) {
+            LY_CHECK_GOTO(lys_compile_refine_config(ctx, node, rfn, 0), error);
+        }
+
+        /* mandatory */
+        if (rfn->flags & LYS_MAND_MASK) {
+            if (!(node->nodetype & (LYS_LEAF | LYS_ANYDATA | LYS_ANYXML | LYS_CHOICE))) {
+                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                       "Invalid refine of mandatory in \"%s\" - %s cannot hold mandatory statement.",
+                       rfn->nodeid, lys_nodetype2str(node->nodetype));
+                goto error;
+            }
+            /* in compiled flags, only the LYS_MAND_TRUE is present */
+            if (rfn->flags & LYS_MAND_TRUE) {
+                /* check if node has default value */
+                if (node->nodetype & LYS_LEAF) {
+                    if (node->flags & LYS_SET_DFLT) {
+                        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                               "Invalid refine of mandatory in \"%s\" - leafswith \"default\" statement.", rfn->nodeid);
+                        goto error;
+                    } else {
+                        /* remove the default value taken from the leaf's type */
+                        FREE_STRING(ctx->ctx, ((struct lysc_node_leaf*)node)->dflt);
+                        ((struct lysc_node_leaf*)node)->dflt = NULL;
+                    }
+                } else if ((node->nodetype & LYS_CHOICE) && ((struct lysc_node_choice*)node)->dflt) {
+                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                           "Invalid refine of mandatory in \"%s\" - choice with \"default\" statement.", rfn->nodeid);
+                    goto error;
+                }
+                if (node->parent && (node->parent->flags & LYS_SET_DFLT)) {
+                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                           "Invalid refine of mandatory in \"%s\" - %s under the default case.",
+                           rfn->nodeid, lys_nodetype2str(node->nodetype));
+                    goto error;
+                }
+
+                node->flags |= LYS_MAND_TRUE;
+            } else {
+                node->flags &= ~LYS_MAND_TRUE;
+            }
+        }
     }
 
     ret = LY_SUCCESS;
@@ -3469,6 +3624,10 @@
             node->prev = ctx->mod->compiled->data->prev;
             ctx->mod->compiled->data->prev = node;
         }
+        if (lys_compile_node_uniqness(ctx, ctx->mod->compiled->data, ctx->mod->compiled->rpcs,
+                                      ctx->mod->compiled->notifs, node->name, node)) {
+            return LY_EVALID;
+        }
     }
 
     return LY_SUCCESS;
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 23e8e44..7dbe83c 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -21,7 +21,6 @@
 
 #define FREE_ARRAY(CTX, ARRAY, FUNC) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FUNC(CTX, &(ARRAY)[c__]);}LY_ARRAY_FREE(ARRAY);}
 #define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER);free(MEMBER);}
-#define FREE_STRING(CTX, STRING) if (STRING) {lydict_remove(CTX, STRING);}
 #define FREE_STRINGS(CTX, ARRAY) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FREE_STRING(CTX, ARRAY[c__]);}LY_ARRAY_FREE(ARRAY);}
 
 static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index f9059fe..f87b3bf 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -405,13 +405,11 @@
     /* search in submodules' typedefs */
     LY_ARRAY_FOR((*module)->includes, u) {
         typedefs = (*module)->includes[u].submodule->typedefs;
-        if (typedefs) {
-            LY_ARRAY_FOR(typedefs, v) {
-                if (!strcmp(name, typedefs[v].name)) {
-                    /* match */
-                    *tpdf = &typedefs[v];
-                    return LY_SUCCESS;
-                }
+        LY_ARRAY_FOR(typedefs, v) {
+            if (!strcmp(name, typedefs[v].name)) {
+                /* match */
+                *tpdf = &typedefs[v];
+                return LY_SUCCESS;
             }
         }
     }
diff --git a/tests/src/test_tree_schema_compile.c b/tests/src/test_tree_schema_compile.c
index 4acbe4d..ea088ed 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/src/test_tree_schema_compile.c
@@ -150,8 +150,16 @@
     assert_int_equal(LY_EINVAL, lys_compile(&mod, 0));
     logbuf_assert("Submodules (test) are not supposed to be compiled, compile only the main modules.");
     assert_null(mod.compiled);
-
     lysp_module_free(mod.parsed);
+
+    /* data definition name collision in top level */
+    assert_int_equal(LY_SUCCESS, yang_parse(&ctx, "module aa {namespace urn:aa;prefix aa;"
+                                                  "leaf a {type string;} container a{presence x;}}", &mod.parsed));
+    assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
+    logbuf_assert("Duplicate identifier \"a\" of data definition statement.");
+    assert_null(mod.compiled);
+    lysp_module_free(mod.parsed);
+
     ly_ctx_destroy(ctx.ctx, NULL);
 }
 
@@ -658,7 +666,7 @@
     assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
     ch = (struct lysc_node_choice*)mod->compiled->data;
     assert_non_null(ch);
-    assert_int_equal(LYS_CONFIG_W | LYS_STATUS_CURR, ch->flags);
+    assert_int_equal(LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, ch->flags);
     cs = ch->cases;
     assert_non_null(cs);
     assert_string_equal("a", cs->name);
@@ -2236,10 +2244,13 @@
     assert_int_equal(LYS_CONTAINER, parent->nodetype);
     assert_non_null((child = ((struct lysc_node_container*)parent)->child));
     assert_string_equal("a2", child->name);
+    assert_ptr_equal(mod, child->module);
     assert_non_null((child = child->next));
     assert_string_equal("a1", child->name);
+    assert_ptr_equal(mod, child->module);
     assert_non_null((child = child->next));
     assert_string_equal("x", child->name);
+    assert_ptr_equal(mod, child->module);
 
     /* invalid */
     assert_non_null(mod = lys_parse_mem(ctx, "module aa {namespace urn:aa;prefix aa;uses missinggrp;}", LYS_IN_YANG));
@@ -2253,6 +2264,15 @@
     assert_int_equal(LY_EVALID, lys_compile(mod, 0));
     logbuf_assert("Grouping \"grp\" references itself through a uses statement.");
 
+    assert_non_null(mod = lys_parse_mem(ctx, "module cc {namespace urn:cc;prefix cc;uses a:missingprefix;}", LYS_IN_YANG));
+    assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+    logbuf_assert("Invalid prefix used for grouping reference (a:missingprefix).");
+
+    assert_non_null(mod = lys_parse_mem(ctx, "module dd {namespace urn:dd;prefix dd;grouping grp{leaf a{type string;}}"
+                                        "leaf a {type string;}uses grp;}", LYS_IN_YANG));
+    assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+    logbuf_assert("Duplicate identifier \"a\" of data definition statement.");
+
     *state = NULL;
     ly_ctx_destroy(ctx, NULL);
 }