schema tree REFACTOR always parse and implement separately
diff --git a/src/context.c b/src/context.c
index ac62cac..a4a9049 100644
--- a/src/context.c
+++ b/src/context.c
@@ -194,7 +194,11 @@
 
     LY_CHECK_ARG_RET(ctx, ctx, name, NULL);
 
-    LY_CHECK_GOTO(ret = lys_load_module(ctx, name, revision, 1, features, &unres, &result), cleanup);
+    /* parse */
+    LY_CHECK_GOTO(ret = lys_parse_load(ctx, name, revision, &unres, &result), cleanup);
+
+    /* implement */
+    LY_CHECK_GOTO(ret = lys_implement(result, features, &unres), cleanup);
 
     /* resolve unres and revert, if needed */
     LY_CHECK_GOTO(ret = lys_compile_unres_glob(ctx, &unres), cleanup);
@@ -279,8 +283,10 @@
     /* load internal modules */
     for (i = 0; i < ((options & LY_CTX_NO_YANGLIBRARY) ? (LY_INTERNAL_MODS_COUNT - 2) : LY_INTERNAL_MODS_COUNT); i++) {
         ly_in_memory(in, internal_modules[i].data);
-        LY_CHECK_GOTO(rc = lys_create_module(ctx, in, internal_modules[i].format, internal_modules[i].implemented,
-                NULL, NULL, NULL, &unres, &module), error);
+        LY_CHECK_GOTO(rc = lys_parse_in(ctx, in, internal_modules[i].format, NULL, NULL, &unres, &module), error);
+        if (internal_modules[i].implemented || (ctx->flags & LY_CTX_ALL_IMPLEMENTED)) {
+            LY_CHECK_GOTO(rc = lys_implement(module, NULL, &unres), error);
+        }
     }
 
     /* resolve global unres */
diff --git a/src/path.c b/src/path.c
index 4109f73..9500422 100644
--- a/src/path.c
+++ b/src/path.c
@@ -431,7 +431,7 @@
             }
 
             assert(unres);
-            LY_CHECK_GOTO(ret = lys_set_implemented_r((struct lys_module *)*mod, NULL, unres), error);
+            LY_CHECK_GOTO(ret = lys_implement((struct lys_module *)*mod, NULL, unres), error);
             if (unres->recompile) {
                 return LY_ERECOMPILE;
             }
diff --git a/src/plugins_types.c b/src/plugins_types.c
index a2cf0f3..adfeb17 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -751,7 +751,7 @@
 API LY_ERR
 lyplg_type_make_implemented(struct lys_module *mod, const char **features, struct lys_glob_unres *unres)
 {
-    LY_CHECK_RET(lys_set_implemented_r(mod, features, unres));
+    LY_CHECK_RET(lys_implement(mod, features, unres));
 
     if (unres->recompile) {
         return LY_ERECOMPILE;
diff --git a/src/schema_compile.c b/src/schema_compile.c
index d7312da..11c317c 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -836,7 +836,7 @@
         if (!mod->implemented) {
             /* unimplemented module found */
             if (implement) {
-                LY_CHECK_RET(lys_set_implemented_r((struct lys_module *)mod, NULL, unres));
+                LY_CHECK_RET(lys_implement((struct lys_module *)mod, NULL, unres));
                 if (unres->recompile) {
                     return LY_ERECOMPILE;
                 }
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 1ea084b..e571546 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -2272,7 +2272,7 @@
 
             if (!mod->implemented) {
                 /* implement (compile) the target module with our augments/deviations */
-                LY_CHECK_GOTO(ret = lys_set_implemented_r(mod, NULL, ctx->unres), cleanup);
+                LY_CHECK_GOTO(ret = lys_implement(mod, NULL, ctx->unres), cleanup);
             } else if (!ctx->unres->full_compilation) {
                 /* target module was already compiled, we need to recompile it */
                 ctx->unres->recompile = 1;
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 4a57cc4..d2ed415 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -798,11 +798,15 @@
 }
 
 LY_ERR
-lys_set_implemented_r(struct lys_module *mod, const char **features, struct lys_glob_unres *unres)
+lys_implement(struct lys_module *mod, const char **features, struct lys_glob_unres *unres)
 {
+    LY_ERR ret;
     struct lys_module *m;
 
-    assert(!mod->implemented);
+    if (mod->implemented) {
+        /* nothing to do */
+        return LY_SUCCESS;
+    }
 
     /* we have module from the current context */
     m = ly_ctx_get_module_implemented(mod->ctx, mod->name);
@@ -815,8 +819,11 @@
         return LY_EDENIED;
     }
 
-    /* enable features */
-    LY_CHECK_RET(lys_enable_features(mod->parsed, features));
+    /* set features */
+    ret = lys_set_features(mod->parsed, features);
+    if (ret && (ret != LY_EEXIST)) {
+        return ret;
+    }
 
     if (mod->ctx->flags & LY_CTX_EXPLICIT_COMPILE) {
         /* do not compile the module yet */
@@ -869,7 +876,7 @@
     }
 
     /* implement this module and any other required modules, recursively */
-    ret = lys_set_implemented_r(mod, features, &unres);
+    ret = lys_implement(mod, features, &unres);
 
     /* the first module being implemented is finished, resolve global unres, consolidate the set */
     if (!ret) {
@@ -894,8 +901,10 @@
     LY_ARRAY_FOR(pmod->imports, u) {
         imp = &pmod->imports[u];
         if (!imp->module) {
-            LY_CHECK_RET(lys_load_module(PARSER_CTX(pctx), imp->name, imp->rev[0] ? imp->rev : NULL, 0, NULL,
-                    pctx->unres, &imp->module));
+            LY_CHECK_RET(lys_parse_load(PARSER_CTX(pctx), imp->name, imp->rev[0] ? imp->rev : NULL, pctx->unres, &imp->module));
+            if (PARSER_CTX(pctx)->flags & LY_CTX_ALL_IMPLEMENTED) {
+                LY_CHECK_RET(lys_implement(imp->module, NULL, pctx->unres));
+            }
         }
         /* check for importing the same module twice */
         for (v = 0; v < u; ++v) {
@@ -1214,11 +1223,11 @@
 }
 
 LY_ERR
-lys_create_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, ly_bool need_implemented,
+lys_parse_in(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format,
         LY_ERR (*custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
-        void *check_data, const char **features, struct lys_glob_unres *unres, struct lys_module **module)
+        void *check_data, struct lys_glob_unres *unres, struct lys_module **module)
 {
-    struct lys_module *mod = NULL, *latest, *mod_dup, *mod_impl;
+    struct lys_module *mod = NULL, *latest, *mod_dup;
     struct lysp_submodule *submod;
     LY_ERR ret;
     LY_ARRAY_COUNT_TYPE u;
@@ -1227,20 +1236,13 @@
     struct lys_parser_ctx *pctx = NULL;
     char *filename, *rev, *dot;
     size_t len;
-    ly_bool implement;
 
-    assert(ctx && in && (!features || need_implemented) && unres);
+    assert(ctx && in && unres);
 
     if (module) {
         *module = NULL;
     }
 
-    if (ctx->flags & LY_CTX_ALL_IMPLEMENTED) {
-        implement = 1;
-    } else {
-        implement = need_implemented;
-    }
-
     mod = calloc(1, sizeof *mod);
     LY_CHECK_ERR_RET(!mod, LOGMEM(ctx), LY_EMEM);
     mod->ctx = ctx;
@@ -1295,29 +1297,7 @@
 
     /* check whether it is not already in the context in the same revision */
     mod_dup = (struct lys_module *)ly_ctx_get_module(ctx, mod->name, mod->revision);
-    if (implement) {
-        mod_impl = ly_ctx_get_module_implemented(ctx, mod->name);
-        if (mod_impl && (mod_impl != mod_dup)) {
-            LOGERR(ctx, LY_EDENIED, "Module \"%s@%s\" is already implemented in the context.", mod_impl->name,
-                    mod_impl->revision ? mod_impl->revision : "<none>");
-            ret = LY_EDENIED;
-            goto free_mod_cleanup;
-        }
-    }
     if (mod_dup) {
-        if (implement) {
-            if (!mod_dup->implemented) {
-                /* just implement it */
-                LY_CHECK_GOTO(ret = lys_set_implemented_r(mod_dup, features, unres), free_mod_cleanup);
-                goto free_mod_cleanup;
-            }
-
-            /* nothing to do */
-            LOGVRB("Module \"%s@%s\" is already implemented in the context.", mod_dup->name,
-                    mod_dup->revision ? mod_dup->revision : "<none>");
-            goto free_mod_cleanup;
-        }
-
         /* nothing to do */
         LOGVRB("Module \"%s@%s\" is already present in the context.", mod_dup->name,
                 mod_dup->revision ? mod_dup->revision : "<none>");
@@ -1402,11 +1382,6 @@
         LY_CHECK_GOTO(ret, cleanup);
     }
 
-    if (implement) {
-        /* implement (compile) */
-        LY_CHECK_GOTO(ret = lys_set_implemented_r(mod, features, unres), cleanup);
-    }
-
     /* success */
     goto cleanup;
 
@@ -1463,6 +1438,7 @@
 lys_parse(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const char **features, const struct lys_module **module)
 {
     LY_ERR ret;
+    struct lys_module *mod;
     struct lys_glob_unres unres = {0};
 
     if (module) {
@@ -1476,7 +1452,12 @@
     /* remember input position */
     in->func_start = in->current;
 
-    ret = lys_create_module(ctx, in, format, 1, NULL, NULL, features, &unres, (struct lys_module **)module);
+    /* parse */
+    ret = lys_parse_in(ctx, in, format, NULL, NULL, &unres, &mod);
+    LY_CHECK_GOTO(ret, cleanup);
+
+    /* implement */
+    ret = lys_implement(mod, features, &unres);
     LY_CHECK_GOTO(ret, cleanup);
 
     /* resolve global unres */
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 14572ce..704095f 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -618,17 +618,13 @@
 }
 
 /**
- * @brief Load the (sub)module into the context.
+ * @brief Parse a (sub)module from a local file and add into the context.
  *
  * This function does not check the presence of the (sub)module in context, it should be done before calling this function.
  *
- * module_name and submodule_name are alternatives - only one of the
- *
  * @param[in] ctx libyang context where to work.
  * @param[in] name Name of the (sub)module to load.
  * @param[in] revision Optional revision of the (sub)module to load, if NULL the newest revision is being loaded.
- * @param[in] features Array of enabled features ended with NULL.
- * @param[in] need_implemented Whether the (sub)module is needed implemented or not.
  * @param[in] main_ctx Parser context of the main module in case of loading submodule.
  * @param[in] main_name Main module name in case of loading submodule.
  * @param[in] required Module is required so error (even if the input file not found) are important. If 0, there is some
@@ -636,12 +632,13 @@
  * @param[in,out] unres Global unres structure for newly implemented modules.
  * @param[out] result Parsed YANG schema tree of the requested module (struct lys_module*) or submodule (struct lysp_submodule*).
  * If it is a module, it is already in the context!
- * @return LY_ERR value, in case of LY_SUCCESS, the \arg result is always provided.
+ * @return LY_SUCCESS on success.
+ * @return LY_ERECOMPILE if unres->recompile dep set needs to be recompiled, @p result is set.
+ * @return LY_ERR on error.
  */
 static LY_ERR
-lys_module_localfile(struct ly_ctx *ctx, const char *name, const char *revision, const char **features,
-        ly_bool need_implemented, struct lys_parser_ctx *main_ctx, const char *main_name, ly_bool required,
-        struct lys_glob_unres *unres, void **result)
+lys_parse_localfile(struct ly_ctx *ctx, const char *name, const char *revision, struct lys_parser_ctx *main_ctx,
+        const char *main_name, ly_bool required, struct lys_glob_unres *unres, void **result)
 {
     struct ly_in *in;
     char *filepath = NULL;
@@ -673,8 +670,7 @@
         ret = lys_parse_submodule(ctx, in, format, main_ctx, lysp_load_module_check, &check_data,
                 (struct lysp_submodule **)&mod);
     } else {
-        ret = lys_create_module(ctx, in, format, need_implemented, lysp_load_module_check, &check_data, features, unres,
-                (struct lys_module **)&mod);
+        ret = lys_parse_in(ctx, in, format, lysp_load_module_check, &check_data, unres, (struct lys_module **)&mod);
 
     }
     ly_in_free(in, 1);
@@ -690,27 +686,19 @@
 }
 
 LY_ERR
-lys_load_module(struct ly_ctx *ctx, const char *name, const char *revision, ly_bool need_implemented,
-        const char **features, struct lys_glob_unres *unres, struct lys_module **mod)
+lys_parse_load(struct ly_ctx *ctx, const char *name, const char *revision, struct lys_glob_unres *unres,
+        struct lys_module **mod)
 {
     const char *module_data = NULL;
     LYS_INFORMAT format = LYS_IN_UNKNOWN;
 
     void (*module_data_free)(void *module_data, void *user_data) = NULL;
     struct lysp_load_module_check_data check_data = {0};
-    struct lys_module *ctx_latest = NULL, *m;
+    struct lys_module *ctx_latest = NULL;
     struct ly_in *in;
-    LY_ERR ret;
-    ly_bool implement;
 
     assert(mod && unres);
 
-    if (ctx->flags & LY_CTX_ALL_IMPLEMENTED) {
-        implement = 1;
-    } else {
-        implement = need_implemented;
-    }
-
     /*
      * try to get the module from the context
      */
@@ -719,30 +707,21 @@
             /* get the specific revision */
             *mod = (struct lys_module *)ly_ctx_get_module(ctx, name, revision);
         } else {
-            if (implement) {
-                /* prefer the implemented module instead of the latest one */
-                *mod = (struct lys_module *)ly_ctx_get_module_implemented(ctx, name);
-            }
-            if (!*mod) {
-                /* get the requested module of the latest revision in the context */
-                *mod = (struct lys_module *)ly_ctx_get_module_latest(ctx, name);
-                if (*mod && ((*mod)->latest_revision == 1)) {
-                    /* let us now search with callback and searchpaths to check if there is newer revision outside the context */
-                    ctx_latest = *mod;
-                    *mod = NULL;
-                }
+            /* get the requested module of the latest revision in the context */
+            *mod = (struct lys_module *)ly_ctx_get_module_latest(ctx, name);
+            if (*mod && ((*mod)->latest_revision == 1)) {
+                /* let us now search with callback and searchpaths to check if there is newer revision outside the context */
+                ctx_latest = *mod;
+                *mod = NULL;
             }
         }
     }
 
-    /* check collision with other implemented revision */
-    if (implement) {
-        m = ly_ctx_get_module_implemented(ctx, name);
-        if (m && (!*mod || (*mod && (m != *mod)))) {
-            LOGVAL(ctx, LYVE_REFERENCE, "Module \"%s\" is already present in other implemented revision.", name);
-            *mod = NULL;
-            return LY_EDENIED;
-        }
+    /* we have module from the current context, circular check */
+    if (*mod && (*mod)->parsed->parsing) {
+        LOGVAL(ctx, LYVE_REFERENCE, "A circular dependency (import) for module \"%s\".", name);
+        *mod = NULL;
+        return LY_EVALID;
     }
 
     /*
@@ -772,8 +751,7 @@
 search_file:
             if (!(ctx->flags & LY_CTX_DISABLE_SEARCHDIRS)) {
                 /* module was not received from the callback or there is no callback set */
-                lys_module_localfile(ctx, name, revision, features, implement, NULL, NULL, ctx_latest ? 0 : 1, unres,
-                        (void **)mod);
+                lys_parse_localfile(ctx, name, revision, NULL, NULL, ctx_latest ? 0 : 1, unres, (void **)mod);
             }
             if (!*mod && (ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
                 goto search_clb;
@@ -792,40 +770,9 @@
         }
 
         if (!*mod) {
-            LOGVAL(ctx, LYVE_REFERENCE, "%s \"%s\" module failed.", implement ? "Loading" : "Importing", name);
+            LOGVAL(ctx, LYVE_REFERENCE, "Loading \"%s\" module failed.", name);
             return LY_EVALID;
         }
-    } else {
-        /* we have module from the current context, circular check */
-        if ((*mod)->parsed->parsing) {
-            LOGVAL(ctx, LYVE_REFERENCE, "A circular dependency (import) for module \"%s\".", name);
-            *mod = NULL;
-            return LY_EVALID;
-        }
-    }
-
-    /*
-     * module found, make sure it is implemented if should be
-     */
-    if (implement) {
-        if (!(*mod)->implemented) {
-            /* implement */
-            ret = lys_set_implemented_r(*mod, features, unres);
-            if (ret) {
-                *mod = NULL;
-                return ret;
-            }
-        } else if (features) {
-            /* set features if different */
-            ret = lys_set_features((*mod)->parsed, features);
-            if (!ret) {
-                /* context need to be recompiled so that feature changes are properly applied */
-                unres->recompile = 1;
-            } else if (ret != LY_EEXIST) {
-                /* error */
-                return ret;
-            } /* else no feature changes */
-        }
     }
 
     return LY_SUCCESS;
@@ -1014,8 +961,7 @@
 search_file:
             if (!(ctx->flags & LY_CTX_DISABLE_SEARCHDIRS)) {
                 /* submodule was not received from the callback or there is no callback set */
-                lys_module_localfile(ctx, inc->name,
-                        inc->rev[0] ? inc->rev : NULL, NULL, 0, pctx,
+                lys_parse_localfile(ctx, inc->name, inc->rev[0] ? inc->rev : NULL, pctx,
                         pctx->parsed_mod->mod->name, 1, NULL, (void **)&submod);
 
                 /* update inc pointer - parsing another (YANG 1.0) submodule can cause injecting
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 642c298..f6e1bae 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -293,21 +293,18 @@
 LY_ERR lysp_check_enum_name(struct lys_parser_ctx *ctx, const char *name, size_t name_len);
 
 /**
- * @brief Find and load a module of the given name.
+ * @brief Find source data for a specific module, parse it, and add into the context.
  *
  * @param[in] ctx libyang context.
  * @param[in] name Name of the module to load.
  * @param[in] revison Optional revision of the module to load. If NULL, the newest revision is loaded.
- * @param[in] need_implemented Whether the module should be implemented. If revision is NULL and this flag is set,
- * the implemented module in the context is returned despite it might not be of the latest revision, because in this
- * case the module of the latest revision can not be made implemented.
- * @param[in] features All the features to enable if implementing the module.
- * @param[in] unres Global unres structure for all newly implemented modules.
+ * @param[in,out] unres Global unres structure.
  * @param[out] mod Created module structure.
- * @return LY_ERR value.
+ * @return LY_SUCCESS on success.
+ * @return LY_ERR on error.
  */
-LY_ERR lys_load_module(struct ly_ctx *ctx, const char *name, const char *revision, ly_bool need_implemented,
-        const char **features, struct lys_glob_unres *unres, struct lys_module **mod);
+LY_ERR lys_parse_load(struct ly_ctx *ctx, const char *name, const char *revision, struct lys_glob_unres *unres,
+        struct lys_module **mod);
 
 /**
  * @brief Parse included submodules into the simply parsed YANG module.
@@ -527,37 +524,33 @@
 const char *lys_datatype2str(LY_DATA_TYPE basetype);
 
 /**
- * @brief Implement a module (just like ::lys_set_implemented()), can be called recursively.
+ * @brief Implement a module, can be called recursively.
  *
  * @param[in] mod Module to implement.
- * @param[in] features Array of features to enable.
+ * @param[in] features Features to set, see ::lys_set_features().
  * @param[in,out] unres Global unres to add to.
- * @return LY_ERR value.
+ * @return LY_ERECOMPILE if unres->recompile dep set needs to be recompiled.
+ * @return LY_ERR on error.
  */
-LY_ERR lys_set_implemented_r(struct lys_module *mod, const char **features, struct lys_glob_unres *unres);
+LY_ERR lys_implement(struct lys_module *mod, const char **features, struct lys_glob_unres *unres);
 
 typedef LY_ERR (*lys_custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod,
         void *check_data);
 
 /**
- * @brief Create a new module.
- *
- * It is parsed, opionally compiled, added into the context, and the latest_revision flag is updated.
+ * @brief Parse a module and add it into the context.
  *
  * @param[in] ctx libyang context where to process the data model.
  * @param[in] in Input structure.
  * @param[in] format Format of the input data (YANG or YIN).
- * @param[in] need_implemented Whether module needs to be implemented and compiled.
  * @param[in] custom_check Callback to check the parsed schema before it is accepted.
  * @param[in] check_data Caller's data to pass to the custom_check callback.
- * @param[in] features Array of features to enable ended with NULL. NULL for all features disabled and '*' for all enabled.
  * @param[in,out] unres Global unres structure for newly implemented modules.
  * @param[out] module Created module.
  * @return LY_ERR value.
  */
-LY_ERR lys_create_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, ly_bool need_implemented,
-        lys_custom_check custom_check, void *check_data, const char **features, struct lys_glob_unres *unres,
-        struct lys_module **module);
+LY_ERR lys_parse_in(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, lys_custom_check custom_check,
+        void *check_data, struct lys_glob_unres *unres, struct lys_module **module);
 
 /**
  * @brief Parse submodule.
diff --git a/tests/utests/basic/test_context.c b/tests/utests/basic/test_context.c
index e7417dd..fbd5b49 100644
--- a/tests/utests/basic/test_context.c
+++ b/tests/utests/basic/test_context.c
@@ -215,7 +215,7 @@
     assert_int_equal(UTEST_LYCTX->change_count, ly_ctx_get_change_count(UTEST_LYCTX));
 
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module x {namespace urn:x;prefix x;}", &in));
-    assert_int_equal(LY_EINVAL, lys_create_module(UTEST_LYCTX, in, 4, 1, NULL, NULL, NULL, &unres, &mod1));
+    assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in, 4, NULL, NULL, &unres, &mod1));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
     CHECK_LOG_CTX("Invalid schema input format.", NULL);
@@ -234,25 +234,26 @@
     /* name collision of module and submodule */
     ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to a {prefix a;} revision 2018-10-30;}");
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module y {namespace urn:y;prefix y;include y;}", &in));
-    assert_int_equal(LY_EVALID, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, &mod1));
+    assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod1));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
     CHECK_LOG_CTX("Name collision between module and submodule of name \"y\".", "Line number 1.");
 
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module a {namespace urn:a;prefix a;include y;revision 2018-10-30; }", &in));
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, &mod1));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod1));
+    assert_int_equal(LY_SUCCESS, lys_implement(mod1, NULL, &unres));
     assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module y {namespace urn:y;prefix y;}", &in));
-    assert_int_equal(LY_EVALID, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, &mod1));
+    assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod1));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
     CHECK_LOG_CTX("Name collision between module and submodule of name \"y\".", "Line number 1.");
 
     ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to b {prefix b;}}");
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module b {namespace urn:b;prefix b;include y;}", &in));
-    assert_int_equal(LY_EVALID, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, &mod1));
+    assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod1));
     lys_compile_unres_glob_revert(UTEST_LYCTX, &unres);
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
@@ -263,14 +264,14 @@
     ly_ctx_reset_latests(UTEST_LYCTX);
     ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to a {prefix a;} revision 2018-10-31;}");
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module a {namespace urn:a;prefix a;include y; revision 2018-10-31;}", &in));
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 0, NULL, NULL, NULL, &unres, &mod2));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod2));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
     assert_string_equal("2018-10-31", mod2->parsed->includes[0].submodule->revs[0].date);
 
     /* reloading module in case only the compiled module resists in the context */
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module w {namespace urn:w;prefix w;revision 2018-10-24;}", &in));
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 0, NULL, NULL, NULL, &unres, &mod1));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod1));
     ly_in_free(in, 0);
     mod1->implemented = 1;
     assert_int_equal(LY_SUCCESS, lys_compile(mod1, 0, 0, &unres));
@@ -294,7 +295,8 @@
 
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module z {namespace urn:z;prefix z;import w {prefix w;revision-date 2018-10-24;}}", &in));
     ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module w {namespace urn:w;prefix w;revision 2018-10-24;}");
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, &mod2));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod2));
+    assert_int_equal(LY_SUCCESS, lys_implement(mod2, NULL, &unres));
     assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
@@ -390,20 +392,22 @@
     assert_non_null(ly_ctx_get_module_ns(UTEST_LYCTX, "urn:ietf:params:xml:ns:yang:ietf-datastores", "2018-02-14"));
 
     /* select module by revision */
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in1, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, &mod));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, NULL, &unres, &mod));
+    assert_int_equal(LY_SUCCESS, lys_implement(mod, NULL, &unres));
     assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     /* invalid attempts - implementing module of the same name and inserting the same module */
-    assert_int_equal(LY_EDENIED, lys_create_module(UTEST_LYCTX, in2, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, NULL));
-    CHECK_LOG_CTX("Module \"a@2018-10-23\" is already implemented in the context.", NULL);
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in2, LYS_IN_YANG, NULL, NULL, &unres, &mod2));
+    assert_int_equal(LY_EDENIED, lys_implement(mod2, NULL, &unres));
+    CHECK_LOG_CTX("Module \"a@2018-10-24\" is present in the context in other implemented revision (2018-10-23).", NULL);
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_reset(in1);
     /* it is already there, fine */
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in1, LYS_IN_YANG, 0, NULL, NULL, NULL, &unres, NULL));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, NULL, &unres, NULL));
     /* insert the second module only as imported, not implemented */
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_reset(in2);
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in2, LYS_IN_YANG, 0, NULL, NULL, NULL, &unres, &mod2));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in2, LYS_IN_YANG, NULL, NULL, &unres, &mod2));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     assert_non_null(mod2);
     assert_ptr_not_equal(mod, mod2);
@@ -412,7 +416,7 @@
     mod2 = ly_ctx_get_module_latest_ns(UTEST_LYCTX, mod->ns);
     assert_ptr_equal(mod, mod2);
     /* work with module with no revision */
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in0, LYS_IN_YANG, 0, NULL, NULL, NULL, &unres, &mod));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in0, LYS_IN_YANG, NULL, NULL, &unres, &mod));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     assert_ptr_equal(mod, ly_ctx_get_module(UTEST_LYCTX, "a", NULL));
     assert_ptr_not_equal(mod, ly_ctx_get_module_latest(UTEST_LYCTX, "a"));
@@ -420,7 +424,7 @@
     str1 = "submodule b {belongs-to a {prefix a;}}";
     ly_in_free(in1, 0);
     assert_int_equal(LY_SUCCESS, ly_in_new_memory(str1, &in1));
-    assert_int_equal(LY_EINVAL, lys_create_module(UTEST_LYCTX, in1, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, &mod));
+    assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, NULL, &unres, &mod));
     CHECK_LOG_CTX("Input data contains submodule which cannot be parsed directly without its main module.", NULL);
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
 
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index 640a1c8..3ab7ccd 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -79,7 +79,7 @@
     assert_int_equal(LY_EINVAL, lys_compile(NULL, 0, 0, NULL));
     CHECK_LOG("Invalid argument mod (lys_compile()).", NULL);
     assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
-    assert_int_equal(LY_SUCCESS, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 0, NULL, NULL, NULL, &unres, &mod));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod));
     assert_int_equal(LY_SUCCESS, lys_compile_unres_glob(UTEST_LYCTX, &unres));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
@@ -107,7 +107,7 @@
     /* submodules cannot be compiled directly */
     str = "submodule test {belongs-to xxx {prefix x;}}";
     assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
-    assert_int_equal(LY_EINVAL, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, NULL));
+    assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, NULL));
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);
     CHECK_LOG_CTX("Input data contains submodule which cannot be parsed directly without its main module.", NULL);
@@ -115,7 +115,8 @@
     /* data definition name collision in top level */
     str = "module aa {namespace urn:aa;prefix aa; leaf a {type string;} container a{presence x;}}";
     assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
-    assert_int_equal(LY_EEXIST, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, &mod));
+    assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres, &mod));
+    assert_int_equal(LY_EEXIST, lys_implement(mod, NULL, &unres));
     CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/aa:a");
     lys_compile_unres_glob_erase(UTEST_LYCTX, &unres);
     ly_in_free(in, 0);