schema tree FEATURE accept adding duplicate modules

Just print a verbose message instead of an error.
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 38a09bd..588fdd0 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -1044,7 +1044,7 @@
         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)
 {
-    struct lys_module *mod = NULL, *latest, *mod_dup;
+    struct lys_module *mod = NULL, *latest, *mod_dup, *mod_impl;
     struct lysp_submodule *submod;
     LY_ERR ret;
     LY_ARRAY_COUNT_TYPE u;
@@ -1064,6 +1064,7 @@
     LY_CHECK_ERR_RET(!mod, LOGMEM(ctx), LY_EMEM);
     mod->ctx = ctx;
 
+    /* parse */
     switch (format) {
     case LYS_IN_YIN:
         ret = yin_parse_module(&yinctx, in, mod, unres);
@@ -1078,12 +1079,12 @@
         ret = LY_EINVAL;
         break;
     }
-    LY_CHECK_GOTO(ret, error);
+    LY_CHECK_GOTO(ret, free_mod_cleanup);
 
     /* make sure that the newest revision is at position 0 */
     lysp_sort_revisions(mod->parsed->revs);
     if (mod->parsed->revs) {
-        LY_CHECK_GOTO(ret = lydict_insert(ctx, mod->parsed->revs[0].date, 0, &mod->revision), error);
+        LY_CHECK_GOTO(ret = lydict_insert(ctx, mod->parsed->revs[0].date, 0, &mod->revision), free_mod_cleanup);
     }
 
     /* decide the latest revision */
@@ -1108,26 +1109,38 @@
     }
 
     if (custom_check) {
-        LY_CHECK_GOTO(ret = custom_check(ctx, mod->parsed, NULL, check_data), error);
+        LY_CHECK_GOTO(ret = custom_check(ctx, mod->parsed, NULL, check_data), free_mod_cleanup);
     }
 
-    /* check for duplicity in the context */
-    if (implement && ly_ctx_get_module_implemented(ctx, mod->name)) {
-        LOGERR(ctx, LY_EDENIED, "Module \"%s\" is already implemented in the context.", mod->name);
-        ret = LY_EDENIED;
-        goto error;
-    }
+    /* 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 (mod_dup) {
-        if (mod->parsed->revs) {
-            LOGERR(ctx, LY_EEXIST, "Module \"%s\" of revision \"%s\" is already present in the context.",
-                    mod->name, mod->parsed->revs[0].date);
-        } else {
-            LOGERR(ctx, LY_EEXIST, "Module \"%s\" with no revision is already present in the context.",
-                    mod->name);
+    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;
         }
-        ret = LY_EEXIST;
-        goto error;
+    }
+    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>");
+        goto free_mod_cleanup;
     }
 
     switch (in->type) {
@@ -1165,7 +1178,7 @@
     case LY_IN_ERROR:
         LOGINT(ctx);
         ret = LY_EINT;
-        goto error;
+        goto free_mod_cleanup;
     }
     lys_parser_fill_filepath(ctx, in, &mod->filepath);
 
@@ -1175,13 +1188,13 @@
 
     /* add internal data in case specific modules were parsed */
     if (!strcmp(mod->name, "ietf-netconf")) {
-        LY_CHECK_GOTO(ret = lys_parsed_add_internal_ietf_netconf(mod->parsed), error);
+        LY_CHECK_GOTO(ret = lys_parsed_add_internal_ietf_netconf(mod->parsed), free_mod_cleanup);
     } else if (!strcmp(mod->name, "ietf-netconf-with-defaults")) {
-        LY_CHECK_GOTO(ret = lys_parsed_add_internal_ietf_netconf_with_defaults(mod->parsed), error);
+        LY_CHECK_GOTO(ret = lys_parsed_add_internal_ietf_netconf_with_defaults(mod->parsed), free_mod_cleanup);
     }
 
     /* add the module into newly created module set, will also be freed from there on any error */
-    LY_CHECK_GOTO(ret = ly_set_add(&unres->creating, mod, 1, NULL), error);
+    LY_CHECK_GOTO(ret = ly_set_add(&unres->creating, mod, 1, NULL), free_mod_cleanup);
 
     /* add into context */
     ret = ly_set_add(&ctx->list, mod, 1, NULL);
@@ -1202,13 +1215,13 @@
 
     if (!implement) {
         /* pre-compile identities of the module */
-        LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod->parsed, mod->parsed->identities, &mod->identities), error);
+        LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod->parsed, mod->parsed->identities, &mod->identities), cleanup);
 
         /* pre-compile identities of any submodules */
         LY_ARRAY_FOR(mod->parsed->includes, u) {
             submod = mod->parsed->includes[u].submodule;
             ret = lys_identity_precompile(NULL, ctx, (struct lysp_module *)submod, submod->identities, &mod->identities);
-            LY_CHECK_GOTO(ret, error);
+            LY_CHECK_GOTO(ret, cleanup);
         }
     } else {
         /* implement (compile) */
@@ -1218,9 +1231,10 @@
     /* success */
     goto cleanup;
 
-error:
-    assert(ret);
+free_mod_cleanup:
     lys_module_free(mod, NULL);
+    mod = NULL;
+
 cleanup:
     if (pctx) {
         ly_set_erase(&pctx->tpdfs_nodes, NULL);
diff --git a/tests/utests/test_context.c b/tests/utests/test_context.c
index 89fd762..be3066c 100644
--- a/tests/utests/test_context.c
+++ b/tests/utests/test_context.c
@@ -478,11 +478,11 @@
     lys_compile_unres_glob_erase(ctx, &unres);
     /* invalid attempts - implementing module of the same name and inserting the same module */
     assert_int_equal(LY_EDENIED, lys_create_module(ctx, in2, LYS_IN_YANG, 1, NULL, NULL, NULL, &unres, NULL));
-    logbuf_assert("Module \"a\" is already implemented in the context.");
+    logbuf_assert("Module \"a@2018-10-23\" is already implemented in the context.");
     lys_compile_unres_glob_erase(ctx, &unres);
     ly_in_reset(in1);
-    assert_int_equal(LY_EEXIST, lys_create_module(ctx, in1, LYS_IN_YANG, 0, NULL, NULL, NULL, &unres, NULL));
-    logbuf_assert("Module \"a\" of revision \"2018-10-23\" is already present in the context.");
+    /* it is already there, fine */
+    assert_int_equal(LY_SUCCESS, lys_create_module(ctx, in1, LYS_IN_YANG, 0, NULL, NULL, NULL, &unres, NULL));
     /* insert the second module only as imported, not implemented */
     lys_compile_unres_glob_erase(ctx, &unres);
     ly_in_reset(in2);