schema helpers CHANGE added LYS_MOD_IMPORTED_REV

The new ::lys_get_module_without_revision() modifies the behavior of
the ::lys_parse_load() when a module is imported without specifying a
revision. Such an imported module is marked with the
::LYS_MOD_IMPORTED_REV flag and its priority is the highest. Also, the
implemented module takes precedence over the module with the latest
revision.
diff --git a/src/context.h b/src/context.h
index bf6c3ef..029f513 100644
--- a/src/context.h
+++ b/src/context.h
@@ -73,8 +73,7 @@
  * For a context, the first time the latest revision of a module is requested, it is properly searched for and loaded.
  * However, when this module is requested (without revision) the second time, the one found previously is returned.
  * This has the advantage of not searching for the module repeatedly but there is a drawback in case the content of search
- * directories is updated and a later revision become available. However, to force libyang to re-search the
- * latest revision, ::ly_ctx_reset_latests() can be used (note that it applies to all the modules in the context).
+ * directories is updated and a later revision become available.
  *
  * Context holds all the schema modules internally. To get a specific module, use ::ly_ctx_get_module() (or some of its
  * variants). If you need to do something with all the modules in the context, it is advised to iterate over them using
@@ -530,6 +529,8 @@
 /**
  * @brief Reset cached latest revision information of the schemas in the context.
  *
+ * This function is deprecated and should not be used.
+ *
  * When a (sub)module is imported/included without revision, the latest revision is
  * searched. libyang searches for the latest revision in searchdirs and/or via provided
  * import callback ::ly_module_imp_clb() just once. Then it is expected that the content
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 2a399cd..66c42a4 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -1191,6 +1191,14 @@
         imp = &pmod->imports[u];
         if (!imp->module) {
             LY_CHECK_RET(lys_parse_load(PARSER_CTX(pctx), imp->name, imp->rev[0] ? imp->rev : NULL, new_mods, &imp->module));
+
+            if (!imp->rev[0]) {
+                /* This module must be selected for the next similar
+                 * import without revision-date to avoid incorrect
+                 * derived identities in the ::lys_module.identities.
+                 */
+                imp->module->latest_revision |= LYS_MOD_IMPORTED_REV;
+            }
         }
         /* check for importing the same module twice */
         for (v = 0; v < u; ++v) {
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 3282db3..2d1f989 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -2333,6 +2333,8 @@
  */
 #define LYS_MOD_LATEST_REV          0x01 /**< This is the latest revision of the module in the current context. */
 #define LYS_MOD_LATEST_SEARCHDIRS   0x02 /**< This is the latest revision of the module found in searchdirs. */
+#define LYS_MOD_IMPORTED_REV        0x04 /**< This is the module revision used when importing the module without an explicit revision-date.
+                                              It is used for all such imports regardless of any changes made in the context. */
 /** @} latestrevflags */
 
 /**
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 5415c28..0dbfefa 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -861,6 +861,53 @@
 }
 
 /**
+ * @brief Get module without revision according to priorities.
+ *
+ * 1. Search for the module with LYS_MOD_IMPORTED_REV.
+ * 2. Search for the implemented module.
+ * 3. Search for the latest module in the context.
+ *
+ * @param[in] ctx libyang context where module is searched.
+ * @param[in] name Name of the searched module.
+ * @param[out] keep_search Flag set to 1 if searchpaths or module
+ * callback must be searched to obtain latest available revision.
+ * @return Found module from context or NULL.
+ */
+static struct lys_module *
+lys_get_module_without_revision(struct ly_ctx *ctx, const char *name, ly_bool *keep_search)
+{
+    struct lys_module *mod, *mod_impl;
+    uint32_t index;
+
+    *keep_search = 0;
+
+    /* Try to find module with LYS_MOD_IMPORTED_REV flag. */
+    index = 0;
+    while ((mod = ly_ctx_get_module_iter(ctx, &index))) {
+        if (!strcmp(mod->name, name) && (mod->latest_revision & LYS_MOD_IMPORTED_REV)) {
+            break;
+        }
+    }
+
+    /* Try to find the implemented module. */
+    mod_impl = ly_ctx_get_module_implemented(ctx, name);
+    if (mod && mod_impl) {
+        LOGVRB("Implemented module \"%s@%s\" is not used for import, "
+                "revision \"%s\" is imported instead.",
+                mod_impl->name, mod_impl->revision, mod->revision);
+        return mod;
+    } else if (mod_impl) {
+        return mod_impl;
+    }
+
+    /* Try to find the latest module in the current context. */
+    mod = ly_ctx_get_module_latest(ctx, name);
+    *keep_search = 1;
+
+    return mod;
+}
+
+/**
  * @brief Check if a circular dependency exists between modules.
  *
  * @param[in] ctx libyang context for log an error.
@@ -885,6 +932,7 @@
 lys_parse_load(struct ly_ctx *ctx, const char *name, const char *revision, struct ly_set *new_mods,
         struct lys_module **mod)
 {
+    ly_bool keep_search;
     struct lys_module *mod_latest = NULL;
 
     assert(mod && new_mods);
@@ -897,8 +945,8 @@
         *mod = ly_ctx_get_module(ctx, name, revision);
     } else {
         /* Get the requested module of the latest revision in the context. */
-        *mod = ly_ctx_get_module_latest(ctx, name);
-        if (*mod) {
+        *mod = lys_get_module_without_revision(ctx, name, &keep_search);
+        if (keep_search) {
             /* Let us now search with callback and searchpaths to check
              * if there is newer revision outside the context.
              */