diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp
index 4f17fe1e6ae0349cbd3f0d3a18f8c387f70c5236..4e6c579e8cf3ce75c72137825dc78469ed1b070b 100644
--- a/src/plugins/cppeditor/cppquickfix.cpp
+++ b/src/plugins/cppeditor/cppquickfix.cpp
@@ -36,6 +36,7 @@
 #include <cplusplus/ResolveExpression.h>
 #include <cplusplus/Overview.h>
 #include <cplusplus/TypeOfExpression.h>
+#include <cplusplus/DependencyTable.h>
 
 #include <TranslationUnit.h>
 #include <ASTVisitor.h>
@@ -1369,6 +1370,128 @@ protected:
     QStringList values;
 };
 
+
+class FixForwardDeclarationOp: public CppQuickFixOperation
+{
+public:
+    FixForwardDeclarationOp(TextEditor::BaseTextEditor *editor)
+        : CppQuickFixOperation(editor), fwdClass(0)
+    {
+    }
+
+    virtual QString description() const
+    {
+        return QApplication::translate("CppTools::QuickFix", "#include header file");
+    }
+
+    bool checkName(const NameAST *ast)
+    {
+        if (ast && isCursorOn(ast)) {
+            if (const Name *name = ast->name) {
+                context = LookupContext(document(), snapshot());
+
+                unsigned line, column;
+                document()->translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column);
+
+                fwdClass = 0;
+
+                foreach (const LookupItem &r, context.lookup(name, document()->scopeAt(line, column))) {
+                    if (! r.declaration())
+                        continue;
+                    else if (ForwardClassDeclaration *fwd = r.declaration()->asForwardClassDeclaration())
+                        fwdClass = fwd;
+                    else if (r.declaration()->isClass())
+                        return -1; // nothing to do.
+                }
+
+                if (fwdClass)
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    virtual int match(const QList<AST *> &path)
+    {
+        for (int index = path.size() - 1; index != -1; --index) {
+            AST *ast = path.at(index);
+            if (NamedTypeSpecifierAST *namedTy = ast->asNamedTypeSpecifier()) {
+                if (checkName(namedTy->name))
+                    return index;
+            } else if (ElaboratedTypeSpecifierAST *eTy = ast->asElaboratedTypeSpecifier()) {
+                if (checkName(eTy->name))
+                    return index;
+            }
+        }
+
+        return -1;
+    }
+
+    virtual void createChanges()
+    {
+        if (Class *k = snapshot().findMatchingClassDeclaration(fwdClass)) {
+            const QString headerFile = QString::fromUtf8(k->fileName(), k->fileNameLength());
+
+            // collect the fwd headers
+            Snapshot fwdHeaders;
+            fwdHeaders.insert(snapshot().document(headerFile));
+            foreach (Document::Ptr doc, snapshot()) {
+                QFileInfo headerFileInfo(doc->fileName());
+                if (doc->globalSymbolCount() == 0 && doc->includes().size() == 1)
+                    fwdHeaders.insert(doc);
+                else if (headerFileInfo.suffix().isEmpty())
+                    fwdHeaders.insert(doc);
+            }
+
+
+            DependencyTable dep;
+            dep.build(fwdHeaders);
+            QStringList candidates = dep.dependencyTable().value(headerFile);
+
+            const QString className = QString::fromUtf8(k->identifier()->chars());
+
+            QString best;
+            foreach (const QString &c, candidates) {
+                QFileInfo headerFileInfo(c);
+                if (headerFileInfo.fileName() == className) {
+                    best = c;
+                    break;
+                } else if (headerFileInfo.fileName().at(0).isUpper()) {
+                    best = c;
+                    // and continue
+                } else if (! best.isEmpty()) {
+                    if (c.count(QLatin1Char('/')) < best.count(QLatin1Char('/')))
+                        best = c;
+                }
+            }
+
+            if (best.isEmpty())
+                best = headerFile;
+
+            int pos = startOf(1);
+
+            unsigned currentLine = textCursor().blockNumber() + 1;
+            unsigned bestLine = 0;
+            foreach (const Document::Include &incl, document()->includes()) {
+                if (incl.line() < currentLine)
+                    bestLine = incl.line();
+            }
+
+            if (bestLine)
+                pos = editor()->document()->findBlockByNumber(bestLine).position();
+
+            Utils::ChangeSet changes;
+            changes.insert(pos, QString("#include <%1>\n").arg(QFileInfo(best).fileName()));
+            refactoringChanges()->changeFile(fileName(), changes);
+        }
+    }
+
+private:
+    LookupContext context;
+    Symbol *fwdClass;
+};
+
 } // end of anonymous namespace
 
 
@@ -1568,6 +1691,7 @@ QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixFactory::quickFixOperations
     QSharedPointer<ConvertNumericToOctal> convertNumericToOctal(new ConvertNumericToOctal(editor));
     QSharedPointer<ConvertNumericToDecimal> convertNumericToDecimal(new ConvertNumericToDecimal(editor));
     QSharedPointer<CompleteSwitchCaseStatement> completeSwitchCaseStatement(new CompleteSwitchCaseStatement(editor));
+    QSharedPointer<FixForwardDeclarationOp> fixForwardDeclarationOp(new FixForwardDeclarationOp(editor));
     QSharedPointer<DeclFromDef> declFromDef(new DeclFromDef(editor));
 
     quickFixOperations.append(rewriteLogicalAndOp);
@@ -1584,6 +1708,7 @@ QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixFactory::quickFixOperations
     quickFixOperations.append(convertNumericToOctal);
     quickFixOperations.append(convertNumericToDecimal);
     quickFixOperations.append(completeSwitchCaseStatement);
+    quickFixOperations.append(fixForwardDeclarationOp);
 
 #if 0
     quickFixOperations.append(declFromDef);