Merge branch 'devel' of https://github.com/CESNET/libyang into yang-data-extensions
diff --git a/src/resolve.c b/src/resolve.c
index 7f82540..9fff92e 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -3,7 +3,7 @@
  * @author Michal Vasko <mvasko@cesnet.cz>
  * @brief libyang resolve functions
  *
- * Copyright (c) 2015 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
  *
  * This source code is licensed under BSD 3-Clause License (the "License").
  * You may not use this file except in compliance with the License.
@@ -1142,14 +1142,14 @@
 
     /* check prefix */
     if ((i = parse_node_identifier(feat_name, &mod_name, &mod_name_len, &name, &nam_len, NULL, 0)) < 1) {
-        LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, feat_name[-i], &feat_name[-i]);
+        LOGVAL(node->module->ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, feat_name[-i], &feat_name[-i]);
         return -1;
     }
 
     module = lyp_get_module(lys_node_module(node), NULL, 0, mod_name, mod_name_len, 0);
     if (!module) {
         /* identity refers unknown data model */
-        LOGVAL(LYE_INMOD_LEN, LY_VLOG_NONE, NULL, mod_name_len, mod_name);
+        LOGVAL(node->module->ctx, LYE_INMOD_LEN, LY_VLOG_NONE, NULL, mod_name_len, mod_name);
         return -1;
     }
 
@@ -1200,7 +1200,7 @@
 
     /* not found */
     str = strndup(feat_name, len);
-    LOGVAL(LYE_INRESOLV, LY_VLOG_NONE, NULL, "feature", str);
+    LOGVAL(node->module->ctx, LYE_INRESOLV, LY_VLOG_NONE, NULL, "feature", str);
     free(str);
     return 1;
 }
@@ -1277,7 +1277,7 @@
     if (stack->index == stack->size) {
         stack->size += 4;
         stack->stack = ly_realloc(stack->stack, stack->size * sizeof *stack->stack);
-        LY_CHECK_ERR_RETURN(!stack->stack, LOGMEM; stack->size = 0, EXIT_FAILURE);
+        LY_CHECK_ERR_RETURN(!stack->stack, LOGMEM(NULL); stack->size = 0, EXIT_FAILURE);
     }
 
     stack->stack[stack->index++] = value;
@@ -1393,11 +1393,12 @@
     uint8_t op;
     struct iff_stack stack = {0, 0, NULL};
     struct unres_iffeat_data *iff_data;
+    struct ly_ctx *ctx = node->module->ctx;
 
     assert(c);
 
     if (isspace(c[0])) {
-        LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, c[0], c);
+        LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, c[0], c);
         return EXIT_FAILURE;
     }
 
@@ -1416,7 +1417,7 @@
 
         if (!strncmp(&c[i], "not", r = 3) || !strncmp(&c[i], "and", r = 3) || !strncmp(&c[i], "or", r = 2)) {
             if (c[i + r] == '\0') {
-                LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
+                LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
                 return EXIT_FAILURE;
             } else if (!isspace(c[i + r])) {
                 /* feature name starting with the not/and/or */
@@ -1452,15 +1453,15 @@
     }
     if (j || f_exp != f_size) {
         /* not matching count of ( and ) */
-        LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
+        LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
         return EXIT_FAILURE;
     }
 
     if (checkversion || expr_size > 1) {
         /* check that we have 1.1 module */
         if (node->module->version != 2) {
-            LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
-            LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "YANG 1.1 if-feature expression found in 1.0 module.");
+            LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "YANG 1.1 if-feature expression found in 1.0 module.");
             return EXIT_FAILURE;
         }
     }
@@ -1469,7 +1470,7 @@
     iffeat_expr->expr = calloc((j = (expr_size / 4) + ((expr_size % 4) ? 1 : 0)), sizeof *iffeat_expr->expr);
     iffeat_expr->features = calloc(f_size, sizeof *iffeat_expr->features);
     stack.stack = malloc(expr_size * sizeof *stack.stack);
-    LY_CHECK_ERR_GOTO(!stack.stack || !iffeat_expr->expr || !iffeat_expr->features, LOGMEM, error);
+    LY_CHECK_ERR_GOTO(!stack.stack || !iffeat_expr->expr || !iffeat_expr->features, LOGMEM(ctx), error);
     stack.size = expr_size;
     f_size--; expr_size--; /* used as indexes from now */
 
@@ -1528,7 +1529,7 @@
              * forward referenced, we have to keep the feature name in auxiliary
              * structure passed into unres */
             iff_data = malloc(sizeof *iff_data);
-            LY_CHECK_ERR_GOTO(!iff_data, LOGMEM, error);
+            LY_CHECK_ERR_GOTO(!iff_data, LOGMEM(ctx), error);
             iff_data->node = node;
             iff_data->fname = lydict_insert(node->module->ctx, &c[i], j - i);
             iff_data->infeature = infeature;
@@ -1537,6 +1538,7 @@
             f_size--;
 
             if (r == -1) {
+                lydict_remove(node->module->ctx, iff_data->fname);
                 free(iff_data);
                 goto error;
             }
@@ -1549,7 +1551,7 @@
 
     if (++expr_size || ++f_size) {
         /* not all expected operators and operands found */
-        LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
+        LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
         rc = EXIT_FAILURE;
     } else {
         rc = EXIT_SUCCESS;
@@ -1583,7 +1585,7 @@
     }
 
     str = p = strdup(nodeid);
-    LY_CHECK_ERR_RETURN(!str, LOGMEM, NULL);
+    LY_CHECK_ERR_RETURN(!str, LOGMEM(start->schema->module->ctx), NULL);
 
     while (p) {
         token = p;
@@ -1683,7 +1685,7 @@
     do {
         r = parse_schema_json_predicate(nodeid, &model, &mod_len, &name, &nam_len, NULL, NULL, &has_predicate);
         if (r < 1) {
-            LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, nodeid[r], &nodeid[r]);
+            LOGVAL(cur_module->ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, nodeid[r], &nodeid[r]);
             return -1;
         }
         nodeid += r;
@@ -1740,6 +1742,7 @@
     /* resolved import module from the start module, it must match the next node-name-match sibling */
     const struct lys_module *start_mod, *aux_mod = NULL;
     char *str;
+    struct ly_ctx *ctx;
 
     assert(nodeid && (start_parent || cur_module) && ret);
     *ret = NULL;
@@ -1747,18 +1750,19 @@
     if (!cur_module) {
         cur_module = lys_node_module(start_parent);
     }
+    ctx = cur_module->ctx;
     id = nodeid;
 
     r = parse_schema_nodeid(id, &mod_name, &mod_name_len, &name, &nam_len, &is_relative, &has_predicate,
                             (extended ? &all_desc : NULL), extended);
     if (r < 1) {
-        LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[r], &id[r]);
+        LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[r], &id[r]);
         return -1;
     }
     id += r;
 
     if (is_relative && !start_parent) {
-        LOGINT;
+        LOGVAL(ctx, LYE_SPEC, LY_VLOG_STR, nodeid, "Starting node must be provided for relative paths.");
         return -1;
     }
 
@@ -1771,7 +1775,7 @@
         start_mod = lyp_get_module(cur_module, NULL, 0, mod_name, mod_name_len, 0);
         if (!start_mod) {
             str = strndup(mod_name, mod_name_len);
-            LOGVAL(LYE_PATH_INMOD, LY_VLOG_STR, str);
+            LOGVAL(ctx, LYE_PATH_INMOD, LY_VLOG_STR, str);
             free(str);
             return -1;
         }
@@ -1789,7 +1793,7 @@
                 aux_mod = lyp_get_module(cur_module, NULL, 0, mod_name, mod_name_len, 0);
                 if (!aux_mod) {
                     str = strndup(mod_name, mod_name_len);
-                    LOGVAL(LYE_PATH_INMOD, LY_VLOG_STR, str);
+                    LOGVAL(ctx, LYE_PATH_INMOD, LY_VLOG_STR, str);
                     free(str);
                     return -1;
                 }
@@ -1808,7 +1812,7 @@
         }
 
         while ((sibling = lys_getnext(sibling, (last_aug ? (struct lys_node *)last_aug : start_parent), start_mod,
-                LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE | LYS_GETNEXT_WITHINOUT | LYS_GETNEXT_PARENTUSES))) {
+                LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE | LYS_GETNEXT_WITHINOUT | LYS_GETNEXT_PARENTUSES | LYS_GETNEXT_NOSTATECHECK))) {
             r = schema_nodeid_siblingcheck(sibling, cur_module, mod_name, mod_name_len, name, nam_len);
 
             /* resolve predicate */
@@ -1827,7 +1831,7 @@
                 /* one matching result */
                 if (nodeid_end) {
                     *ret = ly_set_new();
-                    LY_CHECK_ERR_RETURN(!*ret, LOGMEM, -1);
+                    LY_CHECK_ERR_RETURN(!*ret, LOGMEM(ctx), -1);
                     ly_set_add(*ret, (void *)sibling, LY_SET_OPT_USEASLIST);
                 } else {
                     if (sibling->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)) {
@@ -1842,7 +1846,7 @@
                 /* "*" */
                 if (!*ret) {
                     *ret = ly_set_new();
-                    LY_CHECK_ERR_RETURN(!*ret, LOGMEM, -1);
+                    LY_CHECK_ERR_RETURN(!*ret, LOGMEM(ctx), -1);
                 }
                 ly_set_add(*ret, (void *)sibling, LY_SET_OPT_USEASLIST);
                 if (all_desc) {
@@ -1858,7 +1862,7 @@
                 /* "." */
                 if (!*ret) {
                     *ret = ly_set_new();
-                    LY_CHECK_ERR_RETURN(!*ret, LOGMEM, -1);
+                    LY_CHECK_ERR_RETURN(!*ret, LOGMEM(ctx), -1);
                     ly_set_add(*ret, (void *)start_parent, LY_SET_OPT_USEASLIST);
                 }
                 ly_set_add(*ret, (void *)sibling, LY_SET_OPT_USEASLIST);
@@ -1872,7 +1876,7 @@
                     }
                 }
             } else {
-                LOGINT;
+                LOGINT(ctx);
                 return -1;
             }
         }
@@ -1882,7 +1886,7 @@
             while (id[0] == '[') {
                 id = strchr(id, ']');
                 if (!id) {
-                    LOGINT;
+                    LOGINT(ctx);
                     return -1;
                 }
                 ++id;
@@ -1901,7 +1905,7 @@
             }
             if (no_node_error) {
                 str = strndup(nodeid, (name - nodeid) + nam_len);
-                LOGVAL(LYE_PATH_INNODE, LY_VLOG_STR, str);
+                LOGVAL(ctx, LYE_PATH_INNODE, LY_VLOG_STR, str);
                 free(str);
                 return -1;
             }
@@ -1912,14 +1916,14 @@
         r = parse_schema_nodeid(id, &mod_name, &mod_name_len, &name, &nam_len, &is_relative, &has_predicate,
                                 (extended ? &all_desc : NULL), extended);
         if (r < 1) {
-            LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[r], &id[r]);
+            LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[r], &id[r]);
             return -1;
         }
         id += r;
     }
 
     /* cannot get here */
-    LOGINT;
+    LOGINT(ctx);
     return -1;
 }
 
@@ -1966,7 +1970,7 @@
     while (1) {
         sibling = NULL;
         while ((sibling = lys_getnext(sibling, start_parent, module,
-                                      LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE | LYS_GETNEXT_PARENTUSES))) {
+                LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE | LYS_GETNEXT_PARENTUSES | LYS_GETNEXT_NOSTATECHECK))) {
             r = schema_nodeid_siblingcheck(sibling, module, mod_name, mod_name_len, name, nam_len);
             if (r == 0) {
                 if (!id[0]) {
@@ -2002,7 +2006,7 @@
     }
 
     /* cannot get here */
-    LOGINT;
+    LOGINT(module->ctx);
     return -1;
 }
 
@@ -2076,7 +2080,7 @@
     while (1) {
         sibling = NULL;
         while ((sibling = lys_getnext(sibling, start_parent, abs_start_mod, LYS_GETNEXT_WITHCHOICE
-                                      | LYS_GETNEXT_WITHCASE | LYS_GETNEXT_WITHINOUT | LYS_GETNEXT_WITHGROUPING))) {
+                | LYS_GETNEXT_WITHCASE | LYS_GETNEXT_WITHINOUT | LYS_GETNEXT_WITHGROUPING | LYS_GETNEXT_NOSTATECHECK))) {
             r = schema_nodeid_siblingcheck(sibling, module, mod_name, mod_name_len, name, nam_len);
             if (r == 0) {
                 if (!id[0]) {
@@ -2109,7 +2113,7 @@
     }
 
     /* cannot get here */
-    LOGINT;
+    LOGINT(module->ctx);
     return -1;
 }
 
@@ -2122,7 +2126,7 @@
 
     if (((i = parse_schema_json_predicate(predicate, &mod_name, &mod_name_len, &name, &nam_len, NULL, NULL, &has_predicate)) < 1)
             || !strncmp(name, ".", nam_len)) {
-        LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, predicate[-i], &predicate[-i]);
+        LOGVAL(list->module->ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, predicate[-i], &predicate[-i]);
         return -1;
     }
 
@@ -2138,7 +2142,7 @@
         }
 
         if (i == list->keys_size) {
-            LOGVAL(LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
+            LOGVAL(list->module->ctx, LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
             return -1;
         }
     }
@@ -2155,7 +2159,7 @@
 const struct lys_node *
 resolve_json_nodeid(const char *nodeid, struct ly_ctx *ctx, const struct lys_node *start, int output)
 {
-    char *module_name = ly_buf(), *buf_backup = NULL, *str;
+    char *str;
     const char *name, *mod_name, *id;
     const struct lys_node *sibling, *start_parent, *parent;
     int r, nam_len, mod_name_len, is_relative = -1, has_predicate;
@@ -2170,7 +2174,7 @@
     id = nodeid;
 
     if ((r = parse_schema_nodeid(id, &mod_name, &mod_name_len, &name, &nam_len, &is_relative, &has_predicate, NULL, 0)) < 1) {
-        LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
+        LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
         return NULL;
     }
     id += r;
@@ -2185,34 +2189,18 @@
     } else {
         if (!mod_name) {
             str = strndup(nodeid, (name + nam_len) - nodeid);
-            LOGVAL(LYE_PATH_MISSMOD, LY_VLOG_STR, nodeid);
+            LOGVAL(ctx, LYE_PATH_MISSMOD, LY_VLOG_STR, nodeid);
             free(str);
             return NULL;
-        } else if (mod_name_len > LY_BUF_SIZE - 1) {
-            LOGINT;
-            return NULL;
         }
 
-        if (ly_buf_used && module_name[0]) {
-            buf_backup = strndup(module_name, LY_BUF_SIZE - 1);
-        }
-        ly_buf_used++;
-
-        memmove(module_name, mod_name, mod_name_len);
-        module_name[mod_name_len] = '\0';
-        module = ly_ctx_get_module(ctx, module_name, NULL, 1);
-
-        if (buf_backup) {
-            /* return previous internal buffer content */
-            strcpy(module_name, buf_backup);
-            free(buf_backup);
-            buf_backup = NULL;
-        }
-        ly_buf_used--;
+        str = strndup(mod_name, mod_name_len);
+        module = ly_ctx_get_module(ctx, str, NULL, 1);
+        free(str);
 
         if (!module) {
             str = strndup(nodeid, (mod_name + mod_name_len) - nodeid);
-            LOGVAL(LYE_PATH_INMOD, LY_VLOG_STR, str);
+            LOGVAL(ctx, LYE_PATH_INMOD, LY_VLOG_STR, str);
             free(str);
             return NULL;
         }
@@ -2242,32 +2230,12 @@
 
                 /* module check */
                 if (mod_name) {
-                    if (mod_name_len > LY_BUF_SIZE - 1) {
-                        LOGINT;
-                        return NULL;
-                    }
-
-                    if (ly_buf_used && module_name[0]) {
-                        buf_backup = strndup(module_name, LY_BUF_SIZE - 1);
-                    }
-                    ly_buf_used++;
-
-                    memmove(module_name, mod_name, mod_name_len);
-                    module_name[mod_name_len] = '\0';
                     /* will also find an augment module */
-                    prefix_mod = ly_ctx_get_module(ctx, module_name, NULL, 1);
-
-                    if (buf_backup) {
-                        /* return previous internal buffer content */
-                        strncpy(module_name, buf_backup, LY_BUF_SIZE - 1);
-                        free(buf_backup);
-                        buf_backup = NULL;
-                    }
-                    ly_buf_used--;
+                    prefix_mod = ly_ctx_nget_module(ctx, mod_name, mod_name_len, NULL, 1);
 
                     if (!prefix_mod) {
                         str = strndup(nodeid, (mod_name + mod_name_len) - nodeid);
-                        LOGVAL(LYE_PATH_INMOD, LY_VLOG_STR, str);
+                        LOGVAL(ctx, LYE_PATH_INMOD, LY_VLOG_STR, str);
                         free(str);
                         return NULL;
                     }
@@ -2283,7 +2251,7 @@
                     r = 0;
                     if (sibling->nodetype & (LYS_LEAF | LYS_LEAFLIST)) {
                         if ((r = parse_schema_json_predicate(id, NULL, NULL, NULL, NULL, NULL, NULL, &has_predicate)) < 1) {
-                            LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
+                            LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
                             return NULL;
                         }
                     } else if (sibling->nodetype == LYS_LIST) {
@@ -2291,7 +2259,7 @@
                             return NULL;
                         }
                     } else {
-                        LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[0], id);
+                        LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[0], id);
                         return NULL;
                     }
                     id += r;
@@ -2304,7 +2272,7 @@
 
                 /* move down the tree, if possible */
                 if (sibling->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)) {
-                    LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[0], id);
+                    LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[0], id);
                     return NULL;
                 }
                 start_parent = sibling;
@@ -2318,20 +2286,20 @@
         /* no match */
         if (!sibling) {
             str = strndup(nodeid, (name + nam_len) - nodeid);
-            LOGVAL(LYE_PATH_INNODE, LY_VLOG_STR, str);
+            LOGVAL(ctx, LYE_PATH_INNODE, LY_VLOG_STR, str);
             free(str);
             return NULL;
         }
 
         if ((r = parse_schema_nodeid(id, &mod_name, &mod_name_len, &name, &nam_len, &is_relative, &has_predicate, NULL, 0)) < 1) {
-            LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
+            LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
             return NULL;
         }
         id += r;
     }
 
     /* cannot get here */
-    LOGINT;
+    LOGINT(ctx);
     return NULL;
 }
 
@@ -2343,14 +2311,16 @@
     int mod_name_len, nam_len, val_len, has_predicate = 1, r;
     uint16_t i;
     struct lyd_node_leaf_list *key;
+    struct ly_ctx *ctx;
 
     assert(node);
     assert(node->schema->nodetype == LYS_LIST);
+    ctx = node->schema->module->ctx;
 
     /* is the predicate a number? */
     if (((r = parse_schema_json_predicate(predicate, &mod_name, &mod_name_len, &name, &nam_len, &value, &val_len, &has_predicate)) < 1)
             || !strncmp(name, ".", nam_len)) {
-        LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, predicate[-r], &predicate[-r]);
+        LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, predicate[-r], &predicate[-r]);
         return -1;
     }
 
@@ -2382,13 +2352,13 @@
 
     for (; i < ((struct lys_node_list *)node->schema)->keys_size; ++i) {
         if (!has_predicate) {
-            LOGVAL(LYE_PATH_MISSKEY, LY_VLOG_NONE, NULL, node_name);
+            LOGVAL(ctx, LYE_PATH_MISSKEY, LY_VLOG_NONE, NULL, node_name);
             return -1;
         }
 
         if (((r = parse_schema_json_predicate(predicate, &mod_name, &mod_name_len, &name, &nam_len, &value, &val_len, &has_predicate)) < 1)
                 || !strncmp(name, ".", nam_len)) {
-            LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, predicate[-r], &predicate[-r]);
+            LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, predicate[-r], &predicate[-r]);
             return -1;
         }
 
@@ -2397,7 +2367,7 @@
         *parsed += r;
 
         if (strncmp(key->schema->name, name, nam_len) || key->schema->name[nam_len]) {
-            LOGVAL(LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
+            LOGVAL(ctx, LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
             return -1;
         }
 
@@ -2405,19 +2375,19 @@
             /* specific module, check that the found key is from that module */
             if (strncmp(lyd_node_module((struct lyd_node *)key)->name, mod_name, mod_name_len)
                     || lyd_node_module((struct lyd_node *)key)->name[mod_name_len]) {
-                LOGVAL(LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
+                LOGVAL(ctx, LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
                 return -1;
             }
 
             /* but if the module is the same as the parent, it should have been omitted */
             if (lyd_node_module((struct lyd_node *)key) == lyd_node_module(node)) {
-                LOGVAL(LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
+                LOGVAL(ctx, LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
                 return -1;
             }
         } else {
             /* no module, so it must be the same as the list (parent) */
             if (lyd_node_module((struct lyd_node *)key) != lyd_node_module(node)) {
-                LOGVAL(LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
+                LOGVAL(ctx, LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
                 return -1;
             }
         }
@@ -2440,7 +2410,7 @@
     }
 
     if (has_predicate) {
-        LOGVAL(LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
+        LOGVAL(ctx, LYE_PATH_INKEY, LY_VLOG_NONE, NULL, name);
         return -1;
     }
 
@@ -2460,7 +2430,7 @@
 resolve_partial_json_data_nodeid(const char *nodeid, const char *llist_value, struct lyd_node *start, int options,
                                  int *parsed)
 {
-    char *module_name = ly_buf(), *buf_backup = NULL, *str;
+    char *str;
     const char *id, *mod_name, *name, *pred_name, *data_val;
     int r, ret, mod_name_len, nam_len, is_relative = -1, list_instance_position;
     int has_predicate, last_parsed, llval_len, pred_name_len, last_has_pred;
@@ -2475,7 +2445,7 @@
     id = nodeid;
 
     if ((r = parse_schema_nodeid(id, &mod_name, &mod_name_len, &name, &nam_len, &is_relative, &has_predicate, NULL, 0)) < 1) {
-        LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
+        LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
         *parsed = -1;
         return NULL;
     }
@@ -2499,13 +2469,13 @@
             if (lys_parent(sibling->schema)) {
                 if (options & LYD_PATH_OPT_OUTPUT) {
                     if (lys_parent(sibling->schema)->nodetype == LYS_INPUT) {
-                        LOGERR(LY_EINVAL, "Provided data tree includes some RPC input nodes (%s).", sibling->schema->name);
+                        LOGERR(ctx, LY_EINVAL, "Provided data tree includes some RPC input nodes (%s).", sibling->schema->name);
                         *parsed = -1;
                         return NULL;
                     }
                 } else {
                     if (lys_parent(sibling->schema)->nodetype == LYS_OUTPUT) {
-                        LOGERR(LY_EINVAL, "Provided data tree includes some RPC output nodes (%s).", sibling->schema->name);
+                        LOGERR(ctx, LY_EINVAL, "Provided data tree includes some RPC output nodes (%s).", sibling->schema->name);
                         *parsed = -1;
                         return NULL;
                     }
@@ -2517,33 +2487,11 @@
 
                 /* module check */
                 if (mod_name) {
-                    if (mod_name_len > LY_BUF_SIZE - 1) {
-                        LOGINT;
-                        *parsed = -1;
-                        return NULL;
-                    }
-
-                    if (ly_buf_used && module_name[0]) {
-                        buf_backup = strndup(module_name, LY_BUF_SIZE - 1);
-                    }
-                    ly_buf_used++;
-
-                    memmove(module_name, mod_name, mod_name_len);
-                    module_name[mod_name_len] = '\0';
-                    /* will also find an augment module */
-                    prefix_mod = ly_ctx_get_module(ctx, module_name, NULL, 1);
-
-                    if (buf_backup) {
-                        /* return previous internal buffer content */
-                        strncpy(module_name, buf_backup, LY_BUF_SIZE - 1);
-                        free(buf_backup);
-                        buf_backup = NULL;
-                    }
-                    ly_buf_used--;
+                    prefix_mod = ly_ctx_nget_module(ctx, mod_name, mod_name_len, NULL, 1);
 
                     if (!prefix_mod) {
                         str = strndup(nodeid, (mod_name + mod_name_len) - nodeid);
-                        LOGVAL(LYE_PATH_INMOD, LY_VLOG_STR, str);
+                        LOGVAL(ctx, LYE_PATH_INMOD, LY_VLOG_STR, str);
                         free(str);
                         *parsed = -1;
                         return NULL;
@@ -2563,12 +2511,12 @@
                     if (has_predicate) {
                         if ((r = parse_schema_json_predicate(id, NULL, NULL, &pred_name, &pred_name_len, &llist_value,
                                                              &llval_len, &last_has_pred)) < 1) {
-                            LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[0], id);
+                            LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[0], id);
                             *parsed = -1;
                             return NULL;
                         }
                         if ((pred_name[0] != '.') || (pred_name_len != 1)) {
-                            LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[1], id + 1);
+                            LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[1], id + 1);
                             *parsed = -1;
                             return NULL;
                         }
@@ -2627,7 +2575,7 @@
 
                 /* move down the tree, if possible */
                 if (sibling->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)) {
-                    LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[0], id);
+                    LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[0], id);
                     *parsed = -1;
                     return NULL;
                 }
@@ -2644,7 +2592,7 @@
         }
 
         if ((r = parse_schema_nodeid(id, &mod_name, &mod_name_len, &name, &nam_len, &is_relative, &has_predicate, NULL, 0)) < 1) {
-            LOGVAL(LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
+            LOGVAL(ctx, LYE_PATH_INCHAR, LY_VLOG_NONE, NULL, id[-r], &id[-r]);
             *parsed = -1;
             return NULL;
         }
@@ -2653,7 +2601,7 @@
     }
 
     /* cannot get here */
-    LOGINT;
+    LOGINT(ctx);
     *parsed = -1;
     return NULL;
 }
@@ -2662,6 +2610,7 @@
  * @brief Resolves length or range intervals. Does not log.
  * Syntax is assumed to be correct, *ret MUST be NULL.
  *
+ * @param[in] ctx Context for errors.
  * @param[in] str_restr Restriction as a string.
  * @param[in] type Type of the restriction.
  * @param[out] ret Final interval structure that starts with
@@ -2672,7 +2621,7 @@
  * @return EXIT_SUCCESS on succes, -1 on error.
  */
 int
-resolve_len_ran_interval(const char *str_restr, struct lys_type *type, struct len_ran_intv **ret)
+resolve_len_ran_interval(struct ly_ctx *ctx, const char *str_restr, struct lys_type *type, struct len_ran_intv **ret)
 {
     /* 0 - unsigned, 1 - signed, 2 - floating point */
     int kind;
@@ -2789,7 +2738,7 @@
 
     /* process superior types */
     if (type->der) {
-        if (resolve_len_ran_interval(NULL, &type->der->type, &intv)) {
+        if (resolve_len_ran_interval(ctx, NULL, &type->der->type, &intv)) {
             return -1;
         }
         assert(!intv || (intv->kind == kind));
@@ -2838,7 +2787,7 @@
             tmp_local_intv->next = malloc(sizeof *tmp_local_intv);
             tmp_local_intv = tmp_local_intv->next;
         }
-        LY_CHECK_ERR_GOTO(!tmp_local_intv, LOGMEM, error);
+        LY_CHECK_ERR_GOTO(!tmp_local_intv, LOGMEM(ctx), error);
 
         tmp_local_intv->kind = kind;
         tmp_local_intv->type = type;
@@ -2856,7 +2805,7 @@
                 tmp_local_intv->value.sval.min = strtoll(ptr, (char **)&ptr, 10);
             } else if (kind == 2) {
                 if (parse_range_dec64(&ptr, local_fdig, &tmp_local_intv->value.fval.min)) {
-                    LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, ptr, "range");
+                    LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, ptr, "range");
                     goto error;
                 }
             }
@@ -2912,7 +2861,7 @@
                     tmp_local_intv->value.sval.max = strtoll(ptr, (char **)&ptr, 10);
                 } else if (kind == 2) {
                     if (parse_range_dec64(&ptr, local_fdig, &tmp_local_intv->value.fval.max)) {
-                        LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, ptr, "range");
+                        LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, ptr, "range");
                         goto error;
                     }
                 }
@@ -3204,16 +3153,19 @@
     struct lyd_node_leaf_list node;
     const char *dflt = NULL;
     char *s;
-    int ret = EXIT_SUCCESS;
+    int ret = EXIT_SUCCESS, r;
+    struct ly_ctx *ctx = module->ctx;
 
     assert(value);
+    memset(&node, 0, sizeof node);
 
     if (type->base <= LY_TYPE_DER) {
         /* the type was not resolved yet, nothing to do for now */
-        return EXIT_FAILURE;
+        ret = EXIT_FAILURE;
+        goto cleanup;
     } else if (!tpdf && !module->implemented) {
         /* do not check defaults in not implemented module's data */
-        return EXIT_SUCCESS;
+        goto cleanup;
     } else if (tpdf && !module->implemented && type->base == LY_TYPE_IDENT) {
         /* identityrefs are checked when instantiated in data instead of typedef,
          * but in typedef the value has to be modified to include the prefix */
@@ -3222,38 +3174,43 @@
                 dflt = transform_schema2json(module, *value);
             } else {
                 /* default prefix of the module where the typedef is defined */
-                asprintf(&s, "%s:%s", lys_main_module(module)->name, *value);
-                dflt = lydict_insert_zc(module->ctx, s);
+                if (asprintf(&s, "%s:%s", lys_main_module(module)->name, *value) == -1) {
+                    LOGMEM(ctx);
+                    ret = -1;
+                    goto cleanup;
+                }
+                dflt = lydict_insert_zc(ctx, s);
             }
-            lydict_remove(module->ctx, *value);
+            lydict_remove(ctx, *value);
             *value = dflt;
+            dflt = NULL;
         }
-        return EXIT_SUCCESS;
+        goto cleanup;
     } else if (type->base == LY_TYPE_LEAFREF && tpdf) {
         /* leafref in typedef cannot be checked */
-        return EXIT_SUCCESS;
+        goto cleanup;
     }
 
-    dflt = *value;
+    dflt = lydict_insert(ctx, *value, 0);
     if (!dflt) {
         /* we do not have a new default value, so is there any to check even, in some base type? */
         for (base_tpdf = type->der; base_tpdf->type.der; base_tpdf = base_tpdf->type.der) {
             if (base_tpdf->dflt) {
-                dflt = base_tpdf->dflt;
+                dflt = lydict_insert(ctx, base_tpdf->dflt, 0);
                 break;
             }
         }
 
         if (!dflt) {
             /* no default value, nothing to check, all is well */
-            return EXIT_SUCCESS;
+            goto cleanup;
         }
 
         /* so there is a default value in a base type, but can the default value be no longer valid (did we define some new restrictions)? */
         switch (type->base) {
         case LY_TYPE_IDENT:
             if (lys_main_module(base_tpdf->type.parent->module)->implemented) {
-                return EXIT_SUCCESS;
+                goto cleanup;
             } else {
                 /* check the default value from typedef, but use also the typedef's module
                  * due to possible searching in imported modules which is expected in
@@ -3266,29 +3223,29 @@
         case LY_TYPE_BOOL:
         case LY_TYPE_EMPTY:
             /* these have no restrictions, so we would do the exact same work as the unres in the base typedef */
-            return EXIT_SUCCESS;
+            goto cleanup;
         case LY_TYPE_BITS:
             /* the default value must match the restricted list of values, if the type was restricted */
             if (type->info.bits.count) {
                 break;
             }
-            return EXIT_SUCCESS;
+            goto cleanup;
         case LY_TYPE_ENUM:
             /* the default value must match the restricted list of values, if the type was restricted */
             if (type->info.enums.count) {
                 break;
             }
-            return EXIT_SUCCESS;
+            goto cleanup;
         case LY_TYPE_DEC64:
             if (type->info.dec64.range) {
                 break;
             }
-            return EXIT_SUCCESS;
+            goto cleanup;
         case LY_TYPE_BINARY:
             if (type->info.binary.length) {
                 break;
             }
-            return EXIT_SUCCESS;
+            goto cleanup;
         case LY_TYPE_INT8:
         case LY_TYPE_INT16:
         case LY_TYPE_INT32:
@@ -3300,35 +3257,45 @@
             if (type->info.num.range) {
                 break;
             }
-            return EXIT_SUCCESS;
+            goto cleanup;
         case LY_TYPE_STRING:
             if (type->info.str.length || type->info.str.patterns) {
                 break;
             }
-            return EXIT_SUCCESS;
+            goto cleanup;
         case LY_TYPE_UNION:
             /* way too much trouble learning whether we need to check the default again, so just do it */
             break;
         default:
-            LOGINT;
-            return -1;
+            LOGINT(ctx);
+            ret = -1;
+            goto cleanup;
         }
     } else if (type->base == LY_TYPE_EMPTY) {
-        LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", type->parent->name);
-        LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"empty\" data type cannot have a default value.");
-        return -1;
+        LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", type->parent->name);
+        LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"empty\" data type cannot have a default value.");
+        ret = -1;
+        goto cleanup;
     }
 
     /* dummy leaf */
     memset(&node, 0, sizeof node);
-    node.value_str = dflt;
+    node.value_str = lydict_insert(ctx, dflt, 0);
     node.value_type = type->base;
 
     if (tpdf) {
         node.schema = calloc(1, sizeof (struct lys_node_leaf));
-        LY_CHECK_ERR_RETURN(!node.schema, LOGMEM, -1);
-        asprintf((char **)&node.schema->name, "typedef-%s-default", ((struct lys_tpdf *)type->parent)->name);
-        LY_CHECK_ERR_RETURN(!node.schema->name, LOGMEM; free(node.schema), -1);
+        if (!node.schema) {
+            LOGMEM(ctx);
+            ret = -1;
+            goto cleanup;
+        }
+        r = asprintf((char **)&node.schema->name, "typedef-%s-default", ((struct lys_tpdf *)type->parent)->name);
+        if (r == -1) {
+            LOGMEM(ctx);
+            ret = -1;
+            goto cleanup;
+        }
         node.schema->module = module;
         memcpy(&((struct lys_node_leaf *)node.schema)->type, type, sizeof *type);
     } else {
@@ -3338,48 +3305,55 @@
     if (type->base == LY_TYPE_LEAFREF) {
         if (!type->info.lref.target) {
             ret = EXIT_FAILURE;
-            goto finish;
+            goto cleanup;
         }
         ret = check_default(&type->info.lref.target->type, &dflt, module, 0);
         if (!ret) {
             /* adopt possibly changed default value to its canonical form */
             if (*value) {
+                lydict_remove(ctx, *value);
                 *value = dflt;
+                dflt = NULL;
             }
         }
     } else {
         if (!lyp_parse_value(type, &node.value_str, NULL, &node, NULL, module, 1, 1)) {
             /* possible forward reference */
-            ret = 1;
+            ret = EXIT_FAILURE;
             if (base_tpdf) {
                 /* default value is defined in some base typedef */
                 if ((type->base == LY_TYPE_BITS && type->der->type.der) ||
                         (type->base == LY_TYPE_ENUM && type->der->type.der)) {
                     /* we have refined bits/enums */
-                    LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
                            "Invalid value \"%s\" of the default statement inherited to \"%s\" from \"%s\" base type.",
                            dflt, type->parent->name, base_tpdf->name);
                 }
             }
         } else {
             /* success - adopt canonical form from the node into the default value */
-            if (dflt != node.value_str) {
+            if (!ly_strequal(dflt, node.value_str, 1)) {
                 /* this can happen only if we have non-inherited default value,
                  * inherited default values are already in canonical form */
-                assert(dflt == *value);
+                assert(ly_strequal(dflt, *value, 1));
+
+                lydict_remove(ctx, *value);
                 *value = node.value_str;
+                node.value_str = NULL;
             }
         }
     }
 
-finish:
+cleanup:
     if (node.value_type == LY_TYPE_BITS) {
         free(node.value.bit);
     }
-    if (tpdf) {
+    lydict_remove(ctx, node.value_str);
+    if (tpdf && node.schema) {
         free((char *)node.schema->name);
         free(node.schema);
     }
+    lydict_remove(ctx, dflt);
 
     return ret;
 }
@@ -3402,16 +3376,17 @@
     struct lys_node_leaf *key = list->keys[index];
     char *dup = NULL;
     int j;
+    struct ly_ctx *ctx = list->module->ctx;
 
     /* existence */
     if (!key) {
         if (name[len] != '\0') {
             dup = strdup(name);
-            LY_CHECK_ERR_RETURN(!dup, LOGMEM, -1);
+            LY_CHECK_ERR_RETURN(!dup, LOGMEM(ctx), -1);
             dup[len] = '\0';
             name = dup;
         }
-        LOGVAL(LYE_KEY_MISS, LY_VLOG_LYS, list, name);
+        LOGVAL(ctx, LYE_KEY_MISS, LY_VLOG_LYS, list, name);
         free(dup);
         return -1;
     }
@@ -3419,41 +3394,41 @@
     /* uniqueness */
     for (j = index - 1; j >= 0; j--) {
         if (key == list->keys[j]) {
-            LOGVAL(LYE_KEY_DUP, LY_VLOG_LYS, list, key->name);
+            LOGVAL(ctx, LYE_KEY_DUP, LY_VLOG_LYS, list, key->name);
             return -1;
         }
     }
 
     /* key is a leaf */
     if (key->nodetype != LYS_LEAF) {
-        LOGVAL(LYE_KEY_NLEAF, LY_VLOG_LYS, list, key->name);
+        LOGVAL(ctx, LYE_KEY_NLEAF, LY_VLOG_LYS, list, key->name);
         return -1;
     }
 
     /* type of the leaf is not built-in empty */
     if (key->type.base == LY_TYPE_EMPTY && key->module->version < 2) {
-        LOGVAL(LYE_KEY_TYPE, LY_VLOG_LYS, list, key->name);
+        LOGVAL(ctx, LYE_KEY_TYPE, LY_VLOG_LYS, list, key->name);
         return -1;
     }
 
     /* config attribute is the same as of the list */
     if ((key->flags & LYS_CONFIG_MASK) && (list->flags & LYS_CONFIG_MASK) != (key->flags & LYS_CONFIG_MASK)) {
-        LOGVAL(LYE_KEY_CONFIG, LY_VLOG_LYS, list, key->name);
+        LOGVAL(ctx, LYE_KEY_CONFIG, LY_VLOG_LYS, list, key->name);
         return -1;
     }
 
     /* key is not placed from augment */
     if (key->parent->nodetype == LYS_AUGMENT) {
-        LOGVAL(LYE_KEY_MISS, LY_VLOG_LYS, key, key->name);
-        LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Key inserted from augment.");
+        LOGVAL(ctx, LYE_KEY_MISS, LY_VLOG_LYS, key, key->name);
+        LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Key inserted from augment.");
         return -1;
     }
 
     /* key is not when/if-feature -conditional */
     j = 0;
     if (key->when || (key->iffeature_size && (j = 1))) {
-        LOGVAL(LYE_INCHILDSTMT, LY_VLOG_LYS, key, j ? "if-feature" : "when", "leaf");
-        LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Key definition cannot depend on a \"%s\" condition.",
+        LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, key, j ? "if-feature" : "when", "leaf");
+        LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Key definition cannot depend on a \"%s\" condition.",
                j ? "if-feature" : "when");
         return -1;
     }
@@ -3474,27 +3449,28 @@
 {
     int rc;
     const struct lys_node *leaf = NULL;
+    struct ly_ctx *ctx = parent->module->ctx;
 
     rc = resolve_descendant_schema_nodeid(uniq_str_path, *lys_child(parent, LYS_LEAF), LYS_LEAF, 1, &leaf);
     if (rc || !leaf) {
         if (rc) {
-            LOGVAL(LYE_INARG, LY_VLOG_LYS, parent, uniq_str_path, "unique");
+            LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, parent, uniq_str_path, "unique");
             if (rc > 0) {
-                LOGVAL(LYE_INCHAR, LY_VLOG_PREV, NULL, uniq_str_path[rc - 1], &uniq_str_path[rc - 1]);
+                LOGVAL(ctx, LYE_INCHAR, LY_VLOG_PREV, NULL, uniq_str_path[rc - 1], &uniq_str_path[rc - 1]);
             } else if (rc == -2) {
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Unique argument references list.");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Unique argument references list.");
             }
             rc = -1;
         } else {
-            LOGVAL(LYE_INARG, LY_VLOG_LYS, parent, uniq_str_path, "unique");
-            LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Target leaf not found.");
+            LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, parent, uniq_str_path, "unique");
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Target leaf not found.");
             rc = EXIT_FAILURE;
         }
         goto error;
     }
     if (leaf->nodetype != LYS_LEAF) {
-        LOGVAL(LYE_INARG, LY_VLOG_LYS, parent, uniq_str_path, "unique");
-        LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Target is not a leaf.");
+        LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, parent, uniq_str_path, "unique");
+        LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Target is not a leaf.");
         return -1;
     }
 
@@ -3507,8 +3483,8 @@
     /* check that all unique's targets are of the same config type */
     if (*trg_type) {
         if (((*trg_type == 1) && (leaf->flags & LYS_CONFIG_R)) || ((*trg_type == 2) && (leaf->flags & LYS_CONFIG_W))) {
-            LOGVAL(LYE_INARG, LY_VLOG_LYS, parent, uniq_str_path, "unique");
-            LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL,
+            LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, parent, uniq_str_path, "unique");
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL,
                    "Leaf \"%s\" referenced in unique statement is config %s, but previous referenced leaf is config %s.",
                    uniq_str_path, *trg_type == 1 ? "false" : "true", *trg_type == 1 ? "true" : "false");
             return -1;
@@ -3572,7 +3548,7 @@
     if (!parents->count) {
         parents->count = 1;
         parents->node = malloc(sizeof *parents->node);
-        LY_CHECK_ERR_RETURN(!parents->node, LOGMEM, -1);
+        LY_CHECK_ERR_RETURN(!parents->node, LOGMEM(mod->ctx), -1);
         parents->node[0] = NULL;
     }
     for (i = 0; i < parents->count;) {
@@ -3594,7 +3570,7 @@
                     /* multiple matching, so create a new node */
                     ++parents->count;
                     parents->node = ly_realloc(parents->node, parents->count * sizeof *parents->node);
-                    LY_CHECK_ERR_RETURN(!parents->node, LOGMEM, EXIT_FAILURE);
+                    LY_CHECK_ERR_RETURN(!parents->node, LOGMEM(mod->ctx), EXIT_FAILURE);
                     parents->node[parents->count-1] = node;
                     ++i;
                 }
@@ -3661,11 +3637,12 @@
     const char *path_key_expr, *source, *sour_pref, *dest, *dest_pref;
     int pke_len, sour_len, sour_pref_len, dest_len, dest_pref_len, pke_parsed, parsed = 0;
     int has_predicate, dest_parent_times, i, rc, first_iter;
+    struct ly_ctx *ctx = context_node->module->ctx;
 
     do {
         if ((i = parse_path_predicate(path, &sour_pref, &sour_pref_len, &source, &sour_len, &path_key_expr,
                                       &pke_len, &has_predicate)) < 1) {
-            LOGVAL(LYE_INCHAR, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, path[-i], path-i);
+            LOGVAL(ctx, LYE_INCHAR, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, path[-i], path-i);
             return -parsed+i;
         }
         parsed += i;
@@ -3679,7 +3656,7 @@
         }
         rc = lys_getnext_data(trg_mod, context_node, source, sour_len, LYS_LEAF | LYS_LEAFLIST, &src_node);
         if (rc) {
-            LOGVAL(LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path-parsed);
+            LOGVAL(ctx, LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path-parsed);
             return 0;
         }
 
@@ -3688,7 +3665,7 @@
         pke_parsed = 0;
         if ((i = parse_path_key_expr(path_key_expr, &dest_pref, &dest_pref_len, &dest, &dest_len,
                                      &dest_parent_times)) < 1) {
-            LOGVAL(LYE_INCHAR, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, path_key_expr[-i], path_key_expr-i);
+            LOGVAL(ctx, LYE_INCHAR, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, path_key_expr[-i], path_key_expr-i);
             return -parsed;
         }
         pke_parsed += i;
@@ -3697,7 +3674,7 @@
             if (dst_node->parent && (dst_node->parent->nodetype == LYS_AUGMENT)
                     && !((struct lys_node_augment *)dst_node->parent)->target) {
                 /* we are in an unresolved augment, cannot evaluate */
-                LOGVAL(LYE_SPEC, LY_VLOG_LYS, dst_node->parent,
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYS, dst_node->parent,
                        "Cannot resolve leafref predicate \"%s\" because it is in an unresolved augment.", path_key_expr);
                 return 0;
             }
@@ -3709,7 +3686,7 @@
                  dst_node = lys_parent(dst_node));
 
             if (!dst_node) {
-                LOGVAL(LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path_key_expr);
+                LOGVAL(ctx, LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path_key_expr);
                 return 0;
             }
         }
@@ -3722,7 +3699,7 @@
             }
             rc = lys_getnext_data(trg_mod, dst_node, dest, dest_len, LYS_CONTAINER | LYS_LIST | LYS_LEAF, &dst_node);
             if (rc) {
-                LOGVAL(LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path_key_expr);
+                LOGVAL(ctx, LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path_key_expr);
                 return 0;
             }
 
@@ -3739,7 +3716,7 @@
 
             if ((i = parse_path_key_expr(path_key_expr + pke_parsed, &dest_pref, &dest_pref_len, &dest, &dest_len,
                                          &dest_parent_times)) < 1) {
-                LOGVAL(LYE_INCHAR, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent,
+                LOGVAL(ctx, LYE_INCHAR, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent,
                        (path_key_expr + pke_parsed)[-i], (path_key_expr + pke_parsed)-i);
                 return -parsed;
             }
@@ -3748,8 +3725,8 @@
 
         /* check source - dest match */
         if (dst_node->nodetype != src_node->nodetype) {
-            LOGVAL(LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path - parsed);
-            LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Destination node is not a %s, but a %s.",
+            LOGVAL(ctx, LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path - parsed);
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Destination node is not a %s, but a %s.",
                    strnodetype(src_node->nodetype), strnodetype(dst_node->nodetype));
             return -parsed;
         }
@@ -3770,12 +3747,13 @@
 static int
 resolve_schema_leafref(const char *path, struct lys_node *parent, const struct lys_node **ret)
 {
-    const struct lys_node *node, *op_node = NULL;
+    const struct lys_node *node, *op_node = NULL, *tmp_parent;
     struct lys_node_augment *last_aug;
     const struct lys_module *tmp_mod, *cur_module;
     const char *id, *prefix, *name;
     int pref_len, nam_len, parent_times, has_predicate;
-    int i, first_iter, rc;
+    int i, first_iter;
+    struct ly_ctx *ctx = parent->module->ctx;
 
     first_iter = 1;
     parent_times = 0;
@@ -3789,7 +3767,7 @@
     cur_module = lys_node_module(parent);
     do {
         if ((i = parse_path_arg(cur_module, id, &prefix, &pref_len, &name, &nam_len, &parent_times, &has_predicate)) < 1) {
-            LOGVAL(LYE_INCHAR, LY_VLOG_LYS, parent, id[-i], &id[-i]);
+            LOGVAL(ctx, LYE_INCHAR, LY_VLOG_LYS, parent, id[-i], &id[-i]);
             return -1;
         }
         id += i;
@@ -3797,7 +3775,7 @@
         /* get the current module */
         tmp_mod = prefix ? lyp_get_module(cur_module, NULL, 0, prefix, pref_len, 0) : cur_module;
         if (!tmp_mod) {
-            LOGVAL(LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
+            LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
             return EXIT_FAILURE;
         }
         last_aug = NULL;
@@ -3813,7 +3791,7 @@
                     if (node->parent && (node->parent->nodetype == LYS_AUGMENT)
                             && !((struct lys_node_augment *)node->parent)->target) {
                         /* we are in an unresolved augment, cannot evaluate */
-                        LOGVAL(LYE_SPEC, LY_VLOG_LYS, node->parent,
+                        LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYS, node->parent,
                                "Cannot resolve leafref \"%s\" because it is in an unresolved augment.", path);
                         return EXIT_FAILURE;
                     }
@@ -3831,12 +3809,12 @@
                         }
 
                         /* higher than top-level */
-                        LOGVAL(LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
+                        LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
                         return EXIT_FAILURE;
                     }
                 }
             } else {
-                LOGINT;
+                LOGINT(ctx);
                 return -1;
             }
         }
@@ -3848,13 +3826,23 @@
             last_aug = lys_getnext_target_aug(last_aug, tmp_mod, node);
         }
 
-        rc = lys_getnext_data(tmp_mod, (last_aug ? (struct lys_node *)last_aug : node), name, nam_len, LYS_LIST
-                              | LYS_CONTAINER | LYS_RPC | LYS_ACTION | LYS_NOTIF | LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA, &node);
-        if (rc) {
+        tmp_parent = (last_aug ? (struct lys_node *)last_aug : node);
+        node = NULL;
+        while ((node = lys_getnext(node, tmp_parent, tmp_mod, LYS_GETNEXT_NOSTATECHECK))) {
+            if (lys_node_module(node) != lys_main_module(tmp_mod)) {
+                continue;
+            }
+            if (strncmp(node->name, name, nam_len) || node->name[nam_len]) {
+                continue;
+            }
+            /* match */
+            break;
+        }
+        if (!node) {
             if (last_aug) {
                 goto get_next_augment;
             }
-            LOGVAL(LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
+            LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
             return EXIT_FAILURE;
         }
 
@@ -3870,7 +3858,7 @@
         if (has_predicate) {
             /* we have predicate, so the current result must be list */
             if (node->nodetype != LYS_LIST) {
-                LOGVAL(LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
+                LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
                 return -1;
             }
 
@@ -3887,8 +3875,8 @@
 
     /* the target must be leaf or leaf-list (in YANG 1.1 only) */
     if ((node->nodetype != LYS_LEAF) && (node->nodetype != LYS_LEAFLIST)) {
-        LOGVAL(LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
-        LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Leafref target \"%s\" is not a leaf nor a leaf-list.", path);
+        LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_LYS, parent, "leafref", path);
+        LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Leafref target \"%s\" is not a leaf nor a leaf-list.", path);
         return -1;
     }
 
@@ -3935,7 +3923,7 @@
     if (leaf.value_type == LY_TYPE_LEAFREF) {
         if (!sleaf->type.info.lref.target) {
             /* it should either be unresolved leafref (leaf.value_type are ORed flags) or it will be resolved */
-            LOGINT;
+            LOGINT(node->module->ctx);
             ret = -1;
             goto finish;
         }
@@ -3981,6 +3969,7 @@
     struct lys_node_list *slist = NULL;
     const char *model, *name, *value;
     int mod_len, nam_len, val_len, i, has_predicate, parsed;
+    struct ly_ctx *ctx = prev_mod->ctx;
 
     assert(pred && node && *node);
 
@@ -4000,7 +3989,7 @@
         if (name[0] == '.') {
             /* leaf-list value */
             if ((*node)->schema->nodetype != LYS_LEAFLIST) {
-                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects leaf-list, but have %s \"%s\".",
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects leaf-list, but have %s \"%s\".",
                        strnodetype((*node)->schema->nodetype), (*node)->schema->name);
                 parsed = -1;
                 goto cleanup;
@@ -4017,14 +4006,14 @@
 
             /* keyless list position */
             if ((*node)->schema->nodetype != LYS_LIST) {
-                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects list, but have %s \"%s\".",
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects list, but have %s \"%s\".",
                        strnodetype((*node)->schema->nodetype), (*node)->schema->name);
                 parsed = -1;
                 goto cleanup;
             }
 
             if (((struct lys_node_list *)(*node)->schema)->keys) {
-                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects list without keys, but have list \"%s\".",
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects list without keys, but have list \"%s\".",
                        (*node)->schema->name);
                 parsed = -1;
                 goto cleanup;
@@ -4039,7 +4028,7 @@
         } else {
             /* list key value */
             if ((*node)->schema->nodetype != LYS_LIST) {
-                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects list, but have %s \"%s\".",
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects list, but have %s \"%s\".",
                        strnodetype((*node)->schema->nodetype), (*node)->schema->name);
                 parsed = -1;
                 goto cleanup;
@@ -4049,7 +4038,7 @@
             /* prepare key array */
             if (!list_keys) {
                 list_keys = malloc(slist->keys_size * sizeof *list_keys);
-                LY_CHECK_ERR_RETURN(!list_keys, LOGMEM, -1);
+                LY_CHECK_ERR_RETURN(!list_keys, LOGMEM(ctx), -1);
                 for (i = 0; i < slist->keys_size; ++i) {
                     list_keys[i] = slist->keys[i];
                 }
@@ -4063,7 +4052,7 @@
             }
             if (i == slist->keys_size) {
                 /* this list has no such key */
-                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects list with the key \"%.*s\","
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects list with the key \"%.*s\","
                        " but list \"%s\" does not define it.", nam_len, name, slist->name);
                 parsed = -1;
                 goto cleanup;
@@ -4072,14 +4061,14 @@
             /* check module */
             if (model) {
                 if (strncmp(list_keys[i]->module->name, model, mod_len) || list_keys[i]->module->name[mod_len]) {
-                    LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects key \"%s\" from module \"%.*s\", not \"%s\".",
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects key \"%s\" from module \"%.*s\", not \"%s\".",
                            list_keys[i]->name, model, mod_len, list_keys[i]->module->name);
                     parsed = -1;
                     goto cleanup;
                 }
             } else {
                 if (list_keys[i]->module != prev_mod) {
-                    LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects key \"%s\" from module \"%s\", not \"%s\".",
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier expects key \"%s\" from module \"%s\", not \"%s\".",
                            list_keys[i]->name, prev_mod->name, list_keys[i]->module->name);
                     parsed = -1;
                     goto cleanup;
@@ -4094,7 +4083,7 @@
             }
             if (!key) {
                 /* list instance is missing a key? definitely should not happen */
-                LOGINT;
+                LOGINT(ctx);
                 parsed = -1;
                 goto cleanup;
             }
@@ -4115,7 +4104,7 @@
     if (*node && list_keys) {
         for (i = 0; i < slist->keys_size; ++i) {
             if (list_keys[i]) {
-                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier is missing list key \"%s\".", list_keys[i]->name);
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Instance identifier is missing list key \"%s\".", list_keys[i]->name);
                 parsed = -1;
                 goto cleanup;
             }
@@ -4171,7 +4160,7 @@
     if (type->base == LY_TYPE_LEAFREF) {
         if ((leaf->flags & LYS_CONFIG_W) && type->info.lref.target && type->info.lref.req != -1 &&
                 (type->info.lref.target->flags & LYS_CONFIG_R)) {
-            LOGVAL(LYE_SPEC, LY_VLOG_LYS, leaf, "The leafref %s is config but refers to a non-config %s.",
+            LOGVAL(leaf->module->ctx, LYE_SPEC, LY_VLOG_LYS, leaf, "The leafref %s is config but refers to a non-config %s.",
                    strnodetype(leaf->nodetype), strnodetype(type->info.lref.target->nodetype));
             return -1;
         }
@@ -4202,8 +4191,15 @@
 inherit_config_flag(struct lys_node *node, int flags, int clear)
 {
     struct lys_node_leaf *leaf;
+    struct ly_ctx *ctx;
+
+    if (!node) {
+        return 0;
+    }
 
     assert(!(flags ^ (flags & LYS_CONFIG_MASK)));
+    ctx = node->module->ctx;
+
     LY_TREE_FOR(node, node) {
         if (clear) {
             node->flags &= ~LYS_CONFIG_MASK;
@@ -4212,8 +4208,8 @@
             if (node->flags & LYS_CONFIG_SET) {
                 /* skip nodes with an explicit config value */
                 if ((flags & LYS_CONFIG_R) && (node->flags & LYS_CONFIG_W)) {
-                    LOGVAL(LYE_INARG, LY_VLOG_LYS, node, "true", "config");
-                    LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "State nodes cannot have configuration nodes as children.");
+                    LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, node, "true", "config");
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "State nodes cannot have configuration nodes as children.");
                     return -1;
                 }
                 continue;
@@ -4224,7 +4220,7 @@
                 /* check that configuration lists have keys */
                 if ((node->nodetype == LYS_LIST) && (node->flags & LYS_CONFIG_W)
                         && !((struct lys_node_list *)node)->keys_size) {
-                    LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_LYS, node, "key", "list");
+                    LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, node, "key", "list");
                     return -1;
                 }
             }
@@ -4260,9 +4256,11 @@
     struct lys_node *sub;
     struct lys_module *mod;
     struct ly_set *set;
+    struct ly_ctx *ctx;
 
     assert(aug);
     mod = lys_main_module(aug->module);
+    ctx = mod->ctx;
 
     /* set it as not applied for now */
     aug->flags |= LYS_NOTAPPLIED;
@@ -4272,11 +4270,11 @@
         /* resolve target node */
         rc = resolve_schema_nodeid(aug->target_name, uses, (uses ? NULL : lys_node_module((struct lys_node *)aug)), &set, 0, 0);
         if (rc == -1) {
-            LOGVAL(LYE_PATH, LY_VLOG_LYS, aug);
+            LOGVAL(ctx, LYE_PATH, LY_VLOG_LYS, aug);
             return -1;
         }
         if (!set) {
-            LOGVAL(LYE_INRESOLV, LY_VLOG_LYS, aug, "augment", aug->target_name);
+            LOGVAL(ctx, LYE_INRESOLV, LY_VLOG_LYS, aug, "augment", aug->target_name);
             return EXIT_FAILURE;
         }
         aug->target = set->set.s[0];
@@ -4296,8 +4294,8 @@
         LY_TREE_FOR(aug->child, sub) {
             if (!(sub->nodetype & (LYS_ANYDATA | LYS_CONTAINER | LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_USES
                                    | LYS_CHOICE | LYS_ACTION | LYS_NOTIF))) {
-                LOGVAL(LYE_INCHILDSTMT, LY_VLOG_LYS, aug, strnodetype(sub->nodetype), "augment");
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Cannot augment \"%s\" with a \"%s\".",
+                LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, aug, strnodetype(sub->nodetype), "augment");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Cannot augment \"%s\" with a \"%s\".",
                        strnodetype(aug->target->nodetype), strnodetype(sub->nodetype));
                 return -1;
             }
@@ -4305,8 +4303,8 @@
     } else if (aug->target->nodetype & (LYS_CASE | LYS_INPUT | LYS_OUTPUT | LYS_NOTIF)) {
         LY_TREE_FOR(aug->child, sub) {
             if (!(sub->nodetype & (LYS_ANYDATA | LYS_CONTAINER | LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_USES | LYS_CHOICE))) {
-                LOGVAL(LYE_INCHILDSTMT, LY_VLOG_LYS, aug, strnodetype(sub->nodetype), "augment");
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Cannot augment \"%s\" with a \"%s\".",
+                LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, aug, strnodetype(sub->nodetype), "augment");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Cannot augment \"%s\" with a \"%s\".",
                        strnodetype(aug->target->nodetype), strnodetype(sub->nodetype));
                 return -1;
             }
@@ -4314,15 +4312,15 @@
     } else if (aug->target->nodetype == LYS_CHOICE) {
         LY_TREE_FOR(aug->child, sub) {
             if (!(sub->nodetype & (LYS_CASE | LYS_ANYDATA | LYS_CONTAINER | LYS_LEAF | LYS_LIST | LYS_LEAFLIST))) {
-                LOGVAL(LYE_INCHILDSTMT, LY_VLOG_LYS, aug, strnodetype(sub->nodetype), "augment");
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Cannot augment \"%s\" with a \"%s\".",
+                LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, aug, strnodetype(sub->nodetype), "augment");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Cannot augment \"%s\" with a \"%s\".",
                        strnodetype(aug->target->nodetype), strnodetype(sub->nodetype));
                 return -1;
             }
         }
     } else {
-        LOGVAL(LYE_INARG, LY_VLOG_LYS, aug, aug->target_name, "target-node");
-        LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Invalid augment target node type \"%s\".", strnodetype(aug->target->nodetype));
+        LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, aug, aug->target_name, "target-node");
+        LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Invalid augment target node type \"%s\".", strnodetype(aug->target->nodetype));
         return -1;
     }
 
@@ -4335,7 +4333,7 @@
 
     if (!aug->child) {
         /* empty augment, nothing to connect, but it is techincally applied */
-        LOGWRN("Augment \"%s\" without children.", aug->target_name);
+        LOGWRN(ctx, "Augment \"%s\" without children.", aug->target_name);
         aug->flags &= ~LYS_NOTAPPLIED;
     } else if ((aug->parent || mod->implemented) && apply_aug(aug, unres)) {
         /* we try to connect the augment only in case the module is implemented or
@@ -4357,6 +4355,7 @@
     struct lyxml_elem *next_yin, *yin;
     const struct lys_module *mod;
     struct lys_ext_instance *tmp_ext;
+    struct ly_ctx *ctx = NULL;
     LYEXT_TYPE etype;
 
     switch (info->parent_type) {
@@ -4382,9 +4381,10 @@
         /* get the module where the extension is supposed to be defined */
         mod = lyp_get_import_module_ns(info->mod, info->data.yin->ns->value);
         if (!mod) {
-            LOGVAL(LYE_INSTMT, vlog_type, vlog_node, info->data.yin->name);
+            LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, info->data.yin->name);
             return EXIT_FAILURE;
         }
+        ctx = mod->ctx;
 
         /* find the extension definition */
         e = NULL;
@@ -4404,7 +4404,7 @@
             }
         }
         if (!e) {
-            LOGVAL(LYE_INSTMT, vlog_type, vlog_node, info->data.yin->name);
+            LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, info->data.yin->name);
             return EXIT_FAILURE;
         }
 
@@ -4414,7 +4414,7 @@
             /* common part - we have plugin with position checking function, use it first */
             if ((*e->plugin->check_position)(info->parent, info->parent_type, info->substmt)) {
                 /* extension is not allowed here */
-                LOGVAL(LYE_INSTMT, vlog_type, vlog_node, e->name);
+                LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, e->name);
                 return -1;
             }
         }
@@ -4435,10 +4435,10 @@
             break;
         case LYEXT_ERR:
             /* we never should be here */
-            LOGINT;
+            LOGINT(ctx);
             return -1;
         }
-        LY_CHECK_ERR_RETURN(!*ext, LOGMEM, -1);
+        LY_CHECK_ERR_RETURN(!*ext, LOGMEM(ctx), -1);
 
         /* common part for all extension types */
         (*ext)->def = e;
@@ -4453,7 +4453,7 @@
             if (!(e->flags & LYS_YINELEM)) {
                 (*ext)->arg_value = lyxml_get_attr(info->data.yin, e->argument, NULL);
                 if (!(*ext)->arg_value) {
-                    LOGVAL(LYE_MISSARG, LY_VLOG_NONE, NULL, e->argument, info->data.yin->name);
+                    LOGVAL(ctx, LYE_MISSARG, LY_VLOG_NONE, NULL, e->argument, info->data.yin->name);
                     return -1;
                 }
 
@@ -4487,13 +4487,13 @@
                     continue;
                 } else if (!strcmp(yin->ns->value, LY_NSYIN)) {
                     /* standard YANG statements are not expected here */
-                    LOGVAL(LYE_INCHILDSTMT, vlog_type, vlog_node, yin->name, info->data.yin->name);
+                    LOGVAL(ctx, LYE_INCHILDSTMT, vlog_type, vlog_node, yin->name, info->data.yin->name);
                     return -1;
                 } else if (yin->ns == info->data.yin->ns &&
                         (e->flags & LYS_YINELEM) && ly_strequal(yin->name, e->argument, 1)) {
                     /* we have the extension's argument */
                     if ((*ext)->arg_value) {
-                        LOGVAL(LYE_TOOMANY, vlog_type, vlog_node, yin->name, info->data.yin->name);
+                        LOGVAL(ctx, LYE_TOOMANY, vlog_type, vlog_node, yin->name, info->data.yin->name);
                         return -1;
                     }
                     (*ext)->arg_value = yin->content;
@@ -4529,7 +4529,7 @@
         ext_prefix = (char *)(*ext)->def;
         tmp = strchr(ext_prefix, ':');
         if (!tmp) {
-            LOGVAL(LYE_INSTMT, vlog_type, vlog_node, ext_prefix);
+            LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, ext_prefix);
             goto error;
         }
         ext_name = tmp + 1;
@@ -4537,9 +4537,10 @@
         /* get the module where the extension is supposed to be defined */
         mod = lyp_get_module(info->mod, ext_prefix, tmp - ext_prefix, NULL, 0, 0);
         if (!mod) {
-            LOGVAL(LYE_INSTMT, vlog_type, vlog_node, ext_prefix);
+            LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, ext_prefix);
             return EXIT_FAILURE;
         }
+        ctx = mod->ctx;
 
         /* find the extension definition */
         e = NULL;
@@ -4559,7 +4560,7 @@
             }
         }
         if (!e) {
-            LOGVAL(LYE_INSTMT, vlog_type, vlog_node, ext_prefix);
+            LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, ext_prefix);
             return EXIT_FAILURE;
         }
 
@@ -4572,7 +4573,7 @@
             /* common part - we have plugin with position checking function, use it first */
             if ((*e->plugin->check_position)(info->parent, info->parent_type, info->substmt)) {
                 /* extension is not allowed here */
-                LOGVAL(LYE_INSTMT, vlog_type, vlog_node, e->name);
+                LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, e->name);
                 goto error;
             }
         }
@@ -4584,7 +4585,7 @@
         (*ext)->flags |= e->plugin ? e->plugin->flags : 0;
 
         if (e->argument && !(*ext)->arg_value) {
-            LOGVAL(LYE_MISSARG, LY_VLOG_NONE, NULL, e->argument, ext_name);
+            LOGVAL(ctx, LYE_MISSARG, LY_VLOG_NONE, NULL, e->argument, ext_name);
             goto error;
         }
 
@@ -4609,7 +4610,7 @@
             break;
         case LYEXT_COMPLEX:
             tmp_ext = realloc(*ext, ((struct lyext_plugin_complex*)e->plugin)->instance_size);
-            LY_CHECK_ERR_GOTO(!tmp_ext, LOGMEM, error);
+            LY_CHECK_ERR_GOTO(!tmp_ext, LOGMEM(ctx), error);
             memset((char *)tmp_ext + sizeof **ext, 0, ((struct lyext_plugin_complex*)e->plugin)->instance_size - sizeof **ext);
             (*ext) = tmp_ext;
             ((struct lys_ext_instance_complex*)(*ext))->substmt = ((struct lyext_plugin_complex*)e->plugin)->substmt;
@@ -4630,7 +4631,7 @@
             break;
         case LYEXT_ERR:
             /* we never should be here */
-            LOGINT;
+            LOGINT(ctx);
             goto error;
         }
 
@@ -4717,8 +4718,8 @@
         }
         node = lys_node_dup(uses->module, (struct lys_node *)uses, node_aux, unres, 0);
         if (!node) {
-            LOGVAL(LYE_INARG, LY_VLOG_LYS, uses, uses->grp->name, "uses");
-            LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Copying data from grouping failed.");
+            LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, uses, uses->grp->name, "uses");
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Copying data from grouping failed.");
             goto fail;
         }
         /* test the name of siblings */
@@ -4733,7 +4734,7 @@
 
     if (uses->refine_size) {
         refine_nodes = malloc(uses->refine_size * sizeof *refine_nodes);
-        LY_CHECK_ERR_GOTO(!refine_nodes, LOGMEM, fail);
+        LY_CHECK_ERR_GOTO(!refine_nodes, LOGMEM(ctx), fail);
     }
 
     /* apply refines */
@@ -4743,13 +4744,13 @@
                                               LYS_NO_RPC_NOTIF_NODE | LYS_ACTION | LYS_NOTIF,
                                               0, (const struct lys_node **)&node);
         if (rc || !node) {
-            LOGVAL(LYE_INARG, LY_VLOG_LYS, uses, rfn->target_name, "refine");
+            LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, uses, rfn->target_name, "refine");
             goto fail;
         }
 
         if (rfn->target_type && !(node->nodetype & rfn->target_type)) {
-            LOGVAL(LYE_INARG, LY_VLOG_LYS, uses, rfn->target_name, "refine");
-            LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Refine substatements not applicable to the target-node.");
+            LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, uses, rfn->target_name, "refine");
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Refine substatements not applicable to the target-node.");
             goto fail;
         }
         refine_nodes[i] = node;
@@ -4800,7 +4801,7 @@
 
                 /* copy the default set from refine */
                 llist->dflt = malloc(rfn->dflt_size * sizeof *llist->dflt);
-                LY_CHECK_ERR_GOTO(!llist->dflt, LOGMEM, fail);
+                LY_CHECK_ERR_GOTO(!llist->dflt, LOGMEM(ctx), fail);
                 llist->dflt_size = rfn->dflt_size;
                 for (j = 0; j < llist->dflt_size; j++) {
                     llist->dflt[j] = lydict_insert(ctx, rfn->dflt[j], 0);
@@ -4827,12 +4828,12 @@
             if (rfn->flags & LYS_MAND_TRUE) {
                 /* check if node has default value */
                 if ((node->nodetype & LYS_LEAF) && ((struct lys_node_leaf *)node)->dflt) {
-                    LOGVAL(LYE_SPEC, LY_VLOG_LYS, uses,
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYS, uses,
                            "The \"mandatory\" statement is forbidden on leaf with \"default\".");
                     goto fail;
                 }
                 if ((node->nodetype & LYS_CHOICE) && ((struct lys_node_choice *)node)->dflt) {
-                    LOGVAL(LYE_SPEC, LY_VLOG_LYS, uses,
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYS, uses,
                            "The \"mandatory\" statement is forbidden on choices with \"default\".");
                     goto fail;
                 }
@@ -4887,16 +4888,16 @@
                 old_must = &((struct lys_node_anydata *)node)->must;
                 break;
             default:
-                LOGINT;
+                LOGINT(ctx);
                 goto fail;
             }
 
             size = *old_size + rfn->must_size;
             must = realloc(*old_must, size * sizeof *rfn->must);
-            LY_CHECK_ERR_GOTO(!must, LOGMEM, fail);
+            LY_CHECK_ERR_GOTO(!must, LOGMEM(ctx), fail);
             for (k = 0, j = *old_size; k < rfn->must_size; k++, j++) {
                 must[j].ext_size = rfn->must[k].ext_size;
-                lys_ext_dup(rfn->module, rfn->must[k].ext, rfn->must[k].ext_size, &rfn->must[k], LYEXT_PAR_RESTR,
+                lys_ext_dup(ctx, rfn->module, rfn->must[k].ext, rfn->must[k].ext_size, &rfn->must[k], LYEXT_PAR_RESTR,
                             &must[j].ext, 0, unres);
                 must[j].expr = lydict_insert(ctx, rfn->must[k].expr, 0);
                 must[j].dsc = lydict_insert(ctx, rfn->must[k].dsc, 0);
@@ -4922,7 +4923,7 @@
 
             size = *old_size + rfn->iffeature_size;
             iff = realloc(*old_iff, size * sizeof *rfn->iffeature);
-            LY_CHECK_ERR_GOTO(!iff, LOGMEM, fail);
+            LY_CHECK_ERR_GOTO(!iff, LOGMEM(ctx), fail);
             *old_iff = iff;
 
             for (k = 0, j = *old_size; k < rfn->iffeature_size; k++, j++) {
@@ -4932,17 +4933,17 @@
                     /* duplicate compiled expression */
                     usize = (usize1 / 4) + (usize1 % 4) ? 1 : 0;
                     iff[j].expr = malloc(usize * sizeof *iff[j].expr);
-                    LY_CHECK_ERR_GOTO(!iff[j].expr, LOGMEM, fail);
+                    LY_CHECK_ERR_GOTO(!iff[j].expr, LOGMEM(ctx), fail);
                     memcpy(iff[j].expr, rfn->iffeature[k].expr, usize * sizeof *iff[j].expr);
 
                     /* duplicate list of feature pointers */
                     iff[j].features = malloc(usize2 * sizeof *iff[k].features);
-                    LY_CHECK_ERR_GOTO(!iff[j].expr, LOGMEM, fail);
+                    LY_CHECK_ERR_GOTO(!iff[j].expr, LOGMEM(ctx), fail);
                     memcpy(iff[j].features, rfn->iffeature[k].features, usize2 * sizeof *iff[j].features);
 
                     /* duplicate extensions */
                     iff[j].ext_size = rfn->iffeature[k].ext_size;
-                    lys_ext_dup(rfn->module, rfn->iffeature[k].ext, rfn->iffeature[k].ext_size,
+                    lys_ext_dup(ctx, rfn->module, rfn->iffeature[k].ext, rfn->iffeature[k].ext_size,
                                 &rfn->iffeature[k], LYEXT_PAR_IFFEATURE, &iff[j].ext, 0, unres);
                 }
                 (*old_size)++;
@@ -4971,8 +4972,8 @@
                     ((parent->flags & LYS_CONFIG_MASK) != (rfn->flags & LYS_CONFIG_MASK)) &&
                     (rfn->flags & LYS_CONFIG_W)) {
                 /* setting config true under config false is prohibited */
-                LOGVAL(LYE_INARG, LY_VLOG_LYS, uses, "config", "refine");
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL,
+                LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, uses, "config", "refine");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL,
                        "changing config from 'false' to 'true' is prohibited while "
                        "the target's parent is still config 'false'.");
                 goto fail;
@@ -4989,8 +4990,8 @@
                 } else { /* LYS_CONFIG_R */
                     if ((iter->flags & LYS_CONFIG_SET) && (iter->flags & LYS_CONFIG_W)) {
                         /* error - we would have config data under status data */
-                        LOGVAL(LYE_INARG, LY_VLOG_LYS, uses, "config", "refine");
-                        LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL,
+                        LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, uses, "config", "refine");
+                        LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL,
                                "changing config from 'true' to 'false' is prohibited while the target "
                                "has still a children with explicit config 'true'.");
                         goto fail;
@@ -5032,7 +5033,7 @@
                 ((struct lys_node_choice *)node)->dflt = resolve_choice_dflt((struct lys_node_choice *)node,
                                                                              rfn->dflt[0]);
                 if (!((struct lys_node_choice *)node)->dflt) {
-                    LOGVAL(LYE_INARG, LY_VLOG_LYS, uses, rfn->dflt[0], "default");
+                    LOGVAL(ctx, LYE_INARG, LY_VLOG_LYS, uses, rfn->dflt[0], "default");
                     goto fail;
                 }
                 if (lyp_check_mandatory_choice(node)) {
@@ -5044,14 +5045,14 @@
         /* min/max-elements on list or leaf-list */
         if (node->nodetype == LYS_LIST && ((struct lys_node_list *)node)->max) {
             if (((struct lys_node_list *)node)->min > ((struct lys_node_list *)node)->max) {
-                LOGVAL(LYE_SPEC, LY_VLOG_LYS, uses, "Invalid value \"%d\" of \"%s\".", rfn->mod.list.min, "min-elements");
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "\"min-elements\" is bigger than \"max-elements\".");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYS, uses, "Invalid value \"%d\" of \"%s\".", rfn->mod.list.min, "min-elements");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "\"min-elements\" is bigger than \"max-elements\".");
                 goto fail;
             }
         } else if (node->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)node)->max) {
             if (((struct lys_node_leaflist *)node)->min > ((struct lys_node_leaflist *)node)->max) {
-                LOGVAL(LYE_SPEC, LY_VLOG_LYS, uses, "Invalid value \"%d\" of \"%s\".", rfn->mod.list.min, "min-elements");
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "\"min-elements\" is bigger than \"max-elements\".");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYS, uses, "Invalid value \"%d\" of \"%s\".", rfn->mod.list.min, "min-elements");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "\"min-elements\" is bigger than \"max-elements\".");
                 goto fail;
             }
         }
@@ -5061,16 +5062,16 @@
         if (node->nodetype == LYS_LEAFLIST) {
             llist = (struct lys_node_leaflist *)node;
             if (llist->dflt_size && llist->min) {
-                LOGVAL(LYE_INCHILDSTMT, LY_VLOG_LYS, uses, rfn->dflt_size ? "default" : "min-elements", "refine");
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL,
+                LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, uses, rfn->dflt_size ? "default" : "min-elements", "refine");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL,
                        "The \"min-elements\" statement with non-zero value is forbidden on leaf-lists with the \"default\" statement.");
                 goto fail;
             }
         } else if (node->nodetype == LYS_LEAF) {
             leaf = (struct lys_node_leaf *)node;
             if (leaf->dflt && (leaf->flags & LYS_MAND_TRUE)) {
-                LOGVAL(LYE_INCHILDSTMT, LY_VLOG_LYS, uses, rfn->dflt_size ? "default" : "mandatory", "refine");
-                LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL,
+                LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, uses, rfn->dflt_size ? "default" : "mandatory", "refine");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL,
                        "The \"mandatory\" statement is forbidden on leafs with the \"default\" statement.");
                 goto fail;
             }
@@ -5142,6 +5143,7 @@
 {
     uint32_t i, j;
     struct lys_ident *base = NULL;
+    struct ly_ctx *ctx = module->ctx;
 
     assert(ret);
 
@@ -5189,8 +5191,8 @@
                  * the complete check is done as a side effect of using only completely
                  * resolved identities (previous check of unres content) */
                 if (ly_strequal((const char *)unres->str_snode[i], ident->name, 1)) {
-                    LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, basename, "base");
-                    LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Circular reference of \"%s\" identity.", basename);
+                    LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, basename, "base");
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Circular reference of \"%s\" identity.", basename);
                     return -1;
                 }
 
@@ -5227,6 +5229,7 @@
     struct lys_ident *target, **ret;
     uint16_t flags;
     struct lys_module *mod;
+    struct ly_ctx *ctx = module->ctx;
 
     assert((ident && !type) || (!ident && type));
 
@@ -5239,7 +5242,7 @@
         /* have type to fill */
         ++type->info.ident.count;
         type->info.ident.ref = ly_realloc(type->info.ident.ref, type->info.ident.count * sizeof *type->info.ident.ref);
-        LY_CHECK_ERR_RETURN(!type->info.ident.ref, LOGMEM, -1);
+        LY_CHECK_ERR_RETURN(!type->info.ident.ref, LOGMEM(ctx), -1);
 
         ret = &type->info.ident.ref[type->info.ident.count - 1];
         flags = type->parent->flags;
@@ -5266,7 +5269,7 @@
     module = lyp_get_module(module, NULL, 0, mod_name_len ? basename : NULL, mod_name_len, 0);
     if (!module) {
         /* identity refers unknown data model */
-        LOGVAL(LYE_INMOD, LY_VLOG_NONE, NULL, basename);
+        LOGVAL(ctx, LYE_INMOD, LY_VLOG_NONE, NULL, basename);
         return -1;
     }
 
@@ -5290,7 +5293,7 @@
             }
         }
     } else if (rc == EXIT_FAILURE) {
-        LOGVAL(LYE_INRESOLV, LY_VLOG_NONE, NULL, parent, basename);
+        LOGVAL(ctx, LYE_INRESOLV, LY_VLOG_NONE, NULL, parent, basename);
         if (type) {
             --type->info.ident.count;
         }
@@ -5341,8 +5344,10 @@
     unsigned int i, j;
     struct lys_ident *der, *cur;
     struct lys_module *imod = NULL, *m;
+    struct ly_ctx *ctx;
 
     assert(type && ident_name && node && mod);
+    ctx = mod->ctx;
 
     if (!type || (!type->info.ident.count && !type->der) || !ident_name) {
         return NULL;
@@ -5350,10 +5355,10 @@
 
     rc = parse_node_identifier(ident_name, &mod_name, &mod_name_len, &name, &nam_len, NULL, 0);
     if (rc < 1) {
-        LOGVAL(LYE_INCHAR, LY_VLOG_LYD, node, ident_name[-rc], &ident_name[-rc]);
+        LOGVAL(ctx, LYE_INCHAR, LY_VLOG_LYD, node, ident_name[-rc], &ident_name[-rc]);
         return NULL;
     } else if (rc < (signed)strlen(ident_name)) {
-        LOGVAL(LYE_INCHAR, LY_VLOG_LYD, node, ident_name[rc], &ident_name[rc]);
+        LOGVAL(ctx, LYE_INCHAR, LY_VLOG_LYD, node, ident_name[rc], &ident_name[rc]);
         return NULL;
     }
 
@@ -5396,13 +5401,13 @@
         }
     }
 
-    if (!dflt && (!imod || !imod->implemented) && mod->ctx->data_clb) {
+    if (!dflt && (!imod || !imod->implemented) && ctx->data_clb) {
         /* the needed module was not found, but it may have been expected so call the data callback */
         if (imod) {
-            mod->ctx->data_clb(mod->ctx, imod->name, imod->ns, LY_MODCLB_NOT_IMPLEMENTED, mod->ctx->data_clb_data);
+            ctx->data_clb(ctx, imod->name, imod->ns, LY_MODCLB_NOT_IMPLEMENTED, ctx->data_clb_data);
         } else if (mod_name) {
             str = strndup(mod_name, mod_name_len);
-            imod = (struct lys_module *)mod->ctx->data_clb(mod->ctx, str, NULL, 0, mod->ctx->data_clb_data);
+            imod = (struct lys_module *)ctx->data_clb(ctx, str, NULL, 0, ctx->data_clb_data);
             free(str);
         }
     }
@@ -5450,7 +5455,7 @@
                 type = &type->der->type;
             }
             /* matching base not found */
-            LOGVAL(LYE_SPEC, LY_VLOG_LYD, node, "Identity used as identityref value is not implemented.");
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYD, node, "Identity used as identityref value is not implemented.");
             goto fail;
         }
     }
@@ -5476,14 +5481,14 @@
     }
 
 fail:
-    LOGVAL(LYE_INRESOLV, LY_VLOG_LYD, node, "identityref", ident_name);
+    LOGVAL(ctx, LYE_INRESOLV, LY_VLOG_LYD, node, "identityref", ident_name);
     return NULL;
 
 match:
     for (i = 0; i < cur->iffeature_size; i++) {
         if (!resolve_iffeature(&cur->iffeature[i])) {
-            LOGVAL(LYE_INVAL, LY_VLOG_LYD, node, cur->name, node->schema->name);
-            LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Identity \"%s\" is disabled by its if-feature condition.", cur->name);
+            LOGVAL(ctx, LYE_INVAL, LY_VLOG_LYD, node, cur->name, node->schema->name);
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Identity \"%s\" is disabled by its if-feature condition.", cur->name);
             return NULL;
         }
     }
@@ -5493,14 +5498,14 @@
             LOGVRB("Making \"%s\" module implemented because of identityref default value \"%s\" used in the implemented \"%s\" module",
                    imod->name, cur->name, mod->name);
             if (lys_set_implemented(imod)) {
-                LOGERR(ly_errno, "Setting the module \"%s\" implemented because of used default identity \"%s\" failed.",
+                LOGERR(ctx, ly_errno, "Setting the module \"%s\" implemented because of used default identity \"%s\" failed.",
                        imod->name, cur->name);
-                LOGVAL(LYE_SPEC, LY_VLOG_LYD, node, "Identity used as identityref value is not implemented.");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYD, node, "Identity used as identityref value is not implemented.");
                 goto fail;
             }
         } else {
             /* just say that it was found, but in a non-implemented module */
-            LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Identity found, but in a non-implemented module \"%s\".",
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Identity found, but in a non-implemented module \"%s\".",
                    lys_main_module(cur->module)->name);
             goto fail;
         }
@@ -5521,6 +5526,7 @@
 {
     int rc;
     struct lys_node *par_grp;
+    struct ly_ctx *ctx = uses->module->ctx;
 
     /* HACK: when a grouping has uses inside, all such uses have to be resolved before the grouping itself is used
      *       in some uses. When we see such a uses, the grouping's unres counter is used to store number of so far
@@ -5531,20 +5537,20 @@
     if (!uses->grp) {
         rc = resolve_uses_schema_nodeid(uses->name, (const struct lys_node *)uses, (const struct lys_node_grp **)&uses->grp);
         if (rc == -1) {
-            LOGVAL(LYE_INRESOLV, LY_VLOG_LYS, uses, "uses", uses->name);
+            LOGVAL(ctx, LYE_INRESOLV, LY_VLOG_LYS, uses, "uses", uses->name);
             return -1;
         } else if (rc > 0) {
-            LOGVAL(LYE_INCHAR, LY_VLOG_LYS, uses, uses->name[rc - 1], &uses->name[rc - 1]);
+            LOGVAL(ctx, LYE_INCHAR, LY_VLOG_LYS, uses, uses->name[rc - 1], &uses->name[rc - 1]);
             return -1;
         } else if (!uses->grp) {
             if (par_grp && !(uses->flags & LYS_USESGRP)) {
                 if (++((struct lys_node_grp *)par_grp)->unres_count == 0) {
-                    LOGERR(LY_EINT, "Too many unresolved items (uses) inside a grouping.");
+                    LOGERR(ctx, LY_EINT, "Too many unresolved items (uses) inside a grouping.");
                     return -1;
                 }
                 uses->flags |= LYS_USESGRP;
             }
-            LOGVAL(LYE_INRESOLV, LY_VLOG_LYS, uses, "uses", uses->name);
+            LOGVAL(ctx, LYE_INRESOLV, LY_VLOG_LYS, uses, "uses", uses->name);
             return EXIT_FAILURE;
         }
     }
@@ -5552,7 +5558,7 @@
     if (uses->grp->unres_count) {
         if (par_grp && !(uses->flags & LYS_USESGRP)) {
             if (++((struct lys_node_grp *)par_grp)->unres_count == 0) {
-                LOGERR(LY_EINT, "Too many unresolved items (uses) inside a grouping.");
+                LOGERR(ctx, LY_EINT, "Too many unresolved items (uses) inside a grouping.");
                 return -1;
             }
             uses->flags |= LYS_USESGRP;
@@ -5599,13 +5605,14 @@
     int i, len, rc;
     const char *value;
     char *s = NULL;
+    struct ly_ctx *ctx = list->module->ctx;
 
     for (i = 0; i < list->keys_size; ++i) {
         assert(keys_str);
 
         if (!list->child) {
             /* no child, possible forward reference */
-            LOGVAL(LYE_INRESOLV, LY_VLOG_LYS, list, "list keys", keys_str);
+            LOGVAL(ctx, LYE_INRESOLV, LY_VLOG_LYS, list, "list keys", keys_str);
             return EXIT_FAILURE;
         }
         /* get the key name */
@@ -5626,7 +5633,7 @@
         rc = lys_getnext_data(lys_node_module((struct lys_node *)list), (struct lys_node *)list, keys_str, len, LYS_LEAF,
                               (const struct lys_node **)&list->keys[i]);
         if (rc) {
-            LOGVAL(LYE_INRESOLV, LY_VLOG_LYS, list, "list key", keys_str);
+            LOGVAL(ctx, LYE_INRESOLV, LY_VLOG_LYS, list, "list key", keys_str);
             return EXIT_FAILURE;
         }
 
@@ -5647,11 +5654,11 @@
             /* log is not hidden only in case this resolving fails and in such a case
              * we cannot get here
              */
-            assert(ly_err_main.vlog_hide);
-            ly_vlog_hide(0);
-            LOGWRN("Default value \"%s\" in the list key \"%s\" is ignored. (%s)", list->keys[i]->dflt,
+            assert(log_opt == ILO_STORE);
+            log_opt = ILO_LOG;
+            LOGWRN(ctx, "Default value \"%s\" in the list key \"%s\" is ignored. (%s)", list->keys[i]->dflt,
                    list->keys[i]->name, s = lys_path((struct lys_node*)list, LYS_PATH_FIRST_PREFIX));
-            ly_vlog_hide(1);
+            log_opt = ILO_STORE;
             free(s);
         }
 
@@ -5682,6 +5689,7 @@
     struct lys_node *schema;
     struct lys_restr *must;
     struct lyxp_set set;
+    struct ly_ctx *ctx = node->schema->module->ctx;
 
     assert(node);
     memset(&set, 0, sizeof set);
@@ -5691,7 +5699,7 @@
              schema && (schema->nodetype & (LYS_CHOICE | LYS_CASE | LYS_USES));
              schema = lys_parent(schema));
         if (!schema || !(schema->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
-            LOGINT;
+            LOGINT(ctx);
             return -1;
         }
         must_size = ((struct lys_node_inout *)schema)->must_size;
@@ -5700,7 +5708,7 @@
         /* context node is the RPC/action */
         node = node->parent;
         if (!(node->schema->nodetype & (LYS_RPC | LYS_ACTION))) {
-            LOGINT;
+            LOGINT(ctx);
             return -1;
         }
     } else {
@@ -5747,12 +5755,12 @@
             if ((ignore_fail == 1) || ((must[i].flags & LYS_XPATH_DEP) && (ignore_fail == 2))) {
                 LOGVRB("Must condition \"%s\" not satisfied, but it is not required.", must[i].expr);
             } else {
-                LOGVAL(LYE_NOMUST, LY_VLOG_LYD, node, must[i].expr);
+                LOGVAL(ctx, LYE_NOMUST, LY_VLOG_LYD, node, must[i].expr);
                 if (must[i].emsg) {
-                    LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, must[i].emsg);
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, must[i].emsg);
                 }
                 if (must[i].eapptag) {
-                    strncpy(((struct ly_err *)&ly_errno)->apptag, must[i].eapptag, LY_APPTAG_LEN - 1);
+                    ly_err_last_set_apptag(ctx, must[i].eapptag);
                 }
                 return 1;
             }
@@ -5790,7 +5798,7 @@
                 *ctx_snode_type = LYXP_NODE_ROOT;
             }
             /* we need the first top-level sibling, but no uses or groupings */
-            schema = lys_getnext(NULL, NULL, lys_node_module(schema), 0);
+            schema = lys_getnext(NULL, NULL, lys_node_module(schema), LYS_GETNEXT_NOSTATECHECK);
             break;
         }
         schema = sparent;
@@ -5876,6 +5884,7 @@
 {
     struct lyd_node *next, *elem;
     const struct lys_node *slast;
+    struct ly_ctx *ctx = snode->module->ctx;
 
     switch (snode->nodetype) {
     case LYS_AUGMENT:
@@ -5911,7 +5920,7 @@
                      * lyxp_eval() can handle this special situation.
                      */
                     if (ctx_node_type == LYXP_NODE_ELEM) {
-                        LOGINT;
+                        LOGINT(ctx);
                         return -1;
                     }
 
@@ -5939,7 +5948,7 @@
                 lyd_unlink_internal(elem, 0);
                 if (*unlinked_nodes) {
                     if (lyd_insert_after((*unlinked_nodes)->prev, elem)) {
-                        LOGINT;
+                        LOGINT(ctx);
                         return -1;
                     }
                 } else {
@@ -5954,7 +5963,7 @@
         }
         break;
     default:
-        LOGINT;
+        LOGINT(ctx);
         return -1;
     }
 
@@ -6109,6 +6118,7 @@
     struct lys_node *sparent;
     struct lyxp_set set;
     enum lyxp_node_type ctx_node_type;
+    struct ly_ctx *ctx = node->schema->module->ctx;
     int rc = 0;
 
     assert(node);
@@ -6122,7 +6132,7 @@
         node->validity &= ~LYD_VAL_INUSE;
         if (rc) {
             if (rc == 1) {
-                LOGVAL(LYE_INWHEN, LY_VLOG_LYD, node, ((struct lys_node_container *)node->schema)->when->cond);
+                LOGVAL(ctx, LYE_INWHEN, LY_VLOG_LYD, node, ((struct lys_node_container *)node->schema)->when->cond);
             }
             goto cleanup;
         }
@@ -6136,7 +6146,7 @@
                 LOGVRB("When condition \"%s\" is not satisfied, but it is not required.",
                        ((struct lys_node_container *)node->schema)->when->cond);
             } else {
-                LOGVAL(LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_container *)node->schema)->when->cond);
+                LOGVAL(ctx, LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_container *)node->schema)->when->cond);
                 if (failed_when) {
                     *failed_when = ((struct lys_node_container *)node->schema)->when;
                 }
@@ -6157,7 +6167,7 @@
             if (!ctx_node) {
                 rc = resolve_when_ctx_node(node, sparent, &ctx_node, &ctx_node_type);
                 if (rc) {
-                    LOGINT;
+                    LOGINT(ctx);
                     goto cleanup;
                 }
             }
@@ -6182,7 +6192,7 @@
 
             if (rc) {
                 if (rc == 1) {
-                    LOGVAL(LYE_INWHEN, LY_VLOG_LYD, node, ((struct lys_node_uses *)sparent)->when->cond);
+                    LOGVAL(ctx, LYE_INWHEN, LY_VLOG_LYD, node, ((struct lys_node_uses *)sparent)->when->cond);
                 }
                 goto cleanup;
             }
@@ -6195,7 +6205,7 @@
                         ((struct lys_node_uses *)sparent)->when->cond);
                 } else {
                     node->when_status |= LYD_WHEN_FALSE;
-                    LOGVAL(LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_uses *)sparent)->when->cond);
+                    LOGVAL(ctx, LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_uses *)sparent)->when->cond);
                     if (failed_when) {
                         *failed_when = ((struct lys_node_uses *)sparent)->when;
                     }
@@ -6212,7 +6222,7 @@
             if (!ctx_node) {
                 rc = resolve_when_ctx_node(node, sparent->parent, &ctx_node, &ctx_node_type);
                 if (rc) {
-                    LOGINT;
+                    LOGINT(ctx);
                     goto cleanup;
                 }
             }
@@ -6239,7 +6249,7 @@
 
             if (rc) {
                 if (rc == 1) {
-                    LOGVAL(LYE_INWHEN, LY_VLOG_LYD, node, ((struct lys_node_augment *)sparent->parent)->when->cond);
+                    LOGVAL(ctx, LYE_INWHEN, LY_VLOG_LYD, node, ((struct lys_node_augment *)sparent->parent)->when->cond);
                 }
                 goto cleanup;
             }
@@ -6252,7 +6262,7 @@
                     LOGVRB("When condition \"%s\" is not satisfied, but it is not required.",
                            ((struct lys_node_augment *)sparent->parent)->when->cond);
                 } else {
-                    LOGVAL(LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_augment *)sparent->parent)->when->cond);
+                    LOGVAL(ctx, LYE_NOWHEN, LY_VLOG_LYD, node, ((struct lys_node_augment *)sparent->parent)->when->cond);
                     if (failed_when) {
                         *failed_when = ((struct lys_node_augment *)sparent->parent)->when;
                     }
@@ -6281,6 +6291,7 @@
     struct lys_node *iter;
     struct ly_set *src_parents, *trg_parents, *features;
     struct lys_node_augment *aug;
+    struct ly_ctx *ctx = ((struct lys_tpdf *)type->parent)->module->ctx;
     unsigned int i, j, size, x;
     int ret = EXIT_SUCCESS;
 
@@ -6299,7 +6310,7 @@
             aug = (struct lys_node_augment *)iter->parent;
             if ((aug->module->implemented && (aug->flags & LYS_NOTAPPLIED)) || !aug->target) {
                 /* unresolved augment, wait until it's resolved */
-                LOGVAL(LYE_SPEC, LY_VLOG_LYS, aug,
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYS, aug,
                        "Cannot check leafref \"%s\" if-feature consistency because of an unresolved augment.", type->info.lref.path);
                 ret = EXIT_FAILURE;
                 goto cleanup;
@@ -6316,7 +6327,7 @@
             aug = (struct lys_node_augment *)iter->parent;
             if ((aug->module->implemented && (aug->flags & LYS_NOTAPPLIED)) || !aug->target) {
                 /* unresolved augment, wait until it's resolved */
-                LOGVAL(LYE_SPEC, LY_VLOG_LYS, aug,
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYS, aug,
                        "Cannot check leafref \"%s\" if-feature consistency because of an unresolved augment.", type->info.lref.path);
                 ret = EXIT_FAILURE;
                 goto cleanup;
@@ -6360,10 +6371,10 @@
                     ret = EXIT_FAILURE;
                     goto cleanup;
                 }
-                if ((unsigned int)ly_set_add(features, iter->iffeature[j].features[size - 1], 0) >= x) {
+                if ((unsigned)ly_set_add(features, iter->iffeature[j].features[size - 1], 0) >= x) {
                     /* the feature is not present in features set of target's parents chain */
-                    LOGVAL(LYE_NORESOLV, LY_VLOG_LYS, type->parent, "leafref", type->info.lref.path);
-                    LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL,
+                    LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_LYS, type->parent, "leafref", type->info.lref.path);
+                    LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL,
                            "Leafref is not conditional based on \"%s\" feature as its target.",
                            iter->iffeature[j].features[size - 1]->name);
                     ret = -1;
@@ -6426,8 +6437,9 @@
                           struct unres_schema *unres)
 {
     /* has_str - whether the str_snode is a string in a dictionary that needs to be freed */
-    int rc = -1, has_str = 0, parent_type = 0, i, k, hidden;
+    int rc = -1, has_str = 0, parent_type = 0, i, k;
     unsigned int j;
+    struct ly_ctx * ctx = mod->ctx;
     struct lys_node *root, *next, *node, *par_grp;
     const char *expr;
     uint8_t *u;
@@ -6469,12 +6481,7 @@
             assert(stype->info.lref.target);
 
             if (lys_node_module(node)->implemented) {
-                /* make all the modules on the path implemented, print verbose messages */
-                hidden = ly_vlog_hidden;
-                if (hidden) {
-                    ly_vlog_hide(0);
-                }
-
+                /* make all the modules in the path implemented */
                 for (next = (struct lys_node *)stype->info.lref.target; next; next = lys_parent(next)) {
                     if (!lys_node_module(next)->implemented) {
                         if (lys_set_implemented(lys_node_module(next))) {
@@ -6490,13 +6497,6 @@
                 /* store the backlink from leafref target */
                 if (lys_leaf_add_leafref_target(stype->info.lref.target, (struct lys_node *)stype->parent)) {
                     rc = -1;
-                }
-
-                if (hidden) {
-                    ly_vlog_hide(1);
-                }
-
-                if (rc) {
                     break;
                 }
             }
@@ -6530,7 +6530,7 @@
                 stype->der = (struct lys_tpdf *)yang;
             } else {
                 /* we need to always be able to free this, it's safe only in this case */
-                lydict_remove(mod->ctx, yang->name);
+                lydict_remove(ctx, yang->name);
                 free(yang);
             }
 
@@ -6538,7 +6538,7 @@
             rc = fill_yin_type(mod, node, yin, stype, parent_type, unres);
             if (!rc || rc == -1) {
                 /* we need to always be able to free this, it's safe only in this case */
-                lyxml_free(mod->ctx, yin);
+                lyxml_free(ctx, yin);
             } else {
                 /* may try again later, put all back how it was */
                 stype->der = (struct lys_tpdf *)yin;
@@ -6547,7 +6547,7 @@
         if (rc == EXIT_SUCCESS) {
             /* it does not make sense to have leaf-list of empty type */
             if (!parent_type && node->nodetype == LYS_LEAFLIST && stype->base == LY_TYPE_EMPTY) {
-                LOGWRN("The leaf-list \"%s\" is of \"empty\" type, which does not make sense.", node->name);
+                LOGWRN(ctx, "The leaf-list \"%s\" is of \"empty\" type, which does not make sense.", node->name);
             }
 
             if ((type == UNRES_TYPE_DER_TPDF) && (stype->base == LY_TYPE_UNION)) {
@@ -6556,7 +6556,7 @@
             } else if ((type == UNRES_TYPE_DER) && stype->der->has_union_leafref) {
                 /* copy the type in case it has union leafref flag */
                 if (lys_copy_union_leafrefs(mod, node, stype, NULL, unres)) {
-                    LOGERR(LY_EINT, "Failed to duplicate type.");
+                    LOGERR(ctx, LY_EINT, "Failed to duplicate type.");
                     return -1;
                 }
             }
@@ -6569,7 +6569,7 @@
             for (par_grp = node; par_grp && (par_grp->nodetype != LYS_GROUPING); par_grp = lys_parent(par_grp));
             if (par_grp) {
                 if (++((struct lys_node_grp *)par_grp)->unres_count == 0) {
-                    LOGERR(LY_EINT, "Too many unresolved items (type) inside a grouping.");
+                    LOGERR(ctx, LY_EINT, "Too many unresolved items (type) inside a grouping.");
                     return -1;
                 }
                 stype->base = LY_TYPE_ERR;
@@ -6590,7 +6590,7 @@
                 ly_set_add(feat->depfeatures, iff_data->node, LY_SET_OPT_USEASLIST);
             }
             /* cleanup temporary data */
-            lydict_remove(mod->ctx, iff_data->fname);
+            lydict_remove(ctx, iff_data->fname);
             free(iff_data);
         }
         break;
@@ -6611,7 +6611,7 @@
                     for (; j > 0 ; j--) {
                         if (ref->iffeature[i].features[j - 1]) {
                             if (ref->iffeature[i].features[j - 1] == feat) {
-                                LOGVAL(LYE_CIRC_FEATURES, LY_VLOG_NONE, NULL, feat->name);
+                                LOGVAL(ctx, LYE_CIRC_FEATURES, LY_VLOG_NONE, NULL, feat->name);
                                 goto featurecheckdone;
                             }
 
@@ -6688,7 +6688,7 @@
             if (eplugin) {
                 if (eplugin->check_result || (eplugin->flags & LYEXT_OPT_INHERIT)) {
                     u = malloc(sizeof *u);
-                    LY_CHECK_ERR_RETURN(!u, LOGMEM, -1);
+                    LY_CHECK_ERR_RETURN(!u, LOGMEM(ctx), -1);
                     (*u) = ext_data->ext_index;
                     if (unres_schema_add_node(mod, unres, item, UNRES_EXT_FINALIZE, (struct lys_node *)u) == -1) {
                         /* something really bad happend since the extension finalization is not actually
@@ -6703,7 +6703,7 @@
             /* cleanup on success or fatal error */
             if (ext_data->datatype == LYS_IN_YIN) {
                 /* YIN */
-                lyxml_free(mod->ctx, ext_data->data.yin);
+                lyxml_free(ctx, ext_data->data.yin);
             } else {
                 /* YANG */
                 yang_free_ext_data(ext_data->data.yang);
@@ -6746,16 +6746,16 @@
                             /* no, but continue with the children, just skip the inheriting code for this node */
                             goto inherit_dfs_child;
                         default:
-                            LOGERR(LY_EINT, "Plugin's (%s:%s) check_inherit callback returns invalid value (%d),",
+                            LOGERR(ctx, LY_EINT, "Plugin's (%s:%s) check_inherit callback returns invalid value (%d),",
                                    ext->def->module->name, ext->def->name, rc);
                         }
                     }
 
                     /* inherit the extension */
                     extlist = realloc(node->ext, (node->ext_size + 1) * sizeof *node->ext);
-                    LY_CHECK_ERR_RETURN(!extlist, LOGMEM, -1);
+                    LY_CHECK_ERR_RETURN(!extlist, LOGMEM(ctx), -1);
                     extlist[node->ext_size] = malloc(sizeof **extlist);
-                    LY_CHECK_ERR_RETURN(!extlist[node->ext_size], LOGMEM; node->ext = extlist, -1);
+                    LY_CHECK_ERR_RETURN(!extlist[node->ext_size], LOGMEM(ctx); node->ext = extlist, -1);
                     memcpy(extlist[node->ext_size], ext, sizeof *ext);
                     extlist[node->ext_size]->flags |= LYEXT_OPT_INHERIT;
 
@@ -6793,7 +6793,7 @@
         /* final check */
         if (eplugin->check_result) {
             if ((*eplugin->check_result)(ext)) {
-                ly_errno = LY_EEXT;
+                LOGERR(ctx, LY_EEXT, "Resolving extension failed.");
                 return -1;
             }
         }
@@ -6801,14 +6801,14 @@
         rc = 0;
         break;
     default:
-        LOGINT;
+        LOGINT(ctx);
         break;
     }
 
     if (has_str && !rc) {
         /* the string is no more needed in case of success.
          * In case of forward reference, we will try to resolve the string later */
-        lydict_remove(mod->ctx, str_snode);
+        lydict_remove(ctx, str_snode);
     }
 
     return rc;
@@ -6894,7 +6894,7 @@
         LOGVRB("Resolving extension \"%s\" failed, it will be attempted later.", name);
         break;
     default:
-        LOGINT;
+        LOGINT(NULL);
         break;
     }
 }
@@ -6911,19 +6911,16 @@
 resolve_unres_schema(struct lys_module *mod, struct unres_schema *unres)
 {
     uint32_t i, resolved = 0, unres_count, res_count;
-    struct lyxml_elem *yin;
-    struct yang_type *yang;
-    int rc, log_hidden;
+    struct ly_err_item *prev_eitem;
+    enum int_log_opts prev_ilo;
+    LY_ERR prev_ly_errno;
+    int rc;
 
     assert(unres);
 
     LOGVRB("Resolving \"%s\" unresolved schema nodes and their constraints...", mod->name);
-    if (ly_vlog_hidden) {
-        log_hidden = 1;
-    } else {
-        log_hidden = 0;
-        ly_vlog_hide(1);
-    }
+    prev_ly_errno = ly_errno;
+    ly_ilo_change(mod->ctx, ILO_STORE, &prev_ilo, &prev_eitem);
 
     /* uses */
     do {
@@ -6947,44 +6944,23 @@
                 ++resolved;
                 ++res_count;
             } else if (rc == -1) {
-                if (!log_hidden) {
-                    ly_vlog_hide(0);
-                }
-                /* print the error */
-                ly_err_repeat(ly_parser_data.ctx);
-                return -1;
+                goto error;
             } else {
-                /* forward reference, erase ly_errno */
-                ly_err_clean(ly_parser_data.ctx, 1);
+                /* forward reference, erase errors */
+                ly_err_free_next(mod->ctx, prev_eitem);
             }
         }
     } while (res_count && (res_count < unres_count));
 
     if (res_count < unres_count) {
-        /* just print the errors */
-        if (!log_hidden) {
-            ly_vlog_hide(0);
-        }
+        /* just print the errors (but we must free the ones we have and get them again :-/ ) */
+        ly_ilo_restore(mod->ctx, prev_ilo, prev_eitem, 0);
 
         for (i = 0; i < unres->count; ++i) {
             if (unres->type[i] > UNRES_IDENT) {
                 continue;
             }
             resolve_unres_schema_item(unres->module[i], unres->item[i], unres->type[i], unres->str_snode[i], unres);
-            if (unres->type[i] == UNRES_TYPE_DER_EXT) {
-                yin = (struct lyxml_elem*)((struct lys_type *)unres->item[i])->der;
-                if (yin->flags & LY_YANG_STRUCTURE_FLAG) {
-                    yang =(struct yang_type *)yin;
-                    ((struct lys_type *)unres->item[i])->base = yang->base;
-                    if (yang->base == LY_TYPE_UNION) {
-                        yang_free_type_union(mod->ctx, (struct lys_type *)unres->item[i]);
-                    }
-                    lydict_remove(mod->ctx, yang->name);
-                    free(yang);
-                } else {
-                    lyxml_free(mod->ctx, yin);
-                }
-            }
         }
         return -1;
     }
@@ -7004,21 +6980,16 @@
             unres->type[i] = UNRES_RESOLVED;
             ++resolved;
         } else if (rc == -1) {
-            if (!log_hidden) {
-                ly_vlog_hide(0);
-            }
-            /* print the error */
-            ly_err_repeat(ly_parser_data.ctx);
-            return -1;
+            goto error;
         } else {
-            /* forward reference, erase ly_errno */
-            ly_err_clean(ly_parser_data.ctx, 1);
+            /* forward reference, erase errors */
+            ly_err_free_next(mod->ctx, prev_eitem);
         }
     }
 
-    if (!log_hidden) {
-        ly_vlog_hide(0);
-    }
+    /* log normally now */
+    ly_ilo_restore(mod->ctx, prev_ilo, prev_eitem, 0);
+    ly_errno = prev_ly_errno;
 
     /* finalize extensions, keep it last to provide the complete schema tree information to the plugin's checkers */
     for (i = 0; i < unres->count; ++i) {
@@ -7060,6 +7031,11 @@
     LOGVRB("All \"%s\" schema nodes and constraints resolved.", mod->name);
     unres->count = 0;
     return EXIT_SUCCESS;
+
+error:
+    ly_ilo_restore(mod->ctx, prev_ilo, prev_eitem, 1);
+    /* ly_errno will be set accordingly, we do not want to keep the previous value */
+    return -1;
 }
 
 /**
@@ -7104,9 +7080,13 @@
 unres_schema_add_node(struct lys_module *mod, struct unres_schema *unres, void *item, enum UNRES_ITEM type,
                       struct lys_node *snode)
 {
-    int rc, log_hidden;
+    int rc;
     uint32_t u;
+    enum int_log_opts prev_ilo;
+    struct ly_err_item *prev_eitem;
+    LY_ERR prev_ly_errno;
     struct lyxml_elem *yin;
+    struct ly_ctx *ctx = mod->ctx;
 
     assert(unres && item && ((type != UNRES_LEAFREF) && (type != UNRES_INSTID) && (type != UNRES_WHEN)
            && (type != UNRES_MUST)));
@@ -7127,21 +7107,16 @@
          * xpath is not tried because it would hide some potential warnings */
         rc = EXIT_FAILURE;
     } else {
-        if (ly_vlog_hidden) {
-            log_hidden = 1;
-        } else {
-            log_hidden = 0;
-            ly_vlog_hide(1);
-        }
-        rc = resolve_unres_schema_item(mod, item, type, snode, unres);
-        if (!log_hidden) {
-            ly_vlog_hide(0);
-        }
+        prev_ly_errno = ly_errno;
+        ly_ilo_change(ctx, ILO_STORE, &prev_ilo, &prev_eitem);
 
+        rc = resolve_unres_schema_item(mod, item, type, snode, unres);
         if (rc != EXIT_FAILURE) {
-            if (rc == -1) {
-                ly_err_repeat(ly_parser_data.ctx);
+            ly_ilo_restore(ctx, prev_ilo, prev_eitem, rc == -1 ? 1 : 0);
+            if (rc != -1) {
+                ly_errno = prev_ly_errno;
             }
+
             if (type == UNRES_LIST_UNIQ) {
                 /* free the allocated structure */
                 free(item);
@@ -7152,7 +7127,8 @@
             return rc;
         } else {
             /* erase info about validation errors */
-            ly_err_clean(ly_parser_data.ctx, 1);
+            ly_ilo_restore(ctx, prev_ilo, prev_eitem, 0);
+            ly_errno = prev_ly_errno;
         }
 
         print_unres_schema_item_fail(item, type, snode);
@@ -7169,16 +7145,16 @@
 
     unres->count++;
     unres->item = ly_realloc(unres->item, unres->count*sizeof *unres->item);
-    LY_CHECK_ERR_RETURN(!unres->item, LOGMEM, -1);
+    LY_CHECK_ERR_RETURN(!unres->item, LOGMEM(ctx), -1);
     unres->item[unres->count-1] = item;
     unres->type = ly_realloc(unres->type, unres->count*sizeof *unres->type);
-    LY_CHECK_ERR_RETURN(!unres->type, LOGMEM, -1);
+    LY_CHECK_ERR_RETURN(!unres->type, LOGMEM(ctx), -1);
     unres->type[unres->count-1] = type;
     unres->str_snode = ly_realloc(unres->str_snode, unres->count*sizeof *unres->str_snode);
-    LY_CHECK_ERR_RETURN(!unres->str_snode, LOGMEM, -1);
+    LY_CHECK_ERR_RETURN(!unres->str_snode, LOGMEM(ctx), -1);
     unres->str_snode[unres->count-1] = snode;
     unres->module = ly_realloc(unres->module, unres->count*sizeof *unres->module);
-    LY_CHECK_ERR_RETURN(!unres->module, LOGMEM, -1);
+    LY_CHECK_ERR_RETURN(!unres->module, LOGMEM(ctx), -1);
     unres->module[unres->count-1] = mod;
 
     return rc;
@@ -7222,22 +7198,22 @@
     if ((type == UNRES_TYPE_LEAFREF) || (type == UNRES_USES) || (type == UNRES_TYPE_DFLT) ||
             (type == UNRES_FEATURE) || (type == UNRES_LIST_UNIQ)) {
         if (unres_schema_add_node(mod, unres, new_item, type, unres->str_snode[i]) == -1) {
-            LOGINT;
+            LOGINT(mod->ctx);
             return -1;
         }
     } else if (type == UNRES_IFFEAT) {
         /* duplicate unres_iffeature_data */
         iff_data = malloc(sizeof *iff_data);
-        LY_CHECK_ERR_RETURN(!iff_data, LOGMEM, -1);
+        LY_CHECK_ERR_RETURN(!iff_data, LOGMEM(mod->ctx), -1);
         iff_data->fname = lydict_insert(mod->ctx, ((struct unres_iffeat_data *)unres->str_snode[i])->fname, 0);
         iff_data->node = ((struct unres_iffeat_data *)unres->str_snode[i])->node;
         if (unres_schema_add_node(mod, unres, new_item, type, (struct lys_node *)iff_data) == -1) {
-            LOGINT;
+            LOGINT(mod->ctx);
             return -1;
         }
     } else {
         if (unres_schema_add_str(mod, unres, new_item, type, unres->str_snode[i]) == -1) {
-            LOGINT;
+            LOGINT(mod->ctx);
             return -1;
         }
     }
@@ -7366,8 +7342,9 @@
 check_instid_ext_dep(const struct lys_node *sleaf, const char *json_instid)
 {
     const struct lys_node *op_node, *first_node;
+    enum int_log_opts prev_ilo;
     char *buf;
-    int ret = 0, hidden;
+    int ret = 0;
 
     if (!json_instid || !json_instid[0]) {
         /* no/empty value */
@@ -7386,27 +7363,20 @@
     /* get the first node from the instid */
     buf = strndup(json_instid, strchr(json_instid + 1, '/') - json_instid);
     if (!buf) {
-        LOGMEM;
-        return -1;
+        /* so that we do not have to bother with logging, say it is not external */
+        return 0;
     }
 
     /* find the first schema node, do not log */
-    hidden = ly_vlog_hidden;
-    if (!hidden) {
-        ly_vlog_hide(1);
-    }
+    ly_ilo_change(NULL, ILO_IGNORE, &prev_ilo, NULL);
     first_node = ly_ctx_get_node(NULL, sleaf, buf, 0);
-    if (!hidden) {
-        ly_vlog_hide(0);
-    }
+    ly_ilo_restore(NULL, prev_ilo, NULL, 0);
 
+    free(buf);
     if (!first_node) {
         /* unknown path, say it is not external */
-        free(buf);
-        ly_errno = LY_SUCCESS;
         return 0;
     }
-    free(buf);
 
     /* based on the first schema node in the path we can decide whether it points to an external tree or not */
 
@@ -7455,7 +7425,7 @@
     while (path[i]) {
         j = parse_instance_identifier(&path[i], &model, &mod_len, &name, &name_len, &has_predicate);
         if (j <= 0) {
-            LOGVAL(LYE_INCHAR, LY_VLOG_LYD, data, path[i-j], &path[i-j]);
+            LOGVAL(ctx, LYE_INCHAR, LY_VLOG_LYD, data, path[i-j], &path[i-j]);
             goto error;
         }
         i += j;
@@ -7463,7 +7433,7 @@
         if (model) {
             str = strndup(model, mod_len);
             if (!str) {
-                LOGMEM;
+                LOGMEM(ctx);
                 goto error;
             }
             mod = ly_ctx_get_module(ctx, str, NULL, 1);
@@ -7481,8 +7451,8 @@
             }
         } else if (!prev_mod) {
             /* first iteration and we are missing module name */
-            LOGVAL(LYE_INELEM_LEN, LY_VLOG_NONE, NULL, name_len, name);
-            LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "Instane-identifier is missing prefix in the first node.");
+            LOGVAL(ctx, LYE_INELEM_LEN, LY_VLOG_NONE, NULL, name_len, name);
+            LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "Instane-identifier is missing prefix in the first node.");
             goto error;
         } else {
             mod = prev_mod;
@@ -7502,7 +7472,7 @@
                 node = node_match.node[j];
                 parsed = resolve_instid_predicate(mod, &path[i], &node, cur_idx);
                 if (parsed < 1) {
-                    LOGVAL(LYE_INPRED, LY_VLOG_LYD, data, &path[i - parsed]);
+                    LOGVAL(ctx, LYE_INPRED, LY_VLOG_LYD, data, &path[i - parsed]);
                     goto error;
                 }
 
@@ -7524,7 +7494,7 @@
                 }
             }
             if (!node_match.count) {
-                LOGVAL(LYE_SPEC, LY_VLOG_LYD, data, "Instance identifier is missing list keys.");
+                LOGVAL(ctx, LYE_SPEC, LY_VLOG_LYD, data, "Instance identifier is missing list keys.");
             }
         }
 
@@ -7534,14 +7504,14 @@
     if (!node_match.count) {
         /* no instance exists */
         if (req_inst > -1) {
-            LOGVAL(LYE_NOREQINS, LY_VLOG_LYD, data, path);
+            LOGVAL(ctx, LYE_NOREQINS, LY_VLOG_LYD, data, path);
             return EXIT_FAILURE;
         }
         LOGVRB("There is no instance of \"%s\", but it is not required.", path);
         return EXIT_SUCCESS;
     } else if (node_match.count > 1) {
         /* instance identifier must resolve to a single node */
-        LOGVAL(LYE_TOOMANY, LY_VLOG_LYD, data, path, "data tree");
+        LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYD, data, path, "data tree");
         goto error;
     } else {
         /* we have required result, remember it and cleanup */
@@ -7589,7 +7559,7 @@
     if (!*ret) {
         /* reference not found */
         if (req_inst > -1) {
-            LOGVAL(LYE_NOLEAFREF, LY_VLOG_LYD, leaf, path, leaf->value_str);
+            LOGVAL(leaf->schema->module->ctx, LYE_NOLEAFREF, LY_VLOG_LYD, leaf, path, leaf->value_str);
             return EXIT_FAILURE;
         } else {
             LOGVRB("There is no leafref \"%s\" with the value \"%s\", but it is not required.", path, leaf->value_str);
@@ -7604,9 +7574,11 @@
 resolve_union(struct lyd_node_leaf_list *leaf, struct lys_type *type, int store, int ignore_fail,
               struct lys_type **resolved_type)
 {
+    struct ly_ctx *ctx = leaf->schema->module->ctx;
     struct lys_type *t;
     struct lyd_node *ret;
-    int found, hidden, success = 0, ext_dep, req_inst;
+    enum int_log_opts prev_ilo;
+    int found, success = 0, ext_dep, req_inst;
     const char *json_val = NULL;
 
     assert(type->base == LY_TYPE_UNION);
@@ -7624,8 +7596,7 @@
     }
 
     /* turn logging off, we are going to try to validate the value with all the types in order */
-    hidden = ly_vlog_hidden;
-    ly_vlog_hide(1);
+    ly_ilo_change(NULL, ILO_IGNORE, &prev_ilo, 0);
 
     t = NULL;
     found = 0;
@@ -7648,9 +7619,11 @@
                         leaf->value_type = LY_TYPE_LEAFREF;
                     } else {
                         /* valid unresolved */
+                        ly_ilo_restore(NULL, prev_ilo, NULL, 0);
                         if (!lyp_parse_value(t, &leaf->value_str, NULL, leaf, NULL, NULL, 1, 0)) {
                             return -1;
                         }
+                        ly_ilo_change(NULL, ILO_IGNORE, &prev_ilo, NULL);
                     }
                 }
 
@@ -7659,9 +7632,6 @@
             break;
         case LY_TYPE_INST:
             ext_dep = check_instid_ext_dep(leaf->schema, (json_val ? json_val : leaf->value_str));
-            if (ext_dep == -1) {
-                return -1;
-            }
             if ((ignore_fail == 1) || (ext_dep && (ignore_fail == 2))) {
                 req_inst = -1;
             } else {
@@ -7707,10 +7677,6 @@
             break;
         }
 
-        /* erase information about errors - they are false or irrelevant
-         * and will be replaced by a single error messages */
-        ly_err_clean(ly_parser_data.ctx, 1);
-
         /* erase possible present and invalid value data */
         if (store) {
             if (t->base == LY_TYPE_BITS) {
@@ -7721,9 +7687,7 @@
     }
 
     /* turn logging back on */
-    if (!hidden) {
-        ly_vlog_hide(0);
-    }
+    ly_ilo_restore(NULL, prev_ilo, NULL, 0);
 
     if (json_val) {
         if (!success) {
@@ -7742,7 +7706,7 @@
         }
     } else if (!ignore_fail || !type->info.uni.has_ptr_type) {
         /* not found and it is required */
-        LOGVAL(LYE_INVAL, LY_VLOG_LYD, leaf, leaf->value_str ? leaf->value_str : "", leaf->schema->name);
+        LOGVAL(ctx, LYE_INVAL, LY_VLOG_LYD, leaf, leaf->value_str ? leaf->value_str : "", leaf->schema->name);
         return EXIT_FAILURE;
     }
 
@@ -7853,7 +7817,7 @@
         break;
 
     default:
-        LOGINT;
+        LOGINT(NULL);
         return -1;
     }
 
@@ -7877,10 +7841,10 @@
 
     unres->count++;
     unres->node = ly_realloc(unres->node, unres->count * sizeof *unres->node);
-    LY_CHECK_ERR_RETURN(!unres->node, LOGMEM, -1);
+    LY_CHECK_ERR_RETURN(!unres->node, LOGMEM(NULL), -1);
     unres->node[unres->count - 1] = node;
     unres->type = ly_realloc(unres->type, unres->count * sizeof *unres->type);
-    LY_CHECK_ERR_RETURN(!unres->type, LOGMEM, -1);
+    LY_CHECK_ERR_RETURN(!unres->type, LOGMEM(NULL), -1);
     unres->type[unres->count - 1] = type;
 
     if (type == UNRES_WHEN) {
@@ -7888,7 +7852,7 @@
         node->when_status = LYD_WHEN;
     }
 
-    return EXIT_SUCCESS;
+    return 0;
 }
 
 /**
@@ -7899,6 +7863,7 @@
  *
  * If options includes LYD_OPT_NOAUTODEL, the false resulting when condition on non-default nodes, the error is raised.
  *
+ * @param[in] ctx Context used.
  * @param[in] unres Unres data structure to use.
  * @param[in,out] root Root node of the data tree, can be changed due to autodeletion.
  * @param[in] options Data options as described above.
@@ -7906,10 +7871,13 @@
  * @return EXIT_SUCCESS on success, -1 on error.
  */
 int
-resolve_unres_data(struct unres_data *unres, struct lyd_node **root, int options)
+resolve_unres_data(struct ly_ctx *ctx, struct unres_data *unres, struct lyd_node **root, int options)
 {
     uint32_t i, j, first, resolved, del_items, stmt_count;
     int rc, progress, ignore_fail;
+    enum int_log_opts prev_ilo;
+    struct ly_err_item *prev_eitem;
+    LY_ERR prev_ly_errno;
     struct lyd_node *parent;
     struct lys_when *when;
 
@@ -7929,7 +7897,9 @@
     }
 
     LOGVRB("Resolving unresolved data nodes and their constraints...");
-    ly_vlog_hide(1);
+    /* remember logging state */
+    prev_ly_errno = ly_errno;
+    ly_ilo_change(ctx, ILO_STORE, &prev_ilo, &prev_eitem);
 
     /* when-stmt first */
     first = 1;
@@ -7937,7 +7907,7 @@
     resolved = 0;
     del_items = 0;
     do {
-        ly_err_clean(ly_parser_data.ctx, 1);
+        ly_err_free_next(ctx, prev_eitem);
         progress = 0;
         for (i = 0; i < unres->count; i++) {
             if (unres->type[i] != UNRES_WHEN) {
@@ -7974,14 +7944,11 @@
                         && (!(when->flags & LYS_XPATH_DEP) || !(options & LYD_OPT_NOEXTDEPS))) {
                     if ((options & LYD_OPT_NOAUTODEL) && !unres->node[i]->dflt) {
                         /* false when condition */
-                        ly_vlog_hide(0);
-                        ly_err_repeat(ly_parser_data.ctx);
-                        return -1;
+                        goto error;
                     } /* follows else */
 
                     /* auto-delete */
-                    LOGVRB("auto-delete node \"%s\" due to when condition (%s)", ly_errpath(),
-                           ((struct lys_node_leaf *)unres->node[i]->schema)->when->cond);
+                    LOGVRB("auto-delete node \"%s\" due to when condition (%s)", ly_errpath(ctx), when->cond);
 
                     /* only unlink now, the subtree can contain another nodes stored in the unres list */
                     /* if it has parent non-presence containers that would be empty, we should actually
@@ -8028,14 +7995,11 @@
                 } else {
                     unres->type[i] = UNRES_RESOLVED;
                 }
-                ly_err_clean(ly_parser_data.ctx, 1);
+                ly_err_free_next(ctx, prev_eitem);
                 resolved++;
                 progress = 1;
             } else if (rc == -1) {
-                ly_vlog_hide(0);
-                /* print only this last error */
-                resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail, NULL);
-                return -1;
+                goto error;
             } /* else forward reference */
         }
         first = 0;
@@ -8043,9 +8007,7 @@
 
     /* do we have some unresolved when-stmt? */
     if (stmt_count > resolved) {
-        ly_vlog_hide(0);
-        ly_err_repeat(ly_parser_data.ctx);
-        return -1;
+        goto error;
     }
 
     for (i = 0; del_items && i < unres->count; i++) {
@@ -8083,14 +8045,11 @@
             rc = resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail, NULL);
             if (!rc) {
                 unres->type[i] = UNRES_RESOLVED;
-                ly_err_clean(ly_parser_data.ctx, 1);
+                ly_err_free_next(ctx, prev_eitem);
                 resolved++;
                 progress = 1;
             } else if (rc == -1) {
-                ly_vlog_hide(0);
-                /* print only this last error */
-                resolve_unres_data_item(unres->node[i], unres->type[i], ignore_fail, NULL);
-                return -1;
+                goto error;
             } /* else forward reference */
         }
         first = 0;
@@ -8098,12 +8057,12 @@
 
     /* do we have some unresolved leafrefs? */
     if (stmt_count > resolved) {
-        ly_vlog_hide(0);
-        ly_err_repeat(ly_parser_data.ctx);
-        return -1;
+        goto error;
     }
 
-    ly_vlog_hide(0);
+    /* log normally now, throw away irrelevant errors */
+    ly_ilo_restore(ctx, prev_ilo, prev_eitem, 0);
+    ly_errno = prev_ly_errno;
 
     /* rest */
     for (i = 0; i < unres->count; ++i) {
@@ -8124,4 +8083,10 @@
     LOGVRB("All data nodes and constraints resolved.");
     unres->count = 0;
     return EXIT_SUCCESS;
+
+error:
+    /* print all the new errors */
+    ly_ilo_restore(ctx, prev_ilo, prev_eitem, 1);
+    /* do not restore ly_errno, it was udpated properly */
+    return -1;
 }