diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc
index a1f7ab3ed6f5acd617dd177f1ca21ff3923f4e41..4521b7e2fa4317c8eec094fc53e23be12ebfcc7b 100644
--- a/doc/qtcreator.qdoc
+++ b/doc/qtcreator.qdoc
@@ -814,21 +814,26 @@
     a pointer to some private data structure, you will see a list of children,
     signals and slots.
 
-    Similarily, instead of showing a bunch of pointers and ints,
-    a QHash or QMap will display its contents in an orderly fashion,
-    a QFileInfo will expose e.g. access data, and the otherwise
-    "opaque" QVariant gives access to the "real" contents.
-
-    The \gui{Locals and Watchers View} can be used to change the
-    contents of variables of simple data types like int or float
-    while the program is stopped. To do so, click into the 'Value'
-    column, modify the value there, and hit \key{Return}.
+    Similarly, instead of displaying many pointers and integers, Qt Creator's
+    debugger will display the contents of a QHash or QMap in an orderly manner.
+    Also, the debugger will display access data for QFileInfo and provide
+    access to the "real" contents of QVariant.
+
+    The \gui{Locals and Watchers} view can be used to change the contents of
+    variables of simple data types such as \c int or \c float when the program
+    is stopped. To do so, click on the \gui Value column, modify the value
+    with the inplace editor, and hit \key Enter (or \key Return).
     
 
-
     \section2 Modules
 
-    The \gui{Modules View} is hidden by default and only useful in
+    By default, the \gui Modules view is hidden as it is only useful with the
+    experimental delayed debug information loading feature. You can turn this
+    feature on by selecting \gui{Fast Debugger Start} 
+
+
+
+    The \gui Modules view is hidden by default and only useful in
     connection with the experimental feature of delayed debug 
     information loading. This feature is accessible by selecting
     \gui{Debug} and \gui{Fast Debugger Start}. When using the
@@ -849,29 +854,28 @@
     commands
         
 
+    \section1 A Walkthrough for the Debugger Frontend
 
-    \section1 A short walk through the debugger frontend
-
-    In our \l{Writing a Simple Program with Qt Creator}{TextFinder}
-    example, we read a text file into a QString and then display it with a
-    QTextEdit. Suppose, you would like to look at this QString, \c{line},
-    and see what data it actually stores. Follow the steps described below
-    to place a break point and view the QString object's data.
+    In our \l{Writing a Simple Program with Qt Creator}{TextFinder} example, we
+    read a text file into a QString and then display it with a QTextEdit.
+    Suppose, you would like to look at this QString, \c{line}, and see what
+    data it actually stores. Follow the steps described below to place a
+    breakpoint and view the QString object's data.
 
     \table
         \row
-	    \i \inlineimage qtcreator-setting-breakpoint1.png
+	        \i \inlineimage qtcreator-setting-breakpoint1.png
             \i \bold{Setting a Breakpoint}
 
     First, we set a breakpoint on the line where we invoke
-    \l{QTextEdit::}{setPlainText()} by clicking between the line number and
-    the window border. Then, select \gui{Start Debugging} from the
-    \gui{Debug} menu or press \key{F5}.
+    \l{QTextEdit::}{setPlainText()} by clicking between the line number and the
+    window border. Then, select \gui{Start Debugging} from the \gui{Debug} menu
+    or press \key{F5}.
     \endtable
 
     Breakpoints are visible in the \gui{Breakpoints} view, shown below, in
-    \gui{Debug} mode. If you wish to remove a breakpoint, simply right
-    click on it and select \gui{Delete breakpoint} from the context menu.
+    \gui{Debug} mode. If you wish to remove a breakpoint, simply right-click on
+    it and select \gui{Delete breakpoint} from the context menu.
 
     \image qtcreator-setting-breakpoint2.png
 
@@ -880,10 +884,10 @@
 
     \image qtcreator-watcher.png
 
-    Suppose we modify our \c{on_findButton_clicked()} function to move back
-    to the start of the document and continue searching once the cursor
-    hits the end of the document. Adding this functionality can be done
-    with the code snippet below:
+    Suppose we modify our \c{on_findButton_clicked()} function to move back to
+    the start of the document and continue searching once the cursor hits the
+    end of the document. Adding this functionality can be done with the code
+    snippet below:
 
     \code
     void TextFinder::on_findButton_clicked()
@@ -915,9 +919,9 @@
     }
     \endcode
 
-    However, if you compile and run this code, the application will not
-    work correctly due to a logic error. To locate this logic error, you
-    can step through the code using the following buttons:
+    However, if you compile and run this code, the application will not work
+    correctly due to a logic error. To locate this logic error, you can step
+    through the code using the following buttons:
 
     \image qtcreator-debugging-buttons.png
 */
@@ -931,20 +935,20 @@
 
     \title Tips and Tricks
 
-    \bold{Quick mode switch}
+    \bold{Quickly Switching between Modes}
 
     You can quickly switch between modes by pressing \key{Ctrl+1},
-    \key{Ctrl+2}, etc.
+    \key{Ctrl+2}, and so on.
 
-    \bold{Other keyboard shortcuts}
+    \bold{Keyboard Shortcuts}
 
-    There are a lot of other \l{keyboard-shortcuts}{keyboard shortcuts}.
+    Qt Creator provides a lot of useful keyboard shortcuts. A complete list can
+    be found \l{Keyboard Shortcuts}{here}.
 
-    \bold{Command line}
+    \bold{Running Qt Creator from the Command Line}
 
-    You can start Qt Creator from a command prompt with an already
-    existing session or \c{.pro} file by giving the name as argument on the
-    command line.
+    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}
 
diff --git a/shared/cplusplus/Scope.cpp b/shared/cplusplus/Scope.cpp
index 2c1b986b2c9f48d5afc19a08f5bcb0fc7b90f629..47221da121f58bd39c596bdba6e6b7f69d0067cb 100644
--- a/shared/cplusplus/Scope.cpp
+++ b/shared/cplusplus/Scope.cpp
@@ -292,6 +292,7 @@ Use *Scope::useAt(unsigned index) const
 
 void Scope::addUse(unsigned sourceOffset, Name *name)
 {
+#ifdef CPLUSPLUS_WITH_USES
     if (++_useCount == _allocatedUses) {
         _allocatedUses += 4;
         _uses = reinterpret_cast<Use *>(realloc(_uses, _allocatedUses * sizeof(Use)));
@@ -303,6 +304,7 @@ void Scope::addUse(unsigned sourceOffset, Name *name)
     else
         lastVisibleSymbol = _symbols[_symbolCount];
     _uses[_useCount].init(sourceOffset, name, lastVisibleSymbol);
+#endif
 }
 
 CPLUSPLUS_END_NAMESPACE
diff --git a/shared/help/help.pri b/shared/help/help.pri
index 9503d085938b6ae619b5d2567fa3fe8a163ec88a..dff0ae7699b673175d3571ba8d4ffa952340805e 100644
--- a/shared/help/help.pri
+++ b/shared/help/help.pri
@@ -9,7 +9,8 @@ HEADERS += \
         $$PWD/helpviewer.h \
         $$PWD/contentwindow.h \
         $$PWD/bookmarkmanager.h \
-        $$PWD/../namespace_global.h
+        $$PWD/../namespace_global.h \
+        $$PWD/indexwindow.h
 
 SOURCES += \
         $$PWD/filternamedialog.cpp \
@@ -19,7 +20,7 @@ SOURCES += \
         $$PWD/contentwindow.cpp \
         $$PWD/bookmarkmanager.cpp
 
-FORMS 	+= \
+FORMS   += \
         $$PWD/filternamedialog.ui \
         $$PWD/topicchooser.ui \
         $$PWD/bookmarkdialog.ui
diff --git a/src/libs/cplusplus/Icons.cpp b/src/libs/cplusplus/Icons.cpp
index 94b6469ea46b74a85b739bc5512f030d63a90ae9..3b7ee24da3cc595af3b13d1336e24612ffa7df18 100644
--- a/src/libs/cplusplus/Icons.cpp
+++ b/src/libs/cplusplus/Icons.cpp
@@ -61,11 +61,11 @@ Icons::Icons()
 {
 }
 
-QIcon Icons::iconForSymbol(Symbol *symbol) const
+QIcon Icons::iconForSymbol(const Symbol *symbol) const
 {
     if (symbol->isFunction() || (symbol->isDeclaration() && symbol->type()->isFunction()))
     {
-        Function *function = symbol->asFunction();
+        const Function *function = symbol->asFunction();
         if (!function)
             function = symbol->type()->asFunction();
 
diff --git a/src/libs/cplusplus/Icons.h b/src/libs/cplusplus/Icons.h
index c49bcde12d145dba778329830f3413846d29f376..6d4e0bb25d66fe6274bf13d1def75f78fac28097 100644
--- a/src/libs/cplusplus/Icons.h
+++ b/src/libs/cplusplus/Icons.h
@@ -47,7 +47,7 @@ class CPLUSPLUS_EXPORT Icons
 public:
     Icons();
 
-    QIcon iconForSymbol(Symbol *symbol) const;
+    QIcon iconForSymbol(const Symbol *symbol) const;
 
     QIcon keywordIcon() const;
     QIcon macroIcon() const;
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 019cbfff1ff1656321b595a49c702992ced15950..cfcd06cacd7067b55000916460c59aa08dcb5c83 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -235,9 +235,9 @@ bool ResolveExpression::visit(ExpressionListAST *)
     return false;
 }
 
-bool ResolveExpression::visit(BinaryExpressionAST *)
+bool ResolveExpression::visit(BinaryExpressionAST *ast)
 {
-    // nothing to do.
+    accept(ast->left_expression);
     return false;
 }
 
diff --git a/src/libs/utils/filenamevalidatinglineedit.cpp b/src/libs/utils/filenamevalidatinglineedit.cpp
index 57a0ed7a5f91577946807db122112559ffe75a0c..5b308f5ce4728eef5823a2c82be842180438e5e3 100644
--- a/src/libs/utils/filenamevalidatinglineedit.cpp
+++ b/src/libs/utils/filenamevalidatinglineedit.cpp
@@ -33,26 +33,65 @@
 
 #include "filenamevalidatinglineedit.h"
 
+#include <QtCore/QRegExp>
+#include <QtCore/QDebug>
+
 namespace Core {
 namespace Utils {
 
+// Naming a file like a device name will break on Windows, even if it is
+// "com1.txt". Since we are cross-platform, we generally disallow such file
+//  names.
+static const QRegExp &windowsDeviceNoSubDirPattern()
+{
+    static const QRegExp rc(QLatin1String("CON|AUX|PRN|COM1|COM2|LPT1|LPT2|NUL"),
+                      Qt::CaseInsensitive);
+    Q_ASSERT(rc.isValid());
+    return rc;
+}
+
+static const QRegExp &windowsDeviceSubDirPattern()
+{
+    static const QRegExp rc(QLatin1String(".*[/\\\\]CON|.*[/\\\\]AUX|.*[/\\\\]PRN|.*[/\\\\]COM1|.*[/\\\\]COM2|.*[/\\\\]LPT1|.*[/\\\\]LPT2|.*[/\\\\]NUL"),
+                            Qt::CaseInsensitive);
+    Q_ASSERT(rc.isValid());
+    return rc;
+}
+
+// ----------- FileNameValidatingLineEdit
 FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
-    BaseValidatingLineEdit(parent)
+    BaseValidatingLineEdit(parent),
+    m_allowDirectories(false),
+    m_unused(0)
+{
+}
+
+bool FileNameValidatingLineEdit::allowDirectories() const
 {
+    return m_allowDirectories;
+}
 
+void FileNameValidatingLineEdit::setAllowDirectories(bool v)
+{
+    m_allowDirectories = v;
 }
 
 /* Validate a file base name, check for forbidden characters/strings. */
 
-static const char *notAllowedChars = "/?:&\\*\"|#%<> ";
-static const char *notAllowedSubStrings[] = {".."};
+#ifdef Q_OS_WIN
+#  define SLASHES "/\\"
+#else
+#  define SLASHES "/"
+#endif
 
-// Naming a file like a device name will break on Windows, even if it is
-// "com1.txt". Since we are cross-platform, we generally disallow such file
-//  names.
-static const char *notAllowedStrings[] = {"CON", "AUX", "PRN", "COM1", "COM2", "LPT1", "LPT2" };
+static const char *notAllowedCharsSubDir   = "?:&*\"|#%<> ";
+static const char *notAllowedCharsNoSubDir = "?:&*\"|#%<> "SLASHES;
 
-bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *errorMessage /* = 0*/)
+static const char *notAllowedSubStrings[] = {".."};
+
+bool FileNameValidatingLineEdit::validateFileName(const QString &name,
+                                                  bool allowDirectories,
+                                                  QString *errorMessage /* = 0*/)
 {
     if (name.isEmpty()) {
         if (errorMessage)
@@ -60,6 +99,7 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *
         return false;
     }
     // Characters
+    const char *notAllowedChars = allowDirectories ? notAllowedCharsSubDir : notAllowedCharsNoSubDir;
     for (const char *c = notAllowedChars; *c; c++)
         if (name.contains(QLatin1Char(*c))) {
             if (errorMessage)
@@ -76,22 +116,22 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *
             return false;
         }
     }
-    // Strings
-    const int notAllowedStringCount = sizeof(notAllowedStrings)/sizeof(const char *);
-    for (int s = 0; s < notAllowedStringCount; s++) {
-        const QLatin1String notAllowedString(notAllowedStrings[s]);
-        if (name == notAllowedString) {
-            if (errorMessage)
-                *errorMessage = tr("The name must not be '%1'.").arg(QString(notAllowedString));
-            return false;
-        }
+    // Windows devices
+    bool matchesWinDevice = windowsDeviceNoSubDirPattern().exactMatch(name);
+    if (!matchesWinDevice && allowDirectories)
+        matchesWinDevice = windowsDeviceSubDirPattern().exactMatch(name);
+    if (matchesWinDevice) {
+        if (errorMessage)
+            *errorMessage = tr("The name must not match that of a MS Windows device. (%1).").
+                            arg(windowsDeviceNoSubDirPattern().pattern().replace(QLatin1Char('|'), QLatin1Char(',')));
+        return false;
     }
     return true;
 }
 
 bool  FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
 {
-    return validateFileName(value, errorMessage);
+    return validateFileName(value, m_allowDirectories, errorMessage);
 }
 
 } // namespace Utils
diff --git a/src/libs/utils/filenamevalidatinglineedit.h b/src/libs/utils/filenamevalidatinglineedit.h
index 5476e3cd5e936ec5c4084fe911526153dc092673..042a48fc5f19f5d1bd5a6df02aed5c29a3b0f2f2 100644
--- a/src/libs/utils/filenamevalidatinglineedit.h
+++ b/src/libs/utils/filenamevalidatinglineedit.h
@@ -43,14 +43,23 @@ class QWORKBENCH_UTILS_EXPORT FileNameValidatingLineEdit : public BaseValidating
 {
     Q_OBJECT
     Q_DISABLE_COPY(FileNameValidatingLineEdit)
-
+    Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
 public:
     explicit FileNameValidatingLineEdit(QWidget *parent = 0);
 
-    static bool validateFileName(const QString &name, QString *errorMessage /* = 0*/);
+    static bool validateFileName(const QString &name,
+                                 bool allowDirectories = false,
+                                 QString *errorMessage = 0);
+
+    bool allowDirectories() const;
+    void setAllowDirectories(bool v);
 
 protected:
     virtual bool validate(const QString &value, QString *errorMessage) const;
+
+private:
+    bool m_allowDirectories;
+    void *m_unused;
 };
 
 } // namespace Utils
diff --git a/src/libs/utils/filewizardpage.cpp b/src/libs/utils/filewizardpage.cpp
index 8a12e4c0f3c98a016aa1deedd3093243840b61af..3e85b34d44b729142ff233b5f16f2d37cdc06e23 100644
--- a/src/libs/utils/filewizardpage.cpp
+++ b/src/libs/utils/filewizardpage.cpp
@@ -123,7 +123,7 @@ void FileWizardPage::slotActivated()
 
 bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/)
 {
-    return FileNameValidatingLineEdit::validateFileName(name, errorMessage);
+    return FileNameValidatingLineEdit::validateFileName(name, false, errorMessage);
 }
 
 } // namespace Utils
diff --git a/src/libs/utils/newclasswidget.cpp b/src/libs/utils/newclasswidget.cpp
index df7d81e7b39c9b854fc53cef019de68935d897f0..b34ee40d4fe9469745edd98531560335b682f5ff 100644
--- a/src/libs/utils/newclasswidget.cpp
+++ b/src/libs/utils/newclasswidget.cpp
@@ -346,6 +346,21 @@ void NewClassWidget::setFormExtension(const QString &e)
     m_d->m_formExtension = fixSuffix(e);
 }
 
+bool NewClassWidget::allowDirectories() const
+{
+    return m_d->m_ui.headerFileLineEdit->allowDirectories();
+}
+
+void NewClassWidget::setAllowDirectories(bool v)
+{
+    // We keep all in sync
+    if (allowDirectories() != v) {
+        m_d->m_ui.sourceFileLineEdit->setAllowDirectories(v);
+        m_d->m_ui.headerFileLineEdit->setAllowDirectories(v);
+        m_d->m_ui.formFileLineEdit->setAllowDirectories(v);
+    }
+}
+
 void NewClassWidget::slotValidChanged()
 {
     const bool newValid = isValid();
diff --git a/src/libs/utils/newclasswidget.h b/src/libs/utils/newclasswidget.h
index 04c2aaf58a4f4143ba521955e85e474f87fc943e..40c850d28e94b55809cc91a3d74961a0b8d24bed 100644
--- a/src/libs/utils/newclasswidget.h
+++ b/src/libs/utils/newclasswidget.h
@@ -73,6 +73,7 @@ class QWORKBENCH_UTILS_EXPORT NewClassWidget : public QWidget
     Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension DESIGNABLE true)
     Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true)
     Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true)
+    Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
     // Utility "USER" property for wizards containing file names.
     Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true)
 public:
@@ -97,7 +98,7 @@ public:
     QString sourceExtension() const;
     QString headerExtension() const;
     QString formExtension() const;
-
+    bool allowDirectories() const;
 
     bool isValid(QString *error = 0) const;
 
@@ -125,6 +126,7 @@ public slots:
     void setSourceExtension(const QString &e);
     void setHeaderExtension(const QString &e);
     void setFormExtension(const QString &e);
+    void setAllowDirectories(bool v);
 
     /* Suggest a class name from the base class by stripping the leading 'Q'
      * character. This will happen automagically if the base class combo
diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h
index 7ae60a255bf17c7d55d24121e3ec823e24cbb93c..ab821d5df1eebffd60f53336c2f43ebb46b782d4 100644
--- a/src/libs/utils/pathchooser.h
+++ b/src/libs/utils/pathchooser.h
@@ -30,6 +30,7 @@
 ** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
 **
 ***************************************************************************/
+
 #ifndef PATHCHOOSER_H
 #define PATHCHOOSER_H
 
diff --git a/src/libs/utils/projectnamevalidatinglineedit.cpp b/src/libs/utils/projectnamevalidatinglineedit.cpp
index df77af8e832a21e41746e99c6199bcaa5a9ca1fb..4160bc18792f8a24714fc35fe431415117f0e90c 100644
--- a/src/libs/utils/projectnamevalidatinglineedit.cpp
+++ b/src/libs/utils/projectnamevalidatinglineedit.cpp
@@ -45,7 +45,7 @@ ProjectNameValidatingLineEdit::ProjectNameValidatingLineEdit(QWidget *parent)
 bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/)
 {
     // Validation is file name + checking for dots
-    if (!FileNameValidatingLineEdit::validateFileName(name, errorMessage))
+    if (!FileNameValidatingLineEdit::validateFileName(name, false, errorMessage))
         return false;
 
     // We don't want dots in the directory name for some legacy Windows
diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp
index 078373aa20837842dc505edbf791703539c73a06..6a1b2efa8403d49a73c39712b054a1396717edff 100644
--- a/src/libs/utils/synchronousprocess.cpp
+++ b/src/libs/utils/synchronousprocess.cpp
@@ -125,6 +125,7 @@ struct SynchronousProcessPrivate {
     SynchronousProcessResponse m_result;
     int m_hangTimerCount;
     int m_maxHangTimerCount;
+    bool m_startFailure;
 
     ChannelBuffer m_stdOut;
     ChannelBuffer m_stdErr;
@@ -133,7 +134,8 @@ struct SynchronousProcessPrivate {
 SynchronousProcessPrivate::SynchronousProcessPrivate() :
     m_stdOutCodec(0),
     m_hangTimerCount(0),
-    m_maxHangTimerCount(defaultMaxHangTimerCount)
+    m_maxHangTimerCount(defaultMaxHangTimerCount),
+    m_startFailure(false)
 {
 }
 
@@ -143,6 +145,7 @@ void SynchronousProcessPrivate::clearForRun()
     m_stdOut.clearForRun();
     m_stdErr.clearForRun();
     m_result.clear();
+    m_startFailure = false;
 }
 
 // ----------- SynchronousProcess
@@ -221,22 +224,26 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
         qDebug() << '>' << Q_FUNC_INFO << binary << args;
 
     m_d->clearForRun();
-    m_d->m_timer.start();
-
-    QApplication::setOverrideCursor(Qt::WaitCursor);
 
+    // On Windows, start failure is triggered immediately if the
+    // executable cannot be found in the path. Do not start the
+    // event loop in that case.
     m_d->m_process.start(binary, args, QIODevice::ReadOnly);
-    m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
-    if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) {
-        processStdOut(false);
-        processStdErr(false);
-    }
+    if (!m_d->m_startFailure) {
+        m_d->m_timer.start();
+        QApplication::setOverrideCursor(Qt::WaitCursor);
+        m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
+        if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) {
+            processStdOut(false);
+            processStdErr(false);
+        }
 
-    m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data);
-    m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data);
+        m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data);
+        m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data);
 
-    m_d->m_timer.stop();
-    QApplication::restoreOverrideCursor();
+        m_d->m_timer.stop();
+        QApplication::restoreOverrideCursor();
+    }
 
     if (debug)
         qDebug() << '<' << Q_FUNC_INFO << binary << m_d->m_result;
@@ -246,12 +253,14 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
 void SynchronousProcess::slotTimeout()
 {
     if (++m_d->m_hangTimerCount > m_d->m_maxHangTimerCount) {
+        if (debug)
+            qDebug() << Q_FUNC_INFO << "HANG detected, killing";
         m_d->m_process.kill();
         m_d->m_result.result = SynchronousProcessResponse::Hang;
+    } else {
+        if (debug)
+            qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount;
     }
-
-    if (debug)
-        qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount;
 }
 
 void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e)
@@ -265,7 +274,9 @@ void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e)
         m_d->m_result.exitCode = exitCode;
         break;
     case QProcess::CrashExit:
-        m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally;
+        // Was hang detected before and killed?
+        if (m_d->m_result.result != SynchronousProcessResponse::Hang)
+            m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally;
         m_d->m_result.exitCode = -1;
         break;
     }
@@ -277,7 +288,10 @@ void SynchronousProcess::error(QProcess::ProcessError e)
     m_d->m_hangTimerCount = 0;
     if (debug)
         qDebug() << Q_FUNC_INFO << e;
-    m_d->m_result.result = SynchronousProcessResponse::StartFailed;
+    // Was hang detected before and killed?
+    if (m_d->m_result.result != SynchronousProcessResponse::Hang)
+        m_d->m_result.result = SynchronousProcessResponse::StartFailed;
+    m_d->m_startFailure = true;
     m_d->m_eventLoop.quit();
 }
 
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index 59222acc419685bae0994a0aca0e75fb4c632721..1d9050705496bc05501ed25a3a22cec105f034ce 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -127,6 +127,7 @@ MainWindow::MainWindow() :
     m_mimeDatabase(new MimeDatabase),
     m_navigationWidget(0),
     m_rightPaneWidget(0),
+    m_versionDialog(0),
     m_activeContext(0),
     m_pluginManager(0),
     m_outputPane(new OutputPane(m_globalContext)),
@@ -1085,8 +1086,20 @@ void MainWindow::openRecentFile()
 
 void MainWindow::aboutQtCreator()
 {
-    VersionDialog versionDialog(this);
-    versionDialog.exec();
+    if (!m_versionDialog) {
+        m_versionDialog = new VersionDialog(this);
+        connect(m_versionDialog, SIGNAL(finished(int)),
+                this, SLOT(destroyVersionDialog()));
+    }
+    m_versionDialog->show();
+}
+
+void MainWindow::destroyVersionDialog()
+{
+    if (m_versionDialog) {
+        m_versionDialog->deleteLater();
+        m_versionDialog = 0;
+    }
 }
 
 void MainWindow::aboutPlugins()
diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h
index 180b932d710bffe7d0b1e71cd5d85ecd937fda41..a8edd089972489c1076ddf1359d078969ec6aa2e 100644
--- a/src/plugins/coreplugin/mainwindow.h
+++ b/src/plugins/coreplugin/mainwindow.h
@@ -83,6 +83,7 @@ class OutputPane;
 class ProgressManager;
 class ShortcutSettings;
 class ViewManager;
+class VersionDialog;
 
 class CORE_EXPORT  MainWindow : public QMainWindow
 {
@@ -160,6 +161,7 @@ private slots:
     void aboutPlugins();
     void updateFocusWidget(QWidget *old, QWidget *now);
     void toggleNavigation();
+    void destroyVersionDialog();
 
 private:
     void updateContextObject(IContext *context);
@@ -190,6 +192,7 @@ private:
     NavigationWidget *m_navigationWidget;
     RightPaneWidget *m_rightPaneWidget;
     Core::BaseView *m_outputView;
+    VersionDialog *m_versionDialog;
 
     IContext * m_activeContext;
 
diff --git a/src/plugins/cppeditor/cppclasswizard.cpp b/src/plugins/cppeditor/cppclasswizard.cpp
index 6730f5b9ed9c388184b1d6040bb55cfe433b0bda..652eec535f18aa4221e7bb1055e780a14a569979 100644
--- a/src/plugins/cppeditor/cppclasswizard.cpp
+++ b/src/plugins/cppeditor/cppclasswizard.cpp
@@ -73,6 +73,7 @@ ClassNamePage::ClassNamePage(const QString &sourceSuffix,
     m_newClassWidget->setBaseClassEditable(true);
     m_newClassWidget->setFormInputVisible(false);
     m_newClassWidget->setNamespacesEnabled(true);
+    m_newClassWidget->setAllowDirectories(true);
 
     connect(m_newClassWidget, SIGNAL(validChanged()),
             this, SLOT(slotValidChanged()));
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 254e9341de66b16c24f814dfadeecd1ec0a7170d..da52bb3d6016a367647e00aa59197607fa8d19fa 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -206,6 +206,7 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
 
     connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int)));
     connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex()));
+    connect(m_methodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMethodBoxToolTip()));
 
     connect(file(), SIGNAL(changed()), this, SLOT(updateFileName()));
 
@@ -355,10 +356,16 @@ void CPPEditor::updateMethodBoxIndex()
     if (lastIndex.isValid()) {
         bool blocked = m_methodCombo->blockSignals(true);
         m_methodCombo->setCurrentIndex(lastIndex.row());
+        updateMethodBoxToolTip();
         (void) m_methodCombo->blockSignals(blocked);
     }
 }
 
+void CPPEditor::updateMethodBoxToolTip()
+{
+    m_methodCombo->setToolTip(m_methodCombo->currentText());
+}
+
 static bool isCompatible(Name *name, Name *otherName)
 {
     if (NameId *nameId = name->asNameId()) {
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index e6c6d1aa8633cd807179308b2761685119a0a247..2420bcf4e5e441d67834d5d9d0a612dbbad09f06 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -115,7 +115,7 @@ private slots:
     void updateFileName();
     void jumpToMethod(int index);
     void updateMethodBoxIndex();
-
+    void updateMethodBoxToolTip();
     void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
 
 private:
diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6aa6734fca90b2c0b2d672e8bdaa532975766f4c
--- /dev/null
+++ b/src/plugins/cpptools/cppclassesfilter.cpp
@@ -0,0 +1,50 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "cppclassesfilter.h"
+
+using namespace CppTools::Internal;
+
+CppClassesFilter::CppClassesFilter(CppModelManager *manager, Core::EditorManager *editorManager)
+    : CppQuickOpenFilter(manager, editorManager)
+{
+    setShortcutString("c");
+    setIncludedByDefault(false);
+
+    search.setSymbolsToSearchFor(SearchSymbols::Classes);
+    search.setSeparateScope(true);
+}
+
+CppClassesFilter::~CppClassesFilter()
+{
+}
diff --git a/src/plugins/help/indexwindow.h b/src/plugins/cpptools/cppclassesfilter.h
similarity index 58%
rename from src/plugins/help/indexwindow.h
rename to src/plugins/cpptools/cppclassesfilter.h
index 51ebb06653d197fa2fd1b74f5bcdf1bcc44031c8..ba936eab869fe76cf9b9a0b9ef1ac5f0f266965e 100644
--- a/src/plugins/help/indexwindow.h
+++ b/src/plugins/cpptools/cppclassesfilter.h
@@ -31,52 +31,28 @@
 **
 ***************************************************************************/
 
-#ifndef INDEXWINDOW_H
-#define INDEXWINDOW_H
+#ifndef CPPCLASSESFILTER_H
+#define CPPCLASSESFILTER_H
 
-#include <QtCore/QUrl>
-#include <QtGui/QWidget>
-#include <QtGui/QLineEdit>
+#include <cppquickopenfilter.h>
 
-QT_BEGIN_NAMESPACE
+namespace CppTools {
+namespace Internal {
 
-class QHelpIndexWidget;
-class QHelpEngine;
-
-class IndexWindow : public QWidget
+class CppClassesFilter : public CppQuickOpenFilter
 {
     Q_OBJECT
 
 public:
-    IndexWindow(QHelpEngine *helpEngine, QWidget *parent = 0);
-    ~IndexWindow();
-
-    void setSearchLineEditText(const QString &text);
-    QString searchLineEditText() const
-    {
-        return m_searchLineEdit->text();
-    }
-
-signals:
-    void linkActivated(const QUrl &link);
-    void linksActivated(const QMap<QString, QUrl> &links,
-        const QString &keyword);
-    void escapePressed();
-
-private slots:
-    void filterIndices(const QString &filter);
-    void enableSearchLineEdit();
-    void disableSearchLineEdit();
-
-private:
-    bool eventFilter(QObject *obj, QEvent *e);
-    void focusInEvent(QFocusEvent *e);
+    CppClassesFilter(CppModelManager *manager, Core::EditorManager *editorManager);
+    ~CppClassesFilter();
 
-    QLineEdit *m_searchLineEdit;
-    QHelpIndexWidget *m_indexWidget;
-    QHelpEngine *m_helpEngine;
+    QString trName() const { return tr("Classes"); }
+    QString name() const { return QLatin1String("Classes"); }
+    Priority priority() const { return Medium; }
 };
 
-QT_END_NAMESPACE
+} // namespace Internal
+} // namespace CppTools
 
-#endif // INDEXWINDOW_H
+#endif // CPPCLASSESFILTER_H
diff --git a/src/plugins/cpptools/cpphoverhandler.cpp b/src/plugins/cpptools/cpphoverhandler.cpp
index 37b63bda9c23f4adf11670e34062efaded814a18..16ed8a9215039009e6d47403939d02d996824f83 100644
--- a/src/plugins/cpptools/cpphoverhandler.cpp
+++ b/src/plugins/cpptools/cpphoverhandler.cpp
@@ -60,7 +60,7 @@
 using namespace CppTools::Internal;
 
 CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent)
-    : QObject(parent), m_manager(manager)
+    : QObject(parent), m_manager(manager), m_helpEngineNeedsSetup(false)
 {
     QFileInfo fi(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>()->settings()->fileName());
     m_helpEngine = new QHelpEngineCore(fi.absolutePath()
@@ -68,6 +68,7 @@ CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent)
     //m_helpEngine->setAutoSaveFilter(false);
     m_helpEngine->setupData();
     m_helpEngine->setCurrentFilter(tr("Unfiltered"));
+    m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0;
 }
 
 void CppHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos)
@@ -234,6 +235,12 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
         }
     }
 
+    if (m_helpEngineNeedsSetup
+        && m_helpEngine->registeredDocumentations().count() > 0) {
+        m_helpEngine->setupData();
+        m_helpEngineNeedsSetup = false;
+    }
+
     if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) {
         m_toolTip = QString(QLatin1String("<table><tr><td valign=middle><nobr>%1</td>"
                                           "<td><img src=\":/cpptools/images/f1.svg\"></td></tr></table>")).arg(Qt::escape(m_toolTip));
diff --git a/src/plugins/cpptools/cpphoverhandler.h b/src/plugins/cpptools/cpphoverhandler.h
index 9aaa17cb0f88e1e47c04ebca1a96114f53f6917b..d1de5277b1241468b5dfdfbeff5d9ec14ea49927 100644
--- a/src/plugins/cpptools/cpphoverhandler.h
+++ b/src/plugins/cpptools/cpphoverhandler.h
@@ -68,6 +68,7 @@ private:
     QHelpEngineCore *m_helpEngine;
     QString m_helpId;
     QString m_toolTip;
+    bool m_helpEngineNeedsSetup;
 };
 
 } // namespace Internal
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index ccaff0bcfe5cf2e40a43a815004953f11c9a3607..042b93cc74d064a0bf007f29f587c79791a9355d 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -129,9 +129,12 @@ public:
     void setProjectFiles(const QStringList &files)
     { m_projectFiles = files; }
 
-    void operator()(QString &fileName)
+    void run(QString &fileName)
     { sourceNeeded(fileName, IncludeGlobal); }
 
+    void operator()(QString &fileName)
+    { run(fileName); }
+
 protected:
     bool includeFile(const QString &absoluteFilePath, QByteArray *result)
     {
@@ -254,7 +257,7 @@ protected:
     }
 
     virtual void startExpandingMacro(unsigned offset,
-                                     const rpp::Macro &macro,
+                                     const rpp::Macro &,
                                      const QByteArray &originalText)
     {
         if (! m_currentDoc)
@@ -264,7 +267,7 @@ protected:
         m_currentDoc->addMacroUse(offset, originalText.length());
     }
 
-    virtual void stopExpandingMacro(unsigned offset, const rpp::Macro &macro)
+    virtual void stopExpandingMacro(unsigned, const rpp::Macro &)
     {
         if (! m_currentDoc)
             return;
@@ -409,6 +412,8 @@ CppModelManager::CppModelManager(QObject *parent) :
     CppModelManagerInterface(parent),
     m_core(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>())
 {
+    m_dirty = true;
+
     m_projectExplorer = ExtensionSystem::PluginManager::instance()
                         ->getObject<ProjectExplorer::ProjectExplorerPlugin>();
 
@@ -417,6 +422,9 @@ CppModelManager::CppModelManager(QObject *parent) :
     ProjectExplorer::SessionManager *session = m_projectExplorer->session();
     Q_ASSERT(session != 0);
 
+    connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
+            this, SLOT(onProjectAdded(ProjectExplorer::Project*)));
+
     connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
             this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *)));
 
@@ -448,7 +456,7 @@ Document::Ptr CppModelManager::document(const QString &fileName)
 CppModelManager::DocumentTable CppModelManager::documents()
 { return m_documents; }
 
-QStringList CppModelManager::projectFiles() const
+QStringList CppModelManager::updateProjectFiles() const
 {
     QStringList files;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -460,7 +468,7 @@ QStringList CppModelManager::projectFiles() const
     return files;
 }
 
-QStringList CppModelManager::includePaths() const
+QStringList CppModelManager::updateIncludePaths() const
 {
     QStringList includePaths;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -472,7 +480,7 @@ QStringList CppModelManager::includePaths() const
     return includePaths;
 }
 
-QStringList CppModelManager::frameworkPaths() const
+QStringList CppModelManager::updateFrameworkPaths() const
 {
     QStringList frameworkPaths;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -484,7 +492,7 @@ QStringList CppModelManager::frameworkPaths() const
     return frameworkPaths;
 }
 
-QByteArray CppModelManager::definedMacros() const
+QByteArray CppModelManager::updateDefinedMacros() const
 {
     QByteArray macros;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -496,7 +504,7 @@ QByteArray CppModelManager::definedMacros() const
     return macros;
 }
 
-QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList() const
+QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList()
 {
     QMap<QString, QByteArray> workingCopy;
     QMapIterator<TextEditor::ITextEditor *, CppEditorSupport *> it(m_editorSupport);
@@ -527,8 +535,14 @@ QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles
     if (! sourceFiles.isEmpty() && qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) {
         const QMap<QString, QByteArray> workingCopy = buildWorkingCopyList();
 
-        QFuture<void> result = QtConcurrent::run(&CppModelManager::parse, this,
-                                                 sourceFiles, workingCopy);
+        CppPreprocessor *preproc = new CppPreprocessor(this);
+        preproc->setProjectFiles(projectFiles());
+        preproc->setIncludePaths(includePaths());
+        preproc->setFrameworkPaths(frameworkPaths());
+        preproc->setWorkingCopy(workingCopy);
+
+        QFuture<void> result = QtConcurrent::run(&CppModelManager::parse,
+                                                 preproc, sourceFiles);
 
         if (sourceFiles.count() > 1) {
             m_core->progressManager()->addTask(result, tr("Indexing"),
@@ -669,28 +683,35 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
                 sel.cursor = c;
                 selections.append(sel);
             }
-            ed->setExtraExtraSelections(selections);
+            ed->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection, selections);
             break;
         }
     }
 }
 
+void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
+{
+    m_dirty = true;
+}
+
 void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
 {
+    m_dirty = true;
     m_projects.remove(project);
     GC();
 }
 
 void CppModelManager::onSessionUnloaded()
 {
-    if (m_core->progressManager())
+    if (m_core->progressManager()) {
         m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX);
+        m_dirty = true;
+    }
 }
 
 void CppModelManager::parse(QFutureInterface<void> &future,
-                            CppModelManager *model,
-                            QStringList files,
-                            QMap<QString, QByteArray> workingCopy)
+                            CppPreprocessor *preproc,
+                            QStringList files)
 {
     Q_ASSERT(! files.isEmpty());
 
@@ -699,14 +720,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 
     future.setProgressRange(0, files.size());
 
-    CppPreprocessor preproc(model);
-    preproc.setWorkingCopy(workingCopy);
-    preproc.setProjectFiles(model->projectFiles());
-    preproc.setIncludePaths(model->includePaths());
-    preproc.setFrameworkPaths(model->frameworkPaths());
-
     QString conf = QLatin1String(pp_configuration_file);
-    (void) preproc(conf);
+    (void) preproc->run(conf);
 
     const int STEP = 10;
 
@@ -725,7 +740,7 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 #endif
 
         QString fileName = files.at(i);
-        preproc(fileName);
+        preproc->run(fileName);
 
         if (! (i % STEP)) // Yields execution of the current thread.
             QThread::yieldCurrentThread();
@@ -739,6 +754,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 
     // Restore the previous thread priority.
     QThread::currentThread()->setPriority(QThread::NormalPriority);
+
+    delete preproc;
 }
 
 void CppModelManager::GC()
@@ -746,7 +763,7 @@ void CppModelManager::GC()
     DocumentTable documents = m_documents;
 
     QSet<QString> processed;
-    QStringList todo = m_projectFiles;
+    QStringList todo = projectFiles();
 
     while (! todo.isEmpty()) {
         QString fn = todo.last();
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index 187187cc5d313586293cd3fdb0e7d5186dc30c01..a91a414e4803e2464a68a149b5f1eac9ae43068a 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -58,6 +58,7 @@ namespace CppTools {
 namespace Internal {
 
 class CppEditorSupport;
+class CppPreprocessor;
 class CppHoverHandler;
 
 class CppModelManager : public CppModelManagerInterface
@@ -97,18 +98,54 @@ private Q_SLOTS:
     void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
     void onAboutToRemoveProject(ProjectExplorer::Project *project);
     void onSessionUnloaded();
+    void onProjectAdded(ProjectExplorer::Project *project);
 
 private:
-    QMap<QString, QByteArray> buildWorkingCopyList() const;
-    QStringList projectFiles() const;
-    QStringList includePaths() const;
-    QStringList frameworkPaths() const;
-    QByteArray definedMacros() const;
+    QMap<QString, QByteArray> buildWorkingCopyList();
+
+    QStringList projectFiles()
+    {
+        ensureUpdated();
+        return m_projectFiles;
+    }
+
+    QStringList includePaths()
+    {
+        ensureUpdated();
+        return m_includePaths;
+    }
+
+    QStringList frameworkPaths()
+    {
+        ensureUpdated();
+        return m_frameworkPaths;
+    }
+
+    QByteArray definedMacros()
+    {
+        ensureUpdated();
+        return m_definedMacros;
+    }
+
+    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,
-                      CppModelManager *model,
-                      QStringList files,
-                      QMap<QString, QByteArray> workingCopy);
+                      CppPreprocessor *preproc,
+                      QStringList files);
 
 private:
     Core::ICore *m_core;
@@ -116,8 +153,12 @@ private:
     CppHoverHandler *m_hoverHandler;
     DocumentTable m_documents;
 
-    // List of available source files
+    // cache
+    bool m_dirty;
     QStringList m_projectFiles;
+    QStringList m_includePaths;
+    QStringList m_frameworkPaths;
+    QByteArray m_definedMacros;
 
     // editor integration
     QMap<TextEditor::ITextEditor *, CppEditorSupport *> m_editorSupport;
diff --git a/src/plugins/cpptools/cppquickopenfilter.cpp b/src/plugins/cpptools/cppquickopenfilter.cpp
index 9470ec46039a57c77e3d1499b71c3e457f01c190..a1f1a9b3713e00c76a967d2922dad17875c48034 100644
--- a/src/plugins/cpptools/cppquickopenfilter.cpp
+++ b/src/plugins/cpptools/cppquickopenfilter.cpp
@@ -32,172 +32,13 @@
 ***************************************************************************/
 
 #include "cppquickopenfilter.h"
+#include "cppmodelmanager.h"
 
-#include <Literals.h>
-#include <Symbols.h>
-#include <SymbolVisitor.h>
-#include <Scope.h>
-#include <cplusplus/Overview.h>
-#include <cplusplus/Icons.h>
-
+#include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/editormanager/ieditor.h>
 #include <texteditor/itexteditor.h>
 #include <texteditor/basetexteditor.h>
 
-#include <QtCore/QMultiMap>
-
-#include <functional>
-
-using namespace CPlusPlus;
-
-namespace CppTools {
-namespace Internal {
-
-class SearchSymbols: public std::unary_function<Document::Ptr, QList<ModelItemInfo> >,
-                     protected SymbolVisitor
-{
-    Overview overview;
-    Icons icons;
-    QList<ModelItemInfo> items;
-
-public:
-    QList<ModelItemInfo> operator()(Document::Ptr doc)
-    { return operator()(doc, QString()); }
-
-    QList<ModelItemInfo> operator()(Document::Ptr doc, const QString &scope)
-    {
-        QString previousScope = switchScope(scope);
-        items.clear();
-        for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
-            accept(doc->globalSymbolAt(i));
-        }
-        (void) switchScope(previousScope);
-        return items;
-    }
-
-protected:
-    using SymbolVisitor::visit;
-
-    void accept(Symbol *symbol)
-    { Symbol::visitSymbol(symbol, this); }
-
-    QString switchScope(const QString &scope)
-    {
-        QString previousScope = _scope;
-        _scope = scope;
-        return previousScope;
-    }
-
-    virtual bool visit(Enum *symbol)
-    {
-        QString name = symbolName(symbol);
-        QString previousScope = switchScope(name);
-        QIcon icon = icons.iconForSymbol(symbol);
-        Scope *members = symbol->members();
-        items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum,
-                                   QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
-                                   symbol->line(),
-                                   icon));
-        for (unsigned i = 0; i < members->symbolCount(); ++i) {
-            accept(members->symbolAt(i));
-        }
-        (void) switchScope(previousScope);
-        return false;
-    }
-
-    virtual bool visit(Function *symbol)
-    {
-        QString name = symbolName(symbol);
-        QString type = overview.prettyType(symbol->type());
-        QIcon icon = icons.iconForSymbol(symbol);
-        items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
-                                   QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
-                                   symbol->line(),
-                                   icon));
-        return false;
-    }
-
-    virtual bool visit(Namespace *symbol)
-    {
-        QString name = symbolName(symbol);
-        QString previousScope = switchScope(name);
-        Scope *members = symbol->members();
-        for (unsigned i = 0; i < members->symbolCount(); ++i) {
-            accept(members->symbolAt(i));
-        }
-        (void) switchScope(previousScope);
-        return false;
-    }
-#if 0
-    // This visit method would make function declaration be included in QuickOpen
-    virtual bool visit(Declaration *symbol)
-    {
-        if (symbol->type()->isFunction()) {
-            QString name = symbolName(symbol);
-            QString type = overview.prettyType(symbol->type());
-            //QIcon icon = ...;
-            items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
-                                       QString::fromUtf8(symbol->fileName(), symbol->line()),
-                                       symbol->line()));
-        }
-        return false;
-    }
-#endif
-    virtual bool visit(Class *symbol)
-    {
-        QString name = symbolName(symbol);
-        QString previousScope = switchScope(name);
-        QIcon icon = icons.iconForSymbol(symbol);
-        items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class,
-                                   QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
-                                   symbol->line(),
-                                   icon));
-        Scope *members = symbol->members();
-        for (unsigned i = 0; i < members->symbolCount(); ++i) {
-            accept(members->symbolAt(i));
-        }
-        (void) switchScope(previousScope);
-        return false;
-    }
-
-    QString symbolName(Symbol *symbol) const
-    {
-        QString name = _scope;
-        if (! name.isEmpty())
-            name += QLatin1String("::");
-        QString symbolName = overview.prettyName(symbol->name());
-        if (symbolName.isEmpty()) {
-            QString type;
-            if (symbol->isNamespace()) {
-                type = QLatin1String("namespace");
-            } else if (symbol->isEnum()) {
-                type = QLatin1String("enum");
-            } else if (Class *c = symbol->asClass())  {
-                if (c->isUnion()) {
-                    type = QLatin1String("union");
-                } else if (c->isStruct()) {
-                    type = QLatin1String("struct");
-                } else {
-                    type = QLatin1String("class");
-                }
-            } else {
-                type = QLatin1String("symbol");
-            }
-            symbolName = QLatin1String("<anonymous ");
-            symbolName += type;
-            symbolName += QLatin1String(">");
-        }
-        name += symbolName;
-        return name;
-    }
-
-private:
-    QString _scope;
-};
-
-} // namespace Internal
-} // namespace CppTools
-
 using namespace CppTools::Internal;
 
 CppQuickOpenFilter::CppQuickOpenFilter(CppModelManager *manager, Core::EditorManager *editorManager)
@@ -225,9 +66,8 @@ void CppQuickOpenFilter::onDocumentUpdated(CPlusPlus::Document::Ptr doc)
 
 void CppQuickOpenFilter::onAboutToRemoveFiles(const QStringList &files)
 {
-    foreach (QString file, files) {
+    foreach (const QString &file, files)
         m_searchList.remove(file);
-    }
 }
 
 void CppQuickOpenFilter::refresh(QFutureInterface<void> &future)
@@ -245,7 +85,6 @@ QList<QuickOpen::FilterEntry> CppQuickOpenFilter::matchesFor(const QString &orig
         return entries;
     bool hasWildcard = (entry.contains('*') || entry.contains('?'));
 
-    SearchSymbols search;
     QMutableMapIterator<QString, Info> it(m_searchList);
     while (it.hasNext()) {
         it.next();
@@ -276,6 +115,5 @@ QList<QuickOpen::FilterEntry> CppQuickOpenFilter::matchesFor(const QString &orig
 void CppQuickOpenFilter::accept(QuickOpen::FilterEntry selection) const
 {
     ModelItemInfo info = qvariant_cast<CppTools::Internal::ModelItemInfo>(selection.internalData);
-
     TextEditor::BaseTextEditor::openEditorAt(info.fileName, info.line);
 }
diff --git a/src/plugins/cpptools/cppquickopenfilter.h b/src/plugins/cpptools/cppquickopenfilter.h
index bf6696a02af24ed690d286177e6ed9746e206112..12eaacb3f980d194b7c1e69416dbd6d8ec2b3504 100644
--- a/src/plugins/cpptools/cppquickopenfilter.h
+++ b/src/plugins/cpptools/cppquickopenfilter.h
@@ -34,45 +34,18 @@
 #ifndef CPPQUICKOPENFILTER_H
 #define CPPQUICKOPENFILTER_H
 
-#include "cppmodelmanager.h"
-#include <cplusplus/CppDocument.h>
-#include <coreplugin/editormanager/editormanager.h>
+#include "searchsymbols.h"
+
 #include <quickopen/iquickopenfilter.h>
-#include <QtGui/QIcon>
-#include <QFile>
-#include <QMetaType>
+
+namespace Core {
+class EditorManager;
+}
 
 namespace CppTools {
 namespace Internal {
 
-struct ModelItemInfo
-{
-    enum ItemType { Enum, Class, Method };
-
-    ModelItemInfo()
-    { }
-
-    ModelItemInfo(const QString &symbolName,
-                  const QString &symbolType,
-                  ItemType type,
-                  const QString &fileName,
-                  int line,
-                  const QIcon &icon)
-        : symbolName(symbolName),
-          symbolType(symbolType),
-          type(type),
-          fileName(fileName),
-          line(line),
-          icon(icon)
-    { }
-
-    QString symbolName;
-    QString symbolType;
-    ItemType type;
-    QString fileName;
-    int line;
-    QIcon icon;
-};
+class CppModelManager;
 
 class CppQuickOpenFilter : public QuickOpen::IQuickOpenFilter
 {
@@ -82,12 +55,15 @@ public:
     ~CppQuickOpenFilter();
 
     QString trName() const { return tr("Classes and Methods"); }
-    QString name() const { return "Classes and Methods"; }
+    QString name() const { return QLatin1String("Classes and Methods"); }
     Priority priority() const { return Medium; }
     QList<QuickOpen::FilterEntry> matchesFor(const QString &entry);
     void accept(QuickOpen::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
 
+protected:
+    SearchSymbols search;
+
 private slots:
     void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
     void onAboutToRemoveFiles(const QStringList &files);
@@ -114,6 +90,4 @@ private:
 } // namespace Internal
 } // namespace CppTools
 
-Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo)
-
 #endif // CPPQUICKOPENFILTER_H
diff --git a/src/plugins/cpptools/cpptools.cpp b/src/plugins/cpptools/cpptools.cpp
index 423ddf3016d0d4a967dffd0d4a7e236163aa9793..957f0cae9b07ed7bf97842baaf316c2dd7bd53a2 100644
--- a/src/plugins/cpptools/cpptools.cpp
+++ b/src/plugins/cpptools/cpptools.cpp
@@ -32,6 +32,7 @@
 ***************************************************************************/
 
 #include "cpptools.h"
+#include "cppclassesfilter.h"
 #include "cppcodecompletion.h"
 #include "cpphoverhandler.h"
 #include "cppmodelmanager.h"
@@ -87,6 +88,7 @@ bool CppToolsPlugin::initialize(const QStringList & /*arguments*/, QString *)
     CppQuickOpenFilter *quickOpenFilter = new CppQuickOpenFilter(m_modelManager,
                                                                  m_core->editorManager());
     addAutoReleasedObject(quickOpenFilter);
+    addAutoReleasedObject(new CppClassesFilter(m_modelManager, m_core->editorManager()));
 
     // Menus
     Core::IActionContainer *mtools = am->actionContainer(Core::Constants::M_TOOLS);
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 17b72496a92f3a8c398e8bc3972da1983a7b8230..8a096900ebf699ba9f0712eafb670660ebffb113 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -4,31 +4,27 @@ include(../../qworkbenchplugin.pri)
 include(../../plugins/quickopen/quickopen.pri)
 include(cpptools_dependencies.pri)
 
-#DEFINES += QT_NO_CAST_FROM_ASCII
+# DEFINES += QT_NO_CAST_FROM_ASCII
 DEFINES += QT_NO_CAST_TO_ASCII
-unix:QMAKE_CXXFLAGS_DEBUG+=-O3
-
+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
-
-SOURCES += \
-    cppquickopenfilter.cpp \
-    cpptoolseditorsupport.cpp
+HEADERS += cpptools_global.h \
+    cppquickopenfilter.h \
+    cppclassesfilter.h \
+    searchsymbols.h
+SOURCES += cppquickopenfilter.cpp \
+    cpptoolseditorsupport.cpp \
+    cppclassesfilter.cpp \
+    searchsymbols.cpp
 
 # Input
 SOURCES += cpptools.cpp \
     cppmodelmanager.cpp \
     cppcodecompletion.cpp \
     cpphoverhandler.cpp
-
 HEADERS += cpptools.h \
     cppmodelmanager.h \
     cppcodecompletion.h \
@@ -36,5 +32,4 @@ HEADERS += cpptools.h \
     cppmodelmanagerinterface.h \
     cpptoolseditorsupport.h \
     cpptoolsconstants.h
-
 RESOURCES += cpptools.qrc
diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..670d0d6d471e892f9e70b3752899d8463ecf3a8b
--- /dev/null
+++ b/src/plugins/cpptools/searchsymbols.cpp
@@ -0,0 +1,204 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "searchsymbols.h"
+
+#include <Literals.h>
+#include <Scope.h>
+
+using namespace CPlusPlus;
+using namespace CppTools::Internal;
+
+SearchSymbols::SearchSymbols():
+    symbolsToSearchFor(Classes | Functions | Enums),
+    separateScope(false)
+{
+}
+
+void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types)
+{
+    symbolsToSearchFor = types;
+}
+
+void SearchSymbols::setSeparateScope(bool separateScope)
+{
+    this->separateScope = separateScope;
+}
+
+QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope)
+{
+    QString previousScope = switchScope(scope);
+    items.clear();
+    for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
+        accept(doc->globalSymbolAt(i));
+    }
+    (void) switchScope(previousScope);
+    return items;
+}
+
+QString SearchSymbols::switchScope(const QString &scope)
+{
+    QString previousScope = _scope;
+    _scope = scope;
+    return previousScope;
+}
+
+bool SearchSymbols::visit(Enum *symbol)
+{
+    if (!(symbolsToSearchFor & Enums))
+        return false;
+
+    QString name = symbolName(symbol);
+    QString scopedName = scopedSymbolName(name);
+    QString previousScope = switchScope(scopedName);
+    appendItem(separateScope ? name : scopedName,
+               separateScope ? previousScope : QString(),
+               ModelItemInfo::Enum, symbol);
+    Scope *members = symbol->members();
+    for (unsigned i = 0; i < members->symbolCount(); ++i) {
+        accept(members->symbolAt(i));
+    }
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool SearchSymbols::visit(Function *symbol)
+{
+    if (!(symbolsToSearchFor & Functions))
+        return false;
+
+    QString name = symbolName(symbol);
+    QString scopedName = scopedSymbolName(name);
+    QString type = overview.prettyType(symbol->type(),
+                                       separateScope ? symbol->name() : 0);
+    appendItem(separateScope ? type : scopedName,
+               separateScope ? _scope : type,
+               ModelItemInfo::Method, symbol);
+    return false;
+}
+
+bool SearchSymbols::visit(Namespace *symbol)
+{
+    QString name = findOrInsert(scopedSymbolName(symbol));
+    QString previousScope = switchScope(name);
+    Scope *members = symbol->members();
+    for (unsigned i = 0; i < members->symbolCount(); ++i) {
+        accept(members->symbolAt(i));
+    }
+    (void) switchScope(previousScope);
+    return false;
+}
+
+#if 0
+bool SearchSymbols::visit(Declaration *symbol)
+{
+    if (symbol->type()->isFunction()) {
+        QString name = scopedSymbolName(symbol);
+        QString type = overview.prettyType(symbol->type());
+        appendItems(name, type, ModelItemInfo::Method, symbol->fileName());
+    }
+    return false;
+}
+#endif
+
+bool SearchSymbols::visit(Class *symbol)
+{
+    if (!(symbolsToSearchFor & Classes))
+        return false;
+
+    QString name = symbolName(symbol);
+    QString scopedName = scopedSymbolName(name);
+    QString previousScope = switchScope(scopedName);
+    appendItem(separateScope ? name : scopedName,
+               separateScope ? previousScope : QString(),
+               ModelItemInfo::Class, symbol);
+    Scope *members = symbol->members();
+    for (unsigned i = 0; i < members->symbolCount(); ++i) {
+        accept(members->symbolAt(i));
+    }
+    (void) switchScope(previousScope);
+    return false;
+}
+
+QString SearchSymbols::scopedSymbolName(const QString &symbolName) const
+{
+    QString name = _scope;
+    if (! name.isEmpty())
+        name += QLatin1String("::");
+    name += symbolName;
+    return name;
+}
+
+QString SearchSymbols::scopedSymbolName(const Symbol *symbol) const
+{
+    return scopedSymbolName(symbolName(symbol));
+}
+
+QString SearchSymbols::symbolName(const Symbol *symbol) const
+{
+    QString symbolName = overview.prettyName(symbol->name());
+    if (symbolName.isEmpty()) {
+        QString type;
+        if (symbol->isNamespace()) {
+            type = QLatin1String("namespace");
+        } else if (symbol->isEnum()) {
+            type = QLatin1String("enum");
+        } else if (const Class *c = symbol->asClass())  {
+            if (c->isUnion()) {
+                type = QLatin1String("union");
+            } else if (c->isStruct()) {
+                type = QLatin1String("struct");
+            } else {
+                type = QLatin1String("class");
+            }
+        } else {
+            type = QLatin1String("symbol");
+        }
+        symbolName = QLatin1String("<anonymous ");
+        symbolName += type;
+        symbolName += QLatin1String(">");
+    }
+    return symbolName;
+}
+
+void SearchSymbols::appendItem(const QString &name,
+                               const QString &info,
+                               ModelItemInfo::ItemType type,
+                               const CPlusPlus::Symbol *symbol)
+{
+    const QIcon icon = icons.iconForSymbol(symbol);
+    items.append(ModelItemInfo(name, info, type,
+                               QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
+                               symbol->line(),
+                               icon));
+}
diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h
new file mode 100644
index 0000000000000000000000000000000000000000..d82f285972162ddf332d0cc278ecd5d2b41404ca
--- /dev/null
+++ b/src/plugins/cpptools/searchsymbols.h
@@ -0,0 +1,145 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#ifndef SEARCHSYMBOLS_H
+#define SEARCHSYMBOLS_H
+
+#include <cplusplus/CppDocument.h>
+#include <cplusplus/Icons.h>
+#include <cplusplus/Overview.h>
+#include <Symbols.h>
+#include <SymbolVisitor.h>
+
+#include <QIcon>
+#include <QMetaType>
+#include <QString>
+
+namespace CppTools {
+namespace Internal {
+
+struct ModelItemInfo
+{
+    enum ItemType { Enum, Class, Method };
+
+    ModelItemInfo()
+    { }
+
+    ModelItemInfo(const QString &symbolName,
+                  const QString &symbolType,
+                  ItemType type,
+                  const QString &fileName,
+                  int line,
+                  const QIcon &icon)
+        : symbolName(symbolName),
+          symbolType(symbolType),
+          type(type),
+          fileName(fileName),
+          line(line),
+          icon(icon)
+    { }
+
+    QString symbolName;
+    QString symbolType;
+    ItemType type;
+    QString fileName;
+    int line;
+    QIcon icon;
+};
+
+class SearchSymbols: public std::unary_function<CPlusPlus::Document::Ptr, QList<ModelItemInfo> >,
+                     protected CPlusPlus::SymbolVisitor
+{
+public:
+    enum SymbolType {
+        Classes   = 0x1,
+        Functions = 0x2,
+        Enums     = 0x4
+    };
+    Q_DECLARE_FLAGS(SymbolTypes, SymbolType)
+
+    SearchSymbols();
+
+    void setSymbolsToSearchFor(SymbolTypes types);
+    void setSeparateScope(bool separateScope);
+
+    QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc)
+    { return operator()(doc, QString()); }
+
+    QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc, const QString &scope);
+
+protected:
+    using SymbolVisitor::visit;
+
+    void accept(CPlusPlus::Symbol *symbol)
+    { CPlusPlus::Symbol::visitSymbol(symbol, this); }
+
+    QString switchScope(const QString &scope);
+    virtual bool visit(CPlusPlus::Enum *symbol);
+    virtual bool visit(CPlusPlus::Function *symbol);
+    virtual bool visit(CPlusPlus::Namespace *symbol);
+#if 0
+    // This visit method would make function declaration be included in QuickOpen
+    virtual bool visit(CPlusPlus::Declaration *symbol);
+#endif
+    virtual bool visit(CPlusPlus::Class *symbol);
+
+    QString scopedSymbolName(const QString &symbolName) const;
+    QString scopedSymbolName(const CPlusPlus::Symbol *symbol) const;
+    QString symbolName(const CPlusPlus::Symbol *symbol) const;
+    void appendItem(const QString &name,
+                    const QString &info,
+                    ModelItemInfo::ItemType type,
+                    const CPlusPlus::Symbol *symbol);
+
+private:
+    QString findOrInsert(const QString &s)
+    { return *strings.insert(s); }
+
+    QSet<QString> strings;            // Used to avoid QString duplication
+
+    QString _scope;
+    CPlusPlus::Overview overview;
+    CPlusPlus::Icons icons;
+    QList<ModelItemInfo> items;
+    SymbolTypes symbolsToSearchFor;
+    bool separateScope;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(SearchSymbols::SymbolTypes)
+
+} // namespace Internal
+} // namespace CppTools
+
+Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo)
+
+#endif // SEARCHSYMBOLS_H
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 42551168fe20e1e72e0e934797bfd9c7b0c16ffe..a94b1fb0931e3ac551f4fb815126b947ec998b80 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -317,10 +317,20 @@ void DebuggerManager::init()
 
     m_debugDumpersAction = new QAction(this);
     m_debugDumpersAction->setText(tr("Debug Custom Dumpers"));
+    m_debugDumpersAction->setToolTip(tr("This is an internal tool to "
+        "make debugging the Custom Data Dumper code easier. "
+        "Using this action is in general not needed unless you "
+        "want do debug Qt Creator itself."));
     m_debugDumpersAction->setCheckable(true);
 
     m_skipKnownFramesAction = new QAction(this);
     m_skipKnownFramesAction->setText(tr("Skip Known Frames When Stepping"));
+    m_skipKnownFramesAction->setToolTip(tr("After checking this option"
+        "'Step Into' combines in certain situations several steps, "
+        "leading to 'less noisy' debugging. So will, e.g., the atomic "
+        "reference counting code be skipped, and a single 'Step Into' "
+        "for a signal emission will end up directly in the slot connected "
+        "to it"));
     m_skipKnownFramesAction->setCheckable(true);
 
     m_useCustomDumpersAction = new QAction(this);
@@ -330,13 +340,6 @@ void DebuggerManager::init()
     m_useCustomDumpersAction->setCheckable(true);
     m_useCustomDumpersAction->setChecked(true);
 
-    m_useCustomDumpersAction = new QAction(this);
-    m_useCustomDumpersAction->setText(tr("Use Custom Display for Qt Objects"));
-    m_useCustomDumpersAction->setToolTip(tr("Checking this will make the debugger "
-        "try to use code to format certain data (QObject, QString, ...) nicely. "));
-    m_useCustomDumpersAction->setCheckable(true);
-    m_useCustomDumpersAction->setChecked(true);
-
     m_useFastStartAction = new QAction(this);
     m_useFastStartAction->setText(tr("Fast Debugger Start"));
     m_useFastStartAction->setToolTip(tr("Checking this will make the debugger "
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 80d0a046fc3179f334fa054f8ba1abcd59500cdd..1802c018001c8674588fc031600f7eb2480d41cc 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -1276,7 +1276,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
             m_currentFrame = frame.findChild("addr").data() + '%' +
                  frame.findChild("func").data() + '%';
 
-            QApplication::alert(q->mainWindow(), 200);
+            QApplication::alert(q->mainWindow(), 3000);
             sendCommand("-file-list-exec-source-files", GdbQuerySources);
             sendCommand("-break-list", BreakList);
             QVariant var = QVariant::fromValue<GdbMi>(data);
diff --git a/src/plugins/designer/cpp/formclasswizardpage.cpp b/src/plugins/designer/cpp/formclasswizardpage.cpp
index d076753374b666ef632c4a97a1f2394857993bae..eac7271b404dd48488d17e9ac56bc4d6b2541703 100644
--- a/src/plugins/designer/cpp/formclasswizardpage.cpp
+++ b/src/plugins/designer/cpp/formclasswizardpage.cpp
@@ -63,6 +63,7 @@ FormClassWizardPage::FormClassWizardPage(QWidget * parent) :
 
     m_ui->newClassWidget->setBaseClassInputVisible(false);
     m_ui->newClassWidget->setNamespacesEnabled(true);
+    m_ui->newClassWidget->setAllowDirectories(true);
 
     connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));
 
diff --git a/src/plugins/find/basetextfind.cpp b/src/plugins/find/basetextfind.cpp
index 63740d36527380a654cd3ea5027c6d19e66a0528..6598a47e6f3085409ba899c3f13f4903dd3ffe55 100644
--- a/src/plugins/find/basetextfind.cpp
+++ b/src/plugins/find/basetextfind.cpp
@@ -162,7 +162,10 @@ int BaseTextFind::replaceAll(const QString &before, const QString &after,
     QTextDocument::FindFlags findFlags)
 {
     QTextCursor editCursor = textCursor();
-    editCursor.movePosition(QTextCursor::Start);
+    if (!m_findScope.isNull())
+        editCursor.setPosition(m_findScope.selectionStart());
+    else
+        editCursor.movePosition(QTextCursor::Start);
     editCursor.beginEditBlock();
     int count = 0;
     QTextCursor found;
diff --git a/src/plugins/git/commitdata.cpp b/src/plugins/git/commitdata.cpp
index 60e2173a660ab315b406c5c79313d256a934f107..7ea937233c7e115e901b56ff72d58809edcece29 100644
--- a/src/plugins/git/commitdata.cpp
+++ b/src/plugins/git/commitdata.cpp
@@ -80,16 +80,16 @@ void CommitData::clear()
     panelInfo.clear();
     panelData.clear();
 
-    commitFiles.clear();
-    notUpdatedFiles.clear();
+    stagedFiles.clear();
+    unstagedFiles.clear();
     untrackedFiles.clear();
 }
 
 QDebug operator<<(QDebug d, const CommitData &data)
 {
     d <<  data.panelInfo << data.panelData;
-    d.nospace() << "Commit: " << data.commitFiles << " Not updated: "
-        << data.notUpdatedFiles << " Untracked: " << data.untrackedFiles;
+    d.nospace() << "Commit: " << data.stagedFiles << " Not updated: "
+        << data.unstagedFiles << " Untracked: " << data.untrackedFiles;
     return d;
 }
 
diff --git a/src/plugins/git/commitdata.h b/src/plugins/git/commitdata.h
index 9cd5a83eb16c3e01fec0950c6ef3675354c440bb..b535168f6f357e56e7aa3877313ea9871febeee8 100644
--- a/src/plugins/git/commitdata.h
+++ b/src/plugins/git/commitdata.h
@@ -71,8 +71,8 @@ struct CommitData
     void clear();
     GitSubmitEditorPanelInfo panelInfo;
     GitSubmitEditorPanelData panelData;
-    QStringList commitFiles;
-    QStringList notUpdatedFiles;
+    QStringList stagedFiles;
+    QStringList unstagedFiles;
     QStringList untrackedFiles;
 };
 
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 7d87ce27827838b4971155378b8b4281695a5151..a1668e60cebcf93343e54862c30a7f429cf933dd 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -35,6 +35,7 @@
 #include "gitplugin.h"
 #include "gitconstants.h"
 #include "commitdata.h"
+#include "gitsubmiteditor.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/coreconstants.h>
@@ -51,7 +52,9 @@
 #include <QtCore/QFuture>
 #include <QtCore/QTime>
 
-#include <QtGui/QErrorMessage>
+#include <QtGui/QMessageBox>
+#include <QtGui/QMainWindow> // for msg box parent
+#include <QtGui/QPushButton>
 
 using namespace Git;
 using namespace Git::Internal;
@@ -77,12 +80,24 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property
     return 0;
 }
 
+static inline QString msgRepositoryNotFound(const QString &dir)
+{
+    return GitClient::tr("Unable to determine the repository for %1.").arg(dir);
+}
+
+static inline QString msgParseFilesFailed()
+{
+    return  GitClient::tr("Unable to parse the file output.");
+}
+
+// Format a command for the status window
 static QString formatCommand(const QString &binary, const QStringList &args)
 {
     const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
     return GitClient::tr("%1 Executing: %2 %3\n").arg(timeStamp, binary, args.join(QString(QLatin1Char(' '))));
 }
 
+// ---------------- GitClient
 GitClient::GitClient(GitPlugin* plugin, Core::ICore *core) :
     m_msgWait(tr("Waiting for data...")),
     m_plugin(plugin),
@@ -311,6 +326,19 @@ bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringLis
 
 bool GitClient::synchronousReset(const QString &workingDirectory,
                                  const QStringList &files)
+{
+    QString errorMessage;
+    const bool rc = synchronousReset(workingDirectory, files, &errorMessage);
+    if (!rc) {
+        m_plugin->outputWindow()->append(errorMessage);
+        m_plugin->outputWindow()->popup(false);
+    }
+    return rc;
+}
+
+bool GitClient::synchronousReset(const QString &workingDirectory,
+                                 const QStringList &files,
+                                 QString *errorMessage)
 {
     if (Git::Constants::debug)
         qDebug() << Q_FUNC_INFO << workingDirectory << files;
@@ -325,9 +353,25 @@ bool GitClient::synchronousReset(const QString &workingDirectory,
     // Note that git exits with 1 even if the operation is successful
     // Assume real failure if the output does not contain "foo.cpp modified"
     if (!rc && !output.contains(QLatin1String("modified"))) {
-        const QString errorMessage = tr("Unable to reset %n file(s) in %1: %2", 0, files.size()).
-                                     arg(workingDirectory, QString::fromLocal8Bit(errorText));
-        m_plugin->outputWindow()->append(errorMessage);
+        *errorMessage = tr("Unable to reset %n file(s) in %1: %2", 0, files.size()).arg(workingDirectory, QString::fromLocal8Bit(errorText));
+        return false;
+    }
+    return true;
+}
+
+bool GitClient::synchronousCheckout(const QString &workingDirectory,
+                                    const QStringList &files,
+                                    QString *errorMessage)
+{
+    if (Git::Constants::debug)
+        qDebug() << Q_FUNC_INFO << workingDirectory << files;
+    QByteArray outputText;
+    QByteArray errorText;
+    QStringList arguments;
+    arguments << QLatin1String("checkout") << QLatin1String("--") << files;
+    const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText);
+    if (!rc) {
+        *errorMessage = tr("Unable to checkout %n file(s) in %1: %2", 0, files.size()).arg(workingDirectory, QString::fromLocal8Bit(errorText));
         return false;
     }
     return true;
@@ -365,16 +409,18 @@ void GitClient::executeGit(const QString &workingDirectory, const QStringList &a
     command->execute(arguments, workingDirectory, environment);
 }
 
-bool GitClient::synchronousGit(const QString &workingDirectory
-                                , const QStringList &arguments
-                                , QByteArray* outputText
-                                , QByteArray* errorText)
+bool GitClient::synchronousGit(const QString &workingDirectory,
+                               const QStringList &arguments,
+                               QByteArray* outputText,
+                               QByteArray* errorText,
+                               bool logCommandToWindow)
 {
     if (Git::Constants::debug)
         qDebug() << "synchronousGit" << workingDirectory << arguments;
     const QString binary = QLatin1String(kGitCommand);
 
-    m_plugin->outputWindow()->append(formatCommand(binary, arguments));
+    if (logCommandToWindow)
+        m_plugin->outputWindow()->append(formatCommand(binary, arguments));
 
     QProcess process;
     process.setWorkingDirectory(workingDirectory);
@@ -456,10 +502,11 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory,
     #<tab>modified:<blanks>git.pro
     \endcode
 */
-static bool parseFiles(const QStringList &lines, CommitData *d)
+static bool parseFiles(const QString &output, CommitData *d)
 {
     enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles };
 
+    const QStringList lines = output.split(QLatin1Char('\n'));
     const QString branchIndicator = QLatin1String(kBranchIndicatorC);
     const QString commitIndicator = QLatin1String("# Changes to be committed:");
     const QString notUpdatedIndicator = QLatin1String("# Changed but not updated:");
@@ -492,10 +539,10 @@ static bool parseFiles(const QStringList &lines, CommitData *d)
                             const QString fileSpec = line.mid(2).trimmed();
                             switch (s) {
                             case CommitFiles:
-                                d->commitFiles.push_back(trimFileSpecification(fileSpec));
+                                d->stagedFiles.push_back(trimFileSpecification(fileSpec));
                             break;
                             case NotUpdatedFiles:
-                                d->notUpdatedFiles.push_back(trimFileSpecification(fileSpec));
+                                d->unstagedFiles.push_back(trimFileSpecification(fileSpec));
                                 break;
                             case UntrackedFiles:
                                 d->untrackedFiles.push_back(QLatin1String("untracked: ") + fileSpec);
@@ -509,7 +556,7 @@ static bool parseFiles(const QStringList &lines, CommitData *d)
             }
         }
     }
-    return !d->commitFiles.empty() || !d->notUpdatedFiles.empty() || !d->untrackedFiles.empty();
+    return !d->stagedFiles.empty() || !d->unstagedFiles.empty() || !d->untrackedFiles.empty();
 }
 
 bool GitClient::getCommitData(const QString &workingDirectory,
@@ -525,7 +572,7 @@ bool GitClient::getCommitData(const QString &workingDirectory,
     // Find repo
     const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory);
     if (repoDirectory.isEmpty()) {
-        *errorMessage = tr("Unable to determine the repository for %1.").arg(workingDirectory);
+        *errorMessage = msgRepositoryNotFound(workingDirectory);
         return false;
     }
 
@@ -551,7 +598,7 @@ bool GitClient::getCommitData(const QString &workingDirectory,
     case  StatusChanged:
         break;
     case StatusUnchanged:
-        *errorMessage = tr("There are no modified files.");
+        *errorMessage = msgNoChangedFiles();
         return false;
     case StatusFailed:
         return false;
@@ -575,9 +622,8 @@ bool GitClient::getCommitData(const QString &workingDirectory,
     //    #
     //    #       list of files...
 
-    const QStringList lines = output.split(QLatin1Char('\n'));
-    if (!parseFiles(lines, d)) {
-        *errorMessage = tr("Unable to parse the file output.");
+    if (!parseFiles(output, d)) {
+        *errorMessage = msgParseFilesFailed();
         return false;
     }
 
@@ -638,6 +684,129 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
     return rc;
 }
 
+static inline bool askWithInformativeText(QWidget *parent,
+                                          const QString &title,
+                                          const QString &msg,
+                                          const QString &inf,
+                                          bool defaultValue)
+{
+    QMessageBox msgBox(QMessageBox::Question, title, msg, QMessageBox::Yes|QMessageBox::No, parent);
+    msgBox.setInformativeText(inf);
+    msgBox.setDefaultButton(defaultValue ? QMessageBox::Yes : QMessageBox::No);
+    return msgBox.exec() == QMessageBox::Yes;
+}
+
+/* Revert: This function can be called with a file list (to revert single
+ * files)  or a single directory (revert all). Qt Creator currently has only
+ * 'revert single' in its VCS menus, but the code is prepared to deal with
+ * reverting a directory pending a sophisticated selection dialog in the
+ * VCSBase plugin. */
+
+GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirectory, QString *errorMessage)
+{
+    if (Git::Constants::debug)
+        qDebug() << Q_FUNC_INFO << files;
+
+    if (files.empty())
+        return RevertCanceled;
+
+    // Figure out the working directory
+    const QFileInfo firstFile(files.front());
+    const bool isDirectory = firstFile.isDir();
+    if (ptrToIsDirectory)
+        *ptrToIsDirectory = isDirectory;
+    const QString workingDirectory = isDirectory ? firstFile.absoluteFilePath() : firstFile.absolutePath();
+
+    const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory);
+    if (repoDirectory.isEmpty()) {
+        *errorMessage = msgRepositoryNotFound(workingDirectory);
+        return RevertFailed;
+    }
+
+    // Check for changes
+    QString output;
+    switch (gitStatus(repoDirectory, false, &output, errorMessage)) {
+    case StatusChanged:
+        break;
+    case StatusUnchanged:
+        return RevertUnchanged;
+    case StatusFailed:
+        return RevertFailed;
+    }
+    CommitData d;
+    if (!parseFiles(output, &d)) {
+        *errorMessage = msgParseFilesFailed();
+        return RevertFailed;
+    }
+
+    // If we are looking at files, make them relative to the repository
+    // directory to match them in the status output list.
+    if (!isDirectory) {
+        const QDir repoDir(repoDirectory);
+        const QStringList::iterator cend = files.end();
+        for (QStringList::iterator it = files.begin(); it != cend; ++it)
+            *it = repoDir.relativeFilePath(*it);
+    }
+
+    // From the status output, determine all modified [un]staged files.
+    const QString modifiedPattern = QLatin1String("modified: ");
+    const QStringList allStagedFiles = GitSubmitEditor::statusListToFileList(d.stagedFiles.filter(modifiedPattern));
+    const QStringList allUnstagedFiles = GitSubmitEditor::statusListToFileList(d.unstagedFiles.filter(modifiedPattern));
+    // Unless a directory was passed, filter all modified files for the
+    // argument file list.
+    QStringList stagedFiles = allStagedFiles;
+    QStringList unstagedFiles = allUnstagedFiles;
+    if (!isDirectory) {
+        const QSet<QString> filesSet = files.toSet();
+        stagedFiles = allStagedFiles.toSet().intersect(filesSet).toList();
+        unstagedFiles = allUnstagedFiles.toSet().intersect(filesSet).toList();
+    }
+    if (Git::Constants::debug)
+        qDebug() << Q_FUNC_INFO << d.stagedFiles << d.unstagedFiles << allStagedFiles << allUnstagedFiles << stagedFiles << unstagedFiles;
+
+    if (stagedFiles.empty() && unstagedFiles.empty())
+        return RevertUnchanged;
+
+    // Ask to revert (to do: Handle lists with a selection dialog)
+    const QMessageBox::StandardButton answer
+        = QMessageBox::question(m_core->mainWindow(),
+                                tr("Revert"),
+                                tr("The file has been changed. Do you want to revert it?"),
+                                QMessageBox::Yes|QMessageBox::No,
+                                QMessageBox::No);
+    if (answer == QMessageBox::No)
+        return RevertCanceled;
+
+    // Unstage the staged files
+    if (!stagedFiles.empty() && !synchronousReset(repoDirectory, stagedFiles, errorMessage))
+        return RevertFailed;
+    // Finally revert!
+    if (!synchronousCheckout(repoDirectory, stagedFiles + unstagedFiles, errorMessage))
+        return RevertFailed;
+    return RevertOk;
+}
+
+void GitClient::revert(const QStringList &files)
+{
+    bool isDirectory;
+    QString errorMessage;
+    switch (revertI(files, &isDirectory, &errorMessage)) {
+    case RevertOk:
+    case RevertCanceled:
+        break;
+    case RevertUnchanged: {
+        const QString msg = (isDirectory || files.size() > 1) ? msgNoChangedFiles() : tr("The file is not modified.");
+        m_plugin->outputWindow()->append(msg);
+        m_plugin->outputWindow()->popup();
+    }
+        break;
+    case RevertFailed:
+        m_plugin->outputWindow()->append(errorMessage);
+        m_plugin->outputWindow()->popup();
+        break;
+    }
+}
+
 void GitClient::pull(const QString &workingDirectory)
 {
     executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->outputWindow(), 0, true);
@@ -648,6 +817,11 @@ void GitClient::push(const QString &workingDirectory)
     executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->outputWindow(), 0, true);
 }
 
+QString GitClient::msgNoChangedFiles()
+{
+    return tr("There are no modified files.");
+}
+
 void GitClient::stash(const QString &workingDirectory)
 {
     // Check for changes and stash
@@ -657,7 +831,7 @@ void GitClient::stash(const QString &workingDirectory)
         executeGit(workingDirectory, QStringList(QLatin1String("stash")), m_plugin->outputWindow(), 0, true);
         break;
     case StatusUnchanged:
-        m_plugin->outputWindow()->append(tr("There are no modified files."));
+        m_plugin->outputWindow()->append(msgNoChangedFiles());
         m_plugin->outputWindow()->popup();
         break;
     case StatusFailed:
@@ -694,8 +868,8 @@ QString GitClient::readConfig(const QString &workingDirectory, const QStringList
     arguments << QLatin1String("config") << configVar;
 
     QByteArray outputText;
-    if (synchronousGit(workingDirectory, arguments, &outputText))
-        return QString::fromLocal8Bit(outputText);
+    if (synchronousGit(workingDirectory, arguments, &outputText, 0, false))
+        return QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r'));
     return QString();
 }
 
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 5be276a7877f6d1f1fc82149d74fe0f812b74017..efc767e54095e98e8be96022f1bd5ed04cf4989f 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -90,11 +90,14 @@ public:
     void addFile(const QString &workingDirectory, const QString &fileName);
     bool synchronousAdd(const QString &workingDirectory, const QStringList &files);
     bool synchronousReset(const QString &workingDirectory, const QStringList &files);
+    bool synchronousReset(const QString &workingDirectory, const QStringList &files, QString *errorMessage);
+    bool synchronousCheckout(const QString &workingDirectory, const QStringList &files, QString *errorMessage);
     void pull(const QString &workingDirectory);
     void push(const QString &workingDirectory);
 
     void stash(const QString &workingDirectory);
     void stashPop(const QString &workingDirectory);
+    void revert(const QStringList &files);
     void branchList(const QString &workingDirectory);
     void stashList(const QString &workingDirectory);
 
@@ -113,19 +116,21 @@ public:
                       const QStringList &checkedFiles,
                       const QStringList &origCommitFiles);
 
+    enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed };
+    StatusResult gitStatus(const QString &workingDirectory,
+                           bool untracked,
+                           QString *output = 0,
+                           QString *errorMessage = 0);
+
     GitSettings  settings() const;
     void setSettings(const GitSettings &s);
 
+    static QString msgNoChangedFiles();
+
 public slots:
     void show(const QString &source, const QString &id);
 
 private:
-    enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed };
-    StatusResult gitStatus(const QString &workingDirectory,
-                           bool untracked,
-                           QString *output = 0,
-                           QString *errorMessage = 0);
-
     VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind,
                                                  QString title,
                                                  const QString &source,
@@ -141,9 +146,13 @@ private:
                                            bool outputToWindow = false);
 
     bool synchronousGit(const QString &workingDirectory,
-                                           const QStringList &arguments,
-                                           QByteArray* outputText = 0,
-                                           QByteArray* errorText = 0);
+                        const QStringList &arguments,
+                        QByteArray* outputText = 0,
+                        QByteArray* errorText = 0,
+                        bool logCommandToWindow = true);
+
+    enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed };
+    RevertResult revertI(QStringList files, bool *isDirectory, QString *errorMessage);
 
     const QString m_msgWait;
     GitPlugin     *m_plugin;
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index ef57b9bb12a830b97c6870e2aadb7889a47ff04b..ebce0f7c452dbf9624a7186d3aded21a0fe056d0 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -118,7 +118,9 @@ GitPlugin::GitPlugin() :
     m_undoFileAction(0),
     m_undoProjectAction(0),
     m_showAction(0),
-    m_addAction(0),
+    m_stageAction(0),
+    m_unstageAction(0),
+    m_revertAction(0),
     m_commitAction(0),
     m_pullAction(0),
     m_pushAction(0),
@@ -311,11 +313,23 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
     connect(m_undoFileAction, SIGNAL(triggered()), this, SLOT(undoFileChanges()));
     gitContainer->addAction(command);
 
-    m_addAction = new QAction(tr("Add File"), this);
-    command = actionManager->registerAction(m_addAction, "Git.Add", globalcontext);
+    m_stageAction = new QAction(tr("Stage file for commit"), this);
+    command = actionManager->registerAction(m_stageAction, "Git.Stage", globalcontext);
     command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+A")));
     command->setAttribute(Core::ICommand::CA_UpdateText);
-    connect(m_addAction, SIGNAL(triggered()), this, SLOT(addFile()));
+    connect(m_stageAction, SIGNAL(triggered()), this, SLOT(stageFile()));
+    gitContainer->addAction(command);
+
+    m_unstageAction = new QAction(tr("Unstage file from commit"), this);
+    command = actionManager->registerAction(m_unstageAction, "Git.Unstage", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_unstageAction, SIGNAL(triggered()), this, SLOT(unstageFile()));
+    gitContainer->addAction(command);
+
+    m_revertAction = new QAction(tr("Revert..."), this);
+    command = actionManager->registerAction(m_revertAction, "Git.Revert", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_revertAction, SIGNAL(triggered()), this, SLOT(revertFile()));
     gitContainer->addAction(command);
 
     gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Project"), this));
@@ -537,14 +551,28 @@ void GitPlugin::undoProjectChanges()
     m_gitClient->hardReset(workingDirectory, QString());
 }
 
-void GitPlugin::addFile()
+void GitPlugin::stageFile()
 {
-    QFileInfo fileInfo = currentFile();
-    QString fileName = fileInfo.fileName();
-    QString workingDirectory = fileInfo.absolutePath();
+    const QFileInfo fileInfo = currentFile();
+    const QString fileName = fileInfo.fileName();
+    const QString workingDirectory = fileInfo.absolutePath();
     m_gitClient->addFile(workingDirectory, fileName);
 }
 
+void GitPlugin::unstageFile()
+{
+    const QFileInfo fileInfo = currentFile();
+    const QString fileName = fileInfo.fileName();
+    const QString workingDirectory = fileInfo.absolutePath();
+    m_gitClient->synchronousReset(workingDirectory, QStringList(fileName));
+}
+
+void GitPlugin::revertFile()
+{
+    const QFileInfo fileInfo = currentFile();
+    m_gitClient->revert(QStringList(fileInfo.absoluteFilePath()));
+}
+
 void GitPlugin::startCommit()
 {
     if (m_changeTmpFile) {
@@ -570,7 +598,7 @@ void GitPlugin::startCommit()
     // Store repository for diff and the original list of
     // files to be able to unstage files the user unchecks
     m_submitRepository = data.panelInfo.repository;
-    m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.commitFiles);
+    m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.stagedFiles);
 
     if (Git::Constants::debug)
         qDebug() << Q_FUNC_INFO << data << commitTemplate;
@@ -602,7 +630,7 @@ Core::IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const Commit
     Q_ASSERT(submitEditor);
     // The actions are for some reason enabled by the context switching
     // mechanism. Disable them correctly.
-    m_submitCurrentAction->setEnabled(!cd.commitFiles.empty());
+    m_submitCurrentAction->setEnabled(!cd.stagedFiles.empty());
     m_diffSelectedFilesAction->setEnabled(false);
     m_undoAction->setEnabled(false);
     m_redoAction->setEnabled(false);
@@ -722,7 +750,9 @@ void GitPlugin::updateActions()
     m_logAction->setText(tr("Log %1").arg(fileName));
     m_blameAction->setText(tr("Blame %1").arg(fileName));
     m_undoFileAction->setText(tr("Undo changes for %1").arg(fileName));
-    m_addAction->setText(tr("Add %1").arg(fileName));
+    m_stageAction->setText(tr("Stage %1 for commit").arg(fileName));
+    m_unstageAction->setText(tr("Unstage %1 from commit").arg(fileName));
+    m_revertAction->setText(tr("Revert %1...").arg(fileName));
     if (repository.isEmpty()) {
         // If the file is not in a repository, the corresponding project will
         // be neither and we can disable everything and return
@@ -731,7 +761,9 @@ void GitPlugin::updateActions()
         m_logAction->setEnabled(false);
         m_blameAction->setEnabled(false);
         m_undoFileAction->setEnabled(false);
-        m_addAction->setEnabled(false);
+        m_stageAction->setEnabled(false);
+        m_unstageAction->setEnabled(false);
+        m_revertAction->setEnabled(false);
         m_diffProjectAction->setEnabled(false);
         m_diffProjectAction->setText(tr("Diff Project"));
         m_statusProjectAction->setText(tr("Status Project"));
@@ -747,7 +779,9 @@ void GitPlugin::updateActions()
         m_logAction->setEnabled(true);
         m_blameAction->setEnabled(true);
         m_undoFileAction->setEnabled(true);
-        m_addAction->setEnabled(true);
+        m_stageAction->setEnabled(true);
+        m_unstageAction->setEnabled(true);
+        m_revertAction->setEnabled(true);
     }
 
     if (m_projectExplorer && m_projectExplorer->currentNode()
diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h
index 3da8ff26cec6c1ad194613864a02f330a7edf7a2..adff899e505564dc680a3a9dc4ac161bcae306a0 100644
--- a/src/plugins/git/gitplugin.h
+++ b/src/plugins/git/gitplugin.h
@@ -116,7 +116,9 @@ private slots:
     void                        logProject();
     void                        undoFileChanges();
     void                        undoProjectChanges();
-    void                        addFile();
+    void                        stageFile();
+    void                        unstageFile();
+    void                        revertFile();
 
     void                        showCommit();
     void                        startCommit();
@@ -144,7 +146,9 @@ private:
     QAction                     *m_undoFileAction;
     QAction                     *m_undoProjectAction;
     QAction                     *m_showAction;
-    QAction                     *m_addAction;
+    QAction                     *m_stageAction;
+    QAction                     *m_unstageAction;
+    QAction                     *m_revertAction;
     QAction                     *m_commitAction;
     QAction                     *m_pullAction;
     QAction                     *m_pushAction;
diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp
index 516dc6570b73c7b9e62d72e0fb0d01def65c0513..db854f3e3c6d406bd20f3ff2ca98cd6203645ca0 100644
--- a/src/plugins/git/gitsubmiteditor.cpp
+++ b/src/plugins/git/gitsubmiteditor.cpp
@@ -67,9 +67,9 @@ void GitSubmitEditor::setCommitData(const CommitData &d)
     submitEditorWidget()->setPanelData(d.panelData);
     submitEditorWidget()->setPanelInfo(d.panelInfo);
 
-    addFiles(d.commitFiles, true, true);
+    addFiles(d.stagedFiles, true, true);
     // Not Updated: Initially unchecked
-    addFiles(d.notUpdatedFiles, false, true);
+    addFiles(d.unstagedFiles, false, true);
     addFiles(d.untrackedFiles, false, true);
 }
 
diff --git a/src/plugins/help/help.pro b/src/plugins/help/help.pro
index 1148606cab73e847a7b8bb75ce359cae31a93c21..b2e9a1dbd613cec02e2b73ed04d1cd6c7e1eaa3d 100644
--- a/src/plugins/help/help.pro
+++ b/src/plugins/help/help.pro
@@ -16,8 +16,8 @@ HEADERS += helpplugin.h \
     searchwidget.h \
     helpfindsupport.h \
     help_global.h \
-    helpindexfilter.h \
-    indexwindow.h
+    helpindexfilter.h
+
 SOURCES += helpplugin.cpp \
     docsettingspage.cpp \
     filtersettingspage.cpp \
@@ -26,6 +26,7 @@ SOURCES += helpplugin.cpp \
     searchwidget.cpp \
     helpfindsupport.cpp \
     helpindexfilter.cpp
+
 FORMS += docsettingspage.ui \
     filtersettingspage.ui
 RESOURCES += help.qrc
diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index 2de31700a867462dba9d8a17017cf8d81e990096..dc28901b7050540b8dc028165ccf658308a0c493 100644
--- a/src/plugins/perforce/perforceplugin.cpp
+++ b/src/plugins/perforce/perforceplugin.cpp
@@ -405,17 +405,17 @@ void PerforcePlugin::extensionsInitialized()
 
 void PerforcePlugin::openCurrentFile()
 {
-    runP4Cmd(QStringList() << QLatin1String("edit") << currentFileName(), QStringList(), true);
+    vcsOpen(currentFileName());
 }
 
 void PerforcePlugin::addCurrentFile()
 {
-    runP4Cmd(QStringList() << QLatin1String("add") << currentFileName(), QStringList(), true);
+    vcsAdd(currentFileName());
 }
 
 void PerforcePlugin::deleteCurrentFile()
 {
-    runP4Cmd(QStringList() << QLatin1String("delete") << currentFileName(), QStringList(), true);
+    vcsDelete(currentFileName());
 }
 
 void PerforcePlugin::revertCurrentFile()
@@ -426,7 +426,7 @@ void PerforcePlugin::revertCurrentFile()
     QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
     QStringList args;
     args << QLatin1String("diff") << QLatin1String("-sa");
-    PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec);
+    PerforceResponse result = runP4Cmd(args, QStringList(), CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (result.error)
         return;
 
@@ -444,7 +444,7 @@ void PerforcePlugin::revertCurrentFile()
     foreach (Core::IFile *file, files) {
         fm->blockFileChange(file);
     }
-    PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), true);
+    PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     Core::IFile::ReloadBehavior tempBehavior =
             Core::IFile::ReloadAll;
     foreach (Core::IFile *file, files) {
@@ -489,7 +489,7 @@ void PerforcePlugin::printOpenedFileList()
     Core::IEditor *e = m_coreInstance->editorManager()->currentEditor();
     if (e)
         e->widget()->setFocus();
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("opened"), QStringList(), true);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("opened"), QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
 }
 
 #ifdef USE_P4_API
@@ -522,7 +522,8 @@ void PerforcePlugin::submit()
         return;
     }
 
-    PerforceResponse result = runP4Cmd(QStringList()<< QLatin1String("change") << QLatin1String("-o"), QStringList(), false);
+    PerforceResponse result = runP4Cmd(QStringList()<< QLatin1String("change") << QLatin1String("-o"), QStringList(),
+                                       CommandToWindow|StdErrToWindow|ErrorToWindow);
     if (result.error) {
         delete m_changeTmpFile;
         m_changeTmpFile = 0;
@@ -550,7 +551,8 @@ void PerforcePlugin::submit()
     foreach (const QString &f, files)
         nativeFiles << QDir::toNativeSeparators(f);
 
-    PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles, false);
+    PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles,
+                                        CommandToWindow|StdErrToWindow|ErrorToWindow);
     if (result2.error) {
         delete m_changeTmpFile;
         m_changeTmpFile = 0;
@@ -597,8 +599,10 @@ void PerforcePlugin::printPendingChanges()
     PendingChangesDialog dia(pendingChangesData(), m_coreInstance->mainWindow());
     qApp->restoreOverrideCursor();
     if (dia.exec() == QDialog::Accepted) {
-        int i = dia.changeNumber();
-        PerforceResponse result = runP4Cmd(QStringList()<<"submit"<<"-c"<<QString::number(i), QStringList(), true);
+        const int i = dia.changeNumber();
+        QStringList args(QLatin1String("submit"));
+        args << QLatin1String("-c") << QString::number(i);
+        runP4Cmd(args, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     }
 }
 
@@ -628,7 +632,8 @@ void PerforcePlugin::annotate(const QString &fileName)
     QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
     QStringList args;
     args << QLatin1String("annotate") << QLatin1String("-cqi") << fileName;
-    const PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec);
+    const PerforceResponse result = runP4Cmd(args, QStringList(),
+                                             CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (!result.error) {
         const QFileInfo fi(fileName);
         showOutputInEditor(tr("p4 annotate %1").arg(fi.fileName()), result.stdOut, VCSBase::AnnotateOutput, codec);
@@ -654,7 +659,8 @@ void PerforcePlugin::filelog(const QString &fileName)
     QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
     QStringList args;
     args << QLatin1String("filelog") << QLatin1String("-li") << fileName;
-    const PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec);
+    const PerforceResponse result = runP4Cmd(args, QStringList(),
+                                             CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (!result.error) {
         const QFileInfo fi(fileName);
         showOutputInEditor(tr("p4 filelog %1").arg(fi.fileName()), result.stdOut, VCSBase::LogOutput, codec);
@@ -718,18 +724,19 @@ bool PerforcePlugin::managesDirectory(const QString &directory) const
     QStringList args;
     args << QLatin1String("fstat") << QLatin1String("-m1") << p4Path;
 
-    const PerforceResponse result = runP4Cmd(args, QStringList(), false, false);
+    const PerforceResponse result = runP4Cmd(args, QStringList(), 0u);
     return result.stdOut.contains("depotFile") || result.stdErr.contains("... - no such file(s)");
 }
 
 QString PerforcePlugin::findTopLevelForDirectory(const QString & /* dir */) const
 {
     // First check with p4 client -o
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("client") << QLatin1String("-o"), QStringList(), false, false);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("client") << QLatin1String("-o"), QStringList(), 0u);
     if (result.error)
         return QString::null;
 
     QRegExp regExp(QLatin1String("(\\n|\\r\\n|\\r)Root:\\s*(.*)(\\n|\\r\\n|\\r)"));
+    Q_ASSERT(regExp.isValid());
     regExp.setMinimal(true);
     if (regExp.indexIn(result.stdOut) != -1) {
         QString file = regExp.cap(2).trimmed();
@@ -741,20 +748,24 @@ QString PerforcePlugin::findTopLevelForDirectory(const QString & /* dir */) cons
 
 bool PerforcePlugin::vcsOpen(const QString &fileName)
 {
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("edit") << QDir::toNativeSeparators(fileName), QStringList(), true);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("edit") << QDir::toNativeSeparators(fileName), QStringList(),
+                                       CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     return !result.error;
 }
 
 bool PerforcePlugin::vcsAdd(const QString &fileName)
 {
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("add") << fileName, QStringList(), true);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("add") << fileName, QStringList(),
+                                       CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     return !result.error;
 }
 
 bool PerforcePlugin::vcsDelete(const QString &fileName)
 {
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), true);
-    PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("delete") << fileName, QStringList(), true);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(),
+                                       CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
+    PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("delete") << fileName, QStringList(),
+                                        CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     // TODO need to carefully parse the actual messages from perforce
     // or do a fstat before to decide what to do
 
@@ -767,8 +778,7 @@ bool PerforcePlugin::vcsDelete(const QString &fileName)
 
 PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
                                           const QStringList &extraArgs,
-                                          bool showStdOutInOutputWindow,
-                                          bool showStdErrInOutputWindow,
+                                          unsigned logFlags,
                                           QTextCodec *outputCodec) const
 {
     if (Perforce::Constants::debug)
@@ -801,12 +811,14 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
     }
     actualArgs << args;
 
-    response.command = m_settings.p4Command;
-    response.command += blank;
-    response.command += actualArgs.join(QString(blank));
-    const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
-    const QString outputText = tr("%1 Executing: %2\n").arg(timeStamp, response.command);
-    showOutput(outputText, false);
+    if (logFlags & CommandToWindow) {
+        QString command = m_settings.p4Command;
+        command += blank;
+        command += actualArgs.join(QString(blank));
+        const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
+        const QString outputText = tr("%1 Executing: %2\n").arg(timeStamp, command);
+        showOutput(outputText, false);
+    }
 
     // Run, connect stderr to the output window
     Core::Utils::SynchronousProcess process;
@@ -815,13 +827,13 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
     process.setEnvironment(environment());
 
     // connect stderr to the output window if desired
-    if (showStdErrInOutputWindow) {
+    if (logFlags & StdErrToWindow) {
         process.setStdErrBufferedSignalsEnabled(true);
         connect(&process, SIGNAL(stdErrBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool)));
     }
 
     // connect stdout to the output window if desired
-    if (showStdOutInOutputWindow) {
+    if (logFlags & StdOutToWindow) {
         process.setStdOutBufferedSignalsEnabled(true);
         connect(&process, SIGNAL(stdOutBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool)));
     }
@@ -847,13 +859,15 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
         response.message = tr("Could not start perforce '%1'. Please check your settings in the preferences.").arg(m_settings.p4Command);
         break;
     case Core::Utils::SynchronousProcessResponse::Hang:
-        response.message = tr("Subversion did not respond within timeout limit (%1 ms).").arg(p4Timeout );
+        response.message = tr("Perforce did not respond within timeout limit (%1 ms).").arg(p4Timeout );
         break;
     }
-    if (response.error)
-        m_perforceOutputWindow->append(response.message, true);
-
-
+    if (response.error) {
+        if (Perforce::Constants::debug)
+            qDebug() << response.message;
+        if (logFlags & ErrorToWindow)
+            m_perforceOutputWindow->append(response.message, true);
+    }
     return response;
 }
 
@@ -923,7 +937,7 @@ void PerforcePlugin::p4Diff(const QStringList &files, QString diffname)
         }
     }
 
-    const PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("diff") << QLatin1String("-du"), files, false, codec);
+    const PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("diff") << QLatin1String("-du"), files, CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (result.error)
         return;
 
@@ -948,7 +962,7 @@ void PerforcePlugin::describe(const QString & source, const QString &n)
     QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(0) : VCSBase::VCSBaseEditor::getCodec(m_coreInstance, source);
     QStringList args;
     args << QLatin1String("describe") << QLatin1String("-du") << n;
-    const PerforceResponse result = runP4Cmd(args, QStringList(), codec);
+    const PerforceResponse result = runP4Cmd(args, QStringList(), CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (!result.error)
         showOutputInEditor(tr("p4 describe %1").arg(n), result.stdOut, VCSBase::DiffOutput, codec);
 }
diff --git a/src/plugins/perforce/perforceplugin.h b/src/plugins/perforce/perforceplugin.h
index 4c088563324ae8999d279b5c8607b3300aeabec2..7a4e23077794ef89599d00b3818d537fb118c46a 100644
--- a/src/plugins/perforce/perforceplugin.h
+++ b/src/plugins/perforce/perforceplugin.h
@@ -86,7 +86,6 @@ private:
 struct PerforceResponse
 {
     bool error;
-    QString command;
     QString stdOut;
     QString stdErr;
     QString message;
@@ -161,12 +160,15 @@ private:
     Core::IEditor *showOutputInEditor(const QString& title, const QString output,
                                       int editorType,
                                       QTextCodec *codec = 0);
+
+    // Verbosity flags for runP4Cmd.
+    enum  RunLogFlags { CommandToWindow = 0x1, StdOutToWindow = 0x2, StdErrToWindow = 0x4, ErrorToWindow = 0x8 };
+
     // args are passed as command line arguments
     // extra args via a tempfile and the option -x "temp-filename"
     PerforceResponse runP4Cmd(const QStringList &args,
                               const QStringList &extraArgs = QStringList(),
-                              bool showStdOutInOutputWindow = false,
-                              bool showStdErrInOutputWindow = true,
+                              unsigned logFlags = CommandToWindow|StdErrToWindow|ErrorToWindow,
                               QTextCodec *outputCodec = 0) const;
 
     void openFiles(const QStringList &files);
diff --git a/src/plugins/projectexplorer/projectwizardpage.ui b/src/plugins/projectexplorer/projectwizardpage.ui
index bc31f8c49e14461349c331e8397241300803197a..7c21ec5a91099229862a773163eec8784be9e8bf 100644
--- a/src/plugins/projectexplorer/projectwizardpage.ui
+++ b/src/plugins/projectexplorer/projectwizardpage.ui
@@ -104,8 +104,9 @@
         <widget class="QLabel" name="filesLabel">
          <property name="text">
           <string>The following files will be added:
-f1
-f2
+
+
+
 </string>
          </property>
          <property name="textInteractionFlags">
diff --git a/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp b/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp
index 14965f50187675bf5c69cec9cc2ddc79032c16ff..1090673284f08a4d50278b104b826541e71c9208 100644
--- a/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp
+++ b/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp
@@ -35,6 +35,7 @@
 #include "consoleappwizard.h"
 #include "modulespage.h"
 
+#include <QtCore/QDebug>
 #include <utils/projectintropage.h>
 
 namespace Qt4ProjectManager {
@@ -51,13 +52,11 @@ ConsoleAppWizardDialog::ConsoleAppWizardDialog(const QString &templateName,
     setWindowIcon(icon);
     setWindowTitle(templateName);
     Core::BaseFileWizard::setupWizard(this);
-    setOptions(QWizard::IndependentPages | QWizard::HaveNextButtonOnLastPage);
 
     m_introPage->setDescription(tr("This wizard generates a Qt4 console application "
                           "project. The application derives from QCoreApplication and does not "
                           "present a GUI. You can press 'Finish' at any point in time."));
 
-    m_introPage->setFinalPage(true);
     addPage(m_introPage);
 
     m_modulesPage->setModuleSelected(QLatin1String("core"));
diff --git a/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp b/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp
index 7b1ba073d34e6203a1f2cb720d6dafac79c2faed..621a3b6ba92072de3d411f1713ac6515166102c6 100644
--- a/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp
+++ b/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp
@@ -63,7 +63,6 @@ GuiAppWizardDialog::GuiAppWizardDialog(const QString &templateName,
     setWindowIcon(icon);
     setWindowTitle(templateName);
     Core::BaseFileWizard::setupWizard(this);
-    setOptions(QWizard::IndependentPages);
 
     m_introPage->setDescription(tr("This wizard generates a Qt4 GUI application "
          "project. The application derives by default from QApplication "
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index df5fe4108081d78eb945061deb5e236cd5ce2b25..49d29b75c93e5f8fe030fb7e6d38de05808c8f8b 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -79,6 +79,7 @@
 #include <QtGui/QToolBar>
 #include <QtGui/QToolTip>
 #include <QtGui/QInputDialog>
+#include <QtGui/QMenu>
 
 using namespace TextEditor;
 using namespace TextEditor::Internal;
@@ -487,10 +488,6 @@ ITextEditable *BaseTextEditor::editableInterface() const
                 d->m_editable, SIGNAL(contentsChanged()));
         connect(this, SIGNAL(changed()),
                 d->m_editable, SIGNAL(changed()));
-        connect(this,
-                SIGNAL(markRequested(TextEditor::ITextEditor *, int)),
-                d->m_editable,
-                SIGNAL(markRequested(TextEditor::ITextEditor *, int)));
     }
     return d->m_editable;
 }
@@ -501,7 +498,8 @@ void BaseTextEditor::currentEditorChanged(Core::IEditor *editor)
     if (editor == d->m_editable) {
         if (d->m_document->hasDecodingError()) {
             Core::EditorManager::instance()->showEditorInfoBar(QLatin1String(Constants::SELECT_ENCODING),
-                tr("<b>Error:</b> Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.").arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name())),
+                tr("<b>Error:</b> Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.")
+                    .arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name())),
                 tr("Select Encoding"),
                 this, SLOT(selectEncoding()));
         }
@@ -531,7 +529,6 @@ void BaseTextEditor::selectEncoding()
     }
 }
 
-
 void DocumentMarker::updateMark(ITextMark *mark)
 {
     TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(document->documentLayout());
@@ -598,8 +595,79 @@ void BaseTextEditor::slotSelectionChanged()
         viewport()->update();
     if (!d->m_inBlockSelectionMode)
         d->m_blockSelectionExtraX = 0;
+    if (!d->m_selectBlockAnchor.isNull() && !textCursor().hasSelection())
+        d->m_selectBlockAnchor = QTextCursor();
+}
+
+void BaseTextEditor::gotoBlockStart()
+{
+    QTextCursor cursor = textCursor();
+    if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false))
+        setTextCursor(cursor);
+}
+
+void BaseTextEditor::gotoBlockEnd()
+{
+    QTextCursor cursor = textCursor();
+    if (TextBlockUserData::findNextClosingParenthesis(&cursor, false))
+        setTextCursor(cursor);
+}
+
+void BaseTextEditor::gotoBlockStartWithSelection()
+{
+    QTextCursor cursor = textCursor();
+    if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true))
+        setTextCursor(cursor);
+}
+
+void BaseTextEditor::gotoBlockEndWithSelection()
+{
+    QTextCursor cursor = textCursor();
+    if (TextBlockUserData::findNextClosingParenthesis(&cursor, true))
+        setTextCursor(cursor);
 }
 
+void BaseTextEditor::selectBlockUp()
+{
+    QTextCursor cursor = textCursor();
+    if (!cursor.hasSelection())
+        d->m_selectBlockAnchor = cursor;
+    else
+        cursor.setPosition(cursor.selectionStart());
+
+
+    if (!TextBlockUserData::findPreviousOpenParenthesis(&cursor, false))
+        return;
+    if (!TextBlockUserData::findNextClosingParenthesis(&cursor, true))
+        return;
+    setTextCursor(cursor);
+}
+
+void BaseTextEditor::selectBlockDown()
+{
+    QTextCursor tc = textCursor();
+    QTextCursor cursor = d->m_selectBlockAnchor;
+
+    if (!tc.hasSelection() || cursor.isNull())
+        return;
+    tc.setPosition(tc.selectionStart());
+
+    forever {
+        QTextCursor ahead = cursor;
+        if (!TextBlockUserData::findPreviousOpenParenthesis(&ahead, false))
+            break;
+        if (ahead.position() <= tc.position())
+            break;
+        cursor = ahead;
+    }
+    if ( cursor != d->m_selectBlockAnchor)
+        TextBlockUserData::findNextClosingParenthesis(&cursor, true);
+
+    setTextCursor(cursor);
+}
+
+
+
 void BaseTextEditor::keyPressEvent(QKeyEvent *e)
 {
 
@@ -633,6 +701,11 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
                 e->accept();
                 return;
             }
+        } else if (e == QKeySequence::Paste) {
+            if (!ro) {
+                d->removeBlockSelection();
+                // continue
+            }
         }
     }
 
@@ -693,6 +766,8 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
         break;
     case Qt::Key_Home:
         if (!(e == QKeySequence::MoveToStartOfDocument) && !(e == QKeySequence::SelectStartOfDocument)) {
+            if ((e->modifiers() & (Qt::AltModifier | Qt::ShiftModifier)) == (Qt::AltModifier | Qt::ShiftModifier))
+                d->m_lastEventWasBlockSelectionEvent = true;
             handleHomeKey(e->modifiers() & Qt::ShiftModifier);
             e->accept();
             return;
@@ -708,6 +783,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
             return;
         }
         // fall through
+    case Qt::Key_End:
     case Qt::Key_Right:
     case Qt::Key_Left:
 #ifndef Q_OS_MAC
@@ -795,6 +871,15 @@ skip_event:
         delete e;
 }
 
+void BaseTextEditor::setTextCursor(const QTextCursor &cursor)
+{
+    // workaround for QTextControl bug
+    bool selectionChange = cursor.hasSelection() || textCursor().hasSelection();
+    QPlainTextEdit::setTextCursor(cursor);
+    if (selectionChange)
+        slotSelectionChanged();
+}
+
 void BaseTextEditor::gotoLine(int line, int column)
 {
     const int blockNumber = line - 1;
@@ -2343,6 +2428,12 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
             } else {
                 d->extraAreaToggleMarkBlockNumber = cursor.blockNumber();
             }
+        } else if (e->button() == Qt::RightButton) {
+            QMenu * contextMenu = new QMenu(this);
+            emit d->m_editable->markContextMenuRequested(editableInterface(), cursor.blockNumber(), contextMenu);
+            if (!contextMenu->isEmpty())
+                contextMenu->exec(e->globalPos());
+            delete contextMenu;
         }
     } else if (d->extraAreaSelectionAnchorBlockNumber >= 0) {
         QTextCursor selection = cursor;
@@ -2377,7 +2468,7 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
             d->extraAreaToggleMarkBlockNumber = -1;
             if (cursor.blockNumber() == n) {
                 int line = n + 1;
-                emit markRequested(editableInterface(), line);
+                emit d->m_editable->markRequested(editableInterface(), line);
             }
         }
     }
@@ -2386,6 +2477,9 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
 void BaseTextEditor::slotCursorPositionChanged()
 {
     QList<QTextEdit::ExtraSelection> extraSelections;
+    setExtraSelections(ParenthesesMatchingSelection, extraSelections); // clear
+    if (d->m_parenthesesMatchingEnabled)
+        d->m_parenthesesMatchingTimer->start(50);
 
     if (d->m_highlightCurrentLine) {
         QTextEdit::ExtraSelection sel;
@@ -2396,11 +2490,7 @@ void BaseTextEditor::slotCursorPositionChanged()
         extraSelections.append(sel);
     }
 
-    if (d->m_parenthesesMatchingEnabled)
-        d->m_parenthesesMatchingTimer->start(50);
-
-    d->m_extraSelections = extraSelections;
-    setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections);
+    setExtraSelections(CurrentLineSelection, extraSelections);
 }
 
 QTextBlock TextBlockUserData::testCollapse(const QTextBlock& block)
@@ -2908,6 +2998,61 @@ TextBlockUserData::MatchType TextBlockUserData::checkClosedParenthesis(QTextCurs
     }
 }
 
+
+bool TextBlockUserData::findPreviousOpenParenthesis(QTextCursor *cursor, bool select)
+{
+    QTextBlock block = cursor->block();
+    int position = cursor->position();
+    int ignore = 0;
+    while (block.isValid()) {
+        Parentheses parenList = TextEditDocumentLayout::parentheses(block);
+        if (!parenList.isEmpty()) {
+            for (int i = parenList.count()-1; i >= 0; --i) {
+                Parenthesis paren = parenList.at(i);
+                if (block == cursor->block() && position - block.position() <= paren.pos + 1)
+                    continue;
+                if (paren.type == Parenthesis::Closed) {
+                    ++ignore;
+                } else if (ignore > 0) {
+                    --ignore;
+                } else {
+                    cursor->setPosition(block.position() + paren.pos, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
+                    return true;
+                }
+            }
+        }
+        block = block.previous();
+    }
+    return false;
+}
+
+bool TextBlockUserData::findNextClosingParenthesis(QTextCursor *cursor, bool select)
+{
+    QTextBlock block = cursor->block();
+    int position = cursor->position();
+    int ignore = 0;
+    while (block.isValid()) {
+        Parentheses parenList = TextEditDocumentLayout::parentheses(block);
+        if (!parenList.isEmpty()) {
+            for (int i = 0; i < parenList.count(); ++i) {
+                Parenthesis paren = parenList.at(i);
+                if (block == cursor->block() && position - block.position() >= paren.pos)
+                    continue;
+                if (paren.type == Parenthesis::Opened) {
+                    ++ignore;
+                } else if (ignore > 0) {
+                    --ignore;
+                } else {
+                    cursor->setPosition(block.position() + paren.pos+1, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
+                    return true;
+                }
+            }
+        }
+        block = block.next();
+    }
+    return false;
+}
+
 TextBlockUserData::MatchType TextBlockUserData::matchCursorBackward(QTextCursor *cursor)
 {
     cursor->clearSelection();
@@ -2987,7 +3132,7 @@ void BaseTextEditor::_q_matchParentheses()
     if (backwardMatchType == TextBlockUserData::NoMatch && forwardMatchType == TextBlockUserData::NoMatch)
         return;
 
-    QList<QTextEdit::ExtraSelection> extraSelections = d->m_extraSelections;
+    QList<QTextEdit::ExtraSelection> extraSelections;
 
     if (backwardMatch.hasSelection()) {
         QTextEdit::ExtraSelection sel;
@@ -3040,8 +3185,7 @@ void BaseTextEditor::_q_matchParentheses()
         }
         extraSelections.append(sel);
     }
-    d->m_extraSelections = extraSelections;
-    setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections);
+    setExtraSelections(ParenthesesMatchingSelection, extraSelections);
 }
 
 void BaseTextEditor::setActionHack(QObject *hack)
@@ -3088,15 +3232,21 @@ void BaseTextEditor::deleteLine()
     cut();
 }
 
-void BaseTextEditor::setExtraExtraSelections(const QList<QTextEdit::ExtraSelection> &selections)
+void BaseTextEditor::setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections)
 {
-    d->m_extraExtraSelections = selections;
-    setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections);
+    if (selections.isEmpty() && d->m_extraSelections[kind].isEmpty())
+        return;
+    d->m_extraSelections[kind] = selections;
+
+    QList<QTextEdit::ExtraSelection> all;
+    for (int i = 0; i < NExtraSelectionKinds; ++i)
+        all += d->m_extraSelections[i];
+    QPlainTextEdit::setExtraSelections(all);
 }
 
-QList<QTextEdit::ExtraSelection> BaseTextEditor::extraExtraSelections() const
+QList<QTextEdit::ExtraSelection> BaseTextEditor::extraSelections(ExtraSelectionKind kind) const
 {
-    return d->m_extraExtraSelections;
+    return d->m_extraSelections[kind];
 }
 
 
@@ -3152,13 +3302,16 @@ void BaseTextEditor::collapse()
     TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(doc->documentLayout());
     Q_ASSERT(documentLayout);
     QTextBlock block = textCursor().block();
+    qDebug() << "collapse at block" << block.blockNumber();
     while (block.isValid()) {
-        if (TextBlockUserData::canCollapse(block)) {
-            if ((block.next().userState()) >> 8 == (textCursor().block().userState() >> 8))
+        qDebug() << "test block" << block.blockNumber();
+        if (TextBlockUserData::canCollapse(block) && block.next().isVisible()) {
+            if ((block.next().userState()) >> 8 <= (textCursor().block().userState() >> 8))
                 break;
         }
         block = block.previous();
     }
+    qDebug() << "found" << block.blockNumber();
     if (block.isValid()) {
         TextBlockUserData::doCollapse(block, false);
         d->moveCursorVisible();
@@ -3238,6 +3391,14 @@ void BaseTextEditor::cut()
     QPlainTextEdit::cut();
 }
 
+void BaseTextEditor::paste()
+{
+    if (d->m_inBlockSelectionMode) {
+        d->removeBlockSelection();
+    }
+    QPlainTextEdit::paste();
+}
+
 QMimeData *BaseTextEditor::createMimeDataFromSelection() const
 {
     if (d->m_inBlockSelectionMode) {
diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h
index ced22900030e6684800dc119bd290291987d4818..40454a9c7d430dc6b188567843a7e13323f98f88 100644
--- a/src/plugins/texteditor/basetexteditor.h
+++ b/src/plugins/texteditor/basetexteditor.h
@@ -169,6 +169,8 @@ public:
     static MatchType checkClosedParenthesis(QTextCursor *cursor, QChar c);
     static MatchType matchCursorBackward(QTextCursor *cursor);
     static MatchType matchCursorForward(QTextCursor *cursor);
+    static bool findPreviousOpenParenthesis(QTextCursor *cursor, bool select = false);
+    static bool findNextClosingParenthesis(QTextCursor *cursor, bool select = false);
 
 
 private:
@@ -298,6 +300,8 @@ public:
 
     void setReadOnly(bool b);
 
+    void setTextCursor(const QTextCursor &cursor);
+
 public slots:
     void setDisplayName(const QString &title);
     virtual void setFontSettings(const TextEditor::FontSettings &);
@@ -305,6 +309,7 @@ public slots:
     virtual void unCommentSelection();
     virtual void setStorageSettings(const TextEditor::StorageSettings &);
 
+    void paste();
     void cut();
 
     void zoomIn(int range = 1);
@@ -316,6 +321,14 @@ public slots:
     void expand();
     void selectEncoding();
 
+    void gotoBlockStart();
+    void gotoBlockEnd();
+    void gotoBlockStartWithSelection();
+    void gotoBlockEndWithSelection();
+
+    void selectBlockUp();
+    void selectBlockDown();
+
 signals:
     void changed();
 
@@ -356,7 +369,6 @@ private:
     Internal::BaseTextEditorPrivate *d;
     friend class Internal::BaseTextEditorPrivate;
 
-
 public:
     QWidget *extraArea() const;
     virtual int extraAreaWidth(int *markWidthPtr = 0) const;
@@ -372,8 +384,16 @@ public:
 
     void ensureCursorVisible();
 
-    void setExtraExtraSelections(const QList<QTextEdit::ExtraSelection> &selections);
-    QList<QTextEdit::ExtraSelection> extraExtraSelections() const;
+    enum ExtraSelectionKind {
+        CurrentLineSelection,
+        ParenthesesMatchingSelection,
+        CodeWarningsSelection,
+        CodeSemanticsSelection,
+        OtherSelection,
+        NExtraSelectionKinds
+    };
+    void setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections);
+    QList<QTextEdit::ExtraSelection> extraSelections(ExtraSelectionKind kind) const;
 
     struct BlockRange {
         BlockRange():first(0), last(-1){}
@@ -418,7 +438,6 @@ protected slots:
 
 
 signals:
-    void markRequested(TextEditor::ITextEditor *editor, int line);
     void requestBlockUpdate(const QTextBlock &);
     void requestAutoCompletion(ITextEditable *editor, bool forced);
 
diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h
index 87d1af0de0f078b7a7d3edbceea8a5405ad0d1e7..9f1e5a7eb67b633e56e67268da701357f64327f0 100644
--- a/src/plugins/texteditor/basetexteditor_p.h
+++ b/src/plugins/texteditor/basetexteditor_p.h
@@ -204,8 +204,7 @@ public:
 
     QObject *m_actionHack;
 
-    QList<QTextEdit::ExtraSelection> m_extraSelections;
-    QList<QTextEdit::ExtraSelection> m_extraExtraSelections;
+    QList<QTextEdit::ExtraSelection> m_extraSelections[BaseTextEditor::NExtraSelectionKinds];
 
     // block selection mode
     bool m_inBlockSelectionMode;
@@ -216,6 +215,7 @@ public:
     void removeBlockSelection(const QString &text = QString());
     
     QTextCursor m_findScope;
+    QTextCursor m_selectBlockAnchor;
 
     void moveCursorVisible();
 };
diff --git a/src/plugins/texteditor/itexteditor.h b/src/plugins/texteditor/itexteditor.h
index 432c3c9c5850b34ea8a38b93498979c84f8151a4..514f311472a8a362b6ec08a09b397dab18a10857 100644
--- a/src/plugins/texteditor/itexteditor.h
+++ b/src/plugins/texteditor/itexteditor.h
@@ -44,6 +44,7 @@
 #include <QtGui/QIcon>
 
 QT_BEGIN_NAMESPACE
+class QMenu;
 class QTextBlock;
 QT_END_NAMESPACE
 
@@ -124,6 +125,7 @@ public:
 signals:
     void contentsChanged();
     void markRequested(TextEditor::ITextEditor *editor, int line);
+    void markContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu);
     void tooltipRequested(TextEditor::ITextEditor *editor, const QPoint &globalPos, int position);
     void contextHelpIdRequested(TextEditor::ITextEditor *editor, int position);
 };
diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp
index 94cdca6cfda4110a6c349808a47e8df98ee27a0b..635f96545769d0e36a03dadf3de5a3544d2882b8 100644
--- a/src/plugins/texteditor/texteditoractionhandler.cpp
+++ b/src/plugins/texteditor/texteditoractionhandler.cpp
@@ -67,6 +67,9 @@ TextEditorActionHandler::TextEditorActionHandler(Core::ICore *core,
                  = m_collapseAction = m_expandAction
                  = m_deleteLineAction = m_selectEncodingAction
                  = m_increaseFontSizeAction = m_decreaseFontSizeAction
+                 = m_gotoBlockStartAction = m_gotoBlockStartWithSelectionAction
+                 = m_gotoBlockEndAction = m_gotoBlockEndWithSelectionAction
+                 = m_selectBlockUpAction = m_selectBlockDownAction
                  = 0;
 
     m_contextId << m_core->uniqueIDManager()->uniqueIdentifier(context);
@@ -161,13 +164,11 @@ void TextEditorActionHandler::createActions()
     command = am->registerAction(m_collapseAction, Constants::COLLAPSE, m_contextId);
     command->setDefaultKeySequence(QKeySequence(tr("Ctrl+<")));
     connect(m_collapseAction, SIGNAL(triggered()), this, SLOT(collapse()));
-    advancedMenu->addAction(command);
 
     m_expandAction = new QAction(tr("Expand"), this);
     command = am->registerAction(m_expandAction, Constants::EXPAND, m_contextId);
     command->setDefaultKeySequence(QKeySequence(tr("Ctrl+>")));
     connect(m_expandAction, SIGNAL(triggered()), this, SLOT(expand()));
-    advancedMenu->addAction(command);
 
     m_unCollapseAllAction = new QAction(tr("(Un)&Collapse All"), this);
     command = am->registerAction(m_unCollapseAllAction, Constants::UN_COLLAPSE_ALL, m_contextId);
@@ -185,6 +186,36 @@ void TextEditorActionHandler::createActions()
     command->setDefaultKeySequence(QKeySequence(tr("Ctrl+-")));
     connect(m_decreaseFontSizeAction, SIGNAL(triggered()), this, SLOT(decreaseFontSize()));
     advancedMenu->addAction(command);
+
+    m_gotoBlockStartAction = new QAction(tr("Goto Block Start"), this);
+    command = am->registerAction(m_gotoBlockStartAction, Constants::GOTO_BLOCK_START, m_contextId);
+    command->setDefaultKeySequence(QKeySequence(tr("Ctrl+[")));
+    connect(m_gotoBlockStartAction, SIGNAL(triggered()), this, SLOT(gotoBlockStart()));
+
+    m_gotoBlockEndAction = new QAction(tr("Goto Block End"), this);
+    command = am->registerAction(m_gotoBlockEndAction, Constants::GOTO_BLOCK_END, m_contextId);
+    command->setDefaultKeySequence(QKeySequence(tr("Ctrl+]")));
+    connect(m_gotoBlockEndAction, SIGNAL(triggered()), this, SLOT(gotoBlockEnd()));
+
+    m_gotoBlockStartWithSelectionAction = new QAction(tr("Goto Block Start With Selection"), this);
+    command = am->registerAction(m_gotoBlockStartWithSelectionAction, Constants::GOTO_BLOCK_START_WITH_SELECTION, m_contextId);
+    command->setDefaultKeySequence(QKeySequence(tr("Ctrl+{")));
+    connect(m_gotoBlockStartWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockStartWithSelection()));
+
+    m_gotoBlockEndWithSelectionAction = new QAction(tr("Goto Block End With Selection"), this);
+    command = am->registerAction(m_gotoBlockEndWithSelectionAction, Constants::GOTO_BLOCK_END_WITH_SELECTION, m_contextId);
+    command->setDefaultKeySequence(QKeySequence(tr("Ctrl+}")));
+    connect(m_gotoBlockEndWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockEndWithSelection()));
+
+    m_selectBlockUpAction= new QAction(tr("Select Block Up"), this);
+    command = am->registerAction(m_selectBlockUpAction, Constants::SELECT_BLOCK_UP, m_contextId);
+    command->setDefaultKeySequence(QKeySequence(tr("Ctrl+U")));
+    connect(m_selectBlockUpAction, SIGNAL(triggered()), this, SLOT(selectBlockUp()));
+
+    m_selectBlockDownAction= new QAction(tr("Select Block Down"), this);
+    command = am->registerAction(m_selectBlockDownAction, Constants::SELECT_BLOCK_DOWN, m_contextId);
+    command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+U")));
+    connect(m_selectBlockDownAction, SIGNAL(triggered()), this, SLOT(selectBlockDown()));
 }
 
 bool TextEditorActionHandler::supportsAction(const QString & /*id */) const
@@ -229,35 +260,30 @@ void TextEditorActionHandler::updateActions()
 
 void TextEditorActionHandler::updateActions(UpdateMode um)
 {
-    if (m_pasteAction)
-        m_pasteAction->setEnabled(um != NoEditor);
-    if (m_selectAllAction)
-        m_selectAllAction->setEnabled(um != NoEditor);
-    if (m_gotoAction)
-        m_gotoAction->setEnabled(um != NoEditor);
-    if (m_selectEncodingAction)
-        m_selectEncodingAction->setEnabled(um != NoEditor);
-    if (m_printAction)
-        m_printAction->setEnabled(um != NoEditor);
-    if (m_formatAction)
-        m_formatAction->setEnabled((m_optionalActions & Format) && um != NoEditor);
-    if (m_unCommentSelectionAction)
-        m_unCommentSelectionAction->setEnabled((m_optionalActions & UnCommentSelection) && um != NoEditor);
-    if (m_collapseAction)
-        m_collapseAction->setEnabled(um != NoEditor);
-    if (m_expandAction)
-        m_expandAction->setEnabled(um != NoEditor);
-    if (m_unCollapseAllAction)
-        m_unCollapseAllAction->setEnabled((m_optionalActions & UnCollapseAll) && um != NoEditor);
-    if (m_decreaseFontSizeAction)
-        m_decreaseFontSizeAction->setEnabled(um != NoEditor);
-    if (m_increaseFontSizeAction)
-        m_increaseFontSizeAction->setEnabled(um != NoEditor);
-    if (m_visualizeWhitespaceAction) {
-        m_visualizeWhitespaceAction->setEnabled(um != NoEditor);
-        if (m_currentEditor)
-            m_visualizeWhitespaceAction->setChecked(m_currentEditor->displaySettings().m_visualizeWhitespace);
-    }
+    if (!m_initialized)
+        return;
+    m_pasteAction->setEnabled(um != NoEditor);
+    m_selectAllAction->setEnabled(um != NoEditor);
+    m_gotoAction->setEnabled(um != NoEditor);
+    m_selectEncodingAction->setEnabled(um != NoEditor);
+    m_printAction->setEnabled(um != NoEditor);
+    m_formatAction->setEnabled((m_optionalActions & Format) && um != NoEditor);
+    m_unCommentSelectionAction->setEnabled((m_optionalActions & UnCommentSelection) && um != NoEditor);
+    m_collapseAction->setEnabled(um != NoEditor);
+    m_expandAction->setEnabled(um != NoEditor);
+    m_unCollapseAllAction->setEnabled((m_optionalActions & UnCollapseAll) && um != NoEditor);
+    m_decreaseFontSizeAction->setEnabled(um != NoEditor);
+    m_increaseFontSizeAction->setEnabled(um != NoEditor);
+    m_gotoBlockStartAction->setEnabled(um != NoEditor);
+    m_gotoBlockStartWithSelectionAction->setEnabled(um != NoEditor);
+    m_gotoBlockEndAction->setEnabled(um != NoEditor);
+    m_gotoBlockEndWithSelectionAction->setEnabled(um != NoEditor);
+    m_selectBlockUpAction->setEnabled(um != NoEditor);
+    m_selectBlockDownAction->setEnabled(um != NoEditor);
+
+    m_visualizeWhitespaceAction->setEnabled(um != NoEditor);
+    if (m_currentEditor)
+        m_visualizeWhitespaceAction->setChecked(m_currentEditor->displaySettings().m_visualizeWhitespace);
     if (m_textWrappingAction) {
         m_textWrappingAction->setEnabled(um != NoEditor);
         if (m_currentEditor)
@@ -365,54 +391,31 @@ void TextEditorActionHandler::setTextWrapping(bool checked)
     }
 }
 
-void TextEditorActionHandler::unCommentSelection()
-{
-    if (m_currentEditor)
-        m_currentEditor->unCommentSelection();
-}
-
-void TextEditorActionHandler::deleteLine()
-{
-    if (m_currentEditor)
-        m_currentEditor->deleteLine();
-}
-
-void TextEditorActionHandler::unCollapseAll()
-{
-    if (m_currentEditor)
-        m_currentEditor->unCollapseAll();
-}
-
-void TextEditorActionHandler::collapse()
-{
-    if (m_currentEditor)
-        m_currentEditor->collapse();
-}
-
-void TextEditorActionHandler::expand()
-{
-    if (m_currentEditor)
-        m_currentEditor->expand();
-}
-
-void TextEditorActionHandler::selectEncoding()
-{
-    if (m_currentEditor)
-        m_currentEditor->selectEncoding();
-}
-
-void TextEditorActionHandler::increaseFontSize()
-{
-    if (m_currentEditor)
-        m_currentEditor->zoomIn();
-}
-
-void TextEditorActionHandler::decreaseFontSize()
-{
-    if (m_currentEditor)
-        m_currentEditor->zoomOut();
-}
-
+#define FUNCTION(funcname) void TextEditorActionHandler::funcname ()\
+{\
+    if (m_currentEditor)\
+        m_currentEditor->funcname ();\
+}
+#define FUNCTION2(funcname, funcname2) void TextEditorActionHandler::funcname ()\
+{\
+    if (m_currentEditor)\
+        m_currentEditor->funcname2 ();\
+}
+
+FUNCTION(unCommentSelection)
+FUNCTION(deleteLine)
+FUNCTION(unCollapseAll)
+FUNCTION(collapse)
+FUNCTION(expand)
+FUNCTION2(increaseFontSize, zoomIn)
+FUNCTION2(decreaseFontSize, zoomOut)
+FUNCTION(selectEncoding)
+FUNCTION(gotoBlockStart)
+FUNCTION(gotoBlockEnd)
+FUNCTION(gotoBlockStartWithSelection)
+FUNCTION(gotoBlockEndWithSelection)
+FUNCTION(selectBlockUp)
+FUNCTION(selectBlockDown)
 
 void TextEditorActionHandler::updateCurrentEditor(Core::IContext *object)
 {
diff --git a/src/plugins/texteditor/texteditoractionhandler.h b/src/plugins/texteditor/texteditoractionhandler.h
index 79ac67c21781ab68085e5d3afc75b6765da2a6e3..9a8c7b9f57c89ceb4a6bd1e1971b1c06bce7ed61 100644
--- a/src/plugins/texteditor/texteditoractionhandler.h
+++ b/src/plugins/texteditor/texteditoractionhandler.h
@@ -109,6 +109,12 @@ private slots:
     void selectEncoding();
     void increaseFontSize();
     void decreaseFontSize();
+    void gotoBlockStart();
+    void gotoBlockEnd();
+    void gotoBlockStartWithSelection();
+    void gotoBlockEndWithSelection();
+    void selectBlockUp();
+    void selectBlockDown();
     void updateCurrentEditor(Core::IContext *object);
 
 private:
@@ -131,6 +137,12 @@ private:
     QAction *m_selectEncodingAction;
     QAction *m_increaseFontSizeAction;
     QAction *m_decreaseFontSizeAction;
+    QAction *m_gotoBlockStartAction;
+    QAction *m_gotoBlockEndAction;
+    QAction *m_gotoBlockStartWithSelectionAction;
+    QAction *m_gotoBlockEndWithSelectionAction;
+    QAction *m_selectBlockUpAction;
+    QAction *m_selectBlockDownAction;
 
     uint m_optionalActions;
     QPointer<BaseTextEditor> m_currentEditor;
diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h
index 8313f61fc3dc870980a1ce1e69a30972f45a7e66..9ac9fdff0e4c368ecb3d43f6ad13da8f86f7660d 100644
--- a/src/plugins/texteditor/texteditorconstants.h
+++ b/src/plugins/texteditor/texteditorconstants.h
@@ -48,9 +48,17 @@ const char * const UN_COLLAPSE_ALL       = "TextEditor.UnCollapseAll";
 const char * const AUTO_INDENT_SELECTION = "TextEditor.AutoIndentSelection";
 const char * const INCREASE_FONT_SIZE    = "TextEditor.IncreaseFontSize";
 const char * const DECREASE_FONT_SIZE    = "TextEditor.DecreaseFontSize";
+const char * const GOTO_BLOCK_START      = "TextEditor.GotoBlockStart";
+const char * const GOTO_BLOCK_START_WITH_SELECTION = "TextEditor.GotoBlockStartWithSelection";
+const char * const GOTO_BLOCK_END        = "TextEditor.GotoBlockEnd";
+const char * const GOTO_BLOCK_END_WITH_SELECTION = "TextEditor.GotoBlockEndWithSelection";
+const char * const SELECT_BLOCK_UP       = "TextEditor.SelectBlockUp";
+const char * const SELECT_BLOCK_DOWN     = "TextEditor.SelectBlockDown";
 const char * const DELETE_LINE           = "TextEditor.DeleteLine";
 const char * const DELETE_WORD           = "TextEditor.DeleteWord";
 const char * const SELECT_ENCODING       = "TextEditor.SelectEncoding";
+const char * const GOTO_OPENING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis";
+const char * const GOTO_CLOSING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis";
 const char * const C_TEXTEDITOR_MIMETYPE_TEXT = "text/plain";
 const char * const C_TEXTEDITOR_MIMETYPE_XML = "application/xml";
 
diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp
index dcfe55d195b82650428ce434fef6ab836aee909b..eb65457c1090bacf713cae9b51b5eaf598b8f5fa 100644
--- a/src/plugins/vcsbase/vcsbaseeditor.cpp
+++ b/src/plugins/vcsbase/vcsbaseeditor.cpp
@@ -225,23 +225,12 @@ void VCSBaseEditor::mouseMoveEvent(QMouseEvent *e)
             sel.format.setFontUnderline(true);
             change = changeUnderCursor(cursor);
             sel.format.setProperty(QTextFormat::UserProperty, change);
-            bool found = false;
-            foreach (QTextEdit::ExtraSelection es, extraSelections()) {
-                if (es.format.stringProperty(QTextFormat::UserProperty) == sel.format.stringProperty(QTextFormat::UserProperty)) {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) {
-                setExtraSelections(QList<QTextEdit::ExtraSelection>() << sel);
-                viewport()->setCursor(Qt::PointingHandCursor);
-            }
-        } else {
-            if (!extraSelections().isEmpty()) {
-                setExtraSelections(QList<QTextEdit::ExtraSelection>());
-                viewport()->setCursor(Qt::IBeamCursor);
-            }
+            setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel);
+            viewport()->setCursor(Qt::PointingHandCursor);
         }
+    } else {
+        setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>());
+        viewport()->setCursor(Qt::IBeamCursor);
     }
     TextEditor::BaseTextEditor::mouseMoveEvent(e);
 }