diff --git a/scripts/modules/bpy_types.py b/scripts/modules/bpy_types.py
index 209f7ed050c..f182c5396d7 100644
--- a/scripts/modules/bpy_types.py
+++ b/scripts/modules/bpy_types.py
@@ -987,6 +987,11 @@ class AddonPreferences(StructRNA, metaclass=RNAMeta):
     __slots__ = ()
 
 
+class ReferencedDrawFunc:
+    def __init__(self, func):
+        self.func = func
+        self.used = False
+
 class _GenericUI:
     __slots__ = ()
 
@@ -1007,6 +1012,13 @@ class _GenericUI:
                 else:
                     owner_names = None
 
+                if (hasattr(cls, "reference_debug") and cls.reference_debug):
+                    print ("---")
+                # Reset drawn flag, to be able shown error if not used
+                for label in cls.referenced_post:
+                    for ref in cls.referenced_post[label]:
+                        ref.used = False
+
                 for func in draw_ls._draw_funcs:
 
                     # Begin 'owner_id' filter.
@@ -1030,11 +1042,38 @@ class _GenericUI:
 
                     self.layout.operator_context = operator_context_default
 
+                for label in cls.referenced_post:
+                    for ref in cls.referenced_post[label]:
+                        if ref.used == False:
+                            print("ERR: ", label, " referenced not drawn in", self.__class__.__name__)
+
             draw_funcs = draw_ls._draw_funcs = [cls.draw]
             cls.draw = draw_ls
 
+            cls.referenced_pre = {}
+            cls.referenced_post = {}
+
         return draw_funcs
 
+    def draw_referenced_pre(cls, label):
+        if (hasattr(cls, "reference_debug") and cls.reference_debug):
+            print (label)
+
+        cls._dyn_ui_initialize()
+        if label in cls.referenced_pre:
+            for ref in cls.referenced_pre[label]:
+                #need to get the context
+                ref.used = True
+                ref.func(cls, None)
+
+    def draw_referenced_post(cls, label):
+        cls._dyn_ui_initialize()
+        if label in cls.referenced_post:
+            for ref in cls.referenced_post[label]:
+                #need to get the context
+                ref.used = True
+                ref.func(cls, None)
+
     @staticmethod
     def _dyn_owner_apply(draw_func):
         from _bpy import _bl_owner_id_get
@@ -1047,24 +1086,36 @@ class _GenericUI:
         return bool(getattr(cls.draw, "_draw_funcs", None))
 
     @classmethod
-    def append(cls, draw_func):
+    def append(cls, draw_func, label_referenced = None):
         """
         Append a draw function to this menu,
         takes the same arguments as the menus draw function
         """
         draw_funcs = cls._dyn_ui_initialize()
         cls._dyn_owner_apply(draw_func)
-        draw_funcs.append(draw_func)
+
+        if label_referenced != None:
+            if not (label_referenced in cls.referenced_post):
+                cls.referenced_post[label_referenced] = []
+            cls.referenced_post[label_referenced].append(ReferencedDrawFunc(draw_func))
+        else:
+            draw_funcs.append(draw_func)
 
     @classmethod
-    def prepend(cls, draw_func):
+    def prepend(cls, draw_func, label_referenced = None):
         """
         Prepend a draw function to this menu, takes the same arguments as
         the menus draw function
         """
         draw_funcs = cls._dyn_ui_initialize()
         cls._dyn_owner_apply(draw_func)
-        draw_funcs.insert(0, draw_func)
+
+        if label_referenced != None:
+            if not (label_referenced in cls.referenced_pre):
+                cls.referenced_pre[label_referenced] = []
+            cls.referenced_pre[label_referenced].append(ReferencedDrawFunc(draw_func))
+        else:
+            draw_funcs.insert(0, draw_func)
 
     @classmethod
     def remove(cls, draw_func):
diff --git a/source/blender/editors/include/UI_interface_c.hh b/source/blender/editors/include/UI_interface_c.hh
index a3b4f02eca3..a6f3fd77d29 100644
--- a/source/blender/editors/include/UI_interface_c.hh
+++ b/source/blender/editors/include/UI_interface_c.hh
@@ -2236,6 +2236,9 @@ void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout);
  */
 void UI_paneltype_draw(bContext *C, PanelType *pt, uiLayout *layout);
 
+void *uiLayoutGetParentObject(uiLayout *layout);
+struct ExtensionRNA *uiLayoutGetParentRnaExt(uiLayout *layout);
+
 /* Only for convenience. */
 void uiLayoutSetContextFromBut(uiLayout *layout, uiBut *but);
 
diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc
index dbbdc4356bd..f902d023161 100644
--- a/source/blender/editors/interface/interface_layout.cc
+++ b/source/blender/editors/interface/interface_layout.cc
@@ -169,6 +169,10 @@ struct uiLayout {
   eUIEmbossType emboss;
   /** for fixed width or height to avoid UI size changes */
   float units[2];
+
+  ExtensionRNA *parent_rna_ext;
+  void *parent_object;
+
 };
 
 struct uiLayoutItemFlow {
@@ -6060,6 +6064,20 @@ bContextStore *uiLayoutGetContextStore(uiLayout *layout)
   return layout->context;
 }
 
+void *uiLayoutGetParentObject(uiLayout * layout)
+{
+    return layout->parent_object;
+}
+
+ExtensionRNA *uiLayoutGetParentRnaExt(uiLayout *layout)
+{
+  // rna ext is set on menu draw, layout maybe a sublayout
+  while (layout && layout->parent_rna_ext == NULL) {
+    layout = layout->parent;
+  }
+  return layout ? layout->parent_rna_ext : NULL;
+}
+
 void uiLayoutContextCopy(uiLayout *layout, const bContextStore *context)
 {
   uiBlock *block = layout->root->block;
@@ -6154,6 +6172,9 @@ void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout)
   menu.layout = layout;
   menu.type = mt;
 
+  layout->parent_rna_ext = &mt->rna_ext;
+  layout->parent_object = (void*) &menu;
+
   if (G.debug & G_DEBUG_WM) {
     printf("%s: opening menu \"%s\"\n", __func__, mt->idname);
   }
@@ -6176,6 +6197,10 @@ void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout)
   if (layout->context) {
     CTX_store_set(C, nullptr);
   }
+
+  layout->parent_rna_ext = NULL;
+  layout->parent_object = NULL;
+
 }
 
 static bool ui_layout_has_panel_label(const uiLayout *layout, const PanelType *pt)
diff --git a/source/blender/makesrna/intern/rna_ui.cc b/source/blender/makesrna/intern/rna_ui.cc
index 7339b8c643c..867adae75ad 100644
--- a/source/blender/makesrna/intern/rna_ui.cc
+++ b/source/blender/makesrna/intern/rna_ui.cc
@@ -990,7 +990,7 @@ static StructRNA *rna_Menu_register(Main *bmain,
   const char *error_prefix = "Registering menu class:";
   MenuType *mt, dummy_mt = {nullptr};
   Menu dummy_menu = {nullptr};
-  bool have_function[2];
+  bool have_function[4];
   size_t over_alloc = 0; /* Warning, if this becomes a mess, we better do another allocation. */
   size_t description_size = 0;
   char _menu_descr[RNA_DYN_DESCR_MAX];
@@ -2196,6 +2196,19 @@ static void rna_def_menu(BlenderRNA *brna)
   parm = RNA_def_pointer(func, "context", "Context", "", "");
   RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
 
+  /* draw referenced */
+  func = RNA_def_function(srna, "draw_referenced_pre", nullptr);
+  RNA_def_function_ui_description(func, "Draw UI elements into the menu UI layout before reference");
+  RNA_def_function_flag(func, FUNC_REGISTER);
+  parm = RNA_def_string(func, "label", nullptr, 0, "", "draw reference menu label");
+  RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
+
+  func = RNA_def_function(srna, "draw_referenced_post", nullptr);
+  RNA_def_function_ui_description(func, "Draw UI elements into the menu UI layout after reference");
+  RNA_def_function_flag(func, FUNC_REGISTER);
+  parm = RNA_def_string(func, "label", nullptr, 0, "", "draw reference menu label");
+  RNA_def_parameter_flags(parm,PropertyFlag(0), PARM_REQUIRED);
+
   RNA_define_verify_sdna(false); /* not in sdna */
 
   prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_ui_api.cc b/source/blender/makesrna/intern/rna_ui_api.cc
index bcc0279cf5f..083fc586ab1 100644
--- a/source/blender/makesrna/intern/rna_ui_api.cc
+++ b/source/blender/makesrna/intern/rna_ui_api.cc
@@ -11,6 +11,7 @@
 
 #include "BLI_utildefines.h"
 
+#include "BLI_string.h"
 #include "BLT_translation.h"
 
 #include "RNA_define.hh"
@@ -326,6 +327,63 @@ static void rna_uiItemPointerR(uiLayout *layout,
       layout, ptr, prop, searchptr, searchprop, name, icon, results_are_suggestions);
 }
 
+static void rna_call_draw_referenced(uiLayout *layout, const char *name, FunctionRNA *func)
+{
+  if (*name == '\0') {
+    return;
+  }
+
+  char *label = (char*) MEM_callocN(255, __func__);  // Error defined as not dinamic []
+  BLI_strncpy(label, name, 255);
+
+
+  // Remove ... added in some menus, like Open...
+  size_t label_len = BLI_strnlen(name, 255);
+  if (label_len > 4) {
+    char *end = label + label_len;
+    if (*(end - 1) == '.' && *(end - 2) == '.' && *(end - 3) == '.') {
+      *(end - 3) = '\0';
+    }
+  }
+
+
+  ExtensionRNA *ext_rna = uiLayoutGetParentRnaExt(layout);
+  if (ext_rna) {
+    PointerRNA ptr = RNA_pointer_create(NULL, ext_rna->srna, uiLayoutGetParentObject(layout));
+    ParameterList list;
+    RNA_parameter_list_create(&list, &ptr, func);
+    // Do not know how the get the context, is lost on python RNA call.
+    // RNA_parameter_set_lookup(&list, "context", &C);
+    // rna_ext->call((bContext *)C, &ptr, func, &list);
+    RNA_parameter_set_lookup(&list, "label", &label);
+    ext_rna->call(NULL, &ptr, func, &list);
+    RNA_parameter_list_free(&list);
+  }
+
+  MEM_freeN(label);
+}
+
+static void rna_call_draw_referenced_pre(uiLayout *layout, const char *name)
+{
+
+  extern FunctionRNA rna_Menu_draw_referenced_pre_func;
+  FunctionRNA *func;
+  func = &rna_Menu_draw_referenced_pre_func; /* RNA_struct_find_function(&ptr,
+                                                            "draw_referenced_pre") */
+  rna_call_draw_referenced(layout, name, func);
+}
+
+static void rna_call_draw_referenced_post(uiLayout *layout, const char *name)
+{
+  extern FunctionRNA rna_Menu_draw_referenced_post_func;
+
+  FunctionRNA *func;
+  func = &rna_Menu_draw_referenced_post_func;  /* RNA_struct_find_function(&ptr, "draw_referenced_post") */
+
+  rna_call_draw_referenced(layout, name, func);
+}
+
+
 static PointerRNA rna_uiItemO(uiLayout *layout,
                               const char *opname,
                               const char *name,
@@ -337,6 +395,11 @@ static PointerRNA rna_uiItemO(uiLayout *layout,
                               int icon_value)
 {
   wmOperatorType *ot;
+  char original_name[255] = {0};
+
+  if (name) {
+    BLI_strncpy(original_name, name, 255);
+  }
 
   ot = WM_operatortype_find(opname, false); /* print error next */
   if (!ot || !ot->srna) {
@@ -344,6 +407,13 @@ static PointerRNA rna_uiItemO(uiLayout *layout,
     return PointerRNA_NULL;
   }
 
+   if (name && *name != '\0') {
+    BLI_strncpy(original_name, name, 255);
+  }
+  else {
+    BLI_strncpy(original_name, ot->name, 255);
+  }
+
   /* Get translated name (label). */
   name = rna_translate_ui_text(name, text_ctxt, ot->srna, nullptr, translate);
 
@@ -358,10 +428,15 @@ static PointerRNA rna_uiItemO(uiLayout *layout,
     flag |= UI_ITEM_O_DEPRESS;
   }
 
+  rna_call_draw_referenced_pre(layout, original_name);
+
   PointerRNA opptr;
   uiItemFullO_ptr(
       layout, ot, name, icon, nullptr, uiLayoutGetOperatorContext(layout), flag, &opptr);
-  return opptr;
+
+  rna_call_draw_referenced_post(layout, original_name);
+
+return opptr;
 }
 
 static PointerRNA rna_uiItemOMenuHold(uiLayout *layout,
@@ -405,8 +480,17 @@ static void rna_uiItemsEnumO(uiLayout *layout,
                              const char *propname,
                              const bool icon_only)
 {
+
+  wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+
+  /** Calling only once per operator **/
+  rna_call_draw_referenced_pre(layout, ot->name);
+
   eUI_Item_Flag flag = icon_only ? UI_ITEM_R_ICON_ONLY : UI_ITEM_NONE;
   uiItemsFullEnumO(layout, opname, propname, nullptr, uiLayoutGetOperatorContext(layout), flag);
+
+  rna_call_draw_referenced_post(layout, ot->name);
+
 }
 
 static PointerRNA rna_uiItemMenuEnumO(uiLayout *layout,
@@ -420,6 +504,12 @@ static PointerRNA rna_uiItemMenuEnumO(uiLayout *layout,
 {
   wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */
 
+  char original_name[255] = {0};
+
+  if (name) {
+    BLI_strncpy(original_name, name, 255);
+  }
+
   if (!ot || !ot->srna) {
     RNA_warning("%s '%s'", ot ? "operator missing srna" : "unknown operator", opname);
     return PointerRNA_NULL;
@@ -428,8 +518,13 @@ static PointerRNA rna_uiItemMenuEnumO(uiLayout *layout,
   /* Get translated name (label). */
   name = rna_translate_ui_text(name, text_ctxt, ot->srna, nullptr, translate);
 
+  rna_call_draw_referenced_pre(layout, original_name);
+
   PointerRNA opptr;
   uiItemMenuEnumFullO_ptr(layout, C, ot, propname, name, icon, &opptr);
+
+  rna_call_draw_referenced_post(layout, original_name);
+
   return opptr;
 }
 
@@ -465,12 +560,33 @@ static void rna_uiItemM(uiLayout *layout,
     icon = icon_value;
   }
 
+  MenuType *mt = WM_menutype_find(menuname, false);
+  if (mt == NULL) {
+    RNA_warning("not found %s", menuname);
+    return;
+  }
+
+  rna_call_draw_referenced_pre(layout, mt->label);
+
   uiItemM(layout, menuname, name, icon);
+
+  rna_call_draw_referenced_post(layout, mt->label);
 }
 
 static void rna_uiItemM_contents(uiLayout *layout, const char *menuname)
 {
+
+  MenuType *mt = WM_menutype_find(menuname, false);
+  if (mt == NULL) {
+    RNA_warning("not found %s", menuname);
+    return;
+  }
+
+  rna_call_draw_referenced_pre(layout, mt->label);
+
   uiItemMContents(layout, menuname);
+
+  rna_call_draw_referenced_post(layout, mt->label);
 }
 
 static void rna_uiItemPopoverPanel(uiLayout *layout,
diff --git a/source/blender/tornavis/patches/MB_0009.h b/source/blender/tornavis/patches/MB_0009.h
new file mode 100644
index 00000000000..c978e52a11c
--- /dev/null
+++ b/source/blender/tornavis/patches/MB_0009.h
@@ -0,0 +1 @@
+/* Empty File */
\ No newline at end of file
