void MenuItemManager::reloadAssemblyData()
	{
		clearMenuItems();

		// Reload MenuItem attribute from editor assembly
		MonoAssembly* editorAssembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY);
		mMenuItemAttribute = editorAssembly->getClass(EDITOR_NS, "MenuItem");
		if (mMenuItemAttribute == nullptr)
			BS_EXCEPT(InvalidStateException, "Cannot find MenuItem managed class.");

		mPathField = mMenuItemAttribute->getField("path");
		mShortcutField = mMenuItemAttribute->getField("shortcut");
		mPriorityField = mMenuItemAttribute->getField("priority");
		mSeparatorField = mMenuItemAttribute->getField("separator");

		MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();

		Vector<String> scriptAssemblyNames = mScriptObjectManager.getScriptAssemblies();
		for (auto& assemblyName : scriptAssemblyNames)
		{
			MonoAssembly* assembly = MonoManager::instance().getAssembly(assemblyName);

			// Find new menu item methods
			const Vector<MonoClass*>& allClasses = assembly->getAllClasses();
			for (auto curClass : allClasses)
			{
				const Vector<MonoMethod*>& methods = curClass->getAllMethods();
				for (auto& curMethod : methods)
				{
					String path;
					ShortcutKey shortcutKey = ShortcutKey::NONE;
					INT32 priority = 0;
					bool separator = false;
					if (parseMenuItemMethod(curMethod, path, shortcutKey, priority, separator))
					{
						std::function<void()> callback = std::bind(&MenuItemManager::menuItemCallback, curMethod);

						if (separator)
						{
							Vector<String> pathElements = StringUtil::split(path, "/");
							String separatorPath;
							if (pathElements.size() > 1)
							{
								const String& lastElem = pathElements[pathElements.size() - 1];
								separatorPath = path;
								separatorPath.erase(path.size() - lastElem.size() - 1, lastElem.size() + 1);
							}

							GUIMenuItem* separatorItem = mainWindow->getMenuBar().addMenuItemSeparator(separatorPath, priority);
							mMenuItems.push_back(separatorItem);
						}

						GUIMenuItem* menuItem = mainWindow->getMenuBar().addMenuItem(path, callback, priority, shortcutKey);
						mMenuItems.push_back(menuItem);
					}
				}
			}
		}
	}
	void ScriptEditorApplication::internal_ToggleToolbarItem(MonoString* name, bool on)
	{
		String nativeName = MonoUtil::monoToString(name);

		MainEditorWindow* editorWindow = EditorWindowManager::instance().getMainWindow();
		editorWindow->getMenuBar().toggleToolbarButton(nativeName, on);
	}
	void MenuItemManager::clearMenuItems()
	{
		MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();

		UINT32 numItems = (UINT32)mMenuItems.size();
		Vector<bool> destroyedItems(numItems, false);

		// Remove leaf elements only to avoid deleting child menu items
		bool changesMade;
		do
		{
			changesMade = false;
			for (UINT32 i = 0; i < numItems; i++)
			{
				GUIMenuItem* menuItem = mMenuItems[i];
				if (!destroyedItems[i] && menuItem->getNumChildren() == 0)
				{
					mainWindow->getMenuBar().removeMenuItem(menuItem);

					destroyedItems[i] = true;
					changesMade = true;
				}
			}
		} while (changesMade);

		// Remove remaining items regardless (none of their children are our concern). But when running properly there 
		// should be no entries to remove at this step.
		for (UINT32 i = 0; i < numItems; i++)
		{
			GUIMenuItem* menuItem = mMenuItems[i];
			if (!destroyedItems[i])
				mainWindow->getMenuBar().removeMenuItem(menuItem);
		}

		mMenuItems.clear();
	}