doc FEATURE high level documentation including transition manual
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cca4d5a..1251dc4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -176,7 +176,7 @@
 if(("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG") OR ("${BUILD_TYPE_UPPER}" STREQUAL "RELWITHDEBINFO"))
     option(ENABLE_BUILD_TESTS "Build tests" ON)
     option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" ON)
-    set(INTERNAL_DOCS YES)
+    set(INTERNAL_DOCS NO) # TODO enable when the internal docs ready
 else()
     option(ENABLE_BUILD_TESTS "Build tests" OFF)
     option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" OFF)
diff --git a/Doxyfile.in b/Doxyfile.in
index 204efc1..9abc3c9 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -522,7 +522,7 @@
 # scope will be hidden.
 # The default value is: NO.
 
-HIDE_SCOPE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
 
 # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
 # append additional text to a page's title, such as Class Reference. If set to
@@ -781,7 +781,7 @@
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = @DOXY_HEADERS@
+INPUT                  = doc/transition.dox @DOXY_HEADERS@
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/doc/cesnet-style.css b/doc/cesnet-style.css
index b8f6ec9..296c260 100644
--- a/doc/cesnet-style.css
+++ b/doc/cesnet-style.css
@@ -12,7 +12,7 @@
 div.contents {

     background-color: #fff;

     padding: 1.618em 3.236em;

-    max-width: 700px;

+    max-width: 60em;

     margin: auto;

     margin-left: 0;

     text-align: justify;

@@ -103,4 +103,4 @@
 

 #nav-tree-contents {

     margin: 0;

-}
\ No newline at end of file
+}

diff --git a/doc/transition.dox b/doc/transition.dox
new file mode 100644
index 0000000..82d3681
--- /dev/null
+++ b/doc/transition.dox
@@ -0,0 +1,51 @@
+/**
+ * @page transition Transition Manual (1.x -> 2.0)
+ * 
+ * [TOC]
+ * 
+ * @section transitionContext Context
+ * 
+ * ly_ctx_info() -> ly_ctx_get_yanglib_data()
+ *
+ * - nedoporucuje se menit context po zacatku prace s daty
+ *   - neni ly_ctx_set_module_data_clb() ani souvisejici callback
+ *
+ * 
+ * - ::ly_ctx_find_path() byla odebrana
+ *
+ * @subsection contextSearchpaths Search Paths
+ *
+ * Internally, search directories are still handled the same way. However, API to manipulate the search directories chenged.
+ * 
+ * ### Unchanged functions
+ * - ::ly_ctx_get_searchdirs()
+ * 
+ * ### Changed functions
+ * - ::ly_ctx_set_searchdir() - Return value was changed to ::LY_ERR.
+ 
+ * ### Added functions
+ * - ::ly_ctx_unset_searchdir()
+ * - ::ly_ctx_unset_searchdir_last()
+ * 
+ * ### Removed functions
+ * - ly_ctx_unset_searchdirs() - Since the index is hard to work with, the function was replaced by ::ly_ctx_unset_searchdir() and
+ * ::ly_ctx_unset_searchdir_last().
+ * - lyd_leaf_type() - the type is now more clearer from the schema node than in libyang 1.x 
+ *
+ *
+ * @section transitionSchema Schema 
+ *
+ * lys_set_private() -> lysc_node_set_private()
+ * lys_is_disabled() -> lys_node_is_disabled()
+ * X lys_features_list()
+ * lys_features_enable -> lys_feature_enable()
+ * lys_features_disable -> lys_feature_disable()
+ * N lys_feature_*_force()
+ * lys_features_state() -> lys_feature_value()
+ * N lysc_feature_value()
+ * lyd_validate() -> lyd_validate_all(), lyd_validate_op()
+ * lyd_wd_default() -> lyd_is_default()
+ * X moving data from one context to another
+ * X lys_parent(), lys_module(), lys_node_module(), lys_set_enabled(), lys_set_disabled()
+ * lys_set_private() -> lysc_node_set_private()
+ */
diff --git a/src/common.h b/src/common.h
index 1a2a193..7e3f23b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -224,7 +224,7 @@
     struct ly_set implementing;       /**< set of YANG schemas being atomically implemented (compiled); the first added
                                            module is always the explcitly implemented module, the other ones are dependencies */
     ly_module_imp_clb imp_clb;        /**< Optional callback for retrieving missing included or imported models in a custom way. */
-    void *imp_clb_data;               /**< Optional private data for imp_clb() */
+    void *imp_clb_data;               /**< Optional private data for ::ly_ctx.imp_clb */
     uint16_t module_set_id;           /**< ID of the current set of schemas */
     uint16_t flags;                   /**< context settings, see @ref contextoptions. */
     pthread_key_t errlist_key;        /**< key for the thread-specific list of errors related to the context */
@@ -455,7 +455,7 @@
 LY_ERR ly_mmap(struct ly_ctx *ctx, int fd, size_t *length, void **addr);
 
 /**
- * @brief munmap(2) wrapper to free the memory mapped by ly_mmap()
+ * @brief munmap(2) wrapper to free the memory mapped by ::ly_mmap()
  *
  * @param[in] addr Address where the input file is mapped.
  * @param[in] length Allocated size of the address space.
diff --git a/src/context.h b/src/context.h
index 65e5a68..6249f05 100644
--- a/src/context.h
+++ b/src/context.h
@@ -28,92 +28,88 @@
 struct lysc_node;
 
 /**
- * @page howtocontext Context
+ * @page howtoContext Context
  *
- * The context concept allows callers to work in environments with different sets of YANG schemas.
+ * The context concept allows callers to work in environments with different sets of YANG modules.
  *
- * The first step in libyang is to create a new context using ly_ctx_new(). It returns a handler
- * used in the following work.
+ * The first step with libyang is to create a new context using ::ly_ctx_new(). It returns a handler used in the following work.
+ * Note that the context is supposed to provide a stable environment for work with the data. Therefore the caller should prepare
+ * a complete context and after starting working with the data, the context and its content should not change. Despite the API
+ * does not enforce this approach, it may change in future versions in the form of a locking mechanism which would allow further
+ * optimization of data manipulation. Also note that modules cannot be removed from their context. If you need to change the set
+ * of the schema modules in the context, the recommended way is to create a new context. To remove the context, there is ::ly_ctx_destroy() function.
  *
- * When creating a new context, search dir can be specified (NULL is accepted) to provide directory
- * where libyang will automatically search for schemas being imported or included. The search path
- * can be later changed via ly_ctx_set_searchdir() and ly_ctx_unset_searchdir() functions. Before the search dirs,
- * also the current working directory is (non-recursively) searched. For the case of the explicitly set search
- * dirs, also all their subdirectories (and symlinks) are taken into account. Searching in the current working
- * directory can be avoided with the context's #LY_CTX_DISABLE_SEARCHDIR_CWD option (or via ly_ctx_set_options()).
+ * The context has [several options](@ref contextoptions) changing behavior when processing YANG modules being inserted. The
+ * specific behavior is mentioned below. All the options can be set as a parameter when the context is being created or later
+ * with ::ly_ctx_set_options().
+ *
+ * When creating a new context, another optional parameter is search_dir It provide directory where libyang
+ * will automatically search for YANG modules being imported or included. There is actually a set of search paths which can be later
+ * modified using ::ly_ctx_set_searchdir(), ::ly_ctx_unset_searchdir() and ::ly_ctx_unset_searchdir_last() functions. Before the values
+ * in the set are used, also the current working directory is (non-recursively) searched. For the case of the explicitly set
+ * search directories, they are searched recursively - all their subdirectories (and symlinks) are taken into account. Searching
+ * in the current working directory can be avoided with the context's ::LY_CTX_DISABLE_SEARCHDIR_CWD option.
  * Searching in all the context's search dirs (without removing them) can be avoided with the context's
- * #LY_CTX_DISABLE_SEARCHDIRS option (or via ly_ctx_set_options()). This automatic searching can be preceded
- * by a custom  module searching callback (#ly_module_imp_clb) set via ly_ctx_set_module_imp_clb(). The algorithm of
- * searching in search dirs is also available via API as lys_search_localfile() function.
+ * ::LY_CTX_DISABLE_SEARCHDIRS option (or via ::ly_ctx_set_options()). This automatic searching can be preceded
+ * by a custom  module searching callback (::ly_module_imp_clb) set via ::ly_ctx_set_module_imp_clb(). The algorithm of
+ * searching in search dirs is also available via API as ::lys_search_localfile() function.
  *
- * Schemas are added into the context using [parser functions](@ref howtoschemasparsers) - \b lys_parse_*().
- * Alternatively, also ly_ctx_load_module() can be used - in that case the #ly_module_imp_clb or automatic
- * search in search dir and in the current working directory is used. YANG submodules cannot be loaded or even validated
- * directly, they are loaded always only as includes of YANG modules.
- *
- * YANG schemas are loaded in two steps. First, the input YANG/YIN data are parsed into \b lysp_* structures that reflect
- * the structure of the input schema. Mostly just syntax checks are done, no reference or type checking is performed in
- * this step. If the module is supposed to be implemented, not just imported by another module, the second step is to compile
- * it. The compiled schema may significantly differ in structure from the source schema structure. All the references
- * are resolved, groupings are instantiated, types are resolved (and compiled by grouping all the relevant restrictions
- * when derived from another types) and many other syntactical checks are done.
- *
- * Similarly, data trees can be parsed by \b lyd_parse_*() functions. Note, that functions for schemas have \b lys_
- * prefix (or \b lysp_ for the parsed and \b lysc_ for the compiled schema) while functions for instance data have
- * \b lyd_ prefix. It can happen during data parsing that a schema is required and __not found__ in the context or
- * the schema is found, but is __only imported__, not implemented (so the data cannot actually be instantiated).
- * In these cases, a callback is called, which should add this schema into the context or change its conformance
- * to implemented. You can set the callback using ly_ctx_set_module_data_clb() (more in @ref howtodataparsers
- * and @ref howtodatavalidation).
- *
- * Context can hold multiple revisions of the same schema, but only one of them can be implemented. The schema is not
- * implemented in case it is automatically loaded as import for another module and it is not referenced in such
- * a module (and no other) as target of leafref, augment or deviation. All modules with deviation definition are always
- * marked as implemented. The imported (not implemented) module can be set implemented by lys_set_implemented(). But
- * the implemented module cannot be changed back to just imported module. The imported modules are used only as a
- * source of definitions for types and groupings for uses statements. The data in such modules are ignored - caller
- * is not allowed to create the data (including instantiating identities) defined in the model via data parsers,
- * the default nodes are not added into any data tree and mandatory nodes are not checked in the data trees. This
- * can be changed by ly_ctx_new()'s #LY_CTX_ALLIMPLEMENTED option (or via ly_ctx_set_options()), which causes that
- * all the imported modules are automatically set to be implemented.
+ * YANG modules are added into the context using [parser functions](@ref howtoSchemaParsers) - \b lys_parse*().
+ * Alternatively, also ::ly_ctx_load_module() can be used - in that case the ::ly_module_imp_clb or automatic
+ * search in search directories and in the current working directory is used, as described above. YANG submodules cannot be loaded
+ * or even validated directly, they are loaded always only as includes of YANG modules. Explicitly parsed/loaded modules are
+ * handled as implemented - libyang is able to instantiate data representing such a module. The modules loaded implicitly, are
+ * not implemented and serve only as a source of grouping or typedef definitions. Context can hold multiple revisions of the same
+ * YANG module, but only one of them can be implemented. Details about the difference between implemented and imported modules
+ * can be found on @ref howtoSchema page. This behavior can be changed with the context's ::LY_CTX_ALLIMPLEMENTED option, which
+ * causes that all the parsed modules, despite they were loaded explicitly or implicitly, are set to be implemented. Note, that as
+ * a consequence of this option, only a single revision of any module can be present in the context in this case.
  *
  * When loading/importing a module without revision, the latest revision of the required module is supposed to load.
  * For a context, the first time the latest revision of a module is requested, it is properly searched for and loaded.
  * However, when this module is requested (without revision) the second time, the one found previously is returned.
- * This has the advantage of not searching for the module repeatedly but the drawback that if a later revision
- * of the module is later made available, this context will not use it. However, to force libyang to re-search the
- * latest revision, ly_ctx_reset_latests() can be used (not that it applies to all the schemas in the context).
+ * This has the advantage of not searching for the module repeatedly but there is a drawback in case the content of search
+ * directories is updated and a later revision become available. However, to force libyang to re-search the
+ * latest revision, ::ly_ctx_reset_latests() can be used (note that it applies to all the modules in the context).
  *
- * Context holds all schema modules internally. To get a specific module, use ly_ctx_get_module() (or ly_ctx_get_module_ns())
- * The returned structure includes both, parsed and compiled, schema variants. If you need to do something with all the modules
- * in the context, it is advised to iterate over them using ly_ctx_get_module_iter(), it is the most efficient way.
- * Alternatively, the ly_ctx_info() function can be used to get complex information about the schemas in the context
- * in the form of data tree defined by <a href="https://tools.ietf.org/html/rfc7895">ietf-yang-library</a> schema.
- * To get a specific node defined in a module in the context, ly_ctx_find_path() or ly_ctx_get_node() can be used.
+ * Context holds all the schema modules internally. To get a specific module, use ::ly_ctx_get_module() (or some of its
+ * variants). If you need to do something with all the modules in the context, it is advised to iterate over them using
+ * ::ly_ctx_get_module_iter(). Alternatively, the ::ly_ctx_get_yanglib_data() function can be used to get complex information about the schemas in the context
+ * in the form of data tree defined by <a href="https://tools.ietf.org/html/rfc7895">ietf-yang-library</a> module.
+ * To get a specific node defined in a module in the context, use ::ly_ctx_get_node().
  *
- * Modules cannot be removed from their context. If you need to change the set of the schema modules in the context
- * (use only a subset), a new context must be created. To remove the context, there is ly_ctx_destroy() function.
+ * YANG data can be parsed by \b lyd_parse_*() functions. Note, that functions for schema have \b lys_
+ * prefix (or \b lysp_ for the parsed and \b lysc_ for the compiled schema - for details see @ref howtoSchema page) while
+ * functions for instance data have \b lyd_ prefix. Details about data formats or handling data without the appropriate
+ * YANG module in context can be found on @ref howtoData page.
  *
- * - @subpage howtocontextdict
+ * Besides the YANG modules, context holds also [error information](@ref howtoErrors) and
+ * [database of strings](@ref howtoContextDict), both connected with the processed YANG modules and data.
+ *
+ * - @subpage howtoErrors
+ * - @subpage howtoContextDict
  *
  * \note API for this group of functions is available in the [context module](@ref context).
  *
  * Functions List
  * --------------
+ *
  * - ::ly_ctx_new()
+ * - ::ly_ctx_destroy()
+ *
  * - ::ly_ctx_set_searchdir()
- * - ::ly_ctx_unset_searchdir()
- * - ::ly_ctx_unset_searchdirs()
  * - ::ly_ctx_get_searchdirs()
+ * - ::ly_ctx_unset_searchdir()
+ * - ::ly_ctx_unset_searchdir_last()
+ *
+ * - ::ly_ctx_set_options()
+ * - ::ly_ctx_get_options()
+ * - ::ly_ctx_unset_options()
+ *
  * - ::ly_ctx_set_module_imp_clb()
  * - ::ly_ctx_get_module_imp_clb()
- * - ::ly_ctx_set_module_data_clb()
- * - ::ly_ctx_get_module_data_clb()
- * - ::ly_ctx_set_options()
- * - ::ly_ctx_unset_options()
- * - ::ly_ctx_get_options()
+ *
  * - ::ly_ctx_load_module()
- * - ::ly_ctx_info()
  * - ::ly_ctx_get_module_iter()
  * - ::ly_ctx_get_module()
  * - ::ly_ctx_get_module_ns()
@@ -122,21 +118,31 @@
  * - ::ly_ctx_get_module_latest()
  * - ::ly_ctx_get_module_latest_ns()
  * - ::ly_ctx_reset_latests()
- * - ::ly_ctx_get_module_set_id()
+ *
+ * - ::ly_ctx_get_yanglib_data()
+ * - ::ly_ctx_get_yanglib_id()
+ *
  * - ::ly_ctx_get_node()
- * - ::ly_ctx_find_path()
- * - ::ly_ctx_destroy()
- * - ::lys_set_implemented()
+ * - ::ly_ctx_get_module_set_id()
+ * - ::ly_ctx_internal_module_count()
+ *
  * - ::lys_search_localfile()
+ * - ::lys_set_implemented()
+ *
+ */
+
+/**
+ *
  */
 
 /**
  * @defgroup context Context
  * @{
  *
- * Structures and functions to manipulate with the libyang "containers". The \em context concept allows callers
- * to work in environments with different sets of YANG schemas. More detailed information can be found at
- * @ref howtocontext page.
+ * Structures and functions to manipulate with the libyang context containers.
+ *
+ * The \em context concept allows callers to work in environments with different sets of YANG schemas.
+ * More detailed information can be found at @ref howtoContext page.
  */
 
 /**
@@ -146,8 +152,8 @@
 struct ly_ctx;
 
 /**
- * @defgroup contextoptions Context options
  * @ingroup context
+ * @defgroup contextoptions Context options
  *
  * Options to change context behavior.
  *
@@ -161,15 +167,15 @@
                                         tests. Note that while this option improves performance, it can
                                         lead to an undefined behavior if the schema is not correct. */
 #define LY_CTX_NOYANGLIBRARY  0x04 /**< Do not internally implement ietf-yang-library module. The option
-                                        causes that function ly_ctx_info() does not work (returns NULL) until
+                                        causes that function ::ly_ctx_get_yanglib_data() does not work (returns ::LY_EINVAL) until
                                         the ietf-yang-library module is loaded manually. While any revision
                                         of this schema can be loaded with this option, note that the only
-                                        revisions implemented by ly_ctx_info() are 2016-04-09 and 2018-01-17.
+                                        revisions implemented by ::ly_ctx_get_yanglib_data() are 2016-06-21 and 2019-01-04.
                                         This option cannot be changed on existing context. */
 #define LY_CTX_DISABLE_SEARCHDIRS 0x08  /**< Do not search for schemas in context's searchdirs neither in current
                                         working directory. It is entirely skipped and the only way to get
-                                        schema data for imports or for ly_ctx_load_module() is to use the
-                                        callbacks provided by caller via ly_ctx_set_module_imp_clb() */
+                                        schema data for imports or for ::ly_ctx_load_module() is to use the
+                                        callbacks provided by caller via ::ly_ctx_set_module_imp_clb() */
 #define LY_CTX_DISABLE_SEARCHDIR_CWD 0x10 /**< Do not automatically search for schemas in current working
                                         directory, which is by default searched automatically (despite not
                                         recursively). */
@@ -184,11 +190,11 @@
  * to work with a single context in which libyang is holding all schemas (and other internal
  * information) according to which the data trees will be processed and validated. So, the schema
  * trees are tightly connected with the specific context and they are held by the context internally
- * - caller does not need to keep pointers to the schemas returned by lys_parse(), context knows
- * about them. The data trees created with lyd_parse() are still connected with the specific context,
+ * - caller does not need to keep pointers to the schemas returned by ::lys_parse(), context knows
+ * about them. The data trees created with \b lyd_parse_*() are still connected with the specific context,
  * but they are not internally held by the context. The data tree just points and lean on some data
  * held by the context (schema tree, string dictionary, etc.). Therefore, in case of data trees, caller
- * is supposed to keep pointers returned by the lyd_parse() and manage the data tree on its own. This
+ * is supposed to keep pointers returned by the \b lyd_parse_*() functions and manage the data tree on its own. This
  * also affects the number of instances of both tree types. While you can have only one instance of
  * specific schema connected with a single context, number of data tree instances is not connected.
  *
@@ -203,7 +209,7 @@
 /**
  * @brief Add the search path into libyang context
  *
- * To reset search paths set in the context, use ly_ctx_unset_searchdir() and then
+ * To reset search paths set in the context, use ::ly_ctx_unset_searchdir() and then
  * set search paths again.
  *
  * @param[in] ctx Context to be modified.
@@ -215,7 +221,7 @@
 /**
  * @brief Clean the search path(s) from the libyang context
  *
- * To remove the recently added search path(s), use ly_ctx_unset_searchdir_last().
+ * To remove the recently added search path(s), use ::ly_ctx_unset_searchdir_last().
  *
  * @param[in] ctx Context to be modified.
  * @param[in] value Searchdir to be removed, use NULL to remove them all.
@@ -226,7 +232,7 @@
 /**
  * @brief Remove the least recently added search path(s) from the libyang context.
  *
- * To remove a specific search path by its value, use ly_ctx_unset_searchdir().
+ * To remove a specific search path by its value, use ::ly_ctx_unset_searchdir().
  *
  * @param[in] ctx Context to be modified.
  * @param[in] count Number of the searchdirs to be removed (starting by the least recently added).
@@ -271,7 +277,7 @@
 
 /**
  * @brief Get current ID of the modules set. The value is available also
- * as module-set-id in ly_ctx_info() result.
+ * as module-set-id in ::ly_ctx_get_yanglib_data() result.
  *
  * @param[in] ctx Context to be examined.
  * @return Numeric identifier of the current context's modules set.
@@ -409,7 +415,7 @@
 struct lys_module *ly_ctx_get_module_implemented_ns(const struct ly_ctx *ctx, const char *ns);
 
 /**
- * @brief Get a schema node based on the given data path (JSON format, see @ref howtoxpath).
+ * @brief Get a schema node based on the given data path (JSON format, see @ref howtoXPath).
  *
  * @param[in] ctx libyang context, set for absolute paths.
  * @param[in] ctx_node Starting context node for a relative data path, set for relative paths.
@@ -425,13 +431,13 @@
  *
  * When a (sub)module is imported/included without revision, the latest revision is
  * searched. libyang searches for the latest revision in searchdirs and/or via provided
- * import callback ly_module_imp_clb() just once. Then it is expected that the content
+ * import callback ::ly_module_imp_clb() just once. Then it is expected that the content
  * of searchdirs or data returned by the callback does not change. So when it changes,
  * it is necessary to force searching for the latest revision in case of loading another
  * module, which what this function does.
  *
  * The latest revision information is also reset when the searchdirs set changes via
- * ly_ctx_set_searchdir().
+ * ::ly_ctx_set_searchdir().
  *
  * @param[in] ctx libyang context where the latest revision information is going to be reset.
  */
@@ -490,13 +496,13 @@
  * multiple contexts, the function should be called for each used context.
  *
  * All instance data are supposed to be freed before destroying the context.
- * Data models are destroyed automatically as part of ly_ctx_destroy() call.
+ * Data models are destroyed automatically as part of ::ly_ctx_destroy() call.
  *
  * @param[in] ctx libyang context to destroy
  * @param[in] private_destructor Optional destructor function for private objects assigned
- * to the nodes via lys_set_private(). If NULL, the private objects are not freed by libyang.
+ * to the nodes via ::lysc_set_private(). If NULL, the private objects are not freed by libyang.
  * Remember the differences between the structures derived from ::lysc_node and always check
- * ::lysc_node#nodetype.
+ * ::lysc_node.nodetype.
  */
 void ly_ctx_destroy(struct ly_ctx *ctx, void (*private_destructor)(const struct lysc_node *node, void *priv));
 
diff --git a/src/dict.h b/src/dict.h
index 69bf7d3..68e1081 100644
--- a/src/dict.h
+++ b/src/dict.h
@@ -29,11 +29,37 @@
 struct ly_ctx;
 
 /**
+ * @page howtoContextDict Context Dictionary
+ *
+ * Context includes dictionary to store strings more effectively. The most of strings repeats quite often in schema
+ * as well as data trees. Therefore, instead of allocating those strings each time they appear, libyang stores them
+ * as records in the dictionary. The basic API to the context dictionary is public, so even a caller application can
+ * use the dictionary.
+ *
+ * To insert a string into the dictionary, caller can use ::lydict_insert() (adding a constant string) or
+ * ::lydict_insert_zc() (for dynamically allocated strings that won't be used by the caller after its insertion into
+ * the dictionary). Both functions provide the pointer to the inserted string in the dictionary record.
+ *
+ * To remove (reference of the) string from the context dictionary, ::lydict_remove() is supposed to be used.
+ *
+ * \note Incorrect usage of the dictionary can break libyang functionality.
+ *
+ * \note API for this group of functions is described in the [Dictionary module](@ref dict).
+ *
+ * Functions List
+ * --------------
+ * - ::lydict_insert()
+ * - ::lydict_insert_zc()
+ * - ::lydict_remove()
+ */
+
+/**
  * @defgroup dict Dictionary
  * @{
  *
  * Publicly visible functions and values of the libyang dictionary. They provide
- * access to the strings stored in the libyang context.
+ * access to the strings stored in the libyang context. More detailed information can be found at
+ * @ref howtoContextDict page.
  */
 
 /**
diff --git a/src/hash_table.h b/src/hash_table.h
index 22f49c4..8e135b0 100644
--- a/src/hash_table.h
+++ b/src/hash_table.h
@@ -28,8 +28,8 @@
  *
  * Usage:
  * - init hash to 0
- * - repeatedly call dict_hash_multi(), provide hash from the last call
- * - call dict_hash_multi() with key_part = NULL to finish the hash
+ * - repeatedly call ::dict_hash_multi(), provide hash from the last call
+ * - call ::dict_hash_multi() with key_part = NULL to finish the hash
  */
 uint32_t dict_hash_multi(uint32_t hash, const char *key_part, size_t len);
 
@@ -202,7 +202,7 @@
 LY_ERR lyht_insert(struct hash_table *ht, void *val_p, uint32_t hash, void **match_p);
 
 /**
- * @brief Insert a value into hash table. Same functionality as lyht_insert()
+ * @brief Insert a value into hash table. Same functionality as ::lyht_insert()
  * but allows to specify a temporary val equal callback to be used in case the hash table
  * will be resized after successful insertion.
  *
@@ -232,7 +232,7 @@
 LY_ERR lyht_remove(struct hash_table *ht, void *val_p, uint32_t hash);
 
 /**
- * @brief Remove a value from a hash table. Same functionality as lyht_remove()
+ * @brief Remove a value from a hash table. Same functionality as ::lyht_remove()
  * but allows to specify a temporary val equal callback to be used in case the hash table
  * will be resized after successful removal.
  *
diff --git a/src/json.h b/src/json.h
index 2f32b28..37fbc8d 100644
--- a/src/json.h
+++ b/src/json.h
@@ -109,13 +109,13 @@
 LY_ERR lyjson_ctx_next(struct lyjson_ctx *jsonctx, enum LYJSON_PARSER_STATUS *status);
 
 /**
- * @brief Backup the JSON parser context's state To restore the backup, use lyjson_ctx_restore().
+ * @brief Backup the JSON parser context's state To restore the backup, use ::lyjson_ctx_restore().
  * @param[in] jsonctx JSON parser context to backup.
  */
 void lyjson_ctx_backup(struct lyjson_ctx *jsonctx);
 
 /**
- * @brief REstore the JSON parser context's state from the backup created by lyjson_ctx_backup().
+ * @brief REstore the JSON parser context's state from the backup created by ::lyjson_ctx_backup().
  * @param[in] jsonctx JSON parser context to restore.
  */
 void lyjson_ctx_restore(struct lyjson_ctx *jsonctx);
diff --git a/src/libyang.h b/src/libyang.h
index 14eb110..a5570e6 100644
--- a/src/libyang.h
+++ b/src/libyang.h
@@ -44,22 +44,22 @@
  *
  * @section about-features Main Features
  *
- * - [Parsing (and validating) schemas](@ref howtoschemasparsers) in YANG format.
- * - [Parsing (and validating) schemas](@ref howtoschemasparsers) in YIN format.
- * - [Parsing, validating and printing instance data](@ref howtodata) in XML format.
- * - [Parsing, validating and printing instance data](@ref howtodata) in JSON format
+ * - [Parsing (and validating) schemas](@ref howtoSchema) in YANG format.
+ * - [Parsing (and validating) schemas](@ref howtoSchema) in YIN format.
+ * - [Parsing, validating and printing instance data](@ref howtoData) in XML format.
+ * - [Parsing, validating and printing instance data](@ref howtoData) in JSON format
  *   ([RFC 7951](https://tools.ietf.org/html/rfc7951)).
- * - [Manipulation with the instance data](@ref howtodatamanipulators).
- * - Support for [default values in the instance data](@ref howtodatawd) ([RFC 6243](https://tools.ietf.org/html/rfc6243)).
- * - Support for [YANG extensions and user types](@ref howtoschemaplugins).
- * - Support for [YANG Metadata](@ref howtoschemametadata) ([RFC 7952](https://tools.ietf.org/html/rfc6243)).
+ * - [Manipulation with the instance data](@ref howtoDataManipulation).
+ * - Support for [default values in the instance data](@ref howtoDataWD) ([RFC 6243](https://tools.ietf.org/html/rfc6243)).
+ * - Support for [YANG extensions and user types](@ref howtoPlugins).
+ * - Support for [YANG Metadata](@ref howtoPluginsExtensionsMetadata) ([RFC 7952](https://tools.ietf.org/html/rfc6243)).
  *
  * The current implementation covers YANG 1.0 ([RFC 6020](https://tools.ietf.org/html/rfc6020)) as well as
  * YANG 1.1 ([RFC 7950](https://tools.ietf.org/html/rfc7950)).
  *
  * @section about-license License
  *
- * Copyright (c) 2015-2017 CESNET, z.s.p.o.
+ * Copyright (c) 2015-2020 CESNET, z.s.p.o.
  *
  * (The BSD 3-Clause License)
  *
@@ -80,15 +80,65 @@
 /**
  * @page howto libyang API Overview
  *
- * - @subpage howtocontext
- * - @subpage howtoschemas
- * - @subpage howtodata
- * - @subpage howtoxpath
- * - @subpage howtoxml
- * - @subpage howtothreads
- * - @subpage howtologger
- * - @subpage howtoplugins
- * - @subpage howtostructures
+ * @section howtoGeneral General notes
+ *
+ * libyang is primarily intended for handling data modeled by YANG modeling language, so the library is supposed to be optimized
+ * for this purpose. However, as a side effect, the library has to be able precisely process YANG modules. Thus, it is usable by
+ * YANG module authors to validate their modules and schemas in the development process.
+ *
+ * - @subpage howtoStructures
+ * - @subpage howtoErrors
+ * - @subpage howtoLogger
+ * - @subpage howtoThreads
+ * - @subpage howtoContext
+ * - @subpage howtoParsers
+ * - @subpage howtoPrinters
+ * - @subpage howtoSchema
+ * - @subpage howtoData
+ * - @subpage howtoXPath
+ * - @subpage howtoPlugins
+ */
+
+/**
+ * @page howtoStructures Data Structures
+ *
+ * @section sizedarrays Sized Arrays
+ *
+ * The structure starts with 32bit number storing size of the array - the number of the items inside. The size is part of the
+ * array to have it allocated together with the array itself only when it is needed. However, the pointers to the array always
+ * points after the 32b number, so items can be accessed directly as for standard C arrays. Because of a known size (available
+ * via ::LY_ARRAY_COUNT macro), it is not terminated by any special byte (sequence), so there is also no limitation for specific
+ * content of the stored records (e.g. that first byte must not be NULL).
+ *
+ * The sized arrays must be carefully freed (which should be done anyway only internally), since pointers to the sized arrays used
+ * in libyang structures, does not point to the beginning of the allocated space.
+ *
+ * - ::LY_ARRAY_COUNT
+ * - ::LY_ARRAY_FOR
+ *
+ * @section struct_lists Lists
+ *
+ * The lists are structures connected via a `next` and `prev` pointers. Iterating over the siblings can be simply done by
+ * ::LY_LIST_FOR macro. Examples of such structures are ::lyd_node or ::lysc_node.
+ *
+ * The `prev` pointer is always filled. In case there is just a single item in the list, the `prev` pointer points to the
+ * item itself. Otherwise, the `prev` pointer of the first item points to the last item of the list. In contrast, the
+ * `next` pointer of the last item in the list is always NULL.
+ */
+
+/**
+ * @page howtoPlugins Plugins
+ *
+ * libyang supports several types of plugins to better support generic features of YANG that need some specific code for
+ * their specific instances in YANG schemas. This is the case of YANG types, which are derived from YANG built-in types
+ * (which are implemented by libyang), but the description of the derived type can specify some additional requirements or
+ * restriction that cannot be implemented generically and some special code is needed. The second case for libyang plugins
+ * are YANG extensions. For YANG extensions, most of the specification stays in their description (e.g. allowed substatements
+ * or place of the extension instanciation) and libyang is not able to process such a text in a generic way. In both cases,
+ * libyang provides API to provide functionality implementing the specifics of each type or extension.
+ *
+ * - @subpage howtoPluginsTypes
+ * - @subpage howtoPluginsExtensions
  */
 
 /**
@@ -100,39 +150,6 @@
  * for libyang developers. The texts should explain various decisions made and internal processes utilized in libyang.
  */
 
-/**
- * @page howtostructures Data Structures
- *
- * @section sizedarrays Sized Arrays
- *
- * The structure starts with 32bit number storing size of the array - the number of the items inside. The size is part of the
- * array to have it allocated together with the array itself only when it is needed. However, the pointers to the array always
- * points after the 32b number, so items can be accessed directly as for standard C arrays. Because of a known size (available
- * via ::LY_ARRAY_SIZE macro), it is not terminated by any special byte (sequence), so there is also no limitation for specific
- * content of the stored records (e.g. that first byte must not be NULL).
- *
- * The sized arrays must be carefully freed (which should be done anyway only internally), since pointers to the sized arrays used
- * in libyang structures, does not point to the beginning of the allocated space.
- *
- * - ::LY_ARRAY_SIZE
- * - ::LY_ARRAY_FOR
- *
- * @section struct_lists Lists
- *
- * The lists are structures connected via a `next` pointer. Iterating over the siblings can be simply done by ::LY_LIST_FOR macro.
- */
-
-/**
- * @page howtoplugins Plugins
- *
- * libyang supports several types of plugins to better support generic features of YANG that need some specific code for
- * their specific instances in YANG schemas. This is the case of YANG types, which are derived from YANG built-in types
- * (which are implemented by libyang), but the description of the derived type can specify some additional requirements or
- * restriction that cannot be implemented generically and some special code is needed. The second case for libyang plugins
- * are YANG extensions. For YANG extensions, most of the specification stays in their description (e.g. allowed substatements
- * or place of the extension instanciation) and libyang is not able to process such a text in a generic way. In both cases,
- * libyang provides API to provide functionality implementing the specifics of each type or extension.
- */
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/log.h b/src/log.h
index 27e6fcd..1766fbe 100644
--- a/src/log.h
+++ b/src/log.h
@@ -32,11 +32,50 @@
 typedef uint8_t ly_bool;
 
 /**
+ * @page howtoLogger Information Logging
+ *
+ * The libyang logger is supposed to process all the messages (and some other accompanied information) generated by the performed
+ * functions. According to the logger settings, the information can be printed, stored or further processed by a callback
+ * functions.
+ *
+ * The logger is tightly connected with [errors handling](@ref howtoErrors), because when an error appears, the logger (according
+ * to [logger options](@ref logopts)) generates error records available via libyang context.
+ *
+ * There are 4 verbosity levels defined as ::LY_LOG_LEVEL. The level can be changed by the ::ly_log_level() function.
+ * By default, the verbosity level is set to #LY_LLERR value, so only the errors are processed.
+ *
+ * By default, all libyang messages are printed to `stderr`. However, the callers are able to set their own logging callback
+ * function (::ly_log_clb). In that case, instead of printing messages, libyang passes error level, message and path (if any) to
+ * the caller's callback function set via ::ly_set_log_clb(). In case of error level, the error information is still
+ * automatically stored and available via the [error handling functions](@ref howtoErrors).
+ *
+ * With [logging options](@ref logopts) set via ::ly_log_options(), the caller can modify what is done with all the messages.
+ * Default flags are ::LY_LOLOG and ::LY_LOSTORE_LAST so that messages are logged and the last one is stored. If you set the flag
+ * ::LY_LOSTORE, all the messages will be stored. Be careful because unless you regularly clean them, the error list in context
+ * will grow indefinitely.
+ *
+ * As a separate group, there are @ref dbggroup to select group of debugging messages to print. The options can be set via
+ * ::ly_log_dbg_groups() function, but note that the options take effect only in case the libyang is compiled in
+ * [Debug build mode](@ref building).
+ *
+ * \note API for this group of functions is described in the [logger module](@ref log).
+ *
+ * Functions List
+ * --------------
+ * - ::ly_log_level()
+ * - ::ly_log_dbg_groups()
+ * - ::ly_log_options()
+ * - ::ly_set_log_clb()
+ * - ::ly_get_log_clb()
+ *
+ */
+
+/**
  * @defgroup log Logger
  * @{
  *
  * Publicly visible functions and values of the libyang logger. For more
- * information, see \ref howtologger.
+ * information, see \ref howtoLogger.
  */
 
 /**
@@ -49,7 +88,7 @@
     LY_LLWRN = 1, /**< Print error and warning messages. */
     LY_LLVRB = 2, /**< Besides errors and warnings, print some other verbose messages. */
     LY_LLDBG = 3 /**< Print all messages including some development debug messages (be careful,
-     without subsequently calling ly_verb_dbg() no debug messages will be printed!). */
+     without subsequently calling ::ly_log_dbg_groups() no debug messages will be printed!). */
 } LY_LOG_LEVEL;
 
 /**
@@ -60,11 +99,13 @@
 LY_LOG_LEVEL ly_log_level(LY_LOG_LEVEL level);
 
 /**
- * @defgroup logopts Logging options
  * @ingroup logger
+ * @defgroup logopts Logging options
  *
  * Logging option bits of libyang.
  *
+ * Can be set via ::ly_log_options().
+ *
  * @{
  */
 #define LY_LOLOG        0x01 /**< Log messages normally, using callback if set. If not set, messages will
@@ -79,7 +120,7 @@
  */
 
 /**
- * @brief Set additional logger options. Default is #LY_LOLOG | #LY_LOSTORE_LAST.
+ * @brief Set logger options. Default is #LY_LOLOG | #LY_LOSTORE_LAST.
  *
  * @param[in] opts Bitfield of @ref logopts.
  * @return Previous logger options.
@@ -89,10 +130,12 @@
 #ifndef NDEBUG
 
 /**
- * @defgroup dbggroup Debug message groups
  * @ingroup log
+ * @defgroup dbggroup Debug messages groups
  *
- * Selected displayed debug message groups.
+ * Categories of the debug messages.
+ *
+ * Allows to show only the selected group(s) of the debug messages.
  *
  * @{
  */
@@ -120,7 +163,7 @@
  *
  * !IMPORTANT! If an error has a specific error-app-tag defined in the model, it will NOT be set
  *             at the time of calling this callback. It will be set right after, so to retrieve it
- *             it must be checked afterwards with ly_errapptag().
+ *             it must be checked afterwards with ::ly_errapptag().
  *
  * @param[in] level Log level of the message.
  * @param[in] msg Message.
@@ -149,7 +192,39 @@
 /** @} log */
 
 /**
+ * @page howtoErrors Errors Handling
+ *
+ * The most of the API functions directly returns error code in the form of ::LY_ERR value. In addition, if the ::LY_EVALID error
+ * arises, additional [validation error code](@ref ::LY_VECODE) is provided to categorize validation failures into several groups.
+ *
+ * All the errors arisen in connection with manipulation with the [context](@ref howtoContext), [YANG modules](@ref howtoSchema)
+ * or [YANG data](@ref howtoData), are recorded into the context and can be examined for the more detailed information. These
+ * records are stored as ::ly_err_item structures and they are not only context-specific, but also thread-specific.
+ *
+ * Storing error information is tightly connected with
+ * [logging](@ref howtoLogger). So the @ref logopts control if and which errors are stored in the context. By default, only the
+ * last error is recorded, so a new error replaces the previous one. This can be changed with ::LY_LOSTORE option set via
+ * ::ly_log_options(). Then, the errors are stored as a list preserving the previous error records. The stored records can be
+ * accessed using ::ly_err_last() or ::ly_err_first() functions. The ::ly_err_clean() is used to remove error records from the
+ * context.
+ *
+ * To print a specific error information via libyang logger, there is ::ly_err_print().
+ *
+ * To simplify access to the last error record in the context, there is a set of functions returning important error information.
+ * - ::ly_errapptag()
+ * - ::ly_errcode()
+ * - ::ly_vecode()
+ * - ::ly_errmsg()
+ * - ::ly_errpath()
+ *
+ * \note API for this group of functions is described in the [error information module](@ref errors).
+ */
+
+/**
  * @defgroup errors Error information
+ *
+ * Structures and functions to allow error information processing.
+ *
  * @{
  */
 
@@ -178,10 +253,10 @@
 } LY_ERR;
 
 /**
+ * @ingroup logger
  * @typedef LY_VECODE
  * @brief libyang's codes of validation error. Whenever ly_errno is set to LY_EVALID, the ly_vecode is also set
  * to the appropriate LY_VECODE value.
- * @ingroup logger
  */
 typedef enum {
     LYVE_SUCCESS = 0,  /**< no error */
@@ -235,7 +310,7 @@
  * a specific error message, it will be used instead the default one.
  *
  * Sometimes, the error message is extended with path of the element where the problem is.
- * The path is available via ly_errpath().
+ * The path is available via ::ly_errpath().
  *
  * @param[in] ctx Relative context.
  * @return Text of the last error message, empty string if there is no error.
@@ -245,7 +320,7 @@
 /**
  * @brief Get the last (thread, context-specific) path of the element where was an error.
  *
- * The path always corresponds to the error message available via ly_errmsg(), so
+ * The path always corresponds to the error message available via ::ly_errmsg(), so
  * whenever a subsequent error message is printed, the path is erased or rewritten.
  * The path reflects the type of the processed tree - data path for data tree functions
  * and schema path in case of schema tree functions. In case of processing YIN schema
@@ -261,7 +336,7 @@
  * @brief Get the last (thread, context-specific) error-app-tag if there was a specific one defined
  * in the module for the last error.
  *
- * The app-tag always corresponds to the error message available via ly_errmsg(), so
+ * The app-tag always corresponds to the error message available via ::ly_errmsg(), so
  * whenever a subsequent error message is printed, the app-tag is erased or rewritten.
  *
  * @param[in] ctx Relative context.
diff --git a/src/parser.h b/src/parser.h
index 9375bef..1965f82 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -24,6 +24,54 @@
 #endif
 
 /**
+ * @page howtoParsers Input Processing
+ *
+ * libyang provides a mechanism to generalize work with the inputs (and [outputs](@ref howtoPrinters)) 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.
+ *
+ * The API allows to alter the source of the data behind the handler by another source. Also reseting a seekable source
+ * input is possible with ::ly_in_reset() to re-read the input.
+ *
+ * @note
+ * Currently, libyang supports only reading data from standard (disk) file, not from sockets, pipes, etc. The reason is
+ * that the parsers expects all the data to be present in the file (input data are complete). In future, we would like
+ * to change the internal mechanism and support sequential processing of the input data. In XML wording - we have DOM
+ * parser, but in future we would like to move to something like a SAX parser.
+ *
+ * @note
+ * This mechanism was introduced in libyang 2.0. To simplify transition from libyang 1.0 to version 2.0 and also for
+ * some simple use case where using the input handler would be an overkill, there are some basic parsers functions
+ * that do not require input handler. But remember, that functionality of these function can be limited in particular cases
+ * in contrast to the functions using input handlers.
+ *
+ * Functions List
+ * --------------
+ * - ::ly_in_new_fd()
+ * - ::ly_in_new_file()
+ * - ::ly_in_new_filepath()
+ * - ::ly_in_new_memory()
+ *
+ * - ::ly_in_fd()
+ * - ::ly_in_file()
+ * - ::ly_in_filepath()
+ * - ::ly_in_memory()
+ *
+ * - ::ly_in_type()
+ * - ::ly_in_parsed()
+ *
+ * - ::ly_in_reset()
+ * - ::ly_in_free()
+ *
+ * libyang Parsers List
+ * --------------------
+ * - @subpage howtoSchemaParsers
+ * - @subpage howtoDataParsers
+ */
+
+/**
+ * @struct ly_in
  * @brief Parser input structure specifying where the data are read.
  */
 struct ly_in;
@@ -53,7 +101,7 @@
  * Note that in case the underlying output is not seekable (stream referring a pipe/FIFO/socket or the callback output type),
  * nothing actually happens despite the function succeeds. Also note that the medium is not returned to the state it was when
  * the handler was created. For example, file is seeked into the offset zero, not to the offset where it was opened when
- * ly_in_new_file() was called.
+ * ::ly_in_new_file() was called.
  *
  * @param[in] in Input handler.
  * @return LY_SUCCESS in case of success
@@ -105,7 +153,7 @@
  * @brief Create input handler using memory to read data.
  *
  * @param[in] str Pointer where to start reading data. The input data are expected to be NULL-terminated.
- * Note that in case the destroy argument of ly_in_free() is used, the input string is passed to free(),
+ * Note that in case the destroy argument of ::ly_in_free() is used, the input string is passed to free(),
  * so if it is really a static string, do not use the destroy argument!
  * @param[out] in Created input handler supposed to be passed to different ly*_parse() functions.
  * @return LY_SUCCESS in case of success
@@ -118,7 +166,7 @@
  *
  * @param[in] in Input handler.
  * @param[in] str String containing the data to read. The input data are expected to be NULL-terminated.
- * Note that in case the destroy argument of ly_in_free() is used, the input string is passed to free(),
+ * Note that in case the destroy argument of ::ly_in_free() is used, the input string is passed to free(),
  * so if it is really a static string, do not use the destroy argument!
  * @return Previous starting address to read data from. Note that the caller is responsible to free
  * the data in case of changing string pointer @p str.
diff --git a/src/parser_data.h b/src/parser_data.h
index 4b16efc..02c8806 100644
--- a/src/parser_data.h
+++ b/src/parser_data.h
@@ -24,11 +24,94 @@
 struct ly_in;
 
 /**
+ * @page howtoDataParsers Parsing Data
+ *
+ * Data parser allows to read instances from a specific format. libyang supports the following data formats:
+ *
+ * - XML
+ *
+ *   Original data format used in NETCONF protocol. XML mapping is part of the YANG specification
+ *   ([RFC 6020](http://tools.ietf.org/html/rfc6020)).
+ *
+ * - JSON
+ *
+ *   The alternative data format available in RESTCONF protocol. Specification of JSON encoding of data modeled by YANG
+ *   can be found in [RFC 7951](http://tools.ietf.org/html/rfc7951). The specification does not cover RPCs, actions and
+ *   Notifications, so the representation of these data trees is proprietary and corresponds to the representation of these
+ *   trees in XML.
+ *
+ * While the parsers themselves process the input data only syntactically, all the parser functions actually incorporate
+ * the [common validator](@ref howtoDataValidation) checking the input data semantically. Therefore, the parser functions
+ * accepts two groups of options - @ref dataparseroptions and @ref datavalidationoptions.
+ *
+ * In contrast to the schema parser, data parser also accepts empty input data if such an empty data tree is valid
+ * according to the schemas in the libyang context (i.e. there are no top level mandatory nodes).
+ *
+ * There are individual functions to process different types of the data instances trees:
+ * - ::lyd_parse_data() is intended for standard configuration data trees. According to the given
+ *   [parser options](@ref dataparseroptions), the caller can further specify which kind of data tree is expected:
+ *   - *complete :running datastore*: this is the default case, possibly with the use of (some of) the
+ *     ::LYD_PARSE_STRICT, ::LYD_PARSE_OPAQ or ::LYD_VALIDATE_PRESENT options.
+ *   - *complete configuration-only datastore* (such as :startup): in this case it is necessary to except all state data
+ *     using ::LYD_PARSE_NO_STATE option.
+ *   - *incomplete datastore*: there are situation when the data tree is incomplete or invalid by specification. For
+ *     example the *:operational* datastore is not necessarily valid and results of the NETCONF's \<get\> or \<get-config\>
+ *     oprations used with filters will be incomplete (and thus invalid). This can be allowed using ::LYD_PARSE_ONLY,
+ *     the ::LYD_PARSE_NO_STATE should be used for the data returned by \<get-config\> operation.
+ * - ::lyd_parse_rpc() is used for parsing RPCs/Actions, optionally including the RPC envelopes known from the NETCONF
+ *   protocol.
+ * - ::lyd_parse_reply() processes reply to a previous RPC/Action, which must be provided.
+ * - ::lyd_parse_notif() is able to process complete Notification message.
+ *
+ * Further information regarding the processing input instance data can be found on the following pages.
+ * - @subpage howtoDataValidation
+ * - @subpage howtoDataWD
+ *
+ * Functions List
+ * --------------
+ * - ::lyd_parse_data()
+ * - ::lyd_parse_data_mem()
+ * - ::lyd_parse_data_fd()
+ * - ::lyd_parse_data_path()
+ * - ::lyd_parse_rpc()
+ * - ::lyd_parse_reply()
+ * - ::lyd_parse_notif()
+ */
+
+/**
+ * @page howtoDataValidation Validating Data
+ *
+ * Data validation is performed implicitly to the input data processed by the [parser](@ref howtoDataParsers) and
+ * on demand via the lyd_validate_*() functions. The explicit validation process is supposed to be used when a (complex or
+ * simple) change is done on the data tree (via [data manipulation](@ref howtoDataManipulation) functions) and the data
+ * tree is expected to be valid (it doesn't make sense to validate modified result of filtered \<get\> operation).
+ *
+ * Similarly to the [data parser](@ref howtoDataParsers), there are individual functions to validate standard data tree
+ * (::lyd_validate_all()) and RPC, Action and Notification (::lyd_validate_op()). For the standard data trees, it is possible
+ * to modify the validation process by @ref datavalidationoptions. This way the state data can be prohibited
+ * (::LYD_VALIDATE_NO_STATE) and checking for mandatory nodes can be limited to the YANG modules with already present data
+ * instances (::LYD_VALIDATE_PRESENT). Validation of the standard data tree can be also limited with ::lyd_validate_module()
+ * function, which scopes only to a specified single YANG module.
+ *
+ * Since the operation data trees (RPCs, Actions or Notifications) can reference (leafref, instance-identifier, when/must
+ * expressions) data from a datastore tree, ::lyd_validate_op() may require additional data tree to be provided. This is a
+ * difference in contrast to the parsing process, when the data are loaded from an external source and invalid reference
+ * outside the operation tree is acceptable.
+ *
+ * Functions List
+ * --------------
+ * - ::lyd_validate_all()
+ * - ::lyd_validate_module()
+ * - ::lyd_validate_op()
+ */
+
+/**
  * @addtogroup datatree
  * @{
  */
 
 /**
+ * @ingroup datatree
  * @defgroup dataparseroptions Data parser options
  *
  * Various options to change the data tree parsers behavior.
@@ -61,11 +144,11 @@
                                                  parsed are present). */
 #define LYD_PARSE_TRUSTED   0x020000        /**< Data are considered trusted so they will be parsed as validated. If the parsed
                                                  data are not valid, using this flag may lead to some unexpected behavior!
-                                                 This flag can be used only with #LYD_OPT_PARSE_ONLY. */
+                                                 This flag can be used only with #LYD_PARSE_ONLY. */
 #define LYD_PARSE_STRICT    0x040000        /**< Instead of silently ignoring data without schema definition raise an error.
-                                                 Do not combine with #LYD_OPT_OPAQ (except for ::LYD_LYB). */
+                                                 Do not combine with #LYD_PARSE_OPAQ (except for ::LYD_LYB). */
 #define LYD_PARSE_OPAQ      0x080000        /**< Instead of silently ignoring data without definition, parse them into
-                                                 an opaq node. Do not combine with #LYD_OPT_STRICT (except for ::LYD_LYB). */
+                                                 an opaq node. Do not combine with #LYD_PARSE_STRICT (except for ::LYD_LYB). */
 #define LYD_PARSE_NO_STATE  0x100000        /**< Forbid state data in the parsed data. */
 
 #define LYD_PARSE_LYB_MOD_UPDATE  0x200000  /**< Only for LYB format, allow parsing data printed using a specific module
@@ -74,8 +157,8 @@
 /** @} dataparseroptions */
 
 /**
- * @defgroup datavalidationoptions Data validation options
  * @ingroup datatree
+ * @defgroup datavalidationoptions Data validation options
  *
  * Various options to change data validation behaviour, both for the parser and separate validation.
  *
@@ -102,11 +185,13 @@
 /** @} datavalidationoptions */
 
 /**
- * @defgroup datavalidateop Operation to validate
  * @ingroup datatree
+ * @defgroup datavalidateop Operation to validate
  *
- * Operation provided to lyd_validate_op() to validate. The operation cannot be determined automatically since RPC/action and a reply to it
- * share the common top level node referencing the RPC/action schema node and may not have any input/output children to use for distinction.
+ * Operation provided to ::lyd_validate_op() to validate.
+ *
+ * The operation cannot be determined automatically since RPC/action and a reply to it share the common top level node
+ * referencing the RPC/action schema node and may not have any input/output children to use for distinction.
  */
 typedef enum {
     LYD_VALIDATE_OP_RPC = 1,   /**< Validate RPC/action request (input parameters). */
@@ -125,7 +210,7 @@
  * @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 Resulting data tree built from the input data. Note that NULL can be a valid result as a representation of an empty YANG data tree.
- * The returned data are expected to be freed using lyd_free_all().
+ * The returned data are expected to be freed using ::lyd_free_all().
  * @return LY_SUCCESS in case of successful parsing (and validation).
  * @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
  */
@@ -135,7 +220,7 @@
 /**
  * @brief Parse (and validate) input data as a YANG data tree.
  *
- * Wrapper around lyd_parse_data() hiding work with the input handler.
+ * Wrapper around ::lyd_parse_data() hiding work with the input handler.
  *
  * @param[in] ctx Context to connect with the tree being built here.
  * @param[in] data The input data in the specified @p format to parse (and validate).
@@ -143,7 +228,7 @@
  * @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 Resulting data tree built from the input data. Note that NULL can be a valid result as a representation of an empty YANG data tree.
- * The returned data are expected to be freed using lyd_free_all().
+ * The returned data are expected to be freed using ::lyd_free_all().
  * @return LY_SUCCESS in case of successful parsing (and validation).
  * @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
  */
@@ -153,7 +238,7 @@
 /**
  * @brief Parse (and validate) input data as a YANG data tree.
  *
- * Wrapper around lyd_parse_data() hiding work with the input handler.
+ * Wrapper around ::lyd_parse_data() hiding work with the input handler.
  *
  * @param[in] ctx Context to connect with the tree being built here.
  * @param[in] fd File descriptor of a regular file (e.g. sockets are not supported) containing the input data in the specified @p format to parse (and validate).
@@ -161,7 +246,7 @@
  * @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 Resulting data tree built from the input data. Note that NULL can be a valid result as a representation of an empty YANG data tree.
- * The returned data are expected to be freed using lyd_free_all().
+ * The returned data are expected to be freed using ::lyd_free_all().
  * @return LY_SUCCESS in case of successful parsing (and validation).
  * @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
  */
@@ -171,7 +256,7 @@
 /**
  * @brief Parse (and validate) input data as a YANG data tree.
  *
- * Wrapper around lyd_parse_data() hiding work with the input handler.
+ * Wrapper around ::lyd_parse_data() hiding work with the input handler.
  *
  * @param[in] ctx Context to connect with the tree being built here.
  * @param[in] path Path to the file with the input data in the specified @p format to parse (and validate).
@@ -179,7 +264,7 @@
  * @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 Resulting data tree built from the input data. Note that NULL can be a valid result as a representation of an empty YANG data tree.
- * The returned data are expected to be freed using lyd_free_all().
+ * The returned data are expected to be freed using ::lyd_free_all().
  * @return LY_SUCCESS in case of successful parsing (and validation).
  * @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
  */
@@ -194,10 +279,13 @@
  * \<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.
  *
+ * Similarly, in the case of LYD_JSON @p format, the same envelopes in form of JSON objects are accepted. Nothing
+ * corresponding to the XML attributes is accepted in this case.
+ *
  * @param[in] ctx Context to connect with the tree being built here.
  * @param[in] in The input handle to provide the dumped data in the specified @p format to parse (and validate).
  * @param[in] format Format of the input data to be parsed.
- * @param[out] tree Resulting full RPC/action tree built from the input data. The returned data are expected to be freed using lyd_free_all().
+ * @param[out] tree Resulting full RPC/action tree built from the input data. The returned data are expected to be freed using ::lyd_free_all().
  * In contrast to YANG data tree, result of parsing RPC/action cannot be NULL until an error occurs.
  * @param[out] op Optional pointer to the actual operation node inside the full action @p tree, useful only for action.
  * @return LY_SUCCESS in case of successful parsing (and validation).
@@ -212,12 +300,15 @@
  * In case o LYD_XML @p format, the \<rpc-reply\> envelope element is accepted if present. It is [checked](https://tools.ietf.org/html/rfc6241#section-4.2), an opaq
  * data node (lyd_node_opaq) is created and all its XML attributes are parsed and inserted into the node.
  *
+ * Similarly, in the case of LYD_JSON @p format, the same envelopes in form of JSON objects are accepted. Nothing
+ * corresponding to the XML attributes is processed in this case.
+ *
  * The reply data are strictly expected to be related to the provided RPC/action @p request.
  *
- * @param[in] request The RPC/action tree (result of lyd_parse_rpc()) of the request for the reply being parsed.
+ * @param[in] request The RPC/action tree (result of ::lyd_parse_rpc()) of the request for the reply being parsed.
  * @param[in] in The input handle to provide the dumped data in the specified @p format to parse (and validate).
  * @param[in] format Format of the input data to be parsed.
- * @param[out] tree Resulting full RPC/action reply tree built from the input data. The returned data are expected to be freed using lyd_free_all().
+ * @param[out] tree Resulting full RPC/action reply tree built from the input data. The returned data are expected to be freed using ::lyd_free_all().
  * The reply tree always includes duplicated operation node (and its parents) of the @p request, so in contrast to YANG data tree,
  * the result of parsing RPC/action reply cannot be NULL until an error occurs. At least one of the @p tree and @p op output variables must be provided.
  * @param[out] op Pointer to the actual operation node inside the full action reply @p tree, useful only for action. At least one of the @p op
@@ -234,10 +325,13 @@
  * In case o LYD_XML @p format, the \<notification\> envelope element in combination with the child \<eventTime\> element are accepted if present. They are
  * [checked](https://tools.ietf.org/html/rfc5277#page-25), opaq data nodes (lyd_node_opaq) are created and all their XML attributes are parsed and inserted into the nodes.
  *
+ * Similarly, in the case of LYD_JSON @p format, the same envelopes in form of JSON objects are accepted. Nothing
+ * corresponding to the XML attributes is accepted in this case.
+ *
  * @param[in] ctx Context to connect with the tree being built here.
  * @param[in] in The input handle to provide the dumped data in the specified @p format to parse (and validate).
  * @param[in] format Format of the input data to be parsed.
- * @param[out] tree Resulting full Notification tree built from the input data. The returned data are expected to be freed using lyd_free_all().
+ * @param[out] tree Resulting full Notification tree built from the input data. The returned data are expected to be freed using ::lyd_free_all().
  * In contrast to YANG data tree, result of parsing Notification cannot be NULL until an error occurs.
  * @param[out] ntf Optional pointer to the actual notification node inside the full Notification @p tree, useful for nested notifications.
  * @return LY_SUCCESS in case of successful parsing (and validation).
diff --git a/src/parser_internal.h b/src/parser_internal.h
index 79496c7..794dfc8 100644
--- a/src/parser_internal.h
+++ b/src/parser_internal.h
@@ -165,7 +165,7 @@
 LY_ERR lyd_parser_check_schema(struct lyd_ctx *lydctx, const struct lysc_node *snode);
 
 /**
- * @brief Wrapper around lyd_create_term() for data parsers.
+ * @brief Wrapper around ::lyd_create_term() for data parsers.
  *
  * @param[in] lydctx Data parser context.
  * @param[in] hints Data parser's hint for the value's type.
@@ -174,7 +174,7 @@
         ly_bool *dynamic, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, struct lyd_node **node);
 
 /**
- * @brief Wrapper around lyd_create_meta() for data parsers.
+ * @brief Wrapper around ::lyd_create_meta() for data parsers.
  *
  * @param[in] lydctx Data parser context.
  * @param[in] hints [Value hint](@ref lydvalhints) from the parser regarding the value type.
diff --git a/src/parser_schema.h b/src/parser_schema.h
index 22b49bf..957370f 100644
--- a/src/parser_schema.h
+++ b/src/parser_schema.h
@@ -23,12 +23,68 @@
 struct lys_module;
 
 /**
+ * @page howtoSchemaParsers Parsing YANG Modules
+ *
+ * YANG module parsers allow to read YANG module from a specific format. libyang supports the following module formats:
+ *
+ * - YANG
+ *
+ *   Basic YANG schemas format described in [RFC 6020](http://tools.ietf.org/html/rfc6020) and
+ *   [RFC 7951](http://tools.ietf.org/html/rfc7951) (so both YANG 1.0 and YANG 1.1 versions are supported).
+ *
+ * - YIN
+ *
+ *   Alternative XML-based format to YANG - YANG Independent Notation. The details can be found in
+ *   [RFC 6020](http://tools.ietf.org/html/rfc6020#section-11) and
+ *   [RFC 7951](http://tools.ietf.org/html/rfc7951#section-13).
+ *
+ * When the [context](@ref howtoContext) is created, it already contains the following YANG modules, which
+ * are implemented internally by libyang:
+ * - ietf-yang-metadata@2016-08-05
+ * - yang@2020-06-17
+ * - ietf-inet-types@2013-07-15
+ * - ietf-yang-types@2013-07-15
+ * - ietf-datastores@2018-02-14
+ * - ietf-yang-library@2019-01-04
+ *
+ * The `yang` module is the libyang's internal module to provide namespace and definitions of for various YANG
+ * attributes described in [RFC 7951](https://tools.ietf.org/html/rfc6243) (such as `insert` attribute for
+ * edit-config's data).
+ *
+ * Other modules can be added to the context manually with the functions listed below. Besides them,
+ * it is also possible to use ::ly_ctx_load_module() which tries to find the required module automatically - using
+ * ::ly_module_imp_clb or automatic search in working directory and in the context's search directories. For details, see
+ * [how the context works](@ref howtoContext).
+ *
+ * YANG modules are loaded in two steps. First, the input YANG/YIN data are parsed into \b lysp_* structures that reflect
+ * the structure of the input module and submodule(s). Mostly just syntax checks are done, no reference or type checking is
+ * performed in this step. If the module is supposed to be implemented, not just imported by another module, the second step
+ * is to compile it. The compiled tree may significantly differ from the source (parsed) tree structure. All the references
+ * 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,
+ * to simplify some of the usecases, it is also possible to use other functions accepting input data from various sources.
+ *
+ * Functions List
+ * --------------
+ * - ::lys_parse()
+ * - ::lys_parse_mem()
+ * - ::lys_parse_fd()
+ * - ::lys_parse_path()
+ *
+ * - ::lys_search_localfile()
+ * - ::ly_ctx_set_module_imp_clb()
+ * - ::ly_ctx_load_module()
+ */
+
+/**
  * @addtogroup schematree
  * @{
  */
 
 /**
- * @brief Schema input formats accepted by libyang [parser functions](@ref howtoschemasparsers).
+ * @brief Schema input formats accepted by libyang [parser functions](@ref howtoSchemaParsers).
  */
 typedef enum {
     LYS_IN_UNKNOWN = 0,  /**< unknown format, used as return value in case of error */
@@ -51,7 +107,7 @@
  * @brief Load a schema into the specified context.
  *
  * This function is comsidered for a simple use, if you have a complex usecase,
- * consider use of lys_parse() with a standalone input handler.
+ * consider use of ::lys_parse() with a standalone input handler.
  *
  * @param[in] ctx libyang context where to process the data model.
  * @param[in] data The string containing the dumped data model in the specified format.
@@ -67,7 +123,7 @@
  * \note Current implementation supports only reading data from standard (disk) file, not from sockets, pipes, etc.
  *
  * This function is comsidered for a simple use, if you have a complex usecase,
- * consider use of lys_parse() with a standalone input handler.
+ * consider use of ::lys_parse() with a standalone input handler.
  *
  * @param[in] ctx libyang context where to process the data model.
  * @param[in] fd File descriptor of a regular file (e.g. sockets are not supported) containing the schema
@@ -82,7 +138,7 @@
  * @brief Load a schema into the specified context from a file.
  *
  * This function is comsidered for a simple use, if you have a complex usecase,
- * consider use of lys_parse() with a standalone input handler.
+ * consider use of ::lys_parse() with a standalone input handler.
  *
  * @param[in] ctx libyang context where to process the data model.
  * @param[in] path Path to the file with the model in the specified format.
@@ -97,7 +153,7 @@
  *
  * @param[in] searchpaths NULL-terminated array of paths to be searched (recursively). Current working
  * directory is searched automatically (but non-recursively if not in the provided list). Caller can use
- * result of the ly_ctx_get_searchdirs().
+ * result of the ::ly_ctx_get_searchdirs().
  * @param[in] cwd Flag to implicitly search also in the current working directory (non-recursively).
  * @param[in] name Name of the schema to find.
  * @param[in] revision Revision of the schema to find. If NULL, the newest found schema filepath is returned.
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index 40fd29e..0569468 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -71,8 +71,8 @@
 /**
  * @brief Description of the extension instance substatements.
  *
- * Provided by extensions plugins to libyang's lyext_compile_stmts() to be able to correctly compile the content of extension instances.
- * Note that order of the defined records matters - just follow the values of enum ly_stmt and order the records from lower to higher values.
+ * Provided by extensions plugins to libyang to be able to correctly compile the content of extension instances.
+ * Note that order of the defined records matters - just follow the values of ::ly_stmt and order the records from lower to higher values.
  */
 struct lysc_ext_substmt {
     enum ly_stmt stmt;                     /**< allowed substatement */
@@ -88,14 +88,14 @@
 LY_ERR lys_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext, struct lysc_ext_substmt *substmts);
 
 /**
- * @brief Free the extension instance's data compiled with lys_compile_extension_instance().
+ * @brief Free the extension instance's data compiled with ::lys_compile_extension_instance().
  * TODO
  */
 void lysc_extension_instance_free(struct ly_ctx *ctx, struct lysc_ext_substmt *substmts);
 
 /**
  * @brief Duplicate the compiled extension (definition) structure.
- * TODO should this be in API? currently required for nacm_compile()
+ * TODO should this be in API? currently required by nacm_compile()
  * Instead of duplicating memory, the reference counter in the @p orig is increased.
  *
  * @param[in] orig The extension structure to duplicate.
@@ -107,7 +107,7 @@
  * @brief Update path in the compile context, which is used for logging where the compilation failed.
  *
  * @param[in] ctx Compile context with the path.
- * @param[in] parent Parent of the current node to check difference of the node's module. The current module is taken from lysc_ctx::mod.
+ * @param[in] parent Parent of the current node to check difference with the currently processed module (taken from @p ctx).
  * @param[in] name Name of the node to update path with. If NULL, the last segment is removed. If the format is `{keyword}`, the following
  * call updates the segment to the form `{keyword='name'}` (to remove this compound segment, 2 calls with NULL @p name must be used).
  */
@@ -140,7 +140,7 @@
  * @brief Callback to decide if data instance is valid according to the schema.
  *
  * The callback is used only for the extension instances placed in the following parent statements
- * (which is specified as lysc_ext_instance::parent_type):
+ * (which is specified as ::lysc_ext_instance.parent_type):
  *     - LYEXT_PAR_NODE - @p node is instance of the schema node where the extension instance was specified.
  *     - LYEXT_PAR_TPDF - @p node is instance of the schema node with the value of the typedef's type where the extension instance was specified.
  *     - LYEXT_PAR_TYPE - @p node is instance of the schema node with the value of the type where the extension instance was specified.
@@ -163,7 +163,7 @@
     lyext_clb_compile compile;          /**< Callback to compile extension instance from the parsed data */
     lyext_clb_data_validation validate; /**< Callback to decide if data instance is valid according to the schema. */
     /* TODO printers? (schema/data) */
-    lyext_clb_free free;                /**< Free the extension instance specific data created by lyext_plugin::compile callback */
+    lyext_clb_free free;                /**< Free the extension instance specific data created by ::lyext_plugin.compile callback */
 };
 
 struct lyext_plugins_list {
diff --git a/src/plugins_types.h b/src/plugins_types.h
index fa7d118..ffde8dc 100644
--- a/src/plugins_types.h
+++ b/src/plugins_types.h
@@ -36,15 +36,6 @@
 struct lysp_module;
 
 /**
- * @internal
- * @page internals
- *
- * @section types Types Processing
- *
- * @subsection types_
- */
-
-/**
  * @defgroup types Plugins - Types
  * @{
  *
@@ -52,8 +43,7 @@
  */
 
 /**
- * @page howtoplugins
- * @section Types
+ * @page howtoPluginsTypes
  *
  * YANG allows schemas to define new data types via *typedef* statement or even in leaf's/leaf-list's *type* statements.
  * Such types are derived (directly or indirectly) from a set of [YANG built-in types](https://tools.ietf.org/html/rfc7950#section-4.2.4).
@@ -66,19 +56,21 @@
  * - duplicate data in lyd_value and
  * - free the connected data from lyd_value.
  *
- * All these functions are provided to libyang via a set of callback functions specified as lysc_type_plugin.
+ * All these functions are provided to libyang via a set of callback functions specified as ::lysc_type_plugin.
  * All the callbacks are supposed to do not log directly via libyang logger. Instead, they return LY_ERR value and
- * ly_err_item error structure(s) describing the detected error(s) (helper functions ly_err_new() and ly_err_free()
+ * ::ly_err_item error structure(s) describing the detected error(s) (helper functions ::ly_err_new() and ::ly_err_free()
  * are available).
  *
- * The main functionality is provided via ::ly_type_store_clb callback responsible for validating, canonizing and storing
+ * The main functionality is provided via ::ly_type_store_clb callback responsible for canonizing and storing
  * provided string representation of the value in specified format (XML and JSON supported). Valid value is stored in
- * lyd_value structure - its union allows to store data as one of the predefined type or in a custom form behind
- * lyd_value's ptr member (`void*`). The callback is also responsible for storing original string representation of the
- * value as lyd_value::original. Optionally, the callback can utilize lyd_value::canonical_cache to store data for providing
- * canonical string representation via the ::ly_type_print_clb callback. Canonical value cannot be available directly, since
- * some types do not have/provide canonical value (respectively it may be multivalent according to the output format as
- * in the case of instance-identifiers).
+ * ::lyd_value structure - its union allows to store data as one of the predefined type or in a custom form behind
+ * the ptr member (void *) of ::lyd_value structure. The callback is also responsible for storing canonized string
+ * representation of the value as ::lyd_value.canonical. If the type does not define canonical representation, the original
+ * representation is stored. In case there are any differences between the representation in specific input types, the plugin
+ * is supposed to store the value in JSON representation - typically, the difference is in prefix representation and JSON
+ * format use directly the module names as prefixes. Optionally, in case the type requires some validation referencing other
+ * entities in the data tree, the ::ly_type_validate_clb can be implemented. The stored value can be printed into the
+ * required format via ::ly_type_print_clb implementation.
  */
 
 /**
@@ -91,12 +83,12 @@
  * @param[in] path Path to the node causing the error.
  * @param[in] apptag Error-app-tag value.
  * @return NULL in case of memory allocation failure.
- * @return Created error information structure that can be freed using ly_err_free().
+ * @return Created error information structure that can be freed using ::ly_err_free().
  */
 struct ly_err_item *ly_err_new(LY_LOG_LEVEL level, LY_ERR code, LY_VECODE vecode, char *msg, char *path, char *apptag);
 
 /**
- * @brief Destructor for the error records created with ly_err_new().
+ * @brief Destructor for the error records created with ::ly_err_new().
  *
  * Compatible with the free(), so usable as a generic callback.
  *
@@ -159,15 +151,15 @@
 /**
  * @brief Free compiled prefixes.
  *
- * @param[in] prefix Prefixes to free.
+ * @param[in] prefixes Prefixes to free.
  */
 void lysc_prefixes_free(struct lysc_prefix *prefixes);
 
 /**
- * @defgroup plugintypeopts Options for type plugin callbacks. The same set of the options is passed to
- * all the type's callbacks used together.
+ * @defgroup plugintypeopts Type store callback options.
  *
- * Options applicable to ly_type_store_clb().
+ * Options applicable to ::ly_type_store_clb().
+ *
  * @{
  */
 #define LY_TYPE_OPTS_DYNAMIC      0x01 /**< Flag for the dynamically allocated string value, in this case the value
@@ -192,12 +184,12 @@
  * @param[in] value_len Length (number of bytes) of the given \p value.
  * @param[in] options [Type plugin options](@ref plugintypeopts).
  * @param[in] format Input format of the value.
- * @param[in] prefix_data Format-specific data for resolving any prefixes (see ::ly_resolve_prefix).
+ * @param[in] prefix_data Format-specific data for resolving any prefixes (see ::ly_type_store_resolve_prefix).
  * @param[in] hints Bitmap of [value hints](@ref lydvalhints) of all the allowed value types.
  * @param[in] ctx_node The @p value schema context node.
  * @param[out] storage Storage for the value in the type's specific encoding. All the members should be filled by the plugin.
  * @param[out] err Optionally provided error information in case of failure. If not provided to the caller, a generic
- *             error message is prepared instead. The error structure can be created by ly_err_new().
+ *             error message is prepared instead. The error structure can be created by ::ly_err_new().
  * @return LY_SUCCESS on success,
  * @return LY_EINCOMPLETE in case the ::ly_type_validate_clb should be called to finish value validation in data,
  * @return LY_ERR value on error.
@@ -219,7 +211,7 @@
  * @param[in] tree External data tree (e.g. when validating RPC/Notification) with possibly referenced data.
  * @param[in,out] storage Storage of the value successfully filled by ::ly_type_store_clb. May be modified.
  * @param[out] err Optionally provided error information in case of failure. If not provided to the caller, a generic
- *             error message is prepared instead. The error structure can be created by ly_err_new().
+ *             error message is prepared instead. The error structure can be created by ::ly_err_new().
  * @return LY_SUCCESS on success,
  * @return LY_ERR value on error.
  */
@@ -244,7 +236,7 @@
  * @param[in] value Value to print.
  * @param[in] format Format in which the data are supposed to be printed.
  *            Only 2 formats are currently implemented: LYD_XML and LYD_JSON.
- * @param[in] prefix_data Format-specific data for getting any prefixes (see ::ly_get_prefix).
+ * @param[in] prefix_data Format-specific data for getting any prefixes (see ::ly_type_print_get_prefix()).
  * @param[out] dynamic Flag if the returned string is dynamically allocated. In such a case the caller is responsible
  *            for freeing it.
  * @return String with the value of @p value in specified @p format. According to the returned @p dynamic flag, caller
@@ -256,7 +248,7 @@
 
 /**
  * @brief Callback to duplicate data in data structure. Note that callback is even responsible for
- * duplicating lyd_value::canonized.
+ * duplicating ::lyd_value.canonical.
  *
  * @param[in] ctx libyang context of the @p dup. Note that the context of @p original and @p dup might not be the same.
  * @param[in] original Original data structure to be duplicated.
@@ -267,12 +259,12 @@
 typedef LY_ERR (*ly_type_dup_clb)(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup);
 
 /**
- * @brief Callback for freeing the user type values stored by ly_type_store_clb().
+ * @brief Callback for freeing the user type values stored by ::ly_type_store_clb.
  *
  * Note that this callback is responsible also for freeing the canonized member in the @p value.
  *
  * @param[in] ctx libyang ctx to enable correct manipulation with values that are in the dictionary.
- * @param[in,out] value Value structure to free the data stored there by the plugin's ly_type_store_clb() callback
+ * @param[in,out] value Value structure to free the data stored there by the plugin's ::ly_type_store_clb callback
  */
 typedef void (*ly_type_free_clb)(const struct ly_ctx *ctx, struct lyd_value *value);
 
@@ -312,7 +304,7 @@
  * @param[in] value Value string to parse.
  * @param[in] value_len Length of the @p value (mandatory parameter).
  * @param[out] ret Parsed integer value (optional).
- * @param[out] err Error information in case of failure. The error structure can be freed by ly_err_free().
+ * @param[out] err Error information in case of failure. The error structure can be freed by ::ly_err_free().
  * @return LY_ERR value according to the result of the parsing and validation.
  */
 LY_ERR ly_type_parse_int(const char *datatype, int base, int64_t min, int64_t max, const char *value, size_t value_len,
@@ -328,7 +320,7 @@
  * @param[in] value Value string to parse.
  * @param[in] value_len Length of the @p value (mandatory parameter).
  * @param[out] ret Parsed unsigned integer value (optional).
- * @param[out] err Error information in case of failure. The error structure can be freed by ly_err_free().
+ * @param[out] err Error information in case of failure. The error structure can be freed by ::ly_err_free().
  * @return LY_ERR value according to the result of the parsing and validation.
  */
 LY_ERR ly_type_parse_uint(const char *datatype, int base, uint64_t max, const char *value, size_t value_len,
@@ -342,7 +334,7 @@
  * @param[in] value Value string to parse.
  * @param[in] value_len Length of the @p value (mandatory parameter).
  * @param[out] ret Parsed decimal64 value representing original value * 10^fraction-digits (optional).
- * @param[out] err Error information in case of failure. The error structure can be freed by ly_err_free().
+ * @param[out] err Error information in case of failure. The error structure can be freed by ::ly_err_free().
  * @return LY_ERR value according to the result of the parsing and validation.
  */
 LY_ERR ly_type_parse_dec64(uint8_t fraction_digits, const char *value, size_t value_len, int64_t *ret, struct ly_err_item **err);
@@ -364,7 +356,7 @@
  * @param[in] range Range (length) restriction information.
  * @param[in] value Value to check. In case of basetypes using unsigned integer values, the value is actually cast to uint64_t.
  * @param[in] strval String representation of the @p value for error logging.
- * @param[out] err Error information in case of failure. The error structure can be freed by ly_err_free().
+ * @param[out] err Error information in case of failure. The error structure can be freed by ::ly_err_free().
  * @return LY_ERR value according to the result of the validation.
  */
 LY_ERR ly_type_validate_range(LY_DATA_TYPE basetype, struct lysc_range *range, int64_t value, const char *strval,
@@ -374,10 +366,10 @@
  * @brief Data type validator for pattern-restricted string values.
  *
  * @param[in] patterns ([Sized array](@ref sizedarrays)) of the compiled list of pointers to the pattern restrictions.
- * The array can be found in the lysc_type_str::patterns structure.
+ * The array can be found in the ::lysc_type_str.patterns structure.
  * @param[in] str String to validate.
  * @param[in] str_len Length (number of bytes) of the string to validate (mandatory).
- * @param[out] err Error information in case of failure or non-matching @p str. The error structure can be freed by ly_err_free().
+ * @param[out] err Error information in case of failure or non-matching @p str. The error structure can be freed by ::ly_err_free().
  * @return LY_SUCCESS when @p matches all the patterns.
  * @return LY_EVALID when @p does not match any of the patterns.
  * @return LY_ESYS in case of PCRE2 error.
diff --git a/src/printer.h b/src/printer.h
index 05ed3e2..b3de26a 100644
--- a/src/printer.h
+++ b/src/printer.h
@@ -25,6 +25,57 @@
 #endif
 
 /**
+ * @page howtoPrinters Output Processing
+ *
+ * libyang provides a mechanism to generalize work with the outputs (and [inputs](@ref howtoParsers)) 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()).
+ *
+ * Using a generic output handler avoids need to have a set of functions for each printer functionality and results in simpler API.
+ *
+ * The API allows to alter the target of the data behind the handler by another target (of the same type). Also reseting
+ * a seekable output is possible with ::ly_out_reset() to re-write the output.
+ *
+ * @note
+ * This mechanism was introduced in libyang 2.0. To simplify transition from libyang 1.0 to version 2.0 and also for
+ * some simple use case where using the output handler would be an overkill, there are some basic printer functions
+ * that do not require output handler. But remember, that functionality of these function can be limited in particular cases
+ * in contrast to the functions using output handlers.
+ *
+ * Functions List
+ * --------------
+ * - ::ly_out_new_clb()
+ * - ::ly_out_new_fd()
+ * - ::ly_out_new_file()
+ * - ::ly_out_new_filepath()
+ * - ::ly_out_new_memory()
+ *
+ * - ::ly_out_clb()
+ * - ::ly_out_clb_arg()
+ * - ::ly_out_fd()
+ * - ::ly_out_file()
+ * - ::ly_out_filepath()
+ * - ::ly_out_memory()
+ *
+ * - ::ly_out_type()
+ * - ::ly_out_printed()
+ *
+ * - ::ly_out_reset()
+ * - ::ly_out_free()
+ *
+ * - ::ly_print()
+ * - ::ly_print_flush()
+ * - ::ly_write()
+ *
+ * libyang Printers List
+ * --------------------
+ * - @subpage howtoSchemaPrinters
+ * - @subpage howtoDataPrinters
+ */
+
+/**
+ * @struct ly_out
  * @brief Printer output structure specifying where the data are printed.
  */
 struct ly_out;
@@ -62,7 +113,7 @@
  * Note that in case the underlying output is not seekable (stream referring a pipe/FIFO/socket or the callback output type),
  * nothing actually happens despite the function succeeds. Also note that the medium is not returned to the state it was when
  * the handler was created. For example, file is seeked into the offset zero and truncated, the content from the time it was opened with
- * ly_out_new_file() is not restored.
+ * ::ly_out_new_file() is not restored.
  *
  * @param[in] out Printer handler.
  * @return LY_SUCCESS in case of success
@@ -96,8 +147,9 @@
  * @brief Get or reset callback function associated with a callback printer handler.
  *
  * @param[in] out Printer handler.
- * @param[in] fd Optional value of a new file descriptor for the handler. If -1, only the current file descriptor value is returned.
- * @return Previous value of the file descriptor.
+ * @param[in] writeclb Optional argument providing a new printer callback function for the handler. If NULL, only the current
+ * printer callback is returned.
+ * @return Previous printer callback.
  */
 ly_write_clb ly_out_clb(struct ly_out *out, ly_write_clb writeclb);
 
@@ -167,7 +219,7 @@
  * @brief Get or change memory where the data are dumped.
  *
  * @param[in] out Printer handler.
- * @param[in] strp Optional new string pointer to store the resulting data, same rules as in ly_out_new_memory() are applied.
+ * @param[in] strp Optional new string pointer to store the resulting data, same rules as in ::ly_out_new_memory() are applied.
  * @param[in] size Size of the buffer provided via @p strp. In case it is 0, the buffer for the printed data
  * is newly allocated even if @p strp points to a pointer to an existing buffer. In case the @p strp is NULL, this
  * parameter is ignored.
@@ -179,6 +231,7 @@
  * @brief Create printer handler file of the given filename.
  *
  * @param[in] filepath Path of the file where to write data.
+ * @param[out] out Created printer handler supposed to be passed to different ly*_print() functions.
  * @return NULL in case of error.
  * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
  */
@@ -201,7 +254,7 @@
 /**
  * @brief Generic printer of the given format string into the specified output.
  *
- * Alternatively, ly_write() can be used.
+ * Alternatively, ::ly_write() can be used.
  *
  * @param[in] out Output specification.
  * @param[in] format Format string to be printed.
@@ -218,7 +271,7 @@
 /**
  * @brief Generic printer of the given string buffer into the specified output.
  *
- * Alternatively, ly_print() can be used.
+ * Alternatively, ::ly_print() can be used.
  *
  * @param[in] out Output specification.
  * @param[in] buf Memory buffer with the data to print.
diff --git a/src/printer_data.h b/src/printer_data.h
index c06c631..daafea2 100644
--- a/src/printer_data.h
+++ b/src/printer_data.h
@@ -29,27 +29,69 @@
 struct ly_out;
 
 /**
- * @defgroup dataprinterflags Data printer flags
- * @ingroup datatree
+ * @page howtoDataPrinters Printing Data
  *
- * Validity flags for data nodes.
+ * Data printers allows to serialize internal representation of a data tree in a specific format. libyang
+ * supports the following data formats for printing:
+ *
+ * - XML
+ *
+ *   Basic format as specified in rules of mapping YANG modeled data to XML in
+ *   [RFC 6020](http://tools.ietf.org/html/rfc6020).
+ *
+ * - JSON
+ *
+ *   The alternative data format available in RESTCONF protocol. Specification of JSON encoding of data modeled by YANG
+ *   can be found in [RFC 7951](https://tools.ietf.org/html/rfc7951).
+ *
+ * By default, both formats are printed with indentation (formatting), which can be avoided by ::LYD_PRINT_SHRINK
+ * [printer option](@ref dataprinterflags)). Other options adjust e.g. [with-defaults mode](@ref howtoDataWD).
+ *
+ * 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
+ * [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
+ * themselves.
+ *
+ * Functions List
+ * --------------
+ * - ::lyd_print_all()
+ * - ::lyd_print_tree()
+ * - ::lyd_print_mem()
+ * - ::lyd_print_fd()
+ * - ::lyd_print_file()
+ * - ::lyd_print_path()
+ * - ::lyd_print_clb()
+ */
+
+/**
+ * @ingroup datatree
+ * @defgroup dataprinterflags Data printer flags
+ *
+ * Options to change default behavior of the data printers.
  *
  * @{
  */
-#define LYD_PRINT_WITHSIBLINGS  0x01             /**< Flag for printing also the (following) sibling nodes of the data node. */
+#define LYD_PRINT_WITHSIBLINGS  0x01             /**< Flag for printing also the (following) sibling nodes of the data node.
+                                                      The flag is not allowed for ::lyd_print_all() and ::lyd_print_tree(). */
 #define LYD_PRINT_SHRINK        LY_PRINT_SHRINK  /**< Flag for output without indentation and formatting new lines. */
 #define LYD_PRINT_KEEPEMPTYCONT 0x04             /**< Preserve empty non-presence containers */
 #define LYD_PRINT_WD_MASK       0xF0             /**< Mask for with-defaults modes */
-#define LYD_PRINT_WD_EXPLICIT   0x00             /**< Explicit mode - print only data explicitly being present in the data tree.
-                                                      Note that this is the default value when no WD option is specified. */
-#define LYD_PRINT_WD_TRIM       0x10             /**< Do not print the nodes with the value equal to their default value */
-#define LYD_PRINT_WD_ALL        0x20             /**< Include implicit default nodes */
-#define LYD_PRINT_WD_ALL_TAG    0x40             /**< Same as #LYDP_WD_ALL but also adds attribute 'default' with value 'true' to
+#define LYD_PRINT_WD_EXPLICIT   0x00             /**< Explicit with-defaults mode. Only the data explicitly being present in
+                                                      the data tree are printed, so the implicitly added default nodes are
+                                                      not printed. Note that this is the default value when no WD option is
+                                                      specified. */
+#define LYD_PRINT_WD_TRIM       0x10             /**< Trim mode avoids printing the nodes with the value equal to their
+                                                      default value */
+#define LYD_PRINT_WD_ALL        0x20             /**< With this option, theInclude implicit default nodes */
+#define LYD_PRINT_WD_ALL_TAG    0x40             /**< Same as ::LYD_PRINT_WD_ALL but also adds attribute 'default' with value 'true' to
                                                       all nodes that has its default value. The 'default' attribute has namespace:
                                                       urn:ietf:params:xml:ns:netconf:default:1.0 and thus the attributes are
                                                       printed only when the ietf-netconf-with-defaults module is present in libyang
                                                       context (but in that case this namespace is always printed). */
-#define LYD_PRINT_WD_IMPL_TAG   0x80             /**< Same as LYDP_WD_ALL_TAG but the attributes are added only to the nodes that
+#define LYD_PRINT_WD_IMPL_TAG   0x80             /**< Same as ::LYD_PRINT_WD_ALL_TAG but the attributes are added only to the nodes that
                                                       are not explicitly present in the original data tree despite their
                                                       value is equal to their default value.  There is the same limitation regarding
                                                       the presence of ietf-netconf-with-defaults module in libyang context. */
diff --git a/src/printer_internal.h b/src/printer_internal.h
index cdc9d07..703d423 100644
--- a/src/printer_internal.h
+++ b/src/printer_internal.h
@@ -80,7 +80,7 @@
  * @param[in] module Main module.
  * @param[in] modp Parsed module to print.
  * @param[in] options Schema output options (see @ref schemaprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
 LY_ERR yang_print_parsed_module(struct ly_out *out, const struct lys_module *module, const struct lysp_module *modp, uint32_t options);
 
@@ -100,7 +100,7 @@
  * @param[in] module Main module.
  * @param[in] submodp Parsed submodule to print.
  * @param[in] options Schema output options (see @ref schemaprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @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);
 
@@ -114,7 +114,7 @@
  * @param[in] out Output specification.
  * @param[in] module Schema to be printed (the compiled member is used).
  * @param[in] options Schema output options (see @ref schemaprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
 LY_ERR yang_print_compiled(struct ly_out *out, const struct lys_module *module, uint32_t options);
 
@@ -128,7 +128,7 @@
  * @param[in] out Output specification.
  * @param[in] node Schema node to be printed including all its substatements.
  * @param[in] options Schema output options (see @ref schemaprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
 LY_ERR yang_print_compiled_node(struct ly_out *out, const struct lysc_node *node, uint32_t options);
 
@@ -139,7 +139,7 @@
  * @param[in] module Main module.
  * @param[in] modp Parsed module to print.
  * @param[in] options Schema output options (see @ref schemaprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @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);
 
@@ -150,7 +150,7 @@
  * @param[in] module Main module.
  * @param[in] submodp Parsed submodule to print.
  * @param[in] options Schema output options (see @ref schemaprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @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);
 
@@ -160,7 +160,7 @@
  * @param[in] out Output specification.
  * @param[in] root The root element of the (sub)tree to print.
  * @param[in] options [Data printer flags](@ref dataprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
 LY_ERR xml_print_data(struct ly_out *out, const struct lyd_node *root, uint32_t options);
 
@@ -170,7 +170,7 @@
  * @param[in] out Output specification.
  * @param[in] root The root element of the (sub)tree to print.
  * @param[in] options [Data printer flags](@ref dataprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
 LY_ERR json_print_data(struct ly_out *out, const struct lyd_node *root, uint32_t options);
 
@@ -180,7 +180,7 @@
  * @param[in] out Output structure.
  * @param[in] root The root element of the (sub)tree to print.
  * @param[in] options [Data printer flags](@ref dataprinterflags).
- * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
+ * @return LY_ERR value, number of the printed bytes is updated in ::ly_out.printed.
  */
 LY_ERR lyb_print_data(struct ly_out *out, const struct lyd_node *root, uint32_t options);
 
@@ -223,7 +223,7 @@
  *
  * @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.
+ * @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);
@@ -234,10 +234,10 @@
  * 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] 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.
+ * 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);
diff --git a/src/printer_schema.h b/src/printer_schema.h
index 1f69ff0..9ca5e7a 100644
--- a/src/printer_schema.h
+++ b/src/printer_schema.h
@@ -30,6 +30,57 @@
 struct lysc_node;
 struct lysp_submodule;
 
+
+/**
+ * @page howtoSchemaPrinters Module Printers
+ *
+ * Schema printers allows to serialize internal representations of a schema module in a specific format. libyang
+ * supports the following schema formats for printing:
+ *
+ * - YANG
+ *
+ *   Basic YANG schemas format described in [RFC 6020](http://tools.ietf.org/html/rfc6020) and
+ *   [RFC 7951](http://tools.ietf.org/html/rfc7951) (so both YANG 1.0 and YANG 1.1 versions are supported).
+ *
+ * - YANG compiled
+ *
+ *   Syntactically, this format is based on standard YANG format. In contrast to standard YANG format, YANG compiled format
+ *   represents the module how it is used by libyang - with all uses expanded, augments and deviations applied, etc.
+ *   (more details about the compiled modules can be found on @ref howtoContext page).
+ *
+ * - YIN
+ *
+ *   Alternative XML-based format to YANG - YANG Independent Notation. The details can be found in
+ *   [RFC 6020](http://tools.ietf.org/html/rfc6020#section-11) and
+ *   [RFC 7951](http://tools.ietf.org/html/rfc7951#section-13).
+ *
+ * - Tree Diagram
+ *
+ *   Simple tree diagram providing overview of the module. The details can be found in
+ *   [RFC 8340](https://tools.ietf.org/html/rfc8340).
+ *
+ * For simpler transition from libyang 1.x (and for some simple use cases), there are functions (::lys_print_clb(),
+ * ::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 ::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.
+ *
+ * Functions List
+ * --------------
+ * - ::lys_print_module()
+ * - ::lys_print_submodule()
+ * - ::lys_print_node()
+ *
+ * - ::lys_print_clb()
+ * - ::lys_print_fd()
+ * - ::lys_print_file()
+ * - ::lys_print_mem()
+ * - ::lys_print_path()
+ */
+
 /**
  * @addtogroup schematree
  * @{
@@ -37,6 +88,9 @@
 
 /**
  * @defgroup schemaprinterflags Schema output options
+ *
+ * Options to change default behavior of the schema printers.
+ *
  * @{
  */
 #define LYS_PRINT_SHRINK             LY_PRINT_SHRINK /**< Flag for output without indentation and formatting new lines. */
@@ -50,15 +104,14 @@
 /** @} schemaprinterflags */
 
 /**
- * @brief Schema output formats accepted by libyang [printer functions](@ref howtoschemasprinters).
+ * @brief Schema output formats accepted by libyang [printer functions](@ref howtoSchemaPrinters).
  */
 typedef enum {
     LYS_OUT_UNKNOWN = 0, /**< unknown format, used as return value in case of error */
     LYS_OUT_YANG = 1,    /**< YANG schema output format */
     LYS_OUT_YANG_COMPILED = 2, /**< YANG schema output format of the compiled schema tree */
     LYS_OUT_YIN = 3,     /**< YIN schema output format */
-
-    LYS_OUT_TREE         /**< Tree schema output format, for more information see the [printers](@ref howtoschemasprinters) page */
+    LYS_OUT_TREE         /**< Tree schema output format */
 } LYS_OUTFORMAT;
 
 /**
@@ -79,7 +132,7 @@
  * @param[in] out Printer handler for a specific output. Use ly_out_*() functions to create and free the handler.
  * @param[in] module Main module of the submodule to print.
  * @param[in] submodule Parsed submodule to print.
- * @param[in] format Output format.
+ * @param[in] format Output format (LYS_OUT_YANG_COMPILED is not supported).
  * @param[in] line_length Maximum characters to be printed on a line, 0 for unlimited. Only for #LYS_OUT_TREE printer.
  * @param[in] options Schema output options (see @ref schemaprinterflags).
  * @return LY_ERR value.
@@ -91,7 +144,7 @@
  * @brief Print schema tree in the specified format into a memory block.
  * It is up to caller to free the returned string by free().
  *
- * This is just a wrapper around lys_print() for simple use cases.
+ * This is just a wrapper around ::lys_print_module() for simple use cases.
  * In case of a complex use cases, use lys_print with ly_out output handler.
  *
  * @param[out] strp Pointer to store the resulting dump.
@@ -105,7 +158,7 @@
 /**
  * @brief Print schema tree in the specified format into a file descriptor.
  *
- * This is just a wrapper around lys_print() for simple use cases.
+ * This is just a wrapper around ::lys_print_module() for simple use cases.
  * In case of a complex use cases, use lys_print with ly_out output handler.
  *
  * @param[in] fd File descriptor where to print the data.
@@ -119,7 +172,7 @@
 /**
  * @brief Print schema tree in the specified format into a file stream.
  *
- * This is just a wrapper around lys_print() for simple use cases.
+ * This is just a wrapper around ::lys_print_module() for simple use cases.
  * In case of a complex use cases, use lys_print with ly_out output handler.
  *
  * @param[in] module Schema tree to print.
@@ -133,7 +186,7 @@
 /**
  * @brief Print schema tree in the specified format into a file.
  *
- * This is just a wrapper around lys_print() for simple use cases.
+ * This is just a wrapper around ::lys_print_module() for simple use cases.
  * In case of a complex use cases, use lys_print with ly_out output handler.
  *
  * @param[in] path File where to print the schema.
@@ -147,7 +200,7 @@
 /**
  * @brief Print schema tree in the specified format using a provided callback.
  *
- * This is just a wrapper around lys_print() for simple use cases.
+ * This is just a wrapper around ::lys_print_module() for simple use cases.
  * In case of a complex use cases, use lys_print with ly_out output handler.
  *
  * @param[in] module Schema tree to print.
@@ -164,7 +217,7 @@
  * @brief Schema node printer.
  *
  * @param[in] out Printer handler for a specific output. Use ly_out_*() functions to create and free the handler.
- * @param[in] node Schema node to print, lys_find_node() can be used to get it from a path string.
+ * @param[in] node Schema node to print.
  * @param[in] format Output format.
  * @param[in] line_length Maximum characters to be printed on a line, 0 for unlimited. Only for #LYS_OUT_TREE printer.
  * @param[in] options Schema output options (see @ref schemaprinterflags).
diff --git a/src/schema_compile.h b/src/schema_compile.h
index a233116..db4fa09 100644
--- a/src/schema_compile.h
+++ b/src/schema_compile.h
@@ -156,7 +156,7 @@
 /**
  * @brief Compile information from the identity statement
  *
- * The backlinks to the identities derived from this one are supposed to be filled later via lys_compile_identity_bases().
+ * The backlinks to the identities derived from this one are supposed to be filled later via ::lys_compile_identity_bases().
  *
  * @param[in] ctx_sc Compile context - alternative to the combination of @p ctx and @p parsed_mod.
  * @param[in] ctx libyang context.
@@ -195,7 +195,7 @@
  * the compilation is not finished (if-feature and extensions are missing) and all the features are permanently
  * disabled without a chance to change it. The list is used as target for any if-feature statement in any
  * implemented module to get valid data to evaluate its result. The compilation is finished via
- * lys_feature_precompile_finish() in implemented modules. In case a not implemented module becomes implemented,
+ * ::lys_feature_precompile_finish() in implemented modules. In case a not implemented module becomes implemented,
  * the precompiled list is reused to finish the compilation to preserve pointers already used in various compiled
  * if-feature structures.
  *
diff --git a/src/set.c b/src/set.c
index ea338fd..1eb229b 100644
--- a/src/set.c
+++ b/src/set.c
@@ -100,7 +100,7 @@
     struct ly_set *newset;
     uint32_t u;
 
-    LY_CHECK_ARG_RET(NULL, set, LY_EINVAL);
+    LY_CHECK_ARG_RET(NULL, set, newset_p, LY_EINVAL);
 
     newset = malloc(sizeof *newset);
     LY_CHECK_ERR_RET(!newset, LOGMEM(NULL), LY_EMEM);
diff --git a/src/set.h b/src/set.h
index 8db1b23..c3dbc2d 100644
--- a/src/set.h
+++ b/src/set.h
@@ -37,10 +37,10 @@
  * added to the set and according to its knowledge about the set content, it can access objects via the members
  * of the set union.
  *
- * Until ly_set_rm() or ly_set_rm_index() is used, the set keeps the order of the inserted items as they
+ * Until ::ly_set_rm() or ::ly_set_rm_index() is used, the set keeps the order of the inserted items as they
  * were added into the set, so the first added item is on array index 0.
  *
- * To free the structure, use ly_set_free() function, to manipulate with the structure, use other
+ * To free the structure, use ::ly_set_free() function, to manipulate with the structure, use other
  * ly_set_* functions.
  */
 struct ly_set
@@ -57,7 +57,7 @@
 /**
  * @brief Create and initiate new ::ly_set structure.
  *
- * @param[out] set Pointer to store the created ::ly_set structure.
+ * @param[out] set_p Pointer to store the created ::ly_set structure.
  * @return LY_SUCCESS on success.
  * @return LY_EINVAL in case of NULL @p set parameter.
  * @return LY_EMEM in case of memory allocation failure.
@@ -71,7 +71,10 @@
  * @param[in] duplicator Optional pointer to function that duplicates the objects stored
  * in the original set. If not provided, the new set points to the exact same objects as
  * the original set.
- * @return Duplication of the original set.
+ * @param[out] newset_p Pointer to return the duplication of the original set.
+ * @return LY_SUCCESS in case the data were successfully duplicated.
+ * @return LY_EMEM in case of memory allocation failure.
+ * @return LY_EINVAL in case of invalid parameters.
  */
 LY_ERR ly_set_dup(const struct ly_set *set, void *(*duplicator)(void *obj), struct ly_set **newset_p);
 
@@ -161,7 +164,7 @@
 void ly_set_free(struct ly_set *set, void (*destructor)(void *obj));
 
 /**
- * @brief Alternative to the ly_set_free() for static ::ly_set objects - in contrast to ly_set_free()
+ * @brief Alternative to the ::ly_set_free() for static ::ly_set objects - in contrast to ::ly_set_free()
  * it does not free the provided ::ly_set object.
  *
  * @param[in] set The set to be erased.
diff --git a/src/tree.h b/src/tree.h
index 75dd761..4475766 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -1,7 +1,7 @@
 /**
  * @file tree.h
  * @author Radek Krejci <rkrejci@cesnet.cz>
- * @brief libyang geenric macros and functions to work with YANG schema or data trees.
+ * @brief libyang generic macros and functions to work with YANG schema or data trees.
  *
  * Copyright (c) 2019 CESNET, z.s.p.o.
  *
@@ -24,6 +24,72 @@
 #endif
 
 /**
+ * @page howtoXPath XPath Addressing
+ *
+ * Internally, XPath evaluation is performed on __when__ and __must__ conditions in the schema. For that almost
+ * a full [XPath 1.0](http://www.w3.org/TR/1999/REC-xpath-19991116/) evaluator was implemented.
+ * In YANG models you can also find paths identifying __augment__ targets, __leafref__ targets, and trivial paths in
+ * __choice default__ and __unique__ statements argument. The exact format of all those paths can be found in the
+ * relevant RFCs. Further will only be discussed paths that are used directly in libyang API functions.
+ *
+ * XPath
+ * =====
+ *
+ * Generally, any xpath argument expects an expression similar to _when_ or _must_ as the same evaluator is used. As for
+ * the format of any prefixes, the standardized JSON ([RFC 7951](https://tools.ietf.org/html/rfc7951#section-6.11))
+ * was used. Summarized, xpath follows these conventions:
+ *   - full XPath can be used, but only data nodes (node sets) will always be returned,
+ *   - as per the specification, prefixes are actually __module names__,
+ *   - also in the specification, for _absolute_ paths, the first (leftmost) node _MUST_ have a prefix,
+ *   - for _relative_ paths, you specify the __context node__, which then acts as a parent for the first node in the path,
+ *   - nodes always inherit their module (prefix) from their __parent node__ so whenever a node is from a different
+ *     module than its parent, it _MUST_ have a prefix,
+ *   - nodes from the same module as their __parent__ _MUST NOT_ have a prefix,
+ *   - note that non-data nodes/schema-only node (choice, case, uses, input, output) are skipped and _MUST_ not be
+ *     included in the path.
+ *
+ * Functions List
+ * --------------
+ * - ::lyd_find_xpath()
+ * - ::lys_find_xpath()
+ *
+ * Path
+ * ====
+ *
+ * The term path is used when a simplified (subset of) XPath is expected. Path is always a valid XPath but not
+ * the other way around. In short, paths only identify a specific (set of) nodes based on their ancestors in the
+ * schema. Predicates are allowed the same as for an [instance-identifier](https://tools.ietf.org/html/rfc7950#section-9.13).
+ * Specifically, key values of a list, leaf-list value, or position of lists without keys can be used.
+ *
+ * Examples
+ * --------
+ *
+ * - get __list__ instance with __key1__ of value __1__ and __key2__ of value __2__ (this can return more __list__ instances if there are more keys than __key1__ and __key2__)
+ *
+ *       /module-name:container/list[key1='1'][key2='2']
+ *
+ * - get __leaf-list__ instance with the value __val__
+ *
+ *       /module-name:container/leaf-list[.='val']
+ *
+ * - get __3rd list-without-keys__ instance with no keys defined
+ *
+ *       /module-name:container/list-without-keys[3]
+ *
+ * - get __aug-list__ with __aug-list-key__, which was added to __module-name__ from an augment module __augment-module__
+ *
+ *       /module-name:container/container2/augment-module:aug-cont/aug-list[aug-list-key='value']
+ *
+ * Functions List
+ * --------------
+ * - ::lyd_new_path()
+ * - ::lyd_new_path2()
+ * - ::lyd_path()
+ * - ::ly_ctx_get_node()
+ *
+ */
+
+/**
  * @defgroup trees Trees
  *
  * Generic macros, functions, etc. to work with both [schema](@ref schematree) and [data](@ref datatree) trees.
diff --git a/src/tree_data.h b/src/tree_data.h
index 9cc3391..1defda1 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -33,8 +33,236 @@
 struct lysc_node;
 
 /**
- * @defgroup datatree Data Tree
+ * @page howtoData Data Instances
+ *
+ * All the nodes in data tree comes are based on ::lyd_node structure. According to the content of the ::lyd_node.schema
+ * it can be cast to several other structures.
+ *
+ * In case the ::lyd_node.schema pointer is NULL, the node is actually __opaq__ and can be safely cast to ::lyd_node_opaq.
+ * The opaq node represent an unknown node which wasn't mapped to any [(compiled) schema](@ref howtoSchema) node in the
+ * context. Such a node can appear in several places in the data tree.
+ * - As a part of the tree structure, but only in the case the ::LYD_PARSE_OPAQ option was used when input data were
+ *   [parsed](@ref howtoDataParsers), because unknown data instances are ignored by default. The same way, the opaq nodes can
+ *   appear as a node's attributes.
+ * - As a representation of YANG anydata/anyxml content.
+ * - As envelopes of standard data tree instances (RPCs, actions or Notifications).
+ *
+ * In case the data node has its definition in a [compiled schema tree](@ref howtoSchema), the structure of the data node is
+ * actually one of the followings according to the schema node's nodetype (::lysc_node.nodetype).
+ * - ::lyd_node_inner - represents data nodes corresponding to schema nodes matching ::LYD_NODE_INNER nodetypes. They provide
+ * structure of the tree by having children nodes.
+ * - ::lyd_node_term - represents data nodes corresponding to schema nodes matching ::LYD_NODE_TERM nodetypes. The terminal
+ * nodes provide values of the particular configuration/status information. The values are represented as ::lyd_value
+ * structure with string representation of the value (::lyd_value.canonical) and the type specific data stored in the
+ * structure's union according to the real type of the value (::lyd_value.realtype). The string representation provides
+ * canonical representation of the value in case the type has the canonical representation specified. Otherwise, it is the
+ * original value or, in case the value can contain prefixes, the JSON format is used to make the value unambiguous.
+ * - ::lyd_node_any - represents data nodes corresponding to schema nodes matching ::LYD_NODE_ANY nodetypes.
+ *
+ * Despite all the aforementioned structures and their members are available as part of the libyang API and callers can use
+ * it to navigate through the data tree structure or to obtain various information, we recommend to use the following macros
+ * and functions.
+ * - ::lyd_child() (or ::lyd_child_no_keys()) and ::lyd_parent() to get the node's child/parent node.
+ * - ::LYD_CTX to get libyang context from a data node.
+ * - ::LYD_CANON_VALUE to get canonical string value from a terminal node.
+ * - ::LYD_TREE_DFS_BEGIN and ::LYD_TREE_DFS_END to traverse the data tree (depth-first).
+ * - ::LY_LIST_FOR and ::LY_ARRAY_FOR as described on @ref howtoStructures page.
+ *
+ * Instead of going through the data tree on your own, a specific data node can be also located using a wide set of
+ * \b lyd_find_*() functions.
+ *
+ * More information about specific operations with data instances can be found on the following pages:
+ * - @subpage howtoDataParsers
+ * - @subpage howtoDataValidation
+ * - @subpage howtoDataWD
+ * - @subpage howtoDataManipulation
+ * - @subpage howtoDataPrinters
+ *
+ * \note API for this group of functions is described in the [Data Instances module](@ref datatree).
+ *
+ * Functions List (not assigned to above subsections)
+ * --------------------------------------------------
+ * - ::lyd_child()
+ * - ::lyd_child_no_keys()
+ * - ::lyd_parent()
+ * - ::lyd_owner_module()
+ * - ::lyd_find_xpath()
+ * - ::lyd_find_sibling_val()
+ * - ::lyd_find_sibling_first()
+ * - ::lyd_find_meta()
+ *
+ * - ::lyd_path()
+ * - ::lyd_target()
+ *
+ * - ::lyd_lyb_data_length()
+ */
+
+/**
+ * @page howtoDataManipulation Manipulating Data
+ *
+ * There are many functions to create or modify an existing data tree. You can add new nodes, reconnect nodes from
+ * one tree to another (or e.g. from one list instance to another) or remove nodes. The functions doesn't allow you
+ * to put a node to a wrong place (by checking the YANG module structure), but not all validation checks can be made directly
+ * (or you have to make a valid change by multiple tree modifications) when the tree is being changed. Therefore,
+ * the [validation process](@ref howtoDataValidation) is expected to be invoked after changing the data tree to make sure
+ * that the changed data tree is valid.
+ *
+ * When inserting a node into data tree (no matter if the node already exists, via ::lyd_insert_child() and
+ * ::lyd_insert_sibling(), or a new node is being created), the node is automatically inserted to the place respecting the
+ * nodes order from the YANG schema. So the node is not inserted to the end or beginning of the siblings list, but after the
+ * existing instance of the closest preceding sibling node from the schema. In case the node is opaq (it is not connected
+ * with any schema node), it is placed to the end of the sibling node in the order they are inserted in. The only situation
+ * when it is possible to influence the order of the nodes is the order of user-ordered list/leaf-list instances. In such
+ * a case the ::lyd_insert_after() or ::lyd_insert_before() can be used.
+ *
+ * Creating data is generally possible in two ways, they can be combined. You can add nodes one-by-one based on
+ * the node name and/or its parent (::lyd_new_inner(), ::lyd_new_term(), ::lyd_new_any(), ::lyd_new_list(), ::lyd_new_list2()
+ * and ::lyd_new_opaq()) or address the nodes using a [simple XPath addressing](@ref howtoXPath) (::lyd_new_path(),
+ * ::lyd_new_path2() and ::lyd_new_path_any()). The latter enables to create a whole path of nodes, requires less information
+ * about the modified data, and is generally simpler to use. Actually the third way is duplicating the existing data using
+ * ::lyd_dup_single(), ::lyd_dup_siblings() and ::lyd_dup_meta_single().
+ *
+ * The [metadata](@ref howtoPluginsExtensionsMetadata) (and attributes in opaq nodes) can be created with ::lyd_new_meta()
+ * and ::lyd_new_attr().
+ *
+ * Changing value of a terminal node (leaf, leaf-list) is possible with ::lyd_change_term(). Similarly, the metadata value
+ * can be changed with ::lyd_change_meta(). Before changing the value, it might be useful to compare the node's value
+ * with a string value (::lyd_value_compare()) or verify that the new string value is correct for the specific data node
+ * (::lyd_value_validate()).
+ *
+ * Working with two existing subtrees can also be performed two ways. Usually, you would use lyd_insert*() functions.
+ * They are generally meant for simple inserts of a node into a data tree. For more complicated inserts and when
+ * merging 2 trees use ::lyd_merge_tree() or ::lyd_merge_siblings(). It offers additional options and is basically a more
+ * powerful insert.
+ *
+ * Besides merging, libyang is also capable to provide information about differences between two data trees. For this purpose,
+ * ::lyd_diff_tree() and ::lyd_diff_siblings() generates annotated data trees which can be, in addition, used to change one
+ * data tree to another one using ::lyd_diff_apply_all(), ::lyd_diff_apply_module() and ::lyd_diff_reverse_all(). Multiple
+ * diff data trees can be also put together for further work using ::lyd_diff_merge_all(), ::lyd_diff_merge_module() and
+ * ::lyd_diff_merge_tree() functions. To just check equivalence of the data nodes, ::lyd_compare_single(),
+ * ::lyd_compare_siblings() and ::lyd_compare_meta() can be used.
+ *
+ * To remove a node or subtree from a data tree, use ::lyd_unlink_tree() and then free the unwanted data using
+ * ::lyd_free_all() (or other \b lyd_free_*() functions).
+ *
+ * Also remember, that when you are creating/inserting a node, all the objects in that operation must belong to the
+ * same context.
+ *
+ * Modifying the single data tree in multiple threads is not safe.
+ *
+ * Functions List
+ * --------------
+ * - ::lyd_new_inner()
+ * - ::lyd_new_term()
+ * - ::lyd_new_list()
+ * - ::lyd_new_list2()
+ * - ::lyd_new_any()
+ * - ::lyd_new_opaq()
+ * - ::lyd_new_attr()
+ * - ::lyd_new_meta()
+ * - ::lyd_new_path()
+ * - ::lyd_new_path2()
+ * - ::lyd_new_path_any()
+ *
+ * - ::lyd_dup_single()
+ * - ::lyd_dup_siblings()
+ * - ::lyd_dup_meta_single()
+ *
+ * - ::lyd_insert_child()
+ * - ::lyd_insert_sibling()
+ * - ::lyd_insert_after()
+ * - ::lyd_insert_before()
+ *
+ * - ::lyd_value_compare()
+ * - ::lyd_value_validate()
+ *
+ * - ::lyd_change_term()
+ * - ::lyd_change_meta()
+ *
+ * - ::lyd_compare_single()
+ * - ::lyd_compare_siblings()
+ * - ::lyd_compare_meta()
+ * - ::lyd_diff_tree()
+ * - ::lyd_diff_siblings()
+ * - ::lyd_diff_apply_all()
+ * - ::lyd_diff_apply_module()
+ * - ::lyd_diff_reverse_all()
+ * - ::lyd_diff_merge_all()
+ * - ::lyd_diff_merge_module()
+ * - ::lyd_diff_merge_tree()
+ *
+ * - ::lyd_merge_tree()
+ * - ::lyd_merge_siblings()
+ *
+ * - ::lyd_unlink_tree()
+ *
+ * - ::lyd_free_all()
+ * - ::lyd_free_siblings()
+ * - ::lyd_free_tree()
+ * - ::lyd_free_meta_single()
+ * - ::lyd_free_meta_siblings()
+ * - ::lyd_free_attr_single()
+ * - ::lyd_free_attr_siblings()
+ *
+ * - ::lyd_any_copy_value()
+ */
+
+/**
+ * @page howtoDataWD Default Values
+ *
+ * libyang provides support for work with default values as defined in [RFC 6243](https://tools.ietf.org/html/rfc6243).
+ * However, libyang context do not contains the *ietf-netconf-with-defaults* module on its own and caller is supposed to
+ * add this YANG module to enable full support of the *with-defaults* features described below. Without presence of the
+ * mentioned module in the context, the default nodes are still present and handled in the data trees, but the metadata
+ * providing the information about the default values cannot be used. It means that when parsing data, the default nodes
+ * marked with the metadata as implicit default nodes are handled as explicit data and when printing data tree, the expected
+ * nodes are printed without the ietf-netconf-with-defaults metadata.
+ *
+ * The RFC document defines 4 modes for handling default nodes in a data tree, libyang adds the fifth mode and use them
+ * via @ref dataprinterflags when printing data trees.
+ * - \b explicit - Only the explicitly set configuration data. But in the case of status data, missing default
+ *                 data are added into the tree. In libyang, this mode is represented by ::LYD_PRINT_WD_EXPLICIT option.
+ *                 This is the default with-defaults mode of the printer. The data nodes do not contain any additional
+ *                 metadata information.
+ * - \b trim - Data nodes containing the default value are removed. This mode is applied with ::LYD_PRINT_WD_TRIM option.
+ * - \b report-all - This mode provides all the default data nodes despite they were explicitly present in source data or
+ *                 they were added by libyang's [validation process](@ref howtoDataValidation). This mode is activated by
+ *                 ::LYD_PRINT_WD_ALL option.
+ * - \b report-all-tagged - In this case, all the data nodes (implicit as well the explicit) containing the default value
+ *                 are printed and tagged (see the note below). Printers accept ::LYD_PRINT_WD_ALL_TAG option for this mode.
+ * - \b report-implicit-tagged - The last mode is similar to the previous one, except only the implicitly added nodes
+ *                 are tagged. This is the libyang's extension and it is activated by ::LYD_PRINT_WD_IMPL_TAG option.
+ *
+ * Internally, libyang adds the default nodes into the data tree as part of the [validation process](@ref howtoDataValidation).
+ * When [parsing data](@ref howtoDataParsers) from an input source, adding default nodes can be avoided only by avoiding
+ * the whole [validation process](@ref howtoDataValidation). In case the ietf-netconf-with-defaults module is present in the
+ * context, the [parser process](@ref howtoDataParsers) also supports to recognize the implicit default nodes marked with the
+ * appropriate metadata.
+ *
+ * Note, that in a modified data tree (via e.g. \b lyd_insert_*() or \b lyd_free_*() functions), some of the default nodes
+ * can be missing or they can be present by mistake. Such a data tree is again corrected during the next run of the
+ * [validation process](@ref howtoDataValidation) or manualy using \b lyd_new_implicit_*() functions.
+ *
+ * The implicit (default) nodes, created by libyang, are marked with the ::LYD_DEFAULT flag in ::lyd_node.flags member
+ * Note, that besides leafs and leaf-lists, the flag can appear also in containers, where it means that the container
+ * holds only a default node(s) or it is implicitly added empty container (according to YANG 1.1 spec, all such containers are part of
+ * the accessible data tree). When printing data trees, the presence of empty containers (despite they were added
+ * explicitly or implicitly as part of accessible data tree) depends on ::LYD_PRINT_KEEPEMPTYCONT option.
+ *
+ * To get know if the particular leaf or leaf-list node contains default value (despite implicit or explicit), you can
+ * use ::lyd_is_default() function.
+ *
+ * Functions List
+ * --------------
+ * - ::lyd_is_default()
+ * - ::lyd_new_implicit_all()
+ * - ::lyd_new_implicit_module()
+ * - ::lyd_new_implicit_tree()
+ */
+
+/**
  * @ingroup trees
+ * @defgroup datatree Data Tree
  * @{
  *
  * Data structures and functions to manipulate and access instance data tree.
@@ -122,8 +350,8 @@
 #define LYD_CTX(node) ((node)->schema ? (node)->schema->module->ctx : ((struct lyd_node_opaq *)(node))->ctx)
 
 /**
- * @brief Data input/output formats supported by libyang [parser](@ref howtodataparsers) and
- * [printer](@ref howtodataprinters) functions.
+ * @brief Data input/output formats supported by libyang [parser](@ref howtoDataParsers) and
+ * [printer](@ref howtoDataPrinters) functions.
  */
 typedef enum {
     LYD_UNKNOWN = 0,     /**< unknown data format, invalid value */
@@ -146,9 +374,9 @@
  * @brief List of possible value types stored in ::lyd_node_any.
  */
 typedef enum {
-    LYD_ANYDATA_DATATREE,            /**< Value is a pointer to lyd_node structure (first sibling). When provided as input parameter, the pointer
+    LYD_ANYDATA_DATATREE,            /**< Value is a pointer to ::lyd_node structure (first sibling). When provided as input parameter, the pointer
                                           is directly connected into the anydata node without duplication, caller is supposed to not manipulate
-                                          with the data after a successful call (including calling lyd_free() on the provided data) */
+                                          with the data after a successful call (including calling ::lyd_free_all() on the provided data) */
     LYD_ANYDATA_STRING,              /**< Value is a generic string without any knowledge about its format (e.g. anyxml value in JSON encoded
                                           as string). XML sensitive characters (such as & or \>) are automatically escaped when the anydata
                                           is printed in XML format. */
@@ -165,6 +393,7 @@
 struct lyd_value {
     const char *canonical;           /**< Canonical string representation of the value in the dictionary. It is never
                                           NULL and in case of no canonical value, its JSON representation is used instead. */
+
     union {
         int8_t boolean;              /**< 0 as false, 1 as true */
         int64_t dec64;               /**< decimal64: value = dec64 / 10^fraction-digits  */
@@ -182,16 +411,16 @@
         struct ly_path *target;      /**< Instance-identifier target path. */
         struct lyd_value_subvalue *subvalue; /** Union value with some metadata. */
         void *ptr;                   /**< generic data type structure used to store the data */
-    };  /**< The union is just a list of shorthands to possible values stored by a type's plugin. libyang itself uses the lyd_value::realtype
-             plugin's callbacks to work with the data. */
+    };  /**< The union is just a list of shorthands to possible values stored by a type's plugin. libyang itself uses the ::lyd_value.realtype
+             plugin's callbacks to work with the data.*/
 
     const struct lysc_type *realtype; /**< pointer to the real type of the data stored in the value structure. This type can differ from the type
-                                           in the schema node of the data node since the type's store plugin can use other types/plugins for
-                                           storing data. Speaking about built-in types, this is the case of leafref which stores data as its
-                                           target type. In contrast, union type also use its subtype's callbacks, but inside an internal data
-                                           lyd_value::subvalue structure, so here is the pointer to the union type.
-                                           In general, this type is used to get free callback for this lyd_value structure, so it must reflect
-                                           the type used to store data directly in the same lyd_value instance. */
+                                          in the schema node of the data node since the type's store plugin can use other types/plugins for
+                                          storing data. Speaking about built-in types, this is the case of leafref which stores data as its
+                                          target type. In contrast, union type also uses its subtype's callbacks, but inside an internal data
+                                          stored in subvalue member of ::lyd_value structure, so here is the pointer to the union type.
+                                          In general, this type is used to get free callback for this lyd_value structure, so it must reflect
+                                          the type used to store data directly in the same lyd_value instance. */
 };
 
 /**
@@ -206,18 +435,18 @@
  * @brief Special lyd_value structure for union.
  *
  * Represents data with multiple types (union). Original value is stored in the main lyd_value:canonical_cache while
- * the lyd_value_subvalue::value contains representation according to one of the union's types.
- * The lyd_value_subvalue:prefixes provides (possible) mappings from prefixes in the original value to YANG modules.
+ * the ::lyd_value_subvalue.value contains representation according to one of the union's types.
+ * The ::lyd_value_subvalue.prefix_data provides (possible) mappings from prefixes in the original value to YANG modules.
  * These prefixes are necessary to parse original value to the union's subtypes.
  */
 struct lyd_value_subvalue {
     struct lyd_value value;      /**< representation of the value according to the selected union's subtype
-                                      (stored as lyd_value::realtype here, in subvalue structure */
+                                      (stored as ::lyd_value.realtype here, in subvalue structure */
     const char *original;        /**< Original value in the dictionary. */
     LY_PREFIX_FORMAT format;     /**< Prefix format of the value. However, this information is also used to decide
                                       whether a value is valid for the specific format or not on later validations
                                       (instance-identifier in XML looks different than in JSON). */
-    void *prefix_data;           /**< Format-specific data for prefix resolution (see ::ly_resolve_prefix) */
+    void *prefix_data;           /**< Format-specific data for prefix resolution (see ::ly_type_store_resolve_prefix()) */
     uint32_t hints;              /**< [Value hints](@ref lydvalhints) from the parser */
     const struct lysc_node *ctx_node;   /**< Context schema node. */
 };
@@ -244,7 +473,7 @@
  * @brief Generic prefix and namespace mapping, meaning depends on the format.
  *
  * The union is used as a reference to the data's module and according to the format, it can be used as a key for
- * ly_ctx_get_module_implemented_ns() or ly_ctx_get_module_implemented(). While the module reference is always present,
+ * ::ly_ctx_get_module_implemented_ns() or ::ly_ctx_get_module_implemented(). While the module reference is always present,
  * the id member can be omitted in case it is not present in the source data as a reference to the default namespace.
  */
 struct ly_prefix {
@@ -276,8 +505,8 @@
 #define LYD_NODE_ANY (LYS_ANYDATA)   /**< Schema nodetype mask for lyd_node_any */
 
 /**
- * @defgroup dnodeflags Data node flags
  * @ingroup datatree
+ * @defgroup dnodeflags Data node flags
  * @{
  *
  * Various flags of data nodes.
@@ -314,7 +543,7 @@
                                           nodes are equal due to possible collisions. */
     uint32_t flags;                  /**< [data node flags](@ref dnodeflags) */
     const struct lysc_node *schema;  /**< pointer to the schema definition of this node, note that the target can be not just
-                                          ::struct lysc_node but ::struct lysc_action or ::struct lysc_notif as well */
+                                          ::lysc_node but ::lysc_action or ::lysc_notif as well */
     struct lyd_node_inner *parent;   /**< pointer to the parent node, NULL in case of root node */
     struct lyd_node *next;           /**< pointer to the next sibling node (NULL if there is no one) */
     struct lyd_node *prev;           /**< pointer to the previous sibling node \note Note that this pointer is
@@ -352,7 +581,7 @@
 
     struct lyd_node *child;          /**< pointer to the first child node. */
     struct hash_table *children_ht;  /**< hash table with all the direct children (except keys for a list, lists without keys) */
-#define LYD_HT_MIN_ITEMS 4           /**< minimal number of children to create lyd_node_inner::children_ht hash table. */
+#define LYD_HT_MIN_ITEMS 4           /**< minimal number of children to create ::lyd_node_inner.children_ht hash table. */
 };
 
 /**
@@ -409,14 +638,17 @@
         const char *json;            /**< I-JSON encoded string */
         char *mem;                   /**< LYD_ANYDATA_LYB memory chunk */
     } value;                         /**< pointer to the stored value representation of the anydata/anyxml node */
-    LYD_ANYDATA_VALUETYPE value_type;/**< type of the data stored as lyd_node_any::value */
+    LYD_ANYDATA_VALUETYPE value_type;/**< type of the data stored as ::lyd_node_any.value */
 };
 
 /**
- * @defgroup lydvalhints Value format hints. Any information about value types encoded in the format
- * is hinted this way.
- *
+ * @ingroup datatree
+ * @defgroup lydvalhints Value format hints.
  * @{
+ *
+ * Hints for the type of the data value.
+ *
+ * Any information about value types encoded in the format is hinted by these values.
  */
 #define LYD_VALHINT_STRING     0x0001 /**< value is allowed to be a string */
 #define LYD_VALHINT_DECNUM     0x0002 /**< value is allowed to be a decimal number */
@@ -430,10 +662,13 @@
  */
 
 /**
- * @defgroup lydnodehints Node type format hints. Any information about node types encoded in the format
- * is hinted this way.
- *
+ * @ingroup datatree
+ * @defgroup lydnodehints Node type format hints
  * @{
+ *
+ * Hints for the type of the data node.
+ *
+ * Any information about node types encoded in the format is hinted by these values.
  */
 #define LYD_NODEHINT_LIST       0x0080 /**< node is allowed to be a list instance */
 #define LYD_NODEHINT_LEAFLIST   0x0100 /**< node is allowed to be a leaf-list instance */
@@ -444,10 +679,14 @@
  */
 
 /**
- * @defgroup lydhints Value and node type format hints. Any information about value and node types encoded in the format
- * is hinted this way. It combines [value hints](@ref lydvalhints) and [node hints](@ref lydnodehints).
- *
+ * @ingroup datatree
+ * @defgroup lydhints Value and node type format hints
  * @{
+ *
+ * Hints for the types of data node and its value.
+ *
+ * Any information about value and node types encoded in the format is hinted by these values.
+ * It combines [value hints](@ref lydvalhints) and [node hints](@ref lydnodehints).
  */
 #define LYD_HINT_DATA       0x01F3 /**< special node/value hint to be used for generic data node/value (for cases when
                                         there is no encoding or it does not provide any additional information about
@@ -657,7 +896,7 @@
  * @brief Create new attribute for an opaque data node.
  *
  * @param[in] parent Parent opaque node for the attribute being created.
- * @param[in] module Module name of the attribute being created. There may be none.
+ * @param[in] module_name Name of the module of the attribute being created. There may be none.
  * @param[in] name Attribute name. It can include the module name as the prefix.
  * @param[in] val_str String value of the attribute. Is stored directly.
  * @param[out] attr Optional created attribute.
@@ -667,8 +906,8 @@
         struct lyd_attr **attr);
 
 /**
- * @defgroup pathoptions Data path creation options
  * @ingroup datatree
+ * @defgroup pathoptions Data path creation options
  *
  * Various options to change lyd_new_path*() behavior.
  *
@@ -750,8 +989,8 @@
         LYD_ANYDATA_VALUETYPE value_type, uint32_t options, struct lyd_node **new_parent, struct lyd_node **new_node);
 
 /**
- * @defgroup implicitoptions Implicit node creation options
  * @ingroup datatree
+ * @defgroup implicitoptions Implicit node creation options
  *
  * Various options to change lyd_new_implicit*() behavior.
  *
@@ -819,7 +1058,6 @@
 /**
  * @brief Change the value of a metadata instance.
  *
- * @param[in] ctx libyang context.
  * @param[in] meta Metadata to change.
  * @param[in] val_str New value to set, any prefixes are expected in JSON format.
  * @return LY_SUCCESS if value was changed,
@@ -945,7 +1183,7 @@
  * The given node is not modified in any way - it is just checked if the @p value can be set to the node.
  *
  * If there is no data node instance and you are fine with checking just the type's restrictions without the
- * data tree context (e.g. for the case of require-instance restriction), use lys_value_validate().
+ * data tree context (e.g. for the case of require-instance restriction), use ::lys_value_validate().
  *
  * @param[in] ctx libyang context for logging (function does not log errors when @p ctx is NULL)
  * @param[in] node Data node for the @p value.
@@ -977,10 +1215,10 @@
 LY_ERR lyd_value_compare(const struct lyd_node_term *node, const char *value, size_t value_len);
 
 /**
- * @defgroup datacompareoptions Data compare options
  * @ingroup datatree
- *
- * Various options to change the lyd_compare() behavior.
+ * @defgroup datacompareoptions Data compare options
+ * @{
+ * Various options to change the ::lyd_compare_single() and ::lyd_compare_siblings() behavior.
  */
 #define LYD_COMPARE_FULL_RECURSION 0x01 /* lists and containers are the same only in case all they children
                                            (subtree, so direct as well as indirect children) are the same. By default,
@@ -1024,10 +1262,10 @@
 LY_ERR lyd_compare_meta(const struct lyd_meta *meta1, const struct lyd_meta *meta2);
 
 /**
- * @defgroup dupoptions Data duplication options
  * @ingroup datatree
+ * @defgroup dupoptions Data duplication options
  *
- * Various options to change lyd_dup() behavior.
+ * Various options to change ::lyd_dup_single(), ::lyd_dup_siblings() and ::lyd_dup_meta_single() behavior.
  *
  * Default behavior:
  * - only the specified node is duplicated without siblings, parents, or children.
@@ -1084,10 +1322,10 @@
 LY_ERR lyd_dup_meta_single(const struct lyd_meta *meta, struct lyd_node *parent, struct lyd_meta **dup);
 
 /**
- * @defgroup mergeoptions Data merge options.
  * @ingroup datatree
+ * @defgroup mergeoptions Data merge options.
  *
- * Various options to change lyd_merge() behavior.
+ * Various options to change ::lyd_merge_tree() and ::lyd_merge_siblings() behavior.
  *
  * Default behavior:
  * - source data tree is not modified in any way,
@@ -1126,10 +1364,10 @@
 LY_ERR lyd_merge_siblings(struct lyd_node **target, const struct lyd_node *source, uint16_t options);
 
 /**
- * @defgroup diffoptions Data diff options.
  * @ingroup datatree
+ * @defgroup diffoptions Data diff options.
  *
- * Various options to change lyd_diff() behavior.
+ * Various options to change ::lyd_diff_tree() and ::lyd_diff_siblings() behavior.
  *
  * Default behavior:
  * - any default nodes are treated as non-existent and ignored.
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index d1f91b5..12f5d5a 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -70,7 +70,7 @@
 struct lyd_node **lyd_node_children_p(struct lyd_node *node);
 
 /**
- * @brief Just like lys_getnext() but iterates over all data instances of the schema nodes.
+ * @brief Just like ::lys_getnext() but iterates over all data instances of the schema nodes.
  *
  * @param[in] last Last returned data node.
  * @param[in] sibling Data node sibling to search in.
@@ -505,7 +505,7 @@
 /**
  * @brief Insert hash of the node into the hash table of its parent.
  *
- * @param[in] node Data node which hash will be inserted into the lyd_node_inner::children_hash hash table of its parent.
+ * @param[in] node Data node which hash will be inserted into the ::lyd_node_inner.children_ht hash table of its parent.
  * @return LY_ERR value.
  */
 LY_ERR lyd_insert_hash(struct lyd_node *node);
diff --git a/src/tree_schema.h b/src/tree_schema.h
index f5f2183..0be05a1 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -34,8 +34,125 @@
 struct ly_set;
 
 /**
- * @defgroup schematree Schema Tree
+ * @page howtoSchema YANG Modules
+ *
+ * To be able to work with YANG data instances, libyang has to represent YANG data models. All the processed modules are stored
+ * in libyang [context](@ref howtoContext) and loaded using [parser functions](@ref howtoSchemaParsers). It means, that there is
+ * no way to create/change YANG module programmatically. However, all the YANG model definitions are available and can be examined
+ * through the C structures. All the context's modules together form YANG Schema for the data being instantiated.
+ *
+ * Any YANG module is represented as ::lys_module. In fact, the module is represented in two different formats. As ::lys_module.parsed,
+ * there is a parsed schema reflecting the source YANG module. It is exactly what is read from the input. This format is good for
+ * converting from one format to another (YANG to YIN and vice versa), but it is not very useful for validating/manipulating YANG
+ * data. Therefore, there is ::lys_module.compiled storing the compiled YANG module. It is based on the parsed module, but all the
+ * references are resolved. It means that, for example, there are no `grouping`s or `typedef`s since they are supposed to be placed instead of
+ * `uses` or `type` references. This split also means, that the YANG module is fully validated after compilation of the parsed
+ * representation of the module. YANG submodules are available only in the parsed representation. When a submodule is compiled, it
+ * is fully integrated into its main module.
+ *
+ * The context can contain even modules without the compiled representation. Such modules are still useful as imports of other
+ * modules. The grouping or typedef definition can be even compiled into the importing modules. This is actually the main
+ * difference between the imported and implemented modules in the libyang context. The implemented modules are compiled while the
+ * imported modules are only parsed.
+ *
+ * In case the context's ::LY_CTX_ALLIMPLEMENTED option is not set, the module is not implemented in case it is implicitly
+ * loaded as import for another module and it is not referenced in such a module (and no other) as target of leafref, augment
+ * or deviation.
+ *
+ * All modules with deviation definition are always marked as implemented. The imported (not implemented) module can be set implemented by ::lys_set_implemented(). But
+ * the implemented module cannot be changed back to just imported module. Note also that only one revision of a specific module
+ * can be implemented in a single context. The imported modules are used only as a
+ * source of definitions for types and groupings for uses statements. The data in such modules are ignored - caller
+ * is not allowed to create the data (including instantiating identities) defined in the model via data parsers,
+ * the default nodes are not added into any data tree and mandatory nodes are not checked in the data trees.
+ *
+ * The compiled schema tree nodes are able to hold private objects (::lysc_node.priv as a pointer to a structure, function, variable, ...) used by
+ * a caller application. Such an object can be assigned to a specific node using ::lysc_set_private() function.
+ * Note that the object is not freed by libyang when the context is being destroyed. So the caller is responsible
+ * for freeing the provided structure after the context is destroyed or the private pointer is set to NULL in
+ * appropriate schema nodes where the object was previously set. This can be automated via destructor function
+ * to free these private objects. The destructor is passed to the ::ly_ctx_destroy() function.
+ *
+ * Despite all the schema structures and their members are available as part of the libyang API and callers can use
+ * it to navigate through the schema tree structure or to obtain various information, we recommend to use the following
+ * macros for the specific actions.
+ * - ::LYSC_TREE_DFS_BEGIN and ::LYSC_TREE_DFS_END to traverse the schema tree (depth-first).
+ * - ::LY_LIST_FOR and ::LY_ARRAY_FOR as described on @ref howtoStructures page.
+ *
+ * Further information about modules handling can be found on the following pages:
+ * - @subpage howtoSchemaParsers
+ * - @subpage howtoSchemaFeatures
+ * - @subpage howtoPlugins
+ * - @subpage howtoSchemaPrinters
+ *
+ * \note There are many functions to access information from the schema trees. Details are available in
+ * the [Schema Tree module](@ref schematree).
+ *
+ * For information about difference between implemented and imported modules, see the
+ * [context description](@ref howtoContext).
+ *
+ * Functions List (not assigned to above subsections)
+ * --------------------------------------------------
+ * - ::lys_getnext()
+ * - ::lys_nodetype2str()
+ * - ::lys_set_implemented()
+ * - ::lys_value_validate()
+ *
+ * - ::lysc_set_private()
+ *
+ * - ::lysc_node_children()
+ * - ::lysc_node_actions()
+ * - ::lysc_node_notifs()
+ *
+ * - ::lysp_node_children()
+ * - ::lysp_node_actions()
+ * - ::lysp_node_notifs()
+ * - ::lysp_node_groupings()
+ * - ::lysp_node_typedefs()
+ */
+
+/**
+ * @page howtoSchemaFeatures YANG Features
+ *
+ * YANG feature statement is an iportant part of the language which can significantly affect the meaning of the schemas. Despite
+ * the features have similar effect as loading/removing schema from the context, manipulating with the feature value is not
+ * limited to the context preparation period before working with data. YANG features, respectively their use in if-feature
+ * statements, are evaluated as part of the [data validation process](@ref howtoDataValidation).
+ *
+ * The main functions with *lys_feature_* prefix are used to change the value (true/false) of the feature and to get its current
+ * value. Enabling/disabling all the features in a particular module can be done using '`*`' value instead of the feature name.
+ *
+ * There are two options to reflect feature's if-feature statements when enabling/disabling the feature. The ::lys_feature_enable()
+ * and ::lys_feature_disable() functions check their if-feature expressions (it is not possible to enable feature if it is not
+ * allowed by its if-feature expressions) and also checks for and update other features those if-feature expressions use the
+ * changed feature. On the contrary, ::lys_feature_enable_force() and ::lys_feature_disable_force() ignore all the if-feature
+ * limitations.
+ *
+ * The ::lysc_feature_value() and ::lys_feature_value() functions differ only by their parameters. The ::lysc_iffeature_value()
+ * is used to evaluate (possibly complex in YANG 1.1) logical expression from if-feature statement.
+ *
+ * The list of features of a particular YANG module is available in ::lys_module.features.
+ *
+ * To get know, if a specific schema node is currently disabled or enable, the ::lysc_node_is_disabled() function can be used.
+ *
+ * Note, that the feature's state can affect some of the output formats (e.g. Tree format).
+ *
+ * Functions List
+ * --------------
+ * - ::lys_feature_enable()
+ * - ::lys_feature_enable_force()
+ * - ::lys_feature_disable()
+ * - ::lys_feature_disable_force()
+ * - ::lys_feature_value()
+ * - ::lysc_feature_value()
+ * - ::lysc_iffeature_value()
+ *
+ * - ::lysc_node_is_disabled()
+ */
+
+/**
  * @ingroup trees
+ * @defgroup schematree Schema Tree
  * @{
  *
  * Data structures and functions to manipulate and access schema tree.
@@ -156,13 +273,13 @@
  */
 enum ly_stmt {
     LY_STMT_NONE = 0,
-    LY_STMT_STATUS,             /**< in lysc_ext_substmt::storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
-    LY_STMT_CONFIG,             /**< in lysc_ext_substmt::storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
+    LY_STMT_STATUS,             /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
+    LY_STMT_CONFIG,             /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
     LY_STMT_MANDATORY,
-    LY_STMT_UNITS,              /**< in lysc_ext_substmt::storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
+    LY_STMT_UNITS,              /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
                                      or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
     LY_STMT_DEFAULT,
-    LY_STMT_TYPE,               /**< in lysc_ext_substmt::storage stored as a pointer to `struct lysc_type *` (cardinality < #LY_STMT_CARD_SOME)
+    LY_STMT_TYPE,               /**< in ::lysc_ext_substmt.storage stored as a pointer to `struct lysc_type *` (cardinality < #LY_STMT_CARD_SOME)
                                      or as a pointer to a [sized array](@ref sizedarrays) `struct lysc_type **` */
 
     LY_STMT_ACTION,
@@ -188,7 +305,7 @@
     LY_STMT_FRACTION_DIGITS,
     LY_STMT_GROUPING,
     LY_STMT_IDENTITY,
-    LY_STMT_IF_FEATURE,         /**< in lysc_ext_substmt::storage stored as a pointer to `struct lysc_iffeature` (cardinality < #LY_STMT_CARD_SOME)
+    LY_STMT_IF_FEATURE,         /**< in ::lysc_ext_substmt.storage stored as a pointer to `struct lysc_iffeature` (cardinality < #LY_STMT_CARD_SOME)
                                      or as a pointer to a [sized array](@ref sizedarrays) `struct lysc_iffeature *` */
     LY_STMT_IMPORT,
     LY_STMT_INCLUDE,
@@ -572,7 +689,11 @@
 };
 
 /**
+ * @ingroup schematree
  * @defgroup deviatetypes Deviate types
+ *
+ * Type of the deviate operation (used as ::lysp_deviate.mod)
+ *
  * @{
  */
 #define LYS_DEV_NOT_SUPPORTED 1      /**< deviate type not-supported */
@@ -634,10 +755,10 @@
 };
 
 /**
- * @defgroup spnodeflags Parsed schema nodes flags
  * @ingroup snodeflags
+ * @defgroup spnodeflags Parsed schema nodes flags
  *
- * Various flags for parsed schema nodes.
+ * Various flags for parsed schema nodes (used as ::lysp_node.flags).
  *
  *     1 - container    6 - anydata/anyxml    11 - output       16 - grouping   21 - enum
  *     2 - choice       7 - case              12 - feature      17 - uses       22 - type
@@ -693,10 +814,10 @@
  */
 
 /**
- * @defgroup scnodeflags Compiled schema nodes flags
  * @ingroup snodeflags
+ * @defgroup scnodeflags Compiled schema nodes flags
  *
- * Various flags for compiled schema nodes.
+ * Various flags for compiled schema nodes (used as ::lysc_node.flags).
  *
  *     1 - container    6 - anydata/anyxml    11 - identity
  *     2 - choice       7 - case              12 - extension
@@ -742,6 +863,9 @@
 
 /**
  * @defgroup snodeflags Schema nodes flags
+ *
+ * Various flags for schema nodes ([parsed](@ref spnodeflags) as well as [compiled](@ref scnodeflags)).
+ *
  * @{
  */
 #define LYS_CONFIG_W     0x01        /**< config true; also set for input children nodes */
@@ -766,7 +890,10 @@
 #define LYS_UNIQUE       0x80        /**< flag for leafs being part of a unique set, applicable only to ::lysc_node_leaf */
 #define LYS_KEY          0x100       /**< flag for leafs being a key of a list, applicable only to ::lysc_node_leaf */
 #define LYS_KEYLESS      0x200       /**< flag for list without any key, applicable only to ::lysc_node_list */
-#define LYS_FENABLED     0x100       /**< feature enabled flag, applicable only to ::lysc_feature */
+#define LYS_FENABLED     0x100       /**< feature enabled flag, applicable only to ::lysc_feature.
+                                          Do not interpret presence of this flag as enabled feature! Also if-feature statements
+                                          are supposed to be taken into account, so use ::lys_feature_value() or
+                                          ::lysc_feature_value() to get know if a specific feature is really enabled. */
 #define LYS_ORDBY_SYSTEM 0x80        /**< ordered-by user lists, applicable only to ::lysc_node_leaflist/::lysp_node_leaflist and
                                           ::lysc_node_list/::lysp_node_list */
 #define LYS_ORDBY_USER   0x40        /**< ordered-by user lists, applicable only to ::lysc_node_leaflist/::lysp_node_leaflist and
@@ -1218,7 +1345,7 @@
 
 /**
  * @defgroup ifftokens if-feature expression tokens
- * Tokens of if-feature expression used in ::lysc_iffeature#expr
+ * Tokens of if-feature expression used in ::lysc_iffeature.expr.
  *
  * @{
  */
@@ -1734,7 +1861,7 @@
 /**
  * @brief Examine whether a node is user-ordered list or leaf-list.
  *
- * @param[in] node Node to examine.
+ * @param[in] schema Schema node to examine.
  * @return non-zero if it is,
  * @return Boolean value whether the @p node is user-ordered or not.
  */
@@ -1944,7 +2071,7 @@
  * @brief Get next schema tree (sibling) node element that can be instantiated in a data tree. Returned node can
  * be from an augment.
  *
- * lys_getnext() is supposed to be called sequentially. In the first call, the \p last parameter is usually NULL
+ * ::lys_getnext() is supposed to be called sequentially. In the first call, the \p last parameter is usually NULL
  * and function starts returning i) the first \p parent's child or ii) the first top level element of the \p module.
  * Consequent calls suppose to provide the previously returned node as the \p last parameter and still the same
  * \p parent and \p module parameters.
@@ -1964,16 +2091,19 @@
         const struct lysc_module *module, uint32_t options);
 
 /**
- * @defgroup sgetnextflags lys_getnext() flags
+ * @defgroup sgetnextflags Options for ::lys_getnext().
+ *
+ * Various options setting behavior of ::lys_getnext().
+ *
  * @{
  */
-#define LYS_GETNEXT_WITHCHOICE   0x01 /**< lys_getnext() option to allow returning #LYS_CHOICE nodes instead of looking into them */
-#define LYS_GETNEXT_NOCHOICE     0x02 /**< lys_getnext() option to ignore (kind of conditional) nodes within choice node */
-#define LYS_GETNEXT_WITHCASE     0x04 /**< lys_getnext() option to allow returning #LYS_CASE nodes instead of looking into them */
-#define LYS_GETNEXT_INTONPCONT   0x40 /**< lys_getnext() option to look into non-presence container, instead of returning container itself */
-#define LYS_GETNEXT_NOSTATECHECK 0x100 /**< lys_getnext() option to skip checking module validity (import-only, disabled) and
+#define LYS_GETNEXT_WITHCHOICE   0x01 /**< ::lys_getnext() option to allow returning #LYS_CHOICE nodes instead of looking into them */
+#define LYS_GETNEXT_NOCHOICE     0x02 /**< ::lys_getnext() option to ignore (kind of conditional) nodes within choice node */
+#define LYS_GETNEXT_WITHCASE     0x04 /**< ::lys_getnext() option to allow returning #LYS_CASE nodes instead of looking into them */
+#define LYS_GETNEXT_INTONPCONT   0x40 /**< ::lys_getnext() option to look into non-presence container, instead of returning container itself */
+#define LYS_GETNEXT_NOSTATECHECK 0x100 /**< ::lys_getnext() option to skip checking module validity (import-only, disabled) and
                                             relevant if-feature conditions state */
-#define LYS_GETNEXT_OUTPUT       0x200 /**< lys_getnext() option to provide RPC's/action's output schema nodes instead of input schema nodes
+#define LYS_GETNEXT_OUTPUT       0x200 /**< ::lys_getnext() option to provide RPC's/action's output schema nodes instead of input schema nodes
                                             provided by default */
 /** @} sgetnextflags */
 
@@ -2018,7 +2148,7 @@
  * @brief Check type restrictions applicable to the particular leaf/leaf-list with the given string @p value.
  *
  * This function check just the type's restriction, if you want to check also the data tree context (e.g. in case of
- * require-instance restriction), use lyd_value_validate().
+ * require-instance restriction), use ::lyd_value_validate().
  *
  * @param[in] ctx libyang context for logging (function does not log errors when @p ctx is NULL)
  * @param[in] node Schema node for the @p value.
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 67d9e48..4d45f7e 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -609,7 +609,7 @@
  * @brief Free the compiled container node structure.
  *
  * Only the container-specific members are freed, for generic node free function,
- * use lysc_node_free().
+ * use ::lysc_node_free().
  *
  * @param[in] ctx libyang context where the string data resides in a dictionary.
  * @param[in,out] node Compiled container node structure to be freed.
diff --git a/src/xml.h b/src/xml.h
index aef80b3..a761229 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -137,10 +137,10 @@
  * @brief Get a namespace record for the given prefix in the current context.
  *
  * @param[in] ns_set Set with namespaces from the XML context.
- * @param[in] prefix Pointer to the namespace prefix as taken from lyxml_get_attribute() or lyxml_get_element().
+ * @param[in] prefix Pointer to the namespace prefix as taken from ::lyxml_get_attribute() or ::lyxml_get_element().
  * Can be NULL for default namespace.
- * @param[in] prefix_len Length of the prefix string (since it is not NULL-terminated when returned from lyxml_get_attribute() or
- * lyxml_get_element()).
+ * @param[in] prefix_len Length of the prefix string (since it is not NULL-terminated when returned from ::lyxml_get_attribute() or
+ * ::lyxml_get_element()).
  * @return The namespace record or NULL if the record for the specified prefix not found.
  */
 const struct lyxml_ns *lyxml_ns_get(const struct ly_set *ns_set, const char *prefix, size_t prefix_len);
diff --git a/src/xpath.h b/src/xpath.h
index 9172ca3..4821e75 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -304,7 +304,7 @@
  * @param[in] ctx_scnode Current (context) schema node, NULL in case of the root node.
  * @param[out] set Result set.
  * @param[in] options Whether to apply some evaluation restrictions, one flag must always be used.
- * @return LY_ERR (same as lyxp_eval()).
+ * @return LY_ERR (same as ::lyxp_eval()).
  */
 LY_ERR lyxp_atomize(struct lyxp_expr *exp, const struct lys_module *cur_mod, LY_PREFIX_FORMAT format, void *prefix_data,
         const struct lysc_node *ctx_scnode, struct lyxp_set *set, uint32_t options);