context FEATURE flag for implementing referenced modules
diff --git a/src/schema_compile.c b/src/schema_compile.c
index f6c2552..6156baa 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -1372,24 +1372,16 @@
     return LY_SUCCESS;
 }
 
-/**
- * @brief Check parsed expression for any prefixes of unimplemented modules.
- *
- * @param[in] ctx libyang context.
- * @param[in] expr Parsed expression.
- * @param[in] format Prefix format.
- * @param[in] prefix_data Format-specific data (see ::ly_resolve_prefix()).
- * @param[out] mod_p Optional module that is not implemented.
- * @return Whether all the found modules are implemented or at least one is not.
- */
-static ly_bool
-lys_compile_expr_target_is_implemented(const struct ly_ctx *ctx, const struct lyxp_expr *expr, LY_PREFIX_FORMAT format,
-        void *prefix_data, const struct lys_module **mod_p)
+LY_ERR
+lys_compile_expr_implement(const struct ly_ctx *ctx, const struct lyxp_expr *expr, LY_PREFIX_FORMAT format,
+        void *prefix_data, ly_bool implement, const struct lys_module **mod_p)
 {
     uint32_t i;
     const char *ptr, *start;
     const struct lys_module *mod;
 
+    assert(implement || mod_p);
+
     for (i = 0; i < expr->used; ++i) {
         if ((expr->tokens[i] != LYXP_TOKEN_NAMETEST) && (expr->tokens[i] != LYXP_TOKEN_LITERAL)) {
             /* token cannot have a prefix */
@@ -1409,14 +1401,16 @@
 
         if (!mod->implemented) {
             /* unimplemented module found */
-            if (mod_p) {
+            if (implement) {
+                LY_CHECK_RET(lys_set_implemented((struct lys_module *)mod));
+            } else {
                 *mod_p = mod;
+                break;
             }
-            return 0;
         }
     }
 
-    return 1;
+    return LY_SUCCESS;
 }
 
 /**
@@ -1494,8 +1488,12 @@
 
     LY_ARRAY_FOR(when, u) {
         /* first check whether all the referenced modules are implemented */
-        if (!lys_compile_expr_target_is_implemented(ctx->ctx, when[u]->cond, LY_PREF_SCHEMA_RESOLVED,
-                when[u]->prefixes, &mod)) {
+        mod = NULL;
+        ret = lys_compile_expr_implement(ctx->ctx, when[u]->cond, LY_PREF_SCHEMA_RESOLVED, when[u]->prefixes,
+                ctx->ctx->flags & LY_CTX_REF_IMPLEMENTED, &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);
             continue;
@@ -1504,7 +1502,7 @@
         /* check "when" */
         ret = lyxp_atomize(when[u]->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when[u]->prefixes, when[u]->context,
                 &tmp_set, opts);
-        if (ret != LY_SUCCESS) {
+        if (ret) {
             LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when[u]->cond->expr);
             goto cleanup;
         }
@@ -1540,8 +1538,12 @@
 check_musts:
     LY_ARRAY_FOR(musts, u) {
         /* first check whether all the referenced modules are implemented */
-        if (!lys_compile_expr_target_is_implemented(ctx->ctx, musts[u].cond, LY_PREF_SCHEMA_RESOLVED,
-                musts[u].prefixes, &mod)) {
+        mod = NULL;
+        ret = lys_compile_expr_implement(ctx->ctx, musts[u].cond, LY_PREF_SCHEMA_RESOLVED, musts[u].prefixes,
+                ctx->ctx->flags & LY_CTX_REF_IMPLEMENTED, &mod);
+        if (ret) {
+            goto cleanup;
+        } else if (mod) {
             LOGWRN(ctx->ctx, "Must condition \"%s\" check skipped because referenced module \"%s\" is not implemented.",
                     musts[u].cond->expr, mod->name);
             continue;
@@ -1549,7 +1551,7 @@
 
         /* check "must" */
         ret = lyxp_atomize(musts[u].cond, node->module, LY_PREF_SCHEMA_RESOLVED, musts[u].prefixes, node, &tmp_set, opts);
-        if (ret != LY_SUCCESS) {
+        if (ret) {
             LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_SEMANTICS, "Invalid must restriction \"%s\".", musts[u].cond->expr);
             goto cleanup;
         }
@@ -1711,9 +1713,11 @@
         const struct lysp_module *dflt_pmod, struct lyd_value *storage)
 {
     LY_ERR ret;
+    uint32_t options;
     struct ly_err_item *err = NULL;
 
-    ret = type->plugin->store(ctx->ctx, type, dflt, strlen(dflt), 0, LY_PREF_SCHEMA, (void *)dflt_pmod,
+    options = (ctx->ctx->flags & LY_CTX_REF_IMPLEMENTED) ? LY_TYPE_STORE_IMPLEMENT : 0;
+    ret = type->plugin->store(ctx->ctx, type, dflt, strlen(dflt), options, LY_PREF_SCHEMA, (void *)dflt_pmod,
             LYD_HINT_SCHEMA, node, storage, &err);
     if (ret == LY_EINCOMPLETE) {
         /* we have no data so we will not be resolving it */
@@ -1728,8 +1732,7 @@
                     "Invalid default - value does not fit the type (%s).", err->msg);
             ly_err_free(err);
         } else {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                    "Invalid default - value does not fit the type.");
+            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "Invalid default - value does not fit the type.");
         }
         return ret;
     }