yin parser CHANGE create and use custom context for yin parser functions
struct yin_parser_ctx is compatible with lys_parser_ctx and can be easily expanded (without changes in unrelated structures like struct lyxml_context) in case it's needed.
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 1b97e92..78e3d87 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -49,7 +49,7 @@
 };
 
 enum yang_keyword
-yin_match_keyword(struct lyxml_context *xml_ctx, const char *name, size_t name_len, const char *prefix, size_t prefix_len)
+yin_match_keyword(struct yin_parser_ctx *ctx, const char *name, size_t name_len, const char *prefix, size_t prefix_len)
 {
     const char *start = NULL;
     enum yang_keyword kw = YANG_NONE;
@@ -59,7 +59,7 @@
         return YANG_NONE;
     }
 
-    ns = lyxml_ns_get(xml_ctx, prefix, prefix_len);
+    ns = lyxml_ns_get(&ctx->xml_ctx, prefix, prefix_len);
     if (ns) {
         if (!IS_YIN_NS(ns->uri)) {
             return YANG_CUSTOM;
@@ -154,32 +154,32 @@
  * @brief free argument record, content loaded from lyxml_get_string() can be
  * dynamically allocated in some cases so it must be also freed.
  */
-static void free_arg_rec(struct lyxml_context *xml_ctx, struct yin_arg_record *record) {
-    (void)xml_ctx; /* unused */
+static void free_arg_rec(struct yin_parser_ctx *ctx, struct yin_arg_record *record) {
+    (void)ctx; /* unused */
     if (record->dynamic_content) {
         free(record->content);
     }
 }
 
 LY_ERR
-yin_load_attributes(struct lyxml_context *xml_ctx, const char **data, struct yin_arg_record **attrs)
+yin_load_attributes(struct yin_parser_ctx *ctx, const char **data, struct yin_arg_record **attrs)
 {
     LY_ERR ret = LY_SUCCESS;
     struct yin_arg_record *argument_record = NULL;
     struct sized_string prefix, name;
 
     /* load all attributes */
-    while (xml_ctx->status == LYXML_ATTRIBUTE) {
-        ret = lyxml_get_attribute(xml_ctx, data, &prefix.value, &prefix.len, &name.value, &name.len);
+    while (ctx->xml_ctx.status == LYXML_ATTRIBUTE) {
+        ret = lyxml_get_attribute(&ctx->xml_ctx, data, &prefix.value, &prefix.len, &name.value, &name.len);
         LY_CHECK_GOTO(ret != LY_SUCCESS, cleanup);
 
-        if (xml_ctx->status == LYXML_ATTR_CONTENT) {
-            LY_ARRAY_NEW_GOTO(xml_ctx->ctx, *attrs, argument_record, ret, cleanup);
+        if (ctx->xml_ctx.status == LYXML_ATTR_CONTENT) {
+            LY_ARRAY_NEW_GOTO(ctx->xml_ctx.ctx, *attrs, argument_record, ret, cleanup);
             argument_record->name = name.value;
             argument_record->name_len = name.len;
             argument_record->prefix = prefix.value;
             argument_record->prefix_len = prefix.len;
-            ret = lyxml_get_string(xml_ctx, data, &argument_record->content, &argument_record->content_len,
+            ret = lyxml_get_string(&ctx->xml_ctx, data, &argument_record->content, &argument_record->content_len,
                                    &argument_record->content, &argument_record->content_len, &argument_record->dynamic_content);
             LY_CHECK_GOTO(ret != LY_SUCCESS, cleanup);
         }
@@ -187,7 +187,7 @@
 
 cleanup:
     if (ret != LY_SUCCESS) {
-        FREE_ARRAY(xml_ctx, *attrs, free_arg_rec);
+        FREE_ARRAY(ctx, *attrs, free_arg_rec);
         *attrs = NULL;
     }
     return ret;
@@ -196,7 +196,7 @@
 /**
  * @brief Parse yin argument.
  *
- * @param[in] xml_ctx XML parser context.
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
  * @param[in] attrs Array of attributes.
  * @param[in,out] data Data to read from.
  * @param[in] arg_type Type of argument that is expected in parsed element (use YIN_ARG_NONE for elements without special argument).
@@ -207,7 +207,7 @@
  * @return LY_ERR values.
  */
 static LY_ERR
-yin_parse_attribute(struct lyxml_context *xml_ctx, struct yin_arg_record **attrs, enum YIN_ARGUMENT arg_type,
+yin_parse_attribute(struct yin_parser_ctx *ctx, struct yin_arg_record **attrs, enum YIN_ARGUMENT arg_type,
                     const char **arg_val, uint8_t flags, enum yang_keyword current_element)
 {
     enum YIN_ARGUMENT arg = YIN_ARG_UNKNOWN;
@@ -224,23 +224,23 @@
             } else if (arg == arg_type) {
                 found = true;
                 if (iter->dynamic_content) {
-                    *arg_val = lydict_insert_zc(xml_ctx->ctx, iter->content);
+                    *arg_val = lydict_insert_zc(ctx->xml_ctx.ctx, iter->content);
                     LY_CHECK_RET(!(*arg_val), LY_EMEM);
                     /* string is no longer supposed to be freed when the sized array is freed */
                     iter->dynamic_content = 0;
                 } else {
-                    *arg_val = lydict_insert(xml_ctx->ctx, iter->content, iter->content_len);
+                    *arg_val = lydict_insert(ctx->xml_ctx.ctx, iter->content, iter->content_len);
                     LY_CHECK_RET(!(*arg_val), LY_EMEM);
                 }
             } else {
-                LOGVAL_PARSER(xml_ctx, LYVE_SYNTAX_YIN, "Unexpected attribute \"%.*s\" of %s element.", iter->name_len, iter->name, ly_stmt2str(current_element));
+                LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YIN, "Unexpected attribute \"%.*s\" of %s element.", iter->name_len, iter->name, ly_stmt2str(current_element));
                 return LY_EVALID;
             }
         }
     }
 
     if (flags & YIN_ARG_MANDATORY && !found) {
-        LOGVAL_PARSER(xml_ctx, LYVE_SYNTAX_YIN, "Missing mandatory attribute \"%s\" of %s element.", yin_attr2str(arg_type), ly_stmt2str(current_element));
+        LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YIN, "Missing mandatory attribute \"%s\" of %s element.", yin_attr2str(arg_type), ly_stmt2str(current_element));
         return LY_EVALID;
     }
 
@@ -248,7 +248,7 @@
 }
 
 /**
- * @brief Get record with given type.
+ * @brief Get record with given type. Array must be sorted in ascending order by array[n].type.
  *
  * @param[in] type Type of wanted record.
  * @param[in] array_size Size of array.
@@ -279,13 +279,13 @@
 }
 
 LY_ERR
-yin_check_subelem_mandatory_constraint(struct lyxml_context *xml_ctx, struct yin_subelement *subelem_info,
+yin_check_subelem_mandatory_constraint(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info,
                                        signed char subelem_info_size, enum yang_keyword current_element)
 {
     for (signed char i = 0; i < subelem_info_size; ++i) {
         /* if there is element that is mandatory and isn't parsed log error and rturn LY_EVALID */
         if (subelem_info[i].flags & YIN_SUBELEM_MANDATORY && !(subelem_info[i].flags & YIN_SUBELEM_PARSED)) {
-            LOGVAL_PARSER(xml_ctx, LYVE_SYNTAX_YIN, "Missing mandatory subelement %s of %s element.",
+            LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YIN, "Missing mandatory subelement %s of %s element.",
                           ly_stmt2str(subelem_info[i].type), ly_stmt2str(current_element));
             return LY_EVALID;
         }
@@ -295,12 +295,12 @@
 }
 
 LY_ERR
-yin_check_subelem_first_constraint(struct lyxml_context *xml_ctx, struct yin_subelement *subelem_info,
+yin_check_subelem_first_constraint(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info,
                                    signed char subelem_info_size, enum yang_keyword current_element, struct yin_subelement *exp_first)
 {
     for (signed char i = 0; i < subelem_info_size; ++i) {
         if (subelem_info[i].flags & YIN_SUBELEM_PARSED) {
-            LOGVAL_PARSER(xml_ctx, LYVE_SYNTAX_YIN, "Subelement %s of %s element must be defined as first subelement.",
+            LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YIN, "Subelement %s of %s element must be defined as first subelement.",
                           ly_stmt2str(exp_first->type), ly_stmt2str(current_element));
             return LY_EVALID;
         }
@@ -329,32 +329,32 @@
  * @brief Parse simple element without any special constraints and argument mapped to yin attribute,
  * for example prefix or namespace element.
  *
- * @param[in] xml_ctx Xml context.
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
  * @param[in] attrs Attributes of current element.
  * @param[in,out] data Data to read from, always moved to currently handled character.
  * @param[in] kw Type of current element.
  * @param[out] value Where value of attribute should be stored.
  * @param[in] arg_type Expected type of attribute.
- * @param[in] arg_flags Argument flags can be set to YIN_ATT_value values.
- * @param[in] exts Extension instance to add to.
+ * @param[in] arg_flags Argument flags can be set to YIN_ATR_value values.
+ * @param[in,out] exts Extension instance to add to.
  *
  * @return LY_ERR values.
  */
 static LY_ERR
-yin_parse_simple_element(struct lyxml_context *xml_ctx, struct yin_arg_record *attrs, const char **data, enum yang_keyword kw,
+yin_parse_simple_element(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum yang_keyword kw,
                          const char **value, enum YIN_ARGUMENT arg_type, uint8_t arg_flags, struct lysp_ext_instance **exts)
 {
-    LY_CHECK_RET(yin_parse_attribute(xml_ctx, &attrs, arg_type, value, arg_flags, kw));
+    LY_CHECK_RET(yin_parse_attribute(ctx, &attrs, arg_type, value, arg_flags, kw));
     struct yin_subelement subelems[1] = {{YANG_CUSTOM, NULL, 0}};
 
-    return yin_parse_content(xml_ctx, subelems, 1, data, kw, NULL, exts);
+    return yin_parse_content(ctx, subelems, 1, data, kw, NULL, exts);
 }
 
 /**
  * @brief function to parse meta tags (description, contact, ...) eg. elements with
  * text element as child
  *
- * @param[in] xml_ctx Xml context.
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
  * @param[in] args Sized array of arguments of current element.
  * @param[in,out] data Data to read from.
  * @param[out] value Where the content of meta element should be stored.
@@ -362,7 +362,7 @@
  * @return LY_ERR values.
  */
 static LY_ERR
-yin_parse_meta_element(struct lyxml_context *xml_ctx, const char **data, enum yang_keyword elem_type,
+yin_parse_meta_element(struct yin_parser_ctx *ctx, const char **data, enum yang_keyword elem_type,
                        const char **value, struct lysp_ext_instance **exts)
 {
     assert(elem_type == YANG_ORGANIZATION || elem_type == YANG_CONTACT || elem_type == YANG_DESCRIPTION || elem_type == YANG_REFERENCE);
@@ -370,7 +370,7 @@
     struct yin_subelement subelems[2] = {{YANG_CUSTOM, NULL, 0},
                                          {YIN_TEXT, value, YIN_SUBELEM_MANDATORY | YIN_SUBELEM_UNIQUE | YIN_SUBELEM_FIRST}};
 
-    return yin_parse_content(xml_ctx, subelems, 2, data, elem_type, NULL, exts);
+    return yin_parse_content(ctx, subelems, 2, data, elem_type, NULL, exts);
 }
 
 /**
@@ -454,7 +454,7 @@
 }
 
 LY_ERR
-yin_parse_content(struct lyxml_context *xml_ctx, struct yin_subelement *subelem_info, signed char subelem_info_size,
+yin_parse_content(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info, signed char subelem_info_size,
                   const char **data, enum yang_keyword current_element, const char **text_content, struct lysp_ext_instance **exts)
 {
     LY_ERR ret = LY_SUCCESS;
@@ -467,25 +467,25 @@
     struct yin_subelement *subelem_info_rec = NULL;
     assert(is_ordered(subelem_info, subelem_info_size));
 
-    if (xml_ctx->status == LYXML_ELEM_CONTENT) {
-        ret = lyxml_get_string(xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
+    if (ctx->xml_ctx.status == LYXML_ELEM_CONTENT) {
+        ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
         /* current element has subelements as content */
         if (ret == LY_EINVAL) {
-            while (xml_ctx->status == LYXML_ELEMENT) {
-                ret = lyxml_get_element(xml_ctx, data, &prefix.value, &prefix.len, &name.value, &name.len);
+            while (ctx->xml_ctx.status == LYXML_ELEMENT) {
+                ret = lyxml_get_element(&ctx->xml_ctx, data, &prefix.value, &prefix.len, &name.value, &name.len);
                 LY_CHECK_GOTO(ret, cleanup);
                 if (!name.value) {
                     /* end of current element reached */
                     break;
                 }
-                ret = yin_load_attributes(xml_ctx, data, &subelem_attrs);
+                ret = yin_load_attributes(ctx, data, &subelem_attrs);
                 LY_CHECK_GOTO(ret, cleanup);
-                kw = yin_match_keyword(xml_ctx, name.value, name.len, prefix.value, prefix.len);
+                kw = yin_match_keyword(ctx, name.value, name.len, prefix.value, prefix.len);
 
                 /* check if this element can be child of current element */
                 subelem_info_rec = get_record(kw, subelem_info_size, subelem_info);
                 if (!subelem_info_rec) {
-                    LOGVAL_PARSER(xml_ctx, LY_VCODE_UNEXP_SUBELEM, name.len, name.value, ly_stmt2str(current_element));
+                    LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, name.len, name.value, ly_stmt2str(current_element));
                     ret = LY_EVALID;
                     goto cleanup;
                 }
@@ -493,18 +493,18 @@
                 /* TODO macro to check order */
                 /* if element is unique and already defined log error */
                 if ((subelem_info_rec->flags & YIN_SUBELEM_UNIQUE) && (subelem_info_rec->flags & YIN_SUBELEM_PARSED)) {
-                    LOGVAL_PARSER(xml_ctx, LYVE_SYNTAX_YIN, "Redefinition of %s element in %s element.", ly_stmt2str(kw), ly_stmt2str(current_element));
+                    LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YIN, "Redefinition of %s element in %s element.", ly_stmt2str(kw), ly_stmt2str(current_element));
                     return LY_EVALID;
                 }
                 if (subelem_info_rec->flags & YIN_SUBELEM_FIRST) {
-                    LY_CHECK_RET(yin_check_subelem_first_constraint(xml_ctx, subelem_info, subelem_info_size, current_element, subelem_info_rec));
+                    LY_CHECK_RET(yin_check_subelem_first_constraint(ctx, subelem_info, subelem_info_size, current_element, subelem_info_rec));
                 }
                 subelem_info_rec->flags |= YIN_SUBELEM_PARSED;
 
                 switch (kw) {
                 case YANG_CUSTOM:
                     /* TODO write function to calculate index instead of hardcoded 0 */
-                    ret = yin_parse_extension_instance(xml_ctx, &subelem_attrs, data, name2fullname(name.value, prefix.len),
+                    ret = yin_parse_extension_instance(ctx, &subelem_attrs, data, name2fullname(name.value, prefix.len),
                                                       namelen2fulllen(name.len, prefix.len),
                                                       kw2lyext_substmt(current_element), 0, exts);
                     LY_CHECK_GOTO(ret, cleanup);
@@ -516,7 +516,7 @@
                 case YANG_ANYXML:
                     break;
                 case YANG_ARGUMENT:
-                    ret = yin_parse_argument_element(xml_ctx, &subelem_attrs, data, (struct yin_argument_meta *)subelem_info_rec->dest, exts);
+                    ret = yin_parse_argument_element(ctx, &subelem_attrs, data, (struct yin_argument_meta *)subelem_info_rec->dest, exts);
                     break;
                 case YANG_AUGMENT:
                     break;
@@ -536,7 +536,7 @@
                 case YANG_DESCRIPTION:
                 case YANG_ORGANIZATION:
                 case YANG_REFERENCE:
-                    ret = yin_parse_meta_element(xml_ctx, data, kw, (const char **)subelem_info_rec->dest, exts);
+                    ret = yin_parse_meta_element(ctx, data, kw, (const char **)subelem_info_rec->dest, exts);
                     break;
                 case YANG_CONTAINER:
                     break;
@@ -553,7 +553,7 @@
                 case YANG_ERROR_MESSAGE:
                     break;
                 case YANG_EXTENSION:
-                    ret = yin_parse_extension(xml_ctx, &subelem_attrs, data, (struct lysp_ext **)subelem_info_rec->dest);
+                    ret = yin_parse_extension(ctx, &subelem_attrs, data, (struct lysp_ext **)subelem_info_rec->dest);
                     break;
                 case YANG_FEATURE:
                     break;
@@ -566,7 +566,7 @@
                 case YANG_IF_FEATURE:
                     break;
                 case YANG_IMPORT:
-                    ret = yin_parse_import(xml_ctx, &subelem_attrs, data, (struct lysp_module *)subelem_info_rec->dest);
+                    ret = yin_parse_import(ctx, &subelem_attrs, data, (struct lysp_module *)subelem_info_rec->dest);
                     break;
                 case YANG_INCLUDE:
                     break;
@@ -595,7 +595,7 @@
                 case YANG_MUST:
                     break;
                 case YANG_NAMESPACE:
-                    ret = yin_parse_simple_element(xml_ctx, subelem_attrs, data, current_element,
+                    ret = yin_parse_simple_element(ctx, subelem_attrs, data, current_element,
                                                    (const char **)subelem_info_rec->dest, YIN_ARG_URI, YIN_ARG_MANDATORY, exts);
                     break;
                 case YANG_NOTIFICATION:
@@ -611,7 +611,7 @@
                 case YANG_POSITION:
                     break;
                 case YANG_PREFIX:
-                    ret = yin_parse_simple_element(xml_ctx, subelem_attrs, data, current_element,
+                    ret = yin_parse_simple_element(ctx, subelem_attrs, data, current_element,
                                                    (const char **)subelem_info_rec->dest, YIN_ARG_VALUE, YIN_ARG_MANDATORY, exts);
                     break;
                 case YANG_PRESENCE:
@@ -625,12 +625,12 @@
                 case YANG_REVISION:
                     break;
                 case YANG_REVISION_DATE:
-                    ret = yin_parse_revision_date(xml_ctx, &subelem_attrs, data, (char *)subelem_info_rec->dest, exts);
+                    ret = yin_parse_revision_date(ctx, &subelem_attrs, data, (char *)subelem_info_rec->dest, exts);
                     break;
                 case YANG_RPC:
                     break;
                 case YANG_STATUS:
-                    ret = yin_parse_status(xml_ctx, &subelem_attrs, data, (uint16_t *)subelem_info_rec->dest, exts);
+                    ret = yin_parse_status(ctx, &subelem_attrs, data, (uint16_t *)subelem_info_rec->dest, exts);
                     break;
                 case YANG_SUBMODULE:
                     break;
@@ -651,19 +651,19 @@
                 case YANG_YANG_VERSION:
                     break;
                 case YANG_YIN_ELEMENT:
-                    ret = yin_parse_yin_element_element(xml_ctx, subelem_attrs, data, (uint16_t *)subelem_info_rec->dest, exts);
+                    ret = yin_parse_yin_element_element(ctx, subelem_attrs, data, (uint16_t *)subelem_info_rec->dest, exts);
                     break;
                 case YIN_TEXT:
-                    ret = yin_parse_content(xml_ctx, NULL, 0, data, YIN_TEXT, (const char **)subelem_info_rec->dest, NULL);
+                    ret = yin_parse_content(ctx, NULL, 0, data, YIN_TEXT, (const char **)subelem_info_rec->dest, NULL);
                     break;
                 case YIN_VALUE:
                     break;
                 default:
-                    LOGINT(xml_ctx->ctx);
+                    LOGINT(ctx->xml_ctx.ctx);
                     return LY_EINT;
                 }
                 LY_CHECK_GOTO(ret, cleanup);
-                FREE_ARRAY(xml_ctx, subelem_attrs, free_arg_rec);
+                FREE_ARRAY(ctx, subelem_attrs, free_arg_rec);
                 subelem_attrs = NULL;
                 subelem_info_rec = NULL;
             }
@@ -672,7 +672,7 @@
             /* save text content, if text_content isn't set, it's just ignored */
             if (text_content) {
                 if (dynamic) {
-                    *text_content = lydict_insert_zc(xml_ctx->ctx, out);
+                    *text_content = lydict_insert_zc(ctx->xml_ctx.ctx, out);
                     if (!*text_content) {
                         free(out);
                         return LY_EMEM;
@@ -681,46 +681,46 @@
                     if (out_len == 0) {
                         *text_content = NULL;
                     } else {
-                        *text_content = lydict_insert(xml_ctx->ctx, out, out_len);
+                        *text_content = lydict_insert(ctx->xml_ctx.ctx, out, out_len);
                     }
                 }
             }
             /* load closing element */
-            LY_CHECK_RET(lyxml_get_element(xml_ctx, data, &prefix.value, &prefix.len, &name.value, &name.len));
+            LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix.value, &prefix.len, &name.value, &name.len));
         }
 
-        LY_CHECK_RET(yin_check_subelem_mandatory_constraint(xml_ctx, subelem_info, subelem_info_size, current_element));
+        LY_CHECK_RET(yin_check_subelem_mandatory_constraint(ctx, subelem_info, subelem_info_size, current_element));
     }
 
 cleanup:
-    FREE_ARRAY(xml_ctx, subelem_attrs, free_arg_rec);
+    FREE_ARRAY(ctx, subelem_attrs, free_arg_rec);
     return ret;
 }
 
 LY_ERR
-yin_parse_revision_date(struct lyxml_context *xml_ctx, struct yin_arg_record **attrs, const char **data, char *rev,
+yin_parse_revision_date(struct yin_parser_ctx *ctx, struct yin_arg_record **attrs, const char **data, char *rev,
                         struct lysp_ext_instance **exts)
 {
     LY_ERR ret = LY_SUCCESS;
     const char *temp_rev;
     struct yin_subelement subelems[1] = {{YANG_CUSTOM, NULL, 0}};
 
-    LY_CHECK_RET(yin_parse_attribute(xml_ctx, attrs, YIN_ARG_DATE, &temp_rev, YIN_ARG_MANDATORY, YANG_REVISION_DATE));
+    LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_DATE, &temp_rev, YIN_ARG_MANDATORY, YANG_REVISION_DATE));
     LY_CHECK_RET(ret != LY_SUCCESS, ret);
-    LY_CHECK_RET(lysp_check_date((struct lys_parser_ctx *)xml_ctx, temp_rev, strlen(temp_rev), "revision-date") != LY_SUCCESS, LY_EVALID);
+    LY_CHECK_RET(lysp_check_date((struct lys_parser_ctx *)ctx, temp_rev, strlen(temp_rev), "revision-date") != LY_SUCCESS, LY_EVALID);
 
     strcpy(rev, temp_rev);
-    lydict_remove(xml_ctx->ctx, temp_rev);
+    FREE_STRING(ctx->xml_ctx.ctx, temp_rev);
 
-    return yin_parse_content(xml_ctx, subelems, 1, data, YANG_REVISION_DATE, NULL, exts);
+    return yin_parse_content(ctx, subelems, 1, data, YANG_REVISION_DATE, NULL, exts);
 }
 
 LY_ERR
-yin_parse_import(struct lyxml_context *xml_ctx, struct yin_arg_record **attrs, const char **data, struct lysp_module *mod)
+yin_parse_import(struct yin_parser_ctx *ctx, struct yin_arg_record **attrs, const char **data, struct lysp_module *mod)
 {
     struct lysp_import *imp;
     /* allocate new element in sized array for import */
-    LY_ARRAY_NEW_RET(xml_ctx->ctx, mod->imports, imp, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, mod->imports, imp, LY_EMEM);
 
     struct yin_subelement subelems[5] = {{YANG_DESCRIPTION, &imp->dsc, YIN_SUBELEM_UNIQUE},
                                          {YANG_PREFIX, &imp->prefix, YIN_SUBELEM_MANDATORY | YIN_SUBELEM_UNIQUE},
@@ -729,26 +729,26 @@
                                          {YANG_CUSTOM, NULL, 0}};
 
     /* parse import attributes  */
-    LY_CHECK_RET(yin_parse_attribute(xml_ctx, attrs, YIN_ARG_MODULE, &imp->name, YIN_ARG_MANDATORY, YANG_IMPORT));
-    LY_CHECK_RET(yin_parse_content(xml_ctx, subelems, 5, data, YANG_IMPORT, NULL, &imp->exts));
+    LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_MODULE, &imp->name, YIN_ARG_MANDATORY, YANG_IMPORT));
+    LY_CHECK_RET(yin_parse_content(ctx, subelems, 5, data, YANG_IMPORT, NULL, &imp->exts));
     /* check prefix validity */
-    LY_CHECK_RET(lysp_check_prefix((struct lys_parser_ctx *)xml_ctx, mod->imports, mod->mod->prefix, &imp->prefix), LY_EVALID);
+    LY_CHECK_RET(lysp_check_prefix((struct lys_parser_ctx *)ctx, mod->imports, mod->mod->prefix, &imp->prefix), LY_EVALID);
 
-    return yin_parse_content(xml_ctx, subelems, 5, data, YANG_IMPORT, NULL, &imp->exts);
+    return yin_parse_content(ctx, subelems, 5, data, YANG_IMPORT, NULL, &imp->exts);
 }
 
 LY_ERR
-yin_parse_status(struct lyxml_context *xml_ctx, struct yin_arg_record **attrs, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
+yin_parse_status(struct yin_parser_ctx *ctx, struct yin_arg_record **attrs, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
 {
     const char *value = NULL;
     struct yin_subelement subelems[1] = {{YANG_CUSTOM, NULL, 0}};
 
     if (*flags & LYS_STATUS_MASK) {
-        LOGVAL_PARSER(xml_ctx, LY_VCODE_DUPELEM, "status");
+        LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_DUPELEM, "status");
         return LY_EVALID;
     }
 
-    LY_CHECK_RET(yin_parse_attribute(xml_ctx, attrs, YIN_ARG_VALUE, &value, YIN_ARG_MANDATORY, YANG_STATUS));
+    LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &value, YIN_ARG_MANDATORY, YANG_STATUS));
     if (strcmp(value, "current") == 0) {
         *flags |= LYS_STATUS_CURR;
     } else if (strcmp(value, "deprecated") == 0) {
@@ -756,39 +756,39 @@
     } else if (strcmp(value, "obsolete") == 0) {
         *flags |= LYS_STATUS_OBSLT;
     } else {
-        LOGVAL_PARSER(xml_ctx, LY_VCODE_INVAL_YIN, value, "status");
-        lydict_remove(xml_ctx->ctx, value);
+        LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, value, "status");
+        FREE_STRING(ctx->xml_ctx.ctx, value);
         return LY_EVALID;
     }
-    lydict_remove(xml_ctx->ctx, value);
+    FREE_STRING(ctx->xml_ctx.ctx, value);
 
-    return yin_parse_content(xml_ctx, subelems, 1, data, YANG_STATUS, NULL, exts);
+    return yin_parse_content(ctx, subelems, 1, data, YANG_STATUS, NULL, exts);
 }
 
 LY_ERR
-yin_parse_yin_element_element(struct lyxml_context *xml_ctx, struct yin_arg_record *attrs, const char **data,
+yin_parse_yin_element_element(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
                               uint16_t *flags, struct lysp_ext_instance **exts)
 {
     const char *temp_val = NULL;
     struct yin_subelement subelems[1] = {{YANG_CUSTOM, NULL, 0}};
 
-    LY_CHECK_RET(yin_parse_attribute(xml_ctx, &attrs, YIN_ARG_VALUE, &temp_val, YIN_ARG_MANDATORY, YANG_YIN_ELEMENT));
+    LY_CHECK_RET(yin_parse_attribute(ctx, &attrs, YIN_ARG_VALUE, &temp_val, YIN_ARG_MANDATORY, YANG_YIN_ELEMENT));
     if (strcmp(temp_val, "true") == 0) {
         *flags |= LYS_YINELEM_TRUE;
     } else if (strcmp(temp_val, "false") == 0) {
         *flags |= LYS_YINELEM_FALSE;
     } else {
-        LOGVAL_PARSER(xml_ctx, LY_VCODE_INVAL_YIN, temp_val, "yin-element");
-        lydict_remove(xml_ctx->ctx, temp_val);
+        LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "yin-element");
+        FREE_STRING(ctx->xml_ctx.ctx, temp_val);
         return LY_EVALID;
     }
-    lydict_remove(xml_ctx->ctx, temp_val);
+    FREE_STRING(ctx->xml_ctx.ctx, temp_val);
 
-    return yin_parse_content(xml_ctx, subelems, 1, data, YANG_YIN_ELEMENT, NULL, exts);
+    return yin_parse_content(ctx, subelems, 1, data, YANG_YIN_ELEMENT, NULL, exts);
 }
 
 LY_ERR
-yin_parse_extension_instance(struct lyxml_context *xml_ctx, struct yin_arg_record **attrs, const char **data, const char *ext_name,
+yin_parse_extension_instance(struct yin_parser_ctx *ctx, struct yin_arg_record **attrs, const char **data, const char *ext_name,
                              int ext_name_len, LYEXT_SUBSTMT subelem, uint32_t subelem_index, struct lysp_ext_instance **exts)
 {
     LY_ERR ret = LY_SUCCESS;
@@ -800,11 +800,11 @@
     struct lysp_stmt *last_subelem = NULL, *new_subelem = NULL;
     struct yin_arg_record *iter;
 
-    LY_ARRAY_NEW_RET(xml_ctx->ctx, *exts, e, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *exts, e, LY_EMEM);
 
     e->yin = 0;
     /* store name and insubstmt info */
-    e->name = lydict_insert(xml_ctx->ctx, ext_name, ext_name_len);
+    e->name = lydict_insert(ctx->xml_ctx.ctx, ext_name, ext_name_len);
     e->insubstmt = subelem;
     e->insubstmt_index = subelem_index;
     e->yin |= LYS_YIN;
@@ -821,29 +821,29 @@
             last_subelem = new_subelem;
 
             last_subelem->flags |= LYS_YIN_ATTR;
-            last_subelem->stmt = lydict_insert(xml_ctx->ctx, iter->name, iter->name_len);
-            LY_CHECK_ERR_RET(!last_subelem->stmt, LOGMEM(xml_ctx->ctx), LY_EMEM);
+            last_subelem->stmt = lydict_insert(ctx->xml_ctx.ctx, iter->name, iter->name_len);
+            LY_CHECK_ERR_RET(!last_subelem->stmt, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
             if (iter->dynamic_content) {
-                last_subelem->arg = lydict_insert_zc(xml_ctx->ctx, iter->content);
-                LY_CHECK_ERR_RET(!last_subelem->arg, LOGMEM(xml_ctx->ctx), LY_EMEM);
+                last_subelem->arg = lydict_insert_zc(ctx->xml_ctx.ctx, iter->content);
+                LY_CHECK_ERR_RET(!last_subelem->arg, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
             } else {
-                last_subelem->arg = lydict_insert(xml_ctx->ctx, iter->content, iter->content_len);
-                LY_CHECK_ERR_RET(!last_subelem->arg, LOGMEM(xml_ctx->ctx), LY_EMEM);
+                last_subelem->arg = lydict_insert(ctx->xml_ctx.ctx, iter->content, iter->content_len);
+                LY_CHECK_ERR_RET(!last_subelem->arg, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
             }
         }
     }
 
     /* parse subelements */
-    if (xml_ctx->status == LYXML_ELEM_CONTENT) {
-        ret = lyxml_get_string(xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
+    if (ctx->xml_ctx.status == LYXML_ELEM_CONTENT) {
+        ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
         if (ret == LY_EINVAL) {
-            while (xml_ctx->status == LYXML_ELEMENT) {
-                LY_CHECK_RET(lyxml_get_element(xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
+            while (ctx->xml_ctx.status == LYXML_ELEMENT) {
+                LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
                 if (!name) {
                     /* end of extension instance reached */
                     break;
                 }
-                LY_CHECK_RET(yin_parse_element_generic(xml_ctx, name, name_len, prefix, prefix_len, data, &new_subelem));
+                LY_CHECK_RET(yin_parse_element_generic(ctx, name, name_len, prefix, prefix_len, data, &new_subelem));
                 if (!e->child) {
                     e->child = new_subelem;
                 } else {
@@ -854,16 +854,16 @@
         } else {
             /* save text content */
             if (dynamic) {
-                e->argument = lydict_insert_zc(xml_ctx->ctx, out);
+                e->argument = lydict_insert_zc(ctx->xml_ctx.ctx, out);
                 if (!e->argument) {
                     free(out);
                     return LY_EMEM;
                 }
             } else {
-                e->argument = lydict_insert(xml_ctx->ctx, out, out_len);
+                e->argument = lydict_insert(ctx->xml_ctx.ctx, out, out_len);
                 LY_CHECK_RET(!e->argument, LY_EMEM);
             }
-            LY_CHECK_RET(lyxml_get_element(xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
+            LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
             LY_CHECK_RET(name, LY_EINT);
         }
     }
@@ -872,7 +872,7 @@
 }
 
 LY_ERR
-yin_parse_element_generic(struct lyxml_context *xml_ctx, const char *name, size_t name_len, const char *prefix,
+yin_parse_element_generic(struct yin_parser_ctx *ctx, const char *name, size_t name_len, const char *prefix,
                           size_t prefix_len, const char **data, struct lysp_stmt **element)
 {
     LY_ERR ret = LY_SUCCESS;
@@ -885,15 +885,15 @@
 
     /* allocate new structure for element */
     *element = calloc(1, sizeof(**element));
-    (*element)->stmt = lydict_insert(xml_ctx->ctx, name, name_len);
-    LY_CHECK_ERR_RET(!(*element)->stmt, LOGMEM(xml_ctx->ctx), LY_EMEM);
+    (*element)->stmt = lydict_insert(ctx->xml_ctx.ctx, name, name_len);
+    LY_CHECK_ERR_RET(!(*element)->stmt, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
 
     last = (*element)->child;
     /* load attributes */
-    while(xml_ctx->status == LYXML_ATTRIBUTE) {
+    while(ctx->xml_ctx.status == LYXML_ATTRIBUTE) {
         /* add new element to linked-list */
         new = calloc(1, sizeof(*last));
-        LY_CHECK_ERR_GOTO(ret, LOGMEM(xml_ctx->ctx), err);
+        LY_CHECK_ERR_GOTO(ret, LOGMEM(ctx->xml_ctx.ctx), err);
         if (!(*element)->child) {
             /* save first */
             (*element)->child = new;
@@ -903,41 +903,41 @@
         last = new;
 
         last->flags |= LYS_YIN_ATTR;
-        ret = lyxml_get_attribute(xml_ctx, data, &temp_prefix, &prefix_len, &temp_name, &temp_name_len);
+        ret = lyxml_get_attribute(&ctx->xml_ctx, data, &temp_prefix, &prefix_len, &temp_name, &temp_name_len);
         LY_CHECK_GOTO(ret, err);
-        ret = lyxml_get_string(xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
+        ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
         LY_CHECK_GOTO(ret, err);
-        last->stmt = lydict_insert(xml_ctx->ctx, temp_name, temp_name_len);
-        LY_CHECK_ERR_GOTO(!last->stmt, LOGMEM(xml_ctx->ctx); ret = LY_EMEM, err);
+        last->stmt = lydict_insert(ctx->xml_ctx.ctx, temp_name, temp_name_len);
+        LY_CHECK_ERR_GOTO(!last->stmt, LOGMEM(ctx->xml_ctx.ctx); ret = LY_EMEM, err);
         /* attributes with prefix are ignored */
         if (!temp_prefix) {
             if (dynamic) {
-                last->arg = lydict_insert_zc(xml_ctx->ctx, out);
+                last->arg = lydict_insert_zc(ctx->xml_ctx.ctx, out);
                 if (!last->arg) {
                     free(out);
-                    LOGMEM(xml_ctx->ctx);
+                    LOGMEM(ctx->xml_ctx.ctx);
                     ret = LY_EMEM;
                     goto err;
                 }
             } else {
-                last->arg = lydict_insert(xml_ctx->ctx, out, out_len);
-                LY_CHECK_ERR_GOTO(!last->arg, LOGMEM(xml_ctx->ctx); ret = LY_EMEM, err);
+                last->arg = lydict_insert(ctx->xml_ctx.ctx, out, out_len);
+                LY_CHECK_ERR_GOTO(!last->arg, LOGMEM(ctx->xml_ctx.ctx); ret = LY_EMEM, err);
             }
         }
     }
 
     /* parse content of element */
-    ret = lyxml_get_string(xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
+    ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
     if (ret == LY_EINVAL) {
-        while (xml_ctx->status == LYXML_ELEMENT) {
+        while (ctx->xml_ctx.status == LYXML_ELEMENT) {
             /* parse subelements */
-            ret = lyxml_get_element(xml_ctx, data, &temp_prefix, &temp_prefix_len, &temp_name, &temp_name_len);
+            ret = lyxml_get_element(&ctx->xml_ctx, data, &temp_prefix, &temp_prefix_len, &temp_name, &temp_name_len);
             LY_CHECK_GOTO(ret, err);
             if (!name) {
                 /* end of element reached */
                 break;
             }
-            ret = yin_parse_element_generic(xml_ctx, temp_name, temp_name_len, temp_prefix, temp_prefix_len, data, &last->next);
+            ret = yin_parse_element_generic(ctx, temp_name, temp_name_len, temp_prefix, temp_prefix_len, data, &last->next);
             LY_CHECK_GOTO(ret, err);
             last = last->next;
         }
@@ -945,60 +945,49 @@
         /* save element content */
         if (out_len != 0) {
             if (dynamic) {
-                (*element)->arg = lydict_insert_zc(xml_ctx->ctx, out);
+                (*element)->arg = lydict_insert_zc(ctx->xml_ctx.ctx, out);
                 if (!(*element)->arg) {
                     free(out);
-                    LOGMEM(xml_ctx->ctx);
+                    LOGMEM(ctx->xml_ctx.ctx);
                     ret = LY_EMEM;
                     goto err;
                 }
             } else {
-                (*element)->arg = lydict_insert(xml_ctx->ctx, out, out_len);
-                LY_CHECK_ERR_GOTO(!(*element)->arg, LOGMEM(xml_ctx->ctx); ret = LY_EMEM, err);
+                (*element)->arg = lydict_insert(ctx->xml_ctx.ctx, out, out_len);
+                LY_CHECK_ERR_GOTO(!(*element)->arg, LOGMEM(ctx->xml_ctx.ctx); ret = LY_EMEM, err);
             }
         }
         /* read closing tag */
-        ret = lyxml_get_element(xml_ctx, data, &temp_prefix, &prefix_len, &temp_name, &temp_name_len);
+        ret = lyxml_get_element(&ctx->xml_ctx, data, &temp_prefix, &prefix_len, &temp_name, &temp_name_len);
         LY_CHECK_GOTO(ret, err);
     }
 
-    FREE_ARRAY(xml_ctx, subelem_args, free_arg_rec);
+    FREE_ARRAY(ctx, subelem_args, free_arg_rec);
     return LY_SUCCESS;
 
 err:
-    FREE_ARRAY(xml_ctx, subelem_args, free_arg_rec);
+    FREE_ARRAY(ctx, subelem_args, free_arg_rec);
     return ret;
 }
 
-/**
- * @brief Parse argument element.
- *
- * @param[in,out] xml_ctx Xml context.
- * @param[in] attrs Attributes of this element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
- * @param[in,out] arg_meta Meta information about destionation af prased data.
- * @param[in,out] exts Extension instance to add to.
- *
- * @return LY_ERR values.
- */
 LY_ERR
-yin_parse_argument_element(struct lyxml_context *xml_ctx, struct yin_arg_record **attrs, const char **data,
+yin_parse_argument_element(struct yin_parser_ctx *ctx, struct yin_arg_record **attrs, const char **data,
                            struct yin_argument_meta *arg_meta, struct lysp_ext_instance **exts)
 {
     struct yin_subelement subelems[2] = {{YANG_YIN_ELEMENT, arg_meta->flags, YIN_SUBELEM_UNIQUE},
                                          {YANG_CUSTOM, NULL, 0}};
 
-    LY_CHECK_RET(yin_parse_attribute(xml_ctx, attrs, YIN_ARG_NAME, arg_meta->argument, YIN_ARG_MANDATORY, YANG_ARGUMENT));
+    LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, arg_meta->argument, YIN_ARG_MANDATORY, YANG_ARGUMENT));
 
-    return yin_parse_content(xml_ctx, subelems, 2, data, YANG_ARGUMENT, NULL, exts);
+    return yin_parse_content(ctx, subelems, 2, data, YANG_ARGUMENT, NULL, exts);
 }
 
 LY_ERR
-yin_parse_extension(struct lyxml_context *xml_ctx, struct yin_arg_record **attrs, const char **data, struct lysp_ext **extensions)
+yin_parse_extension(struct yin_parser_ctx *ctx, struct yin_arg_record **attrs, const char **data, struct lysp_ext **extensions)
 {
     struct lysp_ext *ex;
-    LY_ARRAY_NEW_RET(xml_ctx->ctx, *extensions, ex, LY_EMEM);
-    LY_CHECK_RET(yin_parse_attribute(xml_ctx, attrs, YIN_ARG_NAME, &ex->name, YIN_ARG_MANDATORY, YANG_EXTENSION));
+    LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *extensions, ex, LY_EMEM);
+    LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &ex->name, YIN_ARG_MANDATORY, YANG_EXTENSION));
 
     struct yin_argument_meta arg_info = {&ex->flags, &ex->argument};
     struct yin_subelement subelems[5] = {{YANG_ARGUMENT, &arg_info, YIN_SUBELEM_UNIQUE},
@@ -1007,24 +996,23 @@
                                          {YANG_STATUS, &ex->flags, YIN_SUBELEM_UNIQUE},
                                          {YANG_CUSTOM, NULL, 0}};
 
-    return yin_parse_content(xml_ctx, subelems, 5, data, YANG_EXTENSION, NULL, &ex->exts);
+    return yin_parse_content(ctx, subelems, 5, data, YANG_EXTENSION, NULL, &ex->exts);
 }
 
 /**
  * @brief Parse module substatements.
  *
- * @param[in] xml_ctx Xml context.
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
  * @param[in] mod_attrs Attributes of module element.
  * @param[in,out] data Data to read from.
  * @param[out] mod Parsed module structure.
  *
  * @return LY_ERR values.
  */
-LY_ERR
-yin_parse_mod(struct lyxml_context *xml_ctx, struct yin_arg_record **mod_attrs, const char **data, struct lysp_module **mod)
+static LY_ERR
+yin_parse_mod(struct yin_parser_ctx *ctx, struct yin_arg_record **mod_attrs, const char **data, struct lysp_module **mod)
 {
-    struct yin_subelement subelems[9] = {
-                                         {YANG_CONTACT, &(*mod)->mod->contact, YIN_SUBELEM_UNIQUE},
+    struct yin_subelement subelems[9] = {{YANG_CONTACT, &(*mod)->mod->contact, YIN_SUBELEM_UNIQUE},
                                          {YANG_DESCRIPTION, &(*mod)->mod->dsc, YIN_SUBELEM_UNIQUE},
                                          {YANG_EXTENSION, &(*mod)->exts, 0},
                                          {YANG_IMPORT, *mod, 0},
@@ -1034,9 +1022,9 @@
                                          {YANG_REFERENCE, &(*mod)->mod->ref, YIN_SUBELEM_UNIQUE},
                                          {YANG_CUSTOM, NULL, 0}};
 
-    LY_CHECK_RET(yin_parse_attribute(xml_ctx, mod_attrs, YIN_ARG_NAME, &(*mod)->mod->name, YIN_ARG_MANDATORY, YANG_MODULE));
+    LY_CHECK_RET(yin_parse_attribute(ctx, mod_attrs, YIN_ARG_NAME, &(*mod)->mod->name, YIN_ARG_MANDATORY, YANG_MODULE));
 
-    return yin_parse_content(xml_ctx, subelems, 9, data, YANG_MODULE, NULL, &(*mod)->exts);
+    return yin_parse_content(ctx, subelems, 9, data, YANG_MODULE, NULL, &(*mod)->exts);
 }
 
 LY_ERR
@@ -1044,30 +1032,32 @@
 {
     LY_ERR ret = LY_SUCCESS;
     enum yang_keyword kw = YANG_NONE;
-    struct lys_parser_ctx parser_ctx;
-    struct lyxml_context *xml_ctx = (struct lyxml_context *)&parser_ctx;
     struct lysp_module *mod_p = NULL;
     const char *prefix, *name;
     size_t prefix_len, name_len;
+
     struct yin_arg_record *args = NULL;
 
-    /* initialize xml context */
-    memset(&parser_ctx, 0, sizeof parser_ctx);
-    xml_ctx->ctx = ctx;
-    xml_ctx->line = 1;
+    struct yin_parser_ctx yin_ctx;
+
+    /* initialize context */
+    memset(&yin_ctx, 0, sizeof yin_ctx);
+    yin_ctx.xml_ctx.ctx = ctx;
+    yin_ctx.xml_ctx.line = 1;
+
 
     /* check submodule */
-    ret = lyxml_get_element(xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
+    ret = lyxml_get_element(&yin_ctx.xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
     LY_CHECK_GOTO(ret, cleanup);
-    ret = yin_load_attributes(xml_ctx, &data, &args);
+    ret = yin_load_attributes(&yin_ctx, &data, &args);
     LY_CHECK_GOTO(ret, cleanup);
-    kw = yin_match_keyword(xml_ctx, name, name_len, prefix, prefix_len);
+    kw = yin_match_keyword(&yin_ctx, name, name_len, prefix, prefix_len);
     if (kw == YANG_SUBMODULE) {
         LOGERR(ctx, LY_EDENIED, "Input data contains submodule which cannot be parsed directly without its main module.");
         ret = LY_EINVAL;
         goto cleanup;
     } else if (kw != YANG_MODULE) {
-        LOGVAL_PARSER(xml_ctx, LYVE_SYNTAX, "Invalid keyword \"%s\", expected \"module\" or \"submodule\".",
+        LOGVAL_PARSER((struct lys_parser_ctx *)&yin_ctx, LYVE_SYNTAX, "Invalid keyword \"%s\", expected \"module\" or \"submodule\".",
                     ly_stmt2str(kw));
         ret = LY_EVALID;
         goto cleanup;
@@ -1080,7 +1070,7 @@
     mod_p->parsing = 1;
 
     /* parse module substatements */
-    ret = yin_parse_mod(xml_ctx, &args, &data, &mod_p);
+    ret = yin_parse_mod(&yin_ctx, &args, &data, &mod_p);
     LY_CHECK_GOTO(ret, cleanup);
 
     mod_p->parsing = 0;
@@ -1090,7 +1080,7 @@
     if (ret != LY_SUCCESS) {
         lysp_module_free(mod_p);
     }
-    FREE_ARRAY(xml_ctx, args, free_arg_rec);
-    lyxml_context_clear(xml_ctx);
+    FREE_ARRAY(&yin_ctx, args, free_arg_rec);
+    lyxml_context_clear(&yin_ctx.xml_ctx);
     return ret;
 }