libyang REFACTOR printer -> in, parser -> out
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1251dc4..88d05a8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -110,7 +110,7 @@
     src/parser_xml.c
     src/parser_json.c
     src/parser_lyb.c
-    src/printer.c
+    src/out.c
     src/printer_data.c
     src/printer_xml.c
     src/printer_json.c
@@ -121,11 +121,10 @@
     src/tree_schema.c
     src/tree_schema_free.c
     src/tree_schema_helpers.c
-    src/parser.c
+    src/in.c
     src/parser_yang.c
     src/parser_yin.c
     src/parser_stmt.c
-    src/printer.c
     src/printer_schema.c
     src/printer_yang.c
     src/printer_yin.c
@@ -151,12 +150,12 @@
     src/context.h
     src/dict.h
     src/log.h
-    src/parser.h
+    src/in.h
     src/parser_data.h
     src/parser_schema.h
     src/plugins_exts.h
     src/plugins_types.h
-    src/printer.h
+    src/out.h
     src/printer_data.h
     src/printer_schema.h
     src/set.h
diff --git a/src/context.c b/src/context.c
index 6b06acc..5f91f38 100644
--- a/src/context.c
+++ b/src/context.c
@@ -28,7 +28,7 @@
 #include "common.h"
 #include "compat.h"
 #include "hash_table.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_data.h"
 #include "path.h"
 #include "plugins_types.h"
diff --git a/src/parser.c b/src/in.c
similarity index 98%
rename from src/parser.c
rename to src/in.c
index 36c7928..f20195e 100644
--- a/src/parser.c
+++ b/src/in.c
@@ -1,9 +1,9 @@
 /**
- * @file printer.c
+ * @file in.c
  * @author Radek Krejci <rkrejci@cesnet.cz>
- * @brief Generic libyang printers functions.
+ * @brief libyang input functions.
  *
- * Copyright (c) 2015 - 2019 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2020 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.
@@ -14,7 +14,8 @@
 
 #define _GNU_SOURCE
 
-#include "parser.h"
+#include "in.h"
+#include "in_internal.h"
 
 #include <errno.h>
 #include <fcntl.h>
diff --git a/src/parser.h b/src/in.h
similarity index 97%
rename from src/parser.h
rename to src/in.h
index 1965f82..f176c7a 100644
--- a/src/parser.h
+++ b/src/in.h
@@ -1,7 +1,7 @@
 /**
- * @file parser.h
+ * @file in.h
  * @author Radek Krejci <rkrejci@cesnet.cz>
- * @brief Generic libyang parsers structures and functions
+ * @brief libyang input structures and functions
  *
  * Copyright (c) 2020 CESNET, z.s.p.o.
  *
@@ -12,8 +12,8 @@
  *     https://opensource.org/licenses/BSD-3-Clause
  */
 
-#ifndef LY_PARSER_H_
-#define LY_PARSER_H_
+#ifndef LY_IN_H_
+#define LY_IN_H_
 
 #include <stdio.h>
 
@@ -24,9 +24,9 @@
 #endif
 
 /**
- * @page howtoParsers Input Processing
+ * @page howtoInput Input Processing
  *
- * libyang provides a mechanism to generalize work with the inputs (and [outputs](@ref howtoPrinters)) of
+ * libyang provides a mechanism to generalize work with the inputs (and [outputs](@ref howtoOutput)) of
  * the different types. The ::ly_in handler can be created providing necessary information connected with the specific
  * input type and then used throughout the parser functions processing the input data. Using a generic input handler avoids
  * need to have a set of functions for each parser functionality and results in simpler API.
@@ -221,4 +221,4 @@
 }
 #endif
 
-#endif /* LY_PARSER_H_ */
+#endif /* LY_IN_H_ */
diff --git a/src/in_internal.h b/src/in_internal.h
new file mode 100644
index 0000000..684487f
--- /dev/null
+++ b/src/in_internal.h
@@ -0,0 +1,61 @@
+/**
+ * @file in_internal.h
+ * @author Radek Krejci <rkrejci@cesnet.cz>
+ * @brief Internal structures and functions for libyang parsers
+ *
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ *     https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#ifndef LY_IN_INTERNAL_H_
+#define LY_IN_INTERNAL_H_
+
+#include "in.h"
+#include "tree_schema_internal.h"
+
+/**
+ * @brief Parser input structure specifying where the data are read.
+ */
+struct ly_in {
+    LY_IN_TYPE type;        /**< type of the output to select the output method */
+    const char *current;    /**< Current position in the input data */
+    const char *func_start; /**< Input data position when the last parser function was executed */
+    const char *start;      /**< Input data start */
+    size_t length;          /**< mmap() length (if used) */
+    union {
+        int fd;             /**< file descriptor for LY_IN_FD type */
+        FILE *f;            /**< file structure for LY_IN_FILE and LY_IN_FILEPATH types */
+        struct {
+            int fd;         /**< file descriptor for LY_IN_FILEPATH */
+            char *filepath; /**< stored original filepath */
+        } fpath;            /**< filepath structure for LY_IN_FILEPATH */
+    } method;               /**< type-specific information about the output */
+};
+
+/**
+ * @brief Read bytes from an input.
+ *
+ * @param[in] in Input structure.
+ * @param[in] buf Destination buffer.
+ * @param[in] count Number of bytes to read.
+ * @return LY_SUCCESS on success,
+ * @return LY_EDENIED on EOF.
+ */
+LY_ERR ly_in_read(struct ly_in *in, void *buf, size_t count);
+
+/**
+ * @brief Just skip bytes in an input.
+ *
+ * @param[in] in Input structure.
+ * @param[in] count Number of bytes to skip.
+ * @return LY_SUCCESS on success,
+ * @return LY_EDENIED on EOF.
+ */
+LY_ERR ly_in_skip(struct ly_in *in, size_t count);
+
+#endif /* LY_IN_INTERNAL_H_ */
diff --git a/src/json.c b/src/json.c
index e304709..d7bf050 100644
--- a/src/json.c
+++ b/src/json.c
@@ -21,7 +21,7 @@
 
 #include "common.h"
 #include "json.h"
-#include "parser_internal.h"
+#include "in_internal.h"
 
 #define JSON_PUSH_STATUS_RET(CTX, STATUS) \
     LY_CHECK_RET(ly_set_add(&CTX->status, (void*)STATUS, 1, NULL))
diff --git a/src/libyang.h b/src/libyang.h
index a5570e6..6cc4a15 100644
--- a/src/libyang.h
+++ b/src/libyang.h
@@ -24,11 +24,11 @@
 #include "context.h"
 #include "dict.h"
 #include "log.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_data.h"
 #include "parser_schema.h"
 #include "plugins_types.h"
-#include "printer.h"
+#include "out.h"
 #include "printer_data.h"
 #include "printer_schema.h"
 #include "set.h"
@@ -91,8 +91,8 @@
  * - @subpage howtoLogger
  * - @subpage howtoThreads
  * - @subpage howtoContext
- * - @subpage howtoParsers
- * - @subpage howtoPrinters
+ * - @subpage howtoInput
+ * - @subpage howtoOutput
  * - @subpage howtoSchema
  * - @subpage howtoData
  * - @subpage howtoXPath
diff --git a/src/printer.c b/src/out.c
similarity index 98%
rename from src/printer.c
rename to src/out.c
index 174f48e..0d2a46b 100644
--- a/src/printer.c
+++ b/src/out.c
@@ -1,9 +1,9 @@
 /**
- * @file printer.c
+ * @file out.c
  * @author Radek Krejci <rkrejci@cesnet.cz>
- * @brief Generic libyang printers functions.
+ * @brief libyang output functions.
  *
- * Copyright (c) 2015 - 2019 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2020 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.
@@ -14,7 +14,8 @@
 
 #define _GNU_SOURCE
 
-#include "printer.h"
+#include "out.h"
+#include "out_internal.h"
 
 #include <assert.h>
 #include <errno.h>
diff --git a/src/printer.h b/src/out.h
similarity index 97%
rename from src/printer.h
rename to src/out.h
index b3de26a..c52fcb8 100644
--- a/src/printer.h
+++ b/src/out.h
@@ -1,9 +1,9 @@
 /**
- * @file printer.h
+ * @file out.h
  * @author Radek Krejci <rkrejci@cesnet.cz>
- * @brief Generic libyang printer structures and functions
+ * @brief libyang output structures and functions
  *
- * Copyright (c) 2015-2019 CESNET, z.s.p.o.
+ * Copyright (c) 2015-2020 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.
@@ -12,8 +12,8 @@
  *     https://opensource.org/licenses/BSD-3-Clause
  */
 
-#ifndef LY_PRINTER_H_
-#define LY_PRINTER_H_
+#ifndef LY_OUT_H_
+#define LY_OUT_H_
 
 #include <stdio.h>
 #include <unistd.h>
@@ -25,9 +25,9 @@
 #endif
 
 /**
- * @page howtoPrinters Output Processing
+ * @page howtoOutput Output Processing
  *
- * libyang provides a mechanism to generalize work with the outputs (and [inputs](@ref howtoParsers)) of
+ * libyang provides a mechanism to generalize work with the outputs (and [inputs](@ref howtoInput)) of
  * the different types. The ::ly_out handler can be created providing necessary information connected with the specific
  * output type and then used throughout the printers functions. The API allows to combine output from libyang (data or schema)
  * printers and output directly provided by the caller (via ::ly_print() or ::ly_write()).
@@ -301,4 +301,4 @@
 }
 #endif
 
-#endif /* LY_PRINTER_H_ */
+#endif /* LY_OUT_H_ */
diff --git a/src/out_internal.h b/src/out_internal.h
new file mode 100644
index 0000000..e157734
--- /dev/null
+++ b/src/out_internal.h
@@ -0,0 +1,117 @@
+/**
+ * @file out_internal.h
+ * @author Radek Krejci <rkrejci@cesnet.cz>
+ * @brief Internal structures and functions for libyang
+ *
+ * Copyright (c) 2015-2020 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.
+ * You may obtain a copy of the License at
+ *
+ *     https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#ifndef LY_OUT_INTERNAL_H_
+#define LY_OUT_INTERNAL_H_
+
+#include "out.h"
+#include "printer_data.h"
+#include "printer_schema.h"
+
+/**
+ * @brief Printer output structure specifying where the data are printed.
+ */
+struct ly_out {
+    LY_OUT_TYPE type;     /**< type of the output to select the output method */
+    union {
+        int fd;          /**< file descriptor for LY_OUT_FD type */
+        FILE *f;         /**< file structure for LY_OUT_FILE, LY_OUT_FDSTREAM and LY_OUT_FILEPATH types */
+        struct {
+            FILE *f;          /**< file stream from the original file descriptor, variable is mapped to the LY_OUT_FILE's f */
+            int fd;           /**< original file descriptor, which was not used directly because of missing vdprintf() */
+        } fdstream;      /**< structure for LY_OUT_FDSTREAM type, which is LY_OUT_FD when vdprintf() is missing */
+        struct {
+            FILE *f;          /**< file structure for LY_OUT_FILEPATH, variable is mapped to the LY_OUT_FILE's f */
+            char *filepath;   /**< stored original filepath */
+        } fpath;         /**< filepath structure for LY_OUT_FILEPATH */
+        struct {
+            char **buf;       /**< storage for the pointer to the memory buffer to store the output */
+            size_t len;       /**< number of used bytes in the buffer */
+            size_t size;      /**< allocated size of the buffer */
+        } mem;           /**< memory buffer information for LY_OUT_MEMORY type */
+        struct {
+            ssize_t (*func)(void *arg, const void *buf, size_t count); /**< callback function */
+            void *arg;        /**< optional argument for the callback function */
+        } clb;           /**< printer callback for LY_OUT_CALLBACK type */
+    } method;            /**< type-specific information about the output */
+
+    /* LYB only */
+    char *buffered;      /**< additional buffer for holes */
+    size_t buf_len;      /**< number of used bytes in the additional buffer for holes */
+    size_t buf_size;     /**< allocated size of the buffer for holes */
+    size_t hole_count;   /**< hole counter */
+
+    size_t printed;      /**< Total number of printed bytes */
+    size_t func_printed; /**< Number of bytes printed by the last function */
+};
+
+/**
+ * @brief Check whether the node should even be printed.
+ *
+ * @param[in] node Node to check.
+ * @param[in] options Printer options.
+ * @return false (no, it should not be printed) or true (yes, it is supposed to be printed)
+ */
+ly_bool ly_should_print(const struct lyd_node *node, uint32_t options);
+
+/**
+ * @brief Generic printer of the given format string into the specified output.
+ *
+ * Does not reset printed bytes. Adds to printed bytes.
+ *
+ * @param[in] out Output specification.
+ * @param[in] format Format string to be printed.
+ * @return LY_ERR value.
+ */
+LY_ERR ly_print_(struct ly_out *out, const char *format, ...);
+
+/**
+ * @brief Generic printer of the given string buffer into the specified output.
+ *
+ * Does not reset printed bytes. Adds to printed bytes.
+ *
+ * @param[in] out Output specification.
+ * @param[in] buf Memory buffer with the data to print.
+ * @param[in] len Length of the data to print in the @p buf.
+ * @return LY_ERR value.
+ */
+LY_ERR ly_write_(struct ly_out *out, const char *buf, size_t len);
+
+/**
+ * @brief Create a hole in the output data that will be filled later.
+ *
+ * Adds printed bytes.
+ *
+ * @param[in] out Output specification.
+ * @param[in] len Length of the created hole.
+ * @param[out] position Position of the hole, value must be later provided to the ::ly_write_skipped() call.
+ * @return LY_ERR value.
+ */
+LY_ERR ly_write_skip(struct ly_out *out, size_t len, size_t *position);
+
+/**
+ * @brief Write data into the hole at given position.
+ *
+ * Does not change printed bytes.
+ *
+ * @param[in] out Output specification.
+ * @param[in] position Position of the hole to fill, the value was provided by ::ly_write_skip().
+ * @param[in] buf Memory buffer with the data to print.
+ * @param[in] len Length of the data to print in the @p buf. Not that the length must correspond
+ * to the len value specified in the corresponding ::ly_write_skip() call.
+ * @return LY_ERR value.
+ */
+LY_ERR ly_write_skipped(struct ly_out *out, size_t position, const char *buf, size_t len);
+
+#endif /* LY_OUT_INTERNAL_H_ */
diff --git a/src/parser_data.h b/src/parser_data.h
index 02c8806..d54a173 100644
--- a/src/parser_data.h
+++ b/src/parser_data.h
@@ -154,6 +154,9 @@
 #define LYD_PARSE_LYB_MOD_UPDATE  0x200000  /**< Only for LYB format, allow parsing data printed using a specific module
                                                  revision to be loaded even with a module with the same name but newer
                                                  revision. */
+
+#define LYD_PARSE_OPTS_MASK 0xFFFF0000      /**< Mask for all the LYD_PARSE_ options. */
+
 /** @} dataparseroptions */
 
 /**
@@ -179,8 +182,10 @@
  *
  * @{
  */
-#define LYD_VALIDATE_NO_STATE     0x0001    /**< Consider state data not allowed and raise an error if they are found. */
-#define LYD_VALIDATE_PRESENT      0x0002    /**< Validate only modules whose data actually exist. */
+#define LYD_VALIDATE_NO_STATE   0x0001      /**< Consider state data not allowed and raise an error if they are found. */
+#define LYD_VALIDATE_PRESENT    0x0002      /**< Validate only modules whose data actually exist. */
+
+#define LYD_VALIDATE_OPTS_MASK  0x0000FFFF  /**< Mask for all the LYD_VALIDATE_* options. */
 
 /** @} datavalidationoptions */
 
@@ -275,7 +280,7 @@
  * @brief Parse (and validate) data from the input handler as a YANG RPC/action invocation.
  *
  * In case o LYD_XML @p format, the \<rpc\> envelope element is accepted if present. It is [checked](https://tools.ietf.org/html/rfc6241#section-4.1), an opaq
- * data node (lyd_node_opaq) is created and all its XML attributes are parsed and inserted into the node. As a content of the enveloper, an RPC data or
+ * data node (lyd_node_opaq) is created and all its XML attributes are parsed and inserted into the node. As a content of the envelope, an RPC data or
  * \<action\> envelope element is expected. The \<action\> envelope element is also [checked](https://tools.ietf.org/html/rfc7950#section-7.15.2) and parsed as
  * the \<rpc\> envelope. Inside the \<action\> envelope, only an action data are expected.
  *
diff --git a/src/parser_internal.h b/src/parser_internal.h
index 794dfc8..500068a 100644
--- a/src/parser_internal.h
+++ b/src/parser_internal.h
@@ -15,21 +15,11 @@
 #ifndef LY_PARSER_INTERNAL_H_
 #define LY_PARSER_INTERNAL_H_
 
-#include "parser.h"
 #include "plugins_types.h"
 #include "tree_schema_internal.h"
 
-/**
- * @brief Mask for checking LYD_PARSE_ options (@ref dataparseroptions)
- */
-#define LYD_PARSE_OPTS_MASK    0xFFFF0000
-
-/**
- * @brief Mask for checking LYD_VALIDATE_ options (@ref datavalidationoptions)
- */
-#define LYD_VALIDATE_OPTS_MASK 0x0000FFFF
-
 struct lyd_ctx;
+struct ly_in;
 
 /**
  * @brief Callback for lyd_ctx to free the structure
@@ -64,51 +54,11 @@
 };
 
 /**
- * @brief Parser input structure specifying where the data are read.
- */
-struct ly_in {
-    LY_IN_TYPE type;        /**< type of the output to select the output method */
-    const char *current;    /**< Current position in the input data */
-    const char *func_start; /**< Input data position when the last parser function was executed */
-    const char *start;      /**< Input data start */
-    size_t length;          /**< mmap() length (if used) */
-    union {
-        int fd;             /**< file descriptor for LY_IN_FD type */
-        FILE *f;            /**< file structure for LY_IN_FILE and LY_IN_FILEPATH types */
-        struct {
-            int fd;         /**< file descriptor for LY_IN_FILEPATH */
-            char *filepath; /**< stored original filepath */
-        } fpath;            /**< filepath structure for LY_IN_FILEPATH */
-    } method;               /**< type-specific information about the output */
-};
-
-/**
  * @brief Common part of the lyd_ctx_free_t callbacks.
  */
 void lyd_ctx_free(struct lyd_ctx *);
 
 /**
- * @brief Read bytes from an input.
- *
- * @param[in] in Input structure.
- * @param[in] buf Destination buffer.
- * @param[in] count Number of bytes to read.
- * @return LY_SUCCESS on success,
- * @return LY_EDENIED on EOF.
- */
-LY_ERR ly_in_read(struct ly_in *in, void *buf, size_t count);
-
-/**
- * @brief Just skip bytes in an input.
- *
- * @param[in] in Input structure.
- * @param[in] count Number of bytes to skip.
- * @return LY_SUCCESS on success,
- * @return LY_EDENIED on EOF.
- */
-LY_ERR ly_in_skip(struct ly_in *in, size_t count);
-
-/**
  * @brief Parse submodule from YANG data.
  * @param[in,out] ctx Parser context.
  * @param[in] ly_ctx Context of YANG schemas.
@@ -156,6 +106,166 @@
         struct ly_in *in, struct lysp_submodule **submod);
 
 /**
+ * @brief Parse XML string as YANG data tree.
+ *
+ * @param[in] ctx libyang context
+ * @param[in] in Input structure.
+ * @param[in] parse_options Options for parser, see @ref dataparseroptions.
+ * @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
+ * @param[out] tree_p Parsed data tree. Note that NULL can be a valid result.
+ * @param[out] lydctx_p Data parser context to finish validation.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_xml_data(const struct ly_ctx *ctx, struct ly_in *in, uint32_t parse_options, uint32_t validate_options,
+        struct lyd_node **tree_p, struct lyd_ctx **lydctx_p);
+
+/**
+ * @brief Parse XML string as YANG RPC/action invocation.
+ *
+ * Optional \<rpc\> envelope element is accepted if present. It is [checked](https://tools.ietf.org/html/rfc6241#section-4.1) and all
+ * its XML attributes are parsed. As a content of the envelope, an RPC data or \<action\> envelope element is expected. The \<action\> envelope element is
+ * also [checked](https://tools.ietf.org/html/rfc7950#section-7.15.2) and then an action data is expected as a content of this envelope.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full RPC/action tree.
+ * @param[out] op_p Optional pointer to the actual operation. Useful mainly for action.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_xml_rpc(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
+
+/**
+ * @brief Parse XML string as YANG notification.
+ *
+ * Optional \<notification\> envelope element, if present, is [checked](https://tools.ietf.org/html/rfc5277#page-25)
+ * and parsed. Specifically, its namespace and the child \<eventTime\> element and its value.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full notification tree.
+ * @param[out] op_p Optional pointer to the actual notification. Useful mainly for nested notifications.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_xml_notif(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **ntf_p);
+
+/**
+ * @brief Parse XML string as YANG RPC/action reply.
+ *
+ * Optional \<rpc-reply\> envelope element, if present, is [checked](https://tools.ietf.org/html/rfc6241#section-4.2)
+ * and all its XML attributes parsed.
+ *
+ * @param[in] request Data tree of the RPC/action request.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full reply tree. It always includes duplicated operation and parents of the @p request.
+ * @param[out] op_p Optional pointer to the reply operation. Useful mainly for action.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_xml_reply(const struct lyd_node *request, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
+
+/**
+ * @brief Parse JSON string as YANG data tree.
+ *
+ * @param[in] ctx libyang context
+ * @param[in] in Input structure.
+ * @param[in] parse_options Options for parser, see @ref dataparseroptions.
+ * @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
+ * @param[out] tree_p Parsed data tree. Note that NULL can be a valid result.
+ * @param[out] lydctx_p Data parser context to finish validation.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_json_data(const struct ly_ctx *ctx, struct ly_in *in, uint32_t parse_options, uint32_t validate_options,
+        struct lyd_node **tree_p, struct lyd_ctx **lydctx_p);
+
+/**
+ * @brief Parse JSON string as YANG notification.
+ *
+ * Optional top-level "notification" envelope object, if present, is [checked](https://tools.ietf.org/html/rfc5277#page-25)
+ * and parsed. Specifically the child "eventTime" member and its value.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full notification tree.
+ * @param[out] ntf_p Optional pointer to the actual notification. Useful mainly for nested notifications.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_json_notif(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **ntf_p);
+
+/**
+ * @brief Parse JSON string as YANG RPC/action invocation.
+ *
+ * Optional top-level "rpc" envelope object, if present is is [checked](https://tools.ietf.org/html/rfc6241#section-4.1) and the parser
+ * goes inside for the content, which is an RPC data or "action" envelope objects. The "action" envelope object is
+ * also [checked](https://tools.ietf.org/html/rfc7950#section-7.15.2) and then an action data is expected as a content of this envelope.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full RPC/action tree.
+ * @param[out] op_p Optional pointer to the actual operation. Useful mainly for action.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_json_rpc(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
+
+/**
+ * @brief Parse JSON string as YANG RPC/action reply.
+ *
+ * Optional "rpc-reply" envelope object, if present, is [checked](https://tools.ietf.org/html/rfc6241#section-4.2).
+ *
+ * @param[in] request Data tree of the RPC/action request.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full reply tree. It always includes duplicated operation and parents of the @p request.
+ * @param[out] op_p Optional pointer to the reply operation. Useful mainly for action.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_json_reply(const struct lyd_node *request, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
+
+/**
+ * @brief Parse binary data as YANG data tree.
+ *
+ * @param[in] ctx libyang context
+ * @param[in] in Input structure.
+ * @param[in] parse_options Options for parser, see @ref dataparseroptions.
+ * @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
+ * @param[out] tree_p Parsed data tree. Note that NULL can be a valid result.
+ * @param[out] lydctx_p Data parser context to finish validation.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_lyb_data(const struct ly_ctx *ctx, struct ly_in *in, uint32_t parse_options, uint32_t validate_options,
+        struct lyd_node **tree_p, struct lyd_ctx **lydctx_p);
+
+/**
+ * @brief Parse binary data as YANG RPC/action invocation.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full RPC/action tree.
+ * @param[out] op_p Optional pointer to the actual operation. Useful mainly for action.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_lyb_rpc(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
+
+/**
+ * @brief Parse binary data as YANG notification.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full notification tree.
+ * @param[out] ntf_p Optional pointer to the actual notification. Useful mainly for nested notifications.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_lyb_notif(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **ntf_p);
+
+/**
+ * @brief Parse binary data as YANG RPC/action reply.
+ *
+ * @param[in] request Data tree of the RPC/action request.
+ * @param[in] in Input structure.
+ * @param[out] tree_p Parsed full reply tree. It always includes duplicated operation and parents of the @p request.
+ * @param[out] op_p Optional pointer to the reply operation. Useful mainly for action.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_parse_lyb_reply(const struct lyd_node *request, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
+
+/**
  * @brief Check that a data node representing the @p snode is suitable based on options.
  *
  * @param[in] lydctx Common data parsers context.
diff --git a/src/parser_json.c b/src/parser_json.c
index f9cf274..4c3e2aa 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -21,6 +21,7 @@
 #include "common.h"
 #include "compat.h"
 #include "context.h"
+#include "in_internal.h"
 #include "json.h"
 #include "parser_internal.h"
 #include "tree_data.h"
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index 84d9957..2f4a0c7 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -24,6 +24,7 @@
 #include "compat.h"
 #include "context.h"
 #include "dict.h"
+#include "in_internal.h"
 #include "log.h"
 #include "parser_data.h"
 #include "parser_internal.h"
diff --git a/src/parser_schema.h b/src/parser_schema.h
index 957370f..57a3928 100644
--- a/src/parser_schema.h
+++ b/src/parser_schema.h
@@ -63,7 +63,7 @@
  * are resolved, groupings are instantiated, types are resolved (and compiled by joining all the relevant restrictions
  * when derived from another types) and many other syntactical checks are done.
  *
- * There is the main parsing function ::lys_parse() wirking with the libyang [input handler](@ref howtoParsers). However,
+ * There is the main parsing function ::lys_parse() wirking with the libyang [input handler](@ref howtoInput). However,
  * to simplify some of the usecases, it is also possible to use other functions accepting input data from various sources.
  *
  * Functions List
diff --git a/src/parser_stmt.c b/src/parser_stmt.c
index c694fe9..b4e6045 100644
--- a/src/parser_stmt.c
+++ b/src/parser_stmt.c
@@ -22,7 +22,7 @@
 #include "common.h"
 #include "dict.h"
 #include "log.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_schema.h"
 #include "path.h"
 #include "schema_compile.h"
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 5ceb778..8647e69 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -19,6 +19,7 @@
 
 #include "common.h"
 #include "context.h"
+#include "in_internal.h"
 #include "log.h"
 #include "parser_data.h"
 #include "parser_internal.h"
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 4e22218..dbd3880 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -24,6 +24,7 @@
 #include "common.h"
 #include "context.h"
 #include "dict.h"
+#include "in_internal.h"
 #include "log.h"
 #include "parser_schema.h"
 #include "path.h"
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 407c325..87e3206 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -11,8 +11,6 @@
  *
  *     https://opensource.org/licenses/BSD-3-Clause
  */
-#include "parser_yin.h"
-
 #include <assert.h>
 #include <ctype.h>
 #include <errno.h>
@@ -25,6 +23,7 @@
 #include "common.h"
 #include "context.h"
 #include "dict.h"
+#include "in_internal.h"
 #include "parser_internal.h"
 #include "parser_schema.h"
 #include "path.h"
@@ -43,6 +42,20 @@
  */
 #define IS_YIN_NS(ns) (strcmp(ns, YIN_NS_URI) == 0)
 
+enum yin_argument {
+    YIN_ARG_UNKNOWN = 0,   /**< parsed argument can not be matched with any supported yin argument keyword */
+    YIN_ARG_NAME,          /**< argument name */
+    YIN_ARG_TARGET_NODE,   /**< argument target-node */
+    YIN_ARG_MODULE,        /**< argument module */
+    YIN_ARG_VALUE,         /**< argument value */
+    YIN_ARG_TEXT,          /**< argument text */
+    YIN_ARG_CONDITION,     /**< argument condition */
+    YIN_ARG_URI,           /**< argument uri */
+    YIN_ARG_DATE,          /**< argument data */
+    YIN_ARG_TAG,           /**< argument tag */
+    YIN_ARG_NONE           /**< empty (special value) */
+};
+
 const char * const yin_attr_list[] = {
     [YIN_ARG_NAME] = "name",
     [YIN_ARG_TARGET_NODE] = "target-node",
@@ -56,6 +69,98 @@
     [YIN_ARG_NONE] = "none",
 };
 
+#define yin_attr2str(STMT) yin_attr_list[STMT]
+
+#define VALID_VALS1 " Only valid value is \"%s\"."
+#define VALID_VALS2 " Valid values are \"%s\" and \"%s\"."
+#define VALID_VALS3 " Valid values are \"%s\", \"%s\" and \"%s\"."
+#define VALID_VALS4 " Valid values are \"%s\", \"%s\", \"%s\" and \"%s\"."
+
+/* shortcut to determin if keyword can in general be subelement of deviation regardles of it's type */
+#define isdevsub(kw) (kw == LY_STMT_CONFIG || kw == LY_STMT_DEFAULT || kw == LY_STMT_MANDATORY || \
+                      kw == LY_STMT_MAX_ELEMENTS || kw == LY_STMT_MIN_ELEMENTS ||              \
+                      kw == LY_STMT_MUST || kw == LY_STMT_TYPE || kw == LY_STMT_UNIQUE ||         \
+                      kw == LY_STMT_UNITS || kw == LY_STMT_EXTENSION_INSTANCE)
+
+/* flags to set constraints of subelements */
+#define YIN_SUBELEM_MANDATORY   0x01    /**< is set when subelement is mandatory */
+#define YIN_SUBELEM_UNIQUE      0x02    /**< is set when subelement is unique */
+#define YIN_SUBELEM_FIRST       0x04    /**< is set when subelement is actually yang argument mapped to yin element */
+#define YIN_SUBELEM_VER2        0x08    /**< subelemnt is allowed only in modules with version at least 2 (YANG 1.1) */
+
+#define YIN_SUBELEM_PARSED      0x80    /**< is set during parsing when given subelement is encountered for the first
+                                             time to simply check validity of given constraints */
+
+struct yin_subelement {
+    enum ly_stmt type;      /**< type of keyword */
+    void *dest;             /**< meta infromation passed to responsible function (mostly information about where parsed subelement should be stored) */
+    uint16_t flags;         /**< describes constraints of subelement can be set to YIN_SUBELEM_MANDATORY, YIN_SUBELEM_UNIQUE, YIN_SUBELEM_FIRST, YIN_SUBELEM_VER2, and YIN_SUBELEM_DEFAULT_TEXT */
+};
+
+/* Meta information passed to yin_parse_argument function,
+   holds information about where content of argument element will be stored. */
+struct yin_argument_meta {
+    uint16_t *flags;        /**< Argument flags */
+    const char **argument;  /**< Argument value */
+};
+
+/**
+ * @brief Meta information passed to functions working with tree_schema,
+ *        that require additional information about parent node.
+ */
+struct tree_node_meta {
+    struct lysp_node *parent;       /**< parent node */
+    struct lysp_node **nodes;    /**< linked list of siblings */
+};
+
+/**
+ * @brief Meta information passed to yin_parse_import function.
+ */
+struct import_meta {
+    const char *prefix;             /**< module prefix. */
+    struct lysp_import **imports;   /**< imports to add to. */
+};
+
+/**
+ * @brief Meta information passed to yin_parse_include function.
+ */
+struct include_meta {
+    const char *name;               /**< Module/submodule name. */
+    struct lysp_include **includes; /**< [Sized array](@ref sizedarrays) of parsed includes to add to. */
+};
+
+/**
+ * @brief Meta information passed to yin_parse_inout function.
+ */
+struct inout_meta {
+    struct lysp_node *parent;          /**< Parent node. */
+    struct lysp_action_inout *inout_p; /**< inout_p Input/output pointer to write to. */
+};
+
+/**
+ * @brief Meta information passed to yin_parse_minmax function.
+ */
+struct minmax_dev_meta {
+    uint32_t *lim;                      /**< min/max value to write to. */
+    uint16_t *flags;                    /**< min/max flags to write to. */
+    struct lysp_ext_instance **exts;    /**< extension instances to add to. */
+};
+
+LY_ERR yin_parse_content(struct lys_yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
+        enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts);
+
+/**
+ * @brief Match yang keyword from yin data.
+ *
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
+ * @param[in] name Start of keyword name
+ * @param[in] name_len Lenght of keyword name.
+ * @param[in] prefix Start of keyword prefix.
+ * @param[in] prefix_len Lenght of prefix.
+ * @param[in] parrent Identification of parrent element, use LY_STMT_NONE for elements without parrent.
+ *
+ * @return yang_keyword values.
+ */
 enum ly_stmt
 yin_match_keyword(struct lys_yin_parser_ctx *ctx, const char *name, size_t name_len,
         const char *prefix, size_t prefix_len, enum ly_stmt parent)
@@ -100,6 +205,14 @@
     }
 }
 
+/**
+ * @brief Match argument name.
+ *
+ * @param[in] name String representing name.
+ * @param[in] len Lenght of the name.
+ *
+ * @return yin_argument values.
+ */
 enum yin_argument
 yin_match_argument_name(const char *name, size_t len)
 {
@@ -274,6 +387,15 @@
     return LY_EMEM;
 }
 
+/**
+ * @brief Check that val is valid UTF8 character sequence of val_type.
+ *        Doesn't check empty string, only character validity.
+ *
+ * @param[in] ctx Yin parser context for logging.
+ * @param[in] val_type Type of the input string to select method of checking character validity.
+ *
+ * @return LY_ERR values.
+ */
 LY_ERR
 yin_validate_value(struct lys_yin_parser_ctx *ctx, enum yang_arg val_type)
 {
@@ -2861,6 +2983,355 @@
     return ename;
 }
 
+/**
+ * @brief Parse argument of extension subelement that is classic yang keyword and not another instance of extension.
+ *
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
+ * @param[in] elem_type Type of element that is currently being parsed.
+ * @param[out] arg Value to write to.
+ *
+ * @return LY_ERR values.
+ */
+static LY_ERR
+yin_parse_extension_instance_arg(struct lys_yin_parser_ctx *ctx, enum ly_stmt elem_type, const char **arg)
+{
+    enum ly_stmt child;
+
+    LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+
+    switch (elem_type) {
+    case LY_STMT_ACTION:
+    case LY_STMT_ANYDATA:
+    case LY_STMT_ANYXML:
+    case LY_STMT_ARGUMENT:
+    case LY_STMT_BASE:
+    case LY_STMT_BIT:
+    case LY_STMT_CASE:
+    case LY_STMT_CHOICE:
+    case LY_STMT_CONTAINER:
+    case LY_STMT_ENUM:
+    case LY_STMT_EXTENSION:
+    case LY_STMT_FEATURE:
+    case LY_STMT_GROUPING:
+    case LY_STMT_IDENTITY:
+    case LY_STMT_IF_FEATURE:
+    case LY_STMT_LEAF:
+    case LY_STMT_LEAF_LIST:
+    case LY_STMT_LIST:
+    case LY_STMT_MODULE:
+    case LY_STMT_NOTIFICATION:
+    case LY_STMT_RPC:
+    case LY_STMT_SUBMODULE:
+    case LY_STMT_TYPE:
+    case LY_STMT_TYPEDEF:
+    case LY_STMT_UNITS:
+    case LY_STMT_USES:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    case LY_STMT_AUGMENT:
+    case LY_STMT_DEVIATION:
+    case LY_STMT_REFINE:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TARGET_NODE, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    case LY_STMT_CONFIG:
+    case LY_STMT_DEFAULT:
+    case LY_STMT_DEVIATE:
+    case LY_STMT_ERROR_APP_TAG:
+    case LY_STMT_FRACTION_DIGITS:
+    case LY_STMT_KEY:
+    case LY_STMT_LENGTH:
+    case LY_STMT_MANDATORY:
+    case LY_STMT_MAX_ELEMENTS:
+    case LY_STMT_MIN_ELEMENTS:
+    case LY_STMT_MODIFIER:
+    case LY_STMT_ORDERED_BY:
+    case LY_STMT_PATH:
+    case LY_STMT_PATTERN:
+    case LY_STMT_POSITION:
+    case LY_STMT_PREFIX:
+    case LY_STMT_PRESENCE:
+    case LY_STMT_RANGE:
+    case LY_STMT_REQUIRE_INSTANCE:
+    case LY_STMT_STATUS:
+    case LY_STMT_VALUE:
+    case LY_STMT_YANG_VERSION:
+    case LY_STMT_YIN_ELEMENT:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    case LY_STMT_IMPORT:
+    case LY_STMT_INCLUDE:
+    case LY_STMT_BELONGS_TO:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    case LY_STMT_INPUT:
+    case LY_STMT_OUTPUT:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    case LY_STMT_MUST:
+    case LY_STMT_WHEN:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_CONDITION, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    case LY_STMT_NAMESPACE:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_URI, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    case LY_STMT_REVISION:
+    case LY_STMT_REVISION_DATE:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_DATE, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    case LY_STMT_UNIQUE:
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TAG, arg, Y_MAYBE_STR_ARG, elem_type));
+        break;
+    /* argument is mapped to yin element */
+    case LY_STMT_CONTACT:
+    case LY_STMT_DESCRIPTION:
+    case LY_STMT_ORGANIZATION:
+    case LY_STMT_REFERENCE:
+    case LY_STMT_ERROR_MESSAGE:
+        /* there shouldn't be any attribute, argument is supposed to be first subelement */
+        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
+
+        /* no content */
+        assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
+        if (ctx->xmlctx->ws_only) {
+            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+        }
+        if (((ctx->xmlctx->status == LYXML_ELEM_CONTENT) && !ctx->xmlctx->ws_only) || (ctx->xmlctx->status != LYXML_ELEMENT)) {
+            LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_FIRT_SUBELEM,
+                    elem_type == LY_STMT_ERROR_MESSAGE ? "value" : "text", ly_stmt2str(elem_type));
+            return LY_EVALID;
+        }
+
+        /* parse child element */
+        child = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len, elem_type);
+        if (((elem_type == LY_STMT_ERROR_MESSAGE) && (child != LY_STMT_ARG_VALUE)) ||
+                ((elem_type != LY_STMT_ERROR_MESSAGE) && (child != LY_STMT_ARG_TEXT))) {
+            LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len, ctx->xmlctx->name,
+                    ly_stmt2str(elem_type));
+            return LY_EVALID;
+        }
+        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+
+        /* no attributes expected? TODO */
+        while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
+            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+        }
+
+        /* load and save content */
+        INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, *arg);
+        LY_CHECK_RET(!*arg, LY_EMEM);
+
+        /* load closing tag of subelement */
+        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+
+        /* if only subelement was parsed as argument, load also closing tag TODO what? */
+        /*if (ctx->xmlctx->status == LYXML_ELEMENT) {
+            LY_CHECK_RET(lyxml_get_element(&ctx->xmlctx, data, &prefix, &prefix_len, &name, &name_len));
+        }*/
+        break;
+    default:
+        LOGINT(ctx->xmlctx->ctx);
+        return LY_EINT;
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse yin element into generic structure.
+ *
+ * @param[in,out] ctx Yin parser context for XML context, logging, and to store current state.
+ * @param[in] parent Identification of parent element.
+ * @param[out] element Where the element structure should be stored.
+ *
+ * @return LY_ERR values.
+ */
+LY_ERR
+yin_parse_element_generic(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, struct lysp_stmt **element)
+{
+    LY_ERR ret = LY_SUCCESS;
+    struct lysp_stmt *last = NULL, *new = NULL;
+
+    assert(ctx->xmlctx->status == LYXML_ELEMENT);
+
+    /* allocate new structure for element */
+    *element = calloc(1, sizeof(**element));
+    LY_CHECK_ERR_GOTO(!(*element), LOGMEM(ctx->xmlctx->ctx); ret = LY_EMEM, cleanup);
+    (*element)->stmt = name2nsname(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len);
+    LY_CHECK_ERR_GOTO(!(*element)->stmt, ret = LY_EMEM, cleanup);
+
+    (*element)->kw = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
+            ctx->xmlctx->prefix_len, parent);
+
+    last = (*element)->child;
+    if ((*element)->kw == LY_STMT_NONE) {
+        /* unrecognized element */
+        LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len, ctx->xmlctx->name,
+                ly_stmt2str(parent));
+        ret = LY_EVALID;
+        goto cleanup;
+    } else if ((*element)->kw != LY_STMT_EXTENSION_INSTANCE) {
+        /* element is known yang keyword, which means argument can be parsed correctly. */
+        ret = yin_parse_extension_instance_arg(ctx, (*element)->kw, &(*element)->arg);
+        LY_CHECK_GOTO(ret, cleanup);
+    } else {
+        LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+
+        /* load attributes in generic way, save all attributes in linked list */
+        while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
+            new = calloc(1, sizeof(*last));
+            LY_CHECK_ERR_GOTO(!new, LOGMEM(ctx->xmlctx->ctx); ret = LY_EMEM, cleanup);
+            if (!(*element)->child) {
+                /* save first */
+                (*element)->child = new;
+            } else {
+                last->next = new;
+            }
+            last = new;
+
+            last->flags |= LYS_YIN_ATTR;
+            LY_CHECK_GOTO(ret = lydict_insert(ctx->xmlctx->ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, &last->stmt), cleanup);
+            last->kw = LY_STMT_NONE;
+            /* attributes with prefix are ignored */
+            if (!ctx->xmlctx->prefix) {
+                LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+
+                INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, last->arg);
+                LY_CHECK_ERR_GOTO(!last->arg, ret = LY_EMEM, cleanup);
+            } else {
+                LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+            }
+            LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+        }
+    }
+
+    if ((ctx->xmlctx->status != LYXML_ELEM_CONTENT) || ctx->xmlctx->ws_only) {
+        LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+        while (ctx->xmlctx->status == LYXML_ELEMENT) {
+            /* parse subelements */
+            ret = yin_parse_element_generic(ctx, (*element)->kw, &new);
+            LY_CHECK_GOTO(ret, cleanup);
+            if (!(*element)->child) {
+                /* save first */
+                (*element)->child = new;
+            } else {
+                last->next = new;
+            }
+            last = new;
+
+            assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
+            LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+        }
+    } else {
+        /* save element content */
+        if (ctx->xmlctx->value_len) {
+            INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, (*element)->arg);
+            LY_CHECK_ERR_GOTO(!(*element)->arg, ret = LY_EMEM, cleanup);
+        }
+
+        /* read closing tag */
+        LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+    }
+
+cleanup:
+    return ret;
+}
+
+/**
+ * @brief Parse instance of extension.
+ *
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
+ * @param[in] subelem Type of the keyword this extension instance is a subelement of.
+ * @param[in] subelem_index Index of the keyword instance this extension instance is a subelement of
+ * @param[in,out] exts Extension instance to add to.
+ *
+ * @return LY_ERR values.
+ */
+LY_ERR
+yin_parse_extension_instance(struct lys_yin_parser_ctx *ctx, LYEXT_SUBSTMT subelem, LY_ARRAY_COUNT_TYPE subelem_index,
+        struct lysp_ext_instance **exts)
+{
+    struct lysp_ext_instance *e;
+    struct lysp_stmt *last_subelem = NULL, *new_subelem = NULL;
+
+    assert(ctx->xmlctx->status == LYXML_ELEMENT);
+
+    LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *exts, e, LY_EMEM);
+
+    e->yin = 0;
+    /* store name and insubstmt info */
+    e->name = name2nsname(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len);
+    LY_CHECK_RET(!e->name, LY_EMEM);
+    e->insubstmt = subelem;
+    e->insubstmt_index = subelem_index;
+    e->yin |= LYS_YIN;
+    LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+
+    /* store attributes as subelements */
+    while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
+        if (!ctx->xmlctx->prefix) {
+            new_subelem = calloc(1, sizeof(*new_subelem));
+            if (!e->child) {
+                e->child = new_subelem;
+            } else {
+                last_subelem->next = new_subelem;
+            }
+            last_subelem = new_subelem;
+
+            last_subelem->flags |= LYS_YIN_ATTR;
+            LY_CHECK_RET(lydict_insert(ctx->xmlctx->ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, &last_subelem->stmt));
+            LY_CHECK_RET(!last_subelem->stmt, LY_EMEM);
+            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+
+            INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, last_subelem->arg);
+            LY_CHECK_RET(!last_subelem->arg, LY_EMEM);
+        } else {
+            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+        }
+
+        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+    }
+
+    /* parse subelements */
+    assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
+    if (ctx->xmlctx->ws_only) {
+        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+        while (ctx->xmlctx->status == LYXML_ELEMENT) {
+            LY_CHECK_RET(yin_parse_element_generic(ctx, LY_STMT_EXTENSION_INSTANCE, &new_subelem));
+            if (!e->child) {
+                e->child = new_subelem;
+            } else {
+                last_subelem->next = new_subelem;
+            }
+            last_subelem = new_subelem;
+
+            assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
+            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+        }
+    } else if (ctx->xmlctx->value_len) {
+        /* save text content */
+        INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, e->argument);
+        LY_CHECK_RET(!e->argument, LY_EMEM);
+
+        /* parser next */
+        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+    }
+
+    return LY_SUCCESS;
+}
+
+/**
+ * @brief Generic function for content parsing
+ *
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
+ * @param[in] subelem_info array of valid subelement types and meta information
+ * @param[in] subelem_info_size Size of subelem_info array.
+ * @param[in] current_element Type of current element.
+ * @param[out] text_content Where the text content of element should be stored if any. Text content is ignored if set to NULL.
+ * @param[in,out] exts Extension instance to add to. Can be set to null if element cannot have extension as subelements.
+ *
+ * @return LY_ERR values.
+ */
 LY_ERR
 yin_parse_content(struct lys_yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
         enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts)
@@ -3155,324 +3626,14 @@
     return ret;
 }
 
-LY_ERR
-yin_parse_extension_instance(struct lys_yin_parser_ctx *ctx, LYEXT_SUBSTMT subelem, LY_ARRAY_COUNT_TYPE subelem_index,
-        struct lysp_ext_instance **exts)
-{
-    struct lysp_ext_instance *e;
-    struct lysp_stmt *last_subelem = NULL, *new_subelem = NULL;
-
-    assert(ctx->xmlctx->status == LYXML_ELEMENT);
-
-    LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *exts, e, LY_EMEM);
-
-    e->yin = 0;
-    /* store name and insubstmt info */
-    e->name = name2nsname(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len);
-    LY_CHECK_RET(!e->name, LY_EMEM);
-    e->insubstmt = subelem;
-    e->insubstmt_index = subelem_index;
-    e->yin |= LYS_YIN;
-    LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-
-    /* store attributes as subelements */
-    while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
-        if (!ctx->xmlctx->prefix) {
-            new_subelem = calloc(1, sizeof(*new_subelem));
-            if (!e->child) {
-                e->child = new_subelem;
-            } else {
-                last_subelem->next = new_subelem;
-            }
-            last_subelem = new_subelem;
-
-            last_subelem->flags |= LYS_YIN_ATTR;
-            LY_CHECK_RET(lydict_insert(ctx->xmlctx->ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, &last_subelem->stmt));
-            LY_CHECK_RET(!last_subelem->stmt, LY_EMEM);
-            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-
-            INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, last_subelem->arg);
-            LY_CHECK_RET(!last_subelem->arg, LY_EMEM);
-        } else {
-            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-        }
-
-        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-    }
-
-    /* parse subelements */
-    assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
-    if (ctx->xmlctx->ws_only) {
-        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-        while (ctx->xmlctx->status == LYXML_ELEMENT) {
-            LY_CHECK_RET(yin_parse_element_generic(ctx, LY_STMT_EXTENSION_INSTANCE, &new_subelem));
-            if (!e->child) {
-                e->child = new_subelem;
-            } else {
-                last_subelem->next = new_subelem;
-            }
-            last_subelem = new_subelem;
-
-            assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
-            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-        }
-    } else if (ctx->xmlctx->value_len) {
-        /* save text content */
-        INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, e->argument);
-        LY_CHECK_RET(!e->argument, LY_EMEM);
-
-        /* parser next */
-        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-    }
-
-    return LY_SUCCESS;
-}
-
 /**
- * @brief Parse argument of extension subelement that is classic yang keyword and not another instance of extension.
+ * @brief Parse module element.
  *
  * @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] elem_type Type of element that is currently being parsed.
- * @param[out] arg Value to write to.
+ * @param[out] mod Parsed module structure.
  *
  * @return LY_ERR values.
  */
-static LY_ERR
-yin_parse_extension_instance_arg(struct lys_yin_parser_ctx *ctx, enum ly_stmt elem_type, const char **arg)
-{
-    enum ly_stmt child;
-
-    LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-
-    switch (elem_type) {
-    case LY_STMT_ACTION:
-    case LY_STMT_ANYDATA:
-    case LY_STMT_ANYXML:
-    case LY_STMT_ARGUMENT:
-    case LY_STMT_BASE:
-    case LY_STMT_BIT:
-    case LY_STMT_CASE:
-    case LY_STMT_CHOICE:
-    case LY_STMT_CONTAINER:
-    case LY_STMT_ENUM:
-    case LY_STMT_EXTENSION:
-    case LY_STMT_FEATURE:
-    case LY_STMT_GROUPING:
-    case LY_STMT_IDENTITY:
-    case LY_STMT_IF_FEATURE:
-    case LY_STMT_LEAF:
-    case LY_STMT_LEAF_LIST:
-    case LY_STMT_LIST:
-    case LY_STMT_MODULE:
-    case LY_STMT_NOTIFICATION:
-    case LY_STMT_RPC:
-    case LY_STMT_SUBMODULE:
-    case LY_STMT_TYPE:
-    case LY_STMT_TYPEDEF:
-    case LY_STMT_UNITS:
-    case LY_STMT_USES:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    case LY_STMT_AUGMENT:
-    case LY_STMT_DEVIATION:
-    case LY_STMT_REFINE:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TARGET_NODE, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    case LY_STMT_CONFIG:
-    case LY_STMT_DEFAULT:
-    case LY_STMT_DEVIATE:
-    case LY_STMT_ERROR_APP_TAG:
-    case LY_STMT_FRACTION_DIGITS:
-    case LY_STMT_KEY:
-    case LY_STMT_LENGTH:
-    case LY_STMT_MANDATORY:
-    case LY_STMT_MAX_ELEMENTS:
-    case LY_STMT_MIN_ELEMENTS:
-    case LY_STMT_MODIFIER:
-    case LY_STMT_ORDERED_BY:
-    case LY_STMT_PATH:
-    case LY_STMT_PATTERN:
-    case LY_STMT_POSITION:
-    case LY_STMT_PREFIX:
-    case LY_STMT_PRESENCE:
-    case LY_STMT_RANGE:
-    case LY_STMT_REQUIRE_INSTANCE:
-    case LY_STMT_STATUS:
-    case LY_STMT_VALUE:
-    case LY_STMT_YANG_VERSION:
-    case LY_STMT_YIN_ELEMENT:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    case LY_STMT_IMPORT:
-    case LY_STMT_INCLUDE:
-    case LY_STMT_BELONGS_TO:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    case LY_STMT_INPUT:
-    case LY_STMT_OUTPUT:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    case LY_STMT_MUST:
-    case LY_STMT_WHEN:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_CONDITION, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    case LY_STMT_NAMESPACE:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_URI, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    case LY_STMT_REVISION:
-    case LY_STMT_REVISION_DATE:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_DATE, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    case LY_STMT_UNIQUE:
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TAG, arg, Y_MAYBE_STR_ARG, elem_type));
-        break;
-    /* argument is mapped to yin element */
-    case LY_STMT_CONTACT:
-    case LY_STMT_DESCRIPTION:
-    case LY_STMT_ORGANIZATION:
-    case LY_STMT_REFERENCE:
-    case LY_STMT_ERROR_MESSAGE:
-        /* there shouldn't be any attribute, argument is supposed to be first subelement */
-        LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
-
-        /* no content */
-        assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
-        if (ctx->xmlctx->ws_only) {
-            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-        }
-        if (((ctx->xmlctx->status == LYXML_ELEM_CONTENT) && !ctx->xmlctx->ws_only) || (ctx->xmlctx->status != LYXML_ELEMENT)) {
-            LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_FIRT_SUBELEM,
-                    elem_type == LY_STMT_ERROR_MESSAGE ? "value" : "text", ly_stmt2str(elem_type));
-            return LY_EVALID;
-        }
-
-        /* parse child element */
-        child = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len, elem_type);
-        if (((elem_type == LY_STMT_ERROR_MESSAGE) && (child != LY_STMT_ARG_VALUE)) ||
-                ((elem_type != LY_STMT_ERROR_MESSAGE) && (child != LY_STMT_ARG_TEXT))) {
-            LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len, ctx->xmlctx->name,
-                    ly_stmt2str(elem_type));
-            return LY_EVALID;
-        }
-        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-
-        /* no attributes expected? TODO */
-        while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
-            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-            LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-        }
-
-        /* load and save content */
-        INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, *arg);
-        LY_CHECK_RET(!*arg, LY_EMEM);
-
-        /* load closing tag of subelement */
-        LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
-
-        /* if only subelement was parsed as argument, load also closing tag TODO what? */
-        /*if (ctx->xmlctx->status == LYXML_ELEMENT) {
-            LY_CHECK_RET(lyxml_get_element(&ctx->xmlctx, data, &prefix, &prefix_len, &name, &name_len));
-        }*/
-        break;
-    default:
-        LOGINT(ctx->xmlctx->ctx);
-        return LY_EINT;
-    }
-
-    return LY_SUCCESS;
-}
-
-LY_ERR
-yin_parse_element_generic(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, struct lysp_stmt **element)
-{
-    LY_ERR ret = LY_SUCCESS;
-    struct lysp_stmt *last = NULL, *new = NULL;
-
-    assert(ctx->xmlctx->status == LYXML_ELEMENT);
-
-    /* allocate new structure for element */
-    *element = calloc(1, sizeof(**element));
-    LY_CHECK_ERR_GOTO(!(*element), LOGMEM(ctx->xmlctx->ctx); ret = LY_EMEM, cleanup);
-    (*element)->stmt = name2nsname(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len);
-    LY_CHECK_ERR_GOTO(!(*element)->stmt, ret = LY_EMEM, cleanup);
-
-    (*element)->kw = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
-            ctx->xmlctx->prefix_len, parent);
-
-    last = (*element)->child;
-    if ((*element)->kw == LY_STMT_NONE) {
-        /* unrecognized element */
-        LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len, ctx->xmlctx->name,
-                ly_stmt2str(parent));
-        ret = LY_EVALID;
-        goto cleanup;
-    } else if ((*element)->kw != LY_STMT_EXTENSION_INSTANCE) {
-        /* element is known yang keyword, which means argument can be parsed correctly. */
-        ret = yin_parse_extension_instance_arg(ctx, (*element)->kw, &(*element)->arg);
-        LY_CHECK_GOTO(ret, cleanup);
-    } else {
-        LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
-
-        /* load attributes in generic way, save all attributes in linked list */
-        while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
-            new = calloc(1, sizeof(*last));
-            LY_CHECK_ERR_GOTO(!new, LOGMEM(ctx->xmlctx->ctx); ret = LY_EMEM, cleanup);
-            if (!(*element)->child) {
-                /* save first */
-                (*element)->child = new;
-            } else {
-                last->next = new;
-            }
-            last = new;
-
-            last->flags |= LYS_YIN_ATTR;
-            LY_CHECK_GOTO(ret = lydict_insert(ctx->xmlctx->ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, &last->stmt), cleanup);
-            last->kw = LY_STMT_NONE;
-            /* attributes with prefix are ignored */
-            if (!ctx->xmlctx->prefix) {
-                LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
-
-                INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, last->arg);
-                LY_CHECK_ERR_GOTO(!last->arg, ret = LY_EMEM, cleanup);
-            } else {
-                LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
-            }
-            LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
-        }
-    }
-
-    if ((ctx->xmlctx->status != LYXML_ELEM_CONTENT) || ctx->xmlctx->ws_only) {
-        LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
-        while (ctx->xmlctx->status == LYXML_ELEMENT) {
-            /* parse subelements */
-            ret = yin_parse_element_generic(ctx, (*element)->kw, &new);
-            LY_CHECK_GOTO(ret, cleanup);
-            if (!(*element)->child) {
-                /* save first */
-                (*element)->child = new;
-            } else {
-                last->next = new;
-            }
-            last = new;
-
-            assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
-            LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
-        }
-    } else {
-        /* save element content */
-        if (ctx->xmlctx->value_len) {
-            INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, (*element)->arg);
-            LY_CHECK_ERR_GOTO(!(*element)->arg, ret = LY_EMEM, cleanup);
-        }
-
-        /* read closing tag */
-        LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
-    }
-
-cleanup:
-    return ret;
-}
-
 LY_ERR
 yin_parse_mod(struct lys_yin_parser_ctx *ctx, struct lysp_module *mod)
 {
@@ -3532,6 +3693,15 @@
     return LY_SUCCESS;
 }
 
+/**
+ * @brief Parse submodule element.
+ *
+ * @param[in,out] ctx Yin parser context for logging and to store current state.
+ * @param[in] mod_attrs Attributes of submodule element.
+ * @param[out] submod Parsed submodule structure.
+ *
+ * @return LY_ERR values.
+ */
 LY_ERR
 yin_parse_submod(struct lys_yin_parser_ctx *ctx, struct lysp_submodule *submod)
 {
diff --git a/src/parser_yin.h b/src/parser_yin.h
deleted file mode 100644
index 9ca1573..0000000
--- a/src/parser_yin.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/**
- * @file parser_yin.h
- * @author David Sedlák <xsedla1d@stud.fit.vutbr.cz>
- * @brief YIN parser header file.
- *
- * Copyright (c) 2015 - 2019 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.
- * You may obtain a copy of the License at
- *
- *     https://opensource.org/licenses/BSD-3-Clause
- */
-
-#ifndef LY_PARSER_YIN_H_
-#define LY_PARSER_YIN_H_
-
-#include <stdint.h>
-#include <stdio.h>
-
-#include "log.h"
-#include "tree.h"
-#include "tree_schema.h"
-#include "tree_schema_internal.h"
-
-/* list of yin attribute strings */
-extern const char * const yin_attr_list[];
-#define yin_attr2str(STMT) yin_attr_list[STMT]
-
-#define VALID_VALS1 " Only valid value is \"%s\"."
-#define VALID_VALS2 " Valid values are \"%s\" and \"%s\"."
-#define VALID_VALS3 " Valid values are \"%s\", \"%s\" and \"%s\"."
-#define VALID_VALS4 " Valid values are \"%s\", \"%s\", \"%s\" and \"%s\"."
-
-/* shortcut to determin if keyword can in general be subelement of deviation regardles of it's type */
-#define isdevsub(kw) (kw == LY_STMT_CONFIG || kw == LY_STMT_DEFAULT || kw == LY_STMT_MANDATORY || \
-                      kw == LY_STMT_MAX_ELEMENTS || kw == LY_STMT_MIN_ELEMENTS ||              \
-                      kw == LY_STMT_MUST || kw == LY_STMT_TYPE || kw == LY_STMT_UNIQUE ||         \
-                      kw == LY_STMT_UNITS || kw == LY_STMT_EXTENSION_INSTANCE)
-
-enum yin_argument {
-    YIN_ARG_UNKNOWN = 0,   /**< parsed argument can not be matched with any supported yin argument keyword */
-    YIN_ARG_NAME,          /**< argument name */
-    YIN_ARG_TARGET_NODE,   /**< argument target-node */
-    YIN_ARG_MODULE,        /**< argument module */
-    YIN_ARG_VALUE,         /**< argument value */
-    YIN_ARG_TEXT,          /**< argument text */
-    YIN_ARG_CONDITION,     /**< argument condition */
-    YIN_ARG_URI,           /**< argument uri */
-    YIN_ARG_DATE,          /**< argument data */
-    YIN_ARG_TAG,           /**< argument tag */
-    YIN_ARG_NONE           /**< empty (special value) */
-};
-
-/* flags to set constraints of subelements */
-#define YIN_SUBELEM_MANDATORY   0x01    /**< is set when subelement is mandatory */
-#define YIN_SUBELEM_UNIQUE      0x02    /**< is set when subelement is unique */
-#define YIN_SUBELEM_FIRST       0x04    /**< is set when subelement is actually yang argument mapped to yin element */
-#define YIN_SUBELEM_VER2        0x08    /**< subelemnt is allowed only in modules with version at least 2 (YANG 1.1) */
-
-#define YIN_SUBELEM_PARSED      0x80    /**< is set during parsing when given subelement is encountered for the first
-                                             time to simply check validity of given constraints */
-
-struct yin_subelement {
-    enum ly_stmt type;      /**< type of keyword */
-    void *dest;             /**< meta infromation passed to responsible function (mostly information about where parsed subelement should be stored) */
-    uint16_t flags;         /**< describes constraints of subelement can be set to YIN_SUBELEM_MANDATORY, YIN_SUBELEM_UNIQUE, YIN_SUBELEM_FIRST, YIN_SUBELEM_VER2, and YIN_SUBELEM_DEFAULT_TEXT */
-};
-
-/* Meta information passed to yin_parse_argument function,
-   holds information about where content of argument element will be stored. */
-struct yin_argument_meta {
-    uint16_t *flags;        /**< Argument flags */
-    const char **argument;  /**< Argument value */
-};
-
-/**
- * @brief Meta information passed to functions working with tree_schema,
- *        that require additional information about parent node.
- */
-struct tree_node_meta {
-    struct lysp_node *parent;       /**< parent node */
-    struct lysp_node **nodes;    /**< linked list of siblings */
-};
-
-/**
- * @brief Meta information passed to yin_parse_import function.
- */
-struct import_meta {
-    const char *prefix;             /**< module prefix. */
-    struct lysp_import **imports;   /**< imports to add to. */
-};
-
-/**
- * @brief Meta information passed to yin_parse_include function.
- */
-struct include_meta {
-    const char *name;               /**< Module/submodule name. */
-    struct lysp_include **includes; /**< [Sized array](@ref sizedarrays) of parsed includes to add to. */
-};
-
-/**
- * @brief Meta information passed to yin_parse_inout function.
- */
-struct inout_meta {
-    struct lysp_node *parent;          /**< Parent node. */
-    struct lysp_action_inout *inout_p; /**< inout_p Input/output pointer to write to. */
-};
-
-/**
- * @brief Meta information passed to yin_parse_minmax function.
- */
-struct minmax_dev_meta {
-    uint32_t *lim;                      /**< min/max value to write to. */
-    uint16_t *flags;                    /**< min/max flags to write to. */
-    struct lysp_ext_instance **exts;    /**< extension instances to add to. */
-};
-
-/**
- * @brief Match argument name.
- *
- * @param[in] name String representing name.
- * @param[in] len Lenght of the name.
- *
- * @return yin_argument values.
- */
-enum yin_argument yin_match_argument_name(const char *name, size_t len);
-
-/**
- * @brief Generic function for content parsing
- *
- * @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] subelem_info array of valid subelement types and meta information
- * @param[in] subelem_info_size Size of subelem_info array.
- * @param[in] current_element Type of current element.
- * @param[out] text_content Where the text content of element should be stored if any. Text content is ignored if set to NULL.
- * @param[in,out] exts Extension instance to add to. Can be set to null if element cannot have extension as subelements.
- *
- * @return LY_ERR values.
- */
-LY_ERR yin_parse_content(struct lys_yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
-        enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts);
-
-/**
- * @brief Check that val is valid UTF8 character sequence of val_type.
- *        Doesn't check empty string, only character validity.
- *
- * @param[in] ctx Yin parser context for logging.
- * @param[in] val_type Type of the input string to select method of checking character validity.
- *
- * @return LY_ERR values.
- */
-LY_ERR yin_validate_value(struct lys_yin_parser_ctx *ctx, enum yang_arg val_type);
-
-/**
- * @brief Match yang keyword from yin data.
- *
- * @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] name Start of keyword name
- * @param[in] name_len Lenght of keyword name.
- * @param[in] prefix Start of keyword prefix.
- * @param[in] prefix_len Lenght of prefix.
- * @param[in] parrent Identification of parrent element, use LY_STMT_NONE for elements without parrent.
- *
- * @return yang_keyword values.
- */
-enum ly_stmt yin_match_keyword(struct lys_yin_parser_ctx *ctx, const char *name, size_t name_len,
-        const char *prefix, size_t prefix_len, enum ly_stmt parrent);
-
-/**
- * @brief Parse instance of extension.
- *
- * @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] subelem Type of the keyword this extension instance is a subelement of.
- * @param[in] subelem_index Index of the keyword instance this extension instance is a subelement of
- * @param[in,out] exts Extension instance to add to.
- *
- * @return LY_ERR values.
- */
-LY_ERR yin_parse_extension_instance(struct lys_yin_parser_ctx *ctx, LYEXT_SUBSTMT subelem, LY_ARRAY_COUNT_TYPE subelem_index,
-        struct lysp_ext_instance **exts);
-
-/**
- * @brief Parse yin element into generic structure.
- *
- * @param[in,out] ctx Yin parser context for XML context, logging, and to store current state.
- * @param[in] parent Identification of parent element.
- * @param[out] element Where the element structure should be stored.
- *
- * @return LY_ERR values.
- */
-LY_ERR yin_parse_element_generic(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, struct lysp_stmt **element);
-
-/**
- * @brief Parse module element.
- *
- * @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[out] mod Parsed module structure.
- *
- * @return LY_ERR values.
- */
-LY_ERR yin_parse_mod(struct lys_yin_parser_ctx *ctx, struct lysp_module *mod);
-
-/**
- * @brief Parse submodule element.
- *
- * @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] mod_attrs Attributes of submodule element.
- * @param[out] submod Parsed submodule structure.
- *
- * @return LY_ERR values.
- */
-LY_ERR yin_parse_submod(struct lys_yin_parser_ctx *ctx, struct lysp_submodule *submod);
-
-#endif /* LY_PARSER_YIN_H_*/
diff --git a/src/printer_data.c b/src/printer_data.c
index 05a0ef0..ffe9082 100644
--- a/src/printer_data.c
+++ b/src/printer_data.c
@@ -19,7 +19,8 @@
 
 #include "common.h"
 #include "log.h"
-#include "printer.h"
+#include "out.h"
+#include "out_internal.h"
 #include "printer_internal.h"
 #include "tree_data.h"
 #include "tree_schema.h"
diff --git a/src/printer_data.h b/src/printer_data.h
index daafea2..6da3578 100644
--- a/src/printer_data.h
+++ b/src/printer_data.h
@@ -19,7 +19,7 @@
 #include <unistd.h>
 
 #include "log.h"
-#include "printer.h"
+#include "out.h"
 #include "tree_data.h"
 
 #ifdef __cplusplus
@@ -49,7 +49,7 @@
  *
  * Besides the legacy functions from libyang 1.x (::lyd_print_clb(), ::lyd_print_fd(), ::lyd_print_file(), ::lyd_print_mem()
  * and ::lyd_print_path()) printing data into the specified output, there are also new functions using
- * [output handler](@ref howtoPrinters) introduced in libyang 2.0. In contrast to
+ * [output handler](@ref howtoOutput) introduced in libyang 2.0. In contrast to
  * [schema printers](@ref howtoSchemaPrinters), there is no limit of the functionality and the functions can be used
  * interchangeable. The only think to note is that the new functions ::lyd_print_all() and ::lyd_print_tree() does not
  * accept ::LYD_PRINT_WITHSIBLINGS [printer option](@ref dataprinterflags)) since this flag differentiate the functions
diff --git a/src/printer_internal.h b/src/printer_internal.h
index 703d423..d1909f8 100644
--- a/src/printer_internal.h
+++ b/src/printer_internal.h
@@ -15,7 +15,7 @@
 #ifndef LY_PRINTER_INTERNAL_H_
 #define LY_PRINTER_INTERNAL_H_
 
-#include "printer.h"
+#include "out.h"
 #include "printer_data.h"
 #include "printer_schema.h"
 
@@ -23,43 +23,6 @@
 struct lysp_submodule;
 
 /**
- * @brief Printer output structure specifying where the data are printed.
- */
-struct ly_out {
-    LY_OUT_TYPE type;     /**< type of the output to select the output method */
-    union {
-        int fd;          /**< file descriptor for LY_OUT_FD type */
-        FILE *f;         /**< file structure for LY_OUT_FILE, LY_OUT_FDSTREAM and LY_OUT_FILEPATH types */
-        struct {
-            FILE *f;          /**< file stream from the original file descriptor, variable is mapped to the LY_OUT_FILE's f */
-            int fd;           /**< original file descriptor, which was not used directly because of missing vdprintf() */
-        } fdstream;      /**< structure for LY_OUT_FDSTREAM type, which is LY_OUT_FD when vdprintf() is missing */
-        struct {
-            FILE *f;          /**< file structure for LY_OUT_FILEPATH, variable is mapped to the LY_OUT_FILE's f */
-            char *filepath;   /**< stored original filepath */
-        } fpath;         /**< filepath structure for LY_OUT_FILEPATH */
-        struct {
-            char **buf;       /**< storage for the pointer to the memory buffer to store the output */
-            size_t len;       /**< number of used bytes in the buffer */
-            size_t size;      /**< allocated size of the buffer */
-        } mem;           /**< memory buffer information for LY_OUT_MEMORY type */
-        struct {
-            ssize_t (*func)(void *arg, const void *buf, size_t count); /**< callback function */
-            void *arg;        /**< optional argument for the callback function */
-        } clb;           /**< printer callback for LY_OUT_CALLBACK type */
-    } method;            /**< type-specific information about the output */
-
-    /* LYB only */
-    char *buffered;      /**< additional buffer for holes */
-    size_t buf_len;      /**< number of used bytes in the additional buffer for holes */
-    size_t buf_size;     /**< allocated size of the buffer for holes */
-    size_t hole_count;   /**< hole counter */
-
-    size_t printed;      /**< Total number of printed bytes */
-    size_t func_printed; /**< Number of bytes printed by the last function */
-};
-
-/**
  * @brief Informational structure for YANG statements
  */
 struct ext_substmt_info_s {
@@ -70,7 +33,7 @@
 #define SUBST_FLAG_ID 0x2  /**< the value is identifier -> no quotes */
 };
 
-/* filled in printer.c */
+/* filled in out.c */
 extern struct ext_substmt_info_s ext_substmt_info[];
 
 /**
@@ -102,7 +65,8 @@
  * @param[in] options Schema output options (see @ref schemaprinterflags).
  * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
-LY_ERR yang_print_parsed_submodule(struct ly_out *out, const struct lys_module *module, const struct lysp_submodule *submodp, uint32_t options);
+LY_ERR yang_print_parsed_submodule(struct ly_out *out, const struct lys_module *module,
+        const struct lysp_submodule *submodp, uint32_t options);
 
 /**
  * @brief YANG printer of the compiled schemas.
@@ -141,7 +105,8 @@
  * @param[in] options Schema output options (see @ref schemaprinterflags).
  * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
-LY_ERR yin_print_parsed_module(struct ly_out *out, const struct lys_module *module, const struct lysp_module *modp, uint32_t options);
+LY_ERR yin_print_parsed_module(struct ly_out *out, const struct lys_module *module, const struct lysp_module *modp,
+        uint32_t options);
 
 /**
  * @brief YIN printer of the parsed submodule. Full YIN printer.
@@ -152,7 +117,8 @@
  * @param[in] options Schema output options (see @ref schemaprinterflags).
  * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
-LY_ERR yin_print_parsed_submodule(struct ly_out *out, const struct lys_module *module, const struct lysp_submodule *submodp, uint32_t options);
+LY_ERR yin_print_parsed_submodule(struct ly_out *out, const struct lys_module *module,
+        const struct lysp_submodule *submodp, uint32_t options);
 
 /**
  * @brief XML printer of YANG data.
@@ -184,62 +150,4 @@
  */
 LY_ERR lyb_print_data(struct ly_out *out, const struct lyd_node *root, uint32_t options);
 
-/**
- * @brief Check whether the node should even be printed.
- *
- * @param[in] node Node to check.
- * @param[in] options Printer options.
- * @return false (no, it should not be printed) or true (yes, it is supposed to be printed)
- */
-ly_bool ly_should_print(const struct lyd_node *node, uint32_t options);
-
-/**
- * @brief Generic printer of the given format string into the specified output.
- *
- * Does not reset printed bytes. Adds to printed bytes.
- *
- * @param[in] out Output specification.
- * @param[in] format Format string to be printed.
- * @return LY_ERR value.
- */
-LY_ERR ly_print_(struct ly_out *out, const char *format, ...);
-
-/**
- * @brief Generic printer of the given string buffer into the specified output.
- *
- * Does not reset printed bytes. Adds to printed bytes.
- *
- * @param[in] out Output specification.
- * @param[in] buf Memory buffer with the data to print.
- * @param[in] len Length of the data to print in the @p buf.
- * @return LY_ERR value.
- */
-LY_ERR ly_write_(struct ly_out *out, const char *buf, size_t len);
-
-/**
- * @brief Create a hole in the output data that will be filled later.
- *
- * Adds printed bytes.
- *
- * @param[in] out Output specification.
- * @param[in] len Length of the created hole.
- * @param[out] position Position of the hole, value must be later provided to the ::ly_write_skipped() call.
- * @return LY_ERR value.
- */
-LY_ERR ly_write_skip(struct ly_out *out, size_t len, size_t *position);
-
-/**
- * @brief Write data into the hole at given position.
- *
- * Does not change printed bytes.
- *
- * @param[in] out Output specification.
- * @param[in] position Position of the hole to fill, the value was provided by ::ly_write_skip().
- * @param[in] buf Memory buffer with the data to print.
- * @param[in] len Length of the data to print in the @p buf. Not that the length must correspond
- * to the len value specified in the corresponding ::ly_write_skip() call.
- * @return LY_ERR value.
- */
-LY_ERR ly_write_skipped(struct ly_out *out, size_t position, const char *buf, size_t len);
-
 #endif /* LY_PRINTER_INTERNAL_H_ */
diff --git a/src/printer_json.c b/src/printer_json.c
index b4f401a..f67d31f 100644
--- a/src/printer_json.c
+++ b/src/printer_json.c
@@ -18,6 +18,7 @@
 
 #include "common.h"
 #include "log.h"
+#include "out_internal.h"
 #include "parser_data.h"
 #include "plugins_types.h"
 #include "printer_data.h"
diff --git a/src/printer_lyb.c b/src/printer_lyb.c
index 934156e..a1188bd 100644
--- a/src/printer_lyb.c
+++ b/src/printer_lyb.c
@@ -27,7 +27,7 @@
 #include "hash_table.h"
 #include "log.h"
 #include "parser_data.h"
-#include "printer.h"
+#include "out_internal.h"
 #include "printer_data.h"
 #include "printer_internal.h"
 #include "set.h"
diff --git a/src/printer_schema.c b/src/printer_schema.c
index 73c3745..8c20107 100644
--- a/src/printer_schema.c
+++ b/src/printer_schema.c
@@ -20,7 +20,7 @@
 #include "common.h"
 #include "compat.h"
 #include "log.h"
-#include "printer.h"
+#include "out_internal.h"
 #include "printer_internal.h"
 #include "tree_schema.h"
 
diff --git a/src/printer_schema.h b/src/printer_schema.h
index 9ca5e7a..ee47593 100644
--- a/src/printer_schema.h
+++ b/src/printer_schema.h
@@ -19,7 +19,7 @@
 #include <unistd.h>
 
 #include "log.h"
-#include "printer.h"
+#include "out.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -63,7 +63,7 @@
  * ::lys_print_fd(), ::lys_print_file() and ::lys_print_mem()) to print the complete module into the specified output. But note,
  * that these functions are limited to print only the complete module.
  *
- * The full functionality of the schema printers is available via functions using [output handler](@ref howtoPrinters). Besides
+ * The full functionality of the schema printers is available via functions using [output handler](@ref howtoOutput). Besides
  * the ::lys_print_module() function to print the complete module, there are functions to print a submodule
  * (::lys_print_submodule()) or a subtree (::lys_print_node()). Note that these functions might not support all the output
  * formats mentioned above.
diff --git a/src/printer_xml.c b/src/printer_xml.c
index ef82bb7..f3d2c52 100644
--- a/src/printer_xml.c
+++ b/src/printer_xml.c
@@ -24,7 +24,7 @@
 #include "log.h"
 #include "parser_data.h"
 #include "plugins_types.h"
-#include "printer.h"
+#include "out_internal.h"
 #include "printer_data.h"
 #include "printer_internal.h"
 #include "set.h"
diff --git a/src/printer_yang.c b/src/printer_yang.c
index 6b7cfa4..b60b0c4 100644
--- a/src/printer_yang.c
+++ b/src/printer_yang.c
@@ -24,7 +24,7 @@
 #include "compat.h"
 #include "log.h"
 #include "plugins_types.h"
-#include "printer.h"
+#include "out_internal.h"
 #include "printer_internal.h"
 #include "printer_schema.h"
 #include "tree.h"
diff --git a/src/printer_yin.c b/src/printer_yin.c
index d995e77..1b691d9 100644
--- a/src/printer_yin.c
+++ b/src/printer_yin.c
@@ -21,7 +21,7 @@
 #include "common.h"
 #include "compat.h"
 #include "log.h"
-#include "printer.h"
+#include "out_internal.h"
 #include "printer_internal.h"
 #include "tree.h"
 #include "tree_schema.h"
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 5b01287..f6c2552 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -29,7 +29,7 @@
 #include "context.h"
 #include "dict.h"
 #include "log.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_schema.h"
 #include "path.h"
 #include "plugins_exts.h"
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 904e8be..2edc493 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -29,7 +29,7 @@
 #include "context.h"
 #include "dict.h"
 #include "log.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_schema.h"
 #include "path.h"
 #include "plugins_exts.h"
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index de343d7..56580eb 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -29,7 +29,7 @@
 #include "context.h"
 #include "dict.h"
 #include "log.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_schema.h"
 #include "path.h"
 #include "plugins_exts.h"
diff --git a/src/tree_data.c b/src/tree_data.c
index deb93ff..c292037 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -33,6 +33,7 @@
 #include "dict.h"
 #include "diff.h"
 #include "hash_table.h"
+#include "in_internal.h"
 #include "log.h"
 #include "parser_data.h"
 #include "parser_internal.h"
@@ -264,7 +265,6 @@
 static LYD_FORMAT
 lyd_parse_get_format(const struct ly_in *in, LYD_FORMAT format)
 {
-
     if (!format && (in->type == LY_IN_FILEPATH)) {
         /* unknown format - try to detect it from filename's suffix */
         const char *path = in->method.fpath.filepath;
@@ -359,7 +359,7 @@
     }
 
 cleanup:
-    lydctx->free((struct lyd_ctx *)lydctx);
+    lydctx->free(lydctx);
     if (ret) {
         lyd_free_all(*tree);
         *tree = NULL;
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index 12f5d5a..bc181af 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -330,166 +330,6 @@
         LY_PREFIX_FORMAT format, void *prefix_data);
 
 /**
- * @brief Parse XML string as YANG data tree.
- *
- * @param[in] ctx libyang context
- * @param[in] in Input structure.
- * @param[in] parse_options Options for parser, see @ref dataparseroptions.
- * @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
- * @param[out] tree_p Parsed data tree. Note that NULL can be a valid result.
- * @param[out] lydctx_p Data parser context to finish validation.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_xml_data(const struct ly_ctx *ctx, struct ly_in *in, uint32_t parse_options, uint32_t validate_options,
-        struct lyd_node **tree_p, struct lyd_ctx **lydctx_p);
-
-/**
- * @brief Parse XML string as YANG RPC/action invocation.
- *
- * Optional \<rpc\> envelope element is accepted if present. It is [checked](https://tools.ietf.org/html/rfc6241#section-4.1) and all
- * its XML attributes are parsed. As a content of the enveloper, an RPC data or \<action\> envelope element is expected. The \<action\> envelope element is
- * also [checked](https://tools.ietf.org/html/rfc7950#section-7.15.2) and then an action data is expected as a content of this envelope.
- *
- * @param[in] ctx libyang context.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full RPC/action tree.
- * @param[out] op_p Optional pointer to the actual operation. Useful mainly for action.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_xml_rpc(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
-
-/**
- * @brief Parse XML string as YANG notification.
- *
- * Optional \<notification\> envelope element, if present, is [checked](https://tools.ietf.org/html/rfc5277#page-25)
- * and parsed. Specifically, its namespace and the child \<eventTime\> element and its value.
- *
- * @param[in] ctx libyang context.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full notification tree.
- * @param[out] op_p Optional pointer to the actual notification. Useful mainly for nested notifications.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_xml_notif(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **ntf_p);
-
-/**
- * @brief Parse XML string as YANG RPC/action reply.
- *
- * Optional \<rpc-reply\> envelope element, if present, is [checked](https://tools.ietf.org/html/rfc6241#section-4.2)
- * and all its XML attributes parsed.
- *
- * @param[in] request Data tree of the RPC/action request.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full reply tree. It always includes duplicated operation and parents of the @p request.
- * @param[out] op_p Optional pointer to the reply operation. Useful mainly for action.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_xml_reply(const struct lyd_node *request, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
-
-/**
- * @brief Parse JSON string as YANG data tree.
- *
- * @param[in] ctx libyang context
- * @param[in] in Input structure.
- * @param[in] parse_options Options for parser, see @ref dataparseroptions.
- * @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
- * @param[out] tree_p Parsed data tree. Note that NULL can be a valid result.
- * @param[out] lydctx_p Data parser context to finish validation.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_json_data(const struct ly_ctx *ctx, struct ly_in *in, uint32_t parse_options, uint32_t validate_options,
-        struct lyd_node **tree_p, struct lyd_ctx **lydctx_p);
-
-/**
- * @brief Parse JSON string as YANG notification.
- *
- * Optional top-level "notification" envelope object, if present, is [checked](https://tools.ietf.org/html/rfc5277#page-25)
- * and parsed. Specifically the child "eventTime" member and its value.
- *
- * @param[in] ctx libyang context.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full notification tree.
- * @param[out] ntf_p Optional pointer to the actual notification. Useful mainly for nested notifications.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_json_notif(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **ntf_p);
-
-/**
- * @brief Parse JSON string as YANG RPC/action invocation.
- *
- * Optional top-level "rpc" envelope object, if present is is [checked](https://tools.ietf.org/html/rfc6241#section-4.1) and the parser
- * goes inside for the content, which is an RPC data or "action" envelope objects. The "action" envelope object is
- * also [checked](https://tools.ietf.org/html/rfc7950#section-7.15.2) and then an action data is expected as a content of this envelope.
- *
- * @param[in] ctx libyang context.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full RPC/action tree.
- * @param[out] op_p Optional pointer to the actual operation. Useful mainly for action.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_json_rpc(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
-
-/**
- * @brief Parse JSON string as YANG RPC/action reply.
- *
- * Optional "rpc-reply" envelope object, if present, is [checked](https://tools.ietf.org/html/rfc6241#section-4.2).
- *
- * @param[in] request Data tree of the RPC/action request.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full reply tree. It always includes duplicated operation and parents of the @p request.
- * @param[out] op_p Optional pointer to the reply operation. Useful mainly for action.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_json_reply(const struct lyd_node *request, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
-
-/**
- * @brief Parse binary data as YANG data tree.
- *
- * @param[in] ctx libyang context
- * @param[in] in Input structure.
- * @param[in] parse_options Options for parser, see @ref dataparseroptions.
- * @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
- * @param[out] tree_p Parsed data tree. Note that NULL can be a valid result.
- * @param[out] lydctx_p Data parser context to finish validation.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_lyb_data(const struct ly_ctx *ctx, struct ly_in *in, uint32_t parse_options, uint32_t validate_options,
-        struct lyd_node **tree_p, struct lyd_ctx **lydctx_p);
-
-/**
- * @brief Parse binary data as YANG RPC/action invocation.
- *
- * @param[in] ctx libyang context.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full RPC/action tree.
- * @param[out] op_p Optional pointer to the actual operation. Useful mainly for action.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_lyb_rpc(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
-
-/**
- * @brief Parse binary data as YANG notification.
- *
- * @param[in] ctx libyang context.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full notification tree.
- * @param[out] ntf_p Optional pointer to the actual notification. Useful mainly for nested notifications.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_lyb_notif(const struct ly_ctx *ctx, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **ntf_p);
-
-/**
- * @brief Parse binary data as YANG RPC/action reply.
- *
- * @param[in] request Data tree of the RPC/action request.
- * @param[in] in Input structure.
- * @param[out] tree_p Parsed full reply tree. It always includes duplicated operation and parents of the @p request.
- * @param[out] op_p Optional pointer to the reply operation. Useful mainly for action.
- * @return LY_ERR value.
- */
-LY_ERR lyd_parse_lyb_reply(const struct lyd_node *request, struct ly_in *in, struct lyd_node **tree_p, struct lyd_node **op_p);
-
-/**
  * @defgroup datahash Data nodes hash manipulation
  * @ingroup datatree
  */
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 2ecace5..1937de1 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -31,7 +31,7 @@
 #include "context.h"
 #include "dict.h"
 #include "log.h"
-#include "parser.h"
+#include "in_internal.h"
 #include "parser_internal.h"
 #include "parser_schema.h"
 #include "schema_compile.h"
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index f6b2eba..3ea2659 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -26,7 +26,7 @@
 #include "context.h"
 #include "hash_table.h"
 #include "log.h"
-#include "parser.h"
+#include "in_internal.h"
 #include "parser_internal.h"
 #include "parser_schema.h"
 #include "set.h"
diff --git a/src/xml.c b/src/xml.c
index 365a95a..6f4344f 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -27,8 +27,8 @@
 #include "common.h"
 #include "compat.h"
 #include "dict.h"
-#include "parser_internal.h"
-#include "printer_internal.h"
+#include "in_internal.h"
+#include "out_internal.h"
 #include "tree.h"
 #include "tree_data.h"
 
diff --git a/src/xpath.c b/src/xpath.c
index 102c4ce..d3c0b4c 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -36,7 +36,7 @@
 #include "parser_data.h"
 #include "path.h"
 #include "plugins_types.h"
-#include "printer.h"
+#include "out.h"
 #include "printer_data.h"
 #include "schema_compile_node.h"
 #include "tree.h"
diff --git a/tests/utests/data/test_parser_json.c b/tests/utests/data/test_parser_json.c
index 0dfbaba..0c9e0a2 100644
--- a/tests/utests/data/test_parser_json.c
+++ b/tests/utests/data/test_parser_json.c
@@ -21,9 +21,9 @@
 #include <string.h>
 
 #include "context.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_data.h"
-#include "printer.h"
+#include "out.h"
 #include "printer_data.h"
 #include "tests/config.h"
 #include "tree_data_internal.h"
diff --git a/tests/utests/data/test_parser_xml.c b/tests/utests/data/test_parser_xml.c
index c98bc95..183e22f 100644
--- a/tests/utests/data/test_parser_xml.c
+++ b/tests/utests/data/test_parser_xml.c
@@ -21,9 +21,9 @@
 #include <string.h>
 
 #include "context.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_data.h"
-#include "printer.h"
+#include "out.h"
 #include "printer_data.h"
 #include "tests/config.h"
 #include "tree_data_internal.h"
diff --git a/tests/utests/data/test_printer_xml.c b/tests/utests/data/test_printer_xml.c
index d6dfa00..b2bcd75 100644
--- a/tests/utests/data/test_printer_xml.c
+++ b/tests/utests/data/test_printer_xml.c
@@ -23,7 +23,7 @@
 
 #include "context.h"
 #include "parser_data.h"
-#include "printer.h"
+#include "out.h"
 #include "printer_data.h"
 #include "tests/config.h"
 #include "tree_schema.h"
diff --git a/tests/utests/data/test_validation.c b/tests/utests/data/test_validation.c
index 5b6953d..072c375 100644
--- a/tests/utests/data/test_validation.c
+++ b/tests/utests/data/test_validation.c
@@ -21,9 +21,9 @@
 #include <string.h>
 
 #include "context.h"
-#include "parser.h"
+#include "in.h"
 #include "parser_data.h"
-#include "printer.h"
+#include "out.h"
 #include "printer_data.h"
 #include "tests/config.h"
 #include "tree_schema.h"
diff --git a/tests/utests/schema/test_parser_yang.c b/tests/utests/schema/test_parser_yang.c
index 87dc277..f98777a 100644
--- a/tests/utests/schema/test_parser_yang.c
+++ b/tests/utests/schema/test_parser_yang.c
@@ -21,6 +21,7 @@
 #include <string.h>
 
 #include "common.h"
+#include "in_internal.h"
 #include "parser_internal.h"
 #include "tree_schema.h"
 #include "tree_schema_internal.h"
diff --git a/tests/utests/schema/test_parser_yin.c b/tests/utests/schema/test_parser_yin.c
index 28f280e..a4d0c28 100644
--- a/tests/utests/schema/test_parser_yin.c
+++ b/tests/utests/schema/test_parser_yin.c
@@ -22,14 +22,85 @@
 #include <stdbool.h>
 
 #include "common.h"
+#include "in.h"
 #include "parser_internal.h"
-#include "parser_yin.h"
 #include "tree_schema.h"
 #include "tree_schema_internal.h"
 #include "xml.h"
 #include "xpath.h"
 
+/* copied from parser_yin.c */
+enum yin_argument {
+    YIN_ARG_UNKNOWN = 0,   /**< parsed argument can not be matched with any supported yin argument keyword */
+    YIN_ARG_NAME,          /**< argument name */
+    YIN_ARG_TARGET_NODE,   /**< argument target-node */
+    YIN_ARG_MODULE,        /**< argument module */
+    YIN_ARG_VALUE,         /**< argument value */
+    YIN_ARG_TEXT,          /**< argument text */
+    YIN_ARG_CONDITION,     /**< argument condition */
+    YIN_ARG_URI,           /**< argument uri */
+    YIN_ARG_DATE,          /**< argument data */
+    YIN_ARG_TAG,           /**< argument tag */
+    YIN_ARG_NONE           /**< empty (special value) */
+};
+
+struct yin_subelement {
+    enum ly_stmt type;      /**< type of keyword */
+    void *dest;             /**< meta infromation passed to responsible function (mostly information about where parsed subelement should be stored) */
+    uint16_t flags;         /**< describes constraints of subelement can be set to YIN_SUBELEM_MANDATORY, YIN_SUBELEM_UNIQUE, YIN_SUBELEM_FIRST, YIN_SUBELEM_VER2, and YIN_SUBELEM_DEFAULT_TEXT */
+};
+
+struct import_meta {
+    const char *prefix;             /**< module prefix. */
+    struct lysp_import **imports;   /**< imports to add to. */
+};
+
+struct yin_argument_meta {
+    uint16_t *flags;        /**< Argument flags */
+    const char **argument;  /**< Argument value */
+};
+
+struct tree_node_meta {
+    struct lysp_node *parent;       /**< parent node */
+    struct lysp_node **nodes;    /**< linked list of siblings */
+};
+
+struct include_meta {
+    const char *name;               /**< Module/submodule name. */
+    struct lysp_include **includes; /**< [Sized array](@ref sizedarrays) of parsed includes to add to. */
+};
+
+struct inout_meta {
+    struct lysp_node *parent;          /**< Parent node. */
+    struct lysp_action_inout *inout_p; /**< inout_p Input/output pointer to write to. */
+};
+
+struct minmax_dev_meta {
+    uint32_t *lim;                      /**< min/max value to write to. */
+    uint16_t *flags;                    /**< min/max flags to write to. */
+    struct lysp_ext_instance **exts;    /**< extension instances to add to. */
+};
+
+#define YIN_SUBELEM_MANDATORY   0x01
+#define YIN_SUBELEM_UNIQUE      0x02
+#define YIN_SUBELEM_FIRST       0x04
+#define YIN_SUBELEM_VER2        0x08
+
+#define YIN_SUBELEM_PARSED      0x80
+
 /* prototypes of static functions */
+enum yin_argument yin_match_argument_name(const char *name, size_t len);
+LY_ERR yin_parse_content(struct lys_yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
+        enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts);
+LY_ERR yin_validate_value(struct lys_yin_parser_ctx *ctx, enum yang_arg val_type);
+enum ly_stmt yin_match_keyword(struct lys_yin_parser_ctx *ctx, const char *name, size_t name_len,
+        const char *prefix, size_t prefix_len, enum ly_stmt parrent);
+LY_ERR yin_parse_extension_instance(struct lys_yin_parser_ctx *ctx, LYEXT_SUBSTMT subelem, LY_ARRAY_COUNT_TYPE subelem_index,
+        struct lysp_ext_instance **exts);
+LY_ERR yin_parse_element_generic(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, struct lysp_stmt **element);
+LY_ERR yin_parse_mod(struct lys_yin_parser_ctx *ctx, struct lysp_module *mod);
+LY_ERR yin_parse_submod(struct lys_yin_parser_ctx *ctx, struct lysp_submodule *submod);
+
 void lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext);
 void lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext);
 void lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when);
diff --git a/tests/utests/schema/test_printer_yang.c b/tests/utests/schema/test_printer_yang.c
index 7d70e18..52528eb 100644
--- a/tests/utests/schema/test_printer_yang.c
+++ b/tests/utests/schema/test_printer_yang.c
@@ -22,7 +22,7 @@
 
 #include "common.h"
 #include "context.h"
-#include "printer.h"
+#include "out.h"
 #include "printer_schema.h"
 #include "tree_schema.h"
 
diff --git a/tests/utests/schema/test_printer_yin.c b/tests/utests/schema/test_printer_yin.c
index 72ad01f..dcb5925 100644
--- a/tests/utests/schema/test_printer_yin.c
+++ b/tests/utests/schema/test_printer_yin.c
@@ -23,7 +23,7 @@
 
 #include "common.h"
 #include "context.h"
-#include "printer.h"
+#include "out.h"
 #include "printer_schema.h"
 #include "tree_schema.h"
 
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index 003a008..c1ea424 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -21,6 +21,7 @@
 #include <string.h>
 
 #include "common.h"
+#include "in.h"
 #include "parser_internal.h"
 #include "path.h"
 #include "plugins_types.h"
diff --git a/tests/utests/test_context.c b/tests/utests/test_context.c
index a139bf5..bb2bb9f 100644
--- a/tests/utests/test_context.c
+++ b/tests/utests/test_context.c
@@ -22,7 +22,7 @@
 
 #include "common.h"
 #include "context.h"
-#include "parser.h"
+#include "in.h"
 #include "tests/config.h"
 #include "tree_schema_internal.h"
 #include "schema_compile.h"
diff --git a/tests/utests/test_inout.c b/tests/utests/test_inout.c
index 9edc27a..5fac6fb 100644
--- a/tests/utests/test_inout.c
+++ b/tests/utests/test_inout.c
@@ -28,8 +28,8 @@
 
 #include "common.h"
 #include "log.h"
-#include "printer.h"
-#include "parser.h"
+#include "out.h"
+#include "in.h"
 
 
 #define BUFSIZE 1024
diff --git a/tests/utests/test_json.c b/tests/utests/test_json.c
index 0482fd8..1883980 100644
--- a/tests/utests/test_json.c
+++ b/tests/utests/test_json.c
@@ -26,7 +26,7 @@
 
 #include "json.h"
 #include "context.h"
-#include "parser_internal.h"
+#include "in_internal.h"
 
 void *testfunc = NULL;
 
diff --git a/tests/utests/test_xml.c b/tests/utests/test_xml.c
index 0a064aa..89a8ce8 100644
--- a/tests/utests/test_xml.c
+++ b/tests/utests/test_xml.c
@@ -25,8 +25,7 @@
 #include <string.h>
 
 #include "context.h"
-#include "parser.h"
-#include "parser_internal.h"
+#include "in_internal.h"
 #include "xml.h"
 
 LY_ERR lyxml_ns_add(struct lyxml_ctx *xmlctx, const char *prefix, size_t prefix_len, char *uri);