+        wxLogError(_("Initialization failed in post init, aborting."));
+        return false;
+    }
+
+    return true;
+}
+
+bool wxEntryStart(int& argc, wxChar **argv)
+{
+    // do minimal, always necessary, initialization
+    // --------------------------------------------
+
+    // initialize wxRTTI
+    if ( !DoCommonPreInit() )
+    {
+        return false;
+    }
+
+
+    // first of all, we need an application object
+    // -------------------------------------------
+
+    // the user might have already created it himself somehow
+    wxAppPtr app(wxTheApp);
+    if ( !app.get() )
+    {
+        // if not, he might have used IMPLEMENT_APP() to give us a function to
+        // create it
+        wxAppInitializerFunction fnCreate = wxApp::GetInitializerFunction();
+
+        if ( fnCreate )
+        {
+            // he did, try to create the custom wxApp object
+            app.Set((*fnCreate)());
+        }
+    }
+
+    if ( !app.get() )
+    {
+        // either IMPLEMENT_APP() was not used at all or it failed -- in any
+        // case we still need something
+        app.Set(new wxDummyConsoleApp);
+    }
+
+
+    // wxApp initialization: this can be customized
+    // --------------------------------------------
+
+    if ( !app->Initialize(argc, argv) )
+    {
+        return false;
+    }
+
+    // remember, possibly modified (e.g. due to removal of toolkit-specific
+    // parameters), command line arguments in member variables
+    app->argc = argc;
+    app->argv = argv;
+
+
+    wxCallAppCleanup callAppCleanup(app.get());
+
+    // for compatibility call the old initialization function too
+    if ( !app->OnInitGui() )
+        return false;
+
+
+    // common initialization after wxTheApp creation
+    // ---------------------------------------------
+
+    if ( !DoCommonPostInit() )
+        return false;
+
+
+    // prevent the smart pointer from destroying its contents
+    app.release();
+
+    // and the cleanup object from doing cleanup
+    callAppCleanup.Dismiss();
+
+#if wxUSE_LOG
+    // now that we have a valid wxApp (wxLogGui would have crashed if we used
+    // it before now), we can delete the temporary sink we had created for the
+    // initialization messages -- the next time logging function is called, the
+    // sink will be recreated but this time wxAppTraits will be used
+    delete wxLog::SetActiveTarget(NULL);
+#endif // wxUSE_LOG
+
+    return true;
+}
+
+#if wxUSE_UNICODE
+
+// we provide a wxEntryStart() wrapper taking "char *" pointer too
+bool wxEntryStart(int& argc, char **argv)
+{
+    ConvertArgsToUnicode(argc, argv);
+
+    if ( !wxEntryStart(gs_initData.argc, gs_initData.argv) )
+    {
+        FreeConvertedArgs();
+
+        return false;
+    }
+
+    return true;
+}
+
+#endif // wxUSE_UNICODE
+
+// ----------------------------------------------------------------------------
+// clean up
+// ----------------------------------------------------------------------------
+
+// cleanup done before destroying wxTheApp
+static void DoCommonPreCleanup()
+{
+#if wxUSE_LOG
+    // flush the logged messages if any and install a 'safer' log target: the
+    // default one (wxLogGui) can't be used after the resources are freed just
+    // below and the user supplied one might be even more unsafe (using any
+    // wxWidgets GUI function is unsafe starting from now)
+    wxLog::DontCreateOnDemand();
+
+    // this will flush the old messages if any
+    delete wxLog::SetActiveTarget(new wxLogStderr);
+#endif // wxUSE_LOG
+}
+
+// cleanup done after destroying wxTheApp
+static void DoCommonPostCleanup()
+{
+    wxModule::CleanUpModules();
+
+    // we can't do this in wxApp itself because it doesn't know if argv had
+    // been allocated
+#if wxUSE_UNICODE
+    FreeConvertedArgs();
+#endif // wxUSE_UNICODE
+
+    // use Set(NULL) and not Get() to avoid creating a message output object on
+    // demand when we just want to delete it
+    delete wxMessageOutput::Set(NULL);
+
+#if wxUSE_LOG
+    // and now delete the last logger as well
+    delete wxLog::SetActiveTarget(NULL);
+#endif // wxUSE_LOG
+}
+
+void wxEntryCleanup()
+{
+    DoCommonPreCleanup();
+
+
+    // delete the application object
+    if ( wxTheApp )
+    {
+        wxTheApp->CleanUp();
+
+        // reset the global pointer to it to NULL before destroying it as in
+        // some circumstances this can result in executing the code using
+        // wxTheApp and using half-destroyed object is no good
+        wxAppConsole * const app = wxApp::GetInstance();
+        wxApp::SetInstance(NULL);
+        delete app;
+    }
+
+
+    DoCommonPostCleanup();
+}
+
+// ----------------------------------------------------------------------------
+// wxEntry
+// ----------------------------------------------------------------------------
+
+// for MSW the real wxEntry is defined in msw/main.cpp
+#ifndef __WXMSW__
+    #define wxEntryReal wxEntry
+#endif // !__WXMSW__
+
+int wxEntryReal(int& argc, wxChar **argv)
+{
+    // library initialization
+    if ( !wxEntryStart(argc, argv) )
+    {
+#if wxUSE_LOG
+        // flush any log messages explaining why we failed
+        delete wxLog::SetActiveTarget(NULL);
+#endif
+        return -1;