diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 5308d796d15c013952738980f59eb161c5cf9d76..7d576c6599f9d59d382ad7d0df777b5352bcb131 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -58,10 +58,10 @@ QT_END_NAMESPACE
 namespace CPlusPlus {
 class OverviewModel;
 class Symbol;
+class CppModelManagerInterface;
 }
 
 namespace CppTools {
-class CppModelManagerInterface;
 class CppCodeStyleSettings;
 class CppRefactoringFile;
 }
diff --git a/src/plugins/cppeditor/cppquickfix.h b/src/plugins/cppeditor/cppquickfix.h
index 92950136e47246890d55b4c89f3bb5afe8b8c8bc..df1cd80253c1f5939f85e81599cd09ce135e5107 100644
--- a/src/plugins/cppeditor/cppquickfix.h
+++ b/src/plugins/cppeditor/cppquickfix.h
@@ -36,8 +36,11 @@
 #include "cppeditor_global.h"
 #include <texteditor/quickfix.h>
 
+namespace CPlusPlus {
+class CppModelManagerInterface;
+}
+
 namespace CppTools {
-    class CppModelManagerInterface;
     class CppRefactoringFile;
     class CppRefactoringChanges;
     typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr;
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index f4ea4183c7464abc61473027e68a41dee2cbf099..baf506825989b4115a5345a0415fc773a6e115bd 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -56,12 +56,16 @@
 #include <cplusplus/DependencyTable.h>
 #include <cplusplus/Overview.h>
 #include <cplusplus/TypeOfExpression.h>
+#include <cplusplus/ModelManagerInterface.h>
 #include <cplusplus/CppRewriter.h>
 #include <cpptools/cpptoolsconstants.h>
 #include <cpptools/cpprefactoringchanges.h>
 #include <cpptools/insertionpointlocator.h>
 #include <cpptools/cpptoolsreuse.h>
+#include <cpptools/cppclassesfilter.h>
+#include <cpptools/searchsymbols.h>
 #include <extensionsystem/iplugin.h>
+#include <extensionsystem/pluginmanager.h>
 
 #include <QtCore/QFileInfo>
 #include <QtGui/QApplication>
@@ -1701,6 +1705,157 @@ private:
     };
 };
 
+/**
+ * Adds an include for an undefined identifier.
+ */
+class IncludeAdder : public CppQuickFixFactory
+{
+public:
+    virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface)
+    {
+        CppClassesFilter *classesFilter = ExtensionSystem::PluginManager::instance()->getObject<CppClassesFilter>();
+        if (!classesFilter)
+            return noResult();
+
+        const QList<AST *> &path = interface->path();
+
+        if (path.isEmpty())
+            return noResult();
+
+        // find the largest enclosing Name
+        const NameAST *enclosingName = 0;
+        const SimpleNameAST *innermostName = 0;
+        for (int i = path.size() - 1; i >= 0; --i) {
+            if (NameAST *nameAst = path.at(i)->asName()) {
+                enclosingName = nameAst;
+                if (!innermostName) {
+                    innermostName = nameAst->asSimpleName();
+                    if (!innermostName)
+                        return noResult();
+                }
+            } else {
+                break;
+            }
+        }
+        if (!enclosingName || !enclosingName->name)
+            return noResult();
+
+        // find the enclosing scope
+        unsigned line, column;
+        const Document::Ptr &doc = interface->semanticInfo().doc;
+        doc->translationUnit()->getTokenStartPosition(enclosingName->firstToken(), &line, &column);
+        Scope *scope = doc->scopeAt(line, column);
+        if (!scope)
+            return noResult();
+
+        // check if the name resolves to something
+        QList<LookupItem> existingResults = interface->context().lookup(enclosingName->name, scope);
+        if (!existingResults.isEmpty())
+            return noResult();
+
+        const QString &className = Overview()(innermostName->name);
+        if (className.isEmpty())
+            return noResult();
+
+        QList<CppQuickFixOperation::Ptr> results;
+
+        // find the include paths
+        QStringList includePaths;
+        CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
+        QList<CppModelManagerInterface::ProjectInfo> projectInfos = modelManager->projectInfos();
+        bool inProject = false;
+        foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) {
+            if (info.sourceFiles.contains(doc->fileName())) {
+                inProject = true;
+                includePaths += info.includePaths;
+            }
+        }
+        if (!inProject) {
+            // better use all include paths than none
+            foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos)
+                includePaths += info.includePaths;
+        }
+
+        // find a include file through the locator
+        QFutureInterface<Locator::FilterEntry> dummyInterface;
+        QList<Locator::FilterEntry> matches = classesFilter->matchesFor(dummyInterface, className);
+        bool classExists = false;
+        foreach (const Locator::FilterEntry &entry, matches) {
+            const ModelItemInfo info = entry.internalData.value<ModelItemInfo>();
+            if (info.symbolName != className)
+                continue;
+            classExists = true;
+            const QString &fileName = info.fileName;
+            const QFileInfo fileInfo(fileName);
+
+            // find the shortest way to include fileName given the includePaths
+            QString shortestInclude;
+
+            if (fileInfo.path() == QFileInfo(doc->fileName()).path()) {
+                shortestInclude = QString("\"%1\"").arg(fileInfo.fileName());
+            } else {
+                foreach (const QString &includePath, includePaths) {
+                    if (!fileName.startsWith(includePath))
+                        continue;
+                    QString relativePath = fileName.mid(includePath.size());
+                    if (!relativePath.isEmpty() && relativePath.at(0) == QLatin1Char('/'))
+                        relativePath = relativePath.mid(1);
+                    if (shortestInclude.isEmpty() || relativePath.size() + 2 < shortestInclude.size())
+                        shortestInclude = QString("<%1>").arg(relativePath);
+                }
+            }
+
+            if (!shortestInclude.isEmpty())
+                results += CppQuickFixOperation::Ptr(new Operation(interface, 0, shortestInclude));
+        }
+
+        // for QSomething, propose a <QSomething> include -- if such a class was in the locator
+        if (classExists
+                && className.size() > 2
+                && className.at(0) == QLatin1Char('Q')
+                && className.at(1).isUpper()) {
+            results += CppQuickFixOperation::Ptr(new Operation(interface, 1, QString("<%1>").arg(className)));
+        }
+
+        return results;
+    }
+
+private:
+    class Operation: public CppQuickFixOperation
+    {
+    public:
+        Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, const QString &include)
+            : CppQuickFixOperation(interface, priority)
+            , m_include(include)
+        {
+            setDescription(QApplication::translate("CppTools::QuickFix",
+                                                   "Add #include %1").arg(m_include));
+        }
+
+        virtual void performChanges(const CppRefactoringFilePtr &file,
+                                    const CppRefactoringChanges &)
+        {
+            // find location of last include in file
+            QList<Document::Include> includes = file->cppDocument()->includes();
+            unsigned lastIncludeLine = 0;
+            foreach (const Document::Include &include, includes) {
+                if (include.line() > lastIncludeLine)
+                    lastIncludeLine = include.line();
+            }
+
+            // add include
+            const int insertPos = file->position(lastIncludeLine + 1, 1) - 1;
+            ChangeSet changes;
+            changes.insert(insertPos, QString("\n#include %1").arg(m_include));
+            file->setChangeSet(changes);
+            file->apply();
+        }
+
+    private:
+        QString m_include;
+    };
+};
+
 } // end of anonymous namespace
 
 void registerQuickFixes(ExtensionSystem::IPlugin *plugIn)
@@ -1725,4 +1880,5 @@ void registerQuickFixes(ExtensionSystem::IPlugin *plugIn)
     plugIn->addAutoReleasedObject(new DeclFromDef);
     plugIn->addAutoReleasedObject(new DefFromDecl);
     plugIn->addAutoReleasedObject(new ApplyDeclDefLinkChanges);
+    plugIn->addAutoReleasedObject(new IncludeAdder);
 }
diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp
index 4c1e9e73d43aa59f4c2596803329a934ab796760..591e9829db2c186d45950a990efa36c372ec68fe 100644
--- a/src/plugins/cpptools/cppclassesfilter.cpp
+++ b/src/plugins/cpptools/cppclassesfilter.cpp
@@ -32,6 +32,7 @@
 
 #include "cppclassesfilter.h"
 
+using namespace CppTools;
 using namespace CppTools::Internal;
 
 CppClassesFilter::CppClassesFilter(CppModelManager *manager)
diff --git a/src/plugins/cpptools/cppclassesfilter.h b/src/plugins/cpptools/cppclassesfilter.h
index 4f88f79a871509e85245912ce024afb6de8d5954..bb4efb5b6c00c0fcfa327b7f22e216a2858c22ca 100644
--- a/src/plugins/cpptools/cppclassesfilter.h
+++ b/src/plugins/cpptools/cppclassesfilter.h
@@ -33,17 +33,17 @@
 #ifndef CPPCLASSESFILTER_H
 #define CPPCLASSESFILTER_H
 
-#include <cpplocatorfilter.h>
+#include "cpptools_global.h"
+#include "cpplocatorfilter.h"
 
 namespace CppTools {
-namespace Internal {
 
-class CppClassesFilter : public CppLocatorFilter
+class CPPTOOLS_EXPORT CppClassesFilter : public Internal::CppLocatorFilter
 {
     Q_OBJECT
 
 public:
-    CppClassesFilter(CppModelManager *manager);
+    CppClassesFilter(Internal::CppModelManager *manager);
     ~CppClassesFilter();
 
     QString displayName() const { return tr("Classes"); }
@@ -51,7 +51,6 @@ public:
     Priority priority() const { return Medium; }
 };
 
-} // namespace Internal
 } // namespace CppTools
 
 #endif // CPPCLASSESFILTER_H
diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
index 41bf6a38047a92e0f2058d73a48d5d10c26db5d7..0530da5ac87938fe32a7c006166523440b275335 100644
--- a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
+++ b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
@@ -111,7 +111,7 @@ QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(QFutureInterfac
 
 void CppCurrentDocumentFilter::accept(Locator::FilterEntry selection) const
 {
-    ModelItemInfo info = qvariant_cast<CppTools::Internal::ModelItemInfo>(selection.internalData);
+    ModelItemInfo info = qvariant_cast<CppTools::ModelItemInfo>(selection.internalData);
     TextEditor::BaseTextEditorWidget::openEditorAt(info.fileName, info.line, info.column,
                                              Core::Id(), Core::EditorManager::ModeSwitch);
 }
diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp
index 24923bcb313e24d2550f47a3eb3f7a4a2cb43968..2f75a6cf66347311248b7e91e009ce95485e1a84 100644
--- a/src/plugins/cpptools/cpplocatorfilter.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter.cpp
@@ -129,7 +129,7 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locato
 
 void CppLocatorFilter::accept(Locator::FilterEntry selection) const
 {
-    ModelItemInfo info = qvariant_cast<CppTools::Internal::ModelItemInfo>(selection.internalData);
+    ModelItemInfo info = qvariant_cast<CppTools::ModelItemInfo>(selection.internalData);
     TextEditor::BaseTextEditorWidget::openEditorAt(info.fileName, info.line, info.column,
                                              Core::Id(), Core::EditorManager::ModeSwitch);
 }
diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp
index 5d8b3df991e1902c057f12689176b0b70e38c5b9..33f538fb63984dfac4a0f468e488aef412cee779 100644
--- a/src/plugins/cpptools/searchsymbols.cpp
+++ b/src/plugins/cpptools/searchsymbols.cpp
@@ -39,7 +39,7 @@
 #include <QDebug>
 
 using namespace CPlusPlus;
-using namespace CppTools::Internal;
+using namespace CppTools;
 
 SearchSymbols::SymbolTypes SearchSymbols::AllTypes =
         SearchSymbols::Classes
diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h
index 6efdcce89d467bcce7dadbc190f8ca5c83e16e8b..5a2c7ba29ce97e928773edc6920556ef1212e08e 100644
--- a/src/plugins/cpptools/searchsymbols.h
+++ b/src/plugins/cpptools/searchsymbols.h
@@ -33,6 +33,8 @@
 #ifndef SEARCHSYMBOLS_H
 #define SEARCHSYMBOLS_H
 
+#include "cpptools_global.h"
+
 #include <cplusplus/CppDocument.h>
 #include <cplusplus/Icons.h>
 #include <cplusplus/Overview.h>
@@ -48,9 +50,8 @@
 #include <functional>
 
 namespace CppTools {
-namespace Internal {
 
-struct ModelItemInfo
+struct CPPTOOLS_EXPORT ModelItemInfo
 {
     enum ItemType { Enum, Class, Method, Declaration };
 
@@ -180,10 +181,9 @@ private:
     bool separateScope;
 };
 
-} // namespace Internal
 } // namespace CppTools
 
-Q_DECLARE_OPERATORS_FOR_FLAGS(CppTools::Internal::SearchSymbols::SymbolTypes)
-Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo)
+Q_DECLARE_OPERATORS_FOR_FLAGS(CppTools::SearchSymbols::SymbolTypes)
+Q_DECLARE_METATYPE(CppTools::ModelItemInfo)
 
 #endif // SEARCHSYMBOLS_H