extensions CHANGE when parsing extension instance, use the plugin callback to check its position
diff --git a/src/resolve.c b/src/resolve.c
index 526d068..005bd83 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -4482,98 +4482,109 @@
         }
 
         /* we have the extension definition, so now it cannot be forward referenced and error is always fatal */
-        if (!e->plugin || e->plugin->type == LYEXT_FLAG) {
-            if (e->flags & LYS_YINELEM) {
-                value = NULL;
-                c_ext = 0;
-                LY_TREE_FOR_SAFE(info->data.yin->child, next_yin, yin) {
-                    if (!yin->ns) {
-                        /* garbage */
-                        lyxml_free(mod->ctx, yin);
-                        continue;
-                    } else if (!strcmp(yin->ns->value, LY_NSYIN)) {
-                        /* standard YANG statements are not expected here */
-                        LOGVAL(LYE_INCHILDSTMT, vlog_type, vlog_node, yin->name, info->data.yin->name);
-                        return -1;
-                    } else if (yin->ns == info->data.yin->ns && ly_strequal(yin->name, e->argument, 1)) {
-                        /* we have the extension's argument */
-                        if (value) {
-                            LOGVAL(LYE_TOOMANY, vlog_type, vlog_node, yin->name, info->data.yin->name);
-                            return -1;
-                        }
-                        value = yin->content;
-                        yin->content = NULL;
-                        lyxml_free(mod->ctx, yin);
-                    } else {
-                        /* possible extension instance, processed later */
-                        c_ext++;
-                        continue;
-                    }
-                }
-                if (!value) {
-                    LOGVAL(LYE_MISSCHILDSTMT, vlog_type, vlog_node, e->argument, info->data.yin->name);
-                    return -1;
-                }
-            } else if (e->argument) {
-                value = lyxml_get_attr(info->data.yin, e->argument, NULL);
-                if (!value) {
-                    LOGVAL(LYE_MISSARG, LY_VLOG_NONE, NULL, e->argument, info->data.yin->name);
-                    return -1;
-                }
-                value = lydict_insert(mod->ctx, value, 0);
-            } else {
-                value = NULL;
-            }
-            (*ext) = calloc(1, sizeof(struct lys_ext_instance));
-            ((struct lys_ext_instance *)(*ext))->def = e;
-            ((struct lys_ext_instance *)(*ext))->arg_value = value;
-            ((struct lys_ext_instance *)(*ext))->parent = info->parent;
-            ((struct lys_ext_instance *)(*ext))->parent_type = info->parent_type;
 
-            /* extension instances in extension */
-            if (c_ext == -1) {
-                c_ext = 0;
-                /* first, we have to count them */
-                LY_TREE_FOR_SAFE(info->data.yin->child, next_yin, yin) {
-                    if (!yin->ns) {
-                        /* garbage */
-                        lyxml_free(mod->ctx, yin);
-                        continue;
-                    } else if (strcmp(yin->ns->value, LY_NSYIN)) {
-                        /* possible extension instance */
-                        c_ext++;
-                    } else {
-                        /* unexpected statement */
-                        LOGVAL(LYE_INCHILDSTMT, vlog_type, vlog_node, yin->name, info->data.yin->name);
+        if (e->plugin && e->plugin->check_position) {
+            /* common part - we have plugin with position checking function, use it first */
+            if ((*e->plugin->check_position)(info->parent, info->parent_type, info->substmt)) {
+                /* extension is not allowed here */
+                LOGVAL(LYE_INSTMT, vlog_type, vlog_node, e->name);
+                return -1;
+            }
+        }
+
+        /* common part, even if there is no plugin */
+        if (e->flags & LYS_YINELEM) {
+            value = NULL;
+            c_ext = 0;
+            LY_TREE_FOR_SAFE(info->data.yin->child, next_yin, yin) {
+                if (!yin->ns) {
+                    /* garbage */
+                    lyxml_free(mod->ctx, yin);
+                    continue;
+                } else if (!strcmp(yin->ns->value, LY_NSYIN)) {
+                    /* standard YANG statements are not expected here */
+                    LOGVAL(LYE_INCHILDSTMT, vlog_type, vlog_node, yin->name, info->data.yin->name);
+                    return -1;
+                } else if (yin->ns == info->data.yin->ns && ly_strequal(yin->name, e->argument, 1)) {
+                    /* we have the extension's argument */
+                    if (value) {
+                        LOGVAL(LYE_TOOMANY, vlog_type, vlog_node, yin->name, info->data.yin->name);
                         return -1;
                     }
+                    value = yin->content;
+                    yin->content = NULL;
+                    lyxml_free(mod->ctx, yin);
+                } else {
+                    /* possible extension instance, processed later */
+                    c_ext++;
+                    continue;
                 }
             }
-            if (c_ext) {
-                (*ext)->ext = calloc(c_ext, sizeof *(*ext)->ext);
-                if (!(*ext)->ext) {
-                    LOGMEM;
+            if (!value) {
+                LOGVAL(LYE_MISSCHILDSTMT, vlog_type, vlog_node, e->argument, info->data.yin->name);
+                return -1;
+            }
+        } else if (e->argument) {
+            value = lyxml_get_attr(info->data.yin, e->argument, NULL);
+            if (!value) {
+                LOGVAL(LYE_MISSARG, LY_VLOG_NONE, NULL, e->argument, info->data.yin->name);
+                return -1;
+            }
+            value = lydict_insert(mod->ctx, value, 0);
+        } else {
+            value = NULL;
+        }
+        (*ext) = calloc(1, sizeof(struct lys_ext_instance));
+        ((struct lys_ext_instance *)(*ext))->def = e;
+        ((struct lys_ext_instance *)(*ext))->arg_value = value;
+        ((struct lys_ext_instance *)(*ext))->parent = info->parent;
+        ((struct lys_ext_instance *)(*ext))->parent_type = info->parent_type;
+        ((struct lys_ext_instance *)(*ext))->substmt = info->substmt;
+        ((struct lys_ext_instance *)(*ext))->substmt_index = info->substmt_index;
+
+        /* extension instances in extension */
+        if (c_ext == -1) {
+            c_ext = 0;
+            /* first, we have to count them */
+            LY_TREE_FOR_SAFE(info->data.yin->child, next_yin, yin) {
+                if (!yin->ns) {
+                    /* garbage */
+                    lyxml_free(mod->ctx, yin);
+                    continue;
+                } else if (strcmp(yin->ns->value, LY_NSYIN)) {
+                    /* possible extension instance */
+                    c_ext++;
+                } else {
+                    /* unexpected statement */
+                    LOGVAL(LYE_INCHILDSTMT, vlog_type, vlog_node, yin->name, info->data.yin->name);
                     return -1;
                 }
-                LY_TREE_FOR_SAFE(info->data.yin->child, next_yin, yin) {
-                    subinfo = malloc(sizeof *subinfo);
-                    lyxml_unlink(mod->ctx, yin);
-                    subinfo->data.yin = yin;
-                    subinfo->datatype = LYS_IN_YIN;
-                    subinfo->parent = (void *)(*ext);
-                    subinfo->parent_type = LYEXT_PAR_EXTINST;
-                    rc = unres_schema_add_node((struct lys_module *)mod, unres, &(*ext)->ext[(*ext)->ext_size],
-                                               UNRES_EXT, (struct lys_node *)subinfo);
-                    (*ext)->ext_size++;
-                    if (rc == -1) {
-                        return EXIT_FAILURE;
-                    }
+            }
+        }
+        if (c_ext) {
+            (*ext)->ext = calloc(c_ext, sizeof *(*ext)->ext);
+            if (!(*ext)->ext) {
+                LOGMEM;
+                return -1;
+            }
+            LY_TREE_FOR_SAFE(info->data.yin->child, next_yin, yin) {
+                subinfo = malloc(sizeof *subinfo);
+                lyxml_unlink(mod->ctx, yin);
+                subinfo->data.yin = yin;
+                subinfo->datatype = LYS_IN_YIN;
+                subinfo->parent = (void *)(*ext);
+                subinfo->parent_type = LYEXT_PAR_EXTINST;
+                rc = unres_schema_add_node((struct lys_module *)mod, unres, &(*ext)->ext[(*ext)->ext_size],
+                                           UNRES_EXT, (struct lys_node *)subinfo);
+                (*ext)->ext_size++;
+                if (rc == -1) {
+                    return EXIT_FAILURE;
                 }
             }
-        } else {
-            /* unknown */
-            return -1;
         }
+
+        /* TODO - lyext_check_result_clb, other than LYEXT_FLAG plugins */
+
     } else {
         /* TODO YANG */