void Application::Terminate()
        {
            BOOST_ASSERT( m_IsInitialized == true );

            // Terminate the subsystems in the opposite order as they were registered.
            SubsystemList::reverse_iterator iter = m_Subsystems.rbegin();
            while ( iter != m_Subsystems.rend() )
            {
                SubsystemPtr subsystem = (*iter);
                subsystem->Terminate();

                ++iter;
            }

            m_Subsystems.clear();

            // Unload any previously loaded plug-ins
            PluginList plugins = m_Plugins;
            PluginList::iterator pluginIter = plugins.begin();
            while ( pluginIter != plugins.end() )
            {
                PluginPtr plugin = (*pluginIter);
                plugin->Terminate();

                UnloadPlugin( plugin );
                ++pluginIter;
            }

            plugins.clear();
            m_PluginsByName.clear();
            m_PluginsByFileName.clear();
            m_Plugins.clear();

            // Flush all the libraries.  At this point
            // there should be no residual pointers to objects
            // created in the library.
            m_DynamicLibSubsystem->Flush();

            m_IsInitialized = false;

            OnTerminated( EventArgs( *this ) );
        }
        void Application::UnloadPlugin( PluginPtr plugin )
        {
            if ( plugin )
            {
                RemovePlugin( plugin );

                plugin->Terminate();

                // Unload the DLL the plugin was loaded from.
                DynamicLibPtr ptrLib = m_DynamicLibSubsystem->GetLibrary( plugin->FileName );
                if ( ptrLib )
                {
                    DestroyPluginFP destroyPluginFunc = (DestroyPluginFP)ptrLib->GetSymbol( "DestroyPlugin" );
                    if ( destroyPluginFunc != NULL )
                    {
                        // Unload the plugin and all of the types that are associated with the plugin.
                        destroyPluginFunc();
                    }
                    else
                    {
                        std::cerr << "Application::UnloadPlugin: Could not find \"DestroyPlugin\" method in library \"";
                        std::wcerr << ptrLib->FileName.get();
                        std::cerr << "\"" << std::endl;
                    }
                    // Don't forget to call DynamicLibSubsystem::Flush to actually 
                    // release the libraries from memory.
                    m_DynamicLibSubsystem->Unload( ptrLib );
                }
                else
                {
                    std::cerr << "Application::UnloadPlugin: Could not find library with filename: \"";
                    std::wcerr << plugin->FileName.get();
                    std::cerr << "\"" << std::endl;
                }
            }
        }