void BaseApplication::run()
{
    // Construct Ogre::Root
    // We handle our stuff manually, so don't want to use any of the files
    mRoot = new Root(
        /* plugins.cfg file*/	"",
        /* config file */ 		"",
        /* log file */ 			""
    );

    PathManager::init ();

    // Set render system
    //!todo do not hardcode render system

#ifdef _DEBUG
    mRoot->loadPlugin(PathManager::ogre_plugin_dir + "/RenderSystem_GL");
    RenderSystem* rs = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
#else
    mRoot->loadPlugin(PathManager::ogre_plugin_dir + "/RenderSystem_Direct3D9");
    RenderSystem* rs = mRoot->getRenderSystemByName("Direct3D9 Rendering Subsystem");
#endif
    mRoot->setRenderSystem(rs);

    // Fire up Ogre::Root
    mRoot->initialise(false);

    // Create a hidden background window to keep resources
    NameValuePairList params;
    params.insert(std::make_pair("hidden", "true"));
    RenderWindow *wnd = mRoot->createRenderWindow("InactiveHidden", 1, 1, false, &params);
    wnd->setActive(false);

    Ogre::ResourceGroupManager::getSingleton ().addResourceLocation ("./", "FileSystem");
    Ogre::ResourceGroupManager::getSingleton ().initialiseAllResourceGroups ();

    // Create input system
    //mInputManager = new InputManager();

    // Create the application window
    mWindow = new Window();
    mWindow->mListener = static_cast<WindowEventListener*>(this);
    //mWindow->mInputManager = mInputManager;
    mWindow->mWidth = 800;
    mWindow->mHeight = 600;
    mWindow->mFullscreen = false;
    mWindow->create();

    createScene();
    mRoot->addFrameListener(this);
}
//--------------------------------------------------------------------------------//
OSStatus WindowEventUtilities::_CarbonWindowHandler(EventHandlerCallRef nextHandler, EventRef event, void* wnd)
{
    OSStatus status = noErr;
    
    // Only events from our window should make it here
    // This ensures that our user data is our WindowRef
    RenderWindow* curWindow = (RenderWindow*)wnd;
    if(!curWindow) return eventNotHandledErr;
    
    //Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(curWindow),
        end = _msListeners.upper_bound(curWindow);
    
    // We only get called if a window event happens
    UInt32 eventKind = GetEventKind( event );
    
    LogManager* log = LogManager::getSingletonPtr();
    
    switch( eventKind )
    {
        case kEventWindowActivated:
            curWindow->setActive( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDeactivated:
            if( curWindow->isDeactivatedOnFocusChange() )
            {
                curWindow->setActive( false );
            }

            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);

            break;
        case kEventWindowShown:
        case kEventWindowExpanded:
            curWindow->setActive( true );
            curWindow->setVisible( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowHidden:
        case kEventWindowCollapsed:
            curWindow->setActive( false );
            curWindow->setVisible( false );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;            
        case kEventWindowDragCompleted:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowMoved(curWindow);
            break;
        case kEventWindowBoundsChanged:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowResized(curWindow);
            break;
        case kEventWindowClosed:
            curWindow->destroy();
            for( ; start != end; ++start )
				(start->second)->windowClosed(curWindow);
            break;
        default:
            status = eventNotHandledErr;
            break;
    }
    
    return status;
}
//--------------------------------------------------------------------------------//
LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (uMsg == WM_CREATE)
	{	// Store pointer to Win32Window in user data area
		SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)(((LPCREATESTRUCT)lParam)->lpCreateParams));
		return 0;
	}

	// look up window instance
	// note: it is possible to get a WM_SIZE before WM_CREATE
	RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
	if (!win)
		return DefWindowProc(hWnd, uMsg, wParam, lParam);

	//LogManager* log = LogManager::getSingletonPtr();
	//Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(win),
        end = _msListeners.upper_bound(win);

	switch( uMsg )
	{
	case WM_ACTIVATE:
	{
        bool active = (LOWORD(wParam) != WA_INACTIVE);
        if( active )
        {
		    win->setActive( true );
        }
        else
        {
            if( win->isDeactivatedOnFocusChange() )
            {
    		    win->setActive( false );
            }
        }

	    for( ; start != end; ++start )
		    (start->second)->windowFocusChange(win);
		break;
	}
	case WM_SYSKEYDOWN:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSKEYUP:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
		case VK_F10:
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSCHAR:
		// return zero to bypass defProc and signal we processed the message, unless it's an ALT-space
		if (wParam != VK_SPACE)
			return 0;
		break;
	case WM_ENTERSIZEMOVE:
		//log->logMessage("WM_ENTERSIZEMOVE");
		break;
	case WM_EXITSIZEMOVE:
		//log->logMessage("WM_EXITSIZEMOVE");
		break;
	case WM_MOVE:
		//log->logMessage("WM_MOVE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowMoved(win);
		break;
	case WM_DISPLAYCHANGE:
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_SIZE:
		//log->logMessage("WM_SIZE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_GETMINMAXINFO:
		// Prevent the window from going smaller than some minimu size
		((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
		((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
		break;
	case WM_CLOSE:
	{
		//log->logMessage("WM_CLOSE");
		bool close = true;
		for(index = start; index != end; ++index)
		{
			if (!(index->second)->windowClosing(win))
				close = false;
		}
		if (!close) return 0;

		for(index = _msListeners.lower_bound(win); index != end; ++index)
			(index->second)->windowClosed(win);
		win->destroy();
		return 0;
	}
	}

	return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
//--------------------------------------------------------------------------------//
void GLXProc( const XEvent &event )
{
	//We have to find appropriate window based on window id ( kindof hackish :/,
	//but at least this only happens when there is a Window's event - and not that often
	WindowEventUtilities::Windows::iterator i = WindowEventUtilities::_msWindows.begin(),
						e = WindowEventUtilities::_msWindows.end();
	RenderWindow* win = 0;
	for(; i != e; ++i )
	{
		std::size_t wind = 0;
		(*i)->getCustomAttribute("WINDOW", &wind);
		if( event.xany.window == wind )
		{
			win = *i;
			break;
		}
	}

	//Sometimes, seems we get other windows, so just ignore
	if( win == 0 ) return;

	//Now that we have the correct RenderWindow for the generated Event, get an iterator for the listeners
	WindowEventUtilities::WindowEventListeners::iterator 
		start = WindowEventUtilities::_msListeners.lower_bound(win),
		end   = WindowEventUtilities::_msListeners.upper_bound(win);

	switch(event.type)
	{
	case ClientMessage:
	{
		::Atom atom;
		win->getCustomAttribute("ATOM", &atom);
		if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)atom)
		{	//Window Closed (via X button)
			//Send message first, to allow app chance to unregister things that need done before
			//window is shutdown
			for( ; start != end; ++start )
				(start->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case ConfigureNotify:	//Moving or Resizing
		unsigned int width, height, depth;
		int left, top;
		win->getMetrics(width, height, depth, left, top);

		//determine if moving or sizing:
		if( left == event.xconfigure.x && top == event.xconfigure.y )
		{	//Resize width, height
			win->windowMovedOrResized();
			for( ; start != end; ++start )
				(start->second)->windowResized(win);
		}
		else if( width == event.xconfigure.width && height == event.xconfigure.height )
		{	//Moving x, y
			win->windowMovedOrResized();
			for( ; start != end; ++start )
				(start->second)->windowMoved(win);
		}
		break;
	case MapNotify:   //Restored
		win->setActive( true );
		for( ; start != end; ++start )
			(start->second)->windowFocusChange(win);
		break;
	case UnmapNotify: //Minimised
		win->setActive( false );
		win->setVisible( false );
		for( ; start != end; ++start )
			(start->second)->windowFocusChange(win);
		break;
	case VisibilityNotify:
		switch(event.xvisibility.state)
		{
		case VisibilityUnobscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityPartiallyObscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityFullyObscured:
			win->setActive( false );
			win->setVisible( false );
			break;
		}

		//Notify Listeners that focus of window has changed in some way
		for( ; start != end; ++start )
			(start->second)->windowFocusChange(win);
		break;
	default:
		break;
	} //End switch event.type
}