schema compile REFACTOR implement flag meaning changed

Implemented set to 1 means that it was already tried
implementing the module. That means that all tasks
executing only once for each implemented module
are done and should never be performed again. Also,
these one-time tasks were isolated and moved to
lys_implement() so that lys_compile() performs
only strict compiled module creation that cannot
require recompilation on its own.
diff --git a/src/context.c b/src/context.c
index a4a9049..a81e95f 100644
--- a/src/context.c
+++ b/src/context.c
@@ -198,10 +198,8 @@
     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);
+    ret = _lys_set_implemented(mod, features, &unres);
+    LY_CHECK_GOTO(ret, cleanup);
 
 cleanup:
     if (ret) {
@@ -510,9 +508,12 @@
     for (i = 0; i < ctx->list.count; ++i) {
         mod = ctx->list.objs[i];
         if (mod->to_compile) {
-            /* if was not implemented, will be */
-            mod->implemented = 1;
+            assert(mod->implemented);
 
+            /* just unset the flag, it is not used for anything currently */
+            mod->to_compile = 0;
+
+            /* some modules were changed and need to be (re)compiled */
             recompile = 1;
         }
     }
@@ -522,18 +523,8 @@
         return LY_SUCCESS;
     }
 
-    /* recompile */
-    LY_CHECK_RET(lys_recompile(ctx, 1));
-
-    /* everything is fine, clear the flags */
-    for (i = 0; i < ctx->list.count; ++i) {
-        mod = ctx->list.objs[i];
-        if (mod->to_compile) {
-            mod->to_compile = 0;
-        }
-    }
-
-    return LY_SUCCESS;
+    /* (re)compile all the implemented modules */
+    return lys_recompile(ctx, 1);
 }
 
 API uint16_t
@@ -1203,13 +1194,22 @@
 API void
 ly_ctx_destroy(struct ly_ctx *ctx)
 {
+    struct lys_module *mod;
+
     if (!ctx) {
         return;
     }
 
     /* models list */
     for ( ; ctx->list.count; ctx->list.count--) {
+        mod = ctx->list.objs[ctx->list.count - 1];
+
         /* remove the module */
+        if (mod->implemented) {
+            mod->implemented = 0;
+            lysc_module_free(mod->compiled);
+            mod->compiled = NULL;
+        }
         lys_module_free(ctx->list.objs[ctx->list.count - 1]);
     }
     free(ctx->list.objs);