]> git.lyx.org Git - lyx.git/blobdiff - src/LyX.cpp
* add PreBabelPreamble to Language definition (fixes #4786).
[lyx.git] / src / LyX.cpp
index 4e486c9d67da415df31143516c44ebec66898c56..7c2376f980082b8a8575c2f8b391fb01cafcd683 100644 (file)
@@ -4,10 +4,10 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Alfredo Braunstein
  * Licence details can be found in the file COPYING.
  *
  * \author Alfredo Braunstein
- * \author Lars Gullik Bjønnes
+ * \author Lars Gullik Bjønnes
  * \author Jean-Marc Lasgouttes
  * \author John Levon
  * \author Jean-Marc Lasgouttes
  * \author John Levon
- * \author André Pönitz
+ * \author André Pönitz
  *
  * Full author contact details are available in file CREDITS.
  */
  *
  * Full author contact details are available in file CREDITS.
  */
 
 #include "LyX.h"
 
 
 #include "LyX.h"
 
-#include "ConverterCache.h"
+#include "AppleSpellChecker.h"
+#include "AspellChecker.h"
 #include "Buffer.h"
 #include "Buffer.h"
-#include "buffer_funcs.h"
 #include "BufferList.h"
 #include "BufferList.h"
+#include "CmdDef.h"
+#include "ColorSet.h"
+#include "ConverterCache.h"
 #include "Converter.h"
 #include "Converter.h"
-#include "debug.h"
+#include "CutAndPaste.h"
+#include "EnchantChecker.h"
 #include "Encoding.h"
 #include "ErrorList.h"
 #include "Format.h"
 #include "Encoding.h"
 #include "ErrorList.h"
 #include "Format.h"
-#include "gettext.h"
-#include "kb_keymap.h"
+#include "FuncStatus.h"
+#include "HunspellChecker.h"
+#include "KeyMap.h"
 #include "Language.h"
 #include "Language.h"
-#include "Session.h"
-#include "LColor.h"
-#include "lyx_cb.h"
-#include "LyXAction.h"
-#include "LyXFunc.h"
+#include "LayoutFile.h"
 #include "Lexer.h"
 #include "Lexer.h"
+#include "LyX.h"
+#include "LyXAction.h"
 #include "LyXRC.h"
 #include "LyXRC.h"
-#include "LyXServer.h"
-#include "LyXServerSocket.h"
-#include "LyXTextClassList.h"
-#include "MenuBackend.h"
-#include "Messages.h"
+#include "ModuleList.h"
 #include "Mover.h"
 #include "Mover.h"
-#include "ToolbarBackend.h"
+#include "Server.h"
+#include "ServerSocket.h"
+#include "Session.h"
 
 
-#include "frontends/Alert.h"
+#include "frontends/alert.h"
 #include "frontends/Application.h"
 #include "frontends/Application.h"
-#include "frontends/Gui.h"
-#include "frontends/LyXView.h"
 
 
+#include "graphics/Previews.h"
+
+#include "support/lassert.h"
+#include "support/debug.h"
 #include "support/environment.h"
 #include "support/environment.h"
-#include "support/filetools.h"
-#include "support/lyxlib.h"
-#include "support/convert.h"
 #include "support/ExceptionMessage.h"
 #include "support/ExceptionMessage.h"
+#include "support/filetools.h"
+#include "support/gettext.h"
+#include "support/lstrings.h"
+#include "support/Messages.h"
 #include "support/os.h"
 #include "support/Package.h"
 #include "support/Path.h"
 #include "support/Systemcall.h"
 
 #include "support/os.h"
 #include "support/Package.h"
 #include "support/Path.h"
 #include "support/Systemcall.h"
 
-#include <boost/bind.hpp>
-#include <boost/filesystem/operations.hpp>
+#include "support/bind.h"
+#include <boost/scoped_ptr.hpp>
 
 
+#include <algorithm>
 #include <iostream>
 #include <csignal>
 #include <map>
 #include <iostream>
 #include <csignal>
 #include <map>
+#include <stdlib.h>
 #include <string>
 #include <vector>
 
 #include <string>
 #include <vector>
 
+using namespace std;
+using namespace lyx::support;
 
 namespace lyx {
 
 
 namespace lyx {
 
-using support::addName;
-using support::addPath;
-using support::bformat;
-using support::changeExtension;
-using support::createDirectory;
-using support::createLyXTmpDir;
-using support::destroyDir;
-using support::FileName;
-using support::fileSearch;
-using support::getEnv;
-using support::i18nLibFileSearch;
-using support::libFileSearch;
-using support::package;
-using support::prependEnvPath;
-using support::rtrim;
-using support::Systemcall;
-
 namespace Alert = frontend::Alert;
 namespace os = support::os;
 namespace Alert = frontend::Alert;
 namespace os = support::os;
-namespace fs = boost::filesystem;
-
-using std::endl;
-using std::for_each;
-using std::map;
-using std::make_pair;
-using std::string;
-using std::vector;
-
-#ifndef CXX_GLOBAL_CSTD
-using std::exit;
-using std::signal;
-using std::system;
-#endif
 
 
 
 
-/// are we using the GUI at all?
-/** 
-* We default to true and this is changed to false when the export feature is used.
-*/
+
+// Are we using the GUI at all?  We default to true and this is changed
+// to false when the export feature is used.
+
 bool use_gui = true;
 
 
 bool use_gui = true;
 
 
+// We default to open documents in an already running instance, provided that
+// the lyxpipe has been setup. This can be overridden either on the command
+// line or through preference settings.
+
+RunMode run_mode = PREFERRED;
+
+
+// Tell what files can be silently overwritten during batch export.
+// Possible values are: NO_FILES, MAIN_FILE, ALL_FILES, UNSPECIFIED.
+// Unless specified on command line (through the -f switch) or through the
+// environment variable LYX_FORCE_OVERWRITE, the default will be MAIN_FILE.
+
+OverwriteFiles force_overwrite = UNSPECIFIED;
+
+
 namespace {
 
 // Filled with the command line arguments "foo" of "-sysdir foo" or
 namespace {
 
 // Filled with the command line arguments "foo" of "-sysdir foo" or
@@ -120,7 +112,7 @@ namespace {
 string cl_system_support;
 string cl_user_support;
 
 string cl_system_support;
 string cl_user_support;
 
-std::string geometryArg;
+string geometryArg;
 
 LyX * singleton_ = 0;
 
 
 LyX * singleton_ = 0;
 
@@ -137,7 +129,7 @@ void reconfigureUserLyXDir()
        string const configure_command = package().configure_command();
 
        lyxerr << to_utf8(_("LyX: reconfiguring user directory")) << endl;
        string const configure_command = package().configure_command();
 
        lyxerr << to_utf8(_("LyX: reconfiguring user directory")) << endl;
-       support::Path p(package().user_support());
+       PathChanger p(package().user_support());
        Systemcall one;
        one.startscript(Systemcall::Wait, configure_command);
        lyxerr << "LyX: " << to_utf8(_("Done!")) << endl;
        Systemcall one;
        one.startscript(Systemcall::Wait, configure_command);
        lyxerr << "LyX: " << to_utf8(_("Done!")) << endl;
@@ -145,34 +137,42 @@ void reconfigureUserLyXDir()
 
 } // namespace anon
 
 
 } // namespace anon
 
-
 /// The main application class private implementation.
 /// The main application class private implementation.
-struct LyX::Singletons 
+struct LyX::Impl
 {
 {
-       Singletons()
+       Impl() : spell_checker_(0), apple_spell_checker_(0), aspell_checker_(0), enchant_checker_(0), hunspell_checker_(0)
        {
                // Set the default User Interface language as soon as possible.
                // The language used will be derived from the environment
                // variables.
                messages_["GUI"] = Messages();
        }
        {
                // Set the default User Interface language as soon as possible.
                // The language used will be derived from the environment
                // variables.
                messages_["GUI"] = Messages();
        }
-       /// our function handler
-       LyXFunc lyxfunc_;
+
+       ~Impl()
+       {
+               delete apple_spell_checker_;
+               delete aspell_checker_;
+               delete enchant_checker_;
+               delete hunspell_checker_;
+       }
+
        ///
        BufferList buffer_list_;
        ///
        ///
        BufferList buffer_list_;
        ///
-       boost::scoped_ptr<kb_keymap> toplevel_keymap_;
+       KeyMap toplevel_keymap_;
        ///
        ///
-       boost::scoped_ptr<LyXServer> lyx_server_;
+       CmdDef toplevel_cmddef_;
        ///
        ///
-       boost::scoped_ptr<LyXServerSocket> lyx_socket_;
+       boost::scoped_ptr<Server> lyx_server_;
+       ///
+       boost::scoped_ptr<ServerSocket> lyx_socket_;
        ///
        boost::scoped_ptr<frontend::Application> application_;
        /// lyx session, containing lastfiles, lastfilepos, and lastopened
        boost::scoped_ptr<Session> session_;
 
        /// Files to load at start.
        ///
        boost::scoped_ptr<frontend::Application> application_;
        /// lyx session, containing lastfiles, lastfilepos, and lastopened
        boost::scoped_ptr<Session> session_;
 
        /// Files to load at start.
-       vector<FileName> files_to_load_;
+       vector<string> files_to_load_;
 
        /// The messages translators.
        map<string, Messages> messages_;
 
        /// The messages translators.
        map<string, Messages> messages_;
@@ -182,12 +182,29 @@ struct LyX::Singletons
 
        // The system converters copy after reading lyxrc.defaults.
        Converters system_converters_;
 
        // The system converters copy after reading lyxrc.defaults.
        Converters system_converters_;
-       
+
        ///
        Movers movers_;
        ///
        Movers movers_;
-       
        ///
        Movers system_movers_;
        ///
        Movers system_movers_;
+
+       /// has this user started lyx for the first time?
+       bool first_start;
+       /// the parsed command line batch command if any
+       vector<string> batch_commands;
+
+       ///
+       graphics::Previews preview_;
+       ///
+       SpellChecker * spell_checker_;
+       ///
+       SpellChecker * apple_spell_checker_;
+       ///
+       SpellChecker * aspell_checker_;
+       ///
+       SpellChecker * enchant_checker_;
+       ///
+       SpellChecker * hunspell_checker_;
 };
 
 ///
 };
 
 ///
@@ -202,20 +219,28 @@ frontend::Application * theApp()
 
 LyX::~LyX()
 {
 
 LyX::~LyX()
 {
+       delete pimpl_;
+       singleton_ = 0;
 }
 
 
 }
 
 
-LyX & LyX::ref()
+void lyx_exit(int exit_code)
 {
 {
-       BOOST_ASSERT(singleton_);
-       return *singleton_;
-}
+       if (exit_code)
+               // Something wrong happened so better save everything, just in
+               // case.
+               emergencyCleanup();
 
 
+#ifndef NDEBUG
+       // Properly crash in debug mode in order to get a useful backtrace.
+       abort();
+#endif
 
 
-LyX const & LyX::cref()
-{
-       BOOST_ASSERT(singleton_);
-       return *singleton_;
+       // In release mode, try to exit gracefully.
+       if (theApp())
+               theApp()->exit(exit_code);
+       else
+               exit(exit_code);
 }
 
 
 }
 
 
@@ -223,180 +248,77 @@ LyX::LyX()
        : first_start(false)
 {
        singleton_ = this;
        : first_start(false)
 {
        singleton_ = this;
-       pimpl_.reset(new Singletons);
-}
-
-
-BufferList & LyX::bufferList()
-{
-       return pimpl_->buffer_list_;
-}
-
-
-BufferList const & LyX::bufferList() const
-{
-       return pimpl_->buffer_list_;
-}
-
-
-Session & LyX::session()
-{
-       BOOST_ASSERT(pimpl_->session_.get());
-       return *pimpl_->session_.get();
-}
-
-
-Session const & LyX::session() const
-{
-       BOOST_ASSERT(pimpl_->session_.get());
-       return *pimpl_->session_.get();
-}
-
-
-LyXFunc & LyX::lyxFunc()
-{
-       return pimpl_->lyxfunc_;
-}
-
-
-LyXFunc const & LyX::lyxFunc() const
-{
-       return pimpl_->lyxfunc_;
-}
-
-
-LyXServer & LyX::server()
-{
-       BOOST_ASSERT(pimpl_->lyx_server_.get());
-       return *pimpl_->lyx_server_.get(); 
-}
-
-
-LyXServer const & LyX::server() const 
-{
-       BOOST_ASSERT(pimpl_->lyx_server_.get());
-       return *pimpl_->lyx_server_.get(); 
-}
-
-
-LyXServerSocket & LyX::socket()
-{
-       BOOST_ASSERT(pimpl_->lyx_socket_.get());
-       return *pimpl_->lyx_socket_.get();
-}
-
-
-LyXServerSocket const & LyX::socket() const
-{
-       BOOST_ASSERT(pimpl_->lyx_socket_.get());
-       return *pimpl_->lyx_socket_.get();
-}
-
-
-frontend::Application & LyX::application()
-{
-       BOOST_ASSERT(pimpl_->application_.get());
-       return *pimpl_->application_.get();
-}
-
-
-frontend::Application const & LyX::application() const
-{
-       BOOST_ASSERT(pimpl_->application_.get());
-       return *pimpl_->application_.get();
+       pimpl_ = new Impl;
 }
 
 
 }
 
 
-kb_keymap & LyX::topLevelKeymap()
-{
-       BOOST_ASSERT(pimpl_->toplevel_keymap_.get());
-       return *pimpl_->toplevel_keymap_.get();
-}
-
-
-Converters & LyX::converters()
-{
-       return pimpl_->converters_;
-}
-
-
-Converters & LyX::systemConverters()
-{
-       return pimpl_->system_converters_;
-}
-
-
-kb_keymap const & LyX::topLevelKeymap() const
-{
-       BOOST_ASSERT(pimpl_->toplevel_keymap_.get());
-       return *pimpl_->toplevel_keymap_.get();
-}
-
-
-Messages & LyX::getMessages(std::string const & language)
+Messages & LyX::messages(string const & language)
 {
        map<string, Messages>::iterator it = pimpl_->messages_.find(language);
 
        if (it != pimpl_->messages_.end())
                return it->second;
 
 {
        map<string, Messages>::iterator it = pimpl_->messages_.find(language);
 
        if (it != pimpl_->messages_.end())
                return it->second;
 
-       std::pair<map<string, Messages>::iterator, bool> result = 
-                       pimpl_->messages_.insert(std::make_pair(language, Messages(language)));
+       pair<map<string, Messages>::iterator, bool> result =
+                       pimpl_->messages_.insert(make_pair(language, Messages(language)));
 
 
-       BOOST_ASSERT(result.second);
+       LASSERT(result.second, /**/);
        return result.first->second;
 }
 
 
        return result.first->second;
 }
 
 
-Messages & LyX::getGuiMessages()
-{
-       return pimpl_->messages_["GUI"];
-}
-
-
-void LyX::setGuiLanguage(std::string const & language)
+void setRcGuiLanguage()
 {
 {
-       pimpl_->messages_["GUI"] = Messages(language);
-}
-
-
-Buffer const * const LyX::updateInset(InsetBase const * inset) const
-{
-       if (!inset)
-               return 0;
-
-       Buffer const * buffer_ptr = 0;
-       vector<int> const & view_ids = pimpl_->application_->gui().viewIds();
-       vector<int>::const_iterator it = view_ids.begin();
-       vector<int>::const_iterator const end = view_ids.end();
-       for (; it != end; ++it) {
-               Buffer const * ptr =
-                       pimpl_->application_->gui().view(*it).updateInset(inset);
-               if (ptr)
-                       buffer_ptr = ptr;
+       LASSERT(singleton_, /**/);
+       if (lyxrc.gui_language == "auto")
+               return;
+       Language const * language = languages.getLanguage(lyxrc.gui_language);
+       if (language) {
+               LYXERR(Debug::LOCALE, "Setting LANGUAGE to " << language->code());
+               if (!setEnv("LANGUAGE", language->code()))
+                       LYXERR(Debug::LOCALE, "\t... failed!");
        }
        }
-       return buffer_ptr;
+       LYXERR(Debug::LOCALE, "Setting LC_ALL to en_US");
+       if (!setEnv("LC_ALL", "en_US"))
+               LYXERR(Debug::LOCALE, "\t... failed!");
+       Messages::init();
+       singleton_->pimpl_->messages_["GUI"] = Messages();
 }
 
 
 int LyX::exec(int & argc, char * argv[])
 {
 }
 
 
 int LyX::exec(int & argc, char * argv[])
 {
+       // Minimal setting of locale before parsing command line
+       try {
+               init_package(os::utf8_argv(0), string(), string(),
+                       top_build_dir_is_one_level_up);
+       } catch (ExceptionMessage const & message) {
+               LYXERR(Debug::LOCALE, message.title_ + ", " + message.details_);
+       }
+       // FIXME: This breaks out of source build under Windows.
+       locale_init();
+
        // Here we need to parse the command line. At least
        // we need to parse for "-dbg" and "-help"
        easyParse(argc, argv);
 
        // Here we need to parse the command line. At least
        // we need to parse for "-dbg" and "-help"
        easyParse(argc, argv);
 
-       try { support::init_package(to_utf8(from_local8bit(argv[0])),
-                             cl_system_support, cl_user_support,
-                             support::top_build_dir_is_one_level_up);
-       } catch (support::ExceptionMessage const & message) {
-               if (message.type_ == support::ErrorException) {
+       try {
+               init_package(os::utf8_argv(0),
+                       cl_system_support, cl_user_support,
+                       top_build_dir_is_one_level_up);
+       } catch (ExceptionMessage const & message) {
+               if (message.type_ == ErrorException) {
                        Alert::error(message.title_, message.details_);
                        Alert::error(message.title_, message.details_);
-                       exit(1);
-               } else if (message.type_ == support::WarningException) {
+                       lyx_exit(1);
+               } else if (message.type_ == WarningException) {
                        Alert::warning(message.title_, message.details_);
                }
        }
 
                        Alert::warning(message.title_, message.details_);
                }
        }
 
+       // Reinit the messages machinery in case package() knows
+       // something interesting about the locale directory.
+       Messages::init();
+
        if (!use_gui) {
                // FIXME: create a ConsoleApplication
                int exit_status = init(argc, argv);
        if (!use_gui) {
                // FIXME: create a ConsoleApplication
                int exit_status = init(argc, argv);
@@ -405,34 +327,40 @@ int LyX::exec(int & argc, char * argv[])
                        return exit_status;
                }
 
                        return exit_status;
                }
 
-               loadFiles();
+               // this is correct, since return values are inverted.
+               exit_status = !loadFiles();
 
 
-               if (batch_command.empty() || pimpl_->buffer_list_.empty()) {
+               if (pimpl_->batch_commands.empty() || pimpl_->buffer_list_.empty()) {
                        prepareExit();
                        prepareExit();
-                       return EXIT_SUCCESS;
+                       return exit_status;
                }
 
                BufferList::iterator begin = pimpl_->buffer_list_.begin();
                }
 
                BufferList::iterator begin = pimpl_->buffer_list_.begin();
-               BufferList::iterator end = pimpl_->buffer_list_.end();
 
                bool final_success = false;
 
                bool final_success = false;
-               for (BufferList::iterator I = begin; I != end; ++I) {
+               for (BufferList::iterator I = begin; I != pimpl_->buffer_list_.end(); ++I) {
                        Buffer * buf = *I;
                        Buffer * buf = *I;
-                       bool success = false;
-                       buf->dispatch(batch_command, &success);
-                       final_success |= success;                       
+                       if (buf != buf->masterBuffer())
+                               continue;
+                       vector<string>::const_iterator bcit  = pimpl_->batch_commands.begin();
+                       vector<string>::const_iterator bcend = pimpl_->batch_commands.end();
+                       DispatchResult dr;
+                       for (; bcit != bcend; bcit++) {
+                               LYXERR(Debug::ACTION, "Buffer::dispatch: cmd: " << *bcit);
+                               buf->dispatch(*bcit, dr);
+                               final_success |= !dr.error();
+                       }
                }
                prepareExit();
                return !final_success;
        }
 
                }
                prepareExit();
                return !final_success;
        }
 
-       // Force adding of font path _before_ Application is initialized
-       support::os::addFontResources();
-
        // Let the frontend parse and remove all arguments that it knows
        pimpl_->application_.reset(createApplication(argc, argv));
 
        // Let the frontend parse and remove all arguments that it knows
        pimpl_->application_.reset(createApplication(argc, argv));
 
-       initGuiFont();
+       // Reestablish our defaults, as Qt overwrites them
+       // after createApplication()
+       locale_init();
 
        // Parse and remove all known arguments in the LyX singleton
        // Give an error for all remaining ones.
 
        // Parse and remove all known arguments in the LyX singleton
        // Give an error for all remaining ones.
@@ -445,26 +373,38 @@ int LyX::exec(int & argc, char * argv[])
                return exit_status;
        }
 
                return exit_status;
        }
 
+       // If not otherwise specified by a command line option or
+       // by preferences, we default to reuse a running instance.
+       if (run_mode == PREFERRED)
+               run_mode = USE_REMOTE;
+
        // FIXME
        /* Create a CoreApplication class that will provide the main event loop
        * and the socket callback registering. With Qt4, only QtCore
        * library would be needed.
        * When this is done, a server_mode could be created and the following two
        * line would be moved out from here.
        // FIXME
        /* Create a CoreApplication class that will provide the main event loop
        * and the socket callback registering. With Qt4, only QtCore
        * library would be needed.
        * When this is done, a server_mode could be created and the following two
        * line would be moved out from here.
+       * However, note that the first of the two lines below triggers the
+       * "single instance" behavior, which should occur right at this point.
        */
        // Note: socket callback must be registered after init(argc, argv)
        // such that package().temp_dir() is properly initialized.
        */
        // Note: socket callback must be registered after init(argc, argv)
        // such that package().temp_dir() is properly initialized.
-       pimpl_->lyx_server_.reset(new LyXServer(&pimpl_->lyxfunc_, lyxrc.lyxpipes));
-       pimpl_->lyx_socket_.reset(new LyXServerSocket(&pimpl_->lyxfunc_, 
-                       FileName(package().temp_dir().absFilename() + "/lyxsocket")));
+       pimpl_->lyx_server_.reset(new Server(lyxrc.lyxpipes));
+       pimpl_->lyx_socket_.reset(new ServerSocket(
+                       FileName(package().temp_dir().absFileName() + "/lyxsocket")));
 
        // Start the real execution loop.
 
        // Start the real execution loop.
-       exit_status = pimpl_->application_->exec();
-       
-       prepareExit();
+       if (!theServer().deferredLoadingToOtherInstance())
+               exit_status = pimpl_->application_->exec();
+       else if (!pimpl_->files_to_load_.empty()) {
+               vector<string>::const_iterator it = pimpl_->files_to_load_.begin();
+               vector<string>::const_iterator end = pimpl_->files_to_load_.end();
+               lyxerr << _("The following files could not be loaded:") << endl;
+               for (; it != end; ++it)
+                       lyxerr << *it << endl;
+       }
 
 
-       // Restore original font resources after Application is destroyed.
-       support::os::restoreFontResources();
+       prepareExit();
 
        return exit_status;
 }
 
        return exit_status;
 }
@@ -472,26 +412,17 @@ int LyX::exec(int & argc, char * argv[])
 
 void LyX::prepareExit()
 {
 
 void LyX::prepareExit()
 {
-       // Set a flag that we do quitting from the program,
-       // so no refreshes are necessary.
-       quitting = true;
+       // Clear the clipboard and selection stack:
+       cap::clearCutStack();
+       cap::clearSelection();
+
+       // Write the index file of the converter cache
+       ConverterCache::get().writeIndex();
 
        // close buffers first
        pimpl_->buffer_list_.closeAll();
 
 
        // close buffers first
        pimpl_->buffer_list_.closeAll();
 
-       // do any other cleanup procedures now
-       if (package().temp_dir() != package().system_temp_dir()) {
-               LYXERR(Debug::INFO) << "Deleting tmp dir "
-                                   << package().temp_dir().absFilename() << endl;
-
-               if (!destroyDir(package().temp_dir())) {
-                       docstring const msg =
-                               bformat(_("Unable to remove the temporary directory %1$s"),
-                               from_utf8(package().temp_dir().absFilename()));
-                       Alert::warning(_("Unable to remove temporary directory"), msg);
-               }
-       }
-
+       // register session changes and shutdown server and socket
        if (use_gui) {
                if (pimpl_->session_)
                        pimpl_->session_->writeFile();
        if (use_gui) {
                if (pimpl_->session_)
                        pimpl_->session_->writeFile();
@@ -500,6 +431,26 @@ void LyX::prepareExit()
                pimpl_->lyx_socket_.reset();
        }
 
                pimpl_->lyx_socket_.reset();
        }
 
+       // do any other cleanup procedures now
+       if (package().temp_dir() != package().system_temp_dir()) {
+               string const abs_tmpdir = package().temp_dir().absFileName();
+               if (!contains(package().temp_dir().absFileName(), "lyx_tmpdir")) {
+                       docstring const msg =
+                               bformat(_("%1$s does not appear like a LyX created temporary directory."),
+                               from_utf8(abs_tmpdir));
+                       Alert::warning(_("Cannot remove temporary directory"), msg);
+               } else {
+                       LYXERR(Debug::INFO, "Deleting tmp dir "
+                               << package().temp_dir().absFileName());
+                       if (!package().temp_dir().destroyDirectory()) {
+                               docstring const msg =
+                                       bformat(_("Unable to remove the temporary directory %1$s"),
+                                       from_utf8(package().temp_dir().absFileName()));
+                               Alert::warning(_("Unable to remove temporary directory"), msg);
+                       }
+               }
+       }
+
        // Kill the application object before exiting. This avoids crashes
        // when exiting on Linux.
        if (pimpl_->application_)
        // Kill the application object before exiting. This avoids crashes
        // when exiting on Linux.
        if (pimpl_->application_)
@@ -509,7 +460,7 @@ void LyX::prepareExit()
 
 void LyX::earlyExit(int status)
 {
 
 void LyX::earlyExit(int status)
 {
-       BOOST_ASSERT(pimpl_->application_.get());
+       LASSERT(pimpl_->application_.get(), /**/);
        // LyX::pimpl_::application_ is not initialised at this
        // point so it's safe to just exit after some cleanup.
        prepareExit();
        // LyX::pimpl_::application_ is not initialised at this
        // point so it's safe to just exit after some cleanup.
        prepareExit();
@@ -525,161 +476,130 @@ int LyX::init(int & argc, char * argv[])
                if (argv[argi][0] == '-') {
                        lyxerr << to_utf8(
                                bformat(_("Wrong command line option `%1$s'. Exiting."),
                if (argv[argi][0] == '-') {
                        lyxerr << to_utf8(
                                bformat(_("Wrong command line option `%1$s'. Exiting."),
-                               from_utf8(argv[argi]))) << endl;
+                               from_utf8(os::utf8_argv(argi)))) << endl;
                        return EXIT_FAILURE;
                }
        }
 
        // Initialization of LyX (reads lyxrc and more)
                        return EXIT_FAILURE;
                }
        }
 
        // Initialization of LyX (reads lyxrc and more)
-       LYXERR(Debug::INIT) << "Initializing LyX::init..." << endl;
+       LYXERR(Debug::INIT, "Initializing LyX::init...");
        bool success = init();
        bool success = init();
-       LYXERR(Debug::INIT) << "Initializing LyX::init...done" << endl;
+       LYXERR(Debug::INIT, "Initializing LyX::init...done");
        if (!success)
                return EXIT_FAILURE;
 
        if (!success)
                return EXIT_FAILURE;
 
-       for (int argi = argc - 1; argi >= 1; --argi) {
-               // get absolute path of file and add ".lyx" to
-               // the filename if necessary
-               pimpl_->files_to_load_.push_back(fileSearch(string(),
-                       os::internal_path(to_utf8(from_local8bit(argv[argi]))),
-                       "lyx", support::allow_unreadable));
-       }
+       // Remaining arguments are assumed to be files to load.
+       for (int argi = 1; argi < argc; ++argi)
+               pimpl_->files_to_load_.push_back(os::utf8_argv(argi));
 
 
-       if (first_start)
-               pimpl_->files_to_load_.push_back(i18nLibFileSearch("examples", "splash.lyx"));
+       if (first_start) {
+               pimpl_->files_to_load_.push_back(
+                       i18nLibFileSearch("examples", "splash.lyx").absFileName());
+       }
 
        return EXIT_SUCCESS;
 }
 
 
 
        return EXIT_SUCCESS;
 }
 
 
-void LyX::loadFiles()
+bool LyX::loadFiles()
 {
 {
-       vector<FileName>::const_iterator it = pimpl_->files_to_load_.begin();
-       vector<FileName>::const_iterator end = pimpl_->files_to_load_.end();
+       LASSERT(!use_gui, /**/);
+       bool success = true;
+       vector<string>::const_iterator it = pimpl_->files_to_load_.begin();
+       vector<string>::const_iterator end = pimpl_->files_to_load_.end();
 
        for (; it != end; ++it) {
 
        for (; it != end; ++it) {
-               if (it->empty())
+               // get absolute path of file and add ".lyx" to
+               // the filename if necessary
+               FileName fname = fileSearch(string(), os::internal_path(*it), "lyx",
+                       may_not_exist);
+
+               if (fname.empty())
                        continue;
 
                        continue;
 
-               Buffer * buf = pimpl_->buffer_list_.newBuffer(it->absFilename(), false);
-               if (loadLyXFile(buf, *it)) {
+               Buffer * buf = pimpl_->buffer_list_.newBuffer(fname.absFileName(), false);
+               if (buf->loadLyXFile() == Buffer::ReadSuccess) {
                        ErrorList const & el = buf->errorList("Parse");
                        if (!el.empty())
                                for_each(el.begin(), el.end(),
                        ErrorList const & el = buf->errorList("Parse");
                        if (!el.empty())
                                for_each(el.begin(), el.end(),
-                               boost::bind(&LyX::printError, this, _1));
+                               bind(&LyX::printError, this, _1));
                }
                }
-               else
+               else {
                        pimpl_->buffer_list_.release(buf);
                        pimpl_->buffer_list_.release(buf);
+                       success = false;
+               }
        }
        }
+       return success;
+}
+
+
+void execBatchCommands()
+{
+       LASSERT(singleton_, /**/);
+       singleton_->execCommands();
 }
 
 
 }
 
 
-void LyX::execBatchCommands()
+void LyX::execCommands()
 {
        // The advantage of doing this here is that the event loop
        // is already started. So any need for interaction will be
        // aknowledged.
 {
        // The advantage of doing this here is that the event loop
        // is already started. So any need for interaction will be
        // aknowledged.
-       restoreGuiSession();
-
-       // Execute batch commands if available
-       if (batch_command.empty())
-               return;
-
-       LYXERR(Debug::INIT) << "About to handle -x '"
-               << batch_command << '\'' << endl;
-
-       pimpl_->lyxfunc_.dispatch(lyxaction.lookupFunc(batch_command));
-}
 
 
+       // if reconfiguration is needed.
+       if (LayoutFileList::get().empty()) {
+               switch (Alert::prompt(
+                       _("No textclass is found"),
+                       _("LyX will only have minimal functionality because no textclasses "
+                               "have been found. You can either try to reconfigure LyX normally, "
+                               "try to reconfigure using only the defaults, or continue."),
+                       0, 2,
+                       _("&Reconfigure"),
+                       _("&Use Defaults"),
+                       _("&Continue")))
+               {
+               case 0:
+                       // regular reconfigure
+                       lyx::dispatch(FuncRequest(LFUN_RECONFIGURE, ""));
+                       break;
+               case 1:
+                       // reconfigure --without-latex-config
+                       lyx::dispatch(FuncRequest(LFUN_RECONFIGURE,
+                               " --without-latex-config"));
+                       break;
+               default:
+                       break;
+               }
+       }
 
 
-void LyX::restoreGuiSession()
-{
-       LyXView * view = newLyXView();
+       // create the first main window
+       lyx::dispatch(FuncRequest(LFUN_WINDOW_NEW, geometryArg));
 
 
-       // if some files were specified at command-line we assume that the
-       // user wants to edit *these* files and not to restore the session.
        if (!pimpl_->files_to_load_.empty()) {
        if (!pimpl_->files_to_load_.empty()) {
-               for_each(pimpl_->files_to_load_.begin(),
-                       pimpl_->files_to_load_.end(),
-                       bind(&LyXView::loadLyXFile, view, _1, true));
+               // if some files were specified at command-line we assume that the
+               // user wants to edit *these* files and not to restore the session.
+               for (size_t i = 0; i != pimpl_->files_to_load_.size(); ++i) {
+                       lyx::dispatch(
+                               FuncRequest(LFUN_FILE_OPEN, pimpl_->files_to_load_[i]));
+               }
                // clear this list to save a few bytes of RAM
                pimpl_->files_to_load_.clear();
                // clear this list to save a few bytes of RAM
                pimpl_->files_to_load_.clear();
-               pimpl_->session_->lastOpened().clear();
-               return;
-       }
+       } else
+               pimpl_->application_->restoreGuiSession();
 
 
-       if (!lyxrc.load_session)
+       // Execute batch commands if available
+       if (pimpl_->batch_commands.empty())
                return;
 
                return;
 
-       vector<FileName> const & lastopened = pimpl_->session_->lastOpened().getfiles();
-       // do not add to the lastfile list since these files are restored from
-       // last session, and should be already there (regular files), or should
-       // not be added at all (help files).
-       for_each(lastopened.begin(), lastopened.end(),
-               bind(&LyXView::loadLyXFile, view, _1, false));
-
-       // clear this list to save a few bytes of RAM
-       pimpl_->session_->lastOpened().clear();
-}
-
-
-LyXView * LyX::newLyXView()
-{
-       if (!lyx::use_gui)
-               return 0;
-
-       // determine windows size and position, from lyxrc and/or session
-       // initial geometry
-       unsigned int width = 690;
-       unsigned int height = 510;
-       // default icon size, will be overwritten by  stored session value
-       unsigned int iconSizeXY = 0;
-       int maximized = LyXView::NotMaximized;
-       // first try lyxrc
-       if (lyxrc.geometry_width != 0 && lyxrc.geometry_height != 0 ) {
-               width = lyxrc.geometry_width;
-               height = lyxrc.geometry_height;
-       }
-       // if lyxrc returns (0,0), then use session info
-       else {
-               string val = session().sessionInfo().load("WindowWidth");
-               if (!val.empty())
-                       width = convert<unsigned int>(val);
-               val = session().sessionInfo().load("WindowHeight");
-               if (!val.empty())
-                       height = convert<unsigned int>(val);
-               val = session().sessionInfo().load("WindowMaximized");
-               if (!val.empty())
-                       maximized = convert<int>(val);
-               val = session().sessionInfo().load("IconSizeXY");
-               if (!val.empty())
-                       iconSizeXY = convert<unsigned int>(val);
-       }
-
-       // if user wants to restore window position
-       int posx = -1;
-       int posy = -1;
-       if (lyxrc.geometry_xysaved) {
-               string val = session().sessionInfo().load("WindowPosX");
-               if (!val.empty())
-                       posx = convert<int>(val);
-               val = session().sessionInfo().load("WindowPosY");
-               if (!val.empty())
-                       posy = convert<int>(val);
-       }
-
-       if (!geometryArg.empty()) 
-       {
-               width = 0;
-               height = 0;
+       vector<string>::const_iterator bcit  = pimpl_->batch_commands.begin();
+       vector<string>::const_iterator bcend = pimpl_->batch_commands.end();
+       for (; bcit != bcend; bcit++) {
+               LYXERR(Debug::INIT, "About to handle -x '" << *bcit << '\'');
+               lyx::dispatch(lyxaction.lookupFunc(*bcit));
        }
        }
-
-       // create the main window
-       LyXView * view = &pimpl_->application_->createView(width, height, posx, posy, maximized, iconSizeXY, geometryArg);
-
-       return view;
 }
 
 }
 
+
 /*
 Signals and Windows
 ===================
 /*
 Signals and Windows
 ===================
@@ -687,7 +607,7 @@ The SIGHUP signal does not exist on Windows and does not need to be handled.
 
 Windows handles SIGFPE and SIGSEGV signals as expected.
 
 
 Windows handles SIGFPE and SIGSEGV signals as expected.
 
-Cntl+C interrupts (mapped to SIGINT by Windows' POSIX compatability layer)
+Ctrl+C interrupts (mapped to SIGINT by Windows' POSIX compatability layer)
 cause a new thread to be spawned. This may well result in unexpected
 behaviour by the single-threaded LyX.
 
 cause a new thread to be spawned. This may well result in unexpected
 behaviour by the single-threaded LyX.
 
@@ -722,7 +642,7 @@ static void error_handler(int err_sig)
 
        // We have received a signal indicating a fatal error, so
        // try and save the data ASAP.
 
        // We have received a signal indicating a fatal error, so
        // try and save the data ASAP.
-       LyX::cref().emergencyCleanup();
+       emergencyCleanup();
 
        // These lyxerr calls may or may not work:
 
 
        // These lyxerr calls may or may not work:
 
@@ -735,21 +655,23 @@ static void error_handler(int err_sig)
 
        // This shouldn't matter here, however, as we've already invoked
        // emergencyCleanup.
 
        // This shouldn't matter here, however, as we've already invoked
        // emergencyCleanup.
+       docstring msg;
        switch (err_sig) {
 #ifdef SIGHUP
        case SIGHUP:
        switch (err_sig) {
 #ifdef SIGHUP
        case SIGHUP:
-               lyxerr << "\nlyx: SIGHUP signal caught\nBye." << endl;
+               msg = _("SIGHUP signal caught!\nBye.");
                break;
 #endif
        case SIGFPE:
                break;
 #endif
        case SIGFPE:
-               lyxerr << "\nlyx: SIGFPE signal caught\nBye." << endl;
+               msg = _("SIGFPE signal caught!\nBye.");
                break;
        case SIGSEGV:
                break;
        case SIGSEGV:
-               lyxerr << "\nlyx: SIGSEGV signal caught\n"
-                         "Sorry, you have found a bug in LyX. "
+               msg = _("SIGSEGV signal caught!\n"
+                         "Sorry, you have found a bug in LyX, "
+                         "hope you have not lost any data.\n"
                          "Please read the bug-reporting instructions "
                          "Please read the bug-reporting instructions "
-                         "in Help->Introduction and send us a bug report, "
-                         "if necessary. Thanks !\nBye." << endl;
+                         "in 'Help->Introduction' and send us a bug report, "
+                         "if necessary. Thanks !\nBye.");
                break;
        case SIGINT:
        case SIGTERM:
                break;
        case SIGINT:
        case SIGTERM:
@@ -757,6 +679,12 @@ static void error_handler(int err_sig)
                break;
        }
 
                break;
        }
 
+       if (!msg.empty()) {
+               lyxerr << "\nlyx: " << msg << endl;
+               // try to make a GUI message
+               Alert::error(_("LyX crashed!"), msg);
+       }
+
        // Deinstall the signal handlers
 #ifdef SIGHUP
        signal(SIGHUP, SIG_DFL);
        // Deinstall the signal handlers
 #ifdef SIGHUP
        signal(SIGHUP, SIG_DFL);
@@ -768,11 +696,18 @@ static void error_handler(int err_sig)
 
 #ifdef SIGHUP
        if (err_sig == SIGSEGV ||
 
 #ifdef SIGHUP
        if (err_sig == SIGSEGV ||
-           (err_sig != SIGHUP && !getEnv("LYXDEBUG").empty()))
+               (err_sig != SIGHUP && !getEnv("LYXDEBUG").empty())) {
 #else
 #else
-       if (err_sig == SIGSEGV || !getEnv("LYXDEBUG").empty())
+       if (err_sig == SIGSEGV || !getEnv("LYXDEBUG").empty()) {
 #endif
 #endif
-               support::abort();
+#ifdef _MSC_VER
+               // with abort() it crashes again.
+               exit(err_sig);
+#else
+               abort();
+#endif
+       }
+
        exit(0);
 }
 
        exit(0);
 }
 
@@ -783,21 +718,7 @@ void LyX::printError(ErrorItem const & ei)
 {
        docstring tmp = _("LyX: ") + ei.error + char_type(':')
                + ei.description;
 {
        docstring tmp = _("LyX: ") + ei.error + char_type(':')
                + ei.description;
-       std::cerr << to_utf8(tmp) << std::endl;
-}
-
-
-void LyX::initGuiFont()
-{
-       if (lyxrc.roman_font_name.empty())
-               lyxrc.roman_font_name = pimpl_->application_->romanFontName();
-
-       if (lyxrc.sans_font_name.empty())
-               lyxrc.sans_font_name = pimpl_->application_->sansFontName();
-
-       if (lyxrc.typewriter_font_name.empty())
-               lyxrc.typewriter_font_name 
-                       = pimpl_->application_->typewriterFontName();
+       cerr << to_utf8(tmp) << endl;
 }
 
 
 }
 
 
@@ -812,11 +733,15 @@ bool LyX::init()
        signal(SIGTERM, error_handler);
        // SIGPIPE can be safely ignored.
 
        signal(SIGTERM, error_handler);
        // SIGPIPE can be safely ignored.
 
-       lyxrc.tempdir_path = package().temp_dir().absFilename();
-       lyxrc.document_path = package().document_dir().absFilename();
+       lyxrc.tempdir_path = package().temp_dir().absFileName();
+       lyxrc.document_path = package().document_dir().absFileName();
 
 
+       if (lyxrc.example_path.empty()) {
+               lyxrc.example_path = addPath(package().system_support().absFileName(),
+                                             "examples");
+       }
        if (lyxrc.template_path.empty()) {
        if (lyxrc.template_path.empty()) {
-               lyxrc.template_path = addPath(package().system_support().absFilename(),
+               lyxrc.template_path = addPath(package().system_support().absFileName(),
                                              "templates");
        }
 
                                              "templates");
        }
 
@@ -829,14 +754,14 @@ bool LyX::init()
                return false;
 
        // Set the language defined by the distributor.
                return false;
 
        // Set the language defined by the distributor.
-       //setGuiLanguage(lyxrc.gui_language);
+       setRcGuiLanguage();
 
        // Set the PATH correctly.
 #if !defined (USE_POSIX_PACKAGING)
        // Add the directory containing the LyX executable to the path
        // so that LyX can find things like tex2lyx.
        if (package().build_support().empty())
 
        // Set the PATH correctly.
 #if !defined (USE_POSIX_PACKAGING)
        // Add the directory containing the LyX executable to the path
        // so that LyX can find things like tex2lyx.
        if (package().build_support().empty())
-               prependEnvPath("PATH", package().binary_dir().absFilename());
+               prependEnvPath("PATH", package().binary_dir().absFileName());
 #endif
        if (!lyxrc.path_prefix.empty())
                prependEnvPath("PATH", lyxrc.path_prefix);
 #endif
        if (!lyxrc.path_prefix.empty())
                prependEnvPath("PATH", lyxrc.path_prefix);
@@ -845,9 +770,20 @@ bool LyX::init()
        if (queryUserLyXDir(package().explicit_user_support()))
                reconfigureUserLyXDir();
 
        if (queryUserLyXDir(package().explicit_user_support()))
                reconfigureUserLyXDir();
 
-       // no need for a splash when there is no GUI
        if (!use_gui) {
        if (!use_gui) {
+               // No need for a splash when there is no GUI
                first_start = false;
                first_start = false;
+               // Default is to overwrite the main file during export, unless
+               // the -f switch was specified or LYX_FORCE_OVERWRITE was set
+               if (force_overwrite == UNSPECIFIED) {
+                       string const what = getEnv("LYX_FORCE_OVERWRITE");
+                       if (what == "all")
+                               force_overwrite = ALL_FILES;
+                       else if (what == "none")
+                               force_overwrite = NO_FILES;
+                       else
+                               force_overwrite = MAIN_FILE;
+               }
        }
 
        // This one is generated in user_support directory by lib/configure.py.
        }
 
        // This one is generated in user_support directory by lib/configure.py.
@@ -860,6 +796,9 @@ bool LyX::init()
        // Read lyxrc.dist again to be able to override viewer auto-detection.
        readRcFile("lyxrc.dist");
 
        // Read lyxrc.dist again to be able to override viewer auto-detection.
        readRcFile("lyxrc.dist");
 
+       // Set again the language defined by the distributor.
+       setRcGuiLanguage();
+
        system_lyxrc = lyxrc;
        system_formats = formats;
        pimpl_->system_converters_ = pimpl_->converters_;
        system_lyxrc = lyxrc;
        system_formats = formats;
        pimpl_->system_converters_ = pimpl_->converters_;
@@ -875,26 +814,28 @@ bool LyX::init()
        if (!readLanguagesFile("languages"))
                return false;
 
        if (!readLanguagesFile("languages"))
                return false;
 
-       // Load the layouts
-       LYXERR(Debug::INIT) << "Reading layouts..." << endl;
-       if (!LyXSetStyle())
-               return false;
+       // Set the language defined by the user.
+       setRcGuiLanguage();
 
 
-       if (use_gui) {
-               // Set the language defined by the user.
-               //setGuiLanguage(lyxrc.gui_language);
+       LYXERR(Debug::INIT, "Reading layouts...");
+       // Load the layouts
+       LayoutFileList::get().read();
+       //...and the modules
+       theModuleList.read();
 
 
-               // Set up bindings
-               pimpl_->toplevel_keymap_.reset(new kb_keymap);
-               defaultKeyBindings(pimpl_->toplevel_keymap_.get());
-               pimpl_->toplevel_keymap_->read(lyxrc.bind_file);
+       // read keymap and ui files in batch mode as well
+       // because InsetInfo needs to know these to produce
+       // the correct output
 
 
-               pimpl_->lyxfunc_.initKeySequences(pimpl_->toplevel_keymap_.get());
+       // Set up command definitions
+       pimpl_->toplevel_cmddef_.read(lyxrc.def_file);
 
 
-               // Read menus
-               if (!readUIFile(lyxrc.ui_file))
-                       return false;
-       }
+       // FIXME
+       // Set up bindings
+       pimpl_->toplevel_keymap_.read("site");
+       pimpl_->toplevel_keymap_.read(lyxrc.bind_file);
+       // load user bind file user.bind
+       pimpl_->toplevel_keymap_.read("user", 0, KeyMap::MissingOK);
 
        if (lyxerr.debugging(Debug::LYXRC))
                lyxrc.print();
 
        if (lyxerr.debugging(Debug::LYXRC))
                lyxrc.print();
@@ -904,16 +845,15 @@ bool LyX::init()
                prependEnvPath("PATH", lyxrc.path_prefix);
 
        FileName const document_path(lyxrc.document_path);
                prependEnvPath("PATH", lyxrc.path_prefix);
 
        FileName const document_path(lyxrc.document_path);
-       if (fs::exists(document_path.toFilesystemEncoding()) &&
-           fs::is_directory(document_path.toFilesystemEncoding()))
+       if (document_path.exists() && document_path.isDirectory())
                package().document_dir() = document_path;
 
                package().document_dir() = document_path;
 
-       package().temp_dir() = createLyXTmpDir(FileName(lyxrc.tempdir_path));
+       package().set_temp_dir(createLyXTmpDir(FileName(lyxrc.tempdir_path)));
        if (package().temp_dir().empty()) {
                Alert::error(_("Could not create temporary directory"),
                             bformat(_("Could not create a temporary directory in\n"
        if (package().temp_dir().empty()) {
                Alert::error(_("Could not create temporary directory"),
                             bformat(_("Could not create a temporary directory in\n"
-                                                   "%1$s. Make sure that this\n"
-                                                   "path exists and is writable and try again."),
+                                                      "\"%1$s\"\n"
+                                                          "Make sure that this path exists and is writable and try again."),
                                     from_utf8(lyxrc.tempdir_path)));
                // createLyXTmpDir() tries sufficiently hard to create a
                // usable temp dir, so the probability to come here is
                                     from_utf8(lyxrc.tempdir_path)));
                // createLyXTmpDir() tries sufficiently hard to create a
                // usable temp dir, so the probability to come here is
@@ -923,11 +863,10 @@ bool LyX::init()
                return false;
        }
 
                return false;
        }
 
-       LYXERR(Debug::INIT) << "LyX tmp dir: `"
-                           << package().temp_dir().absFilename()
-                           << '\'' << endl;
+       LYXERR(Debug::INIT, "LyX tmp dir: `"
+                           << package().temp_dir().absFileName() << '\'');
 
 
-       LYXERR(Debug::INIT) << "Reading session information '.lyx/session'..." << endl;
+       LYXERR(Debug::INIT, "Reading session information '.lyx/session'...");
        pimpl_->session_.reset(new Session(lyxrc.num_lastfiles));
 
        // This must happen after package initialization and after lyxrc is
        pimpl_->session_.reset(new Session(lyxrc.num_lastfiles));
 
        // This must happen after package initialization and after lyxrc is
@@ -938,136 +877,53 @@ bool LyX::init()
 }
 
 
 }
 
 
-void LyX::defaultKeyBindings(kb_keymap  * kbmap)
-{
-       kbmap->bind("Right", FuncRequest(LFUN_CHAR_FORWARD));
-       kbmap->bind("Left", FuncRequest(LFUN_CHAR_BACKWARD));
-       kbmap->bind("Up", FuncRequest(LFUN_UP));
-       kbmap->bind("Down", FuncRequest(LFUN_DOWN));
-
-       kbmap->bind("Tab", FuncRequest(LFUN_CELL_FORWARD));
-       kbmap->bind("C-Tab", FuncRequest(LFUN_CELL_SPLIT));
-       kbmap->bind("~S-ISO_Left_Tab", FuncRequest(LFUN_CELL_BACKWARD));
-       kbmap->bind("~S-BackTab", FuncRequest(LFUN_CELL_BACKWARD));
-
-       kbmap->bind("Home", FuncRequest(LFUN_LINE_BEGIN));
-       kbmap->bind("End", FuncRequest(LFUN_LINE_END));
-       kbmap->bind("Prior", FuncRequest(LFUN_SCREEN_UP));
-       kbmap->bind("Next", FuncRequest(LFUN_SCREEN_DOWN));
-
-       kbmap->bind("Return", FuncRequest(LFUN_BREAK_PARAGRAPH));
-       //kbmap->bind("~C-~S-~M-nobreakspace", FuncRequest(LFUN_PROTECTEDSPACE));
-
-       kbmap->bind("Delete", FuncRequest(LFUN_CHAR_DELETE_FORWARD));
-       kbmap->bind("BackSpace", FuncRequest(LFUN_CHAR_DELETE_BACKWARD));
-
-       // kbmap->bindings to enable the use of the numeric keypad
-       // e.g. Num Lock set
-       //kbmap->bind("KP_0", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Decimal", FuncRequest(LFUN_SELF_INSERT));
-       kbmap->bind("KP_Enter", FuncRequest(LFUN_BREAK_PARAGRAPH));
-       //kbmap->bind("KP_1", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_2", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_3", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_4", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_5", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_6", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Add", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_7", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_8", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_9", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Divide", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Multiply", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Subtract", FuncRequest(LFUN_SELF_INSERT));
-       kbmap->bind("KP_Right", FuncRequest(LFUN_CHAR_FORWARD));
-       kbmap->bind("KP_Left", FuncRequest(LFUN_CHAR_BACKWARD));
-       kbmap->bind("KP_Up", FuncRequest(LFUN_UP));
-       kbmap->bind("KP_Down", FuncRequest(LFUN_DOWN));
-       kbmap->bind("KP_Home", FuncRequest(LFUN_LINE_BEGIN));
-       kbmap->bind("KP_End", FuncRequest(LFUN_LINE_END));
-       kbmap->bind("KP_Prior", FuncRequest(LFUN_SCREEN_UP));
-       kbmap->bind("KP_Next", FuncRequest(LFUN_SCREEN_DOWN));
-}
-
-
-void LyX::emergencyCleanup() const
+void emergencyCleanup()
 {
        // what to do about tmpfiles is non-obvious. we would
        // like to delete any we find, but our lyxdir might
        // contain documents etc. which might be helpful on
        // a crash
 
 {
        // what to do about tmpfiles is non-obvious. we would
        // like to delete any we find, but our lyxdir might
        // contain documents etc. which might be helpful on
        // a crash
 
-       pimpl_->buffer_list_.emergencyWriteAll();
+       singleton_->pimpl_->buffer_list_.emergencyWriteAll();
        if (use_gui) {
        if (use_gui) {
-               if (pimpl_->lyx_server_)
-                       pimpl_->lyx_server_->emergencyCleanup();
-               pimpl_->lyx_server_.reset();
-               pimpl_->lyx_socket_.reset();
+               if (singleton_->pimpl_->lyx_server_)
+                       singleton_->pimpl_->lyx_server_->emergencyCleanup();
+               singleton_->pimpl_->lyx_server_.reset();
+               singleton_->pimpl_->lyx_socket_.reset();
        }
 }
 
 
        }
 }
 
 
-void LyX::deadKeyBindings(kb_keymap * kbmap)
-{
-       // bindKeyings for transparent handling of deadkeys
-       // The keysyms are gotten from XFree86 X11R6
-       kbmap->bind("~C-~S-~M-dead_acute", FuncRequest(LFUN_ACCENT_ACUTE));
-       kbmap->bind("~C-~S-~M-dead_breve", FuncRequest(LFUN_ACCENT_BREVE));
-       kbmap->bind("~C-~S-~M-dead_caron", FuncRequest(LFUN_ACCENT_CARON));
-       kbmap->bind("~C-~S-~M-dead_cedilla", FuncRequest(LFUN_ACCENT_CEDILLA));
-       kbmap->bind("~C-~S-~M-dead_abovering", FuncRequest(LFUN_ACCENT_CIRCLE));
-       kbmap->bind("~C-~S-~M-dead_circumflex", FuncRequest(LFUN_ACCENT_CIRCUMFLEX));
-       kbmap->bind("~C-~S-~M-dead_abovedot", FuncRequest(LFUN_ACCENT_DOT));
-       kbmap->bind("~C-~S-~M-dead_grave", FuncRequest(LFUN_ACCENT_GRAVE));
-       kbmap->bind("~C-~S-~M-dead_doubleacute", FuncRequest(LFUN_ACCENT_HUNGARIAN_UMLAUT));
-       kbmap->bind("~C-~S-~M-dead_macron", FuncRequest(LFUN_ACCENT_MACRON));
-       // nothing with this name
-       // kbmap->bind("~C-~S-~M-dead_special_caron", LFUN_ACCENT_SPECIAL_CARON);
-       kbmap->bind("~C-~S-~M-dead_tilde", FuncRequest(LFUN_ACCENT_TILDE));
-       kbmap->bind("~C-~S-~M-dead_diaeresis", FuncRequest(LFUN_ACCENT_UMLAUT));
-       // nothing with this name either...
-       //kbmap->bind("~C-~S-~M-dead_underbar", FuncRequest(LFUN_ACCENT_UNDERBAR));
-       kbmap->bind("~C-~S-~M-dead_belowdot", FuncRequest(LFUN_ACCENT_UNDERDOT));
-       kbmap->bind("~C-~S-~M-dead_tie", FuncRequest(LFUN_ACCENT_TIE));
-       kbmap->bind("~C-~S-~M-dead_ogonek",FuncRequest(LFUN_ACCENT_OGONEK));
-}
-
-
-namespace {
-
 // return true if file does not exist or is older than configure.py.
 // return true if file does not exist or is older than configure.py.
-bool needsUpdate(string const & file)
+static bool needsUpdate(string const & file)
 {
        // We cannot initialize configure_script directly because the package
        // is not initialized yet when  static objects are constructed.
 {
        // We cannot initialize configure_script directly because the package
        // is not initialized yet when  static objects are constructed.
-       static string configure_script;
+       static FileName configure_script;
        static bool firstrun = true;
        if (firstrun) {
        static bool firstrun = true;
        if (firstrun) {
-               configure_script = FileName(addName(
-                               package().system_support().absFilename(),
-                               "configure.py")).toFilesystemEncoding();
+               configure_script =
+                       FileName(addName(package().system_support().absFileName(),
+                               "configure.py"));
                firstrun = false;
        }
 
                firstrun = false;
        }
 
-       string const absfile = FileName(addName(
-               package().user_support().absFilename(), file)).toFilesystemEncoding();
-       return (! fs::exists(absfile))
-               || (fs::last_write_time(configure_script)
-                   > fs::last_write_time(absfile));
-}
-
+       FileName absfile =
+               FileName(addName(package().user_support().absFileName(), file));
+       return !absfile.exists()
+               || configure_script.lastModified() > absfile.lastModified();
 }
 
 
 bool LyX::queryUserLyXDir(bool explicit_userdir)
 {
        // Does user directory exist?
 }
 
 
 bool LyX::queryUserLyXDir(bool explicit_userdir)
 {
        // Does user directory exist?
-       string const user_support =
-               package().user_support().toFilesystemEncoding();
-       if (fs::exists(user_support) && fs::is_directory(user_support)) {
+       FileName const sup = package().user_support();
+       if (sup.exists() && sup.isDirectory()) {
                first_start = false;
 
                return needsUpdate("lyxrc.defaults")
                first_start = false;
 
                return needsUpdate("lyxrc.defaults")
+                       || needsUpdate("lyxmodules.lst")
                        || needsUpdate("textclass.lst")
                        || needsUpdate("packages.lst");
        }
                        || needsUpdate("textclass.lst")
                        || needsUpdate("packages.lst");
        }
@@ -1082,7 +938,7 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
                    bformat(_("You have specified a non-existent user "
                                           "LyX directory, %1$s.\n"
                                           "It is needed to keep your own configuration."),
                    bformat(_("You have specified a non-existent user "
                                           "LyX directory, %1$s.\n"
                                           "It is needed to keep your own configuration."),
-                           from_utf8(package().user_support().absFilename())),
+                           from_utf8(package().user_support().absFileName())),
                    1, 0,
                    _("&Create directory"),
                    _("&Exit LyX"))) {
                    1, 0,
                    _("&Create directory"),
                    _("&Exit LyX"))) {
@@ -1091,10 +947,9 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
        }
 
        lyxerr << to_utf8(bformat(_("LyX: Creating directory %1$s"),
        }
 
        lyxerr << to_utf8(bformat(_("LyX: Creating directory %1$s"),
-                         from_utf8(package().user_support().absFilename())))
-              << endl;
+                         from_utf8(sup.absFileName()))) << endl;
 
 
-       if (!createDirectory(package().user_support(), 0755)) {
+       if (!sup.createDirectory(0755)) {
                // Failed, so let's exit.
                lyxerr << to_utf8(_("Failed to create directory. Exiting."))
                       << endl;
                // Failed, so let's exit.
                lyxerr << to_utf8(_("Failed to create directory. Exiting."))
                       << endl;
@@ -1107,124 +962,25 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
 
 bool LyX::readRcFile(string const & name)
 {
 
 bool LyX::readRcFile(string const & name)
 {
-       LYXERR(Debug::INIT) << "About to read " << name << "... ";
+       LYXERR(Debug::INIT, "About to read " << name << "... ");
 
        FileName const lyxrc_path = libFileSearch(string(), name);
        if (!lyxrc_path.empty()) {
 
        FileName const lyxrc_path = libFileSearch(string(), name);
        if (!lyxrc_path.empty()) {
-
-               LYXERR(Debug::INIT) << "Found in " << lyxrc_path << endl;
-
+               LYXERR(Debug::INIT, "Found in " << lyxrc_path);
                if (lyxrc.read(lyxrc_path) < 0) {
                        showFileError(name);
                        return false;
                }
                if (lyxrc.read(lyxrc_path) < 0) {
                        showFileError(name);
                        return false;
                }
-       } else
-               LYXERR(Debug::INIT) << "Not found." << lyxrc_path << endl;
-       return true;
-
-}
-
-
-// Read the ui file `name'
-bool LyX::readUIFile(string const & name, bool include)
-{
-       enum Uitags {
-               ui_menuset = 1,
-               ui_toolbars,
-               ui_toolbarset,
-               ui_include,
-               ui_last
-       };
-
-       struct keyword_item uitags[ui_last - 1] = {
-               { "include", ui_include },
-               { "menuset", ui_menuset },
-               { "toolbars", ui_toolbars },
-               { "toolbarset", ui_toolbarset }
-       };
-
-       // Ensure that a file is read only once (prevents include loops)
-       static std::list<string> uifiles;
-       std::list<string>::const_iterator it  = uifiles.begin();
-       std::list<string>::const_iterator end = uifiles.end();
-       it = std::find(it, end, name);
-       if (it != end) {
-               LYXERR(Debug::INIT) << "UI file '" << name
-                                   << "' has been read already. "
-                                   << "Is this an include loop?"
-                                   << endl;
-               return false;
-       }
-
-       LYXERR(Debug::INIT) << "About to read " << name << "..." << endl;
-
-       
-       FileName ui_path;
-       if (include) {
-               ui_path = libFileSearch("ui", name, "inc");
-               if (ui_path.empty())
-                       ui_path = libFileSearch("ui",
-                                               changeExtension(name, "inc"));
-       }
-       else
-               ui_path = libFileSearch("ui", name, "ui");
-       
-       if (ui_path.empty()) {
-               LYXERR(Debug::INIT) << "Could not find " << name << endl;
-               showFileError(name);
-               return false;
-       }
-
-       uifiles.push_back(name);
-
-       LYXERR(Debug::INIT) << "Found " << name
-                           << " in " << ui_path << endl;
-       Lexer lex(uitags, ui_last - 1);
-       lex.setFile(ui_path);
-       if (!lex.isOK()) {
-               lyxerr << "Unable to set LyXLeX for ui file: " << ui_path
-                      << endl;
-       }
-
-       if (lyxerr.debugging(Debug::PARSER))
-               lex.printTable(lyxerr);
-
-       while (lex.isOK()) {
-               switch (lex.lex()) {
-               case ui_include: {
-                       lex.next(true);
-                       string const file = lex.getString();
-                       if (!readUIFile(file, true))
-                               return false;
-                       break;
-               }
-               case ui_menuset:
-                       menubackend.read(lex);
-                       break;
-
-               case ui_toolbarset:
-                       toolbarbackend.readToolbars(lex);
-                       break;
-
-               case ui_toolbars:
-                       toolbarbackend.readToolbarSettings(lex);
-                       break;
-
-               default:
-                       if (!rtrim(lex.getString()).empty())
-                               lex.printError("LyX::ReadUIFile: "
-                                              "Unknown menu tag: `$$Token'");
-                       break;
-               }
+       } else {
+               LYXERR(Debug::INIT, "Not found." << lyxrc_path);
        }
        return true;
 }
 
        }
        return true;
 }
 
-
 // Read the languages file `name'
 bool LyX::readLanguagesFile(string const & name)
 {
 // Read the languages file `name'
 bool LyX::readLanguagesFile(string const & name)
 {
-       LYXERR(Debug::INIT) << "About to read " << name << "..." << endl;
+       LYXERR(Debug::INIT, "About to read " << name << "...");
 
        FileName const lang_path = libFileSearch(string(), name);
        if (lang_path.empty()) {
 
        FileName const lang_path = libFileSearch(string(), name);
        if (lang_path.empty()) {
@@ -1238,10 +994,10 @@ bool LyX::readLanguagesFile(string const & name)
 
 // Read the encodings file `name'
 bool LyX::readEncodingsFile(string const & enc_name,
 
 // Read the encodings file `name'
 bool LyX::readEncodingsFile(string const & enc_name,
-                            string const & symbols_name)
+                           string const & symbols_name)
 {
 {
-       LYXERR(Debug::INIT) << "About to read " << enc_name << " and "
-                           << symbols_name << "..." << endl;
+       LYXERR(Debug::INIT, "About to read " << enc_name << " and "
+                           << symbols_name << "...");
 
        FileName const symbols_path = libFileSearch(string(), symbols_name);
        if (symbols_path.empty()) {
 
        FileName const symbols_path = libFileSearch(string(), symbols_name);
        if (symbols_path.empty()) {
@@ -1261,12 +1017,10 @@ bool LyX::readEncodingsFile(string const & enc_name,
 
 namespace {
 
 
 namespace {
 
-string batch;
-
 /// return the the number of arguments consumed
 /// return the the number of arguments consumed
-typedef boost::function<int(string const &, string const &)> cmd_helper;
+typedef boost::function<int(string const &, string const &, string &)> cmd_helper;
 
 
-int parse_dbg(string const & arg, string const &)
+int parse_dbg(string const & arg, string const &, string &)
 {
        if (arg.empty()) {
                lyxerr << to_utf8(_("List of supported debug flags:")) << endl;
 {
        if (arg.empty()) {
                lyxerr << to_utf8(_("List of supported debug flags:")) << endl;
@@ -1275,13 +1029,13 @@ int parse_dbg(string const & arg, string const &)
        }
        lyxerr << to_utf8(bformat(_("Setting debug level to %1$s"), from_utf8(arg))) << endl;
 
        }
        lyxerr << to_utf8(bformat(_("Setting debug level to %1$s"), from_utf8(arg))) << endl;
 
-       lyxerr.level(Debug::value(arg));
+       lyxerr.setLevel(Debug::value(arg));
        Debug::showLevel(lyxerr, lyxerr.level());
        return 1;
 }
 
 
        Debug::showLevel(lyxerr, lyxerr.level());
        return 1;
 }
 
 
-int parse_help(string const &, string const &)
+int parse_help(string const &, string const &, string &)
 {
        lyxerr <<
                to_utf8(_("Usage: lyx [ command line switches ] [ name.lyx ... ]\n"
 {
        lyxerr <<
                to_utf8(_("Usage: lyx [ command line switches ] [ name.lyx ... ]\n"
@@ -1297,16 +1051,31 @@ int parse_help(string const &, string const &)
                  "                  where command is a lyx command.\n"
                  "\t-e [--export] fmt\n"
                  "                  where fmt is the export format of choice.\n"
                  "                  where command is a lyx command.\n"
                  "\t-e [--export] fmt\n"
                  "                  where fmt is the export format of choice.\n"
+                 "                  Look on Tools->Preferences->File formats->Format\n"
+                 "                  to get an idea which parameters should be passed.\n"
+                 "                  Note that the order of -e and -x switches matters.\n"
                  "\t-i [--import] fmt file.xxx\n"
                  "                  where fmt is the import format of choice\n"
                  "                  and file.xxx is the file to be imported.\n"
                  "\t-i [--import] fmt file.xxx\n"
                  "                  where fmt is the import format of choice\n"
                  "                  and file.xxx is the file to be imported.\n"
-                 "\t-version        summarize version and build info\n"
+                 "\t-f [--force-overwrite] what\n"
+                 "                  where what is either `all', `main' or `none',\n"
+                 "                  specifying whether all files, main file only, or no files,\n"
+                 "                  respectively, are to be overwritten during a batch export.\n"
+                 "                  Anything else is equivalent to `all', but is not consumed.\n"
+                 "\t-n [--no-remote]\n"
+                 "                  open documents in a new instance\n"
+                 "\t-r [--remote]\n"
+                 "                  open documents in an already running instance\n"
+                 "                  (a working lyxpipe is needed)\n"
+                 "\t-batch    execute commands without launching GUI and exit.\n"
+                 "\t-version  summarize version and build info\n"
                               "Check the LyX man page for more details.")) << endl;
        exit(0);
        return 0;
 }
 
                               "Check the LyX man page for more details.")) << endl;
        exit(0);
        return 0;
 }
 
-int parse_version(string const &, string const &)
+
+int parse_version(string const &, string const &, string &)
 {
        lyxerr << "LyX " << lyx_version
               << " (" << lyx_release_date << ")" << endl;
 {
        lyxerr << "LyX " << lyx_version
               << " (" << lyx_release_date << ")" << endl;
@@ -1317,7 +1086,8 @@ int parse_version(string const &, string const &)
        return 0;
 }
 
        return 0;
 }
 
-int parse_sysdir(string const & arg, string const &)
+
+int parse_sysdir(string const & arg, string const &, string &)
 {
        if (arg.empty()) {
                Alert::error(_("No system directory"),
 {
        if (arg.empty()) {
                Alert::error(_("No system directory"),
@@ -1328,7 +1098,8 @@ int parse_sysdir(string const & arg, string const &)
        return 1;
 }
 
        return 1;
 }
 
-int parse_userdir(string const & arg, string const &)
+
+int parse_userdir(string const & arg, string const &, string &)
 {
        if (arg.empty()) {
                Alert::error(_("No user directory"),
 {
        if (arg.empty()) {
                Alert::error(_("No user directory"),
@@ -1339,7 +1110,8 @@ int parse_userdir(string const & arg, string const &)
        return 1;
 }
 
        return 1;
 }
 
-int parse_execute(string const & arg, string const &)
+
+int parse_execute(string const & arg, string const &, string & batch)
 {
        if (arg.empty()) {
                Alert::error(_("Incomplete command"),
 {
        if (arg.empty()) {
                Alert::error(_("Incomplete command"),
@@ -1350,7 +1122,8 @@ int parse_execute(string const & arg, string const &)
        return 1;
 }
 
        return 1;
 }
 
-int parse_export(string const & type, string const &)
+
+int parse_export(string const & type, string const &, string & batch)
 {
        if (type.empty()) {
                lyxerr << to_utf8(_("Missing file type [eg latex, ps...] after "
 {
        if (type.empty()) {
                lyxerr << to_utf8(_("Missing file type [eg latex, ps...] after "
@@ -1362,7 +1135,8 @@ int parse_export(string const & type, string const &)
        return 1;
 }
 
        return 1;
 }
 
-int parse_import(string const & type, string const & file)
+
+int parse_import(string const & type, string const & file, string & batch)
 {
        if (type.empty()) {
                lyxerr << to_utf8(_("Missing file type [eg latex, ps...] after "
 {
        if (type.empty()) {
                lyxerr << to_utf8(_("Missing file type [eg latex, ps...] after "
@@ -1378,16 +1152,51 @@ int parse_import(string const & type, string const & file)
        return 2;
 }
 
        return 2;
 }
 
-int parse_geometry(string const & arg1, string const &)
+
+int parse_geometry(string const & arg1, string const &, string &)
 {
        geometryArg = arg1;
 {
        geometryArg = arg1;
-#if defined(_WIN32) || (defined(__CYGWIN__) && defined(X_DISPLAY_MISSING))
-       // remove also the arg
-       return 1;
-#else
-       // don't remove "-geometry"
+       // don't remove "-geometry", it will be pruned out later in the
+       // frontend if need be.
        return -1;
        return -1;
-#endif
+}
+
+
+int parse_batch(string const &, string const &, string &)
+{
+       use_gui = false;
+       return 0;
+}
+
+
+int parse_noremote(string const &, string const &, string &)
+{
+       run_mode = NEW_INSTANCE;
+       return 0;
+}
+
+
+int parse_remote(string const &, string const &, string &)
+{
+       run_mode = USE_REMOTE;
+       return 0;
+}
+
+
+int parse_force(string const & arg, string const &, string &)
+{
+       if (arg == "all") {
+               force_overwrite = ALL_FILES;
+               return 1;
+       } else if (arg == "main") {
+               force_overwrite = MAIN_FILE;
+               return 1;
+       } else if (arg == "none") {
+               force_overwrite = NO_FILES;
+               return 1;
+       }
+       force_overwrite = ALL_FILES;
+       return 0;
 }
 
 
 }
 
 
@@ -1396,7 +1205,7 @@ int parse_geometry(string const & arg1, string const &)
 
 void LyX::easyParse(int & argc, char * argv[])
 {
 
 void LyX::easyParse(int & argc, char * argv[])
 {
-       std::map<string, cmd_helper> cmdmap;
+       map<string, cmd_helper> cmdmap;
 
        cmdmap["-dbg"] = parse_dbg;
        cmdmap["-help"] = parse_help;
 
        cmdmap["-dbg"] = parse_dbg;
        cmdmap["-help"] = parse_help;
@@ -1412,126 +1221,234 @@ void LyX::easyParse(int & argc, char * argv[])
        cmdmap["-i"] = parse_import;
        cmdmap["--import"] = parse_import;
        cmdmap["-geometry"] = parse_geometry;
        cmdmap["-i"] = parse_import;
        cmdmap["--import"] = parse_import;
        cmdmap["-geometry"] = parse_geometry;
+       cmdmap["-batch"] = parse_batch;
+       cmdmap["-f"] = parse_force;
+       cmdmap["--force-overwrite"] = parse_force;
+       cmdmap["-n"] = parse_noremote;
+       cmdmap["--no-remote"] = parse_noremote;
+       cmdmap["-r"] = parse_remote;
+       cmdmap["--remote"] = parse_remote;
 
        for (int i = 1; i < argc; ++i) {
 
        for (int i = 1; i < argc; ++i) {
-               std::map<string, cmd_helper>::const_iterator it
+               map<string, cmd_helper>::const_iterator it
                        = cmdmap.find(argv[i]);
 
                // don't complain if not found - may be parsed later
                if (it == cmdmap.end())
                        continue;
 
                        = cmdmap.find(argv[i]);
 
                // don't complain if not found - may be parsed later
                if (it == cmdmap.end())
                        continue;
 
-               string const arg((i + 1 < argc) ? to_utf8(from_local8bit(argv[i + 1])) : string());
-               string const arg2((i + 2 < argc) ? to_utf8(from_local8bit(argv[i + 2])) : string());
+               string const arg =
+                       (i + 1 < argc) ? os::utf8_argv(i + 1) : string();
+               string const arg2 =
+                       (i + 2 < argc) ? os::utf8_argv(i + 2) : string();
 
 
-               int const remove = 1 + it->second(arg, arg2);
+               string batch;
+               int const remove = 1 + it->second(arg, arg2, batch);
+               if (!batch.empty())
+                       pimpl_->batch_commands.push_back(batch);
 
                // Now, remove used arguments by shifting
                // the following ones remove places down.
                if (remove > 0) {
 
                // Now, remove used arguments by shifting
                // the following ones remove places down.
                if (remove > 0) {
+                       os::remove_internal_args(i, remove);
                        argc -= remove;
                        for (int j = i; j < argc; ++j)
                                argv[j] = argv[j + remove];
                        --i;
                }
        }
                        argc -= remove;
                        for (int j = i; j < argc; ++j)
                                argv[j] = argv[j + remove];
                        --i;
                }
        }
-
-       batch_command = batch;
 }
 
 
 FuncStatus getStatus(FuncRequest const & action)
 {
 }
 
 
 FuncStatus getStatus(FuncRequest const & action)
 {
-       return LyX::ref().lyxFunc().getStatus(action);
+       LASSERT(theApp(), /**/);
+       return theApp()->getStatus(action);
 }
 
 
 void dispatch(FuncRequest const & action)
 {
 }
 
 
 void dispatch(FuncRequest const & action)
 {
-       LyX::ref().lyxFunc().dispatch(action);
+       LASSERT(theApp(), /**/);
+       return theApp()->dispatch(action);
 }
 
 
 }
 
 
-BufferList & theBufferList()
+void dispatch(FuncRequest const & action, DispatchResult & dr)
 {
 {
-       return LyX::ref().bufferList();
+       LASSERT(theApp(), /**/);
+       return theApp()->dispatch(action, dr);
 }
 
 
 }
 
 
-LyXFunc & theLyXFunc()
+vector<string> & theFilesToLoad()
 {
 {
-       return LyX::ref().lyxFunc();
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->files_to_load_;
 }
 
 
 }
 
 
-LyXServer & theLyXServer()
+BufferList & theBufferList()
+{
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->buffer_list_;
+}
+
+
+Server & theServer()
 {
        // FIXME: this should not be use_gui dependent
 {
        // FIXME: this should not be use_gui dependent
-       BOOST_ASSERT(use_gui);
-       return LyX::ref().server();
+       LASSERT(use_gui, /**/);
+       LASSERT(singleton_, /**/);
+       return *singleton_->pimpl_->lyx_server_.get();
 }
 
 
 }
 
 
-LyXServerSocket & theLyXServerSocket()
+ServerSocket & theServerSocket()
 {
        // FIXME: this should not be use_gui dependent
 {
        // FIXME: this should not be use_gui dependent
-       BOOST_ASSERT(use_gui);
-       return LyX::ref().socket();
+       LASSERT(use_gui, /**/);
+       LASSERT(singleton_, /**/);
+       return *singleton_->pimpl_->lyx_socket_.get();
 }
 
 
 }
 
 
-kb_keymap & theTopLevelKeymap()
+KeyMap & theTopLevelKeymap()
 {
 {
-       BOOST_ASSERT(use_gui);
-       return LyX::ref().topLevelKeymap();
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->toplevel_keymap_;
 }
 
 
 Converters & theConverters()
 {
 }
 
 
 Converters & theConverters()
 {
-       return  LyX::ref().converters();
+       LASSERT(singleton_, /**/);
+       return  singleton_->pimpl_->converters_;
 }
 
 
 Converters & theSystemConverters()
 {
 }
 
 
 Converters & theSystemConverters()
 {
-       return  LyX::ref().systemConverters();
+       LASSERT(singleton_, /**/);
+       return  singleton_->pimpl_->system_converters_;
 }
 
 
 Movers & theMovers()
 {
 }
 
 
 Movers & theMovers()
 {
-       return  LyX::ref().pimpl_->movers_;
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->movers_;
 }
 
 
 }
 
 
-Mover const & getMover(std::string  const & fmt)
+Mover const & getMover(string  const & fmt)
 {
 {
-       return  LyX::ref().pimpl_->movers_(fmt);
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->movers_(fmt);
 }
 
 
 }
 
 
-void setMover(std::string const & fmt, std::string const & command)
+void setMover(string const & fmt, string const & command)
 {
 {
-       LyX::ref().pimpl_->movers_.set(fmt, command);
+       LASSERT(singleton_, /**/);
+       singleton_->pimpl_->movers_.set(fmt, command);
 }
 
 
 Movers & theSystemMovers()
 {
 }
 
 
 Movers & theSystemMovers()
 {
-       return  LyX::ref().pimpl_->system_movers_;
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->system_movers_;
 }
 
 
 }
 
 
-Messages & getMessages(std::string const & language)
+Messages const & getMessages(string const & language)
 {
 {
-       return LyX::ref().getMessages(language);
+       LASSERT(singleton_, /**/);
+       return singleton_->messages(language);
 }
 
 
 }
 
 
-Messages & getGuiMessages()
+Messages const & getGuiMessages()
 {
 {
-       return LyX::ref().getGuiMessages();
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->messages_["GUI"];
+}
+
+
+graphics::Previews & thePreviews()
+{
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->preview_;
+}
+
+
+Session & theSession()
+{
+       LASSERT(singleton_, /**/);
+       return *singleton_->pimpl_->session_.get();
+}
+
+
+CmdDef & theTopLevelCmdDef()
+{
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->toplevel_cmddef_;
+}
+
+
+SpellChecker * theSpellChecker()
+{
+       if (!singleton_->pimpl_->spell_checker_)
+               setSpellChecker();
+       return singleton_->pimpl_->spell_checker_;
+}
+
+
+void setSpellChecker()
+{
+       SpellChecker::ChangeNumber speller_change_number =singleton_->pimpl_->spell_checker_ ?
+               singleton_->pimpl_->spell_checker_->changeNumber() : 0;
+
+       if (lyxrc.spellchecker == "native") {
+#if defined(USE_MACOSX_PACKAGING)
+               if (!singleton_->pimpl_->apple_spell_checker_)
+                       singleton_->pimpl_->apple_spell_checker_ = new AppleSpellChecker();
+               singleton_->pimpl_->spell_checker_ = singleton_->pimpl_->apple_spell_checker_;
+#else
+               singleton_->pimpl_->spell_checker_ = 0;
+#endif
+       } else if (lyxrc.spellchecker == "aspell") {
+#if defined(USE_ASPELL)
+               if (!singleton_->pimpl_->aspell_checker_)
+                       singleton_->pimpl_->aspell_checker_ = new AspellChecker();
+               singleton_->pimpl_->spell_checker_ = singleton_->pimpl_->aspell_checker_;
+#else
+               singleton_->pimpl_->spell_checker_ = 0;
+#endif
+       } else if (lyxrc.spellchecker == "enchant") {
+#if defined(USE_ENCHANT)
+               if (!singleton_->pimpl_->enchant_checker_)
+                       singleton_->pimpl_->enchant_checker_ = new EnchantChecker();
+               singleton_->pimpl_->spell_checker_ = singleton_->pimpl_->enchant_checker_;
+#else
+               singleton_->pimpl_->spell_checker_ = 0;
+#endif
+       } else if (lyxrc.spellchecker == "hunspell") {
+#if defined(USE_HUNSPELL)
+               if (!singleton_->pimpl_->hunspell_checker_)
+                       singleton_->pimpl_->hunspell_checker_ = new HunspellChecker();
+               singleton_->pimpl_->spell_checker_ = singleton_->pimpl_->hunspell_checker_;
+#else
+               singleton_->pimpl_->spell_checker_ = 0;
+#endif
+       } else {
+               singleton_->pimpl_->spell_checker_ = 0;
+       }
+       if (singleton_->pimpl_->spell_checker_) {
+               singleton_->pimpl_->spell_checker_->changeNumber(speller_change_number);
+               singleton_->pimpl_->spell_checker_->advanceChangeNumber();
+       }
 }
 
 } // namespace lyx
 }
 
 } // namespace lyx