schema tree REFACTOR put parsing and compilation into one function
diff --git a/src/context.c b/src/context.c
index 3769a0c..96de7c1 100644
--- a/src/context.c
+++ b/src/context.c
@@ -252,9 +252,8 @@
     /* load internal modules */
     for (i = 0; i < ((options & LY_CTX_NOYANGLIBRARY) ? (LY_INTERNAL_MODS_COUNT - 2) : LY_INTERNAL_MODS_COUNT); i++) {
         ly_in_memory(in, internal_modules[i].data);
-        LY_CHECK_GOTO(rc = lys_parse_mem_module(ctx, in, internal_modules[i].format, internal_modules[i].implemented,
-                                                NULL, NULL, &module), error);
-        LY_CHECK_GOTO(rc = lys_compile(&module, 0), error);
+        LY_CHECK_GOTO(rc = lys_create_module(ctx, in, internal_modules[i].format, internal_modules[i].implemented,
+                                             NULL, NULL, &module), error);
     }
 
     ly_in_free(in, 0);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index dd5a031..dc2cf6e 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -844,7 +844,7 @@
     mod->implemented = value;
 
     /* compile the schema */
-    LY_CHECK_RET(lys_compile(&mod, LYSC_OPT_INTERNAL));
+    LY_CHECK_RET(lys_compile(mod, LYSC_OPT_INTERNAL));
 
     return LY_SUCCESS;
 }
@@ -887,7 +887,7 @@
 }
 
 LY_ERR
-lys_parse_mem_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, struct lys_parser_ctx *main_ctx,
+lys_parse_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, struct lys_parser_ctx *main_ctx,
         LY_ERR (*custom_check)(const struct ly_ctx *, struct lysp_module *, struct lysp_submodule *, void *),
         void *check_data, struct lysp_submodule **submodule)
 {
@@ -947,6 +947,8 @@
         latest_sp->latest_revision = 0;
     }
 
+    lys_parser_fill_filepath(ctx, in, &submod->filepath);
+
     /* resolve imports and includes */
     LY_CHECK_GOTO(ret = lys_resolve_import_include(pctx, (struct lysp_module *)submod), error);
 
@@ -973,7 +975,7 @@
 }
 
 LY_ERR
-lys_parse_mem_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, ly_bool implement,
+lys_create_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, ly_bool implement,
         LY_ERR (*custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
         void *check_data, struct lys_module **module)
 {
@@ -983,8 +985,13 @@
     struct lys_yang_parser_ctx *yangctx = NULL;
     struct lys_yin_parser_ctx *yinctx = NULL;
     struct lys_parser_ctx *pctx = NULL;
+    char *filename, *rev, *dot;
+    size_t len;
 
     LY_CHECK_ARG_RET(ctx, ctx, in, LY_EINVAL);
+    if (module) {
+        *module = NULL;
+    }
 
     mod = calloc(1, sizeof *mod);
     LY_CHECK_ERR_RET(!mod, LOGMEM(ctx), LY_EMEM);
@@ -1072,79 +1079,6 @@
         }
     }
 
-    if (!mod->implemented) {
-        /* pre-compile features and identities of the module */
-        LY_CHECK_GOTO(ret = lys_feature_precompile(NULL, ctx, mod, mod->parsed->features, &mod->dis_features), error);
-        LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, mod->parsed->identities, &mod->dis_identities), error);
-    }
-
-    if (latest) {
-        latest->latest_revision = 0;
-    }
-
-    /* add into context */
-    ret = ly_set_add(&ctx->list, mod, LY_SET_OPT_USEASLIST, NULL);
-    LY_CHECK_GOTO(ret, error);
-    ctx->module_set_id++;
-
-finish_parsing:
-    /* resolve imports and includes */
-    LY_CHECK_GOTO(ret = lys_resolve_import_include(pctx, mod->parsed), error_ctx);
-
-    if (!mod->implemented) {
-        /* pre-compile features and identities of any submodules */
-        LY_ARRAY_FOR(mod->parsed->includes, u) {
-            LY_CHECK_GOTO(ret = lys_feature_precompile(NULL, ctx, mod, mod->parsed->includes[u].submodule->features,
-                                                       &mod->dis_features), error);
-            LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, mod->parsed->includes[u].submodule->identities,
-                                                        &mod->dis_identities), error);
-        }
-    }
-
-    /* check name collisions - typedefs and TODO groupings */
-    LY_CHECK_GOTO(ret = lysp_check_typedefs(pctx, mod->parsed), error_ctx);
-
-    if (format == LYS_IN_YANG) {
-        yang_parser_ctx_free(yangctx);
-    } else {
-        yin_parser_ctx_free(yinctx);
-    }
-    *module = mod;
-    return LY_SUCCESS;
-
-error_ctx:
-    ly_set_rm(&ctx->list, mod, NULL);
-error:
-    lys_module_free(mod, NULL);
-    if (pctx) {
-        ly_set_erase(&pctx->tpdfs_nodes, NULL);
-    }
-    if (format == LYS_IN_YANG) {
-        yang_parser_ctx_free(yangctx);
-    } else {
-        yin_parser_ctx_free(yinctx);
-    }
-
-    return ret;
-}
-
-API LY_ERR
-lys_parse(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const struct lys_module **module)
-{
-    struct lys_module *mod;
-    char *filename, *rev, *dot;
-    size_t len;
-
-    if (module) {
-        *module = NULL;
-    }
-    LY_CHECK_ARG_RET(NULL, ctx, in, format > LYS_IN_UNKNOWN, LY_EINVAL);
-
-    /* remember input position */
-    in->func_start = in->current;
-
-    LY_CHECK_RET(lys_parse_mem_module(ctx, in, format, 1, NULL, NULL, &mod));
-
     switch (in->type) {
     case LY_IN_FILEPATH:
         /* check that name and revision match filename */
@@ -1177,18 +1111,90 @@
     case LY_IN_MEMORY:
         /* nothing special to do */
         break;
-    default:
-        LOGINT_RET(ctx);
-        break;
+    case LY_IN_ERROR:
+        LOGINT(ctx);
+        ret = LY_EINT;
+        goto error;
     }
 
     lys_parser_fill_filepath(ctx, in, &mod->filepath);
-    LY_CHECK_RET(lys_compile(&mod, 0));
 
+    if (!mod->implemented) {
+        /* pre-compile features and identities of the module */
+        LY_CHECK_GOTO(ret = lys_feature_precompile(NULL, ctx, mod, mod->parsed->features, &mod->dis_features), error);
+        LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, mod->parsed->identities, &mod->dis_identities), error);
+    }
+
+    if (latest) {
+        latest->latest_revision = 0;
+    }
+
+    /* add into context */
+    ret = ly_set_add(&ctx->list, mod, LY_SET_OPT_USEASLIST, NULL);
+    LY_CHECK_GOTO(ret, error);
+    ctx->module_set_id++;
+
+finish_parsing:
+    /* resolve imports and includes */
+    LY_CHECK_GOTO(ret = lys_resolve_import_include(pctx, mod->parsed), error_ctx);
+
+    if (!mod->implemented) {
+        /* pre-compile features and identities of any submodules */
+        LY_ARRAY_FOR(mod->parsed->includes, u) {
+            LY_CHECK_GOTO(ret = lys_feature_precompile(NULL, ctx, mod, mod->parsed->includes[u].submodule->features,
+                                                       &mod->dis_features), error);
+            LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, mod->parsed->includes[u].submodule->identities,
+                                                        &mod->dis_identities), error);
+        }
+    }
+
+    /* check name collisions - typedefs and TODO groupings */
+    LY_CHECK_GOTO(ret = lysp_check_typedefs(pctx, mod->parsed), error_ctx);
+
+    /* compile */
+    if (!mod->compiled) {
+        ret = lys_compile(mod, 0);
+        LY_CHECK_GOTO(ret, error_ctx);
+    }
+
+    if (format == LYS_IN_YANG) {
+        yang_parser_ctx_free(yangctx);
+    } else {
+        yin_parser_ctx_free(yinctx);
+    }
     if (module) {
         *module = mod;
     }
     return LY_SUCCESS;
+
+error_ctx:
+    ly_set_rm(&ctx->list, mod, NULL);
+error:
+    lys_module_free(mod, NULL);
+    if (pctx) {
+        ly_set_erase(&pctx->tpdfs_nodes, NULL);
+    }
+    if (format == LYS_IN_YANG) {
+        yang_parser_ctx_free(yangctx);
+    } else {
+        yin_parser_ctx_free(yinctx);
+    }
+
+    return ret;
+}
+
+API LY_ERR
+lys_parse(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const struct lys_module **module)
+{
+    if (module) {
+        *module = NULL;
+    }
+    LY_CHECK_ARG_RET(NULL, ctx, in, format > LYS_IN_UNKNOWN, LY_EINVAL);
+
+    /* remember input position */
+    in->func_start = in->current;
+
+    return lys_create_module(ctx, in, format, 1, NULL, NULL, (struct lys_module **)module);
 }
 
 API LY_ERR
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 87a5734..8fbe2f1 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -7300,7 +7300,7 @@
 }
 
 LY_ERR
-lys_compile(struct lys_module **mod, uint32_t options)
+lys_compile(struct lys_module *mod, uint32_t options)
 {
     struct lysc_ctx ctx = {0};
     struct lysc_module *mod_c;
@@ -7314,26 +7314,26 @@
     uint16_t compile_id;
     LY_ERR ret = LY_SUCCESS;
 
-    LY_CHECK_ARG_RET(NULL, mod, *mod, (*mod)->parsed, (*mod)->ctx, LY_EINVAL);
+    LY_CHECK_ARG_RET(NULL, mod, mod->parsed, !mod->compiled, mod->ctx, LY_EINVAL);
 
-    if (!(*mod)->implemented) {
+    if (!mod->implemented) {
         /* just imported modules are not compiled */
         return LY_SUCCESS;
     }
 
-    compile_id = ++(*mod)->ctx->module_set_id;
-    sp = (*mod)->parsed;
+    compile_id = ++mod->ctx->module_set_id;
+    sp = mod->parsed;
 
-    ctx.ctx = (*mod)->ctx;
-    ctx.mod = *mod;
-    ctx.mod_def = *mod;
+    ctx.ctx = mod->ctx;
+    ctx.mod = mod;
+    ctx.mod_def = mod;
     ctx.options = options;
     ctx.path_len = 1;
     ctx.path[0] = '/';
 
-    (*mod)->compiled = mod_c = calloc(1, sizeof *mod_c);
-    LY_CHECK_ERR_RET(!mod_c, LOGMEM((*mod)->ctx), LY_EMEM);
-    mod_c->mod = *mod;
+    mod->compiled = mod_c = calloc(1, sizeof *mod_c);
+    LY_CHECK_ERR_RET(!mod_c, LOGMEM(mod->ctx), LY_EMEM);
+    mod_c->mod = mod;
 
     LY_ARRAY_FOR(sp->imports, u) {
         LY_CHECK_GOTO(ret = lys_compile_import(&ctx, &sp->imports[u]), error);
@@ -7343,10 +7343,10 @@
     }
 
     /* features */
-    if ((*mod)->dis_features) {
+    if (mod->dis_features) {
         /* there is already precompiled array of features */
-        mod_c->features = (*mod)->dis_features;
-        (*mod)->dis_features = NULL;
+        mod_c->features = mod->dis_features;
+        mod->dis_features = NULL;
     } else {
         /* features are compiled directly into the compiled module structure,
          * but it must be done in two steps to allow forward references (via if-feature) between the features themselves */
@@ -7373,9 +7373,9 @@
     lysc_update_path(&ctx, NULL, NULL);
 
     /* identities, work similarly to features with the precompilation */
-    if ((*mod)->dis_identities) {
-        mod_c->identities = (*mod)->dis_identities;
-        (*mod)->dis_identities = NULL;
+    if (mod->dis_identities) {
+        mod_c->identities = mod->dis_identities;
+        mod->dis_identities = NULL;
     } else {
         ret = lys_identity_precompile(&ctx, NULL, NULL, sp->identities, &mod_c->identities);
         LY_CHECK_GOTO(ret, error);
@@ -7453,8 +7453,8 @@
 #endif
 
     /* add ietf-netconf-with-defaults "default" metadata to the compiled module */
-    if (!strcmp((*mod)->name, "ietf-netconf-with-defaults")) {
-        LY_CHECK_GOTO(ret = lys_compile_ietf_netconf_wd_annotation(&ctx, *mod), error);
+    if (!strcmp(mod->name, "ietf-netconf-with-defaults")) {
+        LY_CHECK_GOTO(ret = lys_compile_ietf_netconf_wd_annotation(&ctx, mod), error);
     }
 
     ly_set_erase(&ctx.dflts, free);
@@ -7465,8 +7465,8 @@
     LY_ARRAY_FREE(augments);
 
     if (ctx.options & LYSC_OPT_FREE_SP) {
-        lysp_module_free((*mod)->parsed);
-        (*mod)->parsed = NULL;
+        lysp_module_free(mod->parsed);
+        mod->parsed = NULL;
     }
 
     if (!(ctx.options & LYSC_OPT_INTERNAL)) {
@@ -7482,7 +7482,7 @@
     return LY_SUCCESS;
 
 error:
-    lys_feature_precompile_revert(&ctx, *mod);
+    lys_feature_precompile_revert(&ctx, mod);
     ly_set_erase(&ctx.dflts, free);
     ly_set_erase(&ctx.xpath, NULL);
     ly_set_erase(&ctx.leafrefs, NULL);
@@ -7490,7 +7490,7 @@
     ly_set_erase(&ctx.tpdf_chain, NULL);
     LY_ARRAY_FREE(augments);
     lysc_module_free(mod_c, NULL);
-    (*mod)->compiled = NULL;
+    mod->compiled = NULL;
 
     /* revert compilation of modules implemented by dependency, but only by (directly or indirectly) by dependency
      * of this module, since this module can be also compiled from dependency, there can be some other modules being
@@ -7508,10 +7508,5 @@
         }
     }
 
-    /* remove the module itself from the context and free it */
-    ly_set_rm(&ctx.ctx->list, *mod, NULL);
-    lys_module_free(*mod, NULL);
-    *mod = NULL;
-
     return ret;
 }
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index c169359..5a4b9fa 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -778,29 +778,20 @@
     check_data.path = filepath;
     check_data.submoduleof = main_name;
     if (main_ctx) {
-        ret = lys_parse_mem_submodule(ctx, in, format, main_ctx, lysp_load_module_check, &check_data,
+        ret = lys_parse_submodule(ctx, in, format, main_ctx, lysp_load_module_check, &check_data,
                         (struct lysp_submodule **)&mod);
     } else {
-        ret = lys_parse_mem_module(ctx, in, format, implement, lysp_load_module_check, &check_data,
+        ret = lys_create_module(ctx, in, format, implement, lysp_load_module_check, &check_data,
                         (struct lys_module **)&mod);
 
     }
-    LY_CHECK_ERR_GOTO(ret, ly_in_free(in, 1), cleanup);
-
-    if (main_ctx) {
-        lys_parser_fill_filepath(ctx, in, &((struct lysp_submodule *)mod)->filepath);
-    } else {
-        lys_parser_fill_filepath(ctx, in, &((struct lys_module *)mod)->filepath);
-    }
     ly_in_free(in, 1);
-
-    if (mod && implement) {
-        lys_compile((struct lys_module **)&mod, 0);
-    }
+    LY_CHECK_GOTO(ret, cleanup);
 
     *result = mod;
 
     /* success */
+
 cleanup:
     free(filepath);
     return ret;
@@ -866,14 +857,11 @@
                     LY_CHECK_RET(ly_in_new_memory(module_data, &in));
                     check_data.name = name;
                     check_data.revision = revision;
-                    lys_parse_mem_module(ctx, in, format, implement, lysp_load_module_check, &check_data, mod);
+                    lys_create_module(ctx, in, format, implement, lysp_load_module_check, &check_data, mod);
                     ly_in_free(in, 0);
                     if (module_data_free) {
                         module_data_free((void *)module_data, ctx->imp_clb_data);
                     }
-                    if (*mod && implement) {
-                        lys_compile(mod, 0);
-                    }
                 }
             }
             if (!(*mod) && !(ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
@@ -988,7 +976,7 @@
                 check_data.name = inc->name;
                 check_data.revision = inc->rev[0] ? inc->rev : NULL;
                 check_data.submoduleof = pctx->main_mod->name;
-                lys_parse_mem_submodule(ctx, in, format, pctx, lysp_load_module_check, &check_data, &submod);
+                lys_parse_submodule(ctx, in, format, pctx, lysp_load_module_check, &check_data, &submod);
                 ly_in_free(in, 0);
                 if (submodule_data_free) {
                     submodule_data_free((void *)submodule_data, ctx->imp_clb_data);
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 3764664..09bf653 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -319,13 +319,12 @@
 /**
  * @brief Compile printable schema into a validated schema linking all the references.
  *
- * @param[in, out] mod Pointer to the schema structure holding pointers to both schema structure types. The ::lys_module#parsed
+ * @param[in] mod Pointer to the schema structure holding pointers to both schema structure types. The ::lys_module#parsed
  * member is used as input and ::lys_module#compiled is used to hold the result of the compilation.
- * If the compilation fails, the whole module is removed from context, freed and @p mod is set to NULL!
  * @param[in] options Various options to modify compiler behavior, see [compile flags](@ref scflags).
  * @return LY_ERR value - LY_SUCCESS or LY_EVALID.
  */
-LY_ERR lys_compile(struct lys_module **mod, uint32_t options);
+LY_ERR lys_compile(struct lys_module *mod, uint32_t options);
 
 /**
  * @brief Get address of a node's actions list if any.
@@ -483,24 +482,24 @@
         void *check_data);
 
 /**
- * @brief Parse module from a string.
+ * @brief Create a new module.
  *
- * The modules are added into the context and the latest_revision flag is updated.
+ * It is parsed, opionally compiled, added into the context, and the latest_revision flag is updated.
  *
  * @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] implement Flag if the schema is supposed to be marked as implemented.
+ * @param[in] implement Flag if the schema is supposed to be marked as 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[out] module Parsed module.
+ * @param[out] module Created module.
  * @return LY_ERR value.
  */
-LY_ERR lys_parse_mem_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, ly_bool implement,
+LY_ERR lys_create_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, ly_bool implement,
         lys_custom_check custom_check, void *check_data, struct lys_module **module);
 
 /**
- * @brief Parse submodule from a string.
+ * @brief Parse submodule.
  *
  * The latest_revision flag of submodule is updated.
  *
@@ -513,7 +512,7 @@
  * @param[out] submodule Parsed submodule.
  * @return LY_ERR value.
  */
-LY_ERR lys_parse_mem_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format,
+LY_ERR lys_parse_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format,
         struct lys_parser_ctx *main_ctx, lys_custom_check custom_check,
         void *check_data, struct lysp_submodule **submodule);
 
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index 396f3b8..75c5c51 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -114,16 +114,14 @@
 
     assert_int_equal(LY_EINVAL, lys_compile(NULL, 0));
     logbuf_assert("Invalid argument mod (lys_compile()).");
-    assert_int_equal(LY_EINVAL, lys_compile(&mod, 0));
-    logbuf_assert("Invalid argument *mod (lys_compile()).");
     assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in));
-    assert_int_equal(LY_SUCCESS, lys_parse_mem_module(ctx, in, LYS_IN_YANG, 0, NULL, NULL, &mod));
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in, LYS_IN_YANG, 0, NULL, NULL, &mod));
     ly_in_free(in, 0);
     assert_int_equal(0, mod->implemented);
-    assert_int_equal(LY_SUCCESS, lys_compile(&mod, 0));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
     assert_null(mod->compiled);
     mod->implemented = 1;
-    assert_int_equal(LY_SUCCESS, lys_compile(&mod, 0));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
     assert_non_null(mod->compiled);
     assert_string_equal("test", mod->name);
     assert_string_equal("urn:test", mod->ns);
@@ -143,18 +141,16 @@
     /* 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_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, NULL));
+    assert_int_equal(LY_EINVAL, lys_create_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, NULL));
     ly_in_free(in, 0);
     logbuf_assert("Input data contains submodule which cannot be parsed directly without its main module.");
 
     /* 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_SUCCESS, lys_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod));
-    ly_in_free(in, 0);
-    assert_int_equal(LY_EEXIST, lys_compile(&mod, 0));
+    assert_int_equal(LY_EEXIST, lys_create_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod));
     logbuf_assert("Duplicate identifier \"a\" of data definition/RPC/action/notification statement. /aa:a");
-    assert_null(mod);
+    ly_in_free(in, 0);
 
     *state = NULL;
     ly_ctx_destroy(ctx, NULL);
diff --git a/tests/utests/test_context.c b/tests/utests/test_context.c
index 136663c..ce496e6 100644
--- a/tests/utests/test_context.c
+++ b/tests/utests/test_context.c
@@ -285,7 +285,7 @@
     assert_int_equal(ctx->module_set_id, ly_ctx_get_module_set_id(ctx));
 
     assert_int_equal(LY_SUCCESS, ly_in_new_memory("module x {namespace urn:x;prefix x;}", &in));
-    assert_int_equal(LY_EINVAL, lys_parse_mem_module(ctx, in, 4, 1, NULL, NULL, &mod1));
+    assert_int_equal(LY_EINVAL, lys_create_module(ctx, in, 4, 1, NULL, NULL, &mod1));
     ly_in_free(in, 0);
     logbuf_assert("Invalid schema input format.");
 
@@ -303,22 +303,22 @@
     /* name collision of module and submodule */
     ly_ctx_set_module_imp_clb(ctx, 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_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
+    assert_int_equal(LY_EVALID, lys_create_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
     ly_in_free(in, 0);
     logbuf_assert("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_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
     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_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
+    assert_int_equal(LY_EVALID, lys_create_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
     ly_in_free(in, 0);
     logbuf_assert("Name collision between module and submodule of name \"y\". Line number 1.");
 
     store = 1;
     ly_ctx_set_module_imp_clb(ctx, 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_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
+    assert_int_equal(LY_EVALID, lys_create_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
     ly_in_free(in, 0);
     logbuf_assert("Name collision between submodules of name \"y\". Line number 1.");
     store = -1;
@@ -327,32 +327,31 @@
     ly_ctx_reset_latests(ctx);
     ly_ctx_set_module_imp_clb(ctx, 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_parse_mem_module(ctx, in, LYS_IN_YANG, 0, NULL, NULL, &mod2));
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in, LYS_IN_YANG, 0, NULL, NULL, &mod2));
     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_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod1));
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in, LYS_IN_YANG, 0, NULL, NULL, &mod1));
     ly_in_free(in, 0);
-    assert_int_equal(LY_SUCCESS, lys_compile(&mod1, LYSC_OPT_FREE_SP));
+    mod1->implemented = 1;
+    assert_int_equal(LY_SUCCESS, lys_compile(mod1, LYSC_OPT_FREE_SP));
     assert_non_null(mod1->compiled);
     assert_null(mod1->parsed);
 
     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));
-    assert_int_equal(LY_SUCCESS, lys_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod2));
-    ly_in_free(in, 0);
     /* mod1->parsed is necessary to compile mod2 because of possible groupings, typedefs, ... */
     ly_ctx_set_module_imp_clb(ctx, NULL, NULL);
-    assert_int_equal(LY_ENOTFOUND, lys_compile(&mod2, 0));
+    assert_int_equal(LY_ENOTFOUND, lys_create_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod2));
     logbuf_assert("Unable to reload \"w\" module to import it into \"z\", source data not found.");
     assert_null(mod2);
+    ly_in_free(in, 0);
 
     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));
-    assert_int_equal(LY_SUCCESS, lys_parse_mem_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod2));
-    ly_in_free(in, 0);
     ly_ctx_set_module_imp_clb(ctx, test_imp_clb, "module w {namespace urn:w;prefix w;revision 2018-10-24;}");
-    assert_int_equal(LY_SUCCESS, lys_compile(&mod2, 0));
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in, LYS_IN_YANG, 1, NULL, NULL, &mod2));
+    ly_in_free(in, 0);
     assert_non_null(mod2);
     assert_non_null(mod1->parsed);
     assert_string_equal("w", mod1->name);
@@ -456,16 +455,16 @@
     assert_non_null(ly_ctx_get_module_ns(ctx, "urn:ietf:params:xml:ns:yang:ietf-datastores", "2018-02-14"));
 
     /* select module by revision */
-    assert_int_equal(LY_SUCCESS, lys_parse_mem_module(ctx, in1, LYS_IN_YANG, 1, NULL, NULL, &mod));
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in1, LYS_IN_YANG, 1, NULL, NULL, &mod));
     /* invalid attempts - implementing module of the same name and inserting the same module */
-    assert_int_equal(LY_EDENIED, lys_parse_mem_module(ctx, in2, LYS_IN_YANG, 1, NULL, NULL, NULL));
+    assert_int_equal(LY_EDENIED, lys_create_module(ctx, in2, LYS_IN_YANG, 1, NULL, NULL, NULL));
     logbuf_assert("Module \"a\" is already implemented in the context.");
     ly_in_reset(in1);
-    assert_int_equal(LY_EEXIST, lys_parse_mem_module(ctx, in1, LYS_IN_YANG, 0, NULL, NULL, NULL));
+    assert_int_equal(LY_EEXIST, lys_create_module(ctx, in1, LYS_IN_YANG, 0, NULL, NULL, NULL));
     logbuf_assert("Module \"a\" of revision \"2018-10-23\" is already present in the context.");
     /* insert the second module only as imported, not implemented */
     ly_in_reset(in2);
-    assert_int_equal(LY_SUCCESS, lys_parse_mem_module(ctx, in2, LYS_IN_YANG, 0, NULL, NULL, &mod2));
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in2, LYS_IN_YANG, 0, NULL, NULL, &mod2));
     assert_non_null(mod2);
     assert_ptr_not_equal(mod, mod2);
     mod = ly_ctx_get_module_latest(ctx, "a");
@@ -473,14 +472,14 @@
     mod2 = ly_ctx_get_module_latest_ns(ctx, mod->ns);
     assert_ptr_equal(mod, mod2);
     /* work with module with no revision */
-    assert_int_equal(LY_SUCCESS, lys_parse_mem_module(ctx, in0, LYS_IN_YANG, 0, NULL, NULL, &mod));
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in0, LYS_IN_YANG, 0, NULL, NULL, &mod));
     assert_ptr_equal(mod, ly_ctx_get_module(ctx, "a", NULL));
     assert_ptr_not_equal(mod, ly_ctx_get_module_latest(ctx, "a"));
 
     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_parse_mem_module(ctx, in1, LYS_IN_YANG, 1, NULL, NULL, &mod));
+    assert_int_equal(LY_EINVAL, lys_create_module(ctx, in1, LYS_IN_YANG, 1, NULL, NULL, &mod));
     logbuf_assert("Input data contains submodule which cannot be parsed directly without its main module.");
 
     while ((mod = (struct lys_module *)ly_ctx_get_module_iter(ctx, &index))) {