lys_get_schema_inctx(struct lys_node *schema, struct ly_ctx *ctx)
{
    const struct lys_module *mod, *trg_mod = NULL;
    struct lys_node *parent, *first_sibling = NULL, *iter = NULL;
    struct ly_set *parents;
    unsigned int index;
    uint32_t idx;
    void **ptr;

    if (!ctx || schema->module->ctx == ctx) {
        /* we have the same context */
        return schema;
    }

    /* store the parents chain */
    parents = ly_set_new();
    for (parent = schema; parent; parent = lys_parent(parent)) {
        /* note - augments are skipped so we will work only with the implemented modules
         * (where the augments are applied) */
        if (parent->nodetype != LYS_USES) {
            ly_set_add(parents, parent, LY_SET_OPT_USEASLIST);
        }
    }
    assert(parents->number);
    index = parents->number - 1;

    /* process the parents from the top level */
    /* for the top-level node, we have to locate the module first */
    parent = parents->set.s[index];
    if (parent->nodetype == LYS_EXT) {
        ptr = lys_ext_complex_get_substmt(LY_STMT_NODE, (struct lys_ext_instance_complex *)parent, NULL);
        if (!ptr) {
            ly_set_free(parents);
            return NULL;
        }
        first_sibling = *(struct lys_node **)ptr;
        parent = parents->set.s[--index];
    }
    idx = 0;
    while ((mod = ly_ctx_get_module_iter(ctx, &idx))) {
        trg_mod = lys_node_module(parent);
        /* check module name */
        if (strcmp(mod->name, trg_mod->name)) {
            continue;
        }

        /* check revision */
        if ((!mod->rev_size && !trg_mod->rev_size) ||
                (mod->rev_size && trg_mod->rev_size && !strcmp(mod->rev[0].date, trg_mod->rev[0].date))) {
            /* we have match */
            break;
        }
    }
    /* try data callback */
    if (!mod && trg_mod && ctx->data_clb) {
        LOGDBG(LY_LDGYANG, "Attempting to load '%s' into context using callback ...", trg_mod->name);
        mod = ctx->data_clb(ctx, trg_mod->name, NULL, 0, ctx->data_clb_data);
    }
    if (!mod) {
        ly_set_free(parents);
        return NULL;
    }
    if (!first_sibling) {
        first_sibling = mod->data;
    }

    /* now search in the schema tree for the matching node */
    while (1) {
        lys_get_sibling(first_sibling, trg_mod->name, 0, parent->name, 0, parent->nodetype,
                        (const struct lys_node **)&iter);
        if (!iter) {
            /* not found, iter will be used as NULL result */
            break;
        }

        if (index == 0) {
            /* we are done, iter is the result */
            break;
        } else {
            /* we are going to continue, so update variables for the next loop */
            first_sibling = iter->child;
            parent = parents->set.s[--index];
            iter = NULL;
        }
    }

    ly_set_free(parents);
    return iter;
}
lys_get_schema_inctx(struct lys_node *schema, struct ly_ctx *ctx)
{
    const struct lys_module *mod, *trg_mod = NULL;
    struct lys_node *parent, *first_sibling = NULL, *iter = NULL;
    struct ly_set *parents;
    unsigned int index;
    uint32_t idx;
    void **ptr;

    if (!ctx || schema->module->ctx == ctx) {
         
        return schema;
    }

     
    parents = ly_set_new();
    for (parent = schema; parent; parent = lys_parent(parent)) {
         
        if (parent->nodetype != LYS_USES) {
            ly_set_add(parents, parent, LY_SET_OPT_USEASLIST);
        }
    }
    assert(parents->number);
    index = parents->number - 1;

     
     
    parent = parents->set.s[index];
    if (parent->nodetype == LYS_EXT) {
        ptr = lys_ext_complex_get_substmt(LY_STMT_NODE, (struct lys_ext_instance_complex *)parent, NULL);
        if (!ptr) {
            ly_set_free(parents);
            return NULL;
        }
        first_sibling = *(struct lys_node **)ptr;
        parent = parents->set.s[--index];
    }
    idx = 0;
    while ((mod = ly_ctx_get_module_iter(ctx, &idx))) {
        trg_mod = lys_node_module(parent);
         
        if (strcmp(mod->name, trg_mod->name)) {
            continue;
        }

         
        if ((!mod->rev_size && !trg_mod->rev_size) ||
                (mod->rev_size && trg_mod->rev_size && !strcmp(mod->rev[0].date, trg_mod->rev[0].date))) {
             
            break;
        }
    }
     
    if (!mod && trg_mod && ctx->data_clb) {
        LOGDBG(LY_LDGYANG, "Attempting to load '%s' into context using callback ...", trg_mod->name);
        mod = ctx->data_clb(ctx, trg_mod->name, NULL, 0, ctx->data_clb_data);
    }
    if (!mod) {
        ly_set_free(parents);
        return NULL;
    }
    if (!first_sibling) {
        first_sibling = mod->data;
    }

     
    while (1) {
        lys_get_sibling(first_sibling, trg_mod->name, 0, parent->name, 0, parent->nodetype,
                        (const struct lys_node **)&iter);
        if (!iter) {
             
            break;
        }

        if (index == 0) {
             
            break;
        } else {
             
            first_sibling = iter->child;
            parent = parents->set.s[--index];
            iter = NULL;
        }
    }

    ly_set_free(parents);
    return iter;
}