plugins DOC updated documentation including transition manual and howtos
diff --git a/src/libyang.h b/src/libyang.h
index 920c52e..7733def 100644
--- a/src/libyang.h
+++ b/src/libyang.h
@@ -57,14 +57,14 @@
  * - [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)).
+ * - Support for [YANG Metadata](@ref howtoDataMetadata) ([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-2020 CESNET, z.s.p.o.
+ * Copyright (c) 2015-2021 CESNET, z.s.p.o.
  *
  * (The BSD 3-Clause License)
  *
@@ -132,21 +132,6 @@
  */
 
 /**
- * @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
- */
-
-/**
  * @internal
  * @page internals Developers' Notes
  * @tableofcontents
diff --git a/src/parser_data.h b/src/parser_data.h
index 16b5c0a..fbb9a48 100644
--- a/src/parser_data.h
+++ b/src/parser_data.h
@@ -257,12 +257,14 @@
         uint32_t validate_options, struct lyd_node **tree);
 
 /**
- * @brief Parse (and validate) data from the input handler as a YANG data tree following the schema tree of the given
+ * @brief Parse (and validate) data from the input handler as an extension data tree following the schema tree of the given
  * extension instance.
  *
  * Note that the data being parsed are limited only to the schema tree specified by the given extension, it does not allow
  * to mix them with the standard data from any module.
  *
+ * Directly applicable to data defined as [yang-data](@ref howtoDataYangdata).
+ *
  * @param[in] ext Extension instance providing the specific schema tree to match with the data being parsed.
  * @param[in] parent Optional parent to connect the parsed nodes to.
  * @param[in] in The input handle to provide the dumped data in the specified @p format to parse (and validate).
@@ -348,7 +350,9 @@
         enum lyd_type data_type, struct lyd_node **tree, struct lyd_node **op);
 
 /**
- * @brief Parse YANG data into an operation data tree following only the specification from the given extension instance.
+ * @brief Parse extension data into an operation data tree following only the specification from the given extension instance.
+ *
+ * Directly applicable to data defined as [yang-data](@ref howtoDataYangdata).
  *
  * At least one of @p parent, @p tree, or @p op must always be set.
  *
diff --git a/src/plugins.h b/src/plugins.h
index 13ed304..6263c7d 100644
--- a/src/plugins.h
+++ b/src/plugins.h
@@ -22,6 +22,40 @@
 #endif
 
 /**
+ * @page howtoPlugins Plugins
+ *
+ * libyang supports two types of plugins to better support generic features of YANG that need some specific code for
+ * their specific instances in YANG modules. This is the case of YANG types, which are derived from YANG built-in types.
+ * The description of a 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 is hidden in their description (e.g. allowed substatements or place of the extension
+ * instantiation) and libyang is not able to process such a text in a generic way.
+ *
+ * In both cases, libyang provides API to get functionality implementing the specifics of each type or extension.
+ * Furthermore, there are several internal plugins, implementing built-in data types and selected derived types and YANG
+ * extensions. These internal plugins uses the same API and can be taken as examples for implementing user plugins. Internal
+ * plugins are always loaded with the first created [context](@ref howtoContext) and unloaded with destroying the last one.
+ * The external plugins are in the same phase loaded from the default directories specified at compile time via cmake
+ * variables `PLUGINS_DIR` (where the `extensions` and `types` subdirectories are added for each plugin type) or separately
+ * via `PLUGINS_DIR_EXTENSIONS` and `PLUGINS_DIR_TYPES` for each plugin type. The default directories can be replaced runtime
+ * using environment variables `LIBYANG_TYPES_PLUGINS_DIR` and `LIBYANG_EXTENSIONS_PLUGINS_DIR`.
+ *
+ * Order of the plugins determines their priority. libyang searches for the first match with the extension and type, so the
+ * firstly loaded plugin for the specific item is used. Since the internal plugins are loaded always before the external
+ * plugins, the internal plugins cannot be replaced.
+ *
+ * There is also a separate function ::lyplg_add() to add a plugin anytime later. Note, that such a plugin is being used
+ * after it is added with the lowest priority among other already loaded plugins. Also note that since all the plugins are
+ * unloaded with the destruction of the last context, creating a new context after that starts the standard plugins
+ * initiation and the manually added plugins are not loaded automatically.
+ *
+ * The following pages contain description of the API for creating user plugins.
+ *
+ * - @subpage howtoPluginsTypes
+ * - @subpage howtoPluginsExtensions
+ */
+
+/**
  * @defgroup plugins Plugins
  * @{
  *
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index c6f4b5e..9cdd39b 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -33,7 +33,64 @@
 #endif
 
 /**
- * @defgroup extensions YANG Extensions
+ * @page howtoPluginsExtensions Extension Plugins
+ *
+ * Note that the part of the libyang API here is available only by including a separated `<libyang/plugins_exts.h>` header
+ * file. Also note that the extension plugins API is versioned separately from libyang itself, so backward incompatible
+ * changes can come even without changing libyang major version.
+ *
+ * YANG extensions are very complex. Usually only its description specifies how it is supposed to behave, what are the
+ * allowed substatements, their cardinality or if the standard YANG statements placed inside the extension differs somehow
+ * in their meaning or behavior. libyang provids the Extension plugins API to implement such extensions and add its support
+ * into libyang itself. However we tried our best, the API is not (and it cannot be) so universal and complete to cover all
+ * possibilities. There are definitely use cases which cannot be simply implemented only with this API.
+ *
+ * libyang implements 3 important extensions: [NACM](https://tools.ietf.org/html/rfc8341), [Metadata](@ref howtoDataMetadata)
+ * and [yang-data](@ref howtoDataYangdata). Despite the core implementation in all three cases is done via extension plugin
+ * API, also other parts of the libyang code had to be extended to cover complete scope of the extensions.
+ *
+ * We believe, that the API is capable to allow implementation of very wide range of YANG extensions. However, if you see
+ * limitations for the particular YANG extension, don't hesitate to contact the project developers to discuss all the
+ * options, including updating the API.
+ *
+ * The plugin's functionality is provided to libyang via a set of callbacks specified as an array of ::lyplg_ext_record
+ * structures using the ::LYPLG_EXTENSIONS macro.
+ *
+ * The most important ::lyplg_ext.compile callback is responsible for processing the parsed extension instance. In this
+ * phase, the callback must validate all the substatements, their values or placement of the extension instance itself.
+ * If needed, the processed data can be stored in some form into the compiled schema representation of the extension
+ * instance. To make the compilation process as easy as possible, libyang provides several
+ * [helper functions](@ref pluginsExtensionsCompile) to handle the schema compilation context and to compile standard YANG
+ * statements in the same way the libyang does it internally.
+ *
+ * The data validation callback ::lyplg_ext.validate is used for additional validation of a data nodes that contains the
+ * connected extension instance directly (as a substatement) or indirectly in case of terminal nodes via their type (no
+ * matter if the extension instance is placed directly in the leaf's/leaf-list's type or in the type of the referenced
+ * typedef).
+ *
+ * The ::lyplg_ext.sprinter callback implement printing the compiled extension instance data when the schema (module) is
+ * being printed in the ::LYS_OUT_YANG_COMPILED (info) format. As for compile callback, there are also
+ * [helper functions](@ref pluginsExtensionsPrint) to access printer's context and to print standard YANG statements
+ * placed in the extension instance by libyang itself.
+ *
+ * The last callback, ::lyplg_ext.free, is supposed to free all the data allocated by the ::lyplg_ext.compile callback.
+ * To free the data created by helper function ::lys_compile_extension_instance(), the plugin can used
+ * ::lyplg_ext_instance_substatements_free().
+ *
+ * The plugin information contains also the plugin identifier (::lyplg_type.id). This string can serve to identify the
+ * specific plugin responsible to storing data value. In case the user can recognize the id string, it can access the
+ * plugin specific data with the appropriate knowledge of its structure.
+ *
+ * Logging information from an extension plugin is possible via ::lyplg_ext_log() function
+ */
+
+/**
+ * @defgroup pluginsExtensions Plugins: Extensions
+ *
+ * Structures and functions to for libyang plugins implementing specific YANG extensions defined in YANG modules. For more
+ * information, see @ref howtoPluginsTypes.
+ *
+ * This part of libyang API is available by including `<libyang/plugins_ext.h>` header file.
  *
  * @{
  */
@@ -56,7 +113,7 @@
 /**
  * @brief Free the extension instance's data compiled with ::lys_compile_extension_instance().
  *
- * @param[in] libyang context
+ * @param[in] ctx libyang context
  * @param[in] substmts The sized array of extension instance's substatements. The whole array is freed except the storage
  * places which are expected to be covered by the extension plugin.
  */
@@ -150,7 +207,7 @@
 void lyplg_ext_log(const struct lysc_ext_instance *ext, LY_LOG_LEVEL level, LY_ERR err_no, const char *path,
         const char *format, ...);
 
-/** @} extensions */
+/** @} pluginsExtensions */
 
 #ifdef __cplusplus
 }
diff --git a/src/plugins_exts_compile.h b/src/plugins_exts_compile.h
index 2dfde6a..893f364 100644
--- a/src/plugins_exts_compile.h
+++ b/src/plugins_exts_compile.h
@@ -29,7 +29,10 @@
 #endif
 
 /**
- * @ingroup extensions YANG Extensions
+ * @defgroup pluginsExtensionsCompile Plugins: Extensions compilation support
+ * @ingroup pluginsExtensions
+ *
+ * Helper functions to implement extension plugin's compile callback.
  *
  * @{
  */
diff --git a/src/plugins_exts_print.h b/src/plugins_exts_print.h
index 9f6fb56..6a95419 100644
--- a/src/plugins_exts_print.h
+++ b/src/plugins_exts_print.h
@@ -22,7 +22,10 @@
 #endif
 
 /**
- * @ingroup extensions YANG Extensions
+ * @defgroup pluginsExtensionsPrint Plugins: Extensions printer support
+ * @ingroup pluginsExtensions
+ *
+ * Helper functions to implement extension plugin's sprinter callback.
  *
  * @{
  */
@@ -72,7 +75,7 @@
  */
 void lysc_print_extension_instance(struct lyspr_ctx *ctx, const struct lysc_ext_instance *ext, ly_bool *flag);
 
-/** @} extensions */
+/** @} pluginsExtensionsPrint */
 
 #ifdef __cplusplus
 }
diff --git a/src/plugins_types.h b/src/plugins_types.h
index 4e16014..fc1d03b 100644
--- a/src/plugins_types.h
+++ b/src/plugins_types.h
@@ -44,41 +44,111 @@
 struct lysp_module;
 
 /**
- * @defgroup types Plugins - Types
- * @{
+ * @page howtoPluginsTypes Type Plugins
  *
- * Structures and functions to for libyang plugins implementing specific YANG types defined in YANG schemas
- */
-
-/**
- * @page howtoPluginsTypes
+ * Note that the part of the libyang API here is available only by including a separated `<libyang/plugins_types.h>` header
+ * file. Also note that the type plugins API is versioned separately from libyang itself, so backward incompatible changes
+ * can come even without changing libyang major version.
  *
- * YANG allows schemas to define new data types via *typedef* statement or even in leaf's/leaf-list's *type* statements.
+ * YANG allows to define new data types via *typedef* statements 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).
- * libyang implements all handling of the data values of the YANG types via plugins. Internally, plugins for the built-in types
- * and several others are implemented. Type plugin is supposed to
- * - validate (and canonize) data value according to the type's restrictions,
- * - store it as lyd_value,
- * - print it,
- * - compare two values (lyd_value) of the same type,
- * - duplicate data in lyd_value and
- * - free the connected data from lyd_value.
+ * libyang implements all handling of the data values of the YANG types via the Type Plugins API. Internally, there is
+ * implementation of the built-in types and others can be added as an external plugin (see @ref howtoPlugins).
  *
- * All these functions are provided to libyang via a set of callback functions specified as ::lyplg_type.
- * All the callbacks are supposed to do not log directly via libyang logger. Instead, they return LY_ERR value and
+ * Type plugin is supposed to
+ *  - store (and canonize) data value,
+ *  - validate it according to the type's restrictions,
+ *  - compare two values (::lyd_value) of the same type,
+ *  - duplicate value (::lyd_value),
+ *  - print it and
+ *  - free the specific data inserted into ::lyd_value.
+ *
+ * These tasks are implemented as callbacks provided to libyang via ::lyplg_type_record structures defined as array using
+ * ::LYPLG_TYPES macro.
+ *
+ * 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()
  * are available).
  *
  * The main functionality is provided via ::lyplg_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
- * the ptr member (void *) of ::lyd_value structure. The callback is also responsible for storing canonized string
+ * the void *ptr member 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 ::lyplg_type_validate_clb can be implemented. The stored value can be printed into the
- * required format via ::lyplg_type_print_clb implementation.
+ * format uses directly the module names as prefixes.
+ *
+ * Usually, all the validation according to the type's restrictions is done in the store callback. However, in case the type
+ * requires some validation referencing other entities in the data tree, the optional validation callback
+ * ::lyplg_type_validate_clb can be implemented.
+ *
+ * The stored values can be compared in a specific way by providing ::lyplg_type_compare_clb. In case the best way to compare
+ * the values is to compare their canonical string representations, the ::lyplg_type_compare_simple() function can be used.
+ *
+ * Data duplication is done with ::lyplg_type_dup_clb callbacks. Note that the callback is responsible even for duplicating
+ * the ::lyd_value.canonical, so the callback must be always present (the canonical value is always present). If there is
+ * nothing else to duplicate, the plugin can use the generic ::lyplg_type_dup_simple().
+ *
+ * The stored value can be printed into the required format via ::lyplg_type_print_clb implementation. Simple printing
+ * canonical representation of the value is implemented by ::lyplg_type_print_simple().
+ *
+ * And finally freeing any data stored in the ::lyd_value by the plugin is done by implementation of ::lyplg_type_free_clb.
+ * Freeing only the canonical string is implemented by ::lyplg_type_free_simple().
+ *
+ * The plugin information contains also the plugin identifier (::lyplg_type.id). This string can serve to identify the
+ * specific plugin responsible to storing data value. In case the user can recognize the id string, it can access the
+ * plugin specific data with the appropriate knowledge of its structure.
+ *
+ * Besides the mentioned `_simple` functions, libyang provides, as part of the type plugins API, all the callbacks
+ * implementing the built-in types in the internal plugins:
+ *
+ *  - [simple callbacks](@ref pluginsTypesSimple) handling only the canonical strings in the value,
+ *  - [binary built-in type](@ref pluginsTypesBinary)
+ *  - [bits built-in type](@ref pluginsTypesBits)
+ *  - [boolean built-in type](@ref pluginsTypesBoolean)
+ *  - [decimal64 built-in type](@ref pluginsTypesDecimal64)
+ *  - [empty built-in type](@ref pluginsTypesEmpty)
+ *  - [enumeration built-in type](@ref pluginsTypesEnumeration)
+ *  - [identityref built-in type](@ref pluginsTypesIdentityref)
+ *  - [instance-identifier built-in type](@ref pluginsTypesInstanceid)
+ *  - [integer built-in types](@ref pluginsTypesInteger)
+ *  - [leafref built-in type](@ref pluginsTypesLeafref)
+ *  - [string built-in type](@ref pluginsTypesString)
+ *  - [union built-in type](@ref pluginsTypesUnion)
+ *
+ * In addition to these callbacks, the API also provides sevral function which can help to implement your own plugin for the
+ * derived YANG types:
+ *
+ * - ::ly_err_new()
+ * - ::ly_err_free()
+ *
+ * - ::lyplg_type_lypath_new()
+ * - ::lyplg_type_lypath_free()
+ *
+ * - ::lyplg_type_prefix_data_new()
+ * - ::lyplg_type_prefix_data_dup()
+ * - ::lyplg_type_prefix_data_free()
+ * - ::lyplg_type_get_prefix()
+ *
+ * - ::lyplg_type_check_hints()
+ * - ::lyplg_type_identity_isderived()
+ * - ::lyplg_type_identity_module()
+ * - ::lyplg_type_make_implemented()
+ * - ::lyplg_type_parse_dec64()
+ * - ::lyplg_type_parse_int()
+ * - ::lyplg_type_parse_uint()
+ * - ::lyplg_type_resolve_leafref()
+ */
+
+/**
+ * @defgroup pluginsTypes Plugins: Types
+ * @{
+ *
+ * Structures and functions to for libyang plugins implementing specific YANG types defined in YANG modules. For more
+ * information, see @ref howtoPluginsTypes.
+ *
+ * This part of libyang API is available by including `<libyang/plugins_types.h>` header file.
  */
 
 /**
@@ -261,7 +331,7 @@
 void lyplg_type_lypath_free(const struct ly_ctx *ctx, struct ly_path *path);
 
 /**
- * @defgroup plugintypestoreopts Type store callback options.
+ * @defgroup plugintypestoreopts Plugins: Type store callback options.
  *
  * Options applicable to ::lyplg_type_store_clb().
  *
@@ -296,7 +366,7 @@
  * @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[in,out] unres Global unres structure for newly implemented modules. Set only if ::LY_TYPE_STORE_IMPLEMENT is used.
+ * @param[in,out] unres Global unres structure for newly implemented modules.
  * @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().
  * @return LY_SUCCESS on success,
@@ -412,6 +482,15 @@
 };
 
 /**
+ * @defgroup pluginsTypesSimple Plugins: Simple Types Callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Simple functions implementing @ref howtoPluginsTypes callbacks handling simply just the canonical string of the value
+ * (::lyd_value.canonical).
+ */
+
+/**
  * @brief Generic simple comparison callback checking the canonical value.
  * Implementation of the ::lyplg_type_compare_clb.
  */
@@ -435,8 +514,14 @@
  */
 void lyplg_type_free_simple(const struct ly_ctx *ctx, struct lyd_value *value);
 
-/*
- * Binary built-in type functions
+/** @} pluginsTypesSimple */
+
+/**
+ * @defgroup pluginsTypesBinary Plugins: Binary built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement binary built-in type.
  */
 
 /**
@@ -447,8 +532,14 @@
         uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
         struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err);
 
-/*
- * Bits built-in type functions
+/** @} pluginsTypesBinary */
+
+/**
+ * @defgroup pluginsTypesBits Plugins: Bits built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement bits built-in type.
  */
 
 /**
@@ -471,8 +562,14 @@
  */
 void lyplg_type_free_bits(const struct ly_ctx *ctx, struct lyd_value *value);
 
-/*
- * Boolean built-in type functions
+/** @} pluginsTypesBits */
+
+/**
+ * @defgroup pluginsTypesBoolean Plugins: Boolean built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement boolean built-in type.
  */
 
 /**
@@ -483,8 +580,14 @@
         uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
         struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err);
 
-/*
- * Decimal64 built-in type functions
+/** @} pluginsTypesBoolean */
+
+/**
+ * @defgroup pluginsTypesDecimal64 Plugins: Decimal64 built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement decimal64 built-in type.
  */
 
 /**
@@ -495,8 +598,14 @@
         uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
         struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err);
 
-/*
- * Decimal64 built-in type functions
+/** @} pluginsTypesDecimal64 */
+
+/**
+ * @defgroup pluginsTypesEmpty Plugins: Empty built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement empty built-in type.
  */
 
 /**
@@ -513,8 +622,14 @@
  */
 LY_ERR lyplg_type_compare_empty(const struct lyd_value *val1, const struct lyd_value *val2);
 
-/*
- * Enumeration built-in type functions
+/** @} pluginsTypesEmpty */
+
+/**
+ * @defgroup pluginsTypesEnumeration Plugins: Enumeration built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement enumeration built-in type.
  */
 
 /**
@@ -525,8 +640,14 @@
         uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
         struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err);
 
-/*
- * Identityref built-in type functions
+/** @} pluginsTypesEnumeration */
+
+/**
+ * @defgroup pluginsTypesIdentityref Plugins: Identityref built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement identityref built-in type.
  */
 
 /**
@@ -550,8 +671,14 @@
 const char *lyplg_type_print_identityref(const struct lyd_value *value, LY_PREFIX_FORMAT format, void *prefix_data,
         ly_bool *dynamic);
 
-/*
- * Instance-identifier built-in type functions
+/** @} pluginsTypesIdentityref */
+
+/**
+ * @defgroup pluginsTypesInstanceid Plugins: Instance-identifier built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement instance-identifier built-in type.
  */
 
 /**
@@ -594,8 +721,14 @@
  */
 void lyplg_type_free_instanceid(const struct ly_ctx *ctx, struct lyd_value *value);
 
-/*
- * Integer built-in types functions
+/** @} pluginsTypesInstanceid */
+
+/**
+ * @defgroup pluginsTypesInteger Plugins: Integer built-in types callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement integer built-in types.
  */
 
 /**
@@ -614,8 +747,14 @@
         uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
         struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err);
 
-/*
- * Leafref built-in type functions
+/** @} pluginsTypesInteger */
+
+/**
+ * @defgroup pluginsTypesLeafref Plugins: Leafref built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement leafref built-in type.
  */
 
 /**
@@ -658,8 +797,14 @@
  */
 void lyplg_type_free_leafref(const struct ly_ctx *ctx, struct lyd_value *value);
 
-/*
- * String built-in type functions
+/** @} pluginsTypesLeafref */
+
+/**
+ * @defgroup pluginsTypesString Plugins: String built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement string built-in type.
  */
 
 /**
@@ -670,8 +815,14 @@
         uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
         struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err);
 
-/*
- * Union built-in type functions
+/** @} pluginsTypesString */
+
+/**
+ * @defgroup pluginsTypesUnion Plugins: Union built-in type callbacks
+ * @ingroup pluginsTypes
+ * @{
+ *
+ * Callbacs used (besides the [simple callbacks](@ref pluginsTypesSimple)) to implement union built-in type.
  */
 
 /**
@@ -714,9 +865,7 @@
  */
 void lyplg_type_free_union(const struct ly_ctx *ctx, struct lyd_value *value);
 
-/*
- * Other supporting functions
- */
+/** @} pluginsTypesBits */
 
 /**
  * @brief Unsigned integer value parser and validator.
@@ -815,7 +964,7 @@
 LY_ERR lyplg_type_resolve_leafref(const struct lysc_type_leafref *lref, const struct lyd_node *node, struct lyd_value *value,
         const struct lyd_node *tree, struct lyd_node **target, char **errmsg);
 
-/** @} types */
+/** @} pluginsTypes */
 
 #ifdef __cplusplus
 }
diff --git a/src/tree_data.h b/src/tree_data.h
index 9728359..9414baf 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -98,6 +98,82 @@
  * - ::lyd_target()
  *
  * - ::lyd_lyb_data_length()
+ *
+ *
+ * @section howtoDataMetadata Metadata Support
+ *
+ * YANG Metadata annotations are defined in [RFC 7952](https://tools.ietf.org/html/rfc7952) as YANG extension (and libyang
+ * [implements them as internal extension plugin](@ref howtoPluginsExtensions)). In practice, it allows to have XML
+ * attributes (there is also a special encoding for JSON) in YANG modeled data. libyang does not allow to have any XML
+ * attribute without the appropriate annotation definition describing the data as it is done e.g. for leafs. When an
+ * attribute without a matching annotation definition is found in the input data, it is:
+ * - silently dropped (with warning) or
+ * - an error is reported in case the ::LYD_PARSE_STRICT parser option is provided to the
+ *   [parser function](@ref howtoDataParsers) or
+ * - stored into a generic ::lyd_attr structure without a connection with any YANG module in case the ::LYD_PARSE_OPAQ
+ *   parser options is provided to the [parser function](@ref howtoDataParsers).
+ *
+ * There are some XML attributes, described by [YANG](https://tools.ietf.org/html/rfc7950) and
+ * [NETCONF](https://tools.ietf.org/html/rfc6241) specifications, which are not defined as annotations, but libyang
+ * implements them this way. In case of attributes in the YANG namespace (`insert`, `value` and `key` attributes
+ * for the NETCONF edit-config operation), they are defined in special libyang's internal module `yang`, which is
+ * available in each context and the content of this schema can be printed via
+ * [schema printers](@ref howtoSchemaPrinters).
+ *
+ * In case of the attributes described in [NETCONF specification](https://tools.ietf.org/html/rfc6241), the libyang's
+ * annotations structures are hidden and cannot be printed despite, internally, they are part of the `ietf-netconf`'s
+ * schema structure. Therefore, these attributes are available only when the `ietf-netconf` schema is loaded in the
+ * context. The definitions of these annotations are as follows:
+ *
+ *     md:annotation operation {
+ *       type enumeration {
+ *         enum merge;
+ *         enum replace;
+ *         enum create;
+ *         enum delete;
+ *         enum remove;
+ *       }
+ *     }
+ *
+ *     md:annotation type {
+ *       type enumeration {
+ *         enum subtree;
+ *         enum xpath {
+ *           if-feature "nc:xpath";
+ *         }
+ *       }
+ *     }
+ *
+ *     md:annotation select {
+ *       type string;
+ *     }
+ *
+ * Note, that, following the specification,
+ * - the `type` and `select` XML attributes are supposed to be unqualified (without namespace) and that
+ * - the `select`'s content is XPath and it is internally transformed by libyang into the format where the
+ *   XML namespace prefixes are replaced by the YANG module names.
+ *
+ *
+ * @section howtoDataYangdata yang-data Support
+ *
+ * [RFC 8040](https://tools.ietf.org/html/rfc8040) defines ietf-restconf module, which includes yang-data extension. Despite
+ * the definition in the RESTCONF YANG module, the yang-data concept is quite generic and used even in modules without a
+ * connection to RESTCONF protocol. The extension allows to define a separated YANG trees usable separately from any
+ * datastore.
+ *
+ * libyang implements support for yang-data internally as an [extension plugin](@ref howtoPluginsExtensions). To ease the
+ * use of yang-data with libyang, there are several generic functions, which are usable for yang-data:
+ *
+ * - ::lyd_parse_ext_data()
+ * - ::lyd_parse_ext_op()
+ *
+ * - ::lys_getnext_ext()
+ *
+ * - ::lyd_new_ext_inner()
+ * - ::lyd_new_ext_list()
+ * - ::lyd_new_ext_term()
+ * - ::lyd_new_ext_any()
+ * - ::lyd_new_ext_path()
  */
 
 /**
@@ -131,7 +207,7 @@
  * ::lyd_new_ext_inner(), ::lyd_new_ext_term(), ::lyd_new_ext_any(), ::lyd_new_ext_list() and ::lyd_new_ext_path()
  * functions.
  *
- * The [metadata](@ref howtoPluginsExtensionsMetadata) (and attributes in opaq nodes) can be created with ::lyd_new_meta()
+ * The [metadata](@ref howtoDataMetadata) (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