Merge remote-tracking branch 'upstream/libyang2' into libyang2
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 346527b..199cdee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -211,6 +211,7 @@
     src/parser_xml.c
     src/printer_data.c
     src/printer_xml.c
+    src/printer_json.c
     src/tree_schema.c
     src/tree_schema_free.c
     src/tree_schema_compile.c
diff --git a/src/common.h b/src/common.h
index f0f70e4..dc23869 100644
--- a/src/common.h
+++ b/src/common.h
@@ -433,6 +433,14 @@
                                    const char **value, size_t *value_len, const char **errmsg);
 
 /**
+ * @brief ly_clb_get_prefix implementation for JSON. For its simplicity, this implementation is used
+ * internally for various purposes.
+ *
+ * Implemented in printer_json.c
+ */
+const char *json_print_get_prefix(const struct lys_module *mod, void *private);
+
+/**
  * @brief mmap(2) wrapper to map input files into memory to unify parsing.
  *
  * The address space is allocate only for reading.
diff --git a/src/parser_xml.c b/src/parser_xml.c
index fcd9681..48ddf73 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -323,6 +323,14 @@
         /* calculate the hash and insert it into parent (list with keys is handled when its keys are inserted) */
         lyd_hash(cur);
         lyd_insert_hash(cur);
+
+        /* if we have empty non-presence container, we keep it, but mark it as default */
+        if (cur->schema->nodetype == LYS_CONTAINER && !((struct lyd_node_inner*)cur)->child &&
+                !cur->attr && !(((struct lysc_node_container*)cur->schema)->flags & LYS_PRESENCE)) {
+            cur->flags |= LYD_DEFAULT;
+        }
+
+        /* TODO context validation */
     }
 
 cleanup:
diff --git a/src/plugins_types.c b/src/plugins_types.c
index df706a5..15386ad 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -50,14 +50,11 @@
  * Implementation of the ly_type_print_clb.
  */
 static const char *
-ly_type_print_canonical(const struct lyd_value *value, LYD_FORMAT UNUSED(format), int prefixes, int *dynamic)
+ly_type_print_canonical(const struct lyd_value *value, LYD_FORMAT UNUSED(format),
+                        ly_clb_get_prefix UNUSED(get_prefix), void *UNUSED(printer), int *dynamic)
 {
     *dynamic = 0;
-    if (prefixes) {
-        return "";
-    } else {
-        return (char*)value->canonized;
-    }
+    return (char*)value->canonized;
 }
 
 /**
@@ -120,7 +117,7 @@
 }
 
 API struct lyd_value_prefix *
-ly_type_get_prefixes(struct ly_ctx *ctx, const char *value, size_t value_len, ly_clb_resolve_prefix get_prefix, void *parser)
+ly_type_get_prefixes(struct ly_ctx *ctx, const char *value, size_t value_len, ly_clb_resolve_prefix resolve_prefix, void *parser)
 {
     LY_ERR ret;
     unsigned int c;
@@ -150,7 +147,7 @@
                     }
                 }
                 if (!mod) {
-                    mod = get_prefix(ctx, start, len, parser);
+                    mod = resolve_prefix(ctx, start, len, parser);
                     if (mod) {
                         LY_ARRAY_NEW_GOTO(ctx, prefixes, p, ret, error);
                         p->mod = mod;
@@ -439,7 +436,7 @@
  */
 static LY_ERR
 ly_type_store_int(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                  ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                  ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                   const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                   struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -513,7 +510,7 @@
  */
 static LY_ERR
 ly_type_store_uint(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                   ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                   ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                    const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                    struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -586,7 +583,7 @@
  */
 static LY_ERR
 ly_type_store_decimal64(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                        ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                        ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                         const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                         struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -669,7 +666,7 @@
  */
 static LY_ERR
 ly_type_store_binary(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                     ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                     ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                      const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                      struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -772,7 +769,7 @@
  */
 static LY_ERR
 ly_type_store_string(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                     ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                     ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                      const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                      struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -815,7 +812,7 @@
  */
 static LY_ERR
 ly_type_store_bits(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                   ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                   ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                    const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                    struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -1001,7 +998,7 @@
  */
 static LY_ERR
 ly_type_store_enum(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                   ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                   ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                    const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                    struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -1080,7 +1077,7 @@
  */
 static LY_ERR
 ly_type_store_boolean(struct ly_ctx *ctx, struct lysc_type *UNUSED(type), const char *value, size_t value_len, int options,
-                      ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                      ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                       const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                       struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -1128,7 +1125,7 @@
  */
 static LY_ERR
 ly_type_store_empty(struct ly_ctx *ctx, struct lysc_type *UNUSED(type), const char *value, size_t value_len, int options,
-                    ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
+                    ly_clb_resolve_prefix UNUSED(resolve_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
                     const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                     struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -1185,7 +1182,7 @@
  */
 static LY_ERR
 ly_type_store_identityref(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                          ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT UNUSED(format),
+                          ly_clb_resolve_prefix resolve_prefix, void *parser, LYD_FORMAT UNUSED(format),
                           const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
                           struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -1217,7 +1214,7 @@
         goto error;
     }
 
-    mod = get_prefix(ctx, prefix, prefix_len, parser);
+    mod = resolve_prefix(ctx, prefix, prefix_len, parser);
     if (!mod) {
         asprintf(&errmsg, "Invalid identityref \"%.*s\" value - unable to map prefix to YANG schema.", (int)value_len, value);
         goto error;
@@ -1290,28 +1287,14 @@
  * Implementation of the ly_type_print_clb.
  */
 static const char *
-ly_type_print_identityref(const struct lyd_value *value, LYD_FORMAT format, int prefixes, int *dynamic)
+ly_type_print_identityref(const struct lyd_value *value, LYD_FORMAT UNUSED(format), ly_clb_get_prefix get_prefix, void *printer, int *dynamic)
 {
     char *result = NULL;
 
-    if (prefixes) {
-        if (format == LYD_XML) {
-            *dynamic = 1;
-            asprintf(&result, "xmlns:%s=\"%s\"", value->ident->module->prefix, value->ident->module->ns);
-            return result;
-        } else {
-            *dynamic = 0;
-            return "";
-        }
-    } else {
-        *dynamic = 1;
-        if (format == LYD_XML) {
-            asprintf(&result, "%s:%s", value->ident->module->prefix, value->ident->name);
-        } else {
-            asprintf(&result, "%s:%s", value->ident->module->name, value->ident->name);
-        }
-        return result;
-    }
+    *dynamic = 1;
+    asprintf(&result, "%s:%s", get_prefix(value->ident->module, printer), value->ident->name);
+
+    return result;
 }
 
 /* @brief Duplication callback of the identityref values.
@@ -1541,7 +1524,7 @@
  */
 static LY_ERR
 ly_type_store_instanceid(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                         ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format,
+                         ly_clb_resolve_prefix resolve_prefix, void *parser, LYD_FORMAT format,
                          const void *UNUSED(context_node), const struct lyd_node **trees,
                          struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -1568,9 +1551,10 @@
         /* the second run, the first one ended with LY_EINCOMPLETE, but we have prepared the target structure */
 
         if (!lyd_target(storage->target, trees)) {
-            /* TODO print instance-identifier */
+            /* in error message we print the JSON format of the instance-identifier - in case of XML, it is not possible
+             * to get the exactly same string as original, JSON is less demanding and still well readable/understandable. */
             int dynamic = 0;
-            const char *id = storage->realtype->plugin->print(storage, format, 0, &dynamic);
+            const char *id = storage->realtype->plugin->print(storage, LYD_JSON, json_print_get_prefix, NULL, &dynamic);
             asprintf(&errmsg, "Invalid instance-identifier \"%s\" value - required instance not found.", id);
             if (dynamic) {
                 free((char*)id);
@@ -1583,7 +1567,7 @@
         return LY_SUCCESS;
     } else {
         /* first run without prepared target, we will need all the prefixes used in the instance-identifier value */
-        prefixes = ly_type_get_prefixes(ctx, value, value_len, get_prefix, parser);
+        prefixes = ly_type_get_prefixes(ctx, value, value_len, resolve_prefix, parser);
     }
 
     if (value[0] != '/') {
@@ -1683,7 +1667,7 @@
 
                 if (node_d) {
                     while (node_d) {
-                        if (!lyd_value_compare((const struct lyd_node_term*)key_d, val, val_len, get_prefix, parser, format, trees)) {
+                        if (!lyd_value_compare((const struct lyd_node_term*)key_d, val, val_len, resolve_prefix, parser, format, trees)) {
                             /* match */
                             break;
                         }
@@ -1711,7 +1695,7 @@
                     }
                 } else {
                     /* check value to the type */
-                    if (lys_value_validate(NULL, key_s, val, val_len, get_prefix, parser, format)) {
+                    if (lys_value_validate(NULL, key_s, val, val_len, resolve_prefix, parser, format)) {
                         asprintf(&errmsg, "Invalid instance-identifier \"%.*s\" value - key-predicate \"%.*s\"'s key value is invalid.",
                                  (int)value_len, value, (int)(token - pred_start), pred_start);
                         goto error;
@@ -1758,7 +1742,7 @@
 
                 if (key_d) {
                     while (key_d) {
-                        if (!lyd_value_compare((const struct lyd_node_term*)key_d, val, val_len, get_prefix, parser, format, trees)) {
+                        if (!lyd_value_compare((const struct lyd_node_term*)key_d, val, val_len, resolve_prefix, parser, format, trees)) {
                             /* match */
                             break;
                         }
@@ -1772,7 +1756,7 @@
                     }
                 } else {
                     /* check value to the type */
-                    if (lys_value_validate(NULL, key_s, val, val_len, get_prefix, parser, format)) {
+                    if (lys_value_validate(NULL, key_s, val, val_len, resolve_prefix, parser, format)) {
                         asprintf(&errmsg, "Invalid instance-identifier \"%.*s\" value - leaf-list-predicate \"%.*s\"'s value is invalid.",
                                  (int)value_len, value, (int)(token - pred_start), pred_start);
                         goto error;
@@ -1943,152 +1927,91 @@
     return LY_SUCCESS;
 }
 
-static void
-ly_type_print_prefixes_mod(char **str, struct ly_set *printed, struct lys_module *mod)
-{
-    unsigned int u = printed->count;
-    if (ly_set_add(printed, mod, 0) == (int)u) {
-        /* newly added module - print it */
-        asprintf(str, "%s%sxmlns:%s=\"%s\"", *str ? *str : "", *str ? " " : "", mod->prefix, mod->ns);
-    }
-}
-
 /**
  * @brief Printer callback printing the instance-identifier value.
  *
  * Implementation of the ly_type_print_clb.
  */
 static const char *
-ly_type_print_instanceid(const struct lyd_value *value, LYD_FORMAT format, int prefixes, int *dynamic)
+ly_type_print_instanceid(const struct lyd_value *value, LYD_FORMAT format, ly_clb_get_prefix get_prefix, void *printer, int *dynamic)
 {
     unsigned int u, v;
     char *result = NULL;
 
-    if (prefixes) {
-        /* print namespace definition -only for XML, it does not make sense in JSON */
-        if (format == LYD_XML) {
-            struct ly_set printed_prefixes = {0};
-
-            LY_ARRAY_FOR(value->target, u) {
-                ly_type_print_prefixes_mod(&result, &printed_prefixes, value->target[u].node->module);
-                LY_ARRAY_FOR(value->target[u].predicates, v) {
-                    struct lyd_value_path_predicate *pred = &value->target[u].predicates[v];
-                    if (pred->type) {
-                        /* non-position predicate with a value
-                         * (key is of the same namespace as the list, so we don't need to handle its prefix) */
-                        int d = 0;
-                        char *token, *s = (char*)pred->value->realtype->plugin->print(pred->value, LYD_XML, 1, &d);
-                        if (s && s[0]) {
-                            char *start = s;
-                            if (!d) {
-                                start = s = strdup(s);
-                            }
-                            while ((token = strsep(&s, " "))) {
-                                unsigned int i;
-                                char *equal;
-                                equal = strchr(token, '=');
-                                /* check if we already have such a prefix */
-                                for (i = 0; i < printed_prefixes.count; i++) {
-                                    /* equal points to =\"namespace\" and we need to compare just the namespace without quotation */
-                                    size_t len = strlen(equal) - 3;
-                                    size_t len_ns = strlen(((struct lys_module *)printed_prefixes.objs[i])->ns);
-                                    if (len == len_ns && !strncmp(((struct lys_module *)printed_prefixes.objs[i])->ns, equal + 2, len)) {
-                                        /* match, do not print this namespace definition */
-                                        break;
-                                    }
-                                }
-                                if (i == printed_prefixes.count) {
-                                    /* not yet printed namespace */
-                                    ly_strcat(&result, "%s%s", result ? " " : "", token);
-                                }
-                            }
-                            free(start);
-                        }
+    if (format == LYD_XML) {
+        /* everything is prefixed */
+        LY_ARRAY_FOR(value->target, u) {
+            ly_strcat(&result, "/%s:%s", get_prefix(value->target[u].node->module, printer), value->target[u].node->name);
+            LY_ARRAY_FOR(value->target[u].predicates, v) {
+                struct lyd_value_path_predicate *pred = &value->target[u].predicates[v];
+                if (pred->type == 0) {
+                    /* position predicate */
+                    ly_strcat(&result, "[%"PRIu64"]", pred->position);
+                } else if (pred->type == 1) {
+                    /* key-predicate */
+                    int d = 0;
+                    const char *value = pred->value->realtype->plugin->print(pred->value, format, get_prefix, printer, &d);
+                    char quot = '\'';
+                    if (strchr(value, quot)) {
+                        quot = '"';
+                    }
+                    ly_strcat(&result, "[%s:%s=%c%s%c]", get_prefix(pred->key->module, printer), pred->key->name, quot, value, quot);
+                    if (d) {
+                        free((char*)value);
+                    }
+                } else if (pred->type == 2) {
+                    /* leaf-list-predicate */
+                    int d = 0;
+                    const char *value = pred->value->realtype->plugin->print(pred->value, format, get_prefix, printer, &d);
+                    char quot = '\'';
+                    if (strchr(value, quot)) {
+                        quot = '"';
+                    }
+                    ly_strcat(&result, "[.=%c%s%c]", quot, value, quot);
+                    if (d) {
+                        free((char*)value);
                     }
                 }
             }
-            ly_set_erase(&printed_prefixes, NULL);
-        } else { /* JSON */
-            *dynamic = 0;
-            return "";
         }
-    } else {
-        /* print value */
-        if (format == LYD_XML) {
-            /* everything is prefixed */
-            LY_ARRAY_FOR(value->target, u) {
-                 ly_strcat(&result, "/%s:%s", value->target[u].node->module->prefix, value->target[u].node->name);
-                LY_ARRAY_FOR(value->target[u].predicates, v) {
-                    struct lyd_value_path_predicate *pred = &value->target[u].predicates[v];
-                    if (pred->type == 0) {
-                        /* position predicate */
-                        ly_strcat(&result, "[%"PRIu64"]", pred->position);
-                    } else if (pred->type == 1) {
-                        /* key-predicate */
-                        int d = 0;
-                        const char *value = pred->value->realtype->plugin->print(pred->value, format, 0, &d);
-                        char quot = '\'';
-                        if (strchr(value, quot)) {
-                            quot = '"';
-                        }
-                        ly_strcat(&result, "[%s:%s=%c%s%c]", pred->key->module->prefix, pred->key->name, quot, value, quot);
-                        if (d) {
-                            free((char*)value);
-                        }
-                    } else if (pred->type == 2) {
-                        /* leaf-list-predicate */
-                        int d = 0;
-                        const char *value = pred->value->realtype->plugin->print(pred->value, format, 0, &d);
-                        char quot = '\'';
-                        if (strchr(value, quot)) {
-                            quot = '"';
-                        }
-                        ly_strcat(&result, "[.=%c%s%c]", quot, value, quot);
-                        if (d) {
-                            free((char*)value);
-                        }
-                    }
-                }
+    } else { /* LYD_JSON */
+        /* only the first node or the node changing module is prefixed */
+        struct lys_module *mod = NULL;
+        LY_ARRAY_FOR(value->target, u) {
+            if (mod != value->target[u].node->module) {
+                mod = value->target[u].node->module;
+                ly_strcat(&result, "/%s:%s", get_prefix(mod, printer), value->target[u].node->name);
+            } else {
+                ly_strcat(&result, "/%s", value->target[u].node->name);
             }
-        } else { /* LYD_JSON */
-            /* only the first node or the node changing module is prefixed */
-            struct lys_module *mod = NULL;
-            LY_ARRAY_FOR(value->target, u) {
-                if (mod != value->target[u].node->module) {
-                    mod = value->target[u].node->module;
-                    ly_strcat(&result, "/%s:%s", mod->name, value->target[u].node->name);
-                } else {
-                    ly_strcat(&result, "/%s", value->target[u].node->name);
-                }
-                LY_ARRAY_FOR(value->target[u].predicates, v) {
-                    struct lyd_value_path_predicate *pred = &value->target[u].predicates[v];
-                    if (pred->type == 0) {
-                        /* position predicate */
-                        ly_strcat(&result, "[%"PRIu64"]", pred->position);
-                    } else if (pred->type == 1) {
-                        /* key-predicate */
-                        int d = 0;
-                        const char *value = pred->value->realtype->plugin->print(pred->value, format, 0, &d);
-                        char quot = '\'';
-                        if (strchr(value, quot)) {
-                            quot = '"';
-                        }
-                        ly_strcat(&result, "[%s=%c%s%c]", pred->key->name, quot, value, quot);
-                        if (d) {
-                            free((char*)value);
-                        }
-                    } else if (pred->type == 2) {
-                        /* leaf-list-predicate */
-                        int d = 0;
-                        const char *value = pred->value->realtype->plugin->print(pred->value, format, 0, &d);
-                        char quot = '\'';
-                        if (strchr(value, quot)) {
-                            quot = '"';
-                        }
-                        ly_strcat(&result, "[.=%c%s%c]", quot, value, quot);
-                        if (d) {
-                            free((char*)value);
-                        }
+            LY_ARRAY_FOR(value->target[u].predicates, v) {
+                struct lyd_value_path_predicate *pred = &value->target[u].predicates[v];
+                if (pred->type == 0) {
+                    /* position predicate */
+                    ly_strcat(&result, "[%"PRIu64"]", pred->position);
+                } else if (pred->type == 1) {
+                    /* key-predicate */
+                    int d = 0;
+                    const char *value = pred->value->realtype->plugin->print(pred->value, format, get_prefix, printer, &d);
+                    char quot = '\'';
+                    if (strchr(value, quot)) {
+                        quot = '"';
+                    }
+                    ly_strcat(&result, "[%s=%c%s%c]", pred->key->name, quot, value, quot);
+                    if (d) {
+                        free((char*)value);
+                    }
+                } else if (pred->type == 2) {
+                    /* leaf-list-predicate */
+                    int d = 0;
+                    const char *value = pred->value->realtype->plugin->print(pred->value, format, get_prefix, printer, &d);
+                    char quot = '\'';
+                    if (strchr(value, quot)) {
+                        quot = '"';
+                    }
+                    ly_strcat(&result, "[.=%c%s%c]", quot, value, quot);
+                    if (d) {
+                        free((char*)value);
                     }
                 }
             }
@@ -2162,7 +2085,7 @@
  */
 static LY_ERR
 ly_type_store_leafref(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                      ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format,
+                      ly_clb_resolve_prefix resolve_prefix, void *parser, LYD_FORMAT format,
                       const void *context_node, const struct lyd_node **trees,
                       struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -2188,7 +2111,7 @@
 
     /* check value according to the real type of the leafref target */
     ret = type_lr->realtype->plugin->store(ctx, type_lr->realtype, value, value_len, options,
-                                             get_prefix, parser, format, context_node, trees,
+                                             resolve_prefix, parser, format, context_node, trees,
                                              storage, canonized, err);
     if (ret != LY_SUCCESS && ret != LY_EINCOMPLETE) {
         return ret;
@@ -2418,9 +2341,9 @@
  * Implementation of the ly_type_print_clb.
  */
 static const char *
-ly_type_print_leafref(const struct lyd_value *value, LYD_FORMAT format, int prefixes, int *dynamic)
+ly_type_print_leafref(const struct lyd_value *value, LYD_FORMAT format, ly_clb_get_prefix get_prefix, void *printer, int *dynamic)
 {
-    return value->realtype->plugin->print(value, format, prefixes, dynamic);
+    return value->realtype->plugin->print(value, format, get_prefix, printer, dynamic);
 }
 
 /* @brief Duplication callback of the leafref values.
@@ -2451,7 +2374,7 @@
  */
 static LY_ERR
 ly_type_store_union(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                    ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format,
+                    ly_clb_resolve_prefix resolve_prefix, void *parser, LYD_FORMAT format,
                     const void *context_node, const struct lyd_node **trees,
                     struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
 {
@@ -2493,7 +2416,7 @@
         subvalue->value = calloc(1, sizeof *subvalue->value);
 
         /* store prefixes for later use */
-        subvalue->prefixes = ly_type_get_prefixes(ctx, value, value_len, get_prefix, parser);
+        subvalue->prefixes = ly_type_get_prefixes(ctx, value, value_len, resolve_prefix, parser);
 
 search_subtype:
         /* use the first usable sybtype to store the value */
@@ -2583,31 +2506,9 @@
  * Implementation of the ly_type_print_clb.
  */
 static const char *
-ly_type_print_union(const struct lyd_value *value, LYD_FORMAT format, int prefixes, int *dynamic)
+ly_type_print_union(const struct lyd_value *value, LYD_FORMAT format, ly_clb_get_prefix get_prefix, void *printer, int *dynamic)
 {
-    unsigned int u;
-    char *result = NULL;
-
-    if (prefixes) {
-        if (format == LYD_XML) {
-            LY_ARRAY_FOR(value->subvalue->prefixes, u) {
-                ly_strcat(&result, "%sxmlns:%s=\"%s\"", result ? " " : "",
-                          value->subvalue->prefixes[u].prefix, value->subvalue->prefixes[u].mod->ns);
-            }
-            if (result) {
-                *dynamic = 1;
-                return result;
-            } else {
-                *dynamic = 0;
-                return "";
-            }
-        } else {
-            *dynamic = 0;
-            return "";
-        }
-    } else {
-        return ly_type_print_canonical(value, format, 0, dynamic);
-    }
+    return ly_type_print_canonical(value, format, get_prefix, printer, dynamic);
 }
 
 /* @brief Duplication callback of the union values.
diff --git a/src/plugins_types.h b/src/plugins_types.h
index 49f624f..5023b1b 100644
--- a/src/plugins_types.h
+++ b/src/plugins_types.h
@@ -94,8 +94,8 @@
  * @param[in] value_len Length of the given \p value.
  * @param[in] options [Type plugin options ](@ref plugintypeopts).
  *
- * @param[in] get_prefix Parser-specific getter to resolve prefixes used in the value strings.
- * @param[in] parser Parser's data for @p get_prefix
+ * @param[in] resolve_prefix Parser-specific callback to resolve prefixes used in the value strings.
+ * @param[in] parser Parser's data for @p resolve_prefix
  * @param[in] format Input format of the data.
  * @param[in] context_node The @p value's node for the case that the require-instance restriction is supposed to be resolved. This argument is of
  *            lys_node (in case LY_TYPE_OPTS_INCOMPLETE_DATA set in @p options) or lyd_node structure.
@@ -115,7 +115,7 @@
  * @return LY_ERR value if an error occurred and the value could not be canonized following the type's rules.
  */
 typedef LY_ERR (*ly_type_store_clb)(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
-                                    ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format,
+                                    ly_clb_resolve_prefix resolve_prefix, void *parser, LYD_FORMAT format,
                                     const void *context_node, const struct lyd_node **trees,
                                     struct lyd_value *storage, const char **canonized, struct ly_err_item **err);
 
@@ -137,15 +137,15 @@
  * @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] prefixes Flag to get printed prefix/namespace string instead of the value itself.
- *            Since JSON uses YANG module names as prefixes, this option make sense only with LYD_XML @p format.
+ * @param[in] get_prefix Callback to get prefix to use when printing objects supposed to be prefixed.
+ * @param[in] printer Private data for the @p get_prefix callback.
  * @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
  *         can be responsible for freeing allocated memory.
  * @return NULL in case of error.
  */
-typedef const char *(*ly_type_print_clb)(const struct lyd_value *value, LYD_FORMAT format, int prefixes, int *dynamic);
+typedef const char *(*ly_type_print_clb)(const struct lyd_value *value, LYD_FORMAT format, ly_clb_get_prefix get_prefix, void *printer, int *dynamic);
 
 /**
  * @brief Callback to duplicate data in data structure. Note that callback is even responsible for duplicating lyd_value::canonized.
diff --git a/src/printer_json.c b/src/printer_json.c
new file mode 100644
index 0000000..1ef4309
--- /dev/null
+++ b/src/printer_json.c
@@ -0,0 +1,39 @@
+/**
+ * @file printer_xml.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @author Radek Krejci <rkrejci@cesnet.cz>
+ * @brief XML printer for libyang data structure
+ *
+ * Copyright (c) 2015 - 2019 CESNET, z.s.p.o.
+ *
+ * This source code is licensed under BSD 3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "log.h"
+#include "plugins_types.h"
+#include "printer_data.h"
+#include "printer_internal.h"
+#include "tree.h"
+#include "tree_data.h"
+#include "tree_schema.h"
+
+/**
+ * @brief JSON mapping of YANG modules to prefixes in values.
+ *
+ * Implementation of ly_clb_get_prefix.
+ */
+const char *
+json_print_get_prefix(const struct lys_module *mod, void *UNUSED(private))
+{
+    return mod->name;
+}
+
diff --git a/src/printer_xml.c b/src/printer_xml.c
index 813d032..8d2dd01 100644
--- a/src/printer_xml.c
+++ b/src/printer_xml.c
@@ -334,6 +334,20 @@
 static LY_ERR xml_print_node(struct xmlpr_ctx *ctx, const struct lyd_node *node);
 
 /**
+ * @brief XML mapping of YANG modules to prefixes in values.
+ *
+ * Implementation of ly_clb_get_prefix
+ */
+static const char *
+xml_print_get_prefix(const struct lys_module *mod, void *private)
+{
+    struct ly_set *ns_list = (struct ly_set*)private;
+
+    ly_set_add(ns_list, (void*)mod, 0);
+    return mod->prefix;
+}
+
+/**
  * @brief Print XML element representing lyd_node_term.
  *
  * @param[in] ctx XML printer context.
@@ -344,18 +358,28 @@
 xml_print_term(struct xmlpr_ctx *ctx, const struct lyd_node_term *node)
 {
     LY_CHECK_RET(xml_print_node_open(ctx, (struct lyd_node *)node));
+    struct ly_set ns_list = {0};
+    unsigned int u;
+    int dynamic;
+    const char *value = node->value.realtype->plugin->print(&node->value, LYD_XML, xml_print_get_prefix, &ns_list, &dynamic);
 
-    if (((struct lysc_node_leaf*)node->schema)->type->plugin->flags & LY_TYPE_FLAG_PREFIXES) {
-        /* TODO get prefixes from the value and print namespaces */
+    /* print namespaces connected with the values's prefixes */
+    for (u = 0; u < ns_list.count; ++u) {
+        const struct lys_module *mod = (const struct lys_module*)ns_list.objs[u];
+        ly_print(ctx->out, "%sxmlns:%s=\"%s\"", u ? " " : "", mod->prefix, mod->ns);
     }
+    ly_set_erase(&ns_list, NULL);
 
-    if (!node->value.canonized || !node->value.canonized[0]) {
+    if (!value || !value[0]) {
         ly_print(ctx->out, "/>%s", LEVEL ? "\n" : "");
     } else {
         ly_print(ctx->out, ">");
-        lyxml_dump_text(ctx->out, node->value.canonized, 0);
+        lyxml_dump_text(ctx->out, value, 0);
         ly_print(ctx->out, "</%s>%s", node->schema->name, LEVEL ? "\n" : "");
     }
+    if (dynamic) {
+        free((void*)value);
+    }
 
     return LY_SUCCESS;
 }
diff --git a/src/printer_yang.c b/src/printer_yang.c
index 42fcb14..a54c30f 100755
--- a/src/printer_yang.c
+++ b/src/printer_yang.c
@@ -26,6 +26,7 @@
 #include "tree.h"
 #include "tree_schema.h"
 #include "tree_schema_internal.h"
+#include "plugins_types.h"
 #include "xpath.h"
 
 /**
@@ -900,6 +901,19 @@
 }
 
 static void
+yprc_dflt_value(struct ypr_ctx *ctx, const struct lyd_value *value, struct lysc_ext_instance *exts)
+{
+    int dynamic;
+    const char *str;
+
+    str = value->realtype->plugin->print(value, LYD_JSON, json_print_get_prefix, NULL, &dynamic);
+    ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, str, exts);
+    if (dynamic) {
+        free((void*)str);
+    }
+}
+
+static void
 yprc_type(struct ypr_ctx *ctx, const struct lysc_type *type)
 {
     unsigned int u;
@@ -911,7 +925,7 @@
     yprc_extension_instances(ctx, LYEXT_SUBSTMT_SELF, 0, type->exts, &flag, 0);
     if (type->dflt) {
         ypr_open(ctx->out, &flag);
-        ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, type->dflt, type->exts);
+        yprc_dflt_value(ctx, type->dflt, type->exts);
     }
 
     switch(type->basetype) {
@@ -1539,7 +1553,10 @@
     LY_ARRAY_FOR(leaf->musts, u) {
         yprc_must(ctx, &leaf->musts[u], NULL);
     }
-    ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, 0, leaf->dflt, leaf->exts);
+
+    if (leaf->dflt) {
+        yprc_dflt_value(ctx, leaf->dflt, leaf->exts);
+    }
 
     yprc_node_common2(ctx, node, NULL);
 
@@ -1603,7 +1620,7 @@
         yprc_must(ctx, &llist->musts[u], NULL);
     }
     LY_ARRAY_FOR(llist->dflts, u) {
-        ypr_substmt(ctx, LYEXT_SUBSTMT_DEFAULT, u, llist->dflts[u], llist->exts);
+        yprc_dflt_value(ctx, llist->dflts[u], llist->exts);
     }
 
     ypr_config(ctx, node->flags, node->exts, NULL);
diff --git a/src/tree.h b/src/tree.h
index 5210ce2..d0a9ced 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -157,10 +157,12 @@
 extern const char* ly_data_type2str[LY_DATA_TYPE_COUNT];
 
 /**
- * @brief Callback provided by the data parsers to type plugins to resolve (format-specific) mapping between prefixes used in the value strings
- * to the YANG schemas.
+ * @brief Callback provided by the data/schema parsers to type plugins to resolve (format-specific) mapping between prefixes used
+ * in the value strings to the YANG schemas.
  *
- * XML uses XML namespaces, JSON uses schema names as prefixes.
+ * Reverse function to ly_clb_get_prefix.
+ *
+ * XML uses XML namespaces, JSON uses schema names as prefixes, YIN/YANG uses prefixes of the imports.
  *
  * @param[in] ctx libyang context to find the schema.
  * @param[in] prefix Prefix found in the value string
@@ -170,6 +172,20 @@
  */
 typedef const struct lys_module *(*ly_clb_resolve_prefix)(struct ly_ctx *ctx, const char *prefix, size_t prefix_len, void *private);
 
+/**
+ * @brief Callback provided by the data/schema printers to type plugins to resolve (format-specific) mapping between YANG module of a data object
+ * to prefixes used in the value strings.
+ *
+ * Reverse function to ly_clb_resolve_prefix.
+ *
+ * XML uses XML namespaces, JSON uses schema names as prefixes, YIN/YANG uses prefixes of the imports.
+ *
+ * @param[in] mod YANG module of the object.
+ * @param[in] private Internal data needed by the callback.
+ * @return String representing prefix for the object of the given YANG module @p mod.
+ */
+typedef const char *(*ly_clb_get_prefix)(const struct lys_module *mod, void *private);
+
 /** @} */
 
 #ifdef __cplusplus
diff --git a/src/tree_data_hash.c b/src/tree_data_hash.c
index 2d6913a..7627ce5 100644
--- a/src/tree_data_hash.c
+++ b/src/tree_data_hash.c
@@ -57,7 +57,7 @@
             for (iter = list->child; keys_count; --keys_count, iter = iter->next) {
                 int dynamic = 0;
                 struct lysc_type *type = ((struct lysc_node_leaf*)iter->schema)->type;
-                const char *value = type->plugin->print(&((struct lyd_node_term*)iter)->value, LYD_JSON, 0, &dynamic);
+                const char *value = type->plugin->print(&((struct lyd_node_term*)iter)->value, LYD_JSON, json_print_get_prefix, NULL, &dynamic);
                 node->hash = dict_hash_multi(node->hash, value, strlen(value));
                 if (dynamic) {
                     free((char*)value);
@@ -70,7 +70,8 @@
     } else if (node->schema->nodetype == LYS_LEAFLIST) {
         struct lyd_node_term *llist = (struct lyd_node_term*)node;
         int dynamic = 0;
-        const char *value = ((struct lysc_node_leaflist*)node->schema)->type->plugin->print(&llist->value, LYD_JSON, 0, &dynamic);
+        const char *value = ((struct lysc_node_leaflist*)node->schema)->type->plugin->print(&llist->value, LYD_JSON,
+                                                                                            json_print_get_prefix, NULL, &dynamic);
         node->hash = dict_hash_multi(node->hash, value, strlen(value));
         if (dynamic) {
             free((char*)value);
diff --git a/src/tree_schema.h b/src/tree_schema.h
index a8b2d5f..d032021 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -980,7 +980,7 @@
 
 struct lysc_type {
     struct lysc_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-    const char *dflt;                /**< type's default value if any */
+    struct lyd_value *dflt;          /**< type's default value if any */
     struct lysc_type_plugin *plugin; /**< type's plugin with built-in as well as user functions to canonize or validate the value of the type */
     LY_DATA_TYPE basetype;           /**< Base type of the type */
     uint32_t refcount;               /**< reference counter for type sharing */
@@ -988,7 +988,7 @@
 
 struct lysc_type_num {
     struct lysc_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-    const char *dflt;                /**< type's default value if any */
+    struct lyd_value *dflt;          /**< type's default value if any */
     struct lysc_type_plugin *plugin; /**< type's plugin with built-in as well as user functions to canonize or validate the value of the type */
     LY_DATA_TYPE basetype;           /**< Base type of the type */
     uint32_t refcount;               /**< reference counter for type sharing */
@@ -997,7 +997,7 @@
 
 struct lysc_type_dec {
     struct lysc_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-    const char *dflt;                /**< type's default value if any */
+    struct lyd_value *dflt;          /**< type's default value if any */
     struct lysc_type_plugin *plugin; /**< type's plugin with built-in as well as user functions to canonize or validate the value of the type */
     LY_DATA_TYPE basetype;           /**< Base type of the type */
     uint32_t refcount;               /**< reference counter for type sharing */
@@ -1007,7 +1007,7 @@
 
 struct lysc_type_str {
     struct lysc_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
-    const char *dflt;                /**< type's default value if any */
+    struct lyd_value *dflt;          /**< type's default value if any */
     struct lysc_type_plugin *plugin; /**< type's plugin with built-in as well as user functions to canonize or validate the value of the type */
     LY_DATA_TYPE basetype;           /**< Base type of the type */
     uint32_t refcount;               /**< reference counter for type sharing */
@@ -1256,7 +1256,7 @@
     struct lysc_type *type;          /**< type of the leaf node (mandatory) */
 
     const char *units;               /**< units of the leaf's type */
-    const char *dflt;                /**< default value */
+    struct lyd_value *dflt;          /**< default value */
 };
 
 struct lysc_node_leaflist {
@@ -1281,7 +1281,7 @@
     struct lysc_type *type;          /**< type of the leaf node (mandatory) */
 
     const char *units;               /**< units of the leaf's type */
-    const char **dflts;              /**< list of default values ([sized array](@ref sizedarrays)) */
+    struct lyd_value **dflts;        /**< list of default values ([sized array](@ref sizedarrays)) */
     uint32_t min;                    /**< min-elements constraint */
     uint32_t max;                    /**< max-elements constraint */
 
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 8204bf4..d81ac32 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -404,7 +404,7 @@
     LY_CHECK_ERR_RET(!edef, LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
                                    "Extension definition of extension instance \"%s\" not found.", ext_p->name),
                      LY_EVALID);
-    /* TODO plugins */
+    /* TODO extension plugins */
 
     return LY_SUCCESS;
 }
@@ -2939,6 +2939,7 @@
     struct lysc_type *base = NULL, *prev_type;
     struct ly_set tpdf_chain = {0};
     const char *dflt = NULL;
+    struct lys_module *dflt_mod = NULL;
 
     (*type) = NULL;
 
@@ -2965,6 +2966,7 @@
         if (!dflt) {
             /* inherit default */
             dflt = tctx->tpdf->dflt;
+            dflt_mod = tctx->mod->mod;
         }
         if (dummyloops && (!units || *units) && dflt) {
             basetype = ((struct type_context*)tpdf_chain.objs[tpdf_chain.count - 1])->tpdf->type.compiled->basetype;
@@ -3138,8 +3140,20 @@
         (*type) = base;
         ++(*type)->refcount;
     }
-    if (!(*type)->dflt) {
-        DUP_STRING(ctx->ctx, dflt, (*type)->dflt);
+    if (dflt && !(*type)->dflt) {
+        struct ly_err_item *err = NULL;
+        (*type)->dflt = calloc(1, sizeof *(*type)->dflt);
+        (*type)->dflt->realtype = (*type);
+        ret = (*type)->plugin->store(ctx->ctx, (*type), dflt, strlen(dflt),
+                                     LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                     lys_resolve_prefix, (void*)dflt_mod, LYD_XML, NULL, NULL, (*type)->dflt, NULL, &err);
+        if (err) {
+            ly_err_print(err);
+            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                   "Invalid type's default value \"%s\" which does not fit the type (%s).", dflt, err->msg);
+            ly_err_free(err);
+        }
+        LY_CHECK_GOTO(ret, cleanup);
     }
 
     COMPILE_ARRAY_GOTO(ctx, type_p->exts, (*type)->exts, u, lys_compile_ext, ret, cleanup);
@@ -3431,7 +3445,7 @@
 static LY_ERR
 lys_compile_node_type(struct lysc_ctx *ctx, struct lysp_node *context_node, struct lysp_type *type_p, struct lysc_node_leaf *leaf)
 {
-    unsigned int u, v;
+    unsigned int u;
     struct lysc_node_leaflist *llist = (struct lysc_node_leaflist*)leaf;
 
     LY_CHECK_RET(lys_compile_type(ctx, context_node, leaf->flags, ctx->mod_def->parsed, leaf->name, type_p, &leaf->type,
@@ -3439,12 +3453,18 @@
     if (leaf->nodetype == LYS_LEAFLIST) {
         if (llist->type->dflt && !llist->dflts && !llist->min) {
             LY_ARRAY_CREATE_RET(ctx->ctx, llist->dflts, 1, LY_EMEM);
-            DUP_STRING(ctx->ctx, llist->type->dflt, llist->dflts[0]);
+            llist->dflts[0] = calloc(1, sizeof *llist->dflts[0]);
+            llist->dflts[0]->realtype = llist->type->dflt->realtype;
+            llist->dflts[0]->realtype->plugin->duplicate(ctx->ctx, llist->type->dflt, llist->dflts[0]);
+            llist->dflts[0]->realtype->refcount++;
             LY_ARRAY_INCREMENT(llist->dflts);
         }
     } else {
         if (leaf->type->dflt && !leaf->dflt && !(leaf->flags & LYS_MAND_TRUE)) {
-            DUP_STRING(ctx->ctx, leaf->type->dflt, leaf->dflt);
+            leaf->dflt = calloc(1, sizeof *leaf->dflt);
+            leaf->dflt->realtype = leaf->type->dflt->realtype;
+            leaf->dflt->realtype->plugin->duplicate(ctx->ctx, leaf->type->dflt, leaf->dflt);
+            leaf->dflt->realtype->refcount++;
         }
     }
     if (leaf->type->basetype == LY_TYPE_LEAFREF) {
@@ -3458,11 +3478,6 @@
             }
         }
     } else if (leaf->type->basetype == LY_TYPE_EMPTY) {
-        if (leaf->flags & LYS_SET_DFLT) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "%s of type \"empty\" must not have a default value (%s).",
-                   leaf->nodetype == LYS_LEAFLIST ? "Leaf-list" : "Leaf", leaf->nodetype == LYS_LEAFLIST ? llist->dflts[0] : leaf->dflt);
-            return LY_EVALID;
-        }
         if (leaf->nodetype == LYS_LEAFLIST && ctx->mod_def->version < LYS_VERSION_1_1) {
             LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
                    "Leaf-list of type \"empty\" is allowed only in YANG 1.1 modules.");
@@ -3470,21 +3485,6 @@
         }
     }
 
-    if (leaf->nodetype == LYS_LEAFLIST && (llist->flags & LYS_CONFIG_W) && llist->dflts && LY_ARRAY_SIZE(llist->dflts)) {
-        /* configuration data values must be unique - so check the default values */
-        LY_ARRAY_FOR(llist->dflts, u) {
-            for (v = u + 1; v < LY_ARRAY_SIZE(llist->dflts); ++v) {
-                if (!strcmp(llist->dflts[u], llist->dflts[v])) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                           "Configuration leaf-list has multiple defaults of the same value \"%s\".", llist->dflts[v]);
-                    return LY_EVALID;
-                }
-            }
-        }
-    }
-
-    /* TODO validate default value according to the type, possibly postpone the check when the leafref target is known */
-
     return LY_SUCCESS;
 }
 
@@ -3509,12 +3509,29 @@
         leaf->units = lydict_insert(ctx->ctx, leaf_p->units, 0);
         leaf->flags |= LYS_SET_UNITS;
     }
+
+    /* the dflt member is just filled to avoid getting the default value from the type */
+    leaf->dflt = (void*)leaf_p->dflt;
+    ret = lys_compile_node_type(ctx, node_p, &leaf_p->type, leaf);
+
     if (leaf_p->dflt) {
-        leaf->dflt = lydict_insert(ctx->ctx, leaf_p->dflt, 0);
+        struct ly_err_item *err = NULL;
+        leaf->dflt = calloc(1, sizeof *leaf->dflt);
+        leaf->dflt->realtype = leaf->type;
+        ret = leaf->type->plugin->store(ctx->ctx, leaf->type, leaf_p->dflt, strlen(leaf_p->dflt),
+                                        LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                        lys_resolve_prefix, (void*)ctx->mod_def, LYD_XML, NULL, NULL, leaf->dflt, NULL, &err);
+        leaf->dflt->realtype->refcount++;
+        if (err) {
+            ly_err_print(err);
+            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                   "Invalid leaf's default value \"%s\" which does not fit the type (%s).", leaf_p->dflt, err->msg);
+            ly_err_free(err);
+        }
+        LY_CHECK_GOTO(ret, done);
         leaf->flags |= LYS_SET_DFLT;
     }
 
-    ret = lys_compile_node_type(ctx, node_p, &leaf_p->type, leaf);
 
 done:
     return ret;
@@ -3533,7 +3550,7 @@
 {
     struct lysp_node_leaflist *llist_p = (struct lysp_node_leaflist*)node_p;
     struct lysc_node_leaflist *llist = (struct lysc_node_leaflist*)node;
-    unsigned int u;
+    unsigned int u, v;
     LY_ERR ret = LY_SUCCESS;
 
     COMPILE_ARRAY_GOTO(ctx, llist_p->musts, llist->musts, u, lys_compile_must, ret, done);
@@ -3542,14 +3559,50 @@
         llist->flags |= LYS_SET_UNITS;
     }
 
+    /* the dflts member is just filled to avoid getting the default value from the type */
+    llist->dflts = (void*)llist_p->dflts;
+    ret = lys_compile_node_type(ctx, node_p, &llist_p->type, (struct lysc_node_leaf*)llist);
     if (llist_p->dflts) {
+        llist->dflts = NULL; /* reset the temporary llist_p->dflts */
         LY_ARRAY_CREATE_GOTO(ctx->ctx, llist->dflts, LY_ARRAY_SIZE(llist_p->dflts), ret, done);
         LY_ARRAY_FOR(llist_p->dflts, u) {
-            DUP_STRING(ctx->ctx, llist_p->dflts[u], llist->dflts[u]);
+            struct ly_err_item *err = NULL;
             LY_ARRAY_INCREMENT(llist->dflts);
+            llist->dflts[u] = calloc(1, sizeof *llist->dflts[u]);
+            llist->dflts[u]->realtype = llist->type;
+            ret = llist->type->plugin->store(ctx->ctx, llist->type, llist_p->dflts[u], strlen(llist_p->dflts[u]),
+                                             LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                             lys_resolve_prefix, (void*)ctx->mod_def, LYD_XML, NULL, NULL, llist->dflts[u], NULL, &err);
+            llist->dflts[u]->realtype->refcount++;
+            if (err) {
+                ly_err_print(err);
+                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                       "Invalid leaf-lists's default value \"%s\" which does not fit the type (%s).", llist_p->dflts[u], err->msg);
+                ly_err_free(err);
+            }
+            LY_CHECK_GOTO(ret, done);
         }
         llist->flags |= LYS_SET_DFLT;
     }
+    if ((llist->flags & LYS_CONFIG_W) && llist->dflts && LY_ARRAY_SIZE(llist->dflts)) {
+        /* configuration data values must be unique - so check the default values */
+        LY_ARRAY_FOR(llist->dflts, u) {
+            for (v = u + 1; v < LY_ARRAY_SIZE(llist->dflts); ++v) {
+                if (!llist->type->plugin->compare(llist->dflts[u], llist->dflts[v])) {
+                    int dynamic = 0;
+                    const char *val = llist->type->plugin->print(llist->dflts[v], LYD_XML, json_print_get_prefix, NULL, &dynamic);
+                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                           "Configuration leaf-list has multiple defaults of the same value \"%s\".", val);
+                    if (dynamic) {
+                        free((char*)val);
+                    }
+                    return LY_EVALID;
+                }
+            }
+        }
+    }
+
+    /* TODO validate default value according to the type, possibly postpone the check when the leafref target is known */
 
     llist->min = llist_p->min;
     if (llist->min) {
@@ -3557,8 +3610,6 @@
     }
     llist->max = llist_p->max ? llist_p->max : (uint32_t)-1;
 
-    ret = lys_compile_node_type(ctx, node_p, &llist_p->type, (struct lysc_node_leaf*)llist);
-
 done:
     return ret;
 }
@@ -3743,7 +3794,9 @@
 
         /* ignore default values of the key */
         if ((*key)->dflt) {
-            lydict_remove(ctx->ctx, (*key)->dflt);
+            (*key)->dflt->realtype->plugin->free(ctx->ctx, (*key)->dflt);
+            lysc_type_free(ctx->ctx, (*key)->dflt->realtype);
+            free((*key)->dflt);
             (*key)->dflt = NULL;
         }
         /* mark leaf as key */
@@ -4428,10 +4481,13 @@
                            "Invalid refine of mandatory - leaf already has \"default\" statement.");
                     return LY_EVALID;
                 }
-            } else {
+            } else if (((struct lysc_node_leaf*)node)->dflt) {
                 /* remove the default value taken from the leaf's type */
-                FREE_STRING(ctx->ctx, ((struct lysc_node_leaf*)node)->dflt);
-                ((struct lysc_node_leaf*)node)->dflt = NULL;
+                struct lysc_node_leaf *leaf = (struct lysc_node_leaf*)node;
+                leaf->dflt->realtype->plugin->free(ctx->ctx, leaf->dflt);
+                lysc_type_free(ctx->ctx, leaf->dflt->realtype);
+                free(leaf->dflt);
+                leaf->dflt = NULL;
             }
         } else if ((node->nodetype & LYS_CHOICE) && ((struct lysc_node_choice*)node)->dflt) {
             if (refine_flag) {
@@ -4453,9 +4509,13 @@
         node->flags &= ~LYS_MAND_TRUE;
         node->flags |= LYS_MAND_FALSE;
         lys_compile_mandatory_parents(node->parent, 0);
-        if ((node->nodetype & LYS_LEAF) && !((struct lysc_node_leaf*)node)->dflt) {
+        if ((node->nodetype & LYS_LEAF) && !((struct lysc_node_leaf*)node)->dflt && ((struct lysc_node_leaf*)node)->type->dflt) {
             /* get the type's default value if any */
-            DUP_STRING(ctx->ctx, ((struct lysc_node_leaf*)node)->type->dflt, ((struct lysc_node_leaf*)node)->dflt);
+            struct lysc_node_leaf *leaf = (struct lysc_node_leaf*)node;
+            leaf->dflt = calloc(1, sizeof *leaf->dflt);
+            leaf->dflt->realtype = leaf->type->dflt->realtype;
+            leaf->dflt->realtype->plugin->duplicate(ctx->ctx, leaf->type->dflt, leaf->dflt);
+            leaf->dflt->realtype->refcount++;
         }
     }
     return LY_SUCCESS;
@@ -4492,7 +4552,7 @@
     size_t prefix_len, name_len;
     struct lys_module *mod, *mod_old;
     struct lysp_refine *rfn;
-    LY_ERR ret = LY_EVALID;
+    LY_ERR ret = LY_EVALID, rc;
     uint32_t min, max;
     uint16_t flags;
     struct ly_set refined = {0};
@@ -4684,27 +4744,68 @@
                 goto cleanup;
             }
             if (node->nodetype == LYS_LEAF) {
-                FREE_STRING(ctx->ctx, ((struct lysc_node_leaf*)node)->dflt);
-                DUP_STRING(ctx->ctx, rfn->dflts[0], ((struct lysc_node_leaf*)node)->dflt);
-                node->flags |= LYS_SET_DFLT;
-                /* TODO check the default value according to type */
+                struct ly_err_item *err = NULL;
+                struct lysc_node_leaf *leaf = (struct lysc_node_leaf*)node;
+                if (leaf->dflt) {
+                    /* remove the previous default value */
+                    leaf->dflt->realtype->plugin->free(ctx->ctx, leaf->dflt);
+                    lysc_type_free(ctx->ctx, leaf->dflt->realtype);
+                } else {
+                    /* prepare a new one */
+                    leaf->dflt = calloc(1, sizeof *leaf->dflt);
+                    leaf->dflt->realtype = leaf->type;
+                }
+                /* parse the new one */
+                rc = leaf->type->plugin->store(ctx->ctx, leaf->type, rfn->dflts[0], strlen(rfn->dflts[0]),
+                                                LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                                lys_resolve_prefix, (void*)ctx->mod_def, LYD_XML, NULL, NULL, leaf->dflt, NULL, &err);
+                leaf->dflt->realtype->refcount++;
+                if (err) {
+                    ly_err_print(err);
+                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                           "Invalid refine of default - value \"%s\" does not fit the type (%s).", rfn->dflts[0], err->msg);
+                    ly_err_free(err);
+                }
+                LY_CHECK_GOTO(rc, cleanup);
+                leaf->flags |= LYS_SET_DFLT;
             } else if (node->nodetype == LYS_LEAFLIST) {
+                struct lysc_node_leaflist *llist = (struct lysc_node_leaflist*)node;
+
                 if (ctx->mod->version < 2) {
                     LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
                            "Invalid refine of default in leaf-list - the default statement is allowed only in YANG 1.1 modules.");
                     goto cleanup;
                 }
-                LY_ARRAY_FOR(((struct lysc_node_leaflist*)node)->dflts, u) {
-                    lydict_remove(ctx->ctx, ((struct lysc_node_leaflist*)node)->dflts[u]);
+
+                /* remove previous set of default values */
+                LY_ARRAY_FOR(llist->dflts, u) {
+                    llist->dflts[u]->realtype->plugin->free(ctx->ctx, llist->dflts[u]);
+                    lysc_type_free(ctx->ctx, llist->dflts[u]->realtype);
+                    free(llist->dflts[u]);
                 }
-                LY_ARRAY_FREE(((struct lysc_node_leaflist*)node)->dflts);
-                ((struct lysc_node_leaflist*)node)->dflts = NULL;
-                LY_ARRAY_CREATE_GOTO(ctx->ctx, ((struct lysc_node_leaflist*)node)->dflts, LY_ARRAY_SIZE(rfn->dflts), ret, cleanup);
+                LY_ARRAY_FREE(llist->dflts);
+                llist->dflts = NULL;
+
+                /* create the new set of the default values */
+                LY_ARRAY_CREATE_GOTO(ctx->ctx, llist->dflts, LY_ARRAY_SIZE(rfn->dflts), ret, cleanup);
                 LY_ARRAY_FOR(rfn->dflts, u) {
-                    LY_ARRAY_INCREMENT(((struct lysc_node_leaflist*)node)->dflts);
-                    DUP_STRING(ctx->ctx, rfn->dflts[u], ((struct lysc_node_leaflist*)node)->dflts[u]);
+                    struct ly_err_item *err = NULL;
+                    LY_ARRAY_INCREMENT(llist->dflts);
+                    llist->dflts[u] = calloc(1, sizeof *llist->dflts[u]);
+                    llist->dflts[u]->realtype = llist->type;
+                    ret = llist->type->plugin->store(ctx->ctx, llist->type, rfn->dflts[u], strlen(rfn->dflts[u]),
+                                                     LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                                     lys_resolve_prefix, (void*)ctx->mod_def, LYD_XML, NULL, NULL, llist->dflts[u], NULL, &err);
+                    llist->dflts[u]->realtype->refcount++;
+                    if (err) {
+                        ly_err_print(err);
+                        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                               "Invalid refine of default in leaf-lists -  value \"%s\" does not fit the type (%s).", rfn->dflts[u], err->msg);
+                        ly_err_free(err);
+                    }
+                    LY_CHECK_GOTO(ret, cleanup);
                 }
-                /* TODO check the default values according to type */
+                llist->flags |= LYS_SET_DFLT;
             } else if (node->nodetype == LYS_CHOICE) {
                 if (((struct lysc_node_choice*)node)->dflt) {
                     /* unset LYS_SET_DFLT from the current default case */
@@ -5298,7 +5399,7 @@
 LY_ERR
 lys_compile_deviations(struct lysc_ctx *ctx, struct lysp_module *mod_p)
 {
-    LY_ERR ret = LY_EVALID;
+    LY_ERR ret = LY_EVALID, rc;
     struct ly_set devs_p = {0};
     struct ly_set targets = {0};
     struct lysc_node *target; /* target target of the deviation */
@@ -5318,9 +5419,9 @@
         uint16_t flags;                /* target's flags from lys_resolve_schema_nodeid() */
         uint8_t not_supported;         /* flag if deviates contains not-supported deviate */
     } **devs = NULL;
-    int i;
+    int i, changed_type;
     size_t prefix_len, name_len;
-    const char *prefix, *name, *nodeid;
+    const char *prefix, *name, *nodeid, *dflt;
     struct lys_module *mod;
     uint32_t min, max;
     uint16_t flags;
@@ -5398,11 +5499,23 @@
         goto cleanup; \
     }
 
+
 #define DEV_CHECK_NONPRESENCE(TYPE, COND, MEMBER, PROPERTY, VALUEMEMBER) \
+        if (((TYPE)devs[u]->target)->MEMBER && (COND)) { \
+            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, \
+                   "Invalid deviation adding \"%s\" property which already exists (with value \"%s\").", \
+                   PROPERTY, ((TYPE)devs[u]->target)->VALUEMEMBER); \
+            goto cleanup; \
+        }
+
+#define DEV_CHECK_NONPRESENCE_VALUE(TYPE, COND, MEMBER, PROPERTY, VALUEMEMBER) \
     if (((TYPE)devs[u]->target)->MEMBER && (COND)) { \
+        int dynamic_ = 0; const char *val_; \
+        val_ = ((TYPE)devs[u]->target)->VALUEMEMBER->realtype->plugin->print(((TYPE)devs[u]->target)->VALUEMEMBER, \
+                                                                             LYD_XML, lys_get_prefix, ctx->mod_def, &dynamic_); \
         LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, \
-               "Invalid deviation adding \"%s\" property which already exists (with value \"%s\").", \
-               PROPERTY, ((TYPE)devs[u]->target)->VALUEMEMBER); \
+               "Invalid deviation adding \"%s\" property which already exists (with value \"%s\").", PROPERTY, val_); \
+        if (dynamic_) {free((void*)val_);} \
         goto cleanup; \
     }
 
@@ -5427,17 +5540,6 @@
         goto cleanup; \
     }
 
-#define DEV_DEL_MEMBER(TYPE, MEMBER_TRG, MEMBER_DEV, DELFUNC, PROPERTY) \
-    DEV_CHECK_PRESENCE(TYPE, 0, MEMBER_TRG, "deleting", PROPERTY, d_del->MEMBER_DEV); \
-    if (strcmp(((TYPE)devs[u]->target)->MEMBER_TRG, d_del->MEMBER_DEV)) { \
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, \
-               "Invalid deviation deleting \"%s\" property \"%s\" which does not match the target's property value \"%s\".", \
-               PROPERTY, d_del->MEMBER_DEV, ((TYPE)devs[u]->target)->MEMBER_TRG); \
-        goto cleanup; \
-    } \
-    DELFUNC(ctx->ctx, ((TYPE)devs[u]->target)->MEMBER_TRG); \
-    ((TYPE)devs[u]->target)->MEMBER_TRG = NULL;
-
 #define DEV_DEL_ARRAY(TYPE, ARRAY_TRG, ARRAY_DEV, VALMEMBER, VALMEMBER_CMP, DELFUNC_DEREF, DELFUNC, PROPERTY) \
     DEV_CHECK_PRESENCE(TYPE, 0, ARRAY_TRG, "deleting", PROPERTY, d_del->ARRAY_DEV[0]VALMEMBER); \
     LY_ARRAY_FOR(d_del->ARRAY_DEV, x) { \
@@ -5463,6 +5565,13 @@
 
     /* apply deviations */
     for (u = 0; u < devs_p.count && devs[u]; ++u) {
+        struct lysc_node_leaf *leaf = (struct lysc_node_leaf*)devs[u]->target;
+        struct lysc_node_leaflist *llist = (struct lysc_node_leaflist*)devs[u]->target;
+        struct ly_err_item *err = NULL;
+
+        dflt = NULL;
+        changed_type = 0;
+
         lysc_update_path(ctx, NULL, devs[u]->nodeid);
 
         if (devs[u]->flags & LYSC_OPT_INTERNAL) {
@@ -5588,32 +5697,51 @@
                     switch (devs[u]->target->nodetype) {
                     case LYS_LEAF:
                         DEV_CHECK_CARDINALITY(d_add->dflts, 1, "default");
-                        DEV_CHECK_NONPRESENCE(struct lysc_node_leaf*, (devs[u]->target->flags & LYS_SET_DFLT), dflt, "default", dflt);
-                        if (((struct lysc_node_leaf*)devs[u]->target)->dflt) {
+                        DEV_CHECK_NONPRESENCE_VALUE(struct lysc_node_leaf*, (devs[u]->target->flags & LYS_SET_DFLT), dflt, "default", dflt);
+                        if (leaf->dflt) {
                             /* first, remove the default value taken from the type */
-                            lydict_remove(ctx->ctx, ((struct lysc_node_leaf*)devs[u]->target)->dflt);
-                            ((struct lysc_node_leaf*)devs[u]->target)->dflt = NULL;
+                            leaf->dflt->realtype->plugin->free(ctx->ctx, leaf->dflt);
+                            lysc_type_free(ctx->ctx, leaf->dflt->realtype);
+                        } else {
+                            /* prepare new default value storage */
+                            leaf->dflt = calloc(1, sizeof *leaf->dflt);
                         }
-                        DUP_STRING(ctx->ctx, d_add->dflts[0], ((struct lysc_node_leaf*)devs[u]->target)->dflt);
+                        dflt = d_add->dflts[0];
+                        /* parsing is done at the end after possible replace of the leaf's type */
+
                         /* mark the new default values as leaf's own */
                         devs[u]->target->flags |= LYS_SET_DFLT;
                         break;
                     case LYS_LEAFLIST:
-                        if (((struct lysc_node_leaflist*)devs[u]->target)->dflts && !(devs[u]->target->flags & LYS_SET_DFLT)) {
+                        if (llist->dflts && !(devs[u]->target->flags & LYS_SET_DFLT)) {
                             /* first, remove the default value taken from the type */
-                            LY_ARRAY_FOR(((struct lysc_node_leaflist*)devs[u]->target)->dflts, x) {
-                                lydict_remove(ctx->ctx, ((struct lysc_node_leaflist*)devs[u]->target)->dflts[x]);
+                            LY_ARRAY_FOR(llist->dflts, x) {
+                                llist->dflts[x]->realtype->plugin->free(ctx->ctx, llist->dflts[x]);
+                                lysc_type_free(ctx->ctx, llist->dflts[x]->realtype);
+                                free(llist->dflts[x]);
                             }
-                            LY_ARRAY_FREE(((struct lysc_node_leaflist*)devs[u]->target)->dflts);
-                            ((struct lysc_node_leaflist*)devs[u]->target)->dflts = NULL;
+                            LY_ARRAY_FREE(llist->dflts);
+                            llist->dflts = NULL;
                         }
                         /* add new default value(s) */
-                        LY_ARRAY_CREATE_GOTO(ctx->ctx, ((struct lysc_node_leaflist*)devs[u]->target)->dflts,
-                                             LY_ARRAY_SIZE(d_add->dflts), ret, cleanup);
-                        for (x = y = LY_ARRAY_SIZE(((struct lysc_node_leaflist*)devs[u]->target)->dflts);
+                        LY_ARRAY_CREATE_GOTO(ctx->ctx, llist->dflts, LY_ARRAY_SIZE(d_add->dflts), ret, cleanup);
+                        for (x = y = LY_ARRAY_SIZE(llist->dflts);
                                 x < LY_ARRAY_SIZE(d_add->dflts) + y; ++x) {
-                            DUP_STRING(ctx->ctx, d_add->dflts[x - y], ((struct lysc_node_leaflist*)devs[u]->target)->dflts[x]);
-                            LY_ARRAY_INCREMENT(((struct lysc_node_leaflist*)devs[u]->target)->dflts);
+                            LY_ARRAY_INCREMENT(llist->dflts);
+                            llist->dflts[x] = calloc(1, sizeof *llist->dflts[x]);
+                            llist->dflts[x]->realtype = llist->type;
+                            rc = llist->type->plugin->store(ctx->ctx, llist->type, d_add->dflts[x - y], strlen(d_add->dflts[x - y]),
+                                                             LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                                             lys_resolve_prefix, (void*)ctx->mod_def, LYD_XML, NULL, NULL, llist->dflts[x], NULL, &err);
+                            llist->dflts[x]->realtype->refcount++;
+                            if (err) {
+                                ly_err_print(err);
+                                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                                       "Invalid deviation adding \"default\" property \"%s\" which does not fit the type (%s).",
+                                       d_add->dflts[x - y], err->msg);
+                                ly_err_free(err);
+                            }
+                            LY_CHECK_GOTO(rc, cleanup);
                         }
                         /* mark the new default values as leaf-list's own */
                         devs[u]->target->flags |= LYS_SET_DFLT;
@@ -5709,7 +5837,15 @@
                 /* [units-stmt] */
                 if (d_del->units) {
                     DEV_CHECK_NODETYPE(LYS_LEAF | LYS_LEAFLIST, "delete", "units");
-                    DEV_DEL_MEMBER(struct lysc_node_leaf*, units, units, lydict_remove, "units");
+                    DEV_CHECK_PRESENCE(struct lysc_node_leaf*, 0, units, "deleting", "units", d_del->units);
+                    if (strcmp(((struct lysc_node_leaf*)devs[u]->target)->units, d_del->units)) {
+                        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                               "Invalid deviation deleting \"units\" property \"%s\" which does not match the target's property value \"%s\".",
+                               d_del->units, ((struct lysc_node_leaf*)devs[u]->target)->units);
+                        goto cleanup;
+                    }
+                    lydict_remove(ctx->ctx, ((struct lysc_node_leaf*)devs[u]->target)->units);
+                    ((struct lysc_node_leaf*)devs[u]->target)->units = NULL;
                 }
 
                 /* *must-stmt */
@@ -5795,13 +5931,61 @@
                         DEV_CHECK_PRESENCE(struct lysc_node_leaf*, !(devs[u]->target->flags & LYS_SET_DFLT),
                                            dflt, "deleting", "default", d_del->dflts[0]);
 
-                        DEV_DEL_MEMBER(struct lysc_node_leaf*, dflt, dflts[0], lydict_remove, "default");
+                        /* check that the values matches */
+                        dflt = leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, lys_get_prefix, ctx->mod_def, &i);
+                        if (strcmp(dflt, d_del->dflts[0])) {
+                            if (i) {
+                                free((char*)dflt);
+                            }
+                            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                                   "Invalid deviation deleting \"default\" property \"%s\" which does not match the target's property value \"%s\".",
+                                   d_del->dflts[0], dflt);
+                            goto cleanup;
+                        }
+                        if (i) {
+                            free((char*)dflt);
+                        }
+                        dflt = NULL;
+
+                        /* remove the default specification */
+                        leaf->dflt->realtype->plugin->free(ctx->ctx, leaf->dflt);
+                        lysc_type_free(ctx->ctx, leaf->dflt->realtype);
+                        free(leaf->dflt);
+                        leaf->dflt = NULL;
                         devs[u]->target->flags &= ~LYS_SET_DFLT;
                         break;
                     case LYS_LEAFLIST:
-                        DEV_DEL_ARRAY(struct lysc_node_leaflist*, dflts, dflts, , , , lydict_remove, "default");
-                        if (!((struct lysc_node_leaflist*)devs[u]->target)->dflts) {
-                            devs[u]->target->flags &= ~LYS_SET_DFLT;
+                        DEV_CHECK_PRESENCE(struct lysc_node_leaflist*, 0, dflts, "deleting", "default", d_del->dflts[0]);
+                        LY_ARRAY_FOR(d_del->dflts, x) {
+                            LY_ARRAY_FOR(llist->dflts, y) {
+                                dflt = llist->type->plugin->print(llist->dflts[y], LYD_XML, lys_get_prefix, ctx->mod_def, &i);
+                                if (!strcmp(dflt, d_del->dflts[x])) {
+                                    if (i) {
+                                        free((char*)dflt);
+                                    }
+                                    dflt = NULL;
+                                    break;
+                                }
+                                if (i) {
+                                    free((char*)dflt);
+                                }
+                                dflt = NULL;
+                            }
+                            if (y == LY_ARRAY_SIZE(llist->dflts)) {
+                                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "Invalid deviation deleting \"default\" property \"%s\" "
+                                       "which does not match any of the target's property values.", d_del->dflts[x]);
+                                goto cleanup;
+                            }
+                            LY_ARRAY_DECREMENT(llist->dflts);
+                            llist->dflts[y]->realtype->plugin->free(ctx->ctx, llist->dflts[y]);
+                            lysc_type_free(ctx->ctx, llist->dflts[y]->realtype);
+                            free(llist->dflts[y]);
+                            memmove(&llist->dflts[y], &llist->dflts[y + 1], (LY_ARRAY_SIZE(llist->dflts) - y) * (sizeof *llist->dflts));
+                        }
+                        if (!LY_ARRAY_SIZE(llist->dflts)) {
+                            LY_ARRAY_FREE(llist->dflts);
+                            llist->dflts = NULL;
+                            llist->flags &= ~LYS_SET_DFLT;
                         }
                         break;
                     case LYS_CHOICE:
@@ -5853,7 +6037,30 @@
                     DEV_CHECK_NODETYPE(LYS_LEAF | LYS_LEAFLIST, "replace", "type");
                     /* type is mandatory, so checking for its presence is not necessary */
                     lysc_type_free(ctx->ctx, ((struct lysc_node_leaf*)devs[u]->target)->type);
+
+                    if (leaf->dflt && !(devs[u]->target->flags & LYS_SET_DFLT)) {
+                        /* the target has default from the previous type - remove it */
+                        if (devs[u]->target->nodetype == LYS_LEAF) {
+                            leaf->dflt->realtype->plugin->free(ctx->ctx, leaf->dflt);
+                            lysc_type_free(ctx->ctx, leaf->dflt->realtype);
+                            free(leaf->dflt);
+                            leaf->dflt = NULL;
+                        } else { /* LYS_LEAFLIST */
+                            LY_ARRAY_FOR(llist->dflts, x) {
+                                llist->dflts[x]->realtype->plugin->free(ctx->ctx, llist->dflts[x]);
+                                lysc_type_free(ctx->ctx, llist->dflts[x]->realtype);
+                                free(llist->dflts[x]);
+                            }
+                            LY_ARRAY_FREE(llist->dflts);
+                            llist->dflts = NULL;
+                        }
+                    }
+                    if (!leaf->dflt) {
+                        /* do not set changed_type after type compilation */
+                        changed_type = -1;
+                    }
                     LY_CHECK_GOTO(lys_compile_node_type(ctx, NULL, d_rpl->type, (struct lysc_node_leaf*)devs[u]->target), cleanup);
+                    changed_type++;
                 }
 
                 /* [units-stmt] */
@@ -5872,9 +6079,11 @@
                     case LYS_LEAF:
                         DEV_CHECK_PRESENCE(struct lysc_node_leaf*, !(devs[u]->target->flags & LYS_SET_DFLT),
                                            dflt, "replacing", "default", d_rpl->dflt);
-
-                        lydict_remove(ctx->ctx, ((struct lysc_node_leaf*)devs[u]->target)->dflt);
-                        DUP_STRING(ctx->ctx, d_rpl->dflt, ((struct lysc_node_leaf*)devs[u]->target)->dflt);
+                        /* first, remove the default value taken from the type */
+                        leaf->dflt->realtype->plugin->free(ctx->ctx, leaf->dflt);
+                        lysc_type_free(ctx->ctx, leaf->dflt->realtype);
+                        dflt = d_rpl->dflt;
+                        /* parsing is done at the end after possible replace of the leaf's type */
                         break;
                     case LYS_CHOICE:
                         DEV_CHECK_PRESENCE(struct lysc_node_choice*, 0, dflt, "replacing", "default", d_rpl->dflt);
@@ -5976,6 +6185,68 @@
             goto cleanup;
         }
 
+        if (dflt) {
+            /* parse added/changed default value after possible change of the type */
+            leaf->dflt->realtype = leaf->type;
+            rc = leaf->type->plugin->store(ctx->ctx, leaf->type, dflt, strlen(dflt),
+                                            LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                            lys_resolve_prefix, (void*)ctx->mod_def, LYD_XML, NULL, NULL, leaf->dflt, NULL, &err);
+            leaf->dflt->realtype->refcount++;
+            if (err) {
+                ly_err_print(err);
+                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                       "Invalid deviation setting \"default\" property \"%s\" which does not fit the type (%s).", dflt, err->msg);
+                ly_err_free(err);
+            }
+            LY_CHECK_GOTO(rc, cleanup);
+        } else if (changed_type && leaf->dflt) {
+            /* the leaf/leaf-list's type has changed, but there is still a default value for the previous type */
+            int dynamic;
+            if (devs[u]->target->nodetype == LYS_LEAF) {
+                dflt = leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, lys_get_prefix, ctx->mod, &dynamic);
+                leaf->dflt->realtype->plugin->free(ctx->ctx, leaf->dflt);
+                lysc_type_free(ctx->ctx, leaf->dflt->realtype);
+                leaf->dflt->realtype = leaf->type;
+                rc = leaf->type->plugin->store(ctx->ctx, leaf->type, dflt, strlen(dflt),
+                                               LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                               lys_resolve_prefix, (void*)ctx->mod, LYD_XML, NULL, NULL, leaf->dflt, NULL, &err);
+                leaf->dflt->realtype->refcount++;
+                if (err) {
+                    ly_err_print(err);
+                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                           "Invalid deviation replacing leaf's type - the leaf's default value \"%s\" does not match the type (%s).", dflt, err->msg);
+                    ly_err_free(err);
+                }
+                if (dynamic) {
+                    free((void*)dflt);
+                }
+                LY_CHECK_GOTO(rc, cleanup);
+                dflt = NULL;
+            } else { /* LYS_LEAFLIST */
+                LY_ARRAY_FOR(llist->dflts, x) {
+                    llist->dflts[x]->realtype->plugin->print(llist->dflts[x], LYD_XML, lys_get_prefix, ctx->mod, &dynamic);
+                    llist->dflts[x]->realtype->plugin->free(ctx->ctx, llist->dflts[x]);
+                    lysc_type_free(ctx->ctx, llist->dflts[x]->realtype);
+                    llist->dflts[x]->realtype = llist->type;
+                    rc = llist->type->plugin->store(ctx->ctx, llist->type, dflt, strlen(dflt),
+                                                    LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                                    lys_resolve_prefix, (void*)ctx->mod, LYD_XML, NULL, NULL, llist->dflts[x], NULL, &err);
+                    llist->dflts[x]->realtype->refcount++;
+                    if (err) {
+                        ly_err_print(err);
+                        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                               "Invalid deviation replacing leaf-list's type - the leaf-list's default value \"%s\" does not match the type (%s).",
+                               dflt, err->msg);
+                        ly_err_free(err);
+                    }
+                    if (dynamic) {
+                        free((void*)dflt);
+                    }
+                    LY_CHECK_GOTO(rc, cleanup);
+                }
+            }
+        }
+
         /* check mandatory - default compatibility */
         if ((devs[u]->target->nodetype & (LYS_LEAF | LYS_LEAFLIST))
                 && (devs[u]->target->flags & LYS_SET_DFLT)
@@ -5997,8 +6268,6 @@
             goto cleanup;
         }
 
-        /* TODO check default value(s) according to the type */
-
         lysc_update_path(ctx, NULL, NULL);
     }
 
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index e3fd817..f82f240 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -20,6 +20,7 @@
 #include "tree.h"
 #include "tree_schema.h"
 #include "tree_schema_internal.h"
+#include "plugins_types.h"
 #include "xpath.h"
 
 void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
@@ -623,7 +624,11 @@
         break;
     }
     FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
-    FREE_STRING(ctx, type->dflt);
+    if (type->dflt) {
+        type->plugin->free(ctx, type->dflt);
+        lysc_type_free(ctx, type->dflt->realtype);
+        free(type->dflt);
+    }
     free(type);
 }
 
@@ -689,7 +694,11 @@
         lysc_type_free(ctx, node->type);
     }
     FREE_STRING(ctx, node->units);
-    FREE_STRING(ctx, node->dflt);
+    if (node->dflt) {
+        node->dflt->realtype->plugin->free(ctx, node->dflt);
+        lysc_type_free(ctx, node->dflt->realtype);
+        free(node->dflt);
+    }
 }
 
 static void
@@ -703,7 +712,9 @@
     }
     FREE_STRING(ctx, node->units);
     LY_ARRAY_FOR(node->dflts, u) {
-        lydict_remove(ctx, node->dflts[u]);
+        node->dflts[u]->realtype->plugin->free(ctx, node->dflts[u]);
+        lysc_type_free(ctx, node->dflts[u]->realtype);
+        free(node->dflts[u]);
     }
     LY_ARRAY_FREE(node->dflts);
 }
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index ed76616..423e673 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -1628,3 +1628,39 @@
     return LY_ARRAY_SIZE(ext);
 }
 
+/**
+ * @brief Schema mapping of YANG modules to prefixes in values.
+ *
+ * Implementation of ly_clb_get_prefix. Inverse function to lys_resolve_prefix.
+ *
+ * In this case the @p mod is searched in the list of imports and the import's prefix
+ * (not the module's itself) prefix is returned.
+ */
+const char *
+lys_get_prefix(const struct lys_module *mod, void *private)
+{
+    struct lys_module *context_mod = (struct lys_module*)private;
+    unsigned int u;
+
+    LY_ARRAY_FOR(context_mod->compiled->imports, u) {
+        if (context_mod->compiled->imports[u].module == mod) {
+            /* match */
+            return mod->compiled->imports[u].prefix;
+        }
+    }
+
+    return NULL;
+}
+
+/**
+ * @brief Schema mapping of prefix in values to YANG modules (imports).
+ *
+ * Implementation of ly_clb_resolve_prefix. Inverse function to lys_get_prefix().
+ *
+ * In this case the @p prefix is searched in the list of imports' prefixes (not the prefixes of the imported modules themselves).
+ */
+const struct lys_module *
+lys_resolve_prefix(struct ly_ctx *UNUSED(ctx), const char *prefix, size_t prefix_len, void *private)
+{
+    return lys_module_find_prefix((const struct lys_module*)private, prefix, prefix_len);
+}
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index fbd0b6a..53653ba 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -142,6 +142,33 @@
 LY_ERR lysp_check_identifierchar(struct lys_parser_ctx *ctx, unsigned int c, int first, int *prefix);
 
 /**
+ * @brief Internal structure for lys_get_prefix().
+ */
+struct lys_get_prefix_data {
+    const struct lys_module *context_mod;
+    struct ly_set prefixes;
+};
+
+/**
+ * @brief Schema mapping of YANG modules to prefixes in values.
+ *
+ * Implementation of ly_clb_get_prefix. Inverse function to lys_resolve_prefix.
+ *
+ * In this case the @p mod is searched in the list of imports and the import's prefix
+ * (not the module's itself) prefix is returned.
+ */
+const char *lys_get_prefix(const struct lys_module *mod, void *private);
+
+/**
+ * @brief Schema mapping of prefix in values to YANG modules (imports).
+ *
+ * Implementation of ly_clb_resolve_prefix. Inverse function to lys_get_prefix().
+ *
+ * In this case the @p prefix is searched in the list of imports' prefixes (not the prefixes of the imported modules themselves).
+ */
+const struct lys_module *lys_resolve_prefix(struct ly_ctx *ctx, const char *prefix, size_t prefix_len, void *private);
+
+/**
  * @brief Check the currently present prefixes in the module for collision with the new one.
  *
  * @param[in] ctx Context for logging.
diff --git a/tests/features/test_types.c b/tests/features/test_types.c
index 08ad498..94f4832 100644
--- a/tests/features/test_types.c
+++ b/tests/features/test_types.c
@@ -671,19 +671,20 @@
     s->func = NULL;
 }
 
+static const char *
+test_get_prefix(const struct lys_module *mod, void *private)
+{
+    (void)mod;
+    return (const char *)private;
+}
+
 static void
-test_printed_value(const struct lyd_value *value, const char *expected_prefixes, const char *expected_value, LYD_FORMAT format)
+test_printed_value(const struct lyd_value *value, const char *expected_value, LYD_FORMAT format, const char *prefix)
 {
     const char *str;
     int dynamic;
 
-    assert_non_null(str = value->realtype->plugin->print(value, format, 1, &dynamic));
-    assert_string_equal(expected_prefixes, str);
-    if (dynamic) {
-        free((char*)str);
-    }
-
-    assert_non_null(str = value->realtype->plugin->print(value, format, 0, &dynamic));
+    assert_non_null(str = value->realtype->plugin->print(value, format, test_get_prefix, (void*)prefix, &dynamic));
     assert_string_equal(expected_value, str);
     if (dynamic) {
         free((char*)str);
@@ -709,7 +710,7 @@
     leaf = (struct lyd_node_term*)tree;
     assert_null(leaf->value.canonized);
     assert_string_equal("gigabit-ethernet", leaf->value.ident->name);
-    test_printed_value(&leaf->value, "xmlns:t=\"urn:tests:types\"", "t:gigabit-ethernet", LYD_XML);
+    test_printed_value(&leaf->value, "t:gigabit-ethernet", LYD_XML, "t");
 
     value.realtype = leaf->value.realtype;
     assert_int_equal(LY_SUCCESS, value.realtype->plugin->duplicate(s->ctx, &leaf->value, &value));
@@ -724,7 +725,7 @@
     assert_string_equal("ident", tree->schema->name);
     leaf = (struct lyd_node_term*)tree;
     assert_null(leaf->value.canonized);
-    test_printed_value(&leaf->value, "xmlns:d=\"urn:tests:defs\"", "d:fast-ethernet", LYD_XML);
+    test_printed_value(&leaf->value, "d:fast-ethernet", LYD_XML, "d");
     lyd_free_all(tree);
 
     /* invalid value */
@@ -842,8 +843,8 @@
     assert_string_equal("value", leaf->value.target[1].node->name);
     assert_null(leaf->value.target[1].predicates);
 
-    test_printed_value(&leaf->value, "xmlns:t=\"urn:tests:types\"", "/t:list_inst[t:id=\"/t:leaflisttarget[.='b']\"]/t:value", LYD_XML);
-    test_printed_value(&leaf->value, "", "/types:list_inst[id=\"/types:leaflisttarget[.='b']\"]/value", LYD_JSON);
+    test_printed_value(&leaf->value, "/t:list_inst[t:id=\"/t:leaflisttarget[.='b']\"]/t:value", LYD_XML, "t");
+    test_printed_value(&leaf->value, "/types:list_inst[id=\"/types:leaflisttarget[.='b']\"]/value", LYD_JSON, "types");
 
     value.realtype = leaf->value.realtype;
     assert_int_equal(LY_SUCCESS, value.realtype->plugin->duplicate(s->ctx, &leaf->value, &value));
@@ -940,11 +941,13 @@
 
     data =  "<cont xmlns=\"urn:tests:types\"/><t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaftarget</t:inst>";
     assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, 0));
-    logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaftarget\" value - required instance not found. /");
+    /* instance-identifier is here in JSON format because it is already in internal representation without original prefixes */
+    logbuf_assert("Invalid instance-identifier \"/types:cont/leaftarget\" value - required instance not found. /");
 
     data =  "<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaftarget</t:inst>";
     assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, 0));
-    logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaftarget\" value - required instance not found. /");
+    /* instance-identifier is here in JSON format because it is already in internal representation without original prefixes */
+    logbuf_assert("Invalid instance-identifier \"/types:cont/leaftarget\" value - required instance not found. /");
 
     data =  "<leaflisttarget xmlns=\"urn:tests:types\">x</leaflisttarget><t:inst xmlns:t=\"urn:tests:types\">/t:leaflisttarget[1</t:inst>";
     assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, 0));
@@ -969,7 +972,8 @@
     data =  "<cont xmlns=\"urn:tests:types\"><leaflisttarget>1</leaflisttarget><leaflisttarget>2</leaflisttarget></cont>"
             "<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[4]</t:inst>";
     assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, 0));
-    logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[4]\" value - required instance not found. /");
+    /* instance-identifier is here in JSON format because it is already in internal representation without original prefixes */
+    logbuf_assert("Invalid instance-identifier \"/types:cont/leaflisttarget[4]\" value - required instance not found. /");
 
     data =  "<t:inst-noreq xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[6]</t:inst-noreq>";
     assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, 0));
@@ -1000,7 +1004,8 @@
     data =  "<cont xmlns=\"urn:tests:types\"><leaflisttarget>1</leaflisttarget></cont>"
             "<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[.='2']</t:inst>";
     assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, 0));
-    logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[.='2']\" value - required instance not found. /");
+    /* instance-identifier is here in JSON format because it is already in internal representation without original prefixes */
+    logbuf_assert("Invalid instance-identifier \"/types:cont/leaflisttarget[.='2']\" value - required instance not found. /");
 
     data =  "<cont xmlns=\"urn:tests:types\"><leaflisttarget>1</leaflisttarget></cont>"
             "<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[.='x']</t:inst>";
@@ -1017,7 +1022,8 @@
     data =  "<cont xmlns=\"urn:tests:types\"><listtarget><id>1</id><value>x</value></listtarget></cont>"
             "<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:listtarget[t:id='2']</t:inst>";
     assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, 0));
-    logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:id='2']\" value - required instance not found. /");
+    /* instance-identifier is here in JSON format because it is already in internal representation without original prefixes */
+    logbuf_assert("Invalid instance-identifier \"/types:cont/listtarget[id='2']\" value - required instance not found. /");
 
     data = "<leaflisttarget xmlns=\"urn:tests:types\">a</leaflisttarget>"
            "<leaflisttarget xmlns=\"urn:tests:types\">b</leaflisttarget>"
@@ -1239,7 +1245,7 @@
     assert_int_equal(LY_TYPE_INT8, leaf->value.subvalue->value->realtype->basetype);
     assert_int_equal(12, leaf->value.subvalue->value->int8);
 
-    test_printed_value(&leaf->value, "", "12", LYD_XML);
+    test_printed_value(&leaf->value, "12", LYD_XML, NULL);
 
     value.realtype = leaf->value.realtype;
     assert_int_equal(LY_SUCCESS, value.realtype->plugin->duplicate(s->ctx, &leaf->value, &value));
@@ -1275,8 +1281,8 @@
     assert_int_equal(LY_TYPE_IDENT, leaf->value.subvalue->value->realtype->basetype);
     assert_null(leaf->value.subvalue->value->canonized);
 
-    test_printed_value(&leaf->value, "xmlns:x=\"urn:tests:defs\"", "x:fast-ethernet", LYD_XML);
-    test_printed_value(leaf->value.subvalue->value, "xmlns:d=\"urn:tests:defs\"", "d:fast-ethernet", LYD_XML);
+    test_printed_value(&leaf->value, "x:fast-ethernet", LYD_XML, "x");
+    test_printed_value(leaf->value.subvalue->value, "d:fast-ethernet", LYD_XML, "d");
 
     value.realtype = leaf->value.realtype;
     assert_int_equal(LY_SUCCESS, value.realtype->plugin->duplicate(s->ctx, &leaf->value, &value));
diff --git a/tests/src/test_parser_xml.c b/tests/src/test_parser_xml.c
index 9ade723..fa882c0 100644
--- a/tests/src/test_parser_xml.c
+++ b/tests/src/test_parser_xml.c
@@ -58,6 +58,8 @@
     const char *schema_a = "module a {namespace urn:tests:a;prefix a;yang-version 1.1;"
             "list l1 { key \"a b\"; leaf a {type string;} leaf b {type string;} leaf c {type string;}}"
             "leaf foo { type string;}"
+            "container c { leaf x {type string;}}"
+            "container cp {presence \"container switch\"; leaf y {type string;}}"
             "anydata any {config false;} }";
 
 #if ENABLE_LOGGER_CHECKING
@@ -164,12 +166,42 @@
     *state = NULL;
 }
 
+static void
+test_container(void **state)
+{
+    *state = test_container;
+
+    const char *data = "<c xmlns=\"urn:tests:a\"/>";
+    struct lyd_node *tree;
+    struct lyd_node_inner *cont;
+
+    assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, &tree));
+    assert_non_null(tree);
+    assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
+    assert_string_equal("c", tree->schema->name);
+    cont = (struct lyd_node_inner*)tree;
+    assert_true(cont->flags & LYD_DEFAULT);
+    lyd_free_all(tree);
+
+    data = "<cp xmlns=\"urn:tests:a\"/>";
+    assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, &tree));
+    assert_non_null(tree);
+    assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
+    assert_string_equal("cp", tree->schema->name);
+    cont = (struct lyd_node_inner*)tree;
+    assert_false(cont->flags & LYD_DEFAULT);
+    lyd_free_all(tree);
+
+    *state = NULL;
+}
+
 int main(void)
 {
     const struct CMUnitTest tests[] = {
         cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
         cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
         cmocka_unit_test_setup_teardown(test_list, setup, teardown),
+        cmocka_unit_test_setup_teardown(test_container, setup, teardown),
     };
 
     return cmocka_run_group_tests(tests, NULL, NULL);
diff --git a/tests/src/test_tree_schema_compile.c b/tests/src/test_tree_schema_compile.c
index e5e28ff..d56b274 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/src/test_tree_schema_compile.c
@@ -23,6 +23,7 @@
 #include "../../src/common.h"
 #include "../../src/tree_schema_internal.h"
 #include "../../src/xpath.h"
+#include "../../src/plugins_types.h"
 
 void lysc_feature_free(struct ly_ctx *ctx, struct lysc_feature *feat);
 
@@ -480,6 +481,8 @@
     struct lys_module *mod;
     struct lysc_type *type;
     struct lysc_node_leaflist *ll;
+    const char *dflt;
+    int dynamic;
 
     assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
 
@@ -519,16 +522,19 @@
     assert_non_null(mod->compiled);
     assert_non_null((ll = (struct lysc_node_leaflist*)mod->compiled->data));
     assert_non_null(ll->dflts);
-    assert_int_equal(3, ll->type->refcount);
+    assert_int_equal(6, ll->type->refcount); /* 3x type's reference, 3x default value's reference (typedef's default does not reference own type) */
     assert_int_equal(2, LY_ARRAY_SIZE(ll->dflts));
-    assert_string_equal("1", ll->dflts[0]);
-    assert_string_equal("1", ll->dflts[1]);
+    assert_string_equal("1", dflt = ll->dflts[0]->realtype->plugin->print(ll->dflts[0], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("1", dflt = ll->dflts[1]->realtype->plugin->print(ll->dflts[1], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
     assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM | LYS_SET_DFLT | LYS_SET_CONFIG, ll->flags);
     assert_non_null((ll = (struct lysc_node_leaflist*)mod->compiled->data->next));
     assert_non_null(ll->dflts);
-    assert_int_equal(3, ll->type->refcount);
+    assert_int_equal(6, ll->type->refcount); /* 3x type's reference, 3x default value's reference */
     assert_int_equal(1, LY_ARRAY_SIZE(ll->dflts));
-    assert_string_equal("10", ll->dflts[0]);
+    assert_string_equal("10", dflt = ll->dflts[0]->realtype->plugin->print(ll->dflts[0], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
     assert_int_equal(LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_USER, ll->flags);
 
     /* ordered-by is ignored for state data, RPC/action output parameters and notification content */
@@ -555,7 +561,7 @@
     logbuf_assert("Leaf-list of type \"empty\" is allowed only in YANG 1.1 modules. /aa:ll");
 
     assert_null(lys_parse_mem(ctx, "module bb {yang-version 1.1;namespace urn:bb;prefix bb;leaf-list ll {type empty; default x;}}", LYS_IN_YANG));
-    logbuf_assert("Leaf-list of type \"empty\" must not have a default value (x). /bb:ll");
+    logbuf_assert("Invalid leaf-lists's default value \"x\" which does not fit the type (Invalid empty value \"x\".). /bb:ll");
 
     assert_non_null(mod = lys_parse_mem(ctx, "module cc {yang-version 1.1;namespace urn:cc;prefix cc;"
                                         "leaf-list ll {config false;type string; default one;default two;default one;}}", LYS_IN_YANG));
@@ -2123,7 +2129,7 @@
     /* invalid */
     assert_null(lys_parse_mem(ctx, "module aa {namespace urn:aa;prefix aa;"
                                         "leaf l {type empty; default x;}}", LYS_IN_YANG));
-    logbuf_assert("Leaf of type \"empty\" must not have a default value (x). /aa:l");
+    logbuf_assert("Invalid leaf's default value \"x\" which does not fit the type (Invalid empty value \"x\".). /aa:l");
 
     assert_null(lys_parse_mem(ctx, "module bb {namespace urn:bb;prefix bb;typedef mytype {type empty; default x;}"
                                         "leaf l {type mytype;}}", LYS_IN_YANG));
@@ -2222,6 +2228,8 @@
     struct ly_ctx *ctx;
     struct lys_module *mod;
     struct lysc_type *type;
+    struct lysc_node_leaf *leaf;
+    int dynamic;
 
     assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
 
@@ -2243,44 +2251,54 @@
                                         "leaf l {type mybasetype;}}", LYS_IN_YANG));
     type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
     assert_non_null(type);
-    assert_int_equal(2, type->refcount);
+    assert_int_equal(3, type->refcount); /* 2x type reference, 1x default value's reference (typedf's default does not reference own type)*/
     assert_int_equal(LY_TYPE_STRING, type->basetype);
-    assert_string_equal("hello", ((struct lysc_node_leaf*)mod->compiled->data)->dflt);
-    assert_string_equal("xxx", ((struct lysc_node_leaf*)mod->compiled->data)->units);
+    leaf = (struct lysc_node_leaf*)mod->compiled->data;
+    assert_string_equal("hello", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("xxx", leaf->units);
 
     assert_non_null(mod = lys_parse_mem(ctx, "module c {namespace urn:c;prefix c; typedef mybasetype {type string;default hello;units xxx;}"
                                         "leaf l {type mybasetype; default goodbye;units yyy;}}", LYS_IN_YANG));
     type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
     assert_non_null(type);
-    assert_int_equal(2, type->refcount);
+    assert_int_equal(3, type->refcount); /* 2x type reference, 1x default value's reference */
     assert_int_equal(LY_TYPE_STRING, type->basetype);
-    assert_string_equal("goodbye", ((struct lysc_node_leaf*)mod->compiled->data)->dflt);
-    assert_string_equal("yyy", ((struct lysc_node_leaf*)mod->compiled->data)->units);
+    leaf = (struct lysc_node_leaf*)mod->compiled->data;
+    assert_string_equal("goodbye", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("yyy", leaf->units);
 
     assert_non_null(mod = lys_parse_mem(ctx, "module d {namespace urn:d;prefix d; typedef mybasetype {type string;default hello;units xxx;}"
                                         "typedef mytype {type mybasetype;}leaf l1 {type mytype; default goodbye;units yyy;}"
                                         "leaf l2 {type mytype;}}", LYS_IN_YANG));
     type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
     assert_non_null(type);
-    assert_int_equal(4, type->refcount);
+    assert_int_equal(6, type->refcount); /* 4x type reference, 2x default value's reference (1 shared compiled type of typedefs which default does not reference own type) */
     assert_int_equal(LY_TYPE_STRING, type->basetype);
-    assert_string_equal("goodbye", ((struct lysc_node_leaf*)mod->compiled->data)->dflt);
-    assert_string_equal("yyy", ((struct lysc_node_leaf*)mod->compiled->data)->units);
+    leaf = (struct lysc_node_leaf*)mod->compiled->data;
+    assert_string_equal("goodbye", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("yyy", leaf->units);
     type = ((struct lysc_node_leaf*)mod->compiled->data->next)->type;
     assert_non_null(type);
-    assert_int_equal(4, type->refcount);
+    assert_int_equal(6, type->refcount); /* 4x type reference, 2x default value's reference (1 shared compiled type of typedefs which default does not reference own type) */
     assert_int_equal(LY_TYPE_STRING, type->basetype);
-    assert_string_equal("hello", ((struct lysc_node_leaf*)mod->compiled->data->next)->dflt);
-    assert_string_equal("xxx", ((struct lysc_node_leaf*)mod->compiled->data->next)->units);
+    leaf = (struct lysc_node_leaf*)mod->compiled->data->next;
+    assert_string_equal("hello", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("xxx", leaf->units);
 
     assert_non_null(mod = lys_parse_mem(ctx, "module e {namespace urn:e;prefix e; typedef mybasetype {type string;}"
                                         "typedef mytype {type mybasetype; default hello;units xxx;}leaf l {type mytype;}}", LYS_IN_YANG));
     type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
     assert_non_null(type);
-    assert_int_equal(3, type->refcount);
+    assert_int_equal(4, type->refcount); /* 3x type reference, 1x default value's reference (typedef's default does not reference own type) */
     assert_int_equal(LY_TYPE_STRING, type->basetype);
-    assert_string_equal("hello", ((struct lysc_node_leaf*)mod->compiled->data)->dflt);
-    assert_string_equal("xxx", ((struct lysc_node_leaf*)mod->compiled->data)->units);
+    leaf = (struct lysc_node_leaf*)mod->compiled->data;
+    assert_string_equal("hello", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("xxx", leaf->units);
 
     /* mandatory leaf does not takes default value from type */
     assert_non_null(mod = lys_parse_mem(ctx, "module f {namespace urn:f;prefix f;typedef mytype {type string; default hello;units xxx;}"
@@ -2508,6 +2526,9 @@
     struct ly_ctx *ctx;
     struct lys_module *mod;
     struct lysc_node *parent, *child;
+    struct lysc_node_leaf *leaf;
+    struct lysc_node_leaflist *llist;
+    int dynamic;
 
     assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
 
@@ -2529,20 +2550,23 @@
     assert_non_null((parent = mod->compiled->data));
     assert_int_equal(LYS_CONTAINER, parent->nodetype);
     assert_string_equal("c", parent->name);
-    assert_non_null((child = ((struct lysc_node_container*)parent)->child));
-    assert_int_equal(LYS_LEAF, child->nodetype);
-    assert_string_equal("l", child->name);
-    assert_string_equal("hello", ((struct lysc_node_leaf*)child)->dflt);
-    assert_int_equal(LYS_CONFIG_R, child->flags & LYS_CONFIG_MASK);
-    assert_non_null(child = child->next);
-    assert_int_equal(LYS_LEAFLIST, child->nodetype);
-    assert_string_equal("ll", child->name);
-    assert_int_equal(2, LY_ARRAY_SIZE(((struct lysc_node_leaflist*)child)->dflts));
-    assert_string_equal("hello", ((struct lysc_node_leaflist*)child)->dflts[0]);
-    assert_string_equal("world", ((struct lysc_node_leaflist*)child)->dflts[1]);
-    assert_int_equal(2, ((struct lysc_node_leaflist*)child)->min);
-    assert_int_equal(5, ((struct lysc_node_leaflist*)child)->max);
-    assert_non_null(child = child->next);
+    assert_non_null((leaf = (struct lysc_node_leaf*)((struct lysc_node_container*)parent)->child));
+    assert_int_equal(LYS_LEAF, leaf->nodetype);
+    assert_string_equal("l", leaf->name);
+    assert_string_equal("hello", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_int_equal(LYS_CONFIG_R, leaf->flags & LYS_CONFIG_MASK);
+    assert_non_null(llist = (struct lysc_node_leaflist*)leaf->next);
+    assert_int_equal(LYS_LEAFLIST, llist->nodetype);
+    assert_string_equal("ll", llist->name);
+    assert_int_equal(2, LY_ARRAY_SIZE(llist->dflts));
+    assert_string_equal("hello", llist->dflts[0]->realtype->plugin->print(llist->dflts[0], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("world", llist->dflts[1]->realtype->plugin->print(llist->dflts[1], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_int_equal(2, llist->min);
+    assert_int_equal(5, llist->max);
+    assert_non_null(child = llist->next);
     assert_int_equal(LYS_CHOICE, child->nodetype);
     assert_string_equal("ch", child->name);
     assert_string_equal("b", ((struct lysc_node_choice*)child)->dflt->name);
@@ -2550,16 +2574,17 @@
     assert_false(LYS_SET_DFLT & ((struct lysc_node_choice*)child)->cases[0].flags);
     assert_non_null(child->iffeatures);
     assert_int_equal(1, LY_ARRAY_SIZE(child->iffeatures));
-    assert_non_null(child = child->next);
-    assert_int_equal(LYS_LEAF, child->nodetype);
-    assert_string_equal("x", child->name);
-    assert_false(LYS_MAND_TRUE & child->flags);
-    assert_string_equal("cheers!", ((struct lysc_node_leaf*)child)->dflt);
-    assert_non_null(((struct lysc_node_leaf*)child)->musts);
-    assert_int_equal(2, LY_ARRAY_SIZE(((struct lysc_node_leaf*)child)->musts));
-    assert_string_equal("refined", child->dsc);
-    assert_string_equal("refined", child->ref);
-    assert_non_null(child = child->next);
+    assert_non_null(leaf = (struct lysc_node_leaf*)child->next);
+    assert_int_equal(LYS_LEAF, leaf->nodetype);
+    assert_string_equal("x", leaf->name);
+    assert_false(LYS_MAND_TRUE & leaf->flags);
+    assert_string_equal("cheers!", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_non_null(leaf->musts);
+    assert_int_equal(2, LY_ARRAY_SIZE(leaf->musts));
+    assert_string_equal("refined", leaf->dsc);
+    assert_string_equal("refined", leaf->ref);
+    assert_non_null(child = leaf->next);
     assert_int_equal(LYS_ANYDATA, child->nodetype);
     assert_string_equal("a", child->name);
     assert_true(LYS_MAND_TRUE & child->flags);
@@ -2578,11 +2603,12 @@
 
     assert_non_null(mod = lys_parse_mem(ctx, "module b {yang-version 1.1;namespace urn:b;prefix b;import grp {prefix g;}"
                                         "uses g:grp {status deprecated; refine c/x {default hello; mandatory false;}}}", LYS_IN_YANG));
-    assert_non_null((child = ((struct lysc_node_container*)mod->compiled->data)->child->prev->prev->prev));
-    assert_int_equal(LYS_LEAF, child->nodetype);
-    assert_string_equal("x", child->name);
-    assert_false(LYS_MAND_TRUE & child->flags);
-    assert_string_equal("hello", ((struct lysc_node_leaf*)child)->dflt);
+    assert_non_null((leaf = (struct lysc_node_leaf*)((struct lysc_node_container*)mod->compiled->data)->child->prev->prev->prev));
+    assert_int_equal(LYS_LEAF, leaf->nodetype);
+    assert_string_equal("x", leaf->name);
+    assert_false(LYS_MAND_TRUE & leaf->flags);
+    assert_string_equal("hello", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
 
     /* invalid */
     assert_null(lys_parse_mem(ctx, "module aa {namespace urn:aa;prefix aa;import grp {prefix g;}"
@@ -2799,6 +2825,9 @@
     struct lys_module *mod;
     const struct lysc_node *node;
     const struct lysc_node_list *list;
+    const struct lysc_node_leaflist *llist;
+    const struct lysc_node_leaf *leaf;
+    int dynamic;
 
     assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
 
@@ -2881,16 +2910,20 @@
     assert_null(((struct lysc_node_choice*)node)->dflt);
     assert_non_null(node = node->next);
     assert_null(((struct lysc_node_choice*)node)->dflt);
-    assert_non_null(node = node->next);
-    assert_null(((struct lysc_node_leaf*)node)->dflt);
-    assert_non_null(node = node->next);
-    assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_node_leaflist*)node)->dflts));
-    assert_string_equal("hello", ((struct lysc_node_leaflist*)node)->dflts[0]);
-    assert_non_null(node = node->next);
-    assert_string_equal("nothing", ((struct lysc_node_leaf*)node)->dflt);
-    assert_non_null(node = node->next);
-    assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_node_leaflist*)node)->dflts));
-    assert_string_equal("nothing", ((struct lysc_node_leaflist*)node)->dflts[0]);
+    assert_non_null(leaf = (struct lysc_node_leaf*)node->next);
+    assert_null(leaf->dflt);
+    assert_non_null(llist = (struct lysc_node_leaflist*)leaf->next);
+    assert_int_equal(1, LY_ARRAY_SIZE(llist->dflts));
+    assert_string_equal("hello", llist->dflts[0]->realtype->plugin->print(llist->dflts[0], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_non_null(leaf = (struct lysc_node_leaf*)llist->next);
+    assert_string_equal("nothing", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_int_equal(5, leaf->dflt->realtype->refcount); /* 3x type reference, 2x default value reference (typedef's default does not reference own type) */
+    assert_non_null(llist = (struct lysc_node_leaflist*)leaf->next);
+    assert_int_equal(1, LY_ARRAY_SIZE(llist->dflts));
+    assert_string_equal("nothing", llist->dflts[0]->realtype->plugin->print(llist->dflts[0], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
 
     assert_non_null(lys_parse_mem(ctx, "module g {yang-version 1.1; namespace urn:g;prefix g;import e {prefix x;}"
                                   "deviation /x:b {deviate add {default x:b;}}"
@@ -2904,21 +2937,30 @@
     assert_non_null(node = node->next);
     assert_non_null(((struct lysc_node_choice*)node)->dflt);
     assert_string_equal("b", ((struct lysc_node_choice*)node)->dflt->name);
-    assert_non_null(node = node->next);
-    assert_non_null(((struct lysc_node_leaf*)node)->dflt);
-    assert_string_equal("bye", ((struct lysc_node_leaf*)node)->dflt);
-    assert_non_null(node = node->next);
-    assert_int_equal(3, LY_ARRAY_SIZE(((struct lysc_node_leaflist*)node)->dflts));
-    assert_string_equal("hello", ((struct lysc_node_leaflist*)node)->dflts[0]);
-    assert_string_equal("all", ((struct lysc_node_leaflist*)node)->dflts[1]);
-    assert_string_equal("people", ((struct lysc_node_leaflist*)node)->dflts[2]);
-    assert_non_null(node = node->next);
-    assert_non_null(((struct lysc_node_leaf*)node)->dflt);
-    assert_string_equal("hi", ((struct lysc_node_leaf*)node)->dflt);
-    assert_non_null(node = node->next);
-    assert_int_equal(2, LY_ARRAY_SIZE(((struct lysc_node_leaflist*)node)->dflts));
-    assert_string_equal("hi", ((struct lysc_node_leaflist*)node)->dflts[0]);
-    assert_string_equal("all", ((struct lysc_node_leaflist*)node)->dflts[1]);
+    assert_non_null(leaf = (struct lysc_node_leaf*)node->next);
+    assert_non_null(leaf->dflt);
+    assert_string_equal("bye", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_non_null(llist = (struct lysc_node_leaflist*)leaf->next);
+    assert_int_equal(3, LY_ARRAY_SIZE(llist->dflts));
+    assert_string_equal("hello", llist->dflts[0]->realtype->plugin->print(llist->dflts[0], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("all", llist->dflts[1]->realtype->plugin->print(llist->dflts[1], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("people", llist->dflts[2]->realtype->plugin->print(llist->dflts[2], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_non_null(leaf = (struct lysc_node_leaf*)llist->next);
+    assert_non_null(leaf->dflt);
+    assert_string_equal("hi", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_int_equal(6, leaf->dflt->realtype->refcount); /* 3x type reference, 3x default value reference
+    - previous type's default values were replaced by node's default values where d2 now has 2 default values */
+    assert_non_null(llist = (struct lysc_node_leaflist*)leaf->next);
+    assert_int_equal(2, LY_ARRAY_SIZE(llist->dflts));
+    assert_string_equal("hi", llist->dflts[0]->realtype->plugin->print(llist->dflts[0], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_string_equal("all", llist->dflts[1]->realtype->plugin->print(llist->dflts[1], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
 
     assert_non_null(lys_parse_mem(ctx, "module h {yang-version 1.1; namespace urn:h;prefix h;import e {prefix x;}"
                                   "deviation /x:b {deviate replace {default x:a;}}"
@@ -2929,9 +2971,10 @@
     assert_non_null(node = node->next);
     assert_non_null(((struct lysc_node_choice*)node)->dflt);
     assert_string_equal("a", ((struct lysc_node_choice*)node)->dflt->name);
-    assert_non_null(node = node->next);
-    assert_non_null(((struct lysc_node_leaf*)node)->dflt);
-    assert_string_equal("hello", ((struct lysc_node_leaf*)node)->dflt);
+    assert_non_null(leaf = (struct lysc_node_leaf*)node->next);
+    assert_non_null(leaf->dflt);
+    assert_string_equal("hello", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
 
     ly_ctx_set_module_imp_clb(ctx, test_imp_clb, "module i {namespace urn:i;prefix i;"
                               "list l1 {key a; leaf a {type string;} leaf b {type string;} leaf c {type string;}}"
@@ -3044,15 +3087,19 @@
                                         "leaf a {type string; default 10;} leaf-list b {type string;}"
                                         "deviation /a {deviate replace {type mytype;}}"
                                         "deviation /b {deviate replace {type mytype;}}}", LYS_IN_YANG));
-    assert_non_null(node = mod->compiled->data);
-    assert_string_equal("a", node->name);
-    assert_int_equal(LY_TYPE_INT8, ((struct lysc_node_leaf*)node)->type->basetype);
-    assert_string_equal("10", ((struct lysc_node_leaf*)node)->dflt);
-    assert_non_null(node = node->next);
-    assert_string_equal("b", node->name);
-    assert_int_equal(LY_TYPE_INT8, ((struct lysc_node_leaflist*)node)->type->basetype);
-    assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_node_leaflist*)node)->dflts));
-    assert_string_equal("1", ((struct lysc_node_leaflist*)node)->dflts[0]);
+    assert_non_null(leaf = (struct lysc_node_leaf*)mod->compiled->data);
+    assert_string_equal("a", leaf->name);
+    assert_int_equal(LY_TYPE_INT8, leaf->type->basetype);
+    assert_string_equal("10", leaf->dflt->realtype->plugin->print(leaf->dflt, LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_int_equal(10, leaf->dflt->uint8);
+    assert_non_null(llist = (struct lysc_node_leaflist*)leaf->next);
+    assert_string_equal("b", llist->name);
+    assert_int_equal(LY_TYPE_INT8, llist->type->basetype);
+    assert_int_equal(1, LY_ARRAY_SIZE(llist->dflts));
+    assert_string_equal("1", llist->dflts[0]->realtype->plugin->print(llist->dflts[0], LYD_XML, NULL, NULL, &dynamic));
+    assert_int_equal(0, dynamic);
+    assert_int_equal(1, llist->dflts[0]->uint8);
 
     assert_null(lys_parse_mem(ctx, "module aa1 {namespace urn:aa1;prefix aa1;import a {prefix a;}"
                               "deviation /a:top/a:z {deviate not-supported;}}", LYS_IN_YANG));