diff --git a/doc/api/qtcreator-api.qdoc b/doc/api/qtcreator-api.qdoc
index aca770d8b7b118a715642e42ee274ae5477b9b3d..f22ef491fee124990c9cce5a20d2665beed5c01b 100644
--- a/doc/api/qtcreator-api.qdoc
+++ b/doc/api/qtcreator-api.qdoc
@@ -142,7 +142,7 @@
     \row
     \o Add a find filter for the find dialog.
     \o Implement any kind of search term based search.
-    \o \l{Find::IFindFilter}, \l{Find::SearchResultWindow}, \l{Find::ResultWindowItem}
+    \o \l{Find::IFindFilter}, \l{Find::SearchResultWindow}
 
     \row
     \o Add support for the find tool bar to a widget.
diff --git a/src/plugins/find/find.pro b/src/plugins/find/find.pro
index bfdb979332a06cab9a1db6e9809b52d23b87c5a1..d0f67a405c27e05e34a3fb257bdab4f9e2f00d70 100644
--- a/src/plugins/find/find.pro
+++ b/src/plugins/find/find.pro
@@ -27,7 +27,8 @@ SOURCES += findtoolwindow.cpp \
     searchresulttreeitems.cpp \
     searchresulttreemodel.cpp \
     searchresulttreeview.cpp \
-    searchresultwindow.cpp
+    searchresultwindow.cpp \
+    ifindfilter.cpp
 FORMS += findwidget.ui \
     finddialog.ui
 RESOURCES += find.qrc
diff --git a/src/plugins/find/ifindfilter.cpp b/src/plugins/find/ifindfilter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d2eef03065a5db62027ae76ed618a9a9e29af0bf
--- /dev/null
+++ b/src/plugins/find/ifindfilter.cpp
@@ -0,0 +1,174 @@
+#include "ifindfilter.h"
+
+/*!
+    \class Find::IFindFilter
+    \brief The IFindFilter class is the base class for find implementations
+    that are invoked via the \gui{Edit -> Find/Replace -> Advanced Find}
+    dialog.
+
+    Implementations of this class add an additional "Scope" to the Advanced
+    Find dialog. That can be any search that requires the user to provide
+    a text based search term (potentially with find flags like
+    searching case sensitively or using regular expressions). Existing
+    scopes are e.g. "All Projects" (i.e. search in all files in all projects)
+    and "Files on File System" where the user provides a directory and file
+    patterns to search.
+
+    To make your find scope available to the user, you need to implement this
+    class, and register an instance of your subclass in the plugin manager.
+
+    A common way to present the search results to the user, is to use the
+    shared \gui{Search Results} panel.
+
+    If you want to implement a find filter that is doing a file based text
+    search, you should use Find::BaseFileFind, which already implements all
+    the details for this kind of search, only requiring you to provide an
+    iterator over the file names of the files that should be searched.
+
+    If you want to implement a more specialized find filter, you'll need
+    to
+    \list
+        \o Start your search in a separate thread
+        \o Make this known to the Core::ProgressManager, for a progress bar
+           and the ability to cancel the search
+        \o Interface with the shared \gui{Search Results} panel, to show
+           the search results, handle the event that the user click on one
+           of the search result items, and possible handle a global replace
+           of all or some of the search result items.
+    \endlist
+
+    Luckily QtConcurrent and the search result panel provide the frameworks
+    that make it relatively easy to implement,
+    while ensuring a common way for the user.
+
+    The common pattern is roughly this:
+
+    Implement the actual search within a QtConcurrent based method, i.e.
+    a method that takes a \c{QFutureInterface<MySearchResult> &future}
+    as the first parameter and the other information needed for the search
+    as additional parameters. It should set useful progress information
+    on the QFutureInterface, regularly check for \c{future.isPaused()}
+    and \c{future.isCanceled()}, and report the search results
+    (possibly in chunks) via \c{future.reportResult}.
+
+    In the find filter's find/replaceAll method, get the shared
+    \gui{Search Results} window, initiate a new search and connect the
+    signals for handling selection of results and the replace action
+    (see the Find::SearchResultWindow class for details).
+    Start your search implementation via the corresponding QtConcurrent
+    methods. Add the returned QFuture object to the Core::ProgressManager.
+    Use a QFutureWatcher on the returned QFuture object to receive a signal
+    when your search implementation reports search results, and add these
+    to the shared \gui{Search Results} window.
+*/
+
+/*!
+    \fn IFindFilter::~IFindFilter()
+    \internal
+*/
+
+/*!
+    \fn QString IFindFilter::id() const
+    \brief Unique string identifier for this find filter.
+
+    Usually should be something like "MyPlugin.MyFindFilter".
+*/
+
+/*!
+    \fn QString IFindFilter::displayName() const
+    \brief The name of the find filter/scope as presented to the user.
+
+    This is the name that e.g. appears in the scope selection combo box.
+    Always return a translatable string (i.e. use tr() for the return value).
+*/
+
+/*!
+    \fn bool IFindFilter::isEnabled() const
+    \brief Returns if the user should be able to select this find filter
+    at the moment.
+
+    This is used e.g. for the "Current Projects" scope - if the user hasn't
+    opened a project, the scope is disabled.
+
+    \sa changed()
+*/
+
+/*!
+    \fn QKeySequence IFindFilter::defaultShortcut() const
+    \brief Returns the shortcut that can be used to open the advanced find
+    dialog with this filter/scope preselected.
+
+    Usually return an empty shortcut here, the user can still choose and
+    assign a specific shortcut to this find scope via the preferences.
+*/
+
+/*!
+    \fn bool IFindFilter::isReplaceSupported() const
+    \brief Returns if the find filter supports search and replace.
+
+    The default value is false, override this method to return true, if
+    your find filter supports global search and replace.
+*/
+
+/*!
+    \fn void IFindFilter::findAll(const QString &txt, QTextDocument::FindFlags findFlags)
+    \brief This method is called when the user selected this find scope and
+    initiated a search.
+
+    You should start a thread which actually performs the search for \a txt
+    using the given \a findFlags
+    (add it to Core::ProgressManager for a progress bar!) and presents the
+    search results to the user (using the \gui{Search Results} output pane).
+    For more information see the descriptions of this class,
+    Core::ProgressManager, and Find::SearchResultWindow.
+
+    \sa replaceAll()
+    \sa Core::ProgressManager
+    \sa Find::SearchResultWindow
+*/
+
+/*!
+    \fn void IFindFilter::replaceAll(const QString &txt, QTextDocument::FindFlags findFlags)
+    \brief Override this method if you want to support search and replace.
+
+    This method is called when the user selected this find scope and
+    initiated a search and replace.
+    The default implementation does nothing.
+
+    You should start a thread which actually performs the search for \a txt
+    using the given \a findFlags
+    (add it to Core::ProgressManager for a progress bar!) and presents the
+    search results to the user (using the \gui{Search Results} output pane).
+    For more information see the descriptions of this class,
+    Core::ProgressManager, and Find::SearchResultWindow.
+
+    \sa findAll()
+    \sa Core::ProgressManager
+    \sa Find::SearchResultWindow
+*/
+
+/*!
+    \fn QWidget *IFindFilter::createConfigWidget()
+    \brief Return a widget that contains additional controls for options
+    for this find filter.
+
+    The widget will be shown below the common options in the Advanced Find
+    dialog. It will be reparented and deleted by the find plugin.
+*/
+
+/*!
+    \fn void IFindFilter::writeSettings(QSettings *settings)
+    \brief Called at shutdown to write the state of the additional options
+    for this find filter to the \a settings.
+*/
+
+/*!
+    \fn void IFindFilter::readSettings(QSettings *settings)
+    \brief Called at startup to read the state of the additional options
+    for this find filter from the \a settings.
+*/
+
+/*!
+    \fn void IFindFilter::changed()
+    \brief Signals that the enabled state of this find filter has changed.
+*/
diff --git a/src/plugins/find/searchresultwindow.cpp b/src/plugins/find/searchresultwindow.cpp
index 4ee0eea4bc13daa9fb031596b64b1c56d79c6ff9..40ebf6f209d6dc3c85c8b00990d2a9a02eafff39 100644
--- a/src/plugins/find/searchresultwindow.cpp
+++ b/src/plugins/find/searchresultwindow.cpp
@@ -211,8 +211,85 @@ namespace Internal {
 
 using namespace Find::Internal;
 
+/*!
+    \enum Find::SearchResultWindow::SearchMode
+    Specifies if a search should show the replace UI or not.
+
+    \value SearchOnly
+           The search doesn't support replace.
+    \value SearchAndReplace
+           The search supports replace, so show the UI for it.
+*/
+
+/*!
+    \class Find::SearchResult
+    \brief Reports user interaction like activation of a search result item.
+
+    Whenever a new search is initiated via startNewSearch, an instance of this
+    class is returned to provide the initiator with the hooks for handling user
+    interaction.
+*/
+
+/*!
+    \fn void SearchResult::activated(const Find::SearchResultItem &item)
+    \brief Sent if the user activated (e.g. double-clicked) a search result
+    \a item.
+*/
+
+/*!
+    \fn void SearchResult::replaceButtonClicked(const QString &replaceText, const QList<Find::SearchResultItem> &checkedItems)
+    \brief Sent when the user initiated a replace, e.g. by pressing the replace
+    all button.
+
+    The signal reports the text to use for replacement in \a replaceText,
+    and the list of search result items that were selected by the user
+    in \a checkedItems.
+    The handler of this signal should apply the replace only on the selected
+    items.
+*/
+
+/*!
+    \class Find::SearchResultWindow
+    \brief The SearchResultWindow class is the implementation of a commonly
+    shared \gui{Search Results} output pane. Use it to show search results
+    to a user.
+
+    Whenever you want to show the user a list of search results, or want
+    to present UI for a global search and replace, use the single instance
+    of this class.
+
+    Except for being an implementation of a output pane, the
+    SearchResultWindow has a few methods and one enum that allows other
+    plugins to show their search results and hook into the user actions for
+    selecting an entry and performing a global replace.
+
+    Whenever you start a search, call startNewSearch(SearchMode) to initialize
+    the search result window. The parameter determines if the GUI for
+    replacing should be shown.
+    The method returns a SearchResult object that is your
+    hook into the signals from user interaction for this search.
+    When you produce search results, call addResults or addResult to add them
+    to the search result window.
+    After the search has finished call finishSearch to inform the search
+    result window about it.
+
+    After that you get activated signals via your SearchResult instance when
+    the user selects a search result item, and, if you started the search
+    with the SearchAndReplace option, the replaceButtonClicked signal
+    when the user requests a replace.
+*/
+
+/*!
+    \fn QString SearchResultWindow::displayName() const
+    \internal
+*/
+
 SearchResultWindow *SearchResultWindow::m_instance = 0;
 
+/*!
+    \fn SearchResultWindow::SearchResultWindow()
+    \internal
+*/
 SearchResultWindow::SearchResultWindow() : d(new SearchResultWindowPrivate)
 {
     m_instance = this;
@@ -263,6 +340,10 @@ SearchResultWindow::SearchResultWindow() : d(new SearchResultWindowPrivate)
     setShowReplaceUI(false);
 }
 
+/*!
+    \fn SearchResultWindow::~SearchResultWindow()
+    \internal
+*/
 SearchResultWindow::~SearchResultWindow()
 {
     writeSettings();
@@ -274,21 +355,38 @@ SearchResultWindow::~SearchResultWindow()
     delete d;
 }
 
+/*!
+    \fn SearchResultWindow *SearchResultWindow::instance()
+    \brief Returns the single shared instance of the Search Results window.
+*/
 SearchResultWindow *SearchResultWindow::instance()
 {
     return m_instance;
 }
 
+/*!
+    \fn void SearchResultWindow::setTextToReplace(const QString &textToReplace)
+    \brief Sets the value in the UI element that allows the user to type
+    the text that should replace text in search results to \a textToReplace.
+*/
 void SearchResultWindow::setTextToReplace(const QString &textToReplace)
 {
     d->m_replaceTextEdit->setText(textToReplace);
 }
 
+/*!
+    \fn QString SearchResultWindow::textToReplace() const
+    \brief Returns the text that should replace the text in search results.
+*/
 QString SearchResultWindow::textToReplace() const
 {
     return d->m_replaceTextEdit->text();
 }
 
+/*!
+    \fn void SearchResultWindow::setShowReplaceUI(bool show)
+    \internal
+*/
 void SearchResultWindow::setShowReplaceUI(bool show)
 {
     d->m_searchResultTreeView->model()->setShowReplaceUI(show);
@@ -298,6 +396,10 @@ void SearchResultWindow::setShowReplaceUI(bool show)
     d->m_isShowingReplaceUI = show;
 }
 
+/*!
+    \fn void SearchResultWindow::handleReplaceButton()
+    \internal
+*/
 void SearchResultWindow::handleReplaceButton()
 {
     QTC_ASSERT(d->m_currentSearch, return);
@@ -307,6 +409,10 @@ void SearchResultWindow::handleReplaceButton()
         d->m_currentSearch->replaceButtonClicked(d->m_replaceTextEdit->text(), checkedItems());
 }
 
+/*!
+    \fn QList<SearchResultItem> SearchResultWindow::checkedItems() const
+    \internal
+*/
 QList<SearchResultItem> SearchResultWindow::checkedItems() const
 {
     QList<SearchResultItem> result;
@@ -326,20 +432,42 @@ QList<SearchResultItem> SearchResultWindow::checkedItems() const
     return result;
 }
 
+/*!
+    \fn void SearchResultWindow::visibilityChanged(bool)
+    \internal
+*/
 void SearchResultWindow::visibilityChanged(bool /*visible*/)
 {
 }
 
+/*!
+    \fn QWidget *SearchResultWindow::outputWidget(QWidget *)
+    \internal
+*/
 QWidget *SearchResultWindow::outputWidget(QWidget *)
 {
     return d->m_widget;
 }
 
+/*!
+    \fn QList<QWidget*> SearchResultWindow::toolBarWidgets() const
+    \internal
+*/
 QList<QWidget*> SearchResultWindow::toolBarWidgets() const
 {
     return QList<QWidget*>() << d->m_expandCollapseButton << d->m_replaceLabel << d->m_replaceTextEdit << d->m_replaceButton;
 }
 
+/*!
+    \fn SearchResult *SearchResultWindow::startNewSearch(SearchMode searchOrSearchAndReplace)
+    \brief Tells the search results window to start a new search.
+
+    This will clear the contents of the previous search and initialize the UI
+    with regard to showing the replace UI or not (depending on the search mode
+    in \a searchOrSearchAndReplace).
+    Returns a SearchResult object that is used for signaling user interaction
+    with the results of this search.
+*/
 SearchResult *SearchResultWindow::startNewSearch(SearchMode searchOrSearchAndReplace)
 {
     clearContents();
@@ -349,6 +477,11 @@ SearchResult *SearchResultWindow::startNewSearch(SearchMode searchOrSearchAndRep
     return d->m_currentSearch;
 }
 
+/*!
+    \fn void SearchResultWindow::finishSearch()
+    \brief Notifies the search result window that the current search
+    has finished, and the UI should reflect that.
+*/
 void SearchResultWindow::finishSearch()
 {
     if (d->m_items.count()) {
@@ -358,6 +491,10 @@ void SearchResultWindow::finishSearch()
     }
 }
 
+/*!
+    \fn void SearchResultWindow::clearContents()
+    \brief Clears the current contents in the search result window.
+*/
 void SearchResultWindow::clearContents()
 {
     d->m_replaceTextEdit->setEnabled(false);
@@ -369,6 +506,10 @@ void SearchResultWindow::clearContents()
     navigateStateChanged();
 }
 
+/*!
+    \fn void SearchResultWindow::showNoMatchesFound()
+    \internal
+*/
 void SearchResultWindow::showNoMatchesFound()
 {
     d->m_replaceTextEdit->setEnabled(false);
@@ -376,26 +517,47 @@ void SearchResultWindow::showNoMatchesFound()
     d->m_widget->setCurrentWidget(d->m_noMatchesFoundDisplay);
 }
 
+/*!
+    \fn bool SearchResultWindow::isEmpty() const
+    Returns if the search result window currently doesn't show any results.
+*/
 bool SearchResultWindow::isEmpty() const
 {
     return (d->m_searchResultTreeView->model()->rowCount() < 1);
 }
 
+/*!
+    \fn int SearchResultWindow::numberOfResults() const
+    Returns the number of search results currently shown in the search
+    results window.
+*/
 int SearchResultWindow::numberOfResults() const
 {
     return d->m_items.count();
 }
 
+/*!
+    \fn bool SearchResultWindow::hasFocus()
+    \internal
+*/
 bool SearchResultWindow::hasFocus()
 {
     return d->m_searchResultTreeView->hasFocus() || (d->m_isShowingReplaceUI && d->m_replaceTextEdit->hasFocus());
 }
 
+/*!
+    \fn bool SearchResultWindow::canFocus()
+    \internal
+*/
 bool SearchResultWindow::canFocus()
 {
     return !d->m_items.isEmpty();
 }
 
+/*!
+    \fn void SearchResultWindow::setFocus()
+    \internal
+*/
 void SearchResultWindow::setFocus()
 {
     if (!d->m_items.isEmpty()) {
@@ -414,17 +576,37 @@ void SearchResultWindow::setFocus()
     }
 }
 
+/*!
+    \fn void SearchResultWindow::setTextEditorFont(const QFont &font)
+    \internal
+*/
 void SearchResultWindow::setTextEditorFont(const QFont &font)
 {
     d->m_searchResultTreeView->setTextEditorFont(font);
 }
 
+/*!
+    \fn void SearchResultWindow::handleJumpToSearchResult(int index, bool)
+    \internal
+*/
 void SearchResultWindow::handleJumpToSearchResult(int index, bool /* checked */)
 {
     QTC_ASSERT(d->m_currentSearch, return);
     d->m_currentSearch->activated(d->m_items.at(index));
 }
 
+/*!
+    \fn void SearchResultWindow::addResult(const QString &fileName, int lineNumber, const QString &rowText, int searchTermStart, int searchTermLength, const QVariant &userData)
+    \brief Adds a single result line to the search results.
+
+    The \a fileName, \a lineNumber and \a rowText are shown in the result line.
+    \a searchTermStart and \a searchTermLength specify the region that
+    should be visually marked (string position and length in \a rowText).
+    You can attach arbitrary \a userData to the search result, which can
+    be used e.g. when reacting to the signals of the SearchResult for your search.
+
+    \sa addResults()
+*/
 void SearchResultWindow::addResult(const QString &fileName, int lineNumber, const QString &rowText,
     int searchTermStart, int searchTermLength, const QVariant &userData)
 {
@@ -438,6 +620,13 @@ void SearchResultWindow::addResult(const QString &fileName, int lineNumber, cons
     addResults(QList<SearchResultItem>() << item);
 }
 
+/*!
+    \fn void SearchResultWindow::addResults(QList<SearchResultItem> &items)
+    \brief Adds all of the given search result \a items to the search
+    results window.
+
+    \sa addResult()
+*/
 void SearchResultWindow::addResults(QList<SearchResultItem> &items)
 {
     int index = d->m_items.size();
@@ -460,6 +649,10 @@ void SearchResultWindow::addResults(QList<SearchResultItem> &items)
     }
 }
 
+/*!
+    \fn void SearchResultWindow::handleExpandCollapseToolButton(bool checked)
+    \internal
+*/
 void SearchResultWindow::handleExpandCollapseToolButton(bool checked)
 {
     d->m_searchResultTreeView->setAutoExpandResults(checked);
@@ -469,6 +662,10 @@ void SearchResultWindow::handleExpandCollapseToolButton(bool checked)
         d->m_searchResultTreeView->collapseAll();
 }
 
+/*!
+    \fn void SearchResultWindow::readSettings()
+    \internal
+*/
 void SearchResultWindow::readSettings()
 {
     QSettings *s = Core::ICore::instance()->settings();
@@ -479,6 +676,10 @@ void SearchResultWindow::readSettings()
     }
 }
 
+/*!
+    \fn void SearchResultWindow::writeSettings()
+    \internal
+*/
 void SearchResultWindow::writeSettings()
 {
     QSettings *s = Core::ICore::instance()->settings();
@@ -489,21 +690,37 @@ void SearchResultWindow::writeSettings()
     }
 }
 
+/*!
+    \fn int SearchResultWindow::priorityInStatusBar() const
+    \internal
+*/
 int SearchResultWindow::priorityInStatusBar() const
 {
     return 80;
 }
 
+/*!
+    \fn bool SearchResultWindow::canNext()
+    \internal
+*/
 bool SearchResultWindow::canNext()
 {
     return d->m_items.count() > 0;
 }
 
+/*!
+    \fn bool SearchResultWindow::canPrevious()
+    \internal
+*/
 bool SearchResultWindow::canPrevious()
 {
     return d->m_items.count() > 0;
 }
 
+/*!
+    \fn void SearchResultWindow::goToNext()
+    \internal
+*/
 void SearchResultWindow::goToNext()
 {
     if (d->m_items.count() == 0)
@@ -514,6 +731,11 @@ void SearchResultWindow::goToNext()
         d->m_searchResultTreeView->emitJumpToSearchResult(idx);
     }
 }
+
+/*!
+    \fn void SearchResultWindow::goToPrev()
+    \internal
+*/
 void SearchResultWindow::goToPrev()
 {
     if (!d->m_searchResultTreeView->model()->rowCount())
@@ -525,6 +747,10 @@ void SearchResultWindow::goToPrev()
     }
 }
 
+/*!
+    \fn bool SearchResultWindow::canNavigate()
+    \internal
+*/
 bool SearchResultWindow::canNavigate()
 {
     return true;