+static Eina_List *
+_eobj_class_mro_add(Eina_List *mro, const Eobj_Class *klass)
+{
+ Eina_List *extn_pos = NULL;
+ Eina_Bool check_consistency = !mro;
+ if (!klass)
+ return mro;
+
+ mro = eina_list_append(mro, klass);
+
+ /* Recursively add extenions. */
+ {
+ Eobj_Extension_Node *extn;
+ EINA_INLIST_FOREACH(klass->extensions, extn)
+ {
+ mro = _eobj_class_mro_add(mro, extn->klass);
+ if (!mro)
+ return NULL;
+
+ if (check_consistency)
+ {
+ extn_pos = eina_list_append(extn_pos, eina_list_last(mro));
+ }
+ }
+ }
+
+ /* Check if we can create a consistent mro. We only do it for the class
+ * we are working on (i.e no parents). */
+ if (check_consistency)
+ {
+ Eobj_Extension_Node *extn;
+
+ Eina_List *itr = extn_pos;
+ EINA_INLIST_FOREACH(klass->extensions, extn)
+ {
+ /* Get the first one after the extension. */
+ Eina_List *extn_list = eina_list_next(eina_list_data_get(itr));
+
+ /* If we found the extension again. */
+ if (eina_list_data_find_list(extn_list, extn->klass))
+ {
+ eina_list_free(mro);
+ ERR("Cannot create a consistent method resolution order for class '%s' because of '%s'.", klass->desc->name, extn->klass->desc->name);
+ return NULL;
+ }
+
+ itr = eina_list_next(itr);
+ }
+ }
+
+
+ mro = _eobj_class_mro_add(mro, klass->parent);
+
+ return mro;
+}
+
+static Eina_Bool
+_eobj_class_mro_init(Eobj_Class *klass)
+{
+ Eina_List *mro = NULL;
+
+ DBG("Started creating MRO for class '%s'", klass->desc->name);
+ mro = _eobj_class_mro_add(mro, klass);
+
+ if (!mro)
+ return EINA_FALSE;
+
+ /* Remove duplicates and make them the right order. */
+ {
+ Eina_List *itr1, *itr2, *itr2n;
+
+ itr1 = eina_list_last(mro);
+ while (itr1)
+ {
+ itr2 = eina_list_prev(itr1);
+
+ while (itr2)
+ {
+ itr2n = eina_list_prev(itr2);
+
+ if (eina_list_data_get(itr1) == eina_list_data_get(itr2))
+ {
+ mro = eina_list_remove_list(mro, itr2);
+ }
+
+ itr2 = itr2n;
+ }
+
+ itr1 = eina_list_prev(itr1);
+ }
+ }
+
+ /* Copy the mro and free the list. */
+ {
+ const Eobj_Class *kls_itr;
+ const Eobj_Class **mro_itr;
+ klass->mro = calloc(sizeof(*klass->mro), eina_list_count(mro) + 1);
+
+ mro_itr = klass->mro;
+
+ EINA_LIST_FREE(mro, kls_itr)
+ {
+ *(mro_itr++) = kls_itr;
+
+ DBG("Added '%s' to MRO", kls_itr->desc->name);
+ }
+ *(mro_itr) = NULL;
+ }
+
+ DBG("Finished creating MRO for class '%s'", klass->desc->name);
+
+ return EINA_TRUE;
+}
+