diff --git a/src/plugins/find/searchresulttreeitemroles.h b/src/plugins/find/searchresulttreeitemroles.h
index 94b409529d5a8b3b7fddf690cffc937e96964410..eae775192b3164a61cc768962ffaa5d66ee2c217 100644
--- a/src/plugins/find/searchresulttreeitemroles.h
+++ b/src/plugins/find/searchresulttreeitemroles.h
@@ -44,7 +44,8 @@ enum Roles
     ResultLineNumberRole,
     SearchTermStartRole,
     SearchTermLengthRole,
-    RowOfItem // The ?-th child of its parent is this this item
+    RowOfItem, // The ?-th child of its parent is this this item
+    TextRole // for files == FileNameRole, for results == ResultLineRole
 };
 
 } // namespace Internal
diff --git a/src/plugins/find/searchresulttreemodel.cpp b/src/plugins/find/searchresulttreemodel.cpp
index 621664e30496d86f605172a771e3dc724de58fb4..080edd5c5851f2e8360e291b66cdab965416d7bd 100644
--- a/src/plugins/find/searchresulttreemodel.cpp
+++ b/src/plugins/find/searchresulttreemodel.cpp
@@ -36,6 +36,8 @@
 #include <QtGui/QFontMetrics>
 #include <QtGui/QColor>
 #include <QtGui/QPalette>
+#include <QtGui/QTextDocument>
+#include <QtGui/QTextCursor>
 #include <QtCore/QDir>
 #include <QtCore/QDebug>
 
@@ -195,6 +197,7 @@ QVariant SearchResultTreeModel::data(const SearchResultTextRow *row, int role) c
     case Qt::FontRole:
         result = m_textEditorFont;
         break;
+    case ItemDataRoles::TextRole:
     case ItemDataRoles::ResultLineRole:
     case Qt::DisplayRole:
         result = row->rowText();
@@ -252,6 +255,7 @@ QVariant SearchResultTreeModel::data(const SearchResultFile *file, int role) con
                 + QLatin1Char(')');
         return QVariant(result);
     }
+    case ItemDataRoles::TextRole:
     case ItemDataRoles::FileNameRole:
     case Qt::ToolTipRole:
         return QVariant(QDir::toNativeSeparators(file->fileName()));
@@ -349,7 +353,7 @@ void SearchResultTreeModel::clear()
     reset();
 }
 
-QModelIndex SearchResultTreeModel::next(const QModelIndex &idx) const
+QModelIndex SearchResultTreeModel::next(const QModelIndex &idx, bool includeTopLevel) const
 {
     QModelIndex parent = idx.parent();
     if (parent.isValid()) {
@@ -367,6 +371,8 @@ QModelIndex SearchResultTreeModel::next(const QModelIndex &idx) const
                 // Wrap around
                 nextParent = index(0,0);
             }
+            if (includeTopLevel)
+                return nextParent;
             return nextParent.child(0, 0);
         }
     } else {
@@ -376,7 +382,7 @@ QModelIndex SearchResultTreeModel::next(const QModelIndex &idx) const
     return QModelIndex();
 }
 
-QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx) const
+QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx, bool includeTopLevel) const
 {
     QModelIndex parent = idx.parent();
     if (parent.isValid()) {
@@ -385,6 +391,8 @@ QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx) const
             // Same parent
             return index(row - 1, 0, parent);
         } else {
+            if (includeTopLevel)
+                return parent;
             // Prev parent
             int parentRow = parent.row();
             QModelIndex prevParent;
@@ -399,10 +407,56 @@ QModelIndex SearchResultTreeModel::prev(const QModelIndex &idx) const
     } else {
         // We are on a top level item
         int row = idx.row();
+        QModelIndex prevParent;
         if (row > 0) {
-            QModelIndex prevParent = index(row - 1, 0);
-            return prevParent.child(rowCount(prevParent) ,0);
+            prevParent = index(row - 1, 0);
+        } else {
+            // wrap around
+            prevParent = index(rowCount() -1, 0);
         }
+        return prevParent.child(rowCount(prevParent) -1,0);
     }
     return QModelIndex();
 }
+
+QModelIndex SearchResultTreeModel::find(const QRegExp &expr, const QModelIndex &index, QTextDocument::FindFlags flags)
+{
+    QModelIndex resultIndex;
+    QModelIndex currentIndex = index;
+    bool backward = (flags & QTextDocument::FindBackward);
+
+    do {
+        if (backward)
+            currentIndex = prev(currentIndex, true);
+        else
+            currentIndex = next(currentIndex, true);
+        if (currentIndex.isValid()) {
+            const QString &text = data(currentIndex, ItemDataRoles::TextRole).toString();
+            if (expr.indexIn(text) != -1)
+                resultIndex = currentIndex;
+        }
+    } while (!resultIndex.isValid() && currentIndex.isValid() && currentIndex != index);
+    return resultIndex;
+}
+
+QModelIndex SearchResultTreeModel::find(const QString &term, const QModelIndex &index, QTextDocument::FindFlags flags)
+{
+    QModelIndex resultIndex;
+    QModelIndex currentIndex = index;
+    bool backward = (flags & QTextDocument::FindBackward);
+    flags = (flags & (~QTextDocument::FindBackward)); // backward is handled by us ourselves
+
+    do {
+        if (backward)
+            currentIndex = prev(currentIndex, true);
+        else
+            currentIndex = next(currentIndex, true);
+        if (currentIndex.isValid()) {
+            const QString &text = data(currentIndex, ItemDataRoles::TextRole).toString();
+            QTextDocument doc(text);
+            if (!doc.find(term, 0, flags).isNull())
+                resultIndex = currentIndex;
+        }
+    } while (!resultIndex.isValid() && currentIndex.isValid() && currentIndex != index);
+    return resultIndex;
+}
diff --git a/src/plugins/find/searchresulttreemodel.h b/src/plugins/find/searchresulttreemodel.h
index 89418b45cc05b838e84193028a1c9522246695ff..d143c1213a1d8a9003d3c2708110897087bd2b5a 100644
--- a/src/plugins/find/searchresulttreemodel.h
+++ b/src/plugins/find/searchresulttreemodel.h
@@ -33,7 +33,9 @@
 #include "searchresultwindow.h"
 
 #include <QtCore/QAbstractItemModel>
+#include <QtCore/QRegExp>
 #include <QtGui/QFont>
+#include <QtGui/QTextDocument>
 
 namespace Find {
 namespace Internal {
@@ -62,11 +64,14 @@ public:
     bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
     QVariant headerData(int section, Qt::Orientation orientation, int role) const;
 
-    QModelIndex next(const QModelIndex &idx) const;
-    QModelIndex prev(const QModelIndex &idx) const;
+    QModelIndex next(const QModelIndex &idx, bool includeTopLevel = false) const;
+    QModelIndex prev(const QModelIndex &idx, bool includeTopLevel = false) const;
 
     QList<int> addResultLines(const QList<SearchResultItem> &items);
 
+    QModelIndex find(const QRegExp &expr, const QModelIndex &index, QTextDocument::FindFlags flags);
+    QModelIndex find(const QString &term, const QModelIndex &index, QTextDocument::FindFlags flags);
+
 signals:
     void jumpToSearchResult(const QString &fileName, int lineNumber,
                             int searchTermStart, int searchTermLength);
diff --git a/src/plugins/find/searchresultwindow.cpp b/src/plugins/find/searchresultwindow.cpp
index 7af93b2cc40dfbebd1fd25f46ea7521b7d7a134b..404582902da3aa0a0571e39b859c365bc28a1f33 100644
--- a/src/plugins/find/searchresultwindow.cpp
+++ b/src/plugins/find/searchresultwindow.cpp
@@ -31,7 +31,9 @@
 #include "searchresulttreemodel.h"
 #include "searchresulttreeitems.h"
 #include "searchresulttreeview.h"
+#include "ifindsupport.h"
 
+#include <aggregation/aggregate.h>
 #include <coreplugin/icore.h>
 #include <utils/qtcassert.h>
 
@@ -52,6 +54,8 @@ static const char SETTINGSKEYEXPANDRESULTS[] = "ExpandResults";
 
 namespace Find {
 
+namespace Internal {
+
     class WideEnoughLineEdit : public QLineEdit {
         Q_OBJECT
     public:
@@ -70,31 +74,137 @@ namespace Find {
         void updateGeometry() { QLineEdit::updateGeometry(); }
     };
 
+    class SearchResultFindSupport : public IFindSupport
+    {
+        Q_OBJECT
+    public:
+        SearchResultFindSupport(SearchResultTreeView *view)
+            : m_view(view)
+        {
+        }
 
-struct SearchResultWindowPrivate {
-    SearchResultWindowPrivate();
+        bool supportsReplace() const { return false; }
 
-    Internal::SearchResultTreeView *m_searchResultTreeView;
-    QListWidget *m_noMatchesFoundDisplay;
-    QToolButton *m_expandCollapseToolButton;
-    QLabel *m_replaceLabel;
-    QLineEdit *m_replaceTextEdit;
-    QToolButton *m_replaceButton;
-    static const bool m_initiallyExpand = false;
-    QStackedWidget *m_widget;
-    SearchResult *m_currentSearch;
-    QList<SearchResultItem> m_items;
-    bool m_isShowingReplaceUI;
-    bool m_focusReplaceEdit;
-};
+        IFindSupport::FindFlags supportedFindFlags() const
+        {
+            return IFindSupport::FindBackward | IFindSupport::FindCaseSensitively
+                    | IFindSupport::FindRegularExpression | IFindSupport::FindWholeWords;
+        }
 
-SearchResultWindowPrivate::SearchResultWindowPrivate()
-    : m_currentSearch(0),
-    m_isShowingReplaceUI(false),
-    m_focusReplaceEdit(false)
-{
+        void resetIncrementalSearch()
+        {
+            m_incrementalFindStart = QModelIndex();
+        }
+
+        void clearResults() { }
+
+        QString currentFindString() const
+        {
+            return QString();
+        }
+
+        QString completedFindString() const
+        {
+            return QString();
+        }
+
+        void highlightAll(const QString &txt, IFindSupport::FindFlags findFlags)
+        {
+            Q_UNUSED(txt)
+            Q_UNUSED(findFlags)
+            return;
+        }
+
+        IFindSupport::Result findIncremental(const QString &txt, IFindSupport::FindFlags findFlags)
+        {
+            if (!m_incrementalFindStart.isValid())
+                m_incrementalFindStart = m_view->currentIndex();
+            m_view->setCurrentIndex(m_incrementalFindStart);
+            return find(txt, findFlags);
+        }
+
+        IFindSupport::Result findStep(const QString &txt, IFindSupport::FindFlags findFlags)
+        {
+            IFindSupport::Result result = find(txt, findFlags);
+            if (result == IFindSupport::Found)
+                m_incrementalFindStart = m_view->currentIndex();
+            return result;
+        }
+
+        IFindSupport::Result find(const QString &txt, IFindSupport::FindFlags findFlags)
+        {
+            if (txt.isEmpty())
+                return IFindSupport::NotFound;
+            QModelIndex index;
+            if (findFlags & IFindSupport::FindRegularExpression) {
+                bool sensitive = (findFlags & IFindSupport::FindCaseSensitively);
+                index = m_view->model()->find(QRegExp(txt, (sensitive ? Qt::CaseSensitive : Qt::CaseInsensitive)),
+                                      m_view->currentIndex(),
+                                      IFindSupport::textDocumentFlagsForFindFlags(findFlags));
+            } else {
+                index = m_view->model()->find(txt, m_view->currentIndex(),
+                                      IFindSupport::textDocumentFlagsForFindFlags(findFlags));
+            }
+            if (index.isValid()) {
+                m_view->setCurrentIndex(index);
+                m_view->scrollTo(index);
+                if (index.parent().isValid())
+                    m_view->expand(index.parent());
+                return IFindSupport::Found;
+            }
+            return IFindSupport::NotFound;
+        }
+
+        bool replaceStep(const QString &before, const QString &after,
+            IFindSupport::FindFlags findFlags)
+        {
+            Q_UNUSED(before)
+            Q_UNUSED(after)
+            Q_UNUSED(findFlags)
+            return false;
+        }
+
+        int replaceAll(const QString &before, const QString &after,
+            IFindSupport::FindFlags findFlags)
+        {
+            Q_UNUSED(before)
+            Q_UNUSED(after)
+            Q_UNUSED(findFlags)
+            return 0;
+        }
+
+    private:
+        SearchResultTreeView *m_view;
+        QModelIndex m_incrementalFindStart;
+    };
+
+    struct SearchResultWindowPrivate {
+        SearchResultWindowPrivate();
+
+        Internal::SearchResultTreeView *m_searchResultTreeView;
+        QListWidget *m_noMatchesFoundDisplay;
+        QToolButton *m_expandCollapseToolButton;
+        QLabel *m_replaceLabel;
+        QLineEdit *m_replaceTextEdit;
+        QToolButton *m_replaceButton;
+        static const bool m_initiallyExpand = false;
+        QStackedWidget *m_widget;
+        SearchResult *m_currentSearch;
+        QList<SearchResultItem> m_items;
+        bool m_isShowingReplaceUI;
+        bool m_focusReplaceEdit;
+    };
+
+    SearchResultWindowPrivate::SearchResultWindowPrivate()
+        : m_currentSearch(0),
+        m_isShowingReplaceUI(false),
+        m_focusReplaceEdit(false)
+    {
+    }
 }
 
+using namespace Find::Internal;
+
 SearchResultWindow::SearchResultWindow() : d(new SearchResultWindowPrivate)
 {
     d->m_widget = new QStackedWidget;
@@ -104,6 +214,9 @@ SearchResultWindow::SearchResultWindow() : d(new SearchResultWindowPrivate)
     d->m_searchResultTreeView->setFrameStyle(QFrame::NoFrame);
     d->m_searchResultTreeView->setAttribute(Qt::WA_MacShowFocusRect, false);
     d->m_widget->addWidget(d->m_searchResultTreeView);
+    Aggregation::Aggregate * agg = new Aggregation::Aggregate;
+    agg->add(d->m_searchResultTreeView);
+    agg->add(new SearchResultFindSupport(d->m_searchResultTreeView));
 
     d->m_noMatchesFoundDisplay = new QListWidget(d->m_widget);
     d->m_noMatchesFoundDisplay->addItem(tr("No matches found!"));
diff --git a/src/plugins/find/searchresultwindow.h b/src/plugins/find/searchresultwindow.h
index 46932f6fb11f4e8acfe7cc714e3333b613705854..47a80c246824b83feda70db04c6d74a9b25e8d7a 100644
--- a/src/plugins/find/searchresultwindow.h
+++ b/src/plugins/find/searchresultwindow.h
@@ -43,6 +43,7 @@ QT_END_NAMESPACE
 namespace Find {
 namespace Internal {
     class SearchResultTreeView;
+    struct SearchResultWindowPrivate;
 }
 class SearchResultWindow;
 
@@ -69,7 +70,6 @@ signals:
     friend class SearchResultWindow;
 };
 
-struct SearchResultWindowPrivate;
 class FIND_EXPORT SearchResultWindow : public Core::IOutputPane
 {
     Q_OBJECT
@@ -128,7 +128,7 @@ private:
     void writeSettings();
     QList<SearchResultItem> checkedItems() const;
 
-    SearchResultWindowPrivate *d;
+    Internal::SearchResultWindowPrivate *d;
 };
 
 } // namespace Find