MonoObject* ScriptDropDownWindow::internal_CreateInstance(MonoString* ns, MonoString* typeName, 
		ScriptEditorWindow* parentWindow, Vector2I* position)
	{
		String strTypeName = MonoUtil::monoToString(typeName);
		String strNamespace = MonoUtil::monoToString(ns);
		String fullName = strNamespace + "." + strTypeName;

		MonoClass* windowClass = MonoManager::instance().findClass(strNamespace, strTypeName);
		if (windowClass == nullptr)
			return nullptr;

		MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY);

		MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize");
		if (defaultSizeAttrib == nullptr)
			BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed class.");

		MonoField* defaultWidthField = defaultSizeAttrib->getField("width");
		MonoField* defaultHeightField = defaultSizeAttrib->getField("height");

		int width = 200;
		int height = 200;

		MonoObject* defaultSizeObj = windowClass->getAttribute(defaultSizeAttrib);
		if (defaultSizeObj != nullptr)
		{
			defaultWidthField->get(defaultSizeObj, &width);
			defaultHeightField->get(defaultSizeObj, &height);
		}

		MonoObject* instance = windowClass->createInstance(false);

		ManagedDropDownWindow* dropDownWindow = nullptr;
		if (parentWindow != nullptr && !parentWindow->isDestroyed())
		{
			EditorWidgetBase* editorWidget = parentWindow->getEditorWidget();
			EditorWidgetContainer* parentContainer = editorWidget->_getParent();
			if (parentContainer != nullptr)
			{
				SPtr<RenderWindow> parentRenderWindow = parentContainer->getParentWindow()->getRenderWindow();
				SPtr<Camera> parentCamera = parentContainer->getParentWidget().getCamera();

				position->x += editorWidget->getX();
				position->y += editorWidget->getY();

				dropDownWindow = DropDownWindowManager::instance().open<ManagedDropDownWindow>(
					parentRenderWindow, parentCamera, *position, instance, width, height);
			}
		}

		ScriptDropDownWindow* nativeInstance = new (bs_alloc<ScriptDropDownWindow>()) ScriptDropDownWindow(dropDownWindow);

		if (dropDownWindow != nullptr)
			dropDownWindow->initialize(nativeInstance);

		windowClass->construct(instance);
		return instance;
	}
	void ScriptEditorWindow::registerManagedEditorWindows()
	{
		MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY);

		if(assembly != nullptr)
		{
			MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize");
			if (defaultSizeAttrib == nullptr)
				BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed attribute.");

			MonoField* defaultWidthField = defaultSizeAttrib->getField("width");
			MonoField* defaultHeightField = defaultSizeAttrib->getField("height");

			MonoClass* undoRedoLocalAttrib = assembly->getClass("BansheeEditor", "UndoRedoLocal");
			if (undoRedoLocalAttrib == nullptr)
				BS_EXCEPT(InternalErrorException, "Cannot find UndoRedoLocal managed attribute.");

			MonoClass* editorWindowClass = assembly->getClass("BansheeEditor", "EditorWindow");

			const Vector<MonoClass*>& allClasses = assembly->getAllClasses();
			for(auto& curClass : allClasses)
			{
				if(curClass->isSubClassOf(editorWindowClass) && curClass != editorWindowClass)
				{
					UINT32 width = 400;
					UINT32 height = 400;

					MonoObject* defaultSize = curClass->getAttribute(defaultSizeAttrib);
					if (defaultSize != nullptr)
					{
						defaultWidthField->get(defaultSize, &width);
						defaultHeightField->get(defaultSize, &height);
					}

					bool hasLocalUndoRedo = curClass->getAttribute(undoRedoLocalAttrib) != nullptr;

					const String& className = curClass->getFullName();
					EditorWidgetManager::instance().registerWidget(className, 
						std::bind(&ScriptEditorWindow::openEditorWidgetCallback, curClass->getNamespace(), 
						curClass->getTypeName(), width, height, hasLocalUndoRedo, _1));
					AvailableWindowTypes.push_back(className);
				}
			}
		}
	}