diff --git a/bin/gdbmacros/gdbmacros.cpp b/bin/gdbmacros/gdbmacros.cpp
index 0d6575db5b71146b65f7e86cd58582e4030cc895..199b783f45d137abf09d79d56ddcb25e43cf6bc0 100644
--- a/bin/gdbmacros/gdbmacros.cpp
+++ b/bin/gdbmacros/gdbmacros.cpp
@@ -1674,7 +1674,10 @@ static void qDumpQObjectSignal(QDumper &d)
             d.beginHash();
                 P(d, "name", "[" << i << "] slot");
                 P(d, "type", "");
-                P(d, "value", conn.receiver->metaObject()->method(conn.method).signature());
+                if (conn.receiver) 
+                    P(d, "value", conn.receiver->metaObject()->method(conn.method).signature());
+                else
+                    P(d, "value", "<invalid receiver>");
                 P(d, "numchild", "0");
             d.endHash();
             d.beginHash();
@@ -1861,17 +1864,25 @@ static void qDumpQSet(QDumper &d)
             n = 100;
         d << ",children=[";
         int i = 0;
-        for (int bucket = 0; bucket != hd->numBuckets; ++bucket) {
+        for (int bucket = 0; bucket != hd->numBuckets && i <= 10000; ++bucket) {
             for (node = hd->buckets[bucket]; node->next; node = node->next) {
                 d.beginHash();
                 P(d, "name", "[" << i << "]");
                 P(d, "type", d.innertype);
-                P(d, "exp", "(('QHashNode<" << d.innertype
-                    << ",QHashDummyValue>'*)"
+                P(d, "exp", "(('"NS"QHashNode<" << d.innertype
+                    << ","NS"QHashDummyValue>'*)"
                     << static_cast<const void*>(node) << ")->key"
                 );
                 d.endHash();
                 ++i;
+                if (i > 10000) {
+                    d.beginHash();
+                    P(d, "name", "Warning:");
+                    P(d, "value", "<incomplete>");
+                    P(d, "type", "");
+                    d.endHash();
+                    break;
+                }
             }
         }
         d << "]";
diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc
index 4521b7e2fa4317c8eec094fc53e23be12ebfcc7b..4dd7a5fb53cd06eb302a26c27f78971d0a125540 100644
--- a/doc/qtcreator.qdoc
+++ b/doc/qtcreator.qdoc
@@ -950,24 +950,23 @@
     You can start Qt Creator from a command prompt with an existing session or
     \c{.pro} file by giving the name as argument on the command line.
 
-    \bold{Sidebar}
+    \bold{Show and Hide the Sidebar}
 
-    You can hide/unhide the sidebar in the edit and debug mode
-    by clicking on the corresponding icon on the left bottom.
-    Keyboard shortcut is \key{Alt+0}.
+    You can show and hide the the sidebar in \gui Edit and \gui Debug mode by
+    clicking on the corresponding icon, or by pressing \key{Alt+0}.
 
-    \bold{Display signals and slots}
+    \bold{Display Signals and Slots}
 
-    If you have an instance of a class derived from QObject and 
-    want to find all other objects connected to one of its
-    slots by Qt's signals-and-slots mechanism, enable
-    \gui{Debug} and \gui{Use Custom Display for Qt Objects}.
-    In the \gui{Locals and Watchers View}, expand the object's
-    entry and open the wanted slot in the "slots" subitem. The
-    objects connect to this slot are exposed as children of
-    this slot. The same works with signals.
+    If you have an instance of a class that is derived from QObject, and you
+    you would like to find all other objects connected to one of your object's
+    slots using Qt's signals and slots mechanism -- you can enable
+    \gui{Use Custom Display for Qt Objects} feature under the \gui Debug menu.
 
-    \bold{Low level display}
+    In the \gui{Locals and Watchers} view, expand the object's entry and open
+    the slot in the \e slots subitem. The objects connected to this slot are
+    exposed as children of the slot. This method works with signals too.
+
+    \bold{Display Low Level Data}
 
     If the special debugging of Qt objects fails due to data
     corruption within the debugged objects, you can switch the
@@ -983,33 +982,38 @@
 
     \title Glossary
 
-    \bold{System Qt}
-
-    \target glossary-system-qt
-    The version of Qt installed on your system.
-    This is the one whose \c qmake command is found in the \c PATH.
-
-    \bold{Default Qt}
-
-    \target glossary-default-qt
-    The version of Qt configured in \gui{Tools
-    -> Options -> Qt 4 -> Default Qt Version}. This is the version
-    used by new projects. It defaults to the System Qt.
+    \table
+        \header
+            \o  Term
+            \o  Meaning
 
-    \bold{Project Qt}
+        \row
+            \o  System Qt   \target glossary-system-qt
+            \o  The version of Qt installed on your system. This is the Qt
+                version for the \c qmake command found in your \c PATH.
 
-    \target glossary-project-qt
-    The version of Qt configured in \gui{Build&Run
-    -> Build Settings -> Build Configurations}. This is the version
-    actually used by the project. It defaults to the Default Qt.
+        \row
+            \o  Default Qt  \target glossary-default-qt
+            \o  The version of Qt configured in \gui{Tools -> Options -> Qt 4
+                -> Default Qt Version}. This is the Qt version used by your
+                new projects. It defaults to System Qt.
 
-    \bold{Shadow Build}
+        \row
+            \o  Project Qt  \target glossary-project-qt
+            \o  The version of Qt configured in \gui{Build&Run -> Build
+                Settings -> Build Configurations}. This is the Qt version that
+                is actually used by a particular project. It defaults to
+                Default Qt.
 
-    \target glossary-shadow-build
-    Shadow building means building the project not in the source directory,
-    but in a seperate \bold{build directory}. This has the benefit of keeping
-    the source directory clean. It is also considered "best practice" if 
-    you need many build configurations for a single set of sources.
+        \row
+            \o  Shadow Build    \target glossary-shadow-build
+            \o  Shadow building means building a project in a separate
+                directory, the \e{build directory}. The build directory is
+                different from the source directory. One of the benefits of
+                shadow building is that it keeps your source directory clean.
+                Shadow building is the best practice if you need many build
+                configurations for a single set of source.
+    \endtable
 
 */
 
diff --git a/shared/help/bookmarkmanager.h b/shared/help/bookmarkmanager.h
index a8afa867e65b92909617f3b4942ff812755e3eb4..c40d8672db0ff2cb8b3770966a38a75e5bbf97f0 100644
--- a/shared/help/bookmarkmanager.h
+++ b/shared/help/bookmarkmanager.h
@@ -95,8 +95,10 @@ private:
     QSortFilterProxyModel *proxyModel;
 };
 
-class TreeView : public QTreeView {
+class TreeView : public QTreeView
+{
     Q_OBJECT
+
 public:
     TreeView(QWidget* parent = 0) : QTreeView(parent) {}
     void subclassKeyPressEvent(QKeyEvent* event)
@@ -159,18 +161,18 @@ class BookmarkManager : public QObject
     Q_OBJECT
 
 public:
-    BookmarkManager(QHelpEngineCore* helpEngine);
+    BookmarkManager(QHelpEngineCore *helpEngine);
     ~BookmarkManager();
 
-    BookmarkModel* treeBookmarkModel();
-    BookmarkModel* listBookmarkModel();
+    BookmarkModel *treeBookmarkModel();
+    BookmarkModel *listBookmarkModel();
 
     void saveBookmarks();
     QStringList bookmarkFolders() const;
-    QModelIndex addNewFolder(const QModelIndex& index);
+    QModelIndex addNewFolder(const QModelIndex &index);
     void removeBookmarkItem(QTreeView *treeView, const QModelIndex& index);
-    void showBookmarkDialog(QWidget* parent, const QString &name, const QString &url);
-    void addNewBookmark(const QModelIndex& index, const QString &name, const QString &url);
+    void showBookmarkDialog(QWidget *parent, const QString &name, const QString &url);
+    void addNewBookmark(const QModelIndex &index, const QString &name, const QString &url);
     void setupBookmarkModels();
 
 private slots:
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 68dfa3e3b231be7a201086037a37c39b0244e8a9..ad61ab0c7505e59127400ca060a44929c1c2960a 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -212,9 +212,9 @@ int main(int argc, char **argv)
     pluginManager.setPluginPaths(pluginPaths);
 
     const QStringList arguments = app.arguments();
-    QMap<QString,QString> foundAppOptions;
+    QMap<QString, QString> foundAppOptions;
     if (arguments.size() > 1) {
-        QMap<QString,bool> appOptions;
+        QMap<QString, bool> appOptions;
         appOptions.insert(QLatin1String(HELP_OPTION1), false);
         appOptions.insert(QLatin1String(HELP_OPTION2), false);
         appOptions.insert(QLatin1String(HELP_OPTION3), false);
diff --git a/src/libs/cplusplus/cplusplus.pro b/src/libs/cplusplus/cplusplus.pro
index 1a2b5326623927b3854057c33d3874e51fff012b..49d78fda8b36d4def16fdfab74c3158cace20339 100644
--- a/src/libs/cplusplus/cplusplus.pro
+++ b/src/libs/cplusplus/cplusplus.pro
@@ -21,7 +21,16 @@ HEADERS += \
     TypeOfExpression.h \
     TypePrettyPrinter.h \
     ResolveExpression.h \
-    LookupContext.h
+    LookupContext.h \
+    pp-cctype.h \
+    pp-engine.h \
+    pp-fwd.h \
+    pp-macro-expander.h \
+    pp-scanner.h \
+    pp-client.h \
+    pp-environment.h \
+    pp-internal.h \
+    pp-macro.h
 
 SOURCES += \
     SimpleLexer.cpp \
@@ -35,6 +44,9 @@ SOURCES += \
     TypeOfExpression.cpp \
     TypePrettyPrinter.cpp \
     ResolveExpression.cpp \
-    LookupContext.cpp
+    LookupContext.cpp \
+    pp-engine.cpp \
+    pp-environment.cpp \
+    pp-macro-expander.cpp
 
 RESOURCES += cplusplus.qrc
diff --git a/src/plugins/cpptools/rpp/pp-cctype.h b/src/libs/cplusplus/pp-cctype.h
similarity index 98%
rename from src/plugins/cpptools/rpp/pp-cctype.h
rename to src/libs/cplusplus/pp-cctype.h
index 62b44f0bf4c4bae72080f836c0074a7e4fe56620..bec9c25aef1c20b99c489f1840b65432061f9b97 100644
--- a/src/plugins/cpptools/rpp/pp-cctype.h
+++ b/src/libs/cplusplus/pp-cctype.h
@@ -55,7 +55,7 @@
 
 #include <cctype>
 
-namespace rpp {
+namespace CPlusPlus {
 
 inline bool pp_isalpha (int __ch)
 { return std::isalpha ((unsigned char) __ch) != 0; }
@@ -69,6 +69,6 @@ inline bool pp_isdigit (int __ch)
 inline bool pp_isspace (int __ch)
 { return std::isspace ((unsigned char) __ch) != 0; }
 
-} // namespace rpp
+} // namespace CPlusPlus
 
 #endif // PP_CCTYPE_H
diff --git a/src/plugins/cpptools/rpp/pp-client.h b/src/libs/cplusplus/pp-client.h
similarity index 97%
rename from src/plugins/cpptools/rpp/pp-client.h
rename to src/libs/cplusplus/pp-client.h
index 974004a6ce50ec85aeb2df035d63c686df19b444..35df6497331e1dc98abac56d058d51178532e0dc 100644
--- a/src/plugins/cpptools/rpp/pp-client.h
+++ b/src/libs/cplusplus/pp-client.h
@@ -38,7 +38,7 @@
 #include <QString>
 #include <QFile>
 
-namespace rpp {
+namespace CPlusPlus {
 
 class Macro;
 
@@ -74,6 +74,6 @@ public:
   virtual void stopSkippingBlocks(unsigned offset) = 0;
 };
 
-} // namespace rpp
+} // namespace CPlusPlus
 
 #endif // PP_CLIENT_H
diff --git a/src/plugins/cpptools/rpp/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
similarity index 99%
rename from src/plugins/cpptools/rpp/pp-engine.cpp
rename to src/libs/cplusplus/pp-engine.cpp
index 66e8957f355e5dc28c25c755b4d86e83d49f5a04..f2e1d4908ebbeba8c8e9932b0c5b31ffe221c402 100644
--- a/src/plugins/cpptools/rpp/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -57,7 +57,6 @@
 #include <QtDebug>
 #include <algorithm>
 
-using namespace rpp;
 using namespace CPlusPlus;
 
 namespace {
diff --git a/src/plugins/cpptools/rpp/pp-engine.h b/src/libs/cplusplus/pp-engine.h
similarity index 98%
rename from src/plugins/cpptools/rpp/pp-engine.h
rename to src/libs/cplusplus/pp-engine.h
index 13135f6a3102f45fab3fdbb5901c83fb1d75afc0..d0729b3715b3942cc12f2358601fc59cd66bdc8f 100644
--- a/src/plugins/cpptools/rpp/pp-engine.h
+++ b/src/libs/cplusplus/pp-engine.h
@@ -62,7 +62,7 @@ namespace CPlusPlus {
     class Token;
 }
 
-namespace rpp {
+namespace CPlusPlus {
 
     struct Value
     {
@@ -200,7 +200,7 @@ namespace rpp {
 
         Value evalExpression(TokenIterator firstToken,
                              TokenIterator lastToken,
-			     const QByteArray &source) const;
+                             const QByteArray &source) const;
 
         QVector<CPlusPlus::Token> tokenize(const QByteArray &text) const;
 
@@ -226,6 +226,6 @@ namespace rpp {
         bool isQtReservedWord(const QByteArray &name) const;
     };
 
-} // namespace rpp
+} // namespace CPlusPlus
 
 #endif // PP_ENGINE_H
diff --git a/src/plugins/cpptools/rpp/pp-environment.cpp b/src/libs/cplusplus/pp-environment.cpp
similarity index 99%
rename from src/plugins/cpptools/rpp/pp-environment.cpp
rename to src/libs/cplusplus/pp-environment.cpp
index 85e432ae5b5ae49c70557cfd835b7db4eddc60d5..b06d41757dda428477fa86b6f4c3d0d669fb1689 100644
--- a/src/plugins/cpptools/rpp/pp-environment.cpp
+++ b/src/libs/cplusplus/pp-environment.cpp
@@ -54,7 +54,7 @@
 #include "pp.h"
 #include <cstring>
 
-using namespace rpp;
+using namespace CPlusPlus;
 
 Environment::Environment ()
     : currentLine(0),
diff --git a/src/plugins/cpptools/rpp/pp-environment.h b/src/libs/cplusplus/pp-environment.h
similarity index 98%
rename from src/plugins/cpptools/rpp/pp-environment.h
rename to src/libs/cplusplus/pp-environment.h
index 5b97c492d799a07d79e20adbef1f74d937e63b73..e3d130871ba7ac880bab24a4b09231b2b1e6bf2c 100644
--- a/src/plugins/cpptools/rpp/pp-environment.h
+++ b/src/libs/cplusplus/pp-environment.h
@@ -56,7 +56,7 @@
 #include <QVector>
 #include <QByteArray>
 
-namespace rpp {
+namespace CPlusPlus {
 
 struct Macro;
 
@@ -104,6 +104,6 @@ private:
     int _hash_count;
 };
 
-} // namespace rpp
+} // namespace CPlusPlus
 
 #endif // PP_ENVIRONMENT_H
diff --git a/src/libs/cplusplus/pp-fwd.h b/src/libs/cplusplus/pp-fwd.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/plugins/cpptools/rpp/pp-internal.h b/src/libs/cplusplus/pp-internal.h
similarity index 98%
rename from src/plugins/cpptools/rpp/pp-internal.h
rename to src/libs/cplusplus/pp-internal.h
index 13bc7c17e84499f304976e46d94a7730605233b4..c11de37453a24fa960a123ecff8c749f76dfb43d 100644
--- a/src/plugins/cpptools/rpp/pp-internal.h
+++ b/src/libs/cplusplus/pp-internal.h
@@ -55,7 +55,7 @@
 
 #include <QByteArray>
 
-namespace rpp {
+namespace CPlusPlus {
 namespace _PP_internal {
 
 inline bool comment_p (const char *__first, const char *__last)
@@ -73,6 +73,6 @@ inline bool comment_p (const char *__first, const char *__last)
 }
 
 } // _PP_internal
-} // namespace rpp
+} // namespace CPlusPlus
 
 #endif // PP_INTERNAL_H
diff --git a/src/plugins/cpptools/rpp/pp-macro-expander.cpp b/src/libs/cplusplus/pp-macro-expander.cpp
similarity index 99%
rename from src/plugins/cpptools/rpp/pp-macro-expander.cpp
rename to src/libs/cplusplus/pp-macro-expander.cpp
index 6b569eb132feea2bbde069809ca9e293666be378..9ae9702fe18fa21dcd240b0f6c4d59ee21fbf5aa 100644
--- a/src/plugins/cpptools/rpp/pp-macro-expander.cpp
+++ b/src/libs/cplusplus/pp-macro-expander.cpp
@@ -35,7 +35,7 @@
 #include "pp-macro-expander.h"
 #include <QDateTime>
 
-using namespace rpp;
+using namespace CPlusPlus;
 
 MacroExpander::MacroExpander (Environment &env, pp_frame *frame)
     : env(env), frame(frame),
diff --git a/src/plugins/cpptools/rpp/pp-macro-expander.h b/src/libs/cplusplus/pp-macro-expander.h
similarity index 98%
rename from src/plugins/cpptools/rpp/pp-macro-expander.h
rename to src/libs/cplusplus/pp-macro-expander.h
index dd11540c33629ac3c391112188d7445a821b6288..c2f636c1385fba0606f17b73dad40c0549f61448 100644
--- a/src/plugins/cpptools/rpp/pp-macro-expander.h
+++ b/src/libs/cplusplus/pp-macro-expander.h
@@ -53,7 +53,7 @@
 #ifndef PP_MACRO_EXPANDER_H
 #define PP_MACRO_EXPANDER_H
 
-namespace rpp {
+namespace CPlusPlus {
 
     struct pp_frame
     {
@@ -97,7 +97,7 @@ namespace rpp {
         int generated_lines;
     };
 
-} // namespace rpp
+} // namespace CPlusPlus
 
 #endif // PP_MACRO_EXPANDER_H
 
diff --git a/src/plugins/cpptools/rpp/pp-macro.h b/src/libs/cplusplus/pp-macro.h
similarity index 98%
rename from src/plugins/cpptools/rpp/pp-macro.h
rename to src/libs/cplusplus/pp-macro.h
index a7bbe35e1d5995488ea78a0f9d86c0740271d040..b091abd618462d549021342f83040ecb9a77c03b 100644
--- a/src/plugins/cpptools/rpp/pp-macro.h
+++ b/src/libs/cplusplus/pp-macro.h
@@ -56,7 +56,7 @@
 #include <QByteArray>
 #include <QVector>
 
-namespace rpp {
+namespace CPlusPlus {
 
     struct Macro
     {
@@ -90,6 +90,6 @@ namespace rpp {
         { }
     };
 
-} // namespace rpp
+} // namespace CPlusPlus
 
 #endif // PP_MACRO_H
diff --git a/src/plugins/cpptools/rpp/pp-scanner.h b/src/libs/cplusplus/pp-scanner.h
similarity index 99%
rename from src/plugins/cpptools/rpp/pp-scanner.h
rename to src/libs/cplusplus/pp-scanner.h
index 53fea70b52fd7fbaf4dd5219e0d610ec1ed0ffec..85b65403b0bdf750252d877029bc56ffce51bf7e 100644
--- a/src/plugins/cpptools/rpp/pp-scanner.h
+++ b/src/libs/cplusplus/pp-scanner.h
@@ -53,7 +53,7 @@
 #ifndef PP_SCANNER_H
 #define PP_SCANNER_H
 
-namespace rpp {
+namespace CPlusPlus {
 
 struct pp_skip_blanks
 {
@@ -373,7 +373,7 @@ struct pp_skip_argument
   }
 };
 
-} // namespace rpp
+} // namespace CPlusPlus
 
 #endif // PP_SCANNER_H
 
diff --git a/src/plugins/cpptools/rpp/pp.h b/src/libs/cplusplus/pp.h
similarity index 100%
rename from src/plugins/cpptools/rpp/pp.h
rename to src/libs/cplusplus/pp.h
diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp
index 340dbcad36a1d7661dd2c76493948d27c58e134c..68ebe9cbbfd429bd1578d4641ac52151e0f8d2d1 100644
--- a/src/libs/utils/pathchooser.cpp
+++ b/src/libs/utils/pathchooser.cpp
@@ -48,40 +48,54 @@
 namespace Core {
 namespace Utils {
 
+#ifdef Q_OS_OSX
+/*static*/ const char * const PathChooser::browseButtonLabel = "Choose...";
+#else
+/*static*/ const char * const PathChooser::browseButtonLabel = "Browse...";
+#endif
+
 // ------------------ PathValidatingLineEdit
 class PathValidatingLineEdit : public BaseValidatingLineEdit {
 public:
-    explicit PathValidatingLineEdit(QWidget *parent = 0);
+    explicit PathValidatingLineEdit(PathChooser *chooser, QWidget *parent = 0);
 
 protected:
     virtual bool validate(const QString &value, QString *errorMessage) const;
+
+private:
+    PathChooser *m_chooser;
 };
 
-PathValidatingLineEdit::PathValidatingLineEdit(QWidget *parent) :
-    BaseValidatingLineEdit(parent)
+PathValidatingLineEdit::PathValidatingLineEdit(PathChooser *chooser, QWidget *parent) :
+    BaseValidatingLineEdit(parent),
+    m_chooser(chooser)
 {
+    Q_ASSERT(chooser != NULL);
 }
 
 bool PathValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
 {
-    return PathChooser::validatePath(value, errorMessage);
+    return m_chooser->validatePath(value, errorMessage);
 }
 
 // ------------------ PathChooserPrivate
 struct PathChooserPrivate {
-    PathChooserPrivate();
+    PathChooserPrivate(PathChooser *chooser);
 
     PathValidatingLineEdit *m_lineEdit;
+    PathChooser::Kind m_acceptingKind;
+    QString m_dialogTitleOverride;
 };
 
-PathChooserPrivate::PathChooserPrivate() :
-    m_lineEdit(new PathValidatingLineEdit)
+PathChooserPrivate::PathChooserPrivate(PathChooser *chooser) :
+    m_lineEdit(new PathValidatingLineEdit(chooser)),
+    m_acceptingKind(PathChooser::Directory)
 {
 }
 
 PathChooser::PathChooser(QWidget *parent) :
     QWidget(parent),
-    m_d(new PathChooserPrivate)
+    m_d(new PathChooserPrivate(this))
 {
     QHBoxLayout *hLayout = new QHBoxLayout;
     hLayout->setContentsMargins(0, 0, 0, 0);
@@ -90,11 +104,12 @@ PathChooser::PathChooser(QWidget *parent) :
     connect(m_d->m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
     connect(m_d->m_lineEdit, SIGNAL(validChanged()), this, SIGNAL(validChanged()));
 
-    m_d->m_lineEdit->setMinimumWidth(300);
+    m_d->m_lineEdit->setMinimumWidth(260);
     hLayout->addWidget(m_d->m_lineEdit);
+    hLayout->setSizeConstraint(QLayout::SetMinimumSize);
 
     QToolButton *browseButton = new QToolButton;
-    browseButton->setText(tr("..."));
+    browseButton->setText(tr(browseButtonLabel));
     connect(browseButton, SIGNAL(clicked()), this, SLOT(slotBrowse()));
 
     hLayout->addWidget(browseButton);
@@ -123,8 +138,28 @@ void PathChooser::slotBrowse()
     QString predefined = path();
     if (!predefined.isEmpty() && !QFileInfo(predefined).isDir())
         predefined.clear();
-    // Prompt for a directory, delete trailing slashes unless it is "/", only
-    QString newPath = QFileDialog::getExistingDirectory(this, tr("Choose a path"), predefined);
+
+    // Prompt for a file/dir
+    QString dialogTitle;
+    QString newPath;
+    switch (m_d->m_acceptingKind) {
+    case PathChooser::Directory:
+        newPath = QFileDialog::getExistingDirectory(this,
+                makeDialogTitle(tr("Choose a directory")), predefined);
+        break;
+
+    case PathChooser::File: // fall through
+    case PathChooser::Command:
+        newPath = QFileDialog::getOpenFileName(this,
+                makeDialogTitle(tr("Choose a file")), predefined);
+        break;
+
+    default:
+        ;
+    }
+
+    // TODO make cross-platform
+    // Delete trailing slashes unless it is "/", only
     if (!newPath .isEmpty()) {
         if (newPath .size() > 1 && newPath .endsWith(QDir::separator()))
             newPath .truncate(newPath .size() - 1);
@@ -149,20 +184,52 @@ bool PathChooser::validatePath(const QString &path, QString *errorMessage)
             *errorMessage = tr("The path must not be empty.");
         return false;
     }
-    // Must be a directory?
+
     const QFileInfo fi(path);
-    if (fi.isDir())
-        return true; // Happy!
+    const bool isDir = fi.isDir();
 
-    if (!fi.exists()) {
-        if (errorMessage)
-            *errorMessage = tr("The path '%1' does not exist.").arg(path);
-        return false;
+    // Check if existing
+    switch (m_d->m_acceptingKind) {
+    case PathChooser::Directory: // fall through
+    case PathChooser::File:
+        if (!fi.exists()) {
+            if (errorMessage)
+                *errorMessage = tr("The path '%1' does not exist.").arg(path);
+            return false;
+        }
+        break;
+
+    case PathChooser::Command: // fall through
+    default:
+        ;
+    }
+
+    // Check expected kind
+    switch (m_d->m_acceptingKind) {
+    case PathChooser::Directory:
+        if (!isDir)
+            if (errorMessage)
+                *errorMessage = tr("The path '%1' is not a directory.").arg(path);
+            return false;
+        break;
+
+    case PathChooser::File:
+        if (isDir)
+            if (errorMessage)
+                *errorMessage = tr("The path '%1' is not a file.").arg(path);
+            return false;
+        break;
+
+    case PathChooser::Command:
+        // TODO do proper command validation
+        // i.e. search $PATH for a matching file
+        break;
+
+    default:
+        ;
     }
-    // Must be something weird
-    if (errorMessage)
-        *errorMessage = tr("The path '%1' is not a directory.").arg(path);
-    return false;
+
+    return true;
 }
 
 QString PathChooser::label()
@@ -182,5 +249,23 @@ QString PathChooser::homePath()
 #endif
 }
 
+void PathChooser::setExpectedKind(Kind expected)
+{
+    m_d->m_acceptingKind = expected;
+}
+
+void PathChooser::setPromptDialogTitle(const QString &title)
+{
+    m_d->m_dialogTitleOverride = title;
+}
+
+QString PathChooser::makeDialogTitle(const QString &title)
+{
+    if (m_d->m_dialogTitleOverride.isNull())
+        return title;
+    else
+        return m_d->m_dialogTitleOverride;
+}
+
 } // namespace Utils
 } // namespace Core
diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h
index ab821d5df1eebffd60f53336c2f43ebb46b782d4..d4bd098e908769452009f9d5326de5b6af93da6e 100644
--- a/src/libs/utils/pathchooser.h
+++ b/src/libs/utils/pathchooser.h
@@ -54,9 +54,23 @@ class QWORKBENCH_UTILS_EXPORT PathChooser : public QWidget
     Q_PROPERTY(QString path READ path WRITE setPath DESIGNABLE true)
 
 public:
+    static const char * const browseButtonLabel;
+
     explicit PathChooser(QWidget *parent = 0);
     virtual ~PathChooser();
 
+    enum Kind {
+        Directory,
+        File,
+        Command,
+        // ,Any
+    };
+
+    // Default is <Directory>
+    void setExpectedKind(Kind expected);
+
+    void setPromptDialogTitle(const QString &title);
+
     bool isValid() const;
     QString errorMessage() const;
 
@@ -65,11 +79,15 @@ public:
     // Returns the suggested label title when used in a form layout
     static QString label();
 
-    static bool validatePath(const QString &path, QString *errorMessage = 0);
+    bool validatePath(const QString &path, QString *errorMessage = 0);
 
     // Return the home directory, which needs some fixing under Windows.
     static QString homePath();
 
+private:
+    // Returns overridden title or the one from <title>
+    QString makeDialogTitle(const QString &title);
+
 signals:
     void validChanged();
     void changed();
diff --git a/src/plugins/bookmarks/bookmarkmanager.cpp b/src/plugins/bookmarks/bookmarkmanager.cpp
index 0e8482b6f98add4f0920557a7aa7418188837e12..fd4541a01dd2b13f6d1e94f15bd1a0a25d012c53 100644
--- a/src/plugins/bookmarks/bookmarkmanager.cpp
+++ b/src/plugins/bookmarks/bookmarkmanager.cpp
@@ -396,11 +396,16 @@ void BookmarkManager::toggleBookmark()
     if (!editor)
         return;
 
-    const QFileInfo fi(editor->file()->fileName());
-    const int editorLine = editor->currentLine();
+    toggleBookmark(editor->file()->fileName(), editor->currentLine());
+}
+
+void BookmarkManager::toggleBookmark(const QString &fileName, int lineNumber)
+{
+    const QFileInfo fi(fileName);
+    const int editorLine = lineNumber;
 
     // Remove any existing bookmark on this line
-    if (Bookmark *mark = findBookmark(fi.path(), fi.fileName(), editorLine)) {
+    if (Bookmark *mark = findBookmark(fi.path(), fi.fileName(), lineNumber)) {
         // TODO check if the bookmark is really on the same markable Interface
         removeBookmark(mark);
         return;
diff --git a/src/plugins/bookmarks/bookmarkmanager.h b/src/plugins/bookmarks/bookmarkmanager.h
index 3b03e32d670c411f4e1ce7b43459bfeb43500e2b..d3a2fc9a322b0fbb5feda3fafd1c2d22744b6174 100644
--- a/src/plugins/bookmarks/bookmarkmanager.h
+++ b/src/plugins/bookmarks/bookmarkmanager.h
@@ -34,15 +34,15 @@
 #ifndef BOOKMARKMANAGER_H
 #define BOOKMARKMANAGER_H
 
+#include <coreplugin/icontext.h>
+#include <coreplugin/inavigationwidgetfactory.h>
+
 #include <QtCore/QAbstractItemModel>
-#include <QtGui/QListView>
 #include <QtCore/QList>
+#include <QtGui/QListView>
 #include <QtGui/QPixmap>
 #include <QtGui/QStyledItemDelegate>
 
-#include <coreplugin/icontext.h>
-#include <coreplugin/inavigationwidgetfactory.h>
-
 namespace ProjectExplorer {
 class SessionManager;
 }
@@ -89,10 +89,16 @@ public:
     // this QItemSelectionModel is shared by all views
     QItemSelectionModel *selectionModel() const;
 
-    enum Roles {Filename = Qt::UserRole, LineNumber = Qt::UserRole + 1, Directory = Qt::UserRole + 2, LineText = Qt::UserRole + 3};
+    enum Roles {
+        Filename = Qt::UserRole,
+        LineNumber = Qt::UserRole + 1,
+        Directory = Qt::UserRole + 2,
+        LineText = Qt::UserRole + 3
+    };
 
 public slots:
     void toggleBookmark();
+    void toggleBookmark(const QString &fileName, int lineNumber);
     void nextInDocument();
     void prevInDocument();
     void next();
@@ -108,6 +114,7 @@ private slots:
     void updateActionStatus();
     void gotoBookmark(Bookmark *bookmark);
     void loadBookmarks();
+
 private:
     TextEditor::ITextEditor *currentTextEditor() const;
     ProjectExplorer::SessionManager* sessionManager() const;
@@ -120,8 +127,8 @@ private:
     static QString bookmarkToString(const Bookmark *b);
     void saveBookmarks();
 
-    typedef QMultiMap<QString, Bookmark*> FileNameBookmarksMap;
-    typedef QMap<QString, FileNameBookmarksMap*> DirectoryFileBookmarksMap;
+    typedef QMultiMap<QString, Bookmark *> FileNameBookmarksMap;
+    typedef QMap<QString, FileNameBookmarksMap *> DirectoryFileBookmarksMap;
 
     DirectoryFileBookmarksMap m_bookmarksMap;
     Core::ICore *m_core;
@@ -138,7 +145,7 @@ class BookmarkView : public QListView
 public:
     BookmarkView(QWidget *parent = 0);
     ~BookmarkView();
-    void setModel(QAbstractItemModel * model);
+    void setModel(QAbstractItemModel *model);
 public slots:
     void gotoBookmark(const QModelIndex &index);
 protected slots:
@@ -146,7 +153,7 @@ protected slots:
     void removeAll();
 protected:
     void contextMenuEvent(QContextMenuEvent *event);
-    void removeBookmark(const QModelIndex& index);
+    void removeBookmark(const QModelIndex &index);
 private:
     BookmarkContext *m_bookmarkContext;
     QModelIndex m_contextMenuIndex;
diff --git a/src/plugins/bookmarks/bookmarksplugin.cpp b/src/plugins/bookmarks/bookmarksplugin.cpp
index fa749f7bef9004e952d10b4674d5d399f624abed..83c8ec397ee4ef01e4555c3a29815fca59a2a9c2 100644
--- a/src/plugins/bookmarks/bookmarksplugin.cpp
+++ b/src/plugins/bookmarks/bookmarksplugin.cpp
@@ -36,17 +36,22 @@
 #include "bookmarks_global.h"
 
 #include <texteditor/texteditorconstants.h>
+#include <texteditor/itexteditor.h>
 #include <coreplugin/icore.h>
+#include <coreplugin/editormanager/ieditor.h>
+#include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/uniqueidmanager.h>
 #include <coreplugin/actionmanager/actionmanagerinterface.h>
 
 #include <QtCore/qplugin.h>
+#include <QtCore/QDebug>
+
 #include <QtGui/QMenu>
-#include <QDebug>
 
 using namespace Bookmarks::Constants;
 using namespace Bookmarks::Internal;
+using namespace TextEditor;
 
 BookmarksPlugin *BookmarksPlugin::m_instance = 0;
 
@@ -159,6 +164,19 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *)
     updateActions(m_bookmarkManager->state());
     addAutoReleasedObject(new BookmarkViewFactory(m_bookmarkManager));
 
+    m_bookmarkMarginAction = new QAction(this);
+    m_bookmarkMarginAction->setText("Toggle Bookmark");
+    //m_bookmarkAction->setIcon(QIcon(":/gdbdebugger/images/breakpoint.svg"));
+    connect(m_bookmarkMarginAction, SIGNAL(triggered()),
+        this, SLOT(bookmarkMarginActionTriggered()));
+
+    // EditorManager
+    QObject *editorManager = m_core->editorManager();
+    connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
+        this, SLOT(editorAboutToClose(Core::IEditor*)));
+    connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
+        this, SLOT(editorOpened(Core::IEditor*)));
+
     return true;
 }
 
@@ -169,7 +187,6 @@ BookmarksPlugin::~BookmarksPlugin()
 
 void BookmarksPlugin::updateActions(int state)
 {
-
     const bool hasbm    = state >= BookmarkManager::HasBookMarks;
     const bool hasdocbm = state == BookmarkManager::HasBookmarksInDocument;
 
@@ -182,4 +199,32 @@ void BookmarksPlugin::updateActions(int state)
     m_moveDownAction->setEnabled(hasbm);
 }
 
+void BookmarksPlugin::editorOpened(Core::IEditor *editor)
+{
+    connect(editor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
+            this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
+}
+
+void BookmarksPlugin::editorAboutToClose(Core::IEditor *editor)
+{
+    disconnect(editor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
+            this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
+}
+
+void BookmarksPlugin::requestContextMenu(TextEditor::ITextEditor *editor,
+    int lineNumber, QMenu *menu)
+{
+    m_bookmarkMarginActionLineNumber = lineNumber;
+    m_bookmarkMarginActionFileName = editor->file()->fileName();
+    menu->addAction(m_bookmarkMarginAction);
+}
+
+void BookmarksPlugin::bookmarkMarginActionTriggered()
+{
+    m_bookmarkManager->toggleBookmark(
+        m_bookmarkMarginActionFileName,
+        m_bookmarkMarginActionLineNumber
+    );
+}
+
 Q_EXPORT_PLUGIN(BookmarksPlugin)
diff --git a/src/plugins/bookmarks/bookmarksplugin.h b/src/plugins/bookmarks/bookmarksplugin.h
index a5d919eb974a1c7d29094893c7c4c637f16c7c2f..2a60bb04a34e94131b4ed71b3f48160f875efaa9 100644
--- a/src/plugins/bookmarks/bookmarksplugin.h
+++ b/src/plugins/bookmarks/bookmarksplugin.h
@@ -31,18 +31,26 @@
 **
 ***************************************************************************/
 
-#ifndef BOOKMARKS_H
-#define BOOKMARKS_H
+#ifndef BOOKMARKSPLUGIN_H
+#define BOOKMARKSPLUGIN_H
+
+#include <extensionsystem/iplugin.h>
 
 #include <QtCore/QObject>
 #include <QtCore/QMultiMap>
 
-#include <extensionsystem/iplugin.h>
-
-QT_FORWARD_DECLARE_CLASS(QAction)
+QT_BEGIN_NAMESPACE
+class QAction;
+class QMenu;
+QT_END_NAMESPACE
 
 namespace Core {
 class ICore;
+class IEditor;
+}
+
+namespace TextEditor {
+class ITextEditor;
 }
 
 namespace Bookmarks {
@@ -67,6 +75,13 @@ public:
 public slots:
     void updateActions(int stateMask);
 
+private slots:
+    void editorOpened(Core::IEditor *editor);
+    void editorAboutToClose(Core::IEditor *editor);
+    void requestContextMenu(TextEditor::ITextEditor *editor,
+        int lineNumber, QMenu *menu);
+    void bookmarkMarginActionTriggered();
+
 private:
     static BookmarksPlugin *m_instance;
     BookmarkManager *m_bookmarkManager;
@@ -79,6 +94,10 @@ private:
     QAction *m_docNextAction;
     QAction *m_moveUpAction;
     QAction *m_moveDownAction;
+
+    QAction *m_bookmarkMarginAction;
+    int m_bookmarkMarginActionLineNumber;
+    QString m_bookmarkMarginActionFileName;
 };
 
 } // namespace Internal
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index 52c28cbc3d56b555ba3bbdb0abcd236e0bd186f5..5569c900f2b49dbbe8c269f49a888c4d3f6e4f12 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -64,11 +64,12 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
 
         CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
         if (modelmanager) {
-            CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this);
-            pinfo->includePaths = cbpparser.includeFiles();
+            CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
+            pinfo.includePaths = cbpparser.includeFiles();
             // TODO we only want C++ files, not all other stuff that might be in the project
-            pinfo->sourceFiles = m_files;
+            pinfo.sourceFiles = m_files;
             // TODO defines
+            modelmanager->updateProjectInfo(pinfo);
         }
     } else {
         // TODO report error
diff --git a/src/plugins/coreplugin/editormanager/ieditor.h b/src/plugins/coreplugin/editormanager/ieditor.h
index 7cbac8130ff4eab8894be93fbe4b85ae260f42dd..1f087e67e97b199e38c2019b059f9739d891cc14 100644
--- a/src/plugins/coreplugin/editormanager/ieditor.h
+++ b/src/plugins/coreplugin/editormanager/ieditor.h
@@ -100,4 +100,4 @@ signals:
 
 } // namespace Core
 
-#endif //IEDITOR_H
+#endif // IEDITOR_H
diff --git a/src/plugins/coreplugin/viewmanager.cpp b/src/plugins/coreplugin/viewmanager.cpp
index 71ee11329945ebc9312dbbe238a2bb6145fac31f..b7b59f048ae3553340c150d90dfaaa5db7bf7cca 100644
--- a/src/plugins/coreplugin/viewmanager.cpp
+++ b/src/plugins/coreplugin/viewmanager.cpp
@@ -63,7 +63,7 @@ ViewManager::ViewManager(MainWindow *mainWnd)  :
     ViewManagerInterface(mainWnd),
     m_mainWnd(mainWnd)
 {
-    for(int i = 0; i< 3; ++i) {
+    for (int i = 0; i < 3; ++i) {
         QWidget *w = new QWidget();
         m_mainWnd->statusBar()->insertPermanentWidget(i, w);
         w->setLayout(new QHBoxLayout);
@@ -89,7 +89,7 @@ void ViewManager::init()
 
 void ViewManager::objectAdded(QObject *obj)
 {
-    IView * view = Aggregation::query<IView>(obj);
+    IView *view = Aggregation::query<IView>(obj);
     if (!view)
         return;
 
@@ -104,8 +104,8 @@ void ViewManager::objectAdded(QObject *obj)
 
 void ViewManager::aboutToRemoveObject(QObject *obj)
 {
-    IView * view = Aggregation::query<IView>(obj);
-    if(!view)
+    IView *view = Aggregation::query<IView>(obj);
+    if (!view)
         return;
     m_mainWnd->removeContextObject(view);
 }
@@ -121,10 +121,10 @@ void ViewManager::saveSettings(QSettings *settings)
     settings->setValue(QLatin1String("ViewGroup_Default"), m_mainWnd->saveState());
 }
 
-IView * ViewManager::view(const QString & id)
+IView *ViewManager::view(const QString &id)
 {
     QList<IView *> list = m_mainWnd->pluginManager()->getObjects<IView>();
-    foreach (IView * view, list) {
+    foreach (IView *view, list) {
         if (view->uniqueViewName() == id)
             return view;
     }
diff --git a/src/plugins/cpaster/CodePaster.pluginspec b/src/plugins/cpaster/CodePaster.pluginspec
index 2ddd73902e5f4f8181d5cfb756520a44cce5d5c5..7a1be0b876349228a2ad73a6b1576229ad8e5e93 100644
--- a/src/plugins/cpaster/CodePaster.pluginspec
+++ b/src/plugins/cpaster/CodePaster.pluginspec
@@ -1,4 +1,4 @@
-<plugin name="CodePaster" version="0.1" compatVersion="0.1">
+<plugin name="CodePaster" version="0.9.1" compatVersion="0.9.1">
     <vendor>Nokia Corporation</vendor>
     <copyright>(C) 2008 Nokia Corporation</copyright>
     <license>Nokia Technology Preview License Agreement</license>
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index da52bb3d6016a367647e00aa59197607fa8d19fa..8567f81d75139c74cb413357fc70818beff14260 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -79,6 +79,7 @@
 #include <QtGui/QComboBox>
 #include <QtGui/QTreeView>
 #include <QtGui/QHeaderView>
+#include <QtGui/QStringListModel>
 
 using namespace CPlusPlus;
 using namespace CppEditor::Internal;
@@ -202,7 +203,9 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
     m_methodCombo->setMaxVisibleItems(20);
 
     m_overviewModel = new OverviewModel(this);
-    m_methodCombo->setModel(m_overviewModel);
+    m_noSymbolsModel = new QStringListModel(this);
+    m_noSymbolsModel->setStringList(QStringList() << tr("<no symbols>"));
+    m_methodCombo->setModel(m_noSymbolsModel);
 
     connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int)));
     connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex()));
@@ -315,9 +318,16 @@ void CPPEditor::onDocumentUpdated(Document::Ptr doc)
         return;
 
     m_overviewModel->rebuild(doc);
-    OverviewTreeView *treeView = static_cast<OverviewTreeView *>(m_methodCombo->view());
-    treeView->sync();
-    updateMethodBoxIndex();
+    if (m_overviewModel->rowCount() > 0) {
+        if (m_methodCombo->model() != m_overviewModel)
+            m_methodCombo->setModel(m_overviewModel);
+        OverviewTreeView *treeView = static_cast<OverviewTreeView *>(m_methodCombo->view());
+        treeView->sync();
+        updateMethodBoxIndex();
+    } else {
+        if (m_methodCombo->model() != m_noSymbolsModel)
+            m_methodCombo->setModel(m_noSymbolsModel);
+    }
 }
 
 void CPPEditor::updateFileName()
@@ -325,6 +335,8 @@ void CPPEditor::updateFileName()
 
 void CPPEditor::jumpToMethod(int)
 {
+    if (m_methodCombo->model() != m_overviewModel)
+        return;
     QModelIndex index = m_methodCombo->view()->currentIndex();
     Symbol *symbol = m_overviewModel->symbolFromIndex(index);
     if (! symbol)
@@ -339,12 +351,14 @@ void CPPEditor::jumpToMethod(int)
 
 void CPPEditor::updateMethodBoxIndex()
 {
+    if (m_methodCombo->model() != m_overviewModel)
+        return;
     int line = 0, column = 0;
     convertPosition(position(), &line, &column);
 
     QModelIndex lastIndex;
 
-    const int rc = m_overviewModel->rowCount(QModelIndex());
+    const int rc = m_overviewModel->rowCount();
     for (int row = 0; row < rc; ++row) {
         const QModelIndex index = m_overviewModel->index(row, 0, QModelIndex());
         Symbol *symbol = m_overviewModel->symbolFromIndex(index);
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 2420bcf4e5e441d67834d5d9d0a612dbbad09f06..33745eddef27f9156af2ed062295b24a949e9eca 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -42,6 +42,7 @@
 QT_BEGIN_NAMESPACE
 class QAction;
 class QComboBox;
+class QStringListModel;
 QT_END_NAMESPACE
 
 namespace Core {
@@ -138,6 +139,7 @@ private:
     QList<int> m_contexts;
     QComboBox *m_methodCombo;
     CPlusPlus::OverviewModel *m_overviewModel;
+    QStringListModel *m_noSymbolsModel;
 };
 
 } // namespace Internal
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 042b93cc74d064a0bf007f29f587c79791a9355d..af885de622fb67ae30568e6f721871a60203f8d1 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -31,7 +31,6 @@
 **
 ***************************************************************************/
 
-#define _SCL_SECURE_NO_WARNINGS 1
 #include "pp.h"
 
 #include "cppmodelmanager.h"
@@ -66,14 +65,14 @@
 #include <Token.h>
 
 #include <QPlainTextEdit>
+#include <QMutexLocker>
 #include <QTime>
 #include <QDebug>
 
+using namespace CppTools;
+using namespace CppTools::Internal;
 using namespace CPlusPlus;
 
-namespace CppTools {
-namespace Internal {
-
 static const char pp_configuration_file[] = "<configuration>";
 
 static const char pp_configuration[] =
@@ -105,299 +104,328 @@ static const char pp_configuration[] =
     "#define __declspec(a)\n"
     "#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method\n";
 
-class CppPreprocessor: public rpp::Client
+namespace CppTools {
+namespace Internal {
+
+class CppPreprocessor: public CPlusPlus::Client
 {
 public:
-    CppPreprocessor(QPointer<CppModelManager> modelManager)
-        : m_modelManager(modelManager),
-          m_documents(modelManager->documents()),
-          m_proc(this, env)
-    { }
+    CppPreprocessor(QPointer<CppModelManager> modelManager);
 
-    void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
-    { m_workingCopy = workingCopy; }
+    void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy);
+    void setIncludePaths(const QStringList &includePaths);
+    void setFrameworkPaths(const QStringList &frameworkPaths);
+    void addIncludePath(const QString &path);
+    void setProjectFiles(const QStringList &files);
+    void run(QString &fileName);
+    void operator()(QString &fileName);
 
-    void setIncludePaths(const QStringList &includePaths)
-    { m_includePaths = includePaths; }
+protected:
+    CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
 
-    void setFrameworkPaths(const QStringList &frameworkPaths)
-    { m_frameworkPaths = frameworkPaths; }
+    bool includeFile(const QString &absoluteFilePath, QByteArray *result);
+    QByteArray tryIncludeFile(QString &fileName, IncludeType type);
 
-    void addIncludePath(const QString &path)
-    { m_includePaths.append(path); }
+    void mergeEnvironment(CPlusPlus::Document::Ptr doc);
+    void mergeEnvironment(CPlusPlus::Document::Ptr doc, QSet<QString> *processed);
 
-    void setProjectFiles(const QStringList &files)
-    { m_projectFiles = files; }
+    virtual void macroAdded(const QByteArray &macroName,
+                            const QByteArray &macroText);
+    virtual void startExpandingMacro(unsigned offset,
+                                     const Macro &macro,
+                                     const QByteArray &originalText);
+    virtual void stopExpandingMacro(unsigned offset, const Macro &macro);
+    virtual void startSkippingBlocks(unsigned offset);
+    virtual void stopSkippingBlocks(unsigned offset);
+    virtual void sourceNeeded(QString &fileName, IncludeType type);
 
-    void run(QString &fileName)
-    { sourceNeeded(fileName, IncludeGlobal); }
+private:
+    QPointer<CppModelManager> m_modelManager;
+    CppModelManager::DocumentTable m_documents;
+    Environment env;
+    pp m_proc;
+    QStringList m_includePaths;
+    QStringList m_systemIncludePaths;
+    QMap<QString, QByteArray> m_workingCopy;
+    QStringList m_projectFiles;
+    QStringList m_frameworkPaths;
+    QSet<QString> m_included;
+    CPlusPlus::Document::Ptr m_currentDoc;
+};
 
-    void operator()(QString &fileName)
-    { run(fileName); }
+} // namespace Internal
+} // namespace CppTools
 
-protected:
-    bool includeFile(const QString &absoluteFilePath, QByteArray *result)
-    {
-        if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) {
-            return true;
-        }
+CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
+    : m_modelManager(modelManager),
+    m_documents(modelManager->documents()),
+    m_proc(this, env)
+{ }
 
-        if (m_workingCopy.contains(absoluteFilePath)) {
-            m_included.insert(absoluteFilePath);
-            *result = m_workingCopy.value(absoluteFilePath);
-            return true;
-        }
+void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
+{ m_workingCopy = workingCopy; }
 
-        QFileInfo fileInfo(absoluteFilePath);
-        if (! fileInfo.isFile())
-            return false;
-
-        QFile file(absoluteFilePath);
-        if (file.open(QFile::ReadOnly)) {
-            m_included.insert(absoluteFilePath);
-            QTextStream stream(&file);
-            const QString contents = stream.readAll();
-            *result = contents.toUtf8();
-            file.close();
-            return true;
-        }
+void CppPreprocessor::setIncludePaths(const QStringList &includePaths)
+{ m_includePaths = includePaths; }
+
+void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths)
+{ m_frameworkPaths = frameworkPaths; }
+
+void CppPreprocessor::addIncludePath(const QString &path)
+{ m_includePaths.append(path); }
+
+void CppPreprocessor::setProjectFiles(const QStringList &files)
+{ m_projectFiles = files; }
+
+void CppPreprocessor::run(QString &fileName)
+{ sourceNeeded(fileName, IncludeGlobal); }
+
+void CppPreprocessor::operator()(QString &fileName)
+{ run(fileName); }
+
+bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QByteArray *result)
+{
+    if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) {
+        return true;
+    }
+
+    if (m_workingCopy.contains(absoluteFilePath)) {
+        m_included.insert(absoluteFilePath);
+        *result = m_workingCopy.value(absoluteFilePath);
+        return true;
+    }
 
+    QFileInfo fileInfo(absoluteFilePath);
+    if (! fileInfo.isFile())
         return false;
+
+    QFile file(absoluteFilePath);
+    if (file.open(QFile::ReadOnly)) {
+        m_included.insert(absoluteFilePath);
+        QTextStream stream(&file);
+        const QString contents = stream.readAll();
+        *result = contents.toUtf8();
+        file.close();
+        return true;
     }
 
-    QByteArray tryIncludeFile(QString &fileName, IncludeType type)
-    {
-        QFileInfo fileInfo(fileName);
-        if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) {
-            QByteArray contents;
-            includeFile(fileName, &contents);
+    return false;
+}
+
+QByteArray CppPreprocessor::tryIncludeFile(QString &fileName, IncludeType type)
+{
+    QFileInfo fileInfo(fileName);
+    if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) {
+        QByteArray contents;
+        includeFile(fileName, &contents);
+        return contents;
+    }
+
+    if (type == IncludeLocal && m_currentDoc) {
+        QFileInfo currentFileInfo(m_currentDoc->fileName());
+        QString path = currentFileInfo.absolutePath();
+        path += QLatin1Char('/');
+        path += fileName;
+        path = QDir::cleanPath(path);
+        QByteArray contents;
+        if (includeFile(path, &contents)) {
+            fileName = path;
             return contents;
         }
+    }
 
-        if (type == IncludeLocal && m_currentDoc) {
-            QFileInfo currentFileInfo(m_currentDoc->fileName());
-            QString path = currentFileInfo.absolutePath();
-            path += QLatin1Char('/');
-            path += fileName;
-            path = QDir::cleanPath(path);
-            QByteArray contents;
-            if (includeFile(path, &contents)) {
-                fileName = path;
-                return contents;
-            }
+    foreach (const QString &includePath, m_includePaths) {
+        QString path = includePath;
+        path += QLatin1Char('/');
+        path += fileName;
+        path = QDir::cleanPath(path);
+        QByteArray contents;
+        if (includeFile(path, &contents)) {
+            fileName = path;
+            return contents;
         }
+    }
 
-        foreach (const QString &includePath, m_includePaths) {
-            QString path = includePath;
-            path += QLatin1Char('/');
-            path += fileName;
-            path = QDir::cleanPath(path);
-            QByteArray contents;
-            if (includeFile(path, &contents)) {
-                fileName = path;
-                return contents;
-            }
+    // look in the system include paths
+    foreach (const QString &includePath, m_systemIncludePaths) {
+        QString path = includePath;
+        path += QLatin1Char('/');
+        path += fileName;
+        path = QDir::cleanPath(path);
+        QByteArray contents;
+        if (includeFile(path, &contents)) {
+            fileName = path;
+            return contents;
         }
+    }
+
+    int index = fileName.indexOf(QLatin1Char('/'));
+    if (index != -1) {
+        QString frameworkName = fileName.left(index);
+        QString name = fileName.mid(index + 1);
 
-        // look in the system include paths
-        foreach (const QString &includePath, m_systemIncludePaths) {
-            QString path = includePath;
+        foreach (const QString &frameworkPath, m_frameworkPaths) {
+            QString path = frameworkPath;
             path += QLatin1Char('/');
-            path += fileName;
-            path = QDir::cleanPath(path);
+            path += frameworkName;
+            path += QLatin1String(".framework/Headers/");
+            path += name;
             QByteArray contents;
             if (includeFile(path, &contents)) {
                 fileName = path;
                 return contents;
             }
         }
+    }
 
-        int index = fileName.indexOf(QLatin1Char('/'));
-        if (index != -1) {
-            QString frameworkName = fileName.left(index);
-            QString name = fileName.mid(index + 1);
-
-            foreach (const QString &frameworkPath, m_frameworkPaths) {
-                QString path = frameworkPath;
-                path += QLatin1Char('/');
-                path += frameworkName;
-                path += QLatin1String(".framework/Headers/");
-                path += name;
-                QByteArray contents;
-                if (includeFile(path, &contents)) {
-                    fileName = path;
-                    return contents;
-                }
-            }
-        }
-
-        QString path = fileName;
-        if (path.at(0) != QLatin1Char('/'))
-            path.prepend(QLatin1Char('/'));
+    QString path = fileName;
+    if (path.at(0) != QLatin1Char('/'))
+        path.prepend(QLatin1Char('/'));
 
-        foreach (const QString &projectFile, m_projectFiles) {
-            if (projectFile.endsWith(path)) {
-                fileName = projectFile;
-                QByteArray contents;
-                includeFile(fileName, &contents);
-                return contents;
-            }
+    foreach (const QString &projectFile, m_projectFiles) {
+        if (projectFile.endsWith(path)) {
+            fileName = projectFile;
+            QByteArray contents;
+            includeFile(fileName, &contents);
+            return contents;
         }
-
-        //qDebug() << "**** file" << fileName << "not found!";
-        return QByteArray();
     }
 
-    virtual void macroAdded(const QByteArray &macroName, const QByteArray &macroText)
-    {
-        if (! m_currentDoc)
-            return;
+    //qDebug() << "**** file" << fileName << "not found!";
+    return QByteArray();
+}
 
-        m_currentDoc->appendMacro(macroName, macroText);
-    }
+void CppPreprocessor::macroAdded(const QByteArray &macroName, const QByteArray &macroText)
+{
+    if (! m_currentDoc)
+        return;
 
-    virtual void startExpandingMacro(unsigned offset,
-                                     const rpp::Macro &,
-                                     const QByteArray &originalText)
-    {
-        if (! m_currentDoc)
-            return;
-
-        //qDebug() << "start expanding:" << macro.name << "text:" << originalText;
-        m_currentDoc->addMacroUse(offset, originalText.length());
-    }
+    m_currentDoc->appendMacro(macroName, macroText);
+}
 
-    virtual void stopExpandingMacro(unsigned, const rpp::Macro &)
-    {
-        if (! m_currentDoc)
-            return;
+void CppPreprocessor::startExpandingMacro(unsigned offset,
+                                          const Macro &,
+                                          const QByteArray &originalText)
+{
+    if (! m_currentDoc)
+        return;
 
-        //qDebug() << "stop expanding:" << macro.name;
-    }
+    //qDebug() << "start expanding:" << macro.name << "text:" << originalText;
+    m_currentDoc->addMacroUse(offset, originalText.length());
+}
 
-    void mergeEnvironment(Document::Ptr doc)
-    {
-        QSet<QString> processed;
-        mergeEnvironment(doc, &processed);
-    }
+void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &)
+{
+    if (! m_currentDoc)
+        return;
 
-    void mergeEnvironment(Document::Ptr doc, QSet<QString> *processed)
-    {
-        if (! doc)
-            return;
+    //qDebug() << "stop expanding:" << macro.name;
+}
 
-        const QString fn = doc->fileName();
+void CppPreprocessor::mergeEnvironment(Document::Ptr doc)
+{
+    QSet<QString> processed;
+    mergeEnvironment(doc, &processed);
+}
 
-        if (processed->contains(fn))
-            return;
+void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *processed)
+{
+    if (! doc)
+        return;
 
-        processed->insert(fn);
+    const QString fn = doc->fileName();
 
-        foreach (QString includedFile, doc->includedFiles())
-            mergeEnvironment(m_documents.value(includedFile), processed);
+    if (processed->contains(fn))
+        return;
 
-        const QByteArray macros = doc->definedMacros();
-        QByteArray localFileName = doc->fileName().toUtf8();
+    processed->insert(fn);
 
-        QByteArray dummy;
-        m_proc(localFileName, macros, &dummy);
-    }
+    foreach (QString includedFile, doc->includedFiles())
+        mergeEnvironment(m_documents.value(includedFile), processed);
 
-    virtual void startSkippingBlocks(unsigned offset)
-    {
-        //qDebug() << "start skipping blocks:" << offset;
-        if (m_currentDoc)
-            m_currentDoc->startSkippingBlocks(offset);
-    }
+    const QByteArray macros = doc->definedMacros();
+    QByteArray localFileName = doc->fileName().toUtf8();
 
-    virtual void stopSkippingBlocks(unsigned offset)
-    {
-        //qDebug() << "stop skipping blocks:" << offset;
-        if (m_currentDoc)
-            m_currentDoc->stopSkippingBlocks(offset);
-    }
+    QByteArray dummy;
+    m_proc(localFileName, macros, &dummy);
+}
 
-    virtual void sourceNeeded(QString &fileName, IncludeType type)
-    {
-        if (fileName.isEmpty())
-            return;
-
-        QByteArray contents = tryIncludeFile(fileName, type);
-
-        if (m_currentDoc) {
-            m_currentDoc->addIncludeFile(fileName);
-            if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
-                QString msg;
-                msg += fileName;
-                msg += QLatin1String(": No such file or directory");
-                Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
-                                              m_currentDoc->fileName(),
-                                              env.currentLine, /*column = */ 0,
-                                              msg);
-                m_currentDoc->addDiagnosticMessage(d);
-                //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
-            }
+void CppPreprocessor::startSkippingBlocks(unsigned offset)
+{
+    //qDebug() << "start skipping blocks:" << offset;
+    if (m_currentDoc)
+        m_currentDoc->startSkippingBlocks(offset);
+}
+
+void CppPreprocessor::stopSkippingBlocks(unsigned offset)
+{
+    //qDebug() << "stop skipping blocks:" << offset;
+    if (m_currentDoc)
+        m_currentDoc->stopSkippingBlocks(offset);
+}
+
+void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type)
+{
+    if (fileName.isEmpty())
+        return;
+
+    QByteArray contents = tryIncludeFile(fileName, type);
+
+    if (m_currentDoc) {
+        m_currentDoc->addIncludeFile(fileName);
+        if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
+            QString msg;
+            msg += fileName;
+            msg += QLatin1String(": No such file or directory");
+            Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
+                                          m_currentDoc->fileName(),
+                                          env.currentLine, /*column = */ 0,
+                                          msg);
+            m_currentDoc->addDiagnosticMessage(d);
+            //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
         }
+    }
 
-        if (! contents.isEmpty()) {
-            Document::Ptr cachedDoc = m_documents.value(fileName);
-            if (cachedDoc && m_currentDoc) {
-                mergeEnvironment(cachedDoc);
-            } else {
-                Document::Ptr previousDoc = switchDocument(Document::create(fileName));
+    if (! contents.isEmpty()) {
+        Document::Ptr cachedDoc = m_documents.value(fileName);
+        if (cachedDoc && m_currentDoc) {
+            mergeEnvironment(cachedDoc);
+        } else {
+            Document::Ptr previousDoc = switchDocument(Document::create(fileName));
 
-                const QByteArray previousFile = env.current_file;
-                const unsigned previousLine = env.currentLine;
+            const QByteArray previousFile = env.current_file;
+            const unsigned previousLine = env.currentLine;
 
-                env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(),
-                                              m_currentDoc->translationUnit()->fileNameLength());
+            env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(),
+                                          m_currentDoc->translationUnit()->fileNameLength());
 
-                QByteArray preprocessedCode;
-                m_proc(contents, &preprocessedCode);
-                //qDebug() << preprocessedCode;
+            QByteArray preprocessedCode;
+            m_proc(contents, &preprocessedCode);
+            //qDebug() << preprocessedCode;
 
-                env.current_file = previousFile;
-                env.currentLine = previousLine;
+            env.current_file = previousFile;
+            env.currentLine = previousLine;
 
-                m_currentDoc->setSource(preprocessedCode);
-                m_currentDoc->parse();
-                m_currentDoc->check();
-                m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream.
+            m_currentDoc->setSource(preprocessedCode);
+            m_currentDoc->parse();
+            m_currentDoc->check();
+            m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream.
 
-                if (m_modelManager)
-                    m_modelManager->emitDocumentUpdated(m_currentDoc);
-                (void) switchDocument(previousDoc);
-            }
+            if (m_modelManager)
+                m_modelManager->emitDocumentUpdated(m_currentDoc);
+            (void) switchDocument(previousDoc);
         }
     }
+}
 
-    Document::Ptr switchDocument(Document::Ptr doc)
-    {
-        Document::Ptr previousDoc = m_currentDoc;
-        m_currentDoc = doc;
-        return previousDoc;
-    }
-
-private:
-    QPointer<CppModelManager> m_modelManager;
-    CppModelManager::DocumentTable m_documents;
-    rpp::Environment env;
-    rpp::pp m_proc;
-    QStringList m_includePaths;
-    QStringList m_systemIncludePaths;
-    QMap<QString, QByteArray> m_workingCopy;
-    QStringList m_projectFiles;
-    QStringList m_frameworkPaths;
-    QSet<QString> m_included;
-    Document::Ptr m_currentDoc;
-};
-
-} // namespace Internal
-} // namespace CppTools
+Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
+{
+    Document::Ptr previousDoc = m_currentDoc;
+    m_currentDoc = doc;
+    return previousDoc;
+}
 
 
-using namespace CppTools;
-using namespace CppTools::Internal;
 
 /*!
     \class CppTools::CppModelManager
@@ -450,12 +478,25 @@ CppModelManager::CppModelManager(QObject *parent) :
 CppModelManager::~CppModelManager()
 { }
 
-Document::Ptr CppModelManager::document(const QString &fileName)
+Document::Ptr CppModelManager::document(const QString &fileName) const
 { return m_documents.value(fileName); }
 
-CppModelManager::DocumentTable CppModelManager::documents()
+CppModelManager::DocumentTable CppModelManager::documents() const
 { return m_documents; }
 
+void CppModelManager::ensureUpdated()
+{
+    QMutexLocker locker(&mutex);
+    if (! m_dirty)
+        return;
+
+    m_projectFiles = updateProjectFiles();
+    m_includePaths = updateIncludePaths();
+    m_frameworkPaths = updateFrameworkPaths();
+    m_definedMacros = updateDefinedMacros();
+    m_dirty = false;
+}
+
 QStringList CppModelManager::updateProjectFiles() const
 {
     QStringList files;
@@ -527,8 +568,29 @@ QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList()
 void CppModelManager::updateSourceFiles(const QStringList &sourceFiles)
 { (void) refreshSourceFiles(sourceFiles); }
 
-CppModelManager::ProjectInfo *CppModelManager::projectInfo(ProjectExplorer::Project *project)
-{ return &m_projects[project]; }
+QList<CppModelManager::ProjectInfo> CppModelManager::projectInfos() const
+{
+    QMutexLocker locker(&mutex);
+
+    return m_projects.values();
+}
+
+CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Project *project) const
+{
+    QMutexLocker locker(&mutex);
+
+    return m_projects.value(project, ProjectInfo(project));
+}
+
+void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
+{
+    QMutexLocker locker(&mutex);
+
+    if (! pinfo.isValid())
+        return;
+
+    m_projects.insert(pinfo.project, pinfo);
+}
 
 QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles)
 {
@@ -691,13 +753,18 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
 
 void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
 {
+    QMutexLocker locker(&mutex);
     m_dirty = true;
 }
 
 void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
 {
-    m_dirty = true;
-    m_projects.remove(project);
+    do {
+        QMutexLocker locker(&mutex);
+        m_dirty = true;
+        m_projects.remove(project);
+    } while (0);
+
     GC();
 }
 
@@ -705,8 +772,15 @@ void CppModelManager::onSessionUnloaded()
 {
     if (m_core->progressManager()) {
         m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX);
-        m_dirty = true;
     }
+
+    do {
+        QMutexLocker locker(&mutex);
+        m_projects.clear();
+        m_dirty = true;
+    } while (0);
+
+    GC();
 }
 
 void CppModelManager::parse(QFutureInterface<void> &future,
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index a91a414e4803e2464a68a149b5f1eac9ae43068a..6bc7d0c1c55809a5d8bf9c143d384174564e6fbc 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -40,6 +40,7 @@
 
 #include <QMap>
 #include <QFutureInterface>
+#include <QMutex>
 
 namespace Core {
 class ICore;
@@ -70,9 +71,13 @@ public:
     virtual ~CppModelManager();
 
     virtual void updateSourceFiles(const QStringList &sourceFiles);
-    virtual ProjectInfo *projectInfo(ProjectExplorer::Project *project);
-    virtual CPlusPlus::Document::Ptr document(const QString &fileName);
-    virtual DocumentTable documents();
+
+    virtual QList<ProjectInfo> projectInfos() const;
+    virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
+    virtual void updateProjectInfo(const ProjectInfo &pinfo);
+
+    virtual CPlusPlus::Document::Ptr document(const QString &fileName) const;
+    virtual DocumentTable documents() const;
     virtual void GC();
 
     QFuture<void> refreshSourceFiles(const QStringList &sourceFiles);
@@ -127,22 +132,12 @@ private:
         return m_definedMacros;
     }
 
+    void ensureUpdated();
     QStringList updateProjectFiles() const;
     QStringList updateIncludePaths() const;
     QStringList updateFrameworkPaths() const;
     QByteArray updateDefinedMacros() const;
 
-    void ensureUpdated() {
-        if (! m_dirty)
-            return;
-
-        m_projectFiles = updateProjectFiles();
-        m_includePaths = updateIncludePaths();
-        m_frameworkPaths = updateFrameworkPaths();
-        m_definedMacros = updateDefinedMacros();
-        m_dirty = false;
-    }
-
     static void parse(QFutureInterface<void> &future,
                       CppPreprocessor *preproc,
                       QStringList files);
@@ -166,6 +161,8 @@ private:
     // project integration
     QMap<ProjectExplorer::Project *, ProjectInfo> m_projects;
 
+    mutable QMutex mutex;
+
     enum {
         MAX_SELECTION_COUNT = 5
     };
diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h
index 11be08a4b0e20c4a2b5fd572d15db6dfb1b91dd0..e3ad4fe961be962f93cf30f3f7745ca055b8faa0 100644
--- a/src/plugins/cpptools/cppmodelmanagerinterface.h
+++ b/src/plugins/cpptools/cppmodelmanagerinterface.h
@@ -38,6 +38,7 @@
 #include <cplusplus/CppDocument.h>
 #include <QtCore/QObject>
 #include <QtCore/QMap>
+#include <QtCore/QPointer>
 
 namespace ProjectExplorer {
     class Project;
@@ -51,10 +52,29 @@ class CPPTOOLS_EXPORT CppModelManagerInterface
     Q_OBJECT
 
 public:
-    typedef QMap<QString, CPlusPlus::Document::Ptr> DocumentTable;
+    typedef QMap<QString, CPlusPlus::Document::Ptr> DocumentTable; // ### remove me
 
-    struct ProjectInfo
+    class ProjectInfo
     {
+    public:
+        ProjectInfo()
+        { }
+
+        ProjectInfo(QPointer<ProjectExplorer::Project> project)
+            : project(project)
+        { }
+
+        operator bool() const
+        { return ! project.isNull(); }
+
+        bool isValid() const
+        { return ! project.isNull(); }
+
+        bool isNull() const
+        { return project.isNull(); }
+
+    public: // attributes
+        QPointer<ProjectExplorer::Project> project;
         QString projectPath;
         QByteArray defines;
         QStringList sourceFiles;
@@ -69,10 +89,12 @@ public:
     virtual void GC() = 0;
     virtual void updateSourceFiles(const QStringList &sourceFiles) = 0;
 
-    virtual CPlusPlus::Document::Ptr document(const QString &fileName) = 0;
-    virtual DocumentTable documents() = 0;
+    virtual CPlusPlus::Document::Ptr document(const QString &fileName) const = 0;
+    virtual DocumentTable documents() const = 0;
 
-    virtual ProjectInfo *projectInfo(ProjectExplorer::Project *project) = 0;
+    virtual QList<ProjectInfo> projectInfos() const = 0;
+    virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0;
+    virtual void updateProjectInfo(const ProjectInfo &pinfo) = 0;
 };
 
 } // namespace CppTools
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 8a096900ebf699ba9f0712eafb670660ebffb113..92905e42ef9af7659dd58358a3fd7c7d50694b3d 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -10,7 +10,7 @@ unix:QMAKE_CXXFLAGS_DEBUG += -O3
 INCLUDEPATH += .
 DEFINES += CPPTOOLS_LIBRARY
 CONFIG += help
-include(rpp/rpp.pri)|error("Can't find RPP")
+
 HEADERS += cpptools_global.h \
     cppquickopenfilter.h \
     cppclassesfilter.h \
diff --git a/src/plugins/cpptools/rpp/rpp.pri b/src/plugins/cpptools/rpp/rpp.pri
deleted file mode 100644
index a79b0028a056faf793ac0b38a4e4bb048a74b15d..0000000000000000000000000000000000000000
--- a/src/plugins/cpptools/rpp/rpp.pri
+++ /dev/null
@@ -1,18 +0,0 @@
-DEPENDPATH += $$PWD
-INCLUDEPATH += $$PWD
-
-HEADERS += $$PWD/pp-cctype.h \
-           $$PWD/pp-engine.h \
-           $$PWD/pp-environment.h \
-           $$PWD/pp-internal.h \
-           $$PWD/pp-macro-expander.h \
-           $$PWD/pp-macro.h \
-           $$PWD/pp-scanner.h \
-           $$PWD/pp.h \
-           $$PWD/pp-client.h
-
-SOURCES += $$PWD/pp-engine.cpp \
-           $$PWD/pp-environment.cpp \
-           $$PWD/pp-macro-expander.cpp
-
-
diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h
index d82f285972162ddf332d0cc278ecd5d2b41404ca..4997e5cf049bb72d9512c56191bf2d4d0728abcd 100644
--- a/src/plugins/cpptools/searchsymbols.h
+++ b/src/plugins/cpptools/searchsymbols.h
@@ -44,6 +44,8 @@
 #include <QMetaType>
 #include <QString>
 
+#include <functional>
+
 namespace CppTools {
 namespace Internal {
 
diff --git a/src/plugins/debugger/debuggeroutputwindow.cpp b/src/plugins/debugger/debuggeroutputwindow.cpp
index 7dc293cf35a0462bffa36d7f270bb9c4317d8120..cfcd8df36d8c5fdf5363fbfe27abcb8209f9054b 100644
--- a/src/plugins/debugger/debuggeroutputwindow.cpp
+++ b/src/plugins/debugger/debuggeroutputwindow.cpp
@@ -285,6 +285,7 @@ void DebuggerOutputWindow::showOutput(const QString &prefix, const QString &outp
 
 void DebuggerOutputWindow::showInput(const QString &prefix, const QString &input)
 {
+    Q_UNUSED(prefix);
     m_inputText->append(input);
     QTextCursor cursor = m_inputText->textCursor();
     cursor.movePosition(QTextCursor::End);
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index b11472a5243db7bf7ca0ed202a8e8789ffa0b066..feb63fa0c306da890538993d03b4871526d425e2 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -250,6 +250,12 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *error_mes
 
     m_gdbRunningContext = uidm->uniqueIdentifier(Constants::GDBRUNNING);
 
+    m_breakpointMarginAction = new QAction(this);
+    m_breakpointMarginAction->setText("Toggle Breakpoint");
+    //m_breakpointMarginAction->setIcon(QIcon(":/gdbdebugger/images/breakpoint.svg"));
+    connect(m_breakpointMarginAction, SIGNAL(triggered()),
+        this, SLOT(breakpointMarginActionTriggered()));
+
     //Core::IActionContainer *mcppcontext =
     //    actionManager->actionContainer(CppEditor::Constants::M_CONTEXT);
 
@@ -502,6 +508,8 @@ void DebuggerPlugin::editorOpened(Core::IEditor *editor)
             this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
         connect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
             this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
+        connect(textEditor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
+            this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
     }
 }
 
@@ -512,9 +520,27 @@ void DebuggerPlugin::editorAboutToClose(Core::IEditor *editor)
             this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
         disconnect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
             this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
+        disconnect(textEditor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
+            this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
     }
 }
 
+void DebuggerPlugin::requestContextMenu(TextEditor::ITextEditor *editor,
+    int lineNumber, QMenu *menu)
+{
+    m_breakpointMarginActionLineNumber = lineNumber;
+    m_breakpointMarginActionFileName = editor->file()->fileName();
+    menu->addAction(m_breakpointMarginAction);
+}
+
+void DebuggerPlugin::breakpointMarginActionTriggered()
+{
+    m_manager->toggleBreakpoint(
+        m_breakpointMarginActionFileName,
+        m_breakpointMarginActionLineNumber
+    );
+}
+
 void DebuggerPlugin::requestMark(TextEditor::ITextEditor *editor, int lineNumber)
 {
     m_manager->toggleBreakpoint(editor->file()->fileName(), lineNumber);
diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h
index 7dfcae1ffe7f3006a69a644130ba86b807be3174..91ffe4dbf770a43fa839f9d27e4c49818c373d2a 100644
--- a/src/plugins/debugger/debuggerplugin.h
+++ b/src/plugins/debugger/debuggerplugin.h
@@ -84,10 +84,14 @@ private slots:
     void setSessionValue(const QString &name, const QVariant &value);
     void queryConfigValue(const QString &name, QVariant *value);
     void setConfigValue(const QString &name, const QVariant &value);
+    void requestContextMenu(TextEditor::ITextEditor *editor,
+        int lineNumber, QMenu *menu);
 
     void resetLocation();
     void gotoLocation(const QString &fileName, int line, bool setMarker);
 
+    void breakpointMarginActionTriggered();
+
 private:
     friend class DebuggerManager;
     friend class DebugMode; // FIXME: Just a hack now so that it can access the views
@@ -104,6 +108,10 @@ private:
     QString m_previousMode;
     LocationMark *m_locationMark;
     int m_gdbRunningContext;
+
+    QAction *m_breakpointMarginAction;
+    int m_breakpointMarginActionLineNumber;
+    QString m_breakpointMarginActionFileName;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 1802c018001c8674588fc031600f7eb2480d41cc..9336981b128ba3cab1b8e7e63b1c2c0509f2969f 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -1271,6 +1271,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
     if (isStoppedReason(reason) || reason.isEmpty()) {
         // Need another round trip
         if (reason == "breakpoint-hit") {
+            q->showStatusMessage(tr("Stopped at breakpoint."), -1);
             GdbMi frame = data.findChild("frame");
             //qDebug() << frame.toString();
             m_currentFrame = frame.findChild("addr").data() + '%' +
@@ -1282,6 +1283,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
             QVariant var = QVariant::fromValue<GdbMi>(data);
             sendCommand("p 0", GdbAsyncOutput2, var);  // dummy
         } else {
+            q->showStatusMessage(tr("Stopped. %1").arg(reason), -1);
             handleAsyncOutput2(data);
         }
         return;
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 3d99a84ad34edf93ba96a3a4a1f7f0d489d8f8d8..1041c2edcc697a246d403879ca0c96575c6c50ad 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -320,6 +320,51 @@ static WatchData take(const QString &iname, QList<WatchData> *list)
 }
 
 
+static QList<WatchData> initialSet()
+{
+    QList<WatchData> result;
+
+    WatchData root;
+    root.state = 0;
+    root.level = 0;
+    root.row = 0;
+    root.name = "Root";
+    root.parentIndex = -1;
+    root.childIndex.append(1);
+    root.childIndex.append(2);
+    root.childIndex.append(3);
+    result.append(root);
+
+    WatchData local;
+    local.iname = "local";
+    local.name = "Locals";
+    local.state = 0;
+    local.level = 1;
+    local.row = 0;
+    local.parentIndex = 0;
+    result.append(local);
+
+    WatchData tooltip;
+    tooltip.iname = "tooltip";
+    tooltip.name = "Tooltip";
+    tooltip.state = 0;
+    tooltip.level = 1;
+    tooltip.row = 1;
+    tooltip.parentIndex = 0;
+    result.append(tooltip);
+
+    WatchData watch;
+    watch.iname = "watch";
+    watch.name = "Watchers";
+    watch.state = 0;
+    watch.level = 1;
+    watch.row = 2;
+    watch.parentIndex = 0;
+    result.append(watch);
+
+    return result;
+}
+
 ///////////////////////////////////////////////////////////////////////
 //
 // WatchHandler
@@ -332,7 +377,8 @@ WatchHandler::WatchHandler()
     m_inFetchMore = false;
     m_inChange = false;
 
-    cleanModel();
+    m_completeSet = initialSet();
+    m_incompleteSet.clear();
     m_displaySet = m_completeSet;
 }
 
@@ -380,6 +426,7 @@ QVariant WatchHandler::data(const QModelIndex &idx, int role) const
     int node = idx.internalId();
     if (node < 0)
         return QVariant();
+    QWB_ASSERT(node < m_displaySet.size(), return QVariant());
 
     const WatchData &data = m_displaySet.at(node);
 
@@ -441,6 +488,13 @@ QVariant WatchHandler::data(const QModelIndex &idx, int role) const
         case VisualRole:
             return m_displayedINames.contains(data.iname);
     
+        case ExpandedRole:
+            //qDebug() << " FETCHING: " << data.iname
+            //    << m_expandedINames.contains(data.iname)
+            //    << m_expandedINames;
+            // Level 0 and 1 are always expanded
+            return node < 4 || m_expandedINames.contains(data.iname);
+    
         default:
             break; 
     }
@@ -558,10 +612,13 @@ void WatchHandler::rebuildModel()
     MODEL_DEBUG("RECREATE MODEL, CURRENT SET:\n" << toString());
     #endif
 
+    QHash<QString, int> oldTopINames;
     QHash<QString, QString> oldValues;
     for (int i = 0, n = m_oldSet.size(); i != n; ++i) {
         WatchData &data = m_oldSet[i];
         oldValues[data.iname] = data.value;
+        if (data.level == 2)
+            ++oldTopINames[data.iname];
     }
     #ifdef DEBUG_PENDING
     MODEL_DEBUG("OLD VALUES: " << oldValues);
@@ -575,6 +632,9 @@ void WatchHandler::rebuildModel()
 
     qSort(m_completeSet.begin(), m_completeSet.end(), &iNameSorter);
 
+    // This helps to decide whether the view has completely changed or not.
+    QHash<QString, int> topINames;
+
     QHash<QString, int> iname2idx;
 
     for (int i = m_completeSet.size(); --i > 0; ) {
@@ -582,7 +642,10 @@ void WatchHandler::rebuildModel()
         data.parentIndex = 0;
         data.childIndex.clear();
         iname2idx[data.iname] = i;
+        if (data.level == 2)
+            ++topINames[data.iname];
     }
+    //qDebug() << "TOPINAMES: " << topINames << "\nOLD: " << oldTopINames;
 
     for (int i = 1; i < m_completeSet.size(); ++i) {
         WatchData &data = m_completeSet[i];
@@ -603,7 +666,13 @@ void WatchHandler::rebuildModel()
             && data.value != strNotInScope;
     }
 
-    //emit layoutAboutToBeChanged();
+    emit layoutAboutToBeChanged();
+
+    if (oldTopINames != topINames) {
+        m_displaySet = initialSet();
+        m_expandedINames.clear();
+        emit reset();
+    }
 
     m_displaySet = m_completeSet;
 
@@ -668,11 +737,6 @@ void WatchHandler::rebuildModel()
     emit reset();
     //qDebug() << "WATCHHANDLER: RESET EMITTED";
     m_inChange = false;
-    //emit layoutChanged();
-    //QSet<QString> einames = m_expandedINames;
-    //einames.insert("local");
-    //einames.insert("watch");
-    //emit expandedItems(einames);
 
     #if DEBUG_MODEL
     #if USE_MODEL_TEST
@@ -691,8 +755,11 @@ void WatchHandler::cleanup()
     m_oldSet.clear();
     m_expandedINames.clear();
     m_displayedINames.clear();
-    cleanModel();
+
+    m_incompleteSet.clear();
+    m_completeSet = initialSet();
     m_displaySet = m_completeSet;
+
 #if 0
     for (EditWindows::ConstIterator it = m_editWindows.begin();
             it != m_editWindows.end(); ++it) {
@@ -707,7 +774,7 @@ void WatchHandler::cleanup()
 void WatchHandler::collapseChildren(const QModelIndex &idx)
 {
     if (m_inChange || m_completeSet.isEmpty()) {
-        //qDebug() << "WATCHHANDLER: COLLAPSE IGNORED" << idx;
+        qDebug() << "WATCHHANDLER: COLLAPSE IGNORED" << idx;
         return;
     }
     QWB_ASSERT(checkIndex(idx.internalId()), return);
@@ -879,56 +946,10 @@ void WatchHandler::removeWatchExpression(const QString &iname)
     emit watchModelUpdateRequested();
 }
 
-void WatchHandler::cleanModel()
-{
-    // This uses data stored in m_oldSet to re-create a new set
-    // one-by-one
-    m_completeSet.clear();
-    m_incompleteSet.clear();
-
-    WatchData root;
-    root.state = 0;
-    root.level = 0;
-    root.row = 0;
-    root.name = "Root";
-    root.parentIndex = -1;
-    root.childIndex.append(1);
-    root.childIndex.append(2);
-    root.childIndex.append(3);
-    m_completeSet.append(root);
-
-    WatchData local;
-    local.iname = "local";
-    local.name = "Locals";
-    local.state = 0;
-    local.level = 1;
-    local.row = 0;
-    local.parentIndex = 0;
-    m_completeSet.append(local);
-
-    WatchData tooltip;
-    tooltip.iname = "tooltip";
-    tooltip.name = "Tooltip";
-    tooltip.state = 0;
-    tooltip.level = 1;
-    tooltip.row = 1;
-    tooltip.parentIndex = 0;
-    m_completeSet.append(tooltip);
-
-    WatchData watch;
-    watch.iname = "watch";
-    watch.name = "Watchers";
-    watch.state = 0;
-    watch.level = 1;
-    watch.row = 2;
-    watch.parentIndex = 0;
-    m_completeSet.append(watch);
-}
-
-
 void WatchHandler::reinitializeWatchers()
 {
-    cleanModel();
+    m_completeSet = initialSet();
+    m_incompleteSet.clear();
 
     // copy over all watchers and mark all watchers as incomplete
     for (int i = 0, n = m_oldSet.size(); i < n; ++i) {
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 3841d55d30019ce1ab7cc5a75e7b3ca9d492b10b..f27e167dc1b4891f1d3ffe751de00e3b337f3e9c 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -135,7 +135,7 @@ public:
     bool changed;
 };
 
-enum { INameRole = Qt::UserRole, VisualRole };
+enum { INameRole = Qt::UserRole, VisualRole, ExpandedRole };
 
 
 class WatchHandler : public QAbstractItemModel
@@ -192,7 +192,6 @@ signals:
 private:
     WatchData takeData(const QString &iname);
     QString toString() const;
-    void cleanModel();
 
     bool m_expandPointers;
     bool m_inChange;
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index 78366198955d6379c7e7130b1501d9aef0122488..f49b7073aeff5bf32e9e77920ba5b2f807eb92c7 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -46,7 +46,7 @@
 
 using namespace Debugger::Internal;
 
-enum { INameRole = Qt::UserRole, VisualRole };
+enum { INameRole = Qt::UserRole, VisualRole, ExpandedRole };
 
 /////////////////////////////////////////////////////////////////////
 //
@@ -57,7 +57,6 @@ enum { INameRole = Qt::UserRole, VisualRole };
 WatchWindow::WatchWindow(Type type, QWidget *parent)
   : QTreeView(parent), m_type(type)
 {
-    m_blocked = false;
     setWindowTitle(tr("Locals and Watchers"));
     setAlternatingRowColors(true);
     setIndentation(indentation() * 9/10);
@@ -76,12 +75,6 @@ void WatchWindow::expandNode(const QModelIndex &idx)
     //QModelIndex mi0 = idx.sibling(idx.row(), 0);
     //QString iname = model()->data(mi0, INameRole).toString();
     //QString name = model()->data(mi0, Qt::DisplayRole).toString();
-    //qDebug() << "\n\nEXPAND NODE " // << iname << name
-    //    << idx << (m_blocked ? "blocked" : "passed");
-    //if (isExpanded(idx))
-    //    return;
-    //if (m_blocked)
-    //    return;
     emit requestExpandChildren(idx);
 }
 
@@ -91,8 +84,6 @@ void WatchWindow::collapseNode(const QModelIndex &idx)
     //QString iname = model()->data(mi0, INameRole).toString();
     //QString name = model()->data(mi0, Qt::DisplayRole).toString();
     //qDebug() << "COLLAPSE NODE " << idx;
-    if (m_blocked)
-        return;
     emit requestCollapseChildren(idx);
 }
 
@@ -181,6 +172,7 @@ void WatchWindow::reset()
     QTreeView::reset(); 
     setRootIndex(model()->index(row, 0, model()->index(0, 0)));
     //setRootIndex(model()->index(0, 0));
+    resetHelper(model()->index(0, 0));
 }
 
 void WatchWindow::setModel(QAbstractItemModel *model)
@@ -192,55 +184,15 @@ void WatchWindow::setModel(QAbstractItemModel *model)
     header()->setResizeMode(QHeaderView::ResizeToContents);
     if (m_type != LocalsType)
         header()->hide();
-
-    connect(model, SIGNAL(modelAboutToBeReset()),
-        this, SLOT(modelAboutToBeReset()));
-    connect(model, SIGNAL(modelReset()),
-        this, SLOT(modelReset()));
-}
-
-void WatchWindow::modelAboutToBeReset()
-{
-    m_blocked = true;
-    //qDebug() << "Model about to be reset";
-    m_expandedItems.clear();
-    m_expandedItems.insert("local");
-    m_expandedItems.insert("watch");
-    modelAboutToBeResetHelper(model()->index(0, 0));
-    //qDebug() << "   expanded: " << m_expandedItems;
-}
-
-void WatchWindow::modelAboutToBeResetHelper(const QModelIndex &idx)
-{
-    QString iname = model()->data(idx, INameRole).toString();
-    //qDebug() << "Model about to be reset helper" << iname << idx
-    //    << isExpanded(idx);
-    if (isExpanded(idx))
-        m_expandedItems.insert(iname);
-    for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
-        QModelIndex idx1 = model()->index(i, 0, idx);
-        modelAboutToBeResetHelper(idx1);
-    }
-}
-
-void WatchWindow::modelReset()
-{
-    //qDebug() << "Model reset";
-    expand(model()->index(0, 0));
-    modelResetHelper(model()->index(0, 0));
-    m_blocked = false;
 }
 
-void WatchWindow::modelResetHelper(const QModelIndex &idx)
+void WatchWindow::resetHelper(const QModelIndex &idx)
 {
-    QString name = model()->data(idx, Qt::DisplayRole).toString();
-    QString iname = model()->data(idx, INameRole).toString();
-    //qDebug() << "Model reset helper" << iname << name;
-    if (m_expandedItems.contains(iname)) {
+    if (model()->data(idx, ExpandedRole).toBool()) {
         expand(idx);
         for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
             QModelIndex idx1 = model()->index(i, 0, idx);
-            modelResetHelper(idx1);
+            resetHelper(idx1);
         }
     }
 }
diff --git a/src/plugins/debugger/watchwindow.h b/src/plugins/debugger/watchwindow.h
index 9781f79fdb7b7099a36c36bf75daf675bf3ef073..c292bebb5f6d79ad7a3962e2a21ff23cb64a9bd8 100644
--- a/src/plugins/debugger/watchwindow.h
+++ b/src/plugins/debugger/watchwindow.h
@@ -72,21 +72,16 @@ private slots:
     void handleChangedItem(QWidget *);
     void expandNode(const QModelIndex &index);
     void collapseNode(const QModelIndex &index);
-    void modelAboutToBeReset();
-    void modelReset();
 
 private:
     void contextMenuEvent(QContextMenuEvent *ev);
     void editItem(const QModelIndex &idx);
     void reset(); /* reimpl */
 
-    void modelAboutToBeResetHelper(const QModelIndex &idx);
-    void modelResetHelper(const QModelIndex &idx);
+    void resetHelper(const QModelIndex &idx);
 
     bool m_alwaysResizeColumnsToContents;
     Type m_type;
-    bool m_blocked;
-    QSet<QString> m_expandedItems;
 };
 
 
diff --git a/src/plugins/git/ScmGit.pluginspec b/src/plugins/git/ScmGit.pluginspec
index 689cc30a579ffebdbe624cd3a9e4da4f396772be..1f511448a07ff34696292ab6db6e9047185facb0 100644
--- a/src/plugins/git/ScmGit.pluginspec
+++ b/src/plugins/git/ScmGit.pluginspec
@@ -1,4 +1,4 @@
-<plugin name="ScmGit" version="0.1" compatVersion="0.1">
+<plugin name="ScmGit" version="0.9.1" compatVersion="0.9.1">
     <vendor>Nokia Corporation</vendor>
     <copyright>(C) 2008 Nokia Corporation</copyright>
     <license>Nokia Technology Preview License Agreement</license>
diff --git a/src/plugins/perforce/settingspage.cpp b/src/plugins/perforce/settingspage.cpp
index 5fd7dda48625f15af5295397276d7f13c64b17a1..b5cbd7fa0009fff3387fb851527d64627ef0f7aa 100644
--- a/src/plugins/perforce/settingspage.cpp
+++ b/src/plugins/perforce/settingspage.cpp
@@ -39,18 +39,20 @@
 #include <QtGui/QFileDialog>
 
 using namespace Perforce::Internal;
+using namespace Core::Utils;
 
 SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
     QWidget(parent)
 {
     m_ui.setupUi(this);
-    connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseForCommand()));
+    m_ui.pathChooser->setPromptDialogTitle(tr("Perforce Command"));
+    m_ui.pathChooser->setExpectedKind(PathChooser::Command);
 }
 
 PerforceSettings SettingsPageWidget::settings() const
 {
     PerforceSettings rc;
-    rc.p4Command = m_ui.p4CmdLineEdit->text();
+    rc.p4Command = m_ui.pathChooser->path();
     rc.defaultEnv = m_ui.defaultCheckBox->isChecked();
     rc.p4Port = m_ui.portLineEdit->text();
     rc.p4Client = m_ui.clientLineEdit->text();
@@ -60,21 +62,13 @@ PerforceSettings SettingsPageWidget::settings() const
 
 void SettingsPageWidget::setSettings(const PerforceSettings &s)
 {
-    m_ui.p4CmdLineEdit->setText(s.p4Command);
+    m_ui.pathChooser->setPath(s.p4Command);
     m_ui.defaultCheckBox->setChecked(s.defaultEnv);
     m_ui.portLineEdit->setText(s.p4Port);
     m_ui.clientLineEdit->setText(s.p4Client);
     m_ui.userLineEdit->setText(s.p4User);
 }
 
-void SettingsPageWidget::browseForCommand()
-{
-    const QString cmd = QFileDialog::getOpenFileName(window(), tr("Perforce Command"));
-    if (!cmd.isEmpty())
-        m_ui.p4CmdLineEdit->setText(cmd);
-}
-
-
 SettingsPage::SettingsPage()
 {
 }
diff --git a/src/plugins/perforce/settingspage.h b/src/plugins/perforce/settingspage.h
index f73a205e112b0644340eb0df34f731f3e72ae574..23e968125736822484b83339158811842e043a7b 100644
--- a/src/plugins/perforce/settingspage.h
+++ b/src/plugins/perforce/settingspage.h
@@ -54,9 +54,6 @@ public:
     PerforceSettings settings() const;
     void setSettings(const PerforceSettings &);
 
-private slots:;
-    void browseForCommand();
-
 private:
     Ui::SettingsPage m_ui;
 };
diff --git a/src/plugins/perforce/settingspage.ui b/src/plugins/perforce/settingspage.ui
index 1379b7b6666dc1f8cd4a2e3490c9a1b2fd1fc687..b2d6bf10e354968de9496a1de57e628aadb22733 100644
--- a/src/plugins/perforce/settingspage.ui
+++ b/src/plugins/perforce/settingspage.ui
@@ -36,14 +36,7 @@
       </widget>
      </item>
      <item>
-      <widget class="QLineEdit" name="p4CmdLineEdit"/>
-     </item>
-     <item>
-      <widget class="QToolButton" name="browseButton">
-       <property name="text">
-        <string>...</string>
-       </property>
-      </widget>
+      <widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
      </item>
     </layout>
    </item>
@@ -120,11 +113,18 @@
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Core::Utils::PathChooser</class>
+   <extends>QWidget</extends>
+   <header location="global">utils/pathchooser.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <tabstops>
   <tabstop>portLineEdit</tabstop>
   <tabstop>clientLineEdit</tabstop>
   <tabstop>userLineEdit</tabstop>
-  <tabstop>p4CmdLineEdit</tabstop>
  </tabstops>
  <resources/>
  <connections>
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index 2e06e1ae4e55f0a5db8dcf6401af366810c2fac6..b3950ab63b721581430b0f31d14712bd3a13cae5 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -483,23 +483,27 @@ void Qt4Project::updateCodeModel()
     files += m_projectFiles->files[SourceType];
     files += m_projectFiles->generatedFiles[SourceType];
 
-    CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this);
+    CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
 
-    if (pinfo->defines == predefinedMacros         &&
-        pinfo->includePaths == allIncludePaths     &&
-        pinfo->frameworkPaths == allFrameworkPaths &&
-        pinfo->sourceFiles == files) {
-        // Nothing to update...
+    if (pinfo.defines == predefinedMacros             &&
+            pinfo.includePaths == allIncludePaths     &&
+            pinfo.frameworkPaths == allFrameworkPaths &&
+            pinfo.sourceFiles == files) {
+        modelmanager->updateProjectInfo(pinfo);
     } else {
-        pinfo->defines = predefinedMacros;
+        pinfo.defines = predefinedMacros;
         // pinfo->defines += definedMacros;   // ### FIXME: me
-        pinfo->includePaths = allIncludePaths;
-        pinfo->frameworkPaths = allFrameworkPaths;
-        pinfo->sourceFiles = files;
+        pinfo.includePaths = allIncludePaths;
+        pinfo.frameworkPaths = allFrameworkPaths;
+        pinfo.sourceFiles = files;
+
+        modelmanager->updateProjectInfo(pinfo);
 
         modelmanager->GC();
-        modelmanager->updateSourceFiles(pinfo->sourceFiles);
+        modelmanager->updateSourceFiles(pinfo.sourceFiles);
     }
+
+    // update info
 }
 
 
diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp
index 1262f901785b12f91816ecec324ac7c442124bcd..421aa3b77aeeb1c0163144cd632b972fda917bf7 100644
--- a/src/plugins/qt4projectmanager/qtversionmanager.cpp
+++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp
@@ -969,7 +969,7 @@ void QtVersion::updateVersionInfo() const
                 QString line = stream.readLine();
                 int index = line.indexOf(":");
                 if (index != -1)
-                    m_versionInfo.insert(line.left(index), line.mid(index+1));
+                    m_versionInfo.insert(line.left(index), QDir::fromNativeSeparators(line.mid(index+1)));
             }
         }
 
@@ -1041,6 +1041,7 @@ void QtVersion::updateMkSpec() const
 //                        mkspec = mkspec.mid(QString("$$QT_BUILD_TREE/mkspecs/").length());
 //                    else if (mkspec.startsWith("$$QT_BUILD_TREE\\mkspecs\\"))
 //                        mkspec = mkspec.mid(QString("$$QT_BUILD_TREE\\mkspecs\\").length());
+//                    mkspec = QDir::fromNativeSeparators(mkspec);
 //                }
 //                break;
 //            }
@@ -1107,7 +1108,8 @@ void QtVersion::updateMkSpec() const
     int index = mkspec.lastIndexOf('/');
     if(index == -1)
         index = mkspec.lastIndexOf('\\');
-    if (index >= 0 && QDir(mkspec.left(index)).canonicalPath() == QDir(m_path + "/mkspecs/").canonicalPath())
+    QString mkspecDir = QDir(m_path + "/mkspecs/").canonicalPath();
+    if (index >= 0 && QDir(mkspec.left(index)).canonicalPath() == mkspecDir)
         mkspec = mkspec.mid(index+1).trimmed();
 
     m_mkspec = mkspec;
@@ -1119,7 +1121,7 @@ QString QtVersion::makeCommand() const
 {
 #ifdef Q_OS_WIN
     const QString &spec = mkspec();
-    if (spec.startsWith("win32-msvc") || spec == QLatin1String("win32-icc"))
+    if (spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc")))
         return "nmake.exe";
     else if(spec.startsWith("wince"))
         return "nmake.exe";
@@ -1156,7 +1158,7 @@ QtVersion::ToolchainType QtVersion::toolchainType() const
     if (!isValid())
         return INVALID;
     const QString &spec = mkspec();
-    if(spec.startsWith("win32-msvc") || spec == QLatin1String("win32-icc"))
+    if(spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc")))
         return MSVC;
     else if(spec == "win32-g++")
         return MinGW;
diff --git a/src/plugins/subversion/settingspage.cpp b/src/plugins/subversion/settingspage.cpp
index ab785db796e6ae7f41a9a49f949643109316aec8..4621928b9638a87e3752a4d99eedf88b4b2d7d2a 100644
--- a/src/plugins/subversion/settingspage.cpp
+++ b/src/plugins/subversion/settingspage.cpp
@@ -39,20 +39,24 @@
 #include <extensionsystem/pluginmanager.h>
 
 #include <QtGui/QFileDialog>
+#include <utils/pathchooser.h>
 
 using namespace Subversion::Internal;
+using namespace Core::Utils;
+
 
 SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
     QWidget(parent)
 {
     m_ui.setupUi(this);
-    connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseForCommand()));
+    m_ui.pathChooser->setExpectedKind(PathChooser::Command);
+    m_ui.pathChooser->setPromptDialogTitle(tr("Subversion Command"));
 }
 
 SubversionSettings SettingsPageWidget::settings() const
 {
     SubversionSettings rc;
-    rc.svnCommand = m_ui.svnCmdLineEdit->text();
+    rc.svnCommand = m_ui.pathChooser->path();
     rc.useAuthentication = m_ui.userGroupBox->isChecked();
     rc.user =  m_ui.usernameLineEdit->text();
     rc.password = m_ui.passwordLineEdit->text();
@@ -63,19 +67,12 @@ SubversionSettings SettingsPageWidget::settings() const
 
 void SettingsPageWidget::setSettings(const SubversionSettings &s)
 {
-    m_ui.svnCmdLineEdit->setText(s.svnCommand);
+    m_ui.pathChooser->setPath(s.svnCommand);
     m_ui.usernameLineEdit->setText(s.user);
     m_ui.passwordLineEdit->setText(s.password);
     m_ui.userGroupBox->setChecked(s.useAuthentication);
 }
 
-void SettingsPageWidget::browseForCommand()
-{
-    QString cmd = QFileDialog::getOpenFileName(window(), tr("Subversion Command"));
-    if (!cmd.isEmpty())
-        m_ui.svnCmdLineEdit->setText(cmd);
-}
-
 SettingsPage::SettingsPage()
 {
 }
diff --git a/src/plugins/subversion/settingspage.h b/src/plugins/subversion/settingspage.h
index f32401b6d93b052c0caaf2ca62273ebf49b8be79..8ac704f0727158b75c177a60eff995beb0ff6ac4 100644
--- a/src/plugins/subversion/settingspage.h
+++ b/src/plugins/subversion/settingspage.h
@@ -59,9 +59,6 @@ public:
     SubversionSettings settings() const;
     void setSettings(const SubversionSettings &);
 
-private slots:;
-    void browseForCommand();
-
 private:
     Ui::SettingsPage m_ui;
 };
diff --git a/src/plugins/subversion/settingspage.ui b/src/plugins/subversion/settingspage.ui
index 14e5ebce87e85099216c22028c33d1f677423432..21b20187bbd7dd5b59f25597ee9734fa31a5f38b 100644
--- a/src/plugins/subversion/settingspage.ui
+++ b/src/plugins/subversion/settingspage.ui
@@ -32,14 +32,7 @@
         </widget>
        </item>
        <item>
-        <widget class="QLineEdit" name="svnCmdLineEdit"/>
-       </item>
-       <item>
-        <widget class="QToolButton" name="browseButton">
-         <property name="text">
-          <string>...</string>
-         </property>
-        </widget>
+        <widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
        </item>
       </layout>
      </item>
@@ -109,9 +102,14 @@
    </item>
   </layout>
  </widget>
- <tabstops>
-  <tabstop>svnCmdLineEdit</tabstop>
- </tabstops>
+ <customwidgets>
+  <customwidget>
+   <class>Core::Utils::PathChooser</class>
+   <extends>QWidget</extends>
+   <header location="global">utils/pathchooser.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 49d29b75c93e5f8fe030fb7e6d38de05808c8f8b..82a4201b264576bdc79dacc33b6488bc32695357 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -602,29 +602,44 @@ void BaseTextEditor::slotSelectionChanged()
 void BaseTextEditor::gotoBlockStart()
 {
     QTextCursor cursor = textCursor();
-    if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false))
+    if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false)) {
         setTextCursor(cursor);
+        _q_matchParentheses();
+    }
 }
 
 void BaseTextEditor::gotoBlockEnd()
 {
     QTextCursor cursor = textCursor();
-    if (TextBlockUserData::findNextClosingParenthesis(&cursor, false))
+    if (TextBlockUserData::findNextClosingParenthesis(&cursor, false)) {
         setTextCursor(cursor);
+        _q_matchParentheses();
+    }
 }
 
 void BaseTextEditor::gotoBlockStartWithSelection()
 {
     QTextCursor cursor = textCursor();
-    if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true))
+    if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true)) {
         setTextCursor(cursor);
+        _q_matchParentheses();
+    }
 }
 
 void BaseTextEditor::gotoBlockEndWithSelection()
 {
     QTextCursor cursor = textCursor();
-    if (TextBlockUserData::findNextClosingParenthesis(&cursor, true))
+    if (TextBlockUserData::findNextClosingParenthesis(&cursor, true)) {
         setTextCursor(cursor);
+        _q_matchParentheses();
+    }
+}
+
+static QTextCursor flippedCursor(const QTextCursor &cursor) {
+    QTextCursor flipped = cursor;
+    flipped.clearSelection();
+    flipped.setPosition(cursor.anchor(), QTextCursor::KeepAnchor);
+    return flipped;
 }
 
 void BaseTextEditor::selectBlockUp()
@@ -640,7 +655,8 @@ void BaseTextEditor::selectBlockUp()
         return;
     if (!TextBlockUserData::findNextClosingParenthesis(&cursor, true))
         return;
-    setTextCursor(cursor);
+    setTextCursor(flippedCursor(cursor));
+    _q_matchParentheses();
 }
 
 void BaseTextEditor::selectBlockDown()
@@ -663,7 +679,8 @@ void BaseTextEditor::selectBlockDown()
     if ( cursor != d->m_selectBlockAnchor)
         TextBlockUserData::findNextClosingParenthesis(&cursor, true);
 
-    setTextCursor(cursor);
+    setTextCursor(flippedCursor(cursor));
+    _q_matchParentheses();
 }
 
 
diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp
index b00a259457ea99e9eef85fc27431fa4e8b0753b4..958c8985b058c560a6e642a3cb16c6cba79ebb3d 100644
--- a/tests/manual/gdbdebugger/simple/app.cpp
+++ b/tests/manual/gdbdebugger/simple/app.cpp
@@ -351,6 +351,23 @@ void testPlugin()
     }
 }
 
+void testSet()
+{
+    QSet<int> hgg0;
+    hgg0.insert(11);
+    hgg0.insert(22);
+
+    QSet<QString> hgg1;
+    hgg1.insert("22.0");
+
+    QObject ob;
+    QSet<QPointer<QObject> > hash;
+    QPointer<QObject> ptr(&ob);
+    //hash.insert(ptr);
+    //hash.insert(ptr);
+    //hash.insert(ptr);
+}
+
 void stringRefTest(const QString &refstring)
 {
     Q_UNUSED(refstring);
@@ -759,6 +776,7 @@ int main(int argc, char *argv[])
     testImage();
     testMap();
     testString();
+    testSet();
     testStringList();
     testStruct();
     //testThreads();
@@ -767,8 +785,13 @@ int main(int argc, char *argv[])
     testVariant3();
     testVector();
     testVectorOfList();
+
+
+    *(int *)0 = 0;
+
     testObject(argc, argv);
 
+
     //QColor color(255,128,10);
     //QFont font;