diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index a0330789c9cba38538f62a37e40d8199b6c8f3f1..8b1df8fbc23cd983aa1b2bb659aadb85832e1b99 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -134,9 +134,22 @@ signals:
     void aboutToSaveSettings();
 
 protected:
-    // restore all data from the map.
+    // The methods toMap/fromMap are used for serialization of settings data. By default, all
+    // settings are saved in the .user file. For shared settings, one needs to explicitly
+    // specify which keys from a particular map should be saved in the .shared file. This is
+    // done in the following way:
     //
-    // Note: Do not forget to call your base class' fromMap method!
+    //  - Create an item in the map with the key SHARED_SETTINGS_KEYS_KEY and a QStringList
+    //    as a value. If everything from this particular map should be shared simply add
+    //    the unique item ALL_SETTINGS_KEYS_KEY to the QStringList. Otherwise, add to the
+    //    QStringList the keys that should be shared.
+    //
+    // Notice that the sharing process is smart enough in terms of recursion and grouping of
+    // keys. This means that shared keys from deeply nested maps don't need to be propagated
+    // anyhow to the top-level map. Simply add them from within the map they actually belong.
+    //
+    // The other thing to notice is that shared keys are not really excluded from the user
+    // settings file. More details about that in the SettingsAcessor.
     virtual bool fromMap(const QVariantMap &map);
 
     virtual void setProjectContext(Core::Context context);
diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h
index a6c71948922171045d56f55cec5374db2af25a7f..002f7e49133034a5927c4c4c51e031e1f156e789 100644
--- a/src/plugins/projectexplorer/projectexplorerconstants.h
+++ b/src/plugins/projectexplorer/projectexplorerconstants.h
@@ -217,6 +217,10 @@ const int QML_DEFAULT_DEBUG_SERVER_PORT = 3768;
 // Default directory to run custom (build) commands in.
 const char DEFAULT_WORKING_DIR[] = "%{buildDir}";
 
+// Settings files keys
+const char SHARED_SETTINGS_KEYS_KEY[] = "ProjectExplorer.SharedSettingsKeysKey";
+const char ALL_SETTINGS_KEYS_KEY[] = "ProjectExplorer.AllSettingsKeysKey";
+
 } // namespace Constants
 } // namespace ProjectExplorer
 
diff --git a/src/plugins/projectexplorer/settingsaccessor.cpp b/src/plugins/projectexplorer/settingsaccessor.cpp
index f7653d745292c7bc6ec8de59faba353b8891aa61..edacf0c18041620188023b5dda8456ecfc6b5c77 100644
--- a/src/plugins/projectexplorer/settingsaccessor.cpp
+++ b/src/plugins/projectexplorer/settingsaccessor.cpp
@@ -120,6 +120,8 @@ namespace {
 const char VERSION_KEY[] = "ProjectExplorer.Project.Updater.FileVersion";
 const char ENVIRONMENT_ID_KEY[] = "ProjectExplorer.Project.Updater.EnvironmentId";
 
+const char USE_SHARED_SETTINGS[] = "UseSharedSettings";
+
 // Version 0 is used in Qt Creator 1.3.x and
 // (in a slighly different flavour) post 1.3 master.
 class Version0Handler : public UserFileVersionHandler
@@ -390,7 +392,13 @@ SettingsAccessor::SettingsAccessor() :
     m_userFileAcessor(QByteArray("qtcUserFileName"),
                       QLatin1String(".user"),
                       QString::fromLocal8Bit(qgetenv("QTC_EXTENSION")),
-                      true)
+                      true,
+                      true),
+    m_sharedFileAcessor(QByteArray("qtcSharedFileName"),
+                        QLatin1String(".shared"),
+                        QString::fromLocal8Bit(qgetenv("QTC_SHARED_EXTENSION")),
+                        false,
+                        false)
 {
     addVersionHandler(new Version0Handler);
     addVersionHandler(new Version1Handler);
@@ -415,16 +423,74 @@ SettingsAccessor *SettingsAccessor::instance()
     return &acessor;
 }
 
+namespace {
+
+// For the functions below, the full map must prepopulated with the user settings so it
+// has the corresponding keys for the ones in the shared settings (remember that the
+// shared settings are backedup in the user settings).
+
+void mergeSharedSettings(QVariantMap *fullMap, const QVariantMap &sharedMap)
+{
+    QVariantMap::const_iterator it = sharedMap.begin();
+    QVariantMap::const_iterator eit = sharedMap.end();
+    for (; it != eit; ++it) {
+        const QString &key = it.key();
+        QVariant value = it.value();
+        if (value.type() == QVariant::Map) {
+            const QVariant &correspondingValue = fullMap->value(key);
+            if (correspondingValue.type() != QVariant::Map) {
+                // This should happen only if the user manually changed the file in such a way.
+                continue;
+            }
+            QVariantMap nestedMap = correspondingValue.toMap();
+            mergeSharedSettings(&nestedMap, value.toMap());
+            value = nestedMap;
+        }
+        if (fullMap->contains(key))
+            fullMap->insert(key, value); // Replace with the shared setting.
+    }
+}
+
+void splitSharedSettings(QVariantMap *sharedMap, const QVariantMap &fullMap)
+{
+    const QStringList &controlKey =
+            fullMap.value(QLatin1String(Constants::SHARED_SETTINGS_KEYS_KEY)).toStringList();
+    if (controlKey.size() == 1
+            && controlKey.at(0) == QLatin1String(Constants::ALL_SETTINGS_KEYS_KEY)) {
+        *sharedMap = fullMap;
+    } else {
+        const QSet<QString> &shared = QSet<QString>::fromList(controlKey);
+        QVariantMap::iterator it = fullMap.begin();
+        QVariantMap::iterator eit = fullMap.end();
+        for (; it != eit; ++it) {
+            const QString &key = it.key();
+            const QVariant &value = it.value();
+            if (shared.contains(key)) {
+                sharedMap->insert(key, value);
+            } else {
+                if (value.type() == QVariant::Map) {
+                    QVariantMap nestedMap;
+                    splitSharedSettings(&nestedMap, value.toMap());
+                    if (!nestedMap.isEmpty())
+                        sharedMap->insert(key, nestedMap);
+                }
+            }
+        }
+    }
+}
+
+} // Anonymous
+
 QVariantMap SettingsAccessor::restoreSettings(Project *project) const
 {
     if (m_lastVersion < 0 || !project)
         return QVariantMap();
 
-    SettingsData settings;
-    if (!m_userFileAcessor.readFile(project, &settings))
+    SettingsData userSettings;
+    if (!m_userFileAcessor.readFile(project, &userSettings))
         return QVariantMap();
 
-    if (settings.m_version > SettingsAccessor::instance()->m_lastVersion + 1) {
+    if (userSettings.m_version > SettingsAccessor::instance()->m_lastVersion + 1) {
         QMessageBox::information(
                     Core::ICore::instance()->mainWindow(),
                     QApplication::translate("ProjectExplorer::SettingsAccessor",
@@ -442,7 +508,7 @@ QVariantMap SettingsAccessor::restoreSettings(Project *project) const
     }
 
     // Verify environment.
-    if (!verifyEnvironmentId(settings.m_map.value(QLatin1String(ENVIRONMENT_ID_KEY)).toString())) {
+    if (!verifyEnvironmentId(userSettings.m_map.value(QLatin1String(ENVIRONMENT_ID_KEY)).toString())) {
         // TODO tr, casing check
         QMessageBox msgBox(
                     QMessageBox::Question,
@@ -465,19 +531,72 @@ QVariantMap SettingsAccessor::restoreSettings(Project *project) const
     }
 
     // Do we need to generate a backup?
-    if (settings.m_version < m_lastVersion + 1 && !settings.m_usingBackup) {
-        const QString &backupFileName = settings.m_fileName
+    if (userSettings.m_version < m_lastVersion + 1 && !userSettings.m_usingBackup) {
+        const QString &backupFileName = userSettings.m_fileName
                 + '.'
-                + m_handlers.value(settings.m_version)->displayUserFileVersion();
+                + m_handlers.value(userSettings.m_version)->displayUserFileVersion();
         QFile::remove(backupFileName);  // Remove because copy doesn't overwrite
-        QFile::copy(settings.m_fileName, backupFileName);
+        QFile::copy(userSettings.m_fileName, backupFileName);
+    }
+
+
+    // Time to restore the shared settings.
+    bool useSharedSettings = true;
+    int commonFileVersion = userSettings.m_version;
+    SettingsData sharedSettings;
+    if (m_sharedFileAcessor.readFile(project, &sharedSettings)) {
+        if (sharedSettings.m_version != userSettings.m_version) {
+            // At this point the user file version can only be <= Creator's version. This is not
+            // true for the shared file version. In the case the shared version is newer than
+            // Creator's we prompt the user whether we could try an *unsupported* update. This
+            // makes sense for the shared file since the merging operation will only replace the
+            // settings that actually match the corresponding ones in the user file.
+            if (sharedSettings.m_version > m_lastVersion + 1) {
+                QMessageBox msgBox(
+                            QMessageBox::Question,
+                            QApplication::translate("ProjectExplorer::SettingsAccessor",
+                                                    "Unsupported Shared Settings File"),
+                            QApplication::translate("ProjectExplorer::SettingsAccessor",
+                                                    "The version of your .shared file is not yet "
+                                                    "supported. Qt Creator can still load it and "
+                                                    "look for compatible settings (the file will "
+                                                    "be overwritten).\n\n"
+                                                    "Do you want to continue?\n\n"
+                                                    "If you choose not to continue Qt Creator will "
+                                                    "use the corresponding settings which are "
+                                                    "backed-up in your .user file.\n\n"),
+                            QMessageBox::Yes | QMessageBox::No,
+                            Core::ICore::instance()->mainWindow());
+                msgBox.setDefaultButton(QMessageBox::No);
+                msgBox.setEscapeButton(QMessageBox::No);
+                if (msgBox.exec() == QMessageBox::No)
+                    useSharedSettings = false;
+                else
+                    commonFileVersion = m_lastVersion + 1;
+            } else {
+                commonFileVersion = qMax(userSettings.m_version, sharedSettings.m_version);
+            }
+
+            if (useSharedSettings) {
+                // We now update the user and shared settings so they are compatible.
+                for (int i = userSettings.m_version; i < commonFileVersion; ++i)
+                    userSettings.m_map = m_handlers.value(i)->update(project, userSettings.m_map);
+                for (int i = sharedSettings.m_version; i < commonFileVersion; ++i)
+                    sharedSettings.m_map = m_handlers.value(i)->update(project, sharedSettings.m_map);
+            }
+        }
     }
 
-    // Update version.
-    for (int i = settings.m_version; i <= m_lastVersion; ++i)
-        settings.m_map = m_handlers.value(i)->update(project, settings.m_map);
+    QVariantMap mergeMap = userSettings.m_map;
+    if (useSharedSettings && !sharedSettings.m_map.isEmpty())
+        mergeSharedSettings(&mergeMap, sharedSettings.m_map);
+    project->setProperty(USE_SHARED_SETTINGS, useSharedSettings);
+
+    // Finally update from the common version to Creator's version.
+    for (int i = commonFileVersion; i <= m_lastVersion; ++i)
+        mergeMap = m_handlers.value(i)->update(project, mergeMap);
 
-    return settings.m_map;
+    return mergeMap;
 }
 
 bool SettingsAccessor::saveSettings(const Project *project, const QVariantMap &map) const
@@ -486,7 +605,16 @@ bool SettingsAccessor::saveSettings(const Project *project, const QVariantMap &m
         return false;
 
     SettingsData settings(map);
-    return m_userFileAcessor.writeFile(project, &settings);
+    if (m_userFileAcessor.writeFile(project, &settings)) {
+        if (!project->property(USE_SHARED_SETTINGS).toBool())
+            return true;
+
+        SettingsData sharedSettings;
+        splitSharedSettings(&sharedSettings.m_map, map);
+        return m_sharedFileAcessor.writeFile(project, &sharedSettings);
+    }
+
+    return false;
 }
 
 void SettingsAccessor::addVersionHandler(UserFileVersionHandler *handler)
@@ -536,9 +664,11 @@ bool SettingsAccessor::verifyEnvironmentId(const QString &id)
 SettingsAccessor::FileAccessor::FileAccessor(const QByteArray &id,
                                              const QString &defaultSuffix,
                                              const QString &environmentSuffix,
-                                             bool envSpecific)
+                                             bool envSpecific,
+                                             bool versionStrict)
     : m_id(id)
     , m_environmentSpecific(envSpecific)
+    , m_versionStrict(versionStrict)
 {
     assignSuffix(defaultSuffix, environmentSuffix);
 }
@@ -636,6 +766,9 @@ bool SettingsAccessor::FileAccessor::readFile(Project *project,
 
     // Get and verify file version
     settings->m_version = settings->m_map.value(QLatin1String(VERSION_KEY), 0).toInt();
+    if (!m_versionStrict)
+        return true;
+
     if (settings->m_version < SettingsAccessor::instance()->m_firstVersion) {
         qWarning() << "Version" << settings->m_version << "in" << m_suffix << "too old.";
         return false;
diff --git a/src/plugins/projectexplorer/settingsaccessor.h b/src/plugins/projectexplorer/settingsaccessor.h
index b59665da760f1b578112216322136f3db2ccb7aa..55e4663b4f7258d589b540b97e7fd799c01e0fe3 100644
--- a/src/plugins/projectexplorer/settingsaccessor.h
+++ b/src/plugins/projectexplorer/settingsaccessor.h
@@ -44,6 +44,35 @@ namespace Internal {
 class UserFileVersionHandler;
 }
 
+/*
+  The SettingsAcessor
+
+  The SettingsAcessor currently persists a user-specific file and a shared file. By default
+  settings are user-specific and the shared ones are identified through the key
+  SHARED_SETTINGS_KEYS_KEY in the map. The corresponding value for this key must be a
+  QStringList containing the keys from this particular map that should be shared. As an aid,
+  if the QStringList contains a unique item ALL_SETTINGS_KEYS_KEY all keys from the map
+  are considered shared.
+
+  While we are very strict regarding versions from the user settings (we create backups for
+  old versions, always try to find the correct file, etc), this is not the same for the shared
+  files. When considering many usability aspects and issues like having them in repositories
+  (and unintenional overwrites when pulling), simply passing them around, matching their
+  version against the user version, it seems that the more simplistic approach would be the
+  best (at least for now).
+
+  The idea is that shared settings are never removed from the user settings file, they work
+  as a backup when the different "synchronization" issues arise. We then make sure that
+  whenever settings are restored we start with the user ones and eventually merge the shared
+  ones into the final map, replacing the corresponding ones in the user map (so the shared
+  ones take precedences). An analoguous behavior happens when saving the settings.
+
+  The main benefit of this approach is that we always try to use the shared settings. When
+  possible we run the version update handlers and make the shared settings compatible with
+  the user settings (or vice-versa). From that on it's transparent for handlers to update
+  the settings to the current Creator version (if it's the case) since it's just one map.
+
+ */
 class SettingsAccessor
 {
 public:
@@ -80,7 +109,8 @@ private:
         FileAccessor(const QByteArray &id,
                      const QString &defaultSuffix,
                      const QString &environmentSuffix,
-                     bool envSpecific);
+                     bool envSpecific,
+                     bool versionStrict);
 
         bool readFile(Project *project, SettingsData *settings) const;
         bool writeFile(const Project *project, const SettingsData *settings) const;
@@ -93,6 +123,7 @@ private:
         QByteArray m_id;
         QString m_suffix;
         bool m_environmentSpecific;
+        bool m_versionStrict;
     };
 
     static bool verifyEnvironmentId(const QString &id);
@@ -101,6 +132,7 @@ private:
     int m_firstVersion;
     int m_lastVersion;
     const FileAccessor m_userFileAcessor;
+    const FileAccessor m_sharedFileAcessor;
 };
 
 } // namespace ProjectExplorer