libyang CHANGE bind errors and store them in a context
diff --git a/src/libyang.h.in b/src/libyang.h.in
index 2e89340..0ea61b3 100644
--- a/src/libyang.h.in
+++ b/src/libyang.h.in
@@ -997,18 +997,17 @@
  */
 
 /**
- *
  * @page howtologger Logger
  *
  * There are 4 verbosity levels defined as ::LY_LOG_LEVEL. The level can be
  * changed by the ly_verb() function. By default, the verbosity level is
  * set to #LY_LLERR value.
  *
- * When an error is encountered, the error message and error number are stored for
- * later use. Caller is able to access the last error message via ly_errmsg() and the
- * corresponding last error code via #ly_errno. If that was a validation error (#ly_errno
- * is set to #LY_EVALID), also validation error code (via #ly_vecode) and path to the
- * error node (via ly_errpath()) are available.
+ * All the logging operations are tied to the specific **thread** and **context**.
+ * The default behaviour is that the last message (error or warning, verbose and debug
+ * messages are never stored) is always stored and can be accessed using ly_errmsg(). On error,
+ * #ly_errno is set. If that was a validation error (#ly_errno is set to #LY_EVALID),
+ * also validation error code (via ly_vecode()) and path to the error node (via ly_errpath()) are available.
  *
  * For some specific cases, a YANG schema can define error message and/or error tag (mainly for
  * use in NETCONF). If a message is set, it is provided via ly_errmsg(). If a tag is set in schema,
@@ -1019,6 +1018,14 @@
  * (if any) to the caller's callback function. In case of error level, the message and path are still
  * automatically stored and available via the functions and macros described above.
  *
+ * This is the basic way of working with errors but another, more sophisticated is also available. With ly_log_options()
+ * you 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 will grow indefinitely. With ly_err_last() you can retireve
+ * the latest error structure ly_err_item. Its attributes will correspond to the values returned by ly_errmsg(),
+ * ly_errpath(), ... This is actually a linked-list so you can get to previous errors using the **prev** pointer.
+ * Being processed, you can then free them with ly_err_clean().
+ *
  * \note API for this group of functions is described in the [logger module](@ref logger).
  *
  * Functions List
@@ -1026,11 +1033,14 @@
  * - ly_verb()
  * - ly_set_log_clb()
  * - ly_get_log_clb()
+ * - ly_log_options()
+ * - #ly_errno
+ * - ly_vecode()
  * - ly_errmsg()
  * - ly_errpath()
  * - ly_errapptag()
- * - #ly_errno
- * - #ly_vecode
+ * - ly_err_last()
+ * - ly_err_clean()
  */
 
 /**
@@ -1503,7 +1513,7 @@
  * @param[in] data_path Data path to be transformed.
  * @return Created schema path, NULL on error.
  */
-char *ly_path_data2schema(const struct ly_ctx *ctx, const char *data_path);
+char *ly_path_data2schema(struct ly_ctx *ctx, const char *data_path);
 
 /**@} context */
 
@@ -1690,11 +1700,10 @@
  * @brief Verbosity levels of the libyang logger.
  */
 typedef enum {
-    LY_LLSILENT = -1, /**< Print no messages. */
     LY_LLERR = 0,     /**< Print only error messages, default value. */
-    LY_LLWRN,         /**< Print error and warning messages. */
-    LY_LLVRB,         /**< Besides errors and warnings, print some other verbose messages. */
-    LY_LLDBG          /**< Print all messages including some development debug messages (be careful,
+    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!). */
 } LY_LOG_LEVEL;
 
@@ -1705,23 +1714,57 @@
  */
 LY_LOG_LEVEL ly_verb(LY_LOG_LEVEL level);
 
+/**
+ * @defgroup logopts Logging options
+ * @ingroup logger
+ *
+ * Logging option bits of libyang.
+ *
+ * @{
+ */
+#define LY_LOLOG        0x01 /**< Log messages normally, using callback if set. If not set, messages will
+                                  not be printed by libyang. */
+#define LY_LOSTORE      0x02 /**< Store any generated errors or warnings, never verbose or debug messages.
+                                  Note that if #LY_LOLOG is not set then verbose and debug messages are always lost. */
+#define LY_LOSTORE_LAST 0x06 /**< Store any generated errors or warnings but only the last message, always overwrite
+                                  the previous one. */
+
+/**
+ * @}
+ */
+
+/**
+ * @brief Set additional logger options. Default is #LY_LOLOG | #LY_LOSTORE_LAST.
+ *
+ * @param[in] opts Bitfield of @ref logopts.
+ * @return Previous logger options.
+ */
+int ly_log_options(int opts);
+
 #ifndef NDEBUG
 
 /**
- * @typedef LY_LOG_DBG_GROUP
- * @brief Selected displayed debug message groups.
+ * @defgroup dbggroup Debug message groups
+ * @ingroup logger
+ *
+ * Selected displayed debug message groups.
+ *
+ * @{
  */
-typedef enum {
-    LY_LDGDICT = 0x01,  /**< Dictionary additions and deletions. */
-    LY_LDGYANG = 0x02,  /**< YANG parser messages. */
-    LY_LDGYIN = 0x04,   /**< YIN parser messages. */
-    LY_LDGXPATH = 0x08, /**< XPath parsing end evaluation. */
-    LY_LDGDIFF = 0x10   /**< Diff processing and creation. */
-} LY_LOG_DBG_GROUP;
+
+#define LY_LDGDICT  0x01 /**< Dictionary additions and deletions. */
+#define LY_LDGYANG  0x02 /**< YANG parser messages. */
+#define LY_LDGYIN   0x04 /**< YIN parser messages. */
+#define LY_LDGXPATH 0x08 /**< XPath parsing end evaluation. */
+#define LY_LDGDIFF  0x10 /**< Diff processing and creation. */
+
+/**
+ * @}
+ */
 
 /**
  * @brief Enable specific debugging messages (independent of log level).
- * @param[in] dbg_groups Bitfield of #LY_LOG_DBG_GROUP - enabled debug message groups.
+ * @param[in] dbg_groups Bitfield of enabled debug message groups (see @ref dbggroup).
  */
 void ly_verb_dbg(int dbg_groups);
 
@@ -1866,36 +1909,40 @@
 
 /**
  * @cond INTERNAL
- * Get address of (thread-specific) `ly_errno' and `ly_vecode` variable.
+ * Get address of (thread-specific) `ly_errno' variable.
  */
-LY_ERR *ly_errno_address(void);
-
-LY_VECODE *ly_vecode_address(void);
+LY_ERR *ly_errno_glob_address(void);
 
 /**
  * @endcond INTERNAL
  * @brief libyang specific (thread-safe) errno (see #LY_ERR for the list of possible values and their meaning).
  */
-#define ly_errno (*ly_errno_address())
+#define ly_errno (*ly_errno_glob_address())
 
 /**
- * @brief libyang's validation error code
+ * @brief Get the last (thread, context-specific) validation error code.
+ *
+ * This value is set only if ly_errno is #LY_EVALID.
+ *
+ * @param[in] ctx Relative context.
+ * @return Validation error code.
  */
-#define ly_vecode (*ly_vecode_address())
+LY_VECODE ly_vecode(const struct ly_ctx *ctx);
 
 /**
- * @brief Get the last (thread-specific) error message. If the coresponding module defined
+ * @brief Get the last (thread, context-specific) error message. If the coresponding module defined
  * a specific error message, it will be used instead the default one.
  *
- * Sometimes, the error message is extended with path of the element where is the problem.
+ * Sometimes, the error message is extended with path of the element where the problem is.
  * 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.
  */
-const char *ly_errmsg(void);
+const char *ly_errmsg(const struct ly_ctx *ctx);
 
 /**
- * @brief Get the last (thread-specific) path of the element where was an error.
+ * @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
  * whenever a subsequent error message is printed, the path is erased or rewritten.
@@ -1904,22 +1951,58 @@
  * or XML data, the path can be just XML path. In such a case, the corresponding
  * ly_vecode (value 1-3) is set.
  *
+ * @param[in] ctx Relative context.
  * @return Path of the error element, empty string if error path does not apply to the last error.
  */
-const char *ly_errpath(void);
+const char *ly_errpath(const struct ly_ctx *ctx);
 
 /**
- * @brief Get the last (thread-specific) error-app-tag if there was a specific one defined
+ * @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
  * whenever a subsequent error message is printed, the app-tag is erased or rewritten.
  *
+ * @param[in] ctx Relative context.
  * @return Error-app-tag of the last error, empty string if the error-app-tag does not apply to the last error.
  */
-const char *ly_errapptag(void);
+const char *ly_errapptag(const struct ly_ctx *ctx);
 
-/**@} logger */
+/**
+ * @brief Libyang full error structure.
+ */
+struct ly_err_item {
+    LY_LOG_LEVEL level;
+    LY_ERR no;
+    LY_VECODE vecode;
+    char *msg;
+    char *path;
+    char *apptag;
+    struct ly_err_item *next;
+    struct ly_err_item *prev; /* first item's prev points to the last item */
+};
+
+/**
+ * @brief Get the last (thread, context-specific) error structure.
+ *
+ * @param[in] ctx Relative context.
+ * @return Last error structure (can be NULL), do not modify!
+ */
+struct ly_err_item *ly_err_last(const struct ly_ctx *ctx);
+
+/**
+ * @brief Free error structures from a context.
+ *
+ * If \p eitem is not set, free all the error structures.
+ *
+ * @param[in] ctx Relative context.
+ * @param[in] eitem Oldest error structure to remove, optional.
+ */
+void ly_err_clean(struct ly_ctx *ctx, struct ly_err_item *eitem);
+
+/**
+ * @} logger
+ */
 
 #ifdef __cplusplus
 }