diff --git a/src/plugins/clearcase/clearcase.pro b/src/plugins/clearcase/clearcase.pro
index ee6859828fab12fa7fb0a5495f873302c8d286d6..c40f5475dfcd5e019e3f3c5a44fcf9df58d15fe9 100644
--- a/src/plugins/clearcase/clearcase.pro
+++ b/src/plugins/clearcase/clearcase.pro
@@ -17,6 +17,7 @@ HEADERS += activityselector.h \
     clearcasesettings.h \
     clearcasesubmiteditor.h \
     clearcasesubmiteditorwidget.h \
+    clearcasesync.h \
     settingspage.h \
     versionselector.h
 
@@ -29,6 +30,7 @@ SOURCES += activityselector.cpp \
     clearcasesettings.cpp \
     clearcasesubmiteditor.cpp \
     clearcasesubmiteditorwidget.cpp \
+    clearcasesync.cpp \
     settingspage.cpp \
     versionselector.cpp
 
diff --git a/src/plugins/clearcase/clearcase.qbs b/src/plugins/clearcase/clearcase.qbs
index e7de3b0aa41e6a70a04dbeae71b006a31f834079..2a3776d6d1328b0b9ac4c8899f594e9fe9c2fc63 100644
--- a/src/plugins/clearcase/clearcase.qbs
+++ b/src/plugins/clearcase/clearcase.qbs
@@ -47,6 +47,8 @@ QtcPlugin {
         "clearcasesubmiteditor.h",
         "clearcasesubmiteditorwidget.cpp",
         "clearcasesubmiteditorwidget.h",
+        "clearcasesync.cpp",
+        "clearcasesync.h",
         "settingspage.cpp",
         "settingspage.h",
         "settingspage.ui",
diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp
index d71392779f2ca811725dba68919c206bd02d7c55..b2ce710169931cf47d5cbc30d862044b9b20e6be 100644
--- a/src/plugins/clearcase/clearcaseplugin.cpp
+++ b/src/plugins/clearcase/clearcaseplugin.cpp
@@ -38,6 +38,7 @@
 #include "clearcaseplugin.h"
 #include "clearcasesubmiteditor.h"
 #include "clearcasesubmiteditorwidget.h"
+#include "clearcasesync.h"
 #include "settingspage.h"
 #include "versionselector.h"
 #include "ui_undocheckout.h"
@@ -115,8 +116,6 @@ static const char CMD_ID_UPDATE_VIEW[]        = "ClearCase.UpdateView";
 static const char CMD_ID_CHECKIN_ALL[]        = "ClearCase.CheckInAll";
 static const char CMD_ID_STATUS[]             = "ClearCase.Status";
 
-StatusMap ClearCasePlugin::s_statusMap;
-
 static const VcsBase::VcsBaseEditorParameters editorParameters[] = {
 {
     VcsBase::RegularCommandOutput,
@@ -182,8 +181,10 @@ ClearCasePlugin::ClearCasePlugin() :
     m_submitRedoAction(0),
     m_menuAction(0),
     m_submitActionTriggered(false),
-    m_activityMutex(new QMutex)
+    m_activityMutex(new QMutex),
+    m_statusMap(new StatusMap)
 {
+    qRegisterMetaType<ClearCase::Internal::FileStatus::Status>("ClearCase::Internal::FileStatus::Status");
 }
 
 ClearCasePlugin::~ClearCasePlugin()
@@ -538,7 +539,7 @@ QStringList ClearCasePlugin::ccGetActiveVobs() const
 // file must be relative to topLevel, and using '/' path separator
 FileStatus ClearCasePlugin::vcsStatus(const QString &file) const
 {
-    return s_statusMap.value(file, FileStatus(FileStatus::Unknown));
+    return m_statusMap->value(file, FileStatus(FileStatus::Unknown));
 }
 
 QString ClearCasePlugin::ccGetFileActivity(const QString &workingDir, const QString &file)
@@ -568,7 +569,7 @@ ClearCaseSubmitEditor *ClearCasePlugin::openClearCaseSubmitEditor(const QString
 void ClearCasePlugin::updateStatusActions()
 {
     bool hasFile = currentState().hasFile();
-    FileStatus fileStatus = s_statusMap.value(currentState().relativeCurrentFile(), FileStatus(FileStatus::Unknown));
+    FileStatus fileStatus = m_statusMap->value(currentState().relativeCurrentFile(), FileStatus(FileStatus::Unknown));
     m_checkOutAction->setEnabled(hasFile && (fileStatus.status & (FileStatus::CheckedIn | FileStatus::Hijacked)));
     m_undoCheckOutAction->setEnabled(hasFile && (fileStatus.status & FileStatus::CheckedOut));
     m_undoHijackAction->setEnabled(hasFile && (fileStatus.status & FileStatus::Hijacked));
@@ -617,9 +618,9 @@ void ClearCasePlugin::addCurrentFile()
     vcsAdd(state.currentFileTopLevel(), state.relativeCurrentFile());
 }
 
-void ClearCasePlugin::setStatus(const QString &file, FileStatus::Status status, bool update)
+void ClearCasePlugin::setStatus(const QString &file, ClearCase::Internal::FileStatus::Status status, bool update)
 {
-    s_statusMap[file] = FileStatus(status, QFileInfo(currentState().topLevel(), file).permissions());
+    m_statusMap->insert(file, FileStatus(status, QFileInfo(currentState().topLevel(), file).permissions()));
     if (update && (currentState().relativeCurrentFile() == file))
         updateStatusActions();
 }
@@ -742,7 +743,7 @@ void ClearCasePlugin::ccDiffWithPred(const QStringList &files)
 
     if ((m_settings.diffType == GraphicalDiff) && (files.count() == 1)) {
         QString file = files.first();
-        if (s_statusMap[file].status == FileStatus::Hijacked)
+        if (m_statusMap->value(file).status == FileStatus::Hijacked)
             diffGraphical(ccGetFileVersion(topLevel, file), file);
         else
             diffGraphical(file);
@@ -750,7 +751,7 @@ void ClearCasePlugin::ccDiffWithPred(const QStringList &files)
     }
     QString result;
     foreach (const QString &file, files) {
-        if (s_statusMap[QDir::fromNativeSeparators(file)].status == FileStatus::Hijacked)
+        if (m_statusMap->value(QDir::fromNativeSeparators(file)).status == FileStatus::Hijacked)
             result += diffExternal(ccGetFileVersion(topLevel, file), file);
         else
             result += diffExternal(file);
@@ -885,8 +886,8 @@ void ClearCasePlugin::startCheckInAll()
     QTC_ASSERT(state.hasTopLevel(), return);
     QString topLevel = state.topLevel();
     QStringList files;
-    for (StatusMap::ConstIterator iterator = s_statusMap.constBegin();
-         iterator != s_statusMap.constEnd();
+    for (StatusMap::ConstIterator iterator = m_statusMap->constBegin();
+         iterator != m_statusMap->constEnd();
          ++iterator)
     {
         if (iterator.value().status == FileStatus::CheckedOut)
@@ -1025,8 +1026,8 @@ void ClearCasePlugin::viewStatus()
     VcsBase::VcsBaseOutputWindow *outputwindow = VcsBase::VcsBaseOutputWindow::instance();
     outputwindow->appendCommand(QLatin1String("Indexed files status (C=Checked Out, H=Hijacked, ?=Missing)"));
     bool anymod = false;
-    for (StatusMap::ConstIterator it = s_statusMap.constBegin();
-         it != s_statusMap.constEnd();
+    for (StatusMap::ConstIterator it = m_statusMap->constBegin();
+         it != m_statusMap->constEnd();
          ++it)
     {
         char cstat = 0;
@@ -1266,13 +1267,13 @@ bool ClearCasePlugin::vcsOpen(const QString &workingDir, const QString &fileName
     const QString title = QString::fromLatin1("Checkout %1").arg(file);
     CheckOutDialog coDialog(title);
     if (!m_settings.disableIndexer &&
-            (fi.isWritable() || s_statusMap[relFile].status == FileStatus::Unknown))
+            (fi.isWritable() || m_statusMap->value(relFile).status == FileStatus::Unknown))
         QtConcurrent::run(&sync, topLevel, QStringList(relFile)).waitForFinished();
-    if (s_statusMap[relFile].status == FileStatus::CheckedOut) {
+    if (m_statusMap->value(relFile).status == FileStatus::CheckedOut) {
         QMessageBox::information(0, tr("ClearCase Checkout"), tr("File is already checked out."));
         return true;
     }
-    bool isHijacked = (s_statusMap[relFile].status & FileStatus::Hijacked);
+    bool isHijacked = (m_statusMap->value(relFile).status & FileStatus::Hijacked);
     if (!isHijacked)
         coDialog.hideHijack();
     if (coDialog.exec() == QDialog::Accepted) {
@@ -1693,7 +1694,7 @@ void ClearCasePlugin::updateIndex()
     if (!project)
         return;
     m_checkInAllAction->setEnabled(false);
-    s_statusMap.clear();
+    m_statusMap->clear();
     QFuture<void> result = QtConcurrent::run(&sync, currentState().topLevel(),
                project->files(ProjectExplorer::Project::ExcludeGeneratedFiles));
     if (!m_settings.disableIndexer)
@@ -1847,109 +1848,11 @@ void ClearCasePlugin::closing()
 void ClearCasePlugin::sync(QFutureInterface<void> &future, QString topLevel, QStringList files)
 {
     ClearCasePlugin *plugin = ClearCasePlugin::instance();
-
-    ClearCaseSettings settings = plugin->settings();
-    QString program = settings.ccBinaryPath;
-    if (program.isEmpty())
-        return;
-    int total = files.size();
-    bool hot = (total < 10);
-    int processed = 0;
-    QString view = plugin->currentView();
-    if (view.isEmpty())
-        plugin->updateStreamAndView();
-    if (!hot)
-        total = settings.totalFiles.value(view, total);
-
-    // refresh activities list
-    plugin->refreshActivities();
-
-    if (settings.disableIndexer)
-        return;
-    QStringList vobs;
-    if (!settings.indexOnlyVOBs.isEmpty())
-        vobs = settings.indexOnlyVOBs.split(QLatin1Char(','));
-    else
-        vobs = plugin->ccGetActiveVobs();
-    QDir topLevelDir(topLevel);
-    QStringList args(QLatin1String("ls"));
-    if (hot) {
-        // find all files whose permissions changed OR hijacked files
-        // (might have become checked out)
-        foreach (const QString &file, s_statusMap.keys()) {
-            bool permChanged =
-                    s_statusMap[file].permissions != QFileInfo(topLevel, file).permissions();
-            if (permChanged || s_statusMap[file].status == FileStatus::Hijacked) {
-                files.append(file);
-                s_statusMap[file].status = FileStatus::Unknown;
-                ++total;
-            }
-        }
-        args << files;
-    } else {
-        foreach (const QString &file, files)
-            plugin->setStatus(topLevelDir.relativeFilePath(file), FileStatus::Unknown, false);
-        args << QLatin1String("-recurse");
-        args << vobs;
-    }
-
-    // adding 1 for initial sync in which total is not accurate, to prevent finishing
-    // (we don't want it to become green)
-    future.setProgressRange(0, total + 1);
-    QProcess process;
-    process.setWorkingDirectory(topLevel);
-    process.start(program, args);
-    if (!process.waitForStarted())
-        return;
-    QString buffer;
-    while (process.waitForReadyRead() && !future.isCanceled()) {
-        while (process.state() == QProcess::Running &&
-               process.bytesAvailable() && !future.isCanceled())
-        {
-            QString line = QString::fromLocal8Bit(process.readLine().constData());
-            buffer += line;
-            if (buffer.endsWith(QLatin1Char('\n')) || process.atEnd()) {
-                int atatpos = buffer.indexOf(QLatin1String("@@"));
-                if (atatpos != -1) { // probably managed file
-                    // find first whitespace. anything before that is not interesting
-                    int wspos = buffer.indexOf(QRegExp(QLatin1String("\\s")));
-                    const QString file = QDir::fromNativeSeparators(buffer.left(atatpos));
-                    QString ccState;
-                    QRegExp reState(QLatin1String("^\\s*\\[[^\\]]*\\]")); // [hijacked]; [loaded but missing]
-                    if (reState.indexIn(buffer, wspos + 1, QRegExp::CaretAtOffset) != -1) {
-                        ccState = reState.cap();
-                        if (ccState.indexOf(QLatin1String("hijacked")) != -1)
-                            plugin->setStatus(file, FileStatus::Hijacked, true);
-                        else if (ccState.indexOf(QLatin1String("loaded but missing")) != -1)
-                            plugin->setStatus(file, FileStatus::Missing, false);
-                    }
-                    else if (buffer.lastIndexOf(QLatin1String("CHECKEDOUT"), wspos) != -1)
-                        plugin->setStatus(file, FileStatus::CheckedOut, true);
-                    // don't care about checked-in files not listed in project
-                    else if (s_statusMap.contains(file))
-                        plugin->setStatus(file, FileStatus::CheckedIn, false);
-                }
-                buffer.clear();
-                future.setProgressValue(qMin(total, ++processed));
-            }
-        }
-    }
-
-    if (!future.isCanceled()) {
-        foreach (const QString &file, files) {
-            QString relFile = topLevelDir.relativeFilePath(file);
-            if (s_statusMap[relFile].status == FileStatus::Unknown)
-                plugin->setStatus(relFile, FileStatus::NotManaged, false);
-        }
-        future.setProgressValue(total + 1);
-        if (!hot) {
-            settings.totalFiles[view] = processed;
-            plugin->setSettings(settings);
-        }
-    }
-    if (process.state() == QProcess::Running)
-        process.kill();
-    process.waitForFinished();
+    ClearCaseSync ccSync(plugin, plugin->m_statusMap);
+    connect(&ccSync, SIGNAL(updateStreamAndView()), plugin, SLOT(updateStreamAndView()));
+    connect(&ccSync, SIGNAL(setStatus(QString, ClearCase::Internal::FileStatus::Status, bool)),
+            plugin, SLOT(setStatus(QString, ClearCase::Internal::FileStatus::Status, bool)));
+    ccSync.run(future, topLevel, files);
 }
 
 } // namespace Internal
diff --git a/src/plugins/clearcase/clearcaseplugin.h b/src/plugins/clearcase/clearcaseplugin.h
index b3c1cc11180edc36ac6700250cf40e72477c708c..144dd709b8534e99c4caf685cecda8b1bcad4655 100644
--- a/src/plugins/clearcase/clearcaseplugin.h
+++ b/src/plugins/clearcase/clearcaseplugin.h
@@ -39,6 +39,8 @@
 #include <QFile>
 #include <QPair>
 #include <QStringList>
+#include <QMetaType>
+#include <QSharedPointer>
 
 QT_BEGIN_NAMESPACE
 class QAction;
@@ -145,11 +147,14 @@ public:
                   const QString &fileName, const QString &file2 = QString());
     FileStatus vcsStatus(const QString &file) const;
     QString currentView() const { return m_view; }
+    void refreshActivities();
 
 public slots:
     void vcsAnnotate(const QString &workingDir, const QString &file,
                      const QString &revision = QString(), int lineNumber = -1) const;
     bool newActivity();
+    void updateStreamAndView();
+    void setStatus(const QString &file, ClearCase::Internal::FileStatus::Status status, bool update = true);
 
 private slots:
     void checkOutCurrentFile();
@@ -179,7 +184,6 @@ protected:
     void updateActions(VcsBase::VcsBasePlugin::ActionState);
     bool submitEditorAboutToClose(VcsBase::VcsBaseSubmitEditor *submitEditor);
     QString ccGet(const QString &workingDir, const QString &file, const QString &prefix = QString());
-    void refreshActivities();
     QList<QStringPair> ccGetActivities() const;
 
 private:
@@ -204,7 +208,6 @@ private:
     void cleanCheckInMessageFile();
     inline ClearCaseControl *clearCaseControl() const;
     QString ccGetFileActivity(const QString &workingDir, const QString &file);
-    void setStatus(const QString &file, FileStatus::Status status, bool update = true);
     QStringList ccGetActivityVersions(const QString &workingDir, const QString &activity);
     void updateStatusActions();
     void diffGraphical(const QString &file1, const QString &file2 = QString());
@@ -214,11 +217,9 @@ private:
     QString runExtDiff(const QString &workingDir, const QStringList &arguments,
                        int timeOut, QTextCodec *outputCodec = 0);
     QString ccGetView(const QString &workingDir, bool *isDynamic = 0) const;
-    void updateStreamAndView();
 
     ClearCaseSettings m_settings;
 
-    static StatusMap s_statusMap;
     QString m_checkInMessageFileName;
     QString m_topLevel;
     QString m_stream;
@@ -251,6 +252,7 @@ private:
     bool m_submitActionTriggered;
     QMutex *m_activityMutex;
     QList<QStringPair> m_activities;
+    QSharedPointer<StatusMap> m_statusMap;
 
     static ClearCasePlugin *m_clearcasePluginInstance;
 };
@@ -258,4 +260,6 @@ private:
 } // namespace Internal
 } // namespace ClearCase
 
+Q_DECLARE_METATYPE(ClearCase::Internal::FileStatus::Status)
+
 #endif // CLEARCASEPLUGIN_H
diff --git a/src/plugins/clearcase/clearcasesync.cpp b/src/plugins/clearcase/clearcasesync.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3877e62596fee6059475718d673d6ab900f1faa3
--- /dev/null
+++ b/src/plugins/clearcase/clearcasesync.cpp
@@ -0,0 +1,125 @@
+#include "clearcasesync.h"
+
+#include <QDir>
+#include <QFutureInterface>
+#include <QProcess>
+#include <QStringList>
+
+namespace ClearCase {
+namespace Internal {
+
+ClearCaseSync::ClearCaseSync(ClearCasePlugin *plugin, QSharedPointer<StatusMap> statusMap) :
+    m_plugin(plugin),
+    m_statusMap(statusMap)
+{
+}
+
+void ClearCaseSync::run(QFutureInterface<void> &future, const QString &topLevel, QStringList &files)
+{
+    ClearCaseSettings settings = m_plugin->settings();
+    QString program = settings.ccBinaryPath;
+    if (program.isEmpty())
+        return;
+    int total = files.size();
+    bool hot = (total < 10);
+    int processed = 0;
+    QString view = m_plugin->currentView();
+    if (view.isEmpty())
+        emit updateStreamAndView();
+    if (!hot)
+        total = settings.totalFiles.value(view, total);
+
+    // refresh activities list
+    m_plugin->refreshActivities();
+
+    if (settings.disableIndexer)
+        return;
+    QStringList vobs;
+    if (!settings.indexOnlyVOBs.isEmpty())
+        vobs = settings.indexOnlyVOBs.split(QLatin1Char(','));
+    else
+        vobs = m_plugin->ccGetActiveVobs();
+    QDir topLevelDir(topLevel);
+    QStringList args(QLatin1String("ls"));
+    if (hot) {
+        // find all files whose permissions changed OR hijacked files
+        // (might have become checked out)
+        foreach (const QString &file, m_statusMap->keys()) {
+            bool permChanged =
+                    m_statusMap->value(file).permissions != QFileInfo(topLevel, file).permissions();
+            if (permChanged || m_statusMap->value(file).status == FileStatus::Hijacked) {
+                files.append(file);
+                (*m_statusMap)[file].status = FileStatus::Unknown;
+                ++total;
+            }
+        }
+        args << files;
+    } else {
+        foreach (const QString &file, files)
+            emit setStatus(topLevelDir.relativeFilePath(file), FileStatus::Unknown, false);
+        args << QLatin1String("-recurse");
+        args << vobs;
+    }
+
+    // adding 1 for initial sync in which total is not accurate, to prevent finishing
+    // (we don't want it to become green)
+    future.setProgressRange(0, total + 1);
+    QProcess process;
+    process.setWorkingDirectory(topLevel);
+    process.start(program, args);
+    if (!process.waitForStarted())
+        return;
+    QString buffer;
+    while (process.waitForReadyRead() && !future.isCanceled()) {
+        while (process.state() == QProcess::Running &&
+               process.bytesAvailable() && !future.isCanceled())
+        {
+            QString line = QString::fromLocal8Bit(process.readLine().constData());
+            buffer += line;
+            if (buffer.endsWith(QLatin1Char('\n')) || process.atEnd()) {
+                int atatpos = buffer.indexOf(QLatin1String("@@"));
+                if (atatpos != -1) { // probably managed file
+                    // find first whitespace. anything before that is not interesting
+                    int wspos = buffer.indexOf(QRegExp(QLatin1String("\\s")));
+                    const QString file = QDir::fromNativeSeparators(buffer.left(atatpos));
+                    QString ccState;
+                    QRegExp reState(QLatin1String("^\\s*\\[[^\\]]*\\]")); // [hijacked]; [loaded but missing]
+                    if (reState.indexIn(buffer, wspos + 1, QRegExp::CaretAtOffset) != -1) {
+                        ccState = reState.cap();
+                        if (ccState.indexOf(QLatin1String("hijacked")) != -1)
+                            emit setStatus(file, FileStatus::Hijacked, true);
+                        else if (ccState.indexOf(QLatin1String("loaded but missing")) != -1)
+                            emit setStatus(file, FileStatus::Missing, false);
+                    }
+                    else if (buffer.lastIndexOf(QLatin1String("CHECKEDOUT"), wspos) != -1)
+                        emit setStatus(file, FileStatus::CheckedOut, true);
+                    // don't care about checked-in files not listed in project
+                    else if (m_statusMap->contains(file))
+                        emit setStatus(file, FileStatus::CheckedIn, true);
+                }
+                buffer.clear();
+                future.setProgressValue(qMin(total, ++processed));
+            }
+        }
+    }
+
+    if (!future.isCanceled()) {
+        foreach (const QString &file, files) {
+            QString relFile = topLevelDir.relativeFilePath(file);
+            if (m_statusMap->value(relFile).status == FileStatus::Unknown)
+                emit setStatus(relFile, FileStatus::NotManaged, false);
+        }
+        future.setProgressValue(total + 1);
+        if (!hot) {
+            settings = m_plugin->settings(); // Might have changed while task was running
+            settings.totalFiles[view] = processed;
+            m_plugin->setSettings(settings);
+        }
+    }
+    if (process.state() == QProcess::Running)
+        process.kill();
+    process.waitForFinished();
+}
+
+} // namespace Internal
+} // namespace ClearCase
diff --git a/src/plugins/clearcase/clearcasesync.h b/src/plugins/clearcase/clearcasesync.h
new file mode 100644
index 0000000000000000000000000000000000000000..a529a83021222b2b3ba7578db2070b0e7d1b1f5e
--- /dev/null
+++ b/src/plugins/clearcase/clearcasesync.h
@@ -0,0 +1,28 @@
+#ifndef CLEARCASESYNC_H
+#define CLEARCASESYNC_H
+
+#include "clearcaseplugin.h"
+
+namespace ClearCase {
+namespace Internal {
+
+class ClearCaseSync : public QObject
+{
+    Q_OBJECT
+public:
+    explicit ClearCaseSync(ClearCasePlugin *plugin, QSharedPointer<StatusMap> statusMap);
+    void run(QFutureInterface<void> &future, const QString &topLevel, QStringList &files);
+
+signals:
+    void updateStreamAndView();
+    void setStatus(const QString &file, ClearCase::Internal::FileStatus::Status status, bool update);
+
+private:
+    ClearCasePlugin *m_plugin;
+    QSharedPointer<StatusMap> m_statusMap;
+};
+
+} // namespace Internal
+} // namespace ClearCase
+
+#endif // CLEARCASESYNC_H