apply_aug(struct lys_node_augment *augment, struct unres_schema *unres)
{
    struct lys_node *child, *parent;
    struct lys_module *mod;
    struct lys_type *type;
    int clear_config;
    unsigned int u;
    uint8_t *v;
    struct lys_ext_instance *ext;

    assert(augment->target && (augment->flags & LYS_NOTAPPLIED));

    if (!augment->child) {
        /* nothing to apply */
        goto success;
    }

    /* inherit config information from actual parent */
    for (parent = augment->target; parent && !(parent->nodetype & (LYS_NOTIF | LYS_INPUT | LYS_OUTPUT | LYS_RPC)); parent = lys_parent(parent));
    clear_config = (parent) ? 1 : 0;
    LY_TREE_FOR(augment->child, child) {
        if (inherit_config_flag(child, augment->target->flags & LYS_CONFIG_MASK, clear_config)) {
            return -1;
        }
    }

    /* inherit extensions if any */
    for (u = 0; u < augment->target->ext_size; u++) {
        ext = augment->target->ext[u]; /* shortcut */
        if (ext && ext->def->plugin && (ext->def->plugin->flags & LYEXT_OPT_INHERIT)) {
            v = malloc(sizeof *v);
            LY_CHECK_ERR_RETURN(!v, LOGMEM(augment->module->ctx), -1);
            *v = u;
            if (unres_schema_add_node(lys_main_module(augment->module), unres, &augment->target->ext,
                    UNRES_EXT_FINALIZE, (struct lys_node *)v) == -1) {
                /* something really bad happened since the extension finalization is not actually
                 * being resolved while adding into unres, so something more serious with the unres
                 * list itself must happened */
                return -1;
            }
        }
    }

    if (lys_node_module((struct lys_node *)augment)->implemented) {
        /* check that all leafrefs point to implemented modules */
        LY_TREE_DFS_BEGIN((struct lys_node *)augment, parent, child) {
            if (child->nodetype & (LYS_LEAF | LYS_LEAFLIST)) {
                type = &((struct lys_node_leaf *)child)->type;
                if (type->base == LY_TYPE_LEAFREF) {
                    /* must be resolved or in unres */
                    if (!type->info.lref.target) {
                        if (unres_schema_find(unres, -1, type, UNRES_TYPE_LEAFREF) > -1) {
                            if (unres_schema_add_node(lys_node_module(child), unres, type, UNRES_TYPE_LEAFREF, child) == -1) {
                                return -1;
                            }
                        }
                    } else {
                        mod = lys_node_module((struct lys_node *)type->info.lref.target);
                        if (!mod->implemented) {
                            mod->implemented = 1;
                            if (unres_schema_add_node(mod, unres, NULL, UNRES_MOD_IMPLEMENT, NULL) == -1) {
                                return -1;
                            }
                        }
                    }
                }
            }

            LY_TREE_DFS_END((struct lys_node *)augment, parent, child);
        }
    }

    /* reconnect augmenting data into the target - add them to the target child list */
    if (augment->target->child) {
        child = augment->target->child->prev;
        child->next = augment->child;
        augment->target->child->prev = augment->child->prev;
        augment->child->prev = child;
    } else {
        augment->target->child = augment->child;
    }

success:
    /* remove the flag about not applicability */
    augment->flags &= ~LYS_NOTAPPLIED;
    return EXIT_SUCCESS;
}