diff --git a/src/app/main.cpp b/src/app/main.cpp
index 71d00d320b510d8d99a734cc0cb4252a6a45e841..1db6fc2bdaf8ffe4cc397660d6af70be97fdba2a 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -71,7 +71,8 @@ static const char fixedOptionsC[] =
 "    -version                      Display program version\n"
 "    -client                       Attempt to connect to already running first instance\n"
 "    -settingspath <path>          Override the default path where user settings are stored\n"
-"    -pid <pid>                    Attempt to connect to instance given by pid\n";
+"    -pid <pid>                    Attempt to connect to instance given by pid\n"
+"    -block                        Block until editor is closed\n";
 
 
 static const char HELP_OPTION1[] = "-h";
@@ -82,6 +83,7 @@ static const char VERSION_OPTION[] = "-version";
 static const char CLIENT_OPTION[] = "-client";
 static const char SETTINGS_OPTION[] = "-settingspath";
 static const char PID_OPTION[] = "-pid";
+static const char BLOCK_OPTION[] = "-block";
 
 typedef QList<PluginSpec *> PluginSpecSet;
 
@@ -409,6 +411,7 @@ int main(int argc, char **argv)
         appOptions.insert(QLatin1String(VERSION_OPTION), false);
         appOptions.insert(QLatin1String(CLIENT_OPTION), false);
         appOptions.insert(QLatin1String(PID_OPTION), true);
+        appOptions.insert(QLatin1String(BLOCK_OPTION), false);
         QString errorMessage;
         if (!PluginManager::parseOptions(arguments, appOptions, &foundAppOptions, &errorMessage)) {
             displayError(errorMessage);
@@ -456,7 +459,10 @@ int main(int argc, char **argv)
             pid = tmpPid;
     }
 
-    if (app.isRunning() && (pid != -1 || foundAppOptions.contains(QLatin1String(CLIENT_OPTION)))) {
+    bool isBlock = foundAppOptions.contains(QLatin1String(BLOCK_OPTION));
+    if (app.isRunning() && (pid != -1 || isBlock
+                            || foundAppOptions.contains(QLatin1String(CLIENT_OPTION)))) {
+        app.setBlock(isBlock);
         if (app.sendMessage(PluginManager::serializedArguments(), 5000 /*timeout*/, pid))
             return 0;
 
@@ -489,8 +495,8 @@ int main(int argc, char **argv)
 
     // Set up lock and remote arguments.
     app.initialize();
-    QObject::connect(&app, SIGNAL(messageReceived(QString)),
-                     &pluginManager, SLOT(remoteArguments(QString)));
+    QObject::connect(&app, SIGNAL(messageReceived(QString,QObject*)),
+                     &pluginManager, SLOT(remoteArguments(QString,QObject*)));
 
     QObject::connect(&app, SIGNAL(fileOpenRequest(QString)), coreplugin->plugin(),
                      SLOT(fileOpenRequest(QString)));
diff --git a/src/libs/extensionsystem/iplugin.cpp b/src/libs/extensionsystem/iplugin.cpp
index 062e9efdee9b3883c09f6a8a005c279d26574109..b3cda5f508e49fd0bb2d831f26c260c980c7cef5 100644
--- a/src/libs/extensionsystem/iplugin.cpp
+++ b/src/libs/extensionsystem/iplugin.cpp
@@ -157,6 +157,19 @@
     \sa asynchronousShutdownFinished()
 */
 
+/*!
+    \fn QObject *IPlugin::remoteCommand(const QStringList &options, const QStringList &arguments)
+    \brief When \QC is executed with the -client argument while already another instance of \QC
+           is running, this method of plugins is called in the running instance.
+
+    Plugin-specific arguments are passed in \a options, while the rest of the
+    arguments are passed in \a arguments.
+
+    \returns a QObject that blocks the command until it is destroyed, if -block is used.
+
+    \sa PluginManager::serializedArguments()
+*/
+
 /*!
     \fn void IPlugin::asynchronousShutdownFinished()
     Sent by the plugin implementation after a asynchronous shutdown
diff --git a/src/libs/extensionsystem/iplugin.h b/src/libs/extensionsystem/iplugin.h
index 1a49e351acf2d1381492984972a2e76d25f1dc84..1b3e537b242d30277e01ef1ff57103ba16058a74 100644
--- a/src/libs/extensionsystem/iplugin.h
+++ b/src/libs/extensionsystem/iplugin.h
@@ -64,7 +64,7 @@ public:
     virtual void extensionsInitialized() = 0;
     virtual bool delayedInitialize() { return false; }
     virtual ShutdownFlag aboutToShutdown() { return SynchronousShutdown; }
-    virtual void remoteCommand(const QStringList & /* options */, const QStringList & /* arguments */) { }
+    virtual QObject *remoteCommand(const QStringList & /* options */, const QStringList & /* arguments */) { return 0; }
 
     PluginSpec *pluginSpec() const;
 
diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index 8829f757e7889b7b924898a9a39d704a3fb1af1d..63208da0573e68f2b6d8673b9f2d761a2e99a2f8 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -532,13 +532,16 @@ static QStringList subList(const QStringList &in, const QString &key)
 }
 
 /*!
-    \fn PluginManager::remoteArguments(const QString &argument)
+    \fn PluginManager::remoteArguments(const QString &argument, QObject *socket)
 
     Parses the options encoded by serializedArguments() const
     and passes them on to the respective plugins along with the arguments.
+
+    \a socket is passed for disconnecting the peer when the operation is done (for example,
+    document is closed) for supporting the -block flag.
 */
 
-void PluginManager::remoteArguments(const QString &serializedArgument)
+void PluginManager::remoteArguments(const QString &serializedArgument, QObject *socket)
 {
     if (serializedArgument.isEmpty())
         return;
@@ -547,9 +550,15 @@ void PluginManager::remoteArguments(const QString &serializedArgument)
     foreach (const PluginSpec *ps, plugins()) {
         if (ps->state() == PluginSpec::Running) {
             const QStringList pluginOptions = subList(serializedArguments, QLatin1Char(':') + ps->name());
-            ps->plugin()->remoteCommand(pluginOptions, arguments);
+            QObject *socketParent = ps->plugin()->remoteCommand(pluginOptions, arguments);
+            if (socketParent && socket) {
+                socket->setParent(socketParent);
+                socket = 0;
+            }
         }
     }
+    if (socket)
+        delete socket;
 }
 
 /*!
diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h
index 41de4c559141b9e5cddb9c1daa3a7e9b5b14a113..e20159abfca8fbb510cef2f661f1a1a82a124dfb 100644
--- a/src/libs/extensionsystem/pluginmanager.h
+++ b/src/libs/extensionsystem/pluginmanager.h
@@ -137,7 +137,7 @@ signals:
     void initializationDone();
 
 public slots:
-    void remoteArguments(const QString &serializedArguments);
+    void remoteArguments(const QString &serializedArguments, QObject *socket);
     void shutdown();
 
 private slots:
diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp
index 25ebd22851331c3d55fe208b840ce9384b469be1..d170ddb64815545cbaea407d2ee3013fa9f8de44 100644
--- a/src/plugins/coreplugin/coreplugin.cpp
+++ b/src/plugins/coreplugin/coreplugin.cpp
@@ -119,10 +119,12 @@ bool CorePlugin::delayedInitialize()
     return true;
 }
 
-void CorePlugin::remoteCommand(const QStringList & /* options */, const QStringList &args)
+QObject *CorePlugin::remoteCommand(const QStringList & /* options */, const QStringList &args)
 {
-    m_mainWindow->openFiles(args, Core::ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineNumbers));
+    IDocument *res = m_mainWindow->openFiles(
+                args, ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineNumbers));
     m_mainWindow->activateWindow();
+    return res;
 }
 
 void CorePlugin::fileOpenRequest(const QString &f)
diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h
index d7fbef0f2a0a75108b7ff0869e1986f5e4efa23a..b9ca64b855273af51adbe515282afa01d43f9404 100644
--- a/src/plugins/coreplugin/coreplugin.h
+++ b/src/plugins/coreplugin/coreplugin.h
@@ -52,7 +52,7 @@ public:
     void extensionsInitialized();
     bool delayedInitialize();
     ShutdownFlag aboutToShutdown();
-    void remoteCommand(const QStringList & /* options */, const QStringList &args);
+    QObject *remoteCommand(const QStringList & /* options */, const QStringList &args);
 
 public slots:
     void fileOpenRequest(const QString&);
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index e7e2abc6f904af34cd0a749cb9ee17f24c4f235a..862e6e77d3e272fe6166065f9eaaba87014bfa86 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -831,31 +831,51 @@ static IDocumentFactory *findDocumentFactory(const QList<IDocumentFactory*> &fil
     return 0;
 }
 
-// opens either an editor or loads a project
-void MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags)
+/*! Either opens \a fileNames with editors or loads a project.
+ *
+ *  \a flags can be used to stop on first failure, indicate that a file name
+ *  might include line numbers and/or switch mode to edit mode.
+ *
+ *  \returns the first opened document. Required to support the -block flag
+ *  for client mode.
+ *
+ *  \sa IPlugin::remoteArguments()
+ */
+IDocument *MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags)
 {
     QList<IDocumentFactory*> nonEditorFileFactories = getNonEditorDocumentFactories();
+    IDocument *res = 0;
 
     foreach (const QString &fileName, fileNames) {
         const QFileInfo fi(fileName);
         const QString absoluteFilePath = fi.absoluteFilePath();
         if (IDocumentFactory *documentFactory = findDocumentFactory(nonEditorFileFactories, mimeDatabase(), fi)) {
-            Core::IDocument *document = documentFactory->open(absoluteFilePath);
-            if (!document && (flags & ICore::StopOnLoadFail))
-                return;
-            if (document && (flags & ICore::SwitchMode))
-                ModeManager::activateMode(Id(Core::Constants::MODE_EDIT));
+            IDocument *document = documentFactory->open(absoluteFilePath);
+            if (!document) {
+                if (flags & ICore::StopOnLoadFail)
+                    return res;
+            } else {
+                if (!res)
+                    res = document;
+                if (flags & ICore::SwitchMode)
+                    ModeManager::activateMode(Id(Core::Constants::MODE_EDIT));
+            }
         } else {
             QFlags<EditorManager::OpenEditorFlag> emFlags;
             if (flags & ICore::SwitchMode)
                 emFlags = EditorManager::ModeSwitch;
             if (flags & ICore::CanContainLineNumbers)
                 emFlags |=  EditorManager::CanContainLineNumber;
-            Core::IEditor *editor = EditorManager::openEditor(absoluteFilePath, Id(), emFlags);
-            if (!editor && (flags & ICore::StopOnLoadFail))
-                return;
+            IEditor *editor = EditorManager::openEditor(absoluteFilePath, Id(), emFlags);
+            if (!editor) {
+                if (flags & ICore::StopOnLoadFail)
+                    return res;
+            } else if (!res) {
+                res = editor->document();
+            }
         }
     }
+    return res;
 }
 
 void MainWindow::setFocusToEditor()
diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h
index 97a4447d9d55f01f43fcb69362d7c57c795642b2..0fc5c4172dd0976c33b01a5fca975493dbc2c22a 100644
--- a/src/plugins/coreplugin/mainwindow.h
+++ b/src/plugins/coreplugin/mainwindow.h
@@ -53,6 +53,7 @@ class EditorManager;
 class ExternalToolManager;
 class DocumentManager;
 class HelpManager;
+class IDocument;
 class IWizard;
 class MessageManager;
 class MimeDatabase;
@@ -95,7 +96,7 @@ public:
     void removeContextObject(IContext *contex);
     void resetContext();
 
-    void openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags);
+    Core::IDocument *openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags);
 
     Core::ActionManager *actionManager() const;
     Core::MessageManager *messageManager() const;
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 3a2a9175e48eb3f7d325a2bf18186b5f6e8fb052..8227d4268321dc9810ee4fc5f8fc04091e2d7313 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -3441,10 +3441,11 @@ IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown()
     return SynchronousShutdown;
 }
 
-void DebuggerPlugin::remoteCommand(const QStringList &options,
+QObject *DebuggerPlugin::remoteCommand(const QStringList &options,
     const QStringList &list)
 {
     theDebuggerCore->remoteCommand(options, list);
+    return 0;
 }
 
 DebuggerRunControl *DebuggerPlugin::createDebugger
diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h
index 73e221a999a4b745beadb21ee9d2737671d74dd3..1c3925486bc3ee492a05095c6670037258dde6da 100644
--- a/src/plugins/debugger/debuggerplugin.h
+++ b/src/plugins/debugger/debuggerplugin.h
@@ -71,7 +71,7 @@ public:
 private:
     // IPlugin implementation.
     bool initialize(const QStringList &arguments, QString *errorMessage);
-    void remoteCommand(const QStringList &options, const QStringList &arguments);
+    QObject *remoteCommand(const QStringList &options, const QStringList &arguments);
     ShutdownFlag aboutToShutdown();
     void extensionsInitialized();
 
diff --git a/src/shared/qtsingleapplication/qtlocalpeer.cpp b/src/shared/qtsingleapplication/qtlocalpeer.cpp
index 6410db3195a5220655cd18181f2a7b67c5f15630..c1c68938af50ff7fc98c12fdbab82210acbbb124 100644
--- a/src/shared/qtsingleapplication/qtlocalpeer.cpp
+++ b/src/shared/qtsingleapplication/qtlocalpeer.cpp
@@ -99,7 +99,7 @@ bool QtLocalPeer::isClient()
     return false;
 }
 
-bool QtLocalPeer::sendMessage(const QString &message, int timeout)
+bool QtLocalPeer::sendMessage(const QString &message, int timeout, bool block)
 {
     if (!isClient())
         return false;
@@ -129,6 +129,8 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout)
     bool res = socket.waitForBytesWritten(timeout);
     res &= socket.waitForReadyRead(timeout); // wait for ack
     res &= (socket.read(qstrlen(ack)) == ack);
+    if (block) // block until peer disconnects
+        socket.waitForDisconnected(-1);
     return res;
 }
 
@@ -168,8 +170,7 @@ void QtLocalPeer::receiveConnection()
     QString message = QString::fromUtf8(uMsg.constData(), uMsg.size());
     socket->write(ack, qstrlen(ack));
     socket->waitForBytesWritten(1000);
-    delete socket;
-    emit messageReceived(message); // ##(might take a long time to return)
+    emit messageReceived(message, socket); // ##(might take a long time to return)
 }
 
 } // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/qtlocalpeer.h b/src/shared/qtsingleapplication/qtlocalpeer.h
index 14d2d148069cdc6f3145f01b08d23587833f3463..e721a05de9a538ccbefe1623c3619f4fdf0a4009 100644
--- a/src/shared/qtsingleapplication/qtlocalpeer.h
+++ b/src/shared/qtsingleapplication/qtlocalpeer.h
@@ -42,12 +42,12 @@ class QtLocalPeer : public QObject
 public:
     explicit QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
     bool isClient();
-    bool sendMessage(const QString &message, int timeout);
+    bool sendMessage(const QString &message, int timeout, bool block);
     QString applicationId() const
         { return id; }
 
 Q_SIGNALS:
-    void messageReceived(const QString &message);
+    void messageReceived(const QString &message, QObject *socket);
 
 protected Q_SLOTS:
     void receiveConnection();
diff --git a/src/shared/qtsingleapplication/qtsingleapplication.cpp b/src/shared/qtsingleapplication/qtsingleapplication.cpp
index 8fcf2152795571644f407656d8460f076b5e3fec..f00ebea53c37931776a280835cc7dc2b88b70091 100644
--- a/src/shared/qtsingleapplication/qtsingleapplication.cpp
+++ b/src/shared/qtsingleapplication/qtsingleapplication.cpp
@@ -38,10 +38,11 @@ namespace SharedTools {
 void QtSingleApplication::sysInit(const QString &appId)
 {
     actWin = 0;
+    block = false;
     firstPeer = new QtLocalPeer(this, appId);
-    connect(firstPeer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString)));
+    connect(firstPeer, SIGNAL(messageReceived(QString,QObject*)), SIGNAL(messageReceived(QString,QObject*)));
     pidPeer = new QtLocalPeer(this, appId + QLatin1Char('-') + QString::number(QCoreApplication::applicationPid(), 10));
-    connect(pidPeer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString)));
+    connect(pidPeer, SIGNAL(messageReceived(QString,QObject*)), SIGNAL(messageReceived(QString,QObject*)));
 }
 
 
@@ -87,10 +88,10 @@ void QtSingleApplication::initialize(bool)
 bool QtSingleApplication::sendMessage(const QString &message, int timeout, qint64 pid)
 {
     if (pid == -1)
-        return firstPeer->sendMessage(message, timeout);
+        return firstPeer->sendMessage(message, timeout, block);
 
     QtLocalPeer peer(this, appId + QLatin1Char('-') + QString::number(pid, 10));
-    return peer.sendMessage(message, timeout);
+    return peer.sendMessage(message, timeout, block);
 }
 
 QString QtSingleApplication::id() const
@@ -103,15 +104,20 @@ QString QtSingleApplication::applicationId() const
     return appId;
 }
 
+void QtSingleApplication::setBlock(bool value)
+{
+    block = value;
+}
+
 void QtSingleApplication::setActivationWindow(QWidget *aw, bool activateOnMessage)
 {
     actWin = aw;
     if (activateOnMessage) {
-        connect(firstPeer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow()));
-        connect(pidPeer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow()));
+        connect(firstPeer, SIGNAL(messageReceived(QString,QObject*)), this, SLOT(activateWindow()));
+        connect(pidPeer, SIGNAL(messageReceived(QString,QObject*)), this, SLOT(activateWindow()));
     } else {
-        disconnect(firstPeer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow()));
-        disconnect(pidPeer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow()));
+        disconnect(firstPeer, SIGNAL(messageReceived(QString,QObject*)), this, SLOT(activateWindow()));
+        disconnect(pidPeer, SIGNAL(messageReceived(QString,QObject*)), this, SLOT(activateWindow()));
     }
 }
 
diff --git a/src/shared/qtsingleapplication/qtsingleapplication.h b/src/shared/qtsingleapplication/qtsingleapplication.h
index 5baebd5c9adfec6968980840a293e738d2979e98..47f290a925974f29fe86e8367c44001e101e0041 100644
--- a/src/shared/qtsingleapplication/qtsingleapplication.h
+++ b/src/shared/qtsingleapplication/qtsingleapplication.h
@@ -50,6 +50,7 @@ public:
     bool event(QEvent *event);
 
     QString applicationId() const;
+    void setBlock(bool value);
 
 public Q_SLOTS:
     bool sendMessage(const QString &message, int timeout = 5000, qint64 pid = -1);
@@ -61,7 +62,7 @@ public:
 // end obsolete methods
 
 Q_SIGNALS:
-    void messageReceived(const QString &message);
+    void messageReceived(const QString &message, QObject *socket);
     void fileOpenRequest(const QString &file);
 
 private:
@@ -70,6 +71,7 @@ private:
     QtLocalPeer *pidPeer;
     QWidget *actWin;
     QString appId;
+    bool block;
 };
 
 } // namespace SharedTools